aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2010-05-16 20:50:58 +0000
committermarha <marha@users.sourceforge.net>2010-05-16 20:50:58 +0000
commit1c94119ae26b94a60bb2c2b33494ed43c3b8a52f (patch)
treecfe0c736c95314edac7d9f1065be9c13026ed0c1 /xorg-server/hw
parent6b29aa4559aeb6f795caee047561654bfa0a1954 (diff)
downloadvcxsrv-1c94119ae26b94a60bb2c2b33494ed43c3b8a52f.tar.gz
vcxsrv-1c94119ae26b94a60bb2c2b33494ed43c3b8a52f.tar.bz2
vcxsrv-1c94119ae26b94a60bb2c2b33494ed43c3b8a52f.zip
svn merge -r588:HEAD ^/branches/released .
Diffstat (limited to 'xorg-server/hw')
-rw-r--r--xorg-server/hw/dmx/dmx.c2254
-rw-r--r--xorg-server/hw/dmx/dmx_glxvisuals.c1202
-rw-r--r--xorg-server/hw/dmx/dmxcmap.c424
-rw-r--r--xorg-server/hw/dmx/dmxcursor.c1970
-rw-r--r--xorg-server/hw/dmx/dmxfont.c1110
-rw-r--r--xorg-server/hw/dmx/dmxgc.c842
-rw-r--r--xorg-server/hw/dmx/dmxinit.c10
-rw-r--r--xorg-server/hw/dmx/dmxpict.c26
-rw-r--r--xorg-server/hw/dmx/dmxpixmap.c506
-rw-r--r--xorg-server/hw/dmx/dmxprop.c694
-rw-r--r--xorg-server/hw/dmx/dmxscrinit.c1048
-rw-r--r--xorg-server/hw/dmx/dmxsync.c386
-rw-r--r--xorg-server/hw/dmx/dmxwindow.c2030
-rw-r--r--xorg-server/hw/dmx/doc/dmx.sgml5555
-rw-r--r--xorg-server/hw/dmx/glxProxy/glxcmds.c7220
-rw-r--r--xorg-server/hw/dmx/glxProxy/glxext.c1064
-rw-r--r--xorg-server/hw/dmx/glxProxy/glxscreens.c754
-rw-r--r--xorg-server/hw/dmx/glxProxy/glxsingle.c2024
-rw-r--r--xorg-server/hw/dmx/glxProxy/glxswap.c1076
-rw-r--r--xorg-server/hw/dmx/glxProxy/glxutil.c222
-rw-r--r--xorg-server/hw/dmx/glxProxy/glxvendor.c1164
-rw-r--r--xorg-server/hw/dmx/glxProxy/glxvisuals.c1078
-rw-r--r--xorg-server/hw/dmx/glxProxy/unpack.h456
-rw-r--r--xorg-server/hw/dmx/input/dmxinputinit.c2622
-rw-r--r--xorg-server/hw/dmx/input/dmxmotion.c284
-rw-r--r--xorg-server/hw/dmx/input/lnx-keyboard.c1980
-rw-r--r--xorg-server/hw/dmx/input/usb-keyboard.c888
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyr.c20
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyr_draw.c1047
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyrdriext.c2858
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyrglxext.c1446
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyrhostvideo.c2024
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyrvideo.c2546
-rw-r--r--xorg-server/hw/kdrive/fake/fake.c952
-rw-r--r--xorg-server/hw/kdrive/fbdev/fbdev.c1652
-rw-r--r--xorg-server/hw/kdrive/linux/evdev.c1078
-rw-r--r--xorg-server/hw/kdrive/linux/keyboard.c1530
-rw-r--r--xorg-server/hw/kdrive/linux/mouse.c2060
-rw-r--r--xorg-server/hw/kdrive/linux/tslib.c380
-rw-r--r--xorg-server/hw/kdrive/src/kcmap.c492
-rw-r--r--xorg-server/hw/kdrive/src/kdrive.c8
-rw-r--r--xorg-server/hw/kdrive/src/kinfo.c326
-rw-r--r--xorg-server/hw/kdrive/src/kinput.c24
-rw-r--r--xorg-server/hw/kdrive/src/kshadow.c162
-rw-r--r--xorg-server/hw/kdrive/src/kxv.c3814
-rw-r--r--xorg-server/hw/vfb/InitOutput.c1946
-rw-r--r--xorg-server/hw/xfree86/common/xf86.h708
-rw-r--r--xorg-server/hw/xfree86/common/xf86AutoConfig.c1276
-rw-r--r--xorg-server/hw/xfree86/common/xf86Bus.c1366
-rw-r--r--xorg-server/hw/xfree86/common/xf86Config.c5172
-rw-r--r--xorg-server/hw/xfree86/common/xf86Configure.c1784
-rw-r--r--xorg-server/hw/xfree86/common/xf86Cursor.c1724
-rw-r--r--xorg-server/hw/xfree86/common/xf86DGA.c2454
-rw-r--r--xorg-server/hw/xfree86/common/xf86DPMS.c400
-rw-r--r--xorg-server/hw/xfree86/common/xf86Events.c4
-rw-r--r--xorg-server/hw/xfree86/common/xf86Helper.c5176
-rw-r--r--xorg-server/hw/xfree86/common/xf86Init.c3644
-rw-r--r--xorg-server/hw/xfree86/common/xf86Mode.c4134
-rw-r--r--xorg-server/hw/xfree86/common/xf86Option.c1724
-rw-r--r--xorg-server/hw/xfree86/common/xf86Privstr.h343
-rw-r--r--xorg-server/hw/xfree86/common/xf86RandR.c918
-rw-r--r--xorg-server/hw/xfree86/common/xf86ShowOpts.c256
-rw-r--r--xorg-server/hw/xfree86/common/xf86VGAarbiter.c2202
-rw-r--r--xorg-server/hw/xfree86/common/xf86VidMode.c1334
-rw-r--r--xorg-server/hw/xfree86/common/xf86Xinput.c2568
-rw-r--r--xorg-server/hw/xfree86/common/xf86cmap.c2332
-rw-r--r--xorg-server/hw/xfree86/common/xf86fbman.c2876
-rw-r--r--xorg-server/hw/xfree86/common/xf86pciBus.c846
-rw-r--r--xorg-server/hw/xfree86/common/xf86sbusBus.c1376
-rw-r--r--xorg-server/hw/xfree86/common/xf86xv.c4203
-rw-r--r--xorg-server/hw/xfree86/common/xf86xvmc.c458
-rw-r--r--xorg-server/hw/xfree86/common/xisb.c348
-rw-r--r--xorg-server/hw/xfree86/ddc/ddc.c1014
-rw-r--r--xorg-server/hw/xfree86/ddc/ddcProperty.c250
-rw-r--r--xorg-server/hw/xfree86/ddc/interpret_edid.c1370
-rw-r--r--xorg-server/hw/xfree86/dixmods/extmod/modinit.c374
-rw-r--r--xorg-server/hw/xfree86/dixmods/extmod/xf86dga2.c2120
-rw-r--r--xorg-server/hw/xfree86/dixmods/extmod/xf86vmode.c4340
-rw-r--r--xorg-server/hw/xfree86/dri/dri.c5008
-rw-r--r--xorg-server/hw/xfree86/dri/xf86dri.c1358
-rw-r--r--xorg-server/hw/xfree86/dri2/dri2.c165
-rw-r--r--xorg-server/hw/xfree86/dri2/dri2.h9
-rw-r--r--xorg-server/hw/xfree86/dri2/dri2ext.c64
-rw-r--r--xorg-server/hw/xfree86/exa/examodule.c396
-rw-r--r--xorg-server/hw/xfree86/fbdevhw/fbdevhw.c2018
-rw-r--r--xorg-server/hw/xfree86/i2c/bt829.c1490
-rw-r--r--xorg-server/hw/xfree86/i2c/fi1236.c1210
-rw-r--r--xorg-server/hw/xfree86/i2c/msp3430.c1452
-rw-r--r--xorg-server/hw/xfree86/i2c/tda8425.c156
-rw-r--r--xorg-server/hw/xfree86/i2c/tda9850.c224
-rw-r--r--xorg-server/hw/xfree86/i2c/tda9885.c208
-rw-r--r--xorg-server/hw/xfree86/i2c/uda1380.c366
-rw-r--r--xorg-server/hw/xfree86/i2c/xf86i2c.c1732
-rw-r--r--xorg-server/hw/xfree86/int10/generic.c988
-rw-r--r--xorg-server/hw/xfree86/int10/helper_exec.c1454
-rw-r--r--xorg-server/hw/xfree86/int10/helper_mem.c660
-rw-r--r--xorg-server/hw/xfree86/loader/loadext.c884
-rw-r--r--xorg-server/hw/xfree86/loader/loadmod.c2536
-rw-r--r--xorg-server/hw/xfree86/modes/xf86Crtc.c6402
-rw-r--r--xorg-server/hw/xfree86/modes/xf86Cursors.c4
-rw-r--r--xorg-server/hw/xfree86/modes/xf86DiDGA.c436
-rw-r--r--xorg-server/hw/xfree86/modes/xf86DisplayIDModes.c874
-rw-r--r--xorg-server/hw/xfree86/modes/xf86EdidModes.c2430
-rw-r--r--xorg-server/hw/xfree86/modes/xf86Modes.c1454
-rw-r--r--xorg-server/hw/xfree86/modes/xf86RandR12.c3620
-rw-r--r--xorg-server/hw/xfree86/modes/xf86Rotate.c1054
-rw-r--r--xorg-server/hw/xfree86/os-support/bsd/i386_video.c1816
-rw-r--r--xorg-server/hw/xfree86/os-support/bus/Sbus.c1380
-rw-r--r--xorg-server/hw/xfree86/os-support/linux/int10/linux.c1088
-rw-r--r--xorg-server/hw/xfree86/os-support/linux/lnx_agp.c748
-rw-r--r--xorg-server/hw/xfree86/os-support/linux/lnx_video.c1756
-rw-r--r--xorg-server/hw/xfree86/os-support/shared/posix_tty.c1310
-rw-r--r--xorg-server/hw/xfree86/os-support/shared/vidmem.c592
-rw-r--r--xorg-server/hw/xfree86/os-support/solaris/sun_agp.c654
-rw-r--r--xorg-server/hw/xfree86/ramdac/xf86Cursor.c958
-rw-r--r--xorg-server/hw/xfree86/ramdac/xf86HWCurs.c1054
-rw-r--r--xorg-server/hw/xfree86/ramdac/xf86RamDac.c308
-rw-r--r--xorg-server/hw/xfree86/shadowfb/shadow.c3458
-rw-r--r--xorg-server/hw/xfree86/vbe/vbe.c2290
-rw-r--r--xorg-server/hw/xfree86/vbe/vbe.h682
-rw-r--r--xorg-server/hw/xfree86/vbe/vbeModes.c902
-rw-r--r--xorg-server/hw/xfree86/vgahw/vgaCmap.c602
-rw-r--r--xorg-server/hw/xfree86/vgahw/vgaHW.c3990
-rw-r--r--xorg-server/hw/xfree86/xaa/xaaBitBlt.c442
-rw-r--r--xorg-server/hw/xfree86/xaa/xaaCpyArea.c774
-rw-r--r--xorg-server/hw/xfree86/xaa/xaaCpyPlane.c416
-rw-r--r--xorg-server/hw/xfree86/xaa/xaaCpyWin.c164
-rw-r--r--xorg-server/hw/xfree86/xaa/xaaGC.c1312
-rw-r--r--xorg-server/hw/xfree86/xaa/xaaImage.c1042
-rw-r--r--xorg-server/hw/xfree86/xaa/xaaInit.c1248
-rw-r--r--xorg-server/hw/xfree86/xaa/xaaInitAccel.c2996
-rw-r--r--xorg-server/hw/xfree86/xaa/xaaLineMisc.c302
-rw-r--r--xorg-server/hw/xfree86/xaa/xaaNonTEText.c1182
-rw-r--r--xorg-server/hw/xfree86/xaa/xaaOffscreen.c324
-rw-r--r--xorg-server/hw/xfree86/xaa/xaaOverlay.c258
-rw-r--r--xorg-server/hw/xfree86/xaa/xaaOverlayDF.c2100
-rw-r--r--xorg-server/hw/xfree86/xaa/xaaPCache.c4760
-rw-r--r--xorg-server/hw/xfree86/xaa/xaaPict.c1310
-rw-r--r--xorg-server/hw/xfree86/xaa/xaaStateChange.c3252
-rw-r--r--xorg-server/hw/xfree86/xaa/xaaTEGlyph.c2154
-rw-r--r--xorg-server/hw/xfree86/xaa/xaaTEText.c624
-rw-r--r--xorg-server/hw/xfree86/xaa/xaaWrapper.c948
-rw-r--r--xorg-server/hw/xfree86/xaa/xaalocal.h3510
-rw-r--r--xorg-server/hw/xnest/Color.c990
-rw-r--r--xorg-server/hw/xnest/Cursor.c366
-rw-r--r--xorg-server/hw/xnest/Display.c386
-rw-r--r--xorg-server/hw/xnest/Font.c172
-rw-r--r--xorg-server/hw/xnest/GC.c678
-rw-r--r--xorg-server/hw/xnest/Keyboard.c514
-rw-r--r--xorg-server/hw/xnest/Pixmap.c282
-rw-r--r--xorg-server/hw/xnest/Screen.c841
-rw-r--r--xorg-server/hw/xquartz/GL/glcontextmodes.c1100
-rw-r--r--xorg-server/hw/xquartz/GL/indirect.c18
-rw-r--r--xorg-server/hw/xquartz/GL/visualConfigs.c570
-rw-r--r--xorg-server/hw/xquartz/applewm.c1492
-rw-r--r--xorg-server/hw/xquartz/darwin.c1816
-rw-r--r--xorg-server/hw/xquartz/pseudoramiX.c942
-rw-r--r--xorg-server/hw/xquartz/quartz.c897
-rw-r--r--xorg-server/hw/xquartz/xpr/appledri.c858
-rw-r--r--xorg-server/hw/xquartz/xpr/dri.c1906
-rw-r--r--xorg-server/hw/xquartz/xpr/driWrap.c1094
-rw-r--r--xorg-server/hw/xquartz/xpr/x-hook.c240
-rw-r--r--xorg-server/hw/xquartz/xpr/xprCursor.c836
-rw-r--r--xorg-server/hw/xquartz/xpr/xprScreen.c4
-rw-r--r--xorg-server/hw/xwin/glx/indirect.c4928
-rw-r--r--xorg-server/hw/xwin/win.h2884
-rw-r--r--xorg-server/hw/xwin/winauth.c4
-rw-r--r--xorg-server/hw/xwin/winconfig.c4
-rw-r--r--xorg-server/hw/xwin/windialogs.c2
-rw-r--r--xorg-server/hw/xwin/winerror.c340
-rw-r--r--xorg-server/hw/xwin/winvideo.c420
-rw-r--r--xorg-server/hw/xwin/winwindow.c1186
-rw-r--r--xorg-server/hw/xwin/winwindowswm.c26
173 files changed, 119801 insertions, 119701 deletions
diff --git a/xorg-server/hw/dmx/dmx.c b/xorg-server/hw/dmx/dmx.c
index a1afe76cf..b201fb8a7 100644
--- a/xorg-server/hw/dmx/dmx.c
+++ b/xorg-server/hw/dmx/dmx.c
@@ -1,1127 +1,1127 @@
-/*
- * Copyright 2002-2004 Red Hat Inc., Durham, North Carolina.
- *
- * 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 on 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 (including the
- * next paragraph) 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
- * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
- * 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.
- */
-
-/*
- * Authors:
- * Rickard E. (Rik) Faith <faith@redhat.com>
- *
- */
-
-/** \file
- * This file implements the server-side part of the DMX protocol. A
- * vector of fucntions is provided at extension initialization time, so
- * most all of the useful functions in this file are declared static and
- * do not appear in the doxygen documentation.
- *
- * Much of the low-level work is done by functions in \a dmxextension.c
- *
- * Please see the Client-to-Server DMX Extension to the X Protocol
- * document for details about the protocol. */
-
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "os.h"
-#include "dixstruct.h"
-#include "extnsionst.h"
-#include "opaque.h"
-
-#include "dmxextension.h"
-#include <X11/extensions/dmxproto.h>
-#include <X11/extensions/dmx.h>
-#include "protocol-versions.h"
-
-#ifdef PANORAMIX
-#include "panoramiX.h"
-extern unsigned long XRT_WINDOW;
-extern int PanoramiXNumScreens;
-#endif
-
-extern void DMXExtensionInit(void);
-
-static unsigned char DMXCode;
-
-static DISPATCH_PROC(ProcDMXDispatch);
-static DISPATCH_PROC(ProcDMXQueryVersion);
-static DISPATCH_PROC(ProcDMXSync);
-static DISPATCH_PROC(ProcDMXForceWindowCreation);
-static DISPATCH_PROC(ProcDMXGetScreenCount);
-static DISPATCH_PROC(ProcDMXGetScreenAttributes);
-static DISPATCH_PROC(ProcDMXChangeScreensAttributes);
-static DISPATCH_PROC(ProcDMXAddScreen);
-static DISPATCH_PROC(ProcDMXRemoveScreen);
-static DISPATCH_PROC(ProcDMXGetWindowAttributes);
-static DISPATCH_PROC(ProcDMXGetDesktopAttributes);
-static DISPATCH_PROC(ProcDMXChangeDesktopAttributes);
-static DISPATCH_PROC(ProcDMXGetInputCount);
-static DISPATCH_PROC(ProcDMXGetInputAttributes);
-static DISPATCH_PROC(ProcDMXAddInput);
-static DISPATCH_PROC(ProcDMXRemoveInput);
-
-static DISPATCH_PROC(SProcDMXDispatch);
-static DISPATCH_PROC(SProcDMXQueryVersion);
-static DISPATCH_PROC(SProcDMXSync);
-static DISPATCH_PROC(SProcDMXForceWindowCreation);
-static DISPATCH_PROC(SProcDMXGetScreenCount);
-static DISPATCH_PROC(SProcDMXGetScreenAttributes);
-static DISPATCH_PROC(SProcDMXChangeScreensAttributes);
-static DISPATCH_PROC(SProcDMXAddScreen);
-static DISPATCH_PROC(SProcDMXRemoveScreen);
-static DISPATCH_PROC(SProcDMXGetWindowAttributes);
-static DISPATCH_PROC(SProcDMXGetDesktopAttributes);
-static DISPATCH_PROC(SProcDMXChangeDesktopAttributes);
-static DISPATCH_PROC(SProcDMXGetInputCount);
-static DISPATCH_PROC(SProcDMXGetInputAttributes);
-static DISPATCH_PROC(SProcDMXAddInput);
-static DISPATCH_PROC(SProcDMXRemoveInput);
-
-static int _DMXXineramaActive(void)
-{
-#ifdef PANORAMIX
- return !noPanoramiXExtension;
-#endif
- return 0;
-}
-
-/** Initialize the extension. */
-void DMXExtensionInit(void)
-{
- ExtensionEntry *extEntry;
-
- if ((extEntry = AddExtension(DMX_EXTENSION_NAME, 0, 0,
- ProcDMXDispatch, SProcDMXDispatch,
- NULL, StandardMinorOpcode)))
- DMXCode = extEntry->base;
-}
-
-static void dmxSetScreenAttribute(int bit, DMXScreenAttributesPtr attr,
- CARD32 value)
-{
- switch (1 << bit) {
- case DMXScreenWindowWidth: attr->screenWindowWidth = value; break;
- case DMXScreenWindowHeight: attr->screenWindowHeight = value; break;
- case DMXScreenWindowXoffset: attr->screenWindowXoffset = value; break;
- case DMXScreenWindowYoffset: attr->screenWindowYoffset = value; break;
- case DMXRootWindowWidth: attr->rootWindowWidth = value; break;
- case DMXRootWindowHeight: attr->rootWindowHeight = value; break;
- case DMXRootWindowXoffset: attr->rootWindowXoffset = value; break;
- case DMXRootWindowYoffset: attr->rootWindowYoffset = value; break;
- case DMXRootWindowXorigin: attr->rootWindowXorigin = value; break;
- case DMXRootWindowYorigin: attr->rootWindowYorigin = value; break;
- }
-}
-
-static int dmxFetchScreenAttributes(unsigned int mask,
- DMXScreenAttributesPtr attr,
- CARD32 *value_list)
-{
- int i;
- CARD32 *value = value_list;
- int count = 0;
-
- for (i = 0; i < 32; i++) {
- if (mask & (1 << i)) {
- dmxSetScreenAttribute(i, attr, *value);
- ++value;
- ++count;
- }
- }
- return count;
-}
-
-static void dmxSetDesktopAttribute(int bit, DMXDesktopAttributesPtr attr,
- CARD32 value)
-{
- switch (1 << bit) {
- case DMXDesktopWidth: attr->width = value; break;
- case DMXDesktopHeight: attr->height = value; break;
- case DMXDesktopShiftX: attr->shiftX = value; break;
- case DMXDesktopShiftY: attr->shiftY = value; break;
- }
-}
-
-static int dmxFetchDesktopAttributes(unsigned int mask,
- DMXDesktopAttributesPtr attr,
- CARD32 *value_list)
-{
- int i;
- CARD32 *value = value_list;
- int count = 0;
-
- for (i = 0; i < 32; i++) {
- if (mask & (1 << i)) {
- dmxSetDesktopAttribute(i, attr, *value);
- ++value;
- ++count;
- }
- }
- return count;
-}
-
-static void dmxSetInputAttribute(int bit, DMXInputAttributesPtr attr,
- CARD32 value)
-{
- switch (1 << bit) {
- case DMXInputType: attr->inputType = value; break;
- case DMXInputPhysicalScreen: attr->physicalScreen = value; break;
- case DMXInputSendsCore: attr->sendsCore = !!value; break;
- }
-}
-
-static int dmxFetchInputAttributes(unsigned int mask,
- DMXInputAttributesPtr attr,
- CARD32 *value_list)
-{
- int i;
- CARD32 *value = value_list;
- int count = 0;
-
- for (i = 0; i < 32; i++) {
- if (mask & (1 << i)) {
- dmxSetInputAttribute(i, attr, *value);
- ++value;
- ++count;
- }
- }
- return count;
-}
-
-static int ProcDMXQueryVersion(ClientPtr client)
-{
- xDMXQueryVersionReply rep;
- int n;
-
- REQUEST_SIZE_MATCH(xDMXQueryVersionReq);
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.majorVersion = SERVER_DMX_MAJOR_VERSION;
- rep.minorVersion = SERVER_DMX_MINOR_VERSION;
- rep.patchVersion = SERVER_DMX_PATCH_VERSION;
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swapl(&rep.majorVersion, n);
- swapl(&rep.minorVersion, n);
- swapl(&rep.patchVersion, n);
- }
- WriteToClient(client, sizeof(xDMXQueryVersionReply), (char *)&rep);
- return client->noClientException;
-}
-
-static int ProcDMXSync(ClientPtr client)
-{
- xDMXSyncReply rep;
- int n;
-
- REQUEST_SIZE_MATCH(xDMXSyncReq);
-
- dmxFlushPendingSyncs();
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.status = 0;
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swapl(&rep.status, n);
- }
- WriteToClient(client, sizeof(xDMXSyncReply), (char *)&rep);
- return client->noClientException;
-}
-
-static int ProcDMXForceWindowCreation(ClientPtr client)
-{
- xDMXForceWindowCreationReply rep;
- REQUEST(xDMXForceWindowCreationReq);
- WindowPtr pWin;
- int n;
-
- REQUEST_SIZE_MATCH(xDMXForceWindowCreationReq);
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- PanoramiXRes *win;
- int i;
-
- if (!(win = SecurityLookupIDByType(client, stuff->window, XRT_WINDOW,
- DixReadAccess)))
- return -1; /* BadWindow */
-
- FOR_NSCREENS(i) {
- if (Success != dixLookupWindow(&pWin, win->info[i].id, client,
- DixReadAccess))
- return -1; /* BadWindow */
-
- dmxForceWindowCreation(pWin);
- }
- goto doreply;
- }
-#endif
-
- if (Success != dixLookupWindow(&pWin, stuff->window, client,
- DixReadAccess))
- return -1; /* BadWindow */
-
- dmxForceWindowCreation(pWin);
- doreply:
- dmxFlushPendingSyncs();
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.status = 0;
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swapl(&rep.status, n);
- }
- WriteToClient(client, sizeof(xDMXForceWindowCreationReply), (char *)&rep);
- return Success;
-}
-
-static int ProcDMXGetScreenCount(ClientPtr client)
-{
- xDMXGetScreenCountReply rep;
- int n;
-
- REQUEST_SIZE_MATCH(xDMXGetScreenCountReq);
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.screenCount = dmxGetNumScreens();
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swapl(&rep.screenCount, n);
- }
- WriteToClient(client, sizeof(xDMXGetScreenCountReply), (char *)&rep);
- return client->noClientException;
-}
-
-static int ProcDMXGetScreenAttributes(ClientPtr client)
-{
- REQUEST(xDMXGetScreenAttributesReq);
- xDMXGetScreenAttributesReply rep;
- int n;
- int length;
- int paddedLength;
- DMXScreenAttributesRec attr;
-
- REQUEST_SIZE_MATCH(xDMXGetScreenAttributesReq);
-
- if (stuff->physicalScreen < 0
- || stuff->physicalScreen >= dmxGetNumScreens()) return BadValue;
-
- if (!dmxGetScreenAttributes(stuff->physicalScreen, &attr))
- return BadValue;
-
- rep.logicalScreen = attr.logicalScreen;
- rep.screenWindowWidth = attr.screenWindowWidth;
- rep.screenWindowHeight = attr.screenWindowHeight;
- rep.screenWindowXoffset = attr.screenWindowXoffset;
- rep.screenWindowYoffset = attr.screenWindowYoffset;
- rep.rootWindowWidth = attr.rootWindowWidth;
- rep.rootWindowHeight = attr.rootWindowHeight;
- rep.rootWindowXoffset = attr.rootWindowXoffset;
- rep.rootWindowYoffset = attr.rootWindowYoffset;
- rep.rootWindowXorigin = attr.rootWindowXorigin;
- rep.rootWindowYorigin = attr.rootWindowYorigin;
-
- length = attr.displayName ? strlen(attr.displayName) : 0;
- paddedLength = pad_to_int32(length);
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = bytes_to_int32((sizeof(xDMXGetScreenAttributesReply) - sizeof(xGenericReply))
- + paddedLength);
- rep.displayNameLength = length;
-
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swapl(&rep.displayNameLength, n);
- swapl(&rep.logicalScreen, n);
- swaps(&rep.screenWindowWidth, n);
- swaps(&rep.screenWindowHeight, n);
- swaps(&rep.screenWindowXoffset, n);
- swaps(&rep.screenWindowYoffset, n);
- swaps(&rep.rootWindowWidth, n);
- swaps(&rep.rootWindowHeight, n);
- swaps(&rep.rootWindowXoffset, n);
- swaps(&rep.rootWindowYoffset, n);
- swaps(&rep.rootWindowXorigin, n);
- swaps(&rep.rootWindowYorigin, n);
- }
- WriteToClient(client, sizeof(xDMXGetScreenAttributesReply), (char *)&rep);
- if (length) WriteToClient(client, length, (char *)attr.displayName);
- return client->noClientException;
-}
-
-static int ProcDMXChangeScreensAttributes(ClientPtr client)
-{
- REQUEST(xDMXChangeScreensAttributesReq);
- xDMXChangeScreensAttributesReply rep;
- int n;
- int status = DMX_BAD_XINERAMA;
- unsigned int mask = 0;
- unsigned int i;
- CARD32 *screen_list;
- CARD32 *mask_list;
- CARD32 *value_list;
- DMXScreenAttributesPtr attribs;
- int errorScreen = 0;
- unsigned int len;
- int ones = 0;
-
-
- REQUEST_AT_LEAST_SIZE(xDMXChangeScreensAttributesReq);
- len = client->req_len - bytes_to_int32(sizeof(xDMXChangeScreensAttributesReq));
- if (len < stuff->screenCount + stuff->maskCount)
- return BadLength;
-
- screen_list = (CARD32 *)(stuff + 1);
- mask_list = &screen_list[stuff->screenCount];
- value_list = &mask_list[stuff->maskCount];
-
- for (i = 0; i < stuff->maskCount; i++) ones += Ones(mask_list[i]);
- if (len != stuff->screenCount + stuff->maskCount + ones)
- return BadLength;
-
- if (!_DMXXineramaActive()) goto noxinerama;
-
- if (!(attribs = xalloc(stuff->screenCount * sizeof(*attribs))))
- return BadAlloc;
-
- for (i = 0; i < stuff->screenCount; i++) {
- int count;
-
- if (i < stuff->maskCount) mask = mask_list[i];
- dmxGetScreenAttributes(screen_list[i], &attribs[i]);
- count = dmxFetchScreenAttributes(mask, &attribs[i], value_list);
- value_list += count;
- }
-
-#if PANORAMIX
- status = dmxConfigureScreenWindows(stuff->screenCount,
- screen_list,
- attribs,
- &errorScreen);
-#endif
-
- xfree(attribs);
-
- if (status == BadValue) return status;
-
- noxinerama:
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.status = status;
- rep.errorScreen = errorScreen;
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swapl(&rep.status, n);
- swapl(&rep.errorScreen, n);
- }
- WriteToClient(client,
- sizeof(xDMXChangeScreensAttributesReply),
- (char *)&rep);
- return client->noClientException;
-}
-
-static int ProcDMXAddScreen(ClientPtr client)
-{
- REQUEST(xDMXAddScreenReq);
- xDMXAddScreenReply rep;
- int n;
- int status = 0;
- CARD32 *value_list;
- DMXScreenAttributesRec attr;
- int count;
- char *name;
- int len;
- int paddedLength;
-
- REQUEST_AT_LEAST_SIZE(xDMXAddScreenReq);
- paddedLength = pad_to_int32(stuff->displayNameLength);
- len = client->req_len - bytes_to_int32(sizeof(xDMXAddScreenReq));
- if (len != Ones(stuff->valueMask) + paddedLength/4)
- return BadLength;
-
- memset(&attr, 0, sizeof(attr));
- dmxGetScreenAttributes(stuff->physicalScreen, &attr);
- value_list = (CARD32 *)(stuff + 1);
- count = dmxFetchScreenAttributes(stuff->valueMask, &attr, value_list);
-
- if (!(name = xalloc(stuff->displayNameLength + 1 + 4)))
- return BadAlloc;
- memcpy(name, &value_list[count], stuff->displayNameLength);
- name[stuff->displayNameLength] = '\0';
- attr.displayName = name;
-
- status = dmxAttachScreen(stuff->physicalScreen, &attr);
-
- xfree(name);
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.status = status;
- rep.physicalScreen = stuff->physicalScreen;
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swapl(&rep.status, n);
- swapl(&rep.physicalScreen, n);
- }
- WriteToClient(client,
- sizeof(xDMXAddScreenReply),
- (char *)&rep);
- return client->noClientException;
-}
-
-static int ProcDMXRemoveScreen(ClientPtr client)
-{
- REQUEST(xDMXRemoveScreenReq);
- xDMXRemoveScreenReply rep;
- int n;
- int status = 0;
-
- REQUEST_SIZE_MATCH(xDMXRemoveScreenReq);
-
- status = dmxDetachScreen(stuff->physicalScreen);
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.status = status;
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swapl(&rep.status, n);
- }
- WriteToClient(client,
- sizeof(xDMXRemoveScreenReply),
- (char *)&rep);
- return client->noClientException;
-}
-
-
-#ifdef PANORAMIX
-static int dmxPopulatePanoramiX(ClientPtr client, Window window,
- CARD32 *screens, CARD32 *windows,
- xRectangle *pos, xRectangle *vis)
-{
- WindowPtr pWin;
- PanoramiXRes *win;
- int i;
- int count = 0;
- DMXWindowAttributesRec attr;
-
- if (!(win = SecurityLookupIDByType(client, window, XRT_WINDOW,
- DixReadAccess)))
- return -1; /* BadWindow */
-
- FOR_NSCREENS(i) {
- if (Success != dixLookupWindow(&pWin, win->info[i].id, client,
- DixReadAccess))
- return -1; /* BadWindow */
- if (dmxGetWindowAttributes(pWin, &attr)) {
- screens[count] = attr.screen;
- windows[count] = attr.window;
- pos[count] = attr.pos;
- vis[count] = attr.vis;
- ++count; /* Only count existing windows */
- }
- }
- return count;
-}
-#endif
-
-static int dmxPopulate(ClientPtr client, Window window, CARD32 *screens,
- CARD32 *windows, xRectangle *pos, xRectangle *vis)
-{
- WindowPtr pWin;
- DMXWindowAttributesRec attr;
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension)
- return dmxPopulatePanoramiX(client, window, screens, windows,
- pos, vis);
-#endif
-
- if (Success != dixLookupWindow(&pWin, window, client, DixReadAccess))
- return -1; /* BadWindow */
-
- dmxGetWindowAttributes(pWin, &attr);
- *screens = attr.screen;
- *windows = attr.window;
- *pos = attr.pos;
- *vis = attr.vis;
- return 1;
-}
-
-static int dmxMaxNumScreens(void)
-{
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) return PanoramiXNumScreens;
-#endif
- return 1;
-}
-
-static int ProcDMXGetWindowAttributes(ClientPtr client)
-{
- REQUEST(xDMXGetWindowAttributesReq);
- xDMXGetWindowAttributesReply rep;
- int i, n;
- CARD32 *screens;
- CARD32 *windows;
- xRectangle *pos, *vis;
- int count = dmxMaxNumScreens();
-
- REQUEST_SIZE_MATCH(xDMXGetWindowAttributesReq);
-
- if (!(screens = xalloc(count * sizeof(*screens))))
- return BadAlloc;
- if (!(windows = xalloc(count * sizeof(*windows)))) {
- xfree(screens);
- return BadAlloc;
- }
- if (!(pos = xalloc(count * sizeof(*pos)))) {
- xfree(windows);
- xfree(screens);
- return BadAlloc;
- }
- if (!(vis = xalloc(count * sizeof(*vis)))) {
- xfree(pos);
- xfree(windows);
- xfree(screens);
- return BadAlloc;
- }
-
- if ((count = dmxPopulate(client, stuff->window, screens, windows,
- pos, vis)) < 0) {
- xfree(vis);
- xfree(pos);
- xfree(windows);
- xfree(screens);
- return BadWindow;
- }
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = count * 6;
- rep.screenCount = count;
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swapl(&rep.screenCount, n);
- for (i = 0; i < count; i++) {
- swapl(&screens[i], n);
- swapl(&windows[i], n);
-
- swaps(&pos[i].x, n);
- swaps(&pos[i].y, n);
- swaps(&pos[i].width, n);
- swaps(&pos[i].height, n);
-
- swaps(&vis[i].x, n);
- swaps(&vis[i].y, n);
- swaps(&vis[i].width, n);
- swaps(&vis[i].height, n);
- }
- }
-
- dmxFlushPendingSyncs();
-
- WriteToClient(client, sizeof(xDMXGetWindowAttributesReply), (char *)&rep);
- if (count) {
- WriteToClient(client, count * sizeof(*screens), (char *)screens);
- WriteToClient(client, count * sizeof(*windows), (char *)windows);
- WriteToClient(client, count * sizeof(*pos), (char *)pos);
- WriteToClient(client, count * sizeof(*vis), (char *)vis);
- }
-
- xfree(vis);
- xfree(pos);
- xfree(windows);
- xfree(screens);
-
- return client->noClientException;
-}
-
-static int ProcDMXGetDesktopAttributes(ClientPtr client)
-{
- xDMXGetDesktopAttributesReply rep;
- int n;
- DMXDesktopAttributesRec attr;
-
- REQUEST_SIZE_MATCH(xDMXGetDesktopAttributesReq);
-
- dmxGetDesktopAttributes(&attr);
-
- rep.width = attr.width;
- rep.height = attr.height;
- rep.shiftX = attr.shiftX;
- rep.shiftY = attr.shiftY;
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
-
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swapl(&rep.width, n);
- swapl(&rep.height, n);
- swapl(&rep.shiftX, n);
- swapl(&rep.shiftY, n);
- }
- WriteToClient(client, sizeof(xDMXGetDesktopAttributesReply), (char *)&rep);
- return client->noClientException;
-}
-
-static int ProcDMXChangeDesktopAttributes(ClientPtr client)
-{
- REQUEST(xDMXChangeDesktopAttributesReq);
- xDMXChangeDesktopAttributesReply rep;
- int n;
- int status = DMX_BAD_XINERAMA;
- CARD32 *value_list;
- DMXDesktopAttributesRec attr;
- int len;
-
- REQUEST_AT_LEAST_SIZE(xDMXChangeDesktopAttributesReq);
- len = client->req_len - (sizeof(xDMXChangeDesktopAttributesReq) >> 2);
- if (len != Ones(stuff->valueMask))
- return BadLength;
-
- if (!_DMXXineramaActive()) goto noxinerama;
-
- value_list = (CARD32 *)(stuff + 1);
-
- dmxGetDesktopAttributes(&attr);
- dmxFetchDesktopAttributes(stuff->valueMask, &attr, value_list);
-
-#if PANORAMIX
- status = dmxConfigureDesktop(&attr);
-#endif
- if (status == BadValue) return status;
-
- noxinerama:
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.status = status;
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swapl(&rep.status, n);
- }
- WriteToClient(client,
- sizeof(xDMXChangeDesktopAttributesReply),
- (char *)&rep);
- return client->noClientException;
-}
-
-static int ProcDMXGetInputCount(ClientPtr client)
-{
- xDMXGetInputCountReply rep;
- int n;
-
- REQUEST_SIZE_MATCH(xDMXGetInputCountReq);
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.inputCount = dmxGetInputCount();
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swapl(&rep.inputCount, n);
- }
- WriteToClient(client, sizeof(xDMXGetInputCountReply), (char *)&rep);
- return client->noClientException;
-}
-
-static int ProcDMXGetInputAttributes(ClientPtr client)
-{
- REQUEST(xDMXGetInputAttributesReq);
- xDMXGetInputAttributesReply rep;
- int n;
- int length;
- int paddedLength;
- DMXInputAttributesRec attr;
-
- REQUEST_SIZE_MATCH(xDMXGetInputAttributesReq);
-
- if (dmxGetInputAttributes(stuff->deviceId, &attr)) return BadValue;
- rep.inputType = attr.inputType;
- rep.physicalScreen = attr.physicalScreen;
- rep.physicalId = attr.physicalId;
- rep.isCore = attr.isCore;
- rep.sendsCore = attr.sendsCore;
- rep.detached = attr.detached;
-
- length = attr.name ? strlen(attr.name) : 0;
- paddedLength = pad_to_int32(length);
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = bytes_to_int32(paddedLength);
- rep.nameLength = length;
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swapl(&rep.inputType, n);
- swapl(&rep.physicalScreen, n);
- swapl(&rep.physicalId, n);
- swapl(&rep.nameLength, n);
- }
- WriteToClient(client, sizeof(xDMXGetInputAttributesReply), (char *)&rep);
- if (length) WriteToClient(client, length, (char *)attr.name);
- return client->noClientException;
-}
-
-static int ProcDMXAddInput(ClientPtr client)
-{
- REQUEST(xDMXAddInputReq);
- xDMXAddInputReply rep;
- int n;
- int status = 0;
- CARD32 *value_list;
- DMXInputAttributesRec attr;
- int count;
- char *name;
- int len;
- int paddedLength;
- int id = -1;
-
- REQUEST_AT_LEAST_SIZE(xDMXAddInputReq);
- paddedLength = pad_to_int32(stuff->displayNameLength);
- len = client->req_len - (sizeof(xDMXAddInputReq) >> 2);
- if (len != Ones(stuff->valueMask) + paddedLength/4)
- return BadLength;
-
- memset(&attr, 0, sizeof(attr));
- value_list = (CARD32 *)(stuff + 1);
- count = dmxFetchInputAttributes(stuff->valueMask, &attr, value_list);
-
- if (!(name = xalloc(stuff->displayNameLength + 1 + 4)))
- return BadAlloc;
- memcpy(name, &value_list[count], stuff->displayNameLength);
- name[stuff->displayNameLength] = '\0';
- attr.name = name;
-
- status = dmxAddInput(&attr, &id);
-
- xfree(name);
-
- if (status) return status;
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.status = status;
- rep.physicalId = id;
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swapl(&rep.status, n);
- swapl(&rep.physicalId, n);
- }
- WriteToClient(client, sizeof(xDMXAddInputReply), (char *)&rep);
- return client->noClientException;
-}
-
-static int ProcDMXRemoveInput(ClientPtr client)
-{
- REQUEST(xDMXRemoveInputReq);
- xDMXRemoveInputReply rep;
- int n;
- int status = 0;
-
- REQUEST_SIZE_MATCH(xDMXRemoveInputReq);
-
- status = dmxRemoveInput(stuff->physicalId);
-
- if (status) return status;
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.length = 0;
- rep.status = status;
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swapl(&rep.status, n);
- }
- WriteToClient(client, sizeof(xDMXRemoveInputReply), (char *)&rep);
- return client->noClientException;
-}
-
-static int ProcDMXDispatch(ClientPtr client)
-{
- REQUEST(xReq);
-
- switch (stuff->data) {
- case X_DMXQueryVersion: return ProcDMXQueryVersion(client);
- case X_DMXSync: return ProcDMXSync(client);
- case X_DMXForceWindowCreation: return ProcDMXForceWindowCreation(client);
- case X_DMXGetScreenCount: return ProcDMXGetScreenCount(client);
- case X_DMXGetScreenAttributes: return ProcDMXGetScreenAttributes(client);
- case X_DMXChangeScreensAttributes:
- return ProcDMXChangeScreensAttributes(client);
- case X_DMXAddScreen: return ProcDMXAddScreen(client);
- case X_DMXRemoveScreen: return ProcDMXRemoveScreen(client);
- case X_DMXGetWindowAttributes: return ProcDMXGetWindowAttributes(client);
- case X_DMXGetDesktopAttributes: return ProcDMXGetDesktopAttributes(client);
- case X_DMXChangeDesktopAttributes:
- return ProcDMXChangeDesktopAttributes(client);
- case X_DMXGetInputCount: return ProcDMXGetInputCount(client);
- case X_DMXGetInputAttributes: return ProcDMXGetInputAttributes(client);
- case X_DMXAddInput: return ProcDMXAddInput(client);
- case X_DMXRemoveInput: return ProcDMXRemoveInput(client);
-
- case X_DMXGetScreenInformationDEPRECATED:
- case X_DMXForceWindowCreationDEPRECATED:
- case X_DMXReconfigureScreenDEPRECATED:
- return BadImplementation;
-
- default: return BadRequest;
- }
-}
-
-static int SProcDMXQueryVersion(ClientPtr client)
-{
- int n;
- REQUEST(xDMXQueryVersionReq);
-
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xDMXQueryVersionReq);
- return ProcDMXQueryVersion(client);
-}
-
-static int SProcDMXSync(ClientPtr client)
-{
- int n;
- REQUEST(xDMXSyncReq);
-
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xDMXSyncReq);
- return ProcDMXSync(client);
-}
-
-static int SProcDMXForceWindowCreation(ClientPtr client)
-{
- int n;
- REQUEST(xDMXForceWindowCreationReq);
-
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xDMXForceWindowCreationReq);
- swaps(&stuff->window, n);
- return ProcDMXForceWindowCreation(client);
-}
-
-static int SProcDMXGetScreenCount(ClientPtr client)
-{
- int n;
- REQUEST(xDMXGetScreenCountReq);
-
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xDMXGetScreenCountReq);
- return ProcDMXGetScreenCount(client);
-}
-
-static int SProcDMXGetScreenAttributes(ClientPtr client)
-{
- int n;
- REQUEST(xDMXGetScreenAttributesReq);
-
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xDMXGetScreenAttributesReq);
- swapl(&stuff->physicalScreen, n);
- return ProcDMXGetScreenAttributes(client);
-}
-
-static int SProcDMXChangeScreensAttributes(ClientPtr client)
-{
- int n;
- REQUEST(xDMXChangeScreensAttributesReq);
-
- swaps(&stuff->length, n);
- REQUEST_AT_LEAST_SIZE(xDMXGetScreenAttributesReq);
- swapl(&stuff->screenCount, n);
- swapl(&stuff->maskCount, n);
- SwapRestL(stuff);
- return ProcDMXGetScreenAttributes(client);
-}
-
-static int SProcDMXAddScreen(ClientPtr client)
-{
- int n;
- int paddedLength;
- REQUEST(xDMXAddScreenReq);
-
- swaps(&stuff->length, n);
- REQUEST_AT_LEAST_SIZE(xDMXAddScreenReq);
- swapl(&stuff->displayNameLength, n);
- swapl(&stuff->valueMask, n);
- paddedLength = pad_to_int32(stuff->displayNameLength);
- SwapLongs((CARD32 *)(stuff+1), LengthRestL(stuff) - paddedLength/4);
- return ProcDMXAddScreen(client);
-}
-
-static int SProcDMXRemoveScreen(ClientPtr client)
-{
- int n;
- REQUEST(xDMXRemoveScreenReq);
-
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xDMXRemoveScreenReq);
- swapl(&stuff->physicalScreen, n);
- return ProcDMXRemoveScreen(client);
-}
-
-static int SProcDMXGetWindowAttributes(ClientPtr client)
-{
- int n;
- REQUEST(xDMXGetWindowAttributesReq);
-
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xDMXGetWindowAttributesReq);
- swapl(&stuff->window, n);
- return ProcDMXGetWindowAttributes(client);
-}
-
-static int SProcDMXGetDesktopAttributes(ClientPtr client)
-{
- int n;
- REQUEST(xDMXGetDesktopAttributesReq);
-
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xDMXGetDesktopAttributesReq);
- return ProcDMXGetDesktopAttributes(client);
-}
-
-static int SProcDMXChangeDesktopAttributes(ClientPtr client)
-{
- int n;
- REQUEST(xDMXChangeDesktopAttributesReq);
-
- swaps(&stuff->length, n);
- REQUEST_AT_LEAST_SIZE(xDMXChangeDesktopAttributesReq);
- swapl(&stuff->valueMask, n);
- SwapRestL(stuff);
- return ProcDMXChangeDesktopAttributes(client);
-}
-
-static int SProcDMXGetInputCount(ClientPtr client)
-{
- int n;
- REQUEST(xDMXGetInputCountReq);
-
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xDMXGetInputCountReq);
- return ProcDMXGetInputCount(client);
-}
-
-static int SProcDMXGetInputAttributes(ClientPtr client)
-{
- int n;
- REQUEST(xDMXGetInputAttributesReq);
-
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xDMXGetInputAttributesReq);
- swapl(&stuff->deviceId, n);
- return ProcDMXGetInputAttributes(client);
-}
-
-static int SProcDMXAddInput(ClientPtr client)
-{
- int n;
- int paddedLength;
- REQUEST(xDMXAddInputReq);
-
- swaps(&stuff->length, n);
- REQUEST_AT_LEAST_SIZE(xDMXAddInputReq);
- swapl(&stuff->displayNameLength, n);
- swapl(&stuff->valueMask, n);
- paddedLength = pad_to_int32(stuff->displayNameLength);
- SwapLongs((CARD32 *)(stuff+1), LengthRestL(stuff) - paddedLength/4);
- return ProcDMXAddInput(client);
-}
-
-static int SProcDMXRemoveInput(ClientPtr client)
-{
- int n;
- REQUEST(xDMXRemoveInputReq);
-
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xDMXRemoveInputReq);
- swapl(&stuff->physicalId, n);
- return ProcDMXRemoveInput(client);
-}
-
-static int SProcDMXDispatch (ClientPtr client)
-{
- REQUEST(xReq);
-
- switch (stuff->data) {
- case X_DMXQueryVersion: return SProcDMXQueryVersion(client);
- case X_DMXSync: return SProcDMXSync(client);
- case X_DMXForceWindowCreation: return SProcDMXForceWindowCreation(client);
- case X_DMXGetScreenCount: return SProcDMXGetScreenCount(client);
- case X_DMXGetScreenAttributes: return SProcDMXGetScreenAttributes(client);
- case X_DMXChangeScreensAttributes:
- return SProcDMXChangeScreensAttributes(client);
- case X_DMXAddScreen: return SProcDMXAddScreen(client);
- case X_DMXRemoveScreen: return SProcDMXRemoveScreen(client);
- case X_DMXGetWindowAttributes: return SProcDMXGetWindowAttributes(client);
- case X_DMXGetDesktopAttributes:
- return SProcDMXGetDesktopAttributes(client);
- case X_DMXChangeDesktopAttributes:
- return SProcDMXChangeDesktopAttributes(client);
- case X_DMXGetInputCount: return SProcDMXGetInputCount(client);
- case X_DMXGetInputAttributes: return SProcDMXGetInputAttributes(client);
- case X_DMXAddInput: return SProcDMXAddInput(client);
- case X_DMXRemoveInput: return SProcDMXRemoveInput(client);
-
- case X_DMXGetScreenInformationDEPRECATED:
- case X_DMXForceWindowCreationDEPRECATED:
- case X_DMXReconfigureScreenDEPRECATED:
- return BadImplementation;
-
- default: return BadRequest;
- }
-}
+/*
+ * Copyright 2002-2004 Red Hat Inc., Durham, North Carolina.
+ *
+ * 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 on 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 (including the
+ * next paragraph) 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
+ * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
+ * 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.
+ */
+
+/*
+ * Authors:
+ * Rickard E. (Rik) Faith <faith@redhat.com>
+ *
+ */
+
+/** \file
+ * This file implements the server-side part of the DMX protocol. A
+ * vector of fucntions is provided at extension initialization time, so
+ * most all of the useful functions in this file are declared static and
+ * do not appear in the doxygen documentation.
+ *
+ * Much of the low-level work is done by functions in \a dmxextension.c
+ *
+ * Please see the Client-to-Server DMX Extension to the X Protocol
+ * document for details about the protocol. */
+
+#ifdef HAVE_DMX_CONFIG_H
+#include <dmx-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "os.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "opaque.h"
+
+#include "dmxextension.h"
+#include <X11/extensions/dmxproto.h>
+#include <X11/extensions/dmx.h>
+#include "protocol-versions.h"
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+extern unsigned long XRT_WINDOW;
+extern int PanoramiXNumScreens;
+#endif
+
+extern void DMXExtensionInit(void);
+
+static unsigned char DMXCode;
+
+static DISPATCH_PROC(ProcDMXDispatch);
+static DISPATCH_PROC(ProcDMXQueryVersion);
+static DISPATCH_PROC(ProcDMXSync);
+static DISPATCH_PROC(ProcDMXForceWindowCreation);
+static DISPATCH_PROC(ProcDMXGetScreenCount);
+static DISPATCH_PROC(ProcDMXGetScreenAttributes);
+static DISPATCH_PROC(ProcDMXChangeScreensAttributes);
+static DISPATCH_PROC(ProcDMXAddScreen);
+static DISPATCH_PROC(ProcDMXRemoveScreen);
+static DISPATCH_PROC(ProcDMXGetWindowAttributes);
+static DISPATCH_PROC(ProcDMXGetDesktopAttributes);
+static DISPATCH_PROC(ProcDMXChangeDesktopAttributes);
+static DISPATCH_PROC(ProcDMXGetInputCount);
+static DISPATCH_PROC(ProcDMXGetInputAttributes);
+static DISPATCH_PROC(ProcDMXAddInput);
+static DISPATCH_PROC(ProcDMXRemoveInput);
+
+static DISPATCH_PROC(SProcDMXDispatch);
+static DISPATCH_PROC(SProcDMXQueryVersion);
+static DISPATCH_PROC(SProcDMXSync);
+static DISPATCH_PROC(SProcDMXForceWindowCreation);
+static DISPATCH_PROC(SProcDMXGetScreenCount);
+static DISPATCH_PROC(SProcDMXGetScreenAttributes);
+static DISPATCH_PROC(SProcDMXChangeScreensAttributes);
+static DISPATCH_PROC(SProcDMXAddScreen);
+static DISPATCH_PROC(SProcDMXRemoveScreen);
+static DISPATCH_PROC(SProcDMXGetWindowAttributes);
+static DISPATCH_PROC(SProcDMXGetDesktopAttributes);
+static DISPATCH_PROC(SProcDMXChangeDesktopAttributes);
+static DISPATCH_PROC(SProcDMXGetInputCount);
+static DISPATCH_PROC(SProcDMXGetInputAttributes);
+static DISPATCH_PROC(SProcDMXAddInput);
+static DISPATCH_PROC(SProcDMXRemoveInput);
+
+static int _DMXXineramaActive(void)
+{
+#ifdef PANORAMIX
+ return !noPanoramiXExtension;
+#endif
+ return 0;
+}
+
+/** Initialize the extension. */
+void DMXExtensionInit(void)
+{
+ ExtensionEntry *extEntry;
+
+ if ((extEntry = AddExtension(DMX_EXTENSION_NAME, 0, 0,
+ ProcDMXDispatch, SProcDMXDispatch,
+ NULL, StandardMinorOpcode)))
+ DMXCode = extEntry->base;
+}
+
+static void dmxSetScreenAttribute(int bit, DMXScreenAttributesPtr attr,
+ CARD32 value)
+{
+ switch (1 << bit) {
+ case DMXScreenWindowWidth: attr->screenWindowWidth = value; break;
+ case DMXScreenWindowHeight: attr->screenWindowHeight = value; break;
+ case DMXScreenWindowXoffset: attr->screenWindowXoffset = value; break;
+ case DMXScreenWindowYoffset: attr->screenWindowYoffset = value; break;
+ case DMXRootWindowWidth: attr->rootWindowWidth = value; break;
+ case DMXRootWindowHeight: attr->rootWindowHeight = value; break;
+ case DMXRootWindowXoffset: attr->rootWindowXoffset = value; break;
+ case DMXRootWindowYoffset: attr->rootWindowYoffset = value; break;
+ case DMXRootWindowXorigin: attr->rootWindowXorigin = value; break;
+ case DMXRootWindowYorigin: attr->rootWindowYorigin = value; break;
+ }
+}
+
+static int dmxFetchScreenAttributes(unsigned int mask,
+ DMXScreenAttributesPtr attr,
+ CARD32 *value_list)
+{
+ int i;
+ CARD32 *value = value_list;
+ int count = 0;
+
+ for (i = 0; i < 32; i++) {
+ if (mask & (1 << i)) {
+ dmxSetScreenAttribute(i, attr, *value);
+ ++value;
+ ++count;
+ }
+ }
+ return count;
+}
+
+static void dmxSetDesktopAttribute(int bit, DMXDesktopAttributesPtr attr,
+ CARD32 value)
+{
+ switch (1 << bit) {
+ case DMXDesktopWidth: attr->width = value; break;
+ case DMXDesktopHeight: attr->height = value; break;
+ case DMXDesktopShiftX: attr->shiftX = value; break;
+ case DMXDesktopShiftY: attr->shiftY = value; break;
+ }
+}
+
+static int dmxFetchDesktopAttributes(unsigned int mask,
+ DMXDesktopAttributesPtr attr,
+ CARD32 *value_list)
+{
+ int i;
+ CARD32 *value = value_list;
+ int count = 0;
+
+ for (i = 0; i < 32; i++) {
+ if (mask & (1 << i)) {
+ dmxSetDesktopAttribute(i, attr, *value);
+ ++value;
+ ++count;
+ }
+ }
+ return count;
+}
+
+static void dmxSetInputAttribute(int bit, DMXInputAttributesPtr attr,
+ CARD32 value)
+{
+ switch (1 << bit) {
+ case DMXInputType: attr->inputType = value; break;
+ case DMXInputPhysicalScreen: attr->physicalScreen = value; break;
+ case DMXInputSendsCore: attr->sendsCore = !!value; break;
+ }
+}
+
+static int dmxFetchInputAttributes(unsigned int mask,
+ DMXInputAttributesPtr attr,
+ CARD32 *value_list)
+{
+ int i;
+ CARD32 *value = value_list;
+ int count = 0;
+
+ for (i = 0; i < 32; i++) {
+ if (mask & (1 << i)) {
+ dmxSetInputAttribute(i, attr, *value);
+ ++value;
+ ++count;
+ }
+ }
+ return count;
+}
+
+static int ProcDMXQueryVersion(ClientPtr client)
+{
+ xDMXQueryVersionReply rep;
+ int n;
+
+ REQUEST_SIZE_MATCH(xDMXQueryVersionReq);
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.majorVersion = SERVER_DMX_MAJOR_VERSION;
+ rep.minorVersion = SERVER_DMX_MINOR_VERSION;
+ rep.patchVersion = SERVER_DMX_PATCH_VERSION;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.majorVersion, n);
+ swapl(&rep.minorVersion, n);
+ swapl(&rep.patchVersion, n);
+ }
+ WriteToClient(client, sizeof(xDMXQueryVersionReply), (char *)&rep);
+ return Success;
+}
+
+static int ProcDMXSync(ClientPtr client)
+{
+ xDMXSyncReply rep;
+ int n;
+
+ REQUEST_SIZE_MATCH(xDMXSyncReq);
+
+ dmxFlushPendingSyncs();
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.status = 0;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.status, n);
+ }
+ WriteToClient(client, sizeof(xDMXSyncReply), (char *)&rep);
+ return Success;
+}
+
+static int ProcDMXForceWindowCreation(ClientPtr client)
+{
+ xDMXForceWindowCreationReply rep;
+ REQUEST(xDMXForceWindowCreationReq);
+ WindowPtr pWin;
+ int n;
+
+ REQUEST_SIZE_MATCH(xDMXForceWindowCreationReq);
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ PanoramiXRes *win;
+ int i;
+
+ if (!(win = SecurityLookupIDByType(client, stuff->window, XRT_WINDOW,
+ DixReadAccess)))
+ return -1; /* BadWindow */
+
+ FOR_NSCREENS(i) {
+ if (Success != dixLookupWindow(&pWin, win->info[i].id, client,
+ DixReadAccess))
+ return -1; /* BadWindow */
+
+ dmxForceWindowCreation(pWin);
+ }
+ goto doreply;
+ }
+#endif
+
+ if (Success != dixLookupWindow(&pWin, stuff->window, client,
+ DixReadAccess))
+ return -1; /* BadWindow */
+
+ dmxForceWindowCreation(pWin);
+ doreply:
+ dmxFlushPendingSyncs();
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.status = 0;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.status, n);
+ }
+ WriteToClient(client, sizeof(xDMXForceWindowCreationReply), (char *)&rep);
+ return Success;
+}
+
+static int ProcDMXGetScreenCount(ClientPtr client)
+{
+ xDMXGetScreenCountReply rep;
+ int n;
+
+ REQUEST_SIZE_MATCH(xDMXGetScreenCountReq);
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.screenCount = dmxGetNumScreens();
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.screenCount, n);
+ }
+ WriteToClient(client, sizeof(xDMXGetScreenCountReply), (char *)&rep);
+ return Success;
+}
+
+static int ProcDMXGetScreenAttributes(ClientPtr client)
+{
+ REQUEST(xDMXGetScreenAttributesReq);
+ xDMXGetScreenAttributesReply rep;
+ int n;
+ int length;
+ int paddedLength;
+ DMXScreenAttributesRec attr;
+
+ REQUEST_SIZE_MATCH(xDMXGetScreenAttributesReq);
+
+ if (stuff->physicalScreen < 0
+ || stuff->physicalScreen >= dmxGetNumScreens()) return BadValue;
+
+ if (!dmxGetScreenAttributes(stuff->physicalScreen, &attr))
+ return BadValue;
+
+ rep.logicalScreen = attr.logicalScreen;
+ rep.screenWindowWidth = attr.screenWindowWidth;
+ rep.screenWindowHeight = attr.screenWindowHeight;
+ rep.screenWindowXoffset = attr.screenWindowXoffset;
+ rep.screenWindowYoffset = attr.screenWindowYoffset;
+ rep.rootWindowWidth = attr.rootWindowWidth;
+ rep.rootWindowHeight = attr.rootWindowHeight;
+ rep.rootWindowXoffset = attr.rootWindowXoffset;
+ rep.rootWindowYoffset = attr.rootWindowYoffset;
+ rep.rootWindowXorigin = attr.rootWindowXorigin;
+ rep.rootWindowYorigin = attr.rootWindowYorigin;
+
+ length = attr.displayName ? strlen(attr.displayName) : 0;
+ paddedLength = pad_to_int32(length);
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = bytes_to_int32((sizeof(xDMXGetScreenAttributesReply) - sizeof(xGenericReply))
+ + paddedLength);
+ rep.displayNameLength = length;
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.displayNameLength, n);
+ swapl(&rep.logicalScreen, n);
+ swaps(&rep.screenWindowWidth, n);
+ swaps(&rep.screenWindowHeight, n);
+ swaps(&rep.screenWindowXoffset, n);
+ swaps(&rep.screenWindowYoffset, n);
+ swaps(&rep.rootWindowWidth, n);
+ swaps(&rep.rootWindowHeight, n);
+ swaps(&rep.rootWindowXoffset, n);
+ swaps(&rep.rootWindowYoffset, n);
+ swaps(&rep.rootWindowXorigin, n);
+ swaps(&rep.rootWindowYorigin, n);
+ }
+ WriteToClient(client, sizeof(xDMXGetScreenAttributesReply), (char *)&rep);
+ if (length) WriteToClient(client, length, (char *)attr.displayName);
+ return Success;
+}
+
+static int ProcDMXChangeScreensAttributes(ClientPtr client)
+{
+ REQUEST(xDMXChangeScreensAttributesReq);
+ xDMXChangeScreensAttributesReply rep;
+ int n;
+ int status = DMX_BAD_XINERAMA;
+ unsigned int mask = 0;
+ unsigned int i;
+ CARD32 *screen_list;
+ CARD32 *mask_list;
+ CARD32 *value_list;
+ DMXScreenAttributesPtr attribs;
+ int errorScreen = 0;
+ unsigned int len;
+ int ones = 0;
+
+
+ REQUEST_AT_LEAST_SIZE(xDMXChangeScreensAttributesReq);
+ len = client->req_len - bytes_to_int32(sizeof(xDMXChangeScreensAttributesReq));
+ if (len < stuff->screenCount + stuff->maskCount)
+ return BadLength;
+
+ screen_list = (CARD32 *)(stuff + 1);
+ mask_list = &screen_list[stuff->screenCount];
+ value_list = &mask_list[stuff->maskCount];
+
+ for (i = 0; i < stuff->maskCount; i++) ones += Ones(mask_list[i]);
+ if (len != stuff->screenCount + stuff->maskCount + ones)
+ return BadLength;
+
+ if (!_DMXXineramaActive()) goto noxinerama;
+
+ if (!(attribs = malloc(stuff->screenCount * sizeof(*attribs))))
+ return BadAlloc;
+
+ for (i = 0; i < stuff->screenCount; i++) {
+ int count;
+
+ if (i < stuff->maskCount) mask = mask_list[i];
+ dmxGetScreenAttributes(screen_list[i], &attribs[i]);
+ count = dmxFetchScreenAttributes(mask, &attribs[i], value_list);
+ value_list += count;
+ }
+
+#if PANORAMIX
+ status = dmxConfigureScreenWindows(stuff->screenCount,
+ screen_list,
+ attribs,
+ &errorScreen);
+#endif
+
+ free(attribs);
+
+ if (status == BadValue) return status;
+
+ noxinerama:
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.status = status;
+ rep.errorScreen = errorScreen;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.status, n);
+ swapl(&rep.errorScreen, n);
+ }
+ WriteToClient(client,
+ sizeof(xDMXChangeScreensAttributesReply),
+ (char *)&rep);
+ return Success;
+}
+
+static int ProcDMXAddScreen(ClientPtr client)
+{
+ REQUEST(xDMXAddScreenReq);
+ xDMXAddScreenReply rep;
+ int n;
+ int status = 0;
+ CARD32 *value_list;
+ DMXScreenAttributesRec attr;
+ int count;
+ char *name;
+ int len;
+ int paddedLength;
+
+ REQUEST_AT_LEAST_SIZE(xDMXAddScreenReq);
+ paddedLength = pad_to_int32(stuff->displayNameLength);
+ len = client->req_len - bytes_to_int32(sizeof(xDMXAddScreenReq));
+ if (len != Ones(stuff->valueMask) + paddedLength/4)
+ return BadLength;
+
+ memset(&attr, 0, sizeof(attr));
+ dmxGetScreenAttributes(stuff->physicalScreen, &attr);
+ value_list = (CARD32 *)(stuff + 1);
+ count = dmxFetchScreenAttributes(stuff->valueMask, &attr, value_list);
+
+ if (!(name = malloc(stuff->displayNameLength + 1 + 4)))
+ return BadAlloc;
+ memcpy(name, &value_list[count], stuff->displayNameLength);
+ name[stuff->displayNameLength] = '\0';
+ attr.displayName = name;
+
+ status = dmxAttachScreen(stuff->physicalScreen, &attr);
+
+ free(name);
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.status = status;
+ rep.physicalScreen = stuff->physicalScreen;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.status, n);
+ swapl(&rep.physicalScreen, n);
+ }
+ WriteToClient(client,
+ sizeof(xDMXAddScreenReply),
+ (char *)&rep);
+ return Success;
+}
+
+static int ProcDMXRemoveScreen(ClientPtr client)
+{
+ REQUEST(xDMXRemoveScreenReq);
+ xDMXRemoveScreenReply rep;
+ int n;
+ int status = 0;
+
+ REQUEST_SIZE_MATCH(xDMXRemoveScreenReq);
+
+ status = dmxDetachScreen(stuff->physicalScreen);
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.status = status;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.status, n);
+ }
+ WriteToClient(client,
+ sizeof(xDMXRemoveScreenReply),
+ (char *)&rep);
+ return Success;
+}
+
+
+#ifdef PANORAMIX
+static int dmxPopulatePanoramiX(ClientPtr client, Window window,
+ CARD32 *screens, CARD32 *windows,
+ xRectangle *pos, xRectangle *vis)
+{
+ WindowPtr pWin;
+ PanoramiXRes *win;
+ int i;
+ int count = 0;
+ DMXWindowAttributesRec attr;
+
+ if (!(win = SecurityLookupIDByType(client, window, XRT_WINDOW,
+ DixReadAccess)))
+ return -1; /* BadWindow */
+
+ FOR_NSCREENS(i) {
+ if (Success != dixLookupWindow(&pWin, win->info[i].id, client,
+ DixReadAccess))
+ return -1; /* BadWindow */
+ if (dmxGetWindowAttributes(pWin, &attr)) {
+ screens[count] = attr.screen;
+ windows[count] = attr.window;
+ pos[count] = attr.pos;
+ vis[count] = attr.vis;
+ ++count; /* Only count existing windows */
+ }
+ }
+ return count;
+}
+#endif
+
+static int dmxPopulate(ClientPtr client, Window window, CARD32 *screens,
+ CARD32 *windows, xRectangle *pos, xRectangle *vis)
+{
+ WindowPtr pWin;
+ DMXWindowAttributesRec attr;
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension)
+ return dmxPopulatePanoramiX(client, window, screens, windows,
+ pos, vis);
+#endif
+
+ if (Success != dixLookupWindow(&pWin, window, client, DixReadAccess))
+ return -1; /* BadWindow */
+
+ dmxGetWindowAttributes(pWin, &attr);
+ *screens = attr.screen;
+ *windows = attr.window;
+ *pos = attr.pos;
+ *vis = attr.vis;
+ return 1;
+}
+
+static int dmxMaxNumScreens(void)
+{
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) return PanoramiXNumScreens;
+#endif
+ return 1;
+}
+
+static int ProcDMXGetWindowAttributes(ClientPtr client)
+{
+ REQUEST(xDMXGetWindowAttributesReq);
+ xDMXGetWindowAttributesReply rep;
+ int i, n;
+ CARD32 *screens;
+ CARD32 *windows;
+ xRectangle *pos, *vis;
+ int count = dmxMaxNumScreens();
+
+ REQUEST_SIZE_MATCH(xDMXGetWindowAttributesReq);
+
+ if (!(screens = malloc(count * sizeof(*screens))))
+ return BadAlloc;
+ if (!(windows = malloc(count * sizeof(*windows)))) {
+ free(screens);
+ return BadAlloc;
+ }
+ if (!(pos = malloc(count * sizeof(*pos)))) {
+ free(windows);
+ free(screens);
+ return BadAlloc;
+ }
+ if (!(vis = malloc(count * sizeof(*vis)))) {
+ free(pos);
+ free(windows);
+ free(screens);
+ return BadAlloc;
+ }
+
+ if ((count = dmxPopulate(client, stuff->window, screens, windows,
+ pos, vis)) < 0) {
+ free(vis);
+ free(pos);
+ free(windows);
+ free(screens);
+ return BadWindow;
+ }
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = count * 6;
+ rep.screenCount = count;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.screenCount, n);
+ for (i = 0; i < count; i++) {
+ swapl(&screens[i], n);
+ swapl(&windows[i], n);
+
+ swaps(&pos[i].x, n);
+ swaps(&pos[i].y, n);
+ swaps(&pos[i].width, n);
+ swaps(&pos[i].height, n);
+
+ swaps(&vis[i].x, n);
+ swaps(&vis[i].y, n);
+ swaps(&vis[i].width, n);
+ swaps(&vis[i].height, n);
+ }
+ }
+
+ dmxFlushPendingSyncs();
+
+ WriteToClient(client, sizeof(xDMXGetWindowAttributesReply), (char *)&rep);
+ if (count) {
+ WriteToClient(client, count * sizeof(*screens), (char *)screens);
+ WriteToClient(client, count * sizeof(*windows), (char *)windows);
+ WriteToClient(client, count * sizeof(*pos), (char *)pos);
+ WriteToClient(client, count * sizeof(*vis), (char *)vis);
+ }
+
+ free(vis);
+ free(pos);
+ free(windows);
+ free(screens);
+
+ return Success;
+}
+
+static int ProcDMXGetDesktopAttributes(ClientPtr client)
+{
+ xDMXGetDesktopAttributesReply rep;
+ int n;
+ DMXDesktopAttributesRec attr;
+
+ REQUEST_SIZE_MATCH(xDMXGetDesktopAttributesReq);
+
+ dmxGetDesktopAttributes(&attr);
+
+ rep.width = attr.width;
+ rep.height = attr.height;
+ rep.shiftX = attr.shiftX;
+ rep.shiftY = attr.shiftY;
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.width, n);
+ swapl(&rep.height, n);
+ swapl(&rep.shiftX, n);
+ swapl(&rep.shiftY, n);
+ }
+ WriteToClient(client, sizeof(xDMXGetDesktopAttributesReply), (char *)&rep);
+ return Success;
+}
+
+static int ProcDMXChangeDesktopAttributes(ClientPtr client)
+{
+ REQUEST(xDMXChangeDesktopAttributesReq);
+ xDMXChangeDesktopAttributesReply rep;
+ int n;
+ int status = DMX_BAD_XINERAMA;
+ CARD32 *value_list;
+ DMXDesktopAttributesRec attr;
+ int len;
+
+ REQUEST_AT_LEAST_SIZE(xDMXChangeDesktopAttributesReq);
+ len = client->req_len - (sizeof(xDMXChangeDesktopAttributesReq) >> 2);
+ if (len != Ones(stuff->valueMask))
+ return BadLength;
+
+ if (!_DMXXineramaActive()) goto noxinerama;
+
+ value_list = (CARD32 *)(stuff + 1);
+
+ dmxGetDesktopAttributes(&attr);
+ dmxFetchDesktopAttributes(stuff->valueMask, &attr, value_list);
+
+#if PANORAMIX
+ status = dmxConfigureDesktop(&attr);
+#endif
+ if (status == BadValue) return status;
+
+ noxinerama:
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.status = status;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.status, n);
+ }
+ WriteToClient(client,
+ sizeof(xDMXChangeDesktopAttributesReply),
+ (char *)&rep);
+ return Success;
+}
+
+static int ProcDMXGetInputCount(ClientPtr client)
+{
+ xDMXGetInputCountReply rep;
+ int n;
+
+ REQUEST_SIZE_MATCH(xDMXGetInputCountReq);
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.inputCount = dmxGetInputCount();
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.inputCount, n);
+ }
+ WriteToClient(client, sizeof(xDMXGetInputCountReply), (char *)&rep);
+ return Success;
+}
+
+static int ProcDMXGetInputAttributes(ClientPtr client)
+{
+ REQUEST(xDMXGetInputAttributesReq);
+ xDMXGetInputAttributesReply rep;
+ int n;
+ int length;
+ int paddedLength;
+ DMXInputAttributesRec attr;
+
+ REQUEST_SIZE_MATCH(xDMXGetInputAttributesReq);
+
+ if (dmxGetInputAttributes(stuff->deviceId, &attr)) return BadValue;
+ rep.inputType = attr.inputType;
+ rep.physicalScreen = attr.physicalScreen;
+ rep.physicalId = attr.physicalId;
+ rep.isCore = attr.isCore;
+ rep.sendsCore = attr.sendsCore;
+ rep.detached = attr.detached;
+
+ length = attr.name ? strlen(attr.name) : 0;
+ paddedLength = pad_to_int32(length);
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = bytes_to_int32(paddedLength);
+ rep.nameLength = length;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.inputType, n);
+ swapl(&rep.physicalScreen, n);
+ swapl(&rep.physicalId, n);
+ swapl(&rep.nameLength, n);
+ }
+ WriteToClient(client, sizeof(xDMXGetInputAttributesReply), (char *)&rep);
+ if (length) WriteToClient(client, length, (char *)attr.name);
+ return Success;
+}
+
+static int ProcDMXAddInput(ClientPtr client)
+{
+ REQUEST(xDMXAddInputReq);
+ xDMXAddInputReply rep;
+ int n;
+ int status = 0;
+ CARD32 *value_list;
+ DMXInputAttributesRec attr;
+ int count;
+ char *name;
+ int len;
+ int paddedLength;
+ int id = -1;
+
+ REQUEST_AT_LEAST_SIZE(xDMXAddInputReq);
+ paddedLength = pad_to_int32(stuff->displayNameLength);
+ len = client->req_len - (sizeof(xDMXAddInputReq) >> 2);
+ if (len != Ones(stuff->valueMask) + paddedLength/4)
+ return BadLength;
+
+ memset(&attr, 0, sizeof(attr));
+ value_list = (CARD32 *)(stuff + 1);
+ count = dmxFetchInputAttributes(stuff->valueMask, &attr, value_list);
+
+ if (!(name = malloc(stuff->displayNameLength + 1 + 4)))
+ return BadAlloc;
+ memcpy(name, &value_list[count], stuff->displayNameLength);
+ name[stuff->displayNameLength] = '\0';
+ attr.name = name;
+
+ status = dmxAddInput(&attr, &id);
+
+ free(name);
+
+ if (status) return status;
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.status = status;
+ rep.physicalId = id;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.status, n);
+ swapl(&rep.physicalId, n);
+ }
+ WriteToClient(client, sizeof(xDMXAddInputReply), (char *)&rep);
+ return Success;
+}
+
+static int ProcDMXRemoveInput(ClientPtr client)
+{
+ REQUEST(xDMXRemoveInputReq);
+ xDMXRemoveInputReply rep;
+ int n;
+ int status = 0;
+
+ REQUEST_SIZE_MATCH(xDMXRemoveInputReq);
+
+ status = dmxRemoveInput(stuff->physicalId);
+
+ if (status) return status;
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.status = status;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.status, n);
+ }
+ WriteToClient(client, sizeof(xDMXRemoveInputReply), (char *)&rep);
+ return Success;
+}
+
+static int ProcDMXDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+
+ switch (stuff->data) {
+ case X_DMXQueryVersion: return ProcDMXQueryVersion(client);
+ case X_DMXSync: return ProcDMXSync(client);
+ case X_DMXForceWindowCreation: return ProcDMXForceWindowCreation(client);
+ case X_DMXGetScreenCount: return ProcDMXGetScreenCount(client);
+ case X_DMXGetScreenAttributes: return ProcDMXGetScreenAttributes(client);
+ case X_DMXChangeScreensAttributes:
+ return ProcDMXChangeScreensAttributes(client);
+ case X_DMXAddScreen: return ProcDMXAddScreen(client);
+ case X_DMXRemoveScreen: return ProcDMXRemoveScreen(client);
+ case X_DMXGetWindowAttributes: return ProcDMXGetWindowAttributes(client);
+ case X_DMXGetDesktopAttributes: return ProcDMXGetDesktopAttributes(client);
+ case X_DMXChangeDesktopAttributes:
+ return ProcDMXChangeDesktopAttributes(client);
+ case X_DMXGetInputCount: return ProcDMXGetInputCount(client);
+ case X_DMXGetInputAttributes: return ProcDMXGetInputAttributes(client);
+ case X_DMXAddInput: return ProcDMXAddInput(client);
+ case X_DMXRemoveInput: return ProcDMXRemoveInput(client);
+
+ case X_DMXGetScreenInformationDEPRECATED:
+ case X_DMXForceWindowCreationDEPRECATED:
+ case X_DMXReconfigureScreenDEPRECATED:
+ return BadImplementation;
+
+ default: return BadRequest;
+ }
+}
+
+static int SProcDMXQueryVersion(ClientPtr client)
+{
+ int n;
+ REQUEST(xDMXQueryVersionReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xDMXQueryVersionReq);
+ return ProcDMXQueryVersion(client);
+}
+
+static int SProcDMXSync(ClientPtr client)
+{
+ int n;
+ REQUEST(xDMXSyncReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xDMXSyncReq);
+ return ProcDMXSync(client);
+}
+
+static int SProcDMXForceWindowCreation(ClientPtr client)
+{
+ int n;
+ REQUEST(xDMXForceWindowCreationReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xDMXForceWindowCreationReq);
+ swaps(&stuff->window, n);
+ return ProcDMXForceWindowCreation(client);
+}
+
+static int SProcDMXGetScreenCount(ClientPtr client)
+{
+ int n;
+ REQUEST(xDMXGetScreenCountReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xDMXGetScreenCountReq);
+ return ProcDMXGetScreenCount(client);
+}
+
+static int SProcDMXGetScreenAttributes(ClientPtr client)
+{
+ int n;
+ REQUEST(xDMXGetScreenAttributesReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xDMXGetScreenAttributesReq);
+ swapl(&stuff->physicalScreen, n);
+ return ProcDMXGetScreenAttributes(client);
+}
+
+static int SProcDMXChangeScreensAttributes(ClientPtr client)
+{
+ int n;
+ REQUEST(xDMXChangeScreensAttributesReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xDMXGetScreenAttributesReq);
+ swapl(&stuff->screenCount, n);
+ swapl(&stuff->maskCount, n);
+ SwapRestL(stuff);
+ return ProcDMXGetScreenAttributes(client);
+}
+
+static int SProcDMXAddScreen(ClientPtr client)
+{
+ int n;
+ int paddedLength;
+ REQUEST(xDMXAddScreenReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xDMXAddScreenReq);
+ swapl(&stuff->displayNameLength, n);
+ swapl(&stuff->valueMask, n);
+ paddedLength = pad_to_int32(stuff->displayNameLength);
+ SwapLongs((CARD32 *)(stuff+1), LengthRestL(stuff) - paddedLength/4);
+ return ProcDMXAddScreen(client);
+}
+
+static int SProcDMXRemoveScreen(ClientPtr client)
+{
+ int n;
+ REQUEST(xDMXRemoveScreenReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xDMXRemoveScreenReq);
+ swapl(&stuff->physicalScreen, n);
+ return ProcDMXRemoveScreen(client);
+}
+
+static int SProcDMXGetWindowAttributes(ClientPtr client)
+{
+ int n;
+ REQUEST(xDMXGetWindowAttributesReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xDMXGetWindowAttributesReq);
+ swapl(&stuff->window, n);
+ return ProcDMXGetWindowAttributes(client);
+}
+
+static int SProcDMXGetDesktopAttributes(ClientPtr client)
+{
+ int n;
+ REQUEST(xDMXGetDesktopAttributesReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xDMXGetDesktopAttributesReq);
+ return ProcDMXGetDesktopAttributes(client);
+}
+
+static int SProcDMXChangeDesktopAttributes(ClientPtr client)
+{
+ int n;
+ REQUEST(xDMXChangeDesktopAttributesReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xDMXChangeDesktopAttributesReq);
+ swapl(&stuff->valueMask, n);
+ SwapRestL(stuff);
+ return ProcDMXChangeDesktopAttributes(client);
+}
+
+static int SProcDMXGetInputCount(ClientPtr client)
+{
+ int n;
+ REQUEST(xDMXGetInputCountReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xDMXGetInputCountReq);
+ return ProcDMXGetInputCount(client);
+}
+
+static int SProcDMXGetInputAttributes(ClientPtr client)
+{
+ int n;
+ REQUEST(xDMXGetInputAttributesReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xDMXGetInputAttributesReq);
+ swapl(&stuff->deviceId, n);
+ return ProcDMXGetInputAttributes(client);
+}
+
+static int SProcDMXAddInput(ClientPtr client)
+{
+ int n;
+ int paddedLength;
+ REQUEST(xDMXAddInputReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xDMXAddInputReq);
+ swapl(&stuff->displayNameLength, n);
+ swapl(&stuff->valueMask, n);
+ paddedLength = pad_to_int32(stuff->displayNameLength);
+ SwapLongs((CARD32 *)(stuff+1), LengthRestL(stuff) - paddedLength/4);
+ return ProcDMXAddInput(client);
+}
+
+static int SProcDMXRemoveInput(ClientPtr client)
+{
+ int n;
+ REQUEST(xDMXRemoveInputReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xDMXRemoveInputReq);
+ swapl(&stuff->physicalId, n);
+ return ProcDMXRemoveInput(client);
+}
+
+static int SProcDMXDispatch (ClientPtr client)
+{
+ REQUEST(xReq);
+
+ switch (stuff->data) {
+ case X_DMXQueryVersion: return SProcDMXQueryVersion(client);
+ case X_DMXSync: return SProcDMXSync(client);
+ case X_DMXForceWindowCreation: return SProcDMXForceWindowCreation(client);
+ case X_DMXGetScreenCount: return SProcDMXGetScreenCount(client);
+ case X_DMXGetScreenAttributes: return SProcDMXGetScreenAttributes(client);
+ case X_DMXChangeScreensAttributes:
+ return SProcDMXChangeScreensAttributes(client);
+ case X_DMXAddScreen: return SProcDMXAddScreen(client);
+ case X_DMXRemoveScreen: return SProcDMXRemoveScreen(client);
+ case X_DMXGetWindowAttributes: return SProcDMXGetWindowAttributes(client);
+ case X_DMXGetDesktopAttributes:
+ return SProcDMXGetDesktopAttributes(client);
+ case X_DMXChangeDesktopAttributes:
+ return SProcDMXChangeDesktopAttributes(client);
+ case X_DMXGetInputCount: return SProcDMXGetInputCount(client);
+ case X_DMXGetInputAttributes: return SProcDMXGetInputAttributes(client);
+ case X_DMXAddInput: return SProcDMXAddInput(client);
+ case X_DMXRemoveInput: return SProcDMXRemoveInput(client);
+
+ case X_DMXGetScreenInformationDEPRECATED:
+ case X_DMXForceWindowCreationDEPRECATED:
+ case X_DMXReconfigureScreenDEPRECATED:
+ return BadImplementation;
+
+ default: return BadRequest;
+ }
+}
diff --git a/xorg-server/hw/dmx/dmx_glxvisuals.c b/xorg-server/hw/dmx/dmx_glxvisuals.c
index ec33468be..50a23e30f 100644
--- a/xorg-server/hw/dmx/dmx_glxvisuals.c
+++ b/xorg-server/hw/dmx/dmx_glxvisuals.c
@@ -1,601 +1,601 @@
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, 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 including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * 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
- * SILICON GRAPHICS, INC. 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 Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
-
-#include "dmx.h"
-#include <GL/glx.h>
-#include <GL/glxproto.h>
-#include <X11/extensions/Xext.h>
-#include <X11/extensions/extutil.h>
-
-#include "dmx_glxvisuals.h"
-
-__GLXvisualConfig *GetGLXVisualConfigs(Display *dpy, int screen, int *nconfigs)
-{
- xGLXGetVisualConfigsReq *req;
- xGLXGetVisualConfigsReply reply;
- __GLXvisualConfig *config, *configs;
- GLint i, j, nvisuals, nprops;
- INT32 *props, *p;
- int majorOpcode, dummy;
- int num_good_visuals;
-
- if (!XQueryExtension(dpy, "GLX", &majorOpcode, &dummy, &dummy)) {
- return(NULL);
- }
-
- /* Send the glXGetVisualConfigs request */
- LockDisplay(dpy);
- GetReq(GLXGetVisualConfigs,req);
- req->reqType = majorOpcode;
- req->glxCode = X_GLXGetVisualConfigs;
- req->screen = screen;
- if (!_XReply(dpy, (xReply*) &reply, 0, False)) {
- /* Something is busted. Punt. */
- UnlockDisplay(dpy);
- SyncHandle();
- return NULL;
- }
-
- nvisuals = (int)reply.numVisuals;
- if (!nvisuals) {
- /* This screen does not support GL rendering */
- UnlockDisplay(dpy);
- SyncHandle();
- return NULL;
- }
-
- /* Check number of properties per visual */
- nprops = (int)reply.numProps;
- if (nprops < __GLX_MIN_CONFIG_PROPS) {
- /* Huh? Not in protocol defined limits. Punt */
- UnlockDisplay(dpy);
- SyncHandle();
- return NULL;
- }
- props = (INT32*) Xmalloc(nprops * __GLX_SIZE_CARD32);
- if (!props) {
- UnlockDisplay(dpy);
- SyncHandle();
- return NULL;
- }
-
- /* Allocate memory for our config structure */
- config = (__GLXvisualConfig*)
- Xmalloc(nvisuals * sizeof(__GLXvisualConfig));
- if (!config) {
- Xfree(props);
- UnlockDisplay(dpy);
- SyncHandle();
- return NULL;
- }
- memset(config, 0, nvisuals * sizeof(__GLXvisualConfig));
- configs = config;
- num_good_visuals = 0;
-
- /* Convert config structure into our format */
- for (i=0; i<nvisuals; i++) {
-
- /* Read config structure */
- _XRead(dpy, (char *)props, (nprops * __GLX_SIZE_CARD32));
-
- /* fill in default values */
- config->visualRating = GLX_NONE_EXT;
- config->transparentPixel = GLX_NONE_EXT;
-
- /* Copy in the first set of properties */
- config->vid = props[0];
- config->class = props[1];
-
- config->rgba = (Bool) props[2];
-
- config->redSize = props[3];
- config->greenSize = props[4];
- config->blueSize = props[5];
- config->alphaSize = props[6];
-
- config->accumRedSize = props[7];
- config->accumGreenSize = props[8];
- config->accumBlueSize = props[9];
- config->accumAlphaSize = props[10];
-
- config->doubleBuffer = (Bool) props[11];
- config->stereo = (Bool) props[12];
-
- config->bufferSize = props[13];
- config->depthSize = props[14];
- config->stencilSize = props[15];
-
- config->auxBuffers = props[16];
- config->level = props[17];
-
- /* Process remaining properties */
- p = &props[18];
- for (j=__GLX_MIN_CONFIG_PROPS; j<nprops; j+=2) {
- int property = *p++;
- int value = *p++;
-
- switch (property) {
- case GLX_SAMPLES_SGIS:
- config->multiSampleSize = value;
- break;
- case GLX_SAMPLE_BUFFERS_SGIS:
- config->nMultiSampleBuffers = value;
- break;
-
- case GLX_TRANSPARENT_TYPE_EXT:
- config->transparentPixel = value;
- break;
- case GLX_TRANSPARENT_INDEX_VALUE_EXT:
- config->transparentIndex = value;
- break;
- case GLX_TRANSPARENT_RED_VALUE_EXT:
- config->transparentRed = value;
- break;
- case GLX_TRANSPARENT_GREEN_VALUE_EXT:
- config->transparentGreen = value;
- break;
- case GLX_TRANSPARENT_BLUE_VALUE_EXT:
- config->transparentBlue = value;
- break;
- case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
- config->transparentAlpha = value;
- break;
-
- case GLX_VISUAL_CAVEAT_EXT:
- config->visualRating = value;
- break;
-
- /* visualSelectGroup is an internal used property */
- case GLX_VISUAL_SELECT_GROUP_SGIX:
- config->visualSelectGroup = value;
- break;
-
- default :
- /* Ignore properties we don't recognize */
- break;
- }
- } /* for j */
-
- /*
- // filter out overlay visuals (dmx does not support overlays)
- */
- if (config->level == 0) {
- config++;
- num_good_visuals++;
- }
-
- } /* for i */
-
- UnlockDisplay(dpy);
-
- nvisuals = num_good_visuals;
-
- config = configs;
- for (i=0; i<nvisuals; i++) {
- /* XXX hack to fill-in mask info (need a better way to do this) */
- {
- XVisualInfo *vis, template;
- int n;
-
- template.screen = screen;
- template.visualid = config->vid;
- vis = XGetVisualInfo(dpy, VisualScreenMask|VisualIDMask,
- &template, &n);
-
- if (vis != NULL) {
- config->redMask = vis->red_mask;
- config->greenMask = vis->green_mask;
- config->blueMask = vis->blue_mask;
- config->alphaMask = 0; /* XXX */
- free(vis);
- }
- }
- config++;
- } /* for i */
-
- XFree(props);
- SyncHandle();
-
- *nconfigs = nvisuals;
- return( configs );
-}
-
-
-__GLXFBConfig *GetGLXFBConfigs(Display *dpy, int glxMajorOpcode, int *nconfigs)
-{
- xGLXGetFBConfigsReq *req;
- xGLXGetFBConfigsReply reply;
- __GLXFBConfig *config, *fbconfigs;
- GLint i, j, numFBConfigs, numAttribs;
- INT32 *attrs, *p;
- int screen = DefaultScreen( dpy );
- int numValidConfigs = 0;
-
- /* Send the glXGetFBConfigs request */
- LockDisplay(dpy);
- GetReq(GLXGetFBConfigs, req);
- req->reqType = glxMajorOpcode;
- req->glxCode = X_GLXGetFBConfigs;
- req->screen = screen;
-
- *nconfigs = 0;
-
- if (!_XReply(dpy, (xReply*) &reply, 0, False)) {
- /* Something is busted. Punt. */
- UnlockDisplay(dpy);
- SyncHandle();
- return NULL;
- }
-
- numFBConfigs = (int)reply.numFBConfigs;
- if (!numFBConfigs) {
- /* This screen does not support GL rendering */
- UnlockDisplay(dpy);
- SyncHandle();
- return NULL;
- }
-
- numAttribs = (int)reply.numAttribs;
- if (!numAttribs) {
- UnlockDisplay(dpy);
- SyncHandle();
- return NULL;
- }
-
- attrs = (INT32*) Xmalloc(2*numAttribs * __GLX_SIZE_CARD32);
- if (!attrs) {
- UnlockDisplay(dpy);
- SyncHandle();
- return NULL;
- }
-
- /* Allocate memory for our config structure */
- config = (__GLXFBConfig*)
- Xmalloc(numFBConfigs * sizeof(__GLXFBConfig));
- if (!config) {
- Xfree(attrs);
- UnlockDisplay(dpy);
- SyncHandle();
- return NULL;
- }
- memset(config, 0, numFBConfigs * sizeof(__GLXFBConfig));
- fbconfigs = config;
-
- /* Convert attribute list into our format */
- for (i=0; i<numFBConfigs; i++) {
-
- /* Fill in default properties */
- config->transparentType = GLX_NONE_EXT;
- config->visualCaveat = GLX_NONE_EXT;
- config->minRed = 0.;
- config->maxRed = 1.;
- config->minGreen = 0.;
- config->maxGreen = 1.;
- config->minBlue = 0.;
- config->maxBlue = 1.;
- config->minAlpha = 0.;
- config->maxAlpha = 1.;
-
- /* Read attribute list */
- _XRead(dpy, (char *)attrs, (2*numAttribs * __GLX_SIZE_CARD32));
-
- p = attrs;
- for (j=0; j<numAttribs; j++) {
- int attribute = *p++;
- int value = *p++;
-
- switch (attribute) {
- /* core attributes */
- case GLX_FBCONFIG_ID:
- config->id = value;
- break;
- case GLX_BUFFER_SIZE:
- config->indexBits = value;
- break;
- case GLX_LEVEL:
- config->level = value;
- break;
- case GLX_DOUBLEBUFFER:
- config->doubleBufferMode = value;
- break;
- case GLX_STEREO:
- config->stereoMode = value;
- break;
- case GLX_AUX_BUFFERS:
- config->maxAuxBuffers = value;
- break;
- case GLX_RED_SIZE:
- config->redBits = value;
- break;
- case GLX_GREEN_SIZE:
- config->greenBits = value;
- break;
- case GLX_BLUE_SIZE:
- config->blueBits = value;
- break;
- case GLX_ALPHA_SIZE:
- config->alphaBits = value;
- break;
- case GLX_DEPTH_SIZE:
- config->depthBits = value;
- break;
- case GLX_STENCIL_SIZE:
- config->stencilBits = value;
- break;
- case GLX_ACCUM_RED_SIZE:
- config->accumRedBits = value;
- break;
- case GLX_ACCUM_GREEN_SIZE:
- config->accumGreenBits = value;
- break;
- case GLX_ACCUM_BLUE_SIZE:
- config->accumBlueBits = value;
- break;
- case GLX_ACCUM_ALPHA_SIZE:
- config->accumAlphaBits = value;
- break;
- case GLX_RENDER_TYPE:
- config->renderType = value;
- break;
- case GLX_DRAWABLE_TYPE:
- config->drawableType = value;
- break;
- case GLX_X_VISUAL_TYPE:
- config->visualType = value;
- break;
- case GLX_CONFIG_CAVEAT:
- config->visualCaveat = value;
- break;
- case GLX_TRANSPARENT_TYPE:
- config->transparentType = value;
- break;
- case GLX_TRANSPARENT_INDEX_VALUE:
- config->transparentIndex = value;
- break;
- case GLX_TRANSPARENT_RED_VALUE:
- config->transparentRed = value;
- break;
- case GLX_TRANSPARENT_GREEN_VALUE:
- config->transparentGreen = value;
- break;
- case GLX_TRANSPARENT_BLUE_VALUE:
- config->transparentBlue = value;
- break;
- case GLX_TRANSPARENT_ALPHA_VALUE:
- config->transparentAlpha = value;
- break;
- case GLX_MAX_PBUFFER_WIDTH:
- config->maxPbufferWidth = value;
- break;
- case GLX_MAX_PBUFFER_HEIGHT:
- config->maxPbufferHeight = value;
- break;
- case GLX_MAX_PBUFFER_PIXELS:
- config->maxPbufferPixels = value;
- break;
- case GLX_VISUAL_ID:
- config->associatedVisualId = value;
- break;
-
- /* visualSelectGroup is an internal used property */
- case GLX_VISUAL_SELECT_GROUP_SGIX:
- config->visualSelectGroup = value;
- break;
-
- /* SGIS_multisample attributes */
- case GLX_SAMPLES_SGIS:
- config->multiSampleSize = value;
- break;
- case GLX_SAMPLE_BUFFERS_SGIS:
- config->nMultiSampleBuffers = value;
- break;
-
- /* SGIX_pbuffer specific attributes */
- case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX:
- config->optimalPbufferWidth = value;
- break;
- case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX:
- config->optimalPbufferHeight = value;
- break;
-
- default:
- /* Ignore attributes we don't recognize */
- break;
- }
- } /* for j */
-
- /* Fill in derived values */
- config->screen = screen;
-
- config->rgbMode = config->renderType & GLX_RGBA_BIT;
- config->colorIndexMode = !config->rgbMode;
-
- config->haveAccumBuffer =
- config->accumRedBits > 0 ||
- config->accumGreenBits > 0 ||
- config->accumBlueBits > 0;
- /* Can't have alpha without color */
-
- config->haveDepthBuffer = config->depthBits > 0;
- config->haveStencilBuffer = config->stencilBits > 0;
-
- /* overlay visuals are not valid for now */
- if (!config->level) {
- config++;
- numValidConfigs++;
- }
-
- } /* for i */
- UnlockDisplay(dpy);
-
- config = fbconfigs;
- for (i=0; i<numValidConfigs; i++) {
-
- /* XXX hack to fill-in mask info (need a better way to do this) */
- if (config->associatedVisualId != 0) {
- XVisualInfo *vis, template;
- int n;
-
- template.screen = screen;
- template.visualid = config->associatedVisualId;
- vis = XGetVisualInfo(dpy, VisualScreenMask|VisualIDMask,
- &template, &n);
-
- if (vis != NULL) {
- config->redMask = (GLuint)vis->red_mask;
- config->greenMask = (GLuint)vis->green_mask;
- config->blueMask = (GLuint)vis->blue_mask;
- config->alphaMask = 0; /* XXX */
- free(vis);
- }
- }
-
- config++;
- } /* for i */
-
- XFree(attrs);
- SyncHandle();
-
- *nconfigs = numValidConfigs;
- return fbconfigs;
-}
-
-__GLXvisualConfig *
-GetGLXVisualConfigsFromFBConfigs(__GLXFBConfig *fbconfigs, int nfbconfigs,
- XVisualInfo *visuals, int nvisuals,
- __GLXvisualConfig *glxConfigs, int nGlxConfigs,
- int *nconfigs)
-{
- __GLXvisualConfig *configs = NULL;
- int i;
-
- if (!fbconfigs || !nfbconfigs || !nconfigs) return(NULL);
- *nconfigs = 0;
-
- /* Allocate memory for our config structure */
- configs = (__GLXvisualConfig*)
- Xmalloc(nfbconfigs * sizeof(__GLXvisualConfig));
- if (!configs) {
- return NULL;
- }
- memset(configs, 0, nfbconfigs * sizeof(__GLXvisualConfig));
-
- for (i=0; i<nfbconfigs; i++) {
- __GLXFBConfig *fbcfg = &fbconfigs[i];
-
- if (fbcfg->associatedVisualId > 0) {
- __GLXvisualConfig *cfg = configs + (*nconfigs);
- int j;
- XVisualInfo *vinfo = NULL;
-
- for (j=0; j<nvisuals; j++) {
- if (visuals[j].visualid == fbcfg->associatedVisualId) {
- vinfo = &visuals[j];
- break;
- }
- }
- if (!vinfo) continue;
-
- /* skip 16 bit colormap visuals */
- if (vinfo->depth == 16 &&
- vinfo->class != TrueColor &&
- vinfo->class != DirectColor ) {
- continue;
- }
-
- (*nconfigs)++;
-
- /*
- * if the same visualid exists in the glx configs,
- * copy the glx attributes from the glx config
- */
- for (j=0; j<nGlxConfigs; j++) {
- if (glxConfigs[j].vid == vinfo->visualid)
- break;
- }
- if (j < nGlxConfigs) {
- memcpy(cfg, &glxConfigs[j], sizeof(__GLXvisualConfig) );
- continue;
- }
-
- /*
- * make glx attributes from the FB config attributes
- */
- cfg->vid = fbcfg->associatedVisualId;
- cfg->class = vinfo->class;
- cfg->rgba = !(fbcfg->renderType & GLX_COLOR_INDEX_BIT_SGIX);
- cfg->redSize = fbcfg->redBits;
- cfg->greenSize = fbcfg->greenBits;
- cfg->blueSize = fbcfg->blueBits;
- cfg->alphaSize = fbcfg->alphaBits;
- cfg->redMask = fbcfg->redMask;
- cfg->greenMask = fbcfg->greenMask;
- cfg->blueMask = fbcfg->blueMask;
- cfg->alphaMask = fbcfg->alphaMask;
- cfg->accumRedSize = fbcfg->accumRedBits;
- cfg->accumGreenSize = fbcfg->accumGreenBits;
- cfg->accumBlueSize = fbcfg->accumBlueBits;
- cfg->accumAlphaSize = fbcfg->accumAlphaBits;
- cfg->doubleBuffer = fbcfg->doubleBufferMode;
- cfg->stereo = fbcfg->stereoMode;
- if (vinfo->class == TrueColor || vinfo->class == DirectColor) {
- cfg->bufferSize = (fbcfg->rgbMode ? (fbcfg->redBits +
- fbcfg->greenBits +
- fbcfg->blueBits +
- fbcfg->alphaBits)
- : fbcfg->indexBits );
- }
- else {
- cfg->bufferSize = vinfo->depth;
- }
- cfg->depthSize = fbcfg->depthBits;
- cfg->stencilSize = fbcfg->stencilBits;
- cfg->auxBuffers = fbcfg->maxAuxBuffers;
- cfg->level = fbcfg->level;
- cfg->visualRating = fbcfg->visualCaveat;
- cfg->transparentPixel = fbcfg->transparentType;
- cfg->transparentRed = fbcfg->transparentRed;
- cfg->transparentGreen = fbcfg->transparentGreen;
- cfg->transparentBlue = fbcfg->transparentBlue;
- cfg->transparentAlpha = fbcfg->transparentAlpha;
- cfg->transparentIndex = fbcfg->transparentIndex;
- cfg->multiSampleSize = fbcfg->multiSampleSize;
- cfg->nMultiSampleBuffers = fbcfg->nMultiSampleBuffers;
- cfg->visualSelectGroup = fbcfg->visualSelectGroup;
- }
- }
-
- return( configs );
-}
-
+/*
+ * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
+ * Copyright (C) 1991-2000 Silicon Graphics, 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 including the dates of first publication and
+ * either this permission notice or a reference to
+ * http://oss.sgi.com/projects/FreeB/
+ * 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
+ * SILICON GRAPHICS, INC. 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 Silicon Graphics, Inc.
+ * shall not be used in advertising or otherwise to promote the sale, use or
+ * other dealings in this Software without prior written authorization from
+ * Silicon Graphics, Inc.
+ */
+
+#ifdef HAVE_DMX_CONFIG_H
+#include <dmx-config.h>
+#endif
+
+#include "dmx.h"
+#include <GL/glx.h>
+#include <GL/glxproto.h>
+#include <X11/extensions/Xext.h>
+#include <X11/extensions/extutil.h>
+
+#include "dmx_glxvisuals.h"
+
+__GLXvisualConfig *GetGLXVisualConfigs(Display *dpy, int screen, int *nconfigs)
+{
+ xGLXGetVisualConfigsReq *req;
+ xGLXGetVisualConfigsReply reply;
+ __GLXvisualConfig *config, *configs;
+ GLint i, j, nvisuals, nprops;
+ INT32 *props, *p;
+ int majorOpcode, dummy;
+ int num_good_visuals;
+
+ if (!XQueryExtension(dpy, "GLX", &majorOpcode, &dummy, &dummy)) {
+ return(NULL);
+ }
+
+ /* Send the glXGetVisualConfigs request */
+ LockDisplay(dpy);
+ GetReq(GLXGetVisualConfigs,req);
+ req->reqType = majorOpcode;
+ req->glxCode = X_GLXGetVisualConfigs;
+ req->screen = screen;
+ if (!_XReply(dpy, (xReply*) &reply, 0, False)) {
+ /* Something is busted. Punt. */
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return NULL;
+ }
+
+ nvisuals = (int)reply.numVisuals;
+ if (!nvisuals) {
+ /* This screen does not support GL rendering */
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return NULL;
+ }
+
+ /* Check number of properties per visual */
+ nprops = (int)reply.numProps;
+ if (nprops < __GLX_MIN_CONFIG_PROPS) {
+ /* Huh? Not in protocol defined limits. Punt */
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return NULL;
+ }
+ props = (INT32*) Xmalloc(nprops * __GLX_SIZE_CARD32);
+ if (!props) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return NULL;
+ }
+
+ /* Allocate memory for our config structure */
+ config = (__GLXvisualConfig*)
+ Xmalloc(nvisuals * sizeof(__GLXvisualConfig));
+ if (!config) {
+ free(props);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return NULL;
+ }
+ memset(config, 0, nvisuals * sizeof(__GLXvisualConfig));
+ configs = config;
+ num_good_visuals = 0;
+
+ /* Convert config structure into our format */
+ for (i=0; i<nvisuals; i++) {
+
+ /* Read config structure */
+ _XRead(dpy, (char *)props, (nprops * __GLX_SIZE_CARD32));
+
+ /* fill in default values */
+ config->visualRating = GLX_NONE_EXT;
+ config->transparentPixel = GLX_NONE_EXT;
+
+ /* Copy in the first set of properties */
+ config->vid = props[0];
+ config->class = props[1];
+
+ config->rgba = (Bool) props[2];
+
+ config->redSize = props[3];
+ config->greenSize = props[4];
+ config->blueSize = props[5];
+ config->alphaSize = props[6];
+
+ config->accumRedSize = props[7];
+ config->accumGreenSize = props[8];
+ config->accumBlueSize = props[9];
+ config->accumAlphaSize = props[10];
+
+ config->doubleBuffer = (Bool) props[11];
+ config->stereo = (Bool) props[12];
+
+ config->bufferSize = props[13];
+ config->depthSize = props[14];
+ config->stencilSize = props[15];
+
+ config->auxBuffers = props[16];
+ config->level = props[17];
+
+ /* Process remaining properties */
+ p = &props[18];
+ for (j=__GLX_MIN_CONFIG_PROPS; j<nprops; j+=2) {
+ int property = *p++;
+ int value = *p++;
+
+ switch (property) {
+ case GLX_SAMPLES_SGIS:
+ config->multiSampleSize = value;
+ break;
+ case GLX_SAMPLE_BUFFERS_SGIS:
+ config->nMultiSampleBuffers = value;
+ break;
+
+ case GLX_TRANSPARENT_TYPE_EXT:
+ config->transparentPixel = value;
+ break;
+ case GLX_TRANSPARENT_INDEX_VALUE_EXT:
+ config->transparentIndex = value;
+ break;
+ case GLX_TRANSPARENT_RED_VALUE_EXT:
+ config->transparentRed = value;
+ break;
+ case GLX_TRANSPARENT_GREEN_VALUE_EXT:
+ config->transparentGreen = value;
+ break;
+ case GLX_TRANSPARENT_BLUE_VALUE_EXT:
+ config->transparentBlue = value;
+ break;
+ case GLX_TRANSPARENT_ALPHA_VALUE_EXT:
+ config->transparentAlpha = value;
+ break;
+
+ case GLX_VISUAL_CAVEAT_EXT:
+ config->visualRating = value;
+ break;
+
+ /* visualSelectGroup is an internal used property */
+ case GLX_VISUAL_SELECT_GROUP_SGIX:
+ config->visualSelectGroup = value;
+ break;
+
+ default :
+ /* Ignore properties we don't recognize */
+ break;
+ }
+ } /* for j */
+
+ /*
+ // filter out overlay visuals (dmx does not support overlays)
+ */
+ if (config->level == 0) {
+ config++;
+ num_good_visuals++;
+ }
+
+ } /* for i */
+
+ UnlockDisplay(dpy);
+
+ nvisuals = num_good_visuals;
+
+ config = configs;
+ for (i=0; i<nvisuals; i++) {
+ /* XXX hack to fill-in mask info (need a better way to do this) */
+ {
+ XVisualInfo *vis, template;
+ int n;
+
+ template.screen = screen;
+ template.visualid = config->vid;
+ vis = XGetVisualInfo(dpy, VisualScreenMask|VisualIDMask,
+ &template, &n);
+
+ if (vis != NULL) {
+ config->redMask = vis->red_mask;
+ config->greenMask = vis->green_mask;
+ config->blueMask = vis->blue_mask;
+ config->alphaMask = 0; /* XXX */
+ free(vis);
+ }
+ }
+ config++;
+ } /* for i */
+
+ XFree(props);
+ SyncHandle();
+
+ *nconfigs = nvisuals;
+ return( configs );
+}
+
+
+__GLXFBConfig *GetGLXFBConfigs(Display *dpy, int glxMajorOpcode, int *nconfigs)
+{
+ xGLXGetFBConfigsReq *req;
+ xGLXGetFBConfigsReply reply;
+ __GLXFBConfig *config, *fbconfigs;
+ GLint i, j, numFBConfigs, numAttribs;
+ INT32 *attrs, *p;
+ int screen = DefaultScreen( dpy );
+ int numValidConfigs = 0;
+
+ /* Send the glXGetFBConfigs request */
+ LockDisplay(dpy);
+ GetReq(GLXGetFBConfigs, req);
+ req->reqType = glxMajorOpcode;
+ req->glxCode = X_GLXGetFBConfigs;
+ req->screen = screen;
+
+ *nconfigs = 0;
+
+ if (!_XReply(dpy, (xReply*) &reply, 0, False)) {
+ /* Something is busted. Punt. */
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return NULL;
+ }
+
+ numFBConfigs = (int)reply.numFBConfigs;
+ if (!numFBConfigs) {
+ /* This screen does not support GL rendering */
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return NULL;
+ }
+
+ numAttribs = (int)reply.numAttribs;
+ if (!numAttribs) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return NULL;
+ }
+
+ attrs = (INT32*) Xmalloc(2*numAttribs * __GLX_SIZE_CARD32);
+ if (!attrs) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return NULL;
+ }
+
+ /* Allocate memory for our config structure */
+ config = (__GLXFBConfig*)
+ Xmalloc(numFBConfigs * sizeof(__GLXFBConfig));
+ if (!config) {
+ free(attrs);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return NULL;
+ }
+ memset(config, 0, numFBConfigs * sizeof(__GLXFBConfig));
+ fbconfigs = config;
+
+ /* Convert attribute list into our format */
+ for (i=0; i<numFBConfigs; i++) {
+
+ /* Fill in default properties */
+ config->transparentType = GLX_NONE_EXT;
+ config->visualCaveat = GLX_NONE_EXT;
+ config->minRed = 0.;
+ config->maxRed = 1.;
+ config->minGreen = 0.;
+ config->maxGreen = 1.;
+ config->minBlue = 0.;
+ config->maxBlue = 1.;
+ config->minAlpha = 0.;
+ config->maxAlpha = 1.;
+
+ /* Read attribute list */
+ _XRead(dpy, (char *)attrs, (2*numAttribs * __GLX_SIZE_CARD32));
+
+ p = attrs;
+ for (j=0; j<numAttribs; j++) {
+ int attribute = *p++;
+ int value = *p++;
+
+ switch (attribute) {
+ /* core attributes */
+ case GLX_FBCONFIG_ID:
+ config->id = value;
+ break;
+ case GLX_BUFFER_SIZE:
+ config->indexBits = value;
+ break;
+ case GLX_LEVEL:
+ config->level = value;
+ break;
+ case GLX_DOUBLEBUFFER:
+ config->doubleBufferMode = value;
+ break;
+ case GLX_STEREO:
+ config->stereoMode = value;
+ break;
+ case GLX_AUX_BUFFERS:
+ config->maxAuxBuffers = value;
+ break;
+ case GLX_RED_SIZE:
+ config->redBits = value;
+ break;
+ case GLX_GREEN_SIZE:
+ config->greenBits = value;
+ break;
+ case GLX_BLUE_SIZE:
+ config->blueBits = value;
+ break;
+ case GLX_ALPHA_SIZE:
+ config->alphaBits = value;
+ break;
+ case GLX_DEPTH_SIZE:
+ config->depthBits = value;
+ break;
+ case GLX_STENCIL_SIZE:
+ config->stencilBits = value;
+ break;
+ case GLX_ACCUM_RED_SIZE:
+ config->accumRedBits = value;
+ break;
+ case GLX_ACCUM_GREEN_SIZE:
+ config->accumGreenBits = value;
+ break;
+ case GLX_ACCUM_BLUE_SIZE:
+ config->accumBlueBits = value;
+ break;
+ case GLX_ACCUM_ALPHA_SIZE:
+ config->accumAlphaBits = value;
+ break;
+ case GLX_RENDER_TYPE:
+ config->renderType = value;
+ break;
+ case GLX_DRAWABLE_TYPE:
+ config->drawableType = value;
+ break;
+ case GLX_X_VISUAL_TYPE:
+ config->visualType = value;
+ break;
+ case GLX_CONFIG_CAVEAT:
+ config->visualCaveat = value;
+ break;
+ case GLX_TRANSPARENT_TYPE:
+ config->transparentType = value;
+ break;
+ case GLX_TRANSPARENT_INDEX_VALUE:
+ config->transparentIndex = value;
+ break;
+ case GLX_TRANSPARENT_RED_VALUE:
+ config->transparentRed = value;
+ break;
+ case GLX_TRANSPARENT_GREEN_VALUE:
+ config->transparentGreen = value;
+ break;
+ case GLX_TRANSPARENT_BLUE_VALUE:
+ config->transparentBlue = value;
+ break;
+ case GLX_TRANSPARENT_ALPHA_VALUE:
+ config->transparentAlpha = value;
+ break;
+ case GLX_MAX_PBUFFER_WIDTH:
+ config->maxPbufferWidth = value;
+ break;
+ case GLX_MAX_PBUFFER_HEIGHT:
+ config->maxPbufferHeight = value;
+ break;
+ case GLX_MAX_PBUFFER_PIXELS:
+ config->maxPbufferPixels = value;
+ break;
+ case GLX_VISUAL_ID:
+ config->associatedVisualId = value;
+ break;
+
+ /* visualSelectGroup is an internal used property */
+ case GLX_VISUAL_SELECT_GROUP_SGIX:
+ config->visualSelectGroup = value;
+ break;
+
+ /* SGIS_multisample attributes */
+ case GLX_SAMPLES_SGIS:
+ config->multiSampleSize = value;
+ break;
+ case GLX_SAMPLE_BUFFERS_SGIS:
+ config->nMultiSampleBuffers = value;
+ break;
+
+ /* SGIX_pbuffer specific attributes */
+ case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX:
+ config->optimalPbufferWidth = value;
+ break;
+ case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX:
+ config->optimalPbufferHeight = value;
+ break;
+
+ default:
+ /* Ignore attributes we don't recognize */
+ break;
+ }
+ } /* for j */
+
+ /* Fill in derived values */
+ config->screen = screen;
+
+ config->rgbMode = config->renderType & GLX_RGBA_BIT;
+ config->colorIndexMode = !config->rgbMode;
+
+ config->haveAccumBuffer =
+ config->accumRedBits > 0 ||
+ config->accumGreenBits > 0 ||
+ config->accumBlueBits > 0;
+ /* Can't have alpha without color */
+
+ config->haveDepthBuffer = config->depthBits > 0;
+ config->haveStencilBuffer = config->stencilBits > 0;
+
+ /* overlay visuals are not valid for now */
+ if (!config->level) {
+ config++;
+ numValidConfigs++;
+ }
+
+ } /* for i */
+ UnlockDisplay(dpy);
+
+ config = fbconfigs;
+ for (i=0; i<numValidConfigs; i++) {
+
+ /* XXX hack to fill-in mask info (need a better way to do this) */
+ if (config->associatedVisualId != 0) {
+ XVisualInfo *vis, template;
+ int n;
+
+ template.screen = screen;
+ template.visualid = config->associatedVisualId;
+ vis = XGetVisualInfo(dpy, VisualScreenMask|VisualIDMask,
+ &template, &n);
+
+ if (vis != NULL) {
+ config->redMask = (GLuint)vis->red_mask;
+ config->greenMask = (GLuint)vis->green_mask;
+ config->blueMask = (GLuint)vis->blue_mask;
+ config->alphaMask = 0; /* XXX */
+ free(vis);
+ }
+ }
+
+ config++;
+ } /* for i */
+
+ XFree(attrs);
+ SyncHandle();
+
+ *nconfigs = numValidConfigs;
+ return fbconfigs;
+}
+
+__GLXvisualConfig *
+GetGLXVisualConfigsFromFBConfigs(__GLXFBConfig *fbconfigs, int nfbconfigs,
+ XVisualInfo *visuals, int nvisuals,
+ __GLXvisualConfig *glxConfigs, int nGlxConfigs,
+ int *nconfigs)
+{
+ __GLXvisualConfig *configs = NULL;
+ int i;
+
+ if (!fbconfigs || !nfbconfigs || !nconfigs) return(NULL);
+ *nconfigs = 0;
+
+ /* Allocate memory for our config structure */
+ configs = (__GLXvisualConfig*)
+ Xmalloc(nfbconfigs * sizeof(__GLXvisualConfig));
+ if (!configs) {
+ return NULL;
+ }
+ memset(configs, 0, nfbconfigs * sizeof(__GLXvisualConfig));
+
+ for (i=0; i<nfbconfigs; i++) {
+ __GLXFBConfig *fbcfg = &fbconfigs[i];
+
+ if (fbcfg->associatedVisualId > 0) {
+ __GLXvisualConfig *cfg = configs + (*nconfigs);
+ int j;
+ XVisualInfo *vinfo = NULL;
+
+ for (j=0; j<nvisuals; j++) {
+ if (visuals[j].visualid == fbcfg->associatedVisualId) {
+ vinfo = &visuals[j];
+ break;
+ }
+ }
+ if (!vinfo) continue;
+
+ /* skip 16 bit colormap visuals */
+ if (vinfo->depth == 16 &&
+ vinfo->class != TrueColor &&
+ vinfo->class != DirectColor ) {
+ continue;
+ }
+
+ (*nconfigs)++;
+
+ /*
+ * if the same visualid exists in the glx configs,
+ * copy the glx attributes from the glx config
+ */
+ for (j=0; j<nGlxConfigs; j++) {
+ if (glxConfigs[j].vid == vinfo->visualid)
+ break;
+ }
+ if (j < nGlxConfigs) {
+ memcpy(cfg, &glxConfigs[j], sizeof(__GLXvisualConfig) );
+ continue;
+ }
+
+ /*
+ * make glx attributes from the FB config attributes
+ */
+ cfg->vid = fbcfg->associatedVisualId;
+ cfg->class = vinfo->class;
+ cfg->rgba = !(fbcfg->renderType & GLX_COLOR_INDEX_BIT_SGIX);
+ cfg->redSize = fbcfg->redBits;
+ cfg->greenSize = fbcfg->greenBits;
+ cfg->blueSize = fbcfg->blueBits;
+ cfg->alphaSize = fbcfg->alphaBits;
+ cfg->redMask = fbcfg->redMask;
+ cfg->greenMask = fbcfg->greenMask;
+ cfg->blueMask = fbcfg->blueMask;
+ cfg->alphaMask = fbcfg->alphaMask;
+ cfg->accumRedSize = fbcfg->accumRedBits;
+ cfg->accumGreenSize = fbcfg->accumGreenBits;
+ cfg->accumBlueSize = fbcfg->accumBlueBits;
+ cfg->accumAlphaSize = fbcfg->accumAlphaBits;
+ cfg->doubleBuffer = fbcfg->doubleBufferMode;
+ cfg->stereo = fbcfg->stereoMode;
+ if (vinfo->class == TrueColor || vinfo->class == DirectColor) {
+ cfg->bufferSize = (fbcfg->rgbMode ? (fbcfg->redBits +
+ fbcfg->greenBits +
+ fbcfg->blueBits +
+ fbcfg->alphaBits)
+ : fbcfg->indexBits );
+ }
+ else {
+ cfg->bufferSize = vinfo->depth;
+ }
+ cfg->depthSize = fbcfg->depthBits;
+ cfg->stencilSize = fbcfg->stencilBits;
+ cfg->auxBuffers = fbcfg->maxAuxBuffers;
+ cfg->level = fbcfg->level;
+ cfg->visualRating = fbcfg->visualCaveat;
+ cfg->transparentPixel = fbcfg->transparentType;
+ cfg->transparentRed = fbcfg->transparentRed;
+ cfg->transparentGreen = fbcfg->transparentGreen;
+ cfg->transparentBlue = fbcfg->transparentBlue;
+ cfg->transparentAlpha = fbcfg->transparentAlpha;
+ cfg->transparentIndex = fbcfg->transparentIndex;
+ cfg->multiSampleSize = fbcfg->multiSampleSize;
+ cfg->nMultiSampleBuffers = fbcfg->nMultiSampleBuffers;
+ cfg->visualSelectGroup = fbcfg->visualSelectGroup;
+ }
+ }
+
+ return( configs );
+}
+
diff --git a/xorg-server/hw/dmx/dmxcmap.c b/xorg-server/hw/dmx/dmxcmap.c
index 4aa586aff..5a56afda2 100644
--- a/xorg-server/hw/dmx/dmxcmap.c
+++ b/xorg-server/hw/dmx/dmxcmap.c
@@ -1,212 +1,212 @@
-/*
- * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina.
- *
- * 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 on 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 (including the
- * next paragraph) 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
- * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
- * 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.
- */
-
-/*
- * Authors:
- * Kevin E. Martin <kem@redhat.com>
- *
- */
-
-/** \file
- * Colormap support. */
-
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
-
-#include "dmx.h"
-#include "dmxlog.h"
-#include "dmxsync.h"
-#include "dmxcmap.h"
-#include "dmxvisual.h"
-
-#include "micmap.h"
-
-static Bool dmxAllocateColormapPrivates(ColormapPtr pColormap)
-{
- dmxColormapPrivPtr pCmapPriv;
-
- pCmapPriv = (dmxColormapPrivPtr)xalloc(sizeof(*pCmapPriv));
- if (!pCmapPriv)
- return FALSE;
- pCmapPriv->cmap = (Colormap)0;
-
- DMX_SET_COLORMAP_PRIV(pColormap, pCmapPriv);
-
- return TRUE;
-}
-
-/** Create \a pColormap on the back-end server. */
-Bool dmxBECreateColormap(ColormapPtr pColormap)
-{
- ScreenPtr pScreen = pColormap->pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxColormapPrivPtr pCmapPriv = DMX_GET_COLORMAP_PRIV(pColormap);
- VisualPtr pVisual = pColormap->pVisual;
- Visual *visual = dmxLookupVisual(pScreen, pVisual);
-
- if (visual) {
- pCmapPriv->cmap = XCreateColormap(dmxScreen->beDisplay,
- dmxScreen->scrnWin,
- visual,
- (pVisual->class & DynamicClass ?
- AllocAll : AllocNone));
- return (pCmapPriv->cmap != 0);
- }
- else {
- dmxLog(dmxWarning, "dmxBECreateColormap: No visual found\n");
- return 0;
- }
-}
-
-/** Create colormap on back-end server associated with \a pColormap's
- * screen. */
-Bool dmxCreateColormap(ColormapPtr pColormap)
-{
- ScreenPtr pScreen = pColormap->pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- Bool ret = TRUE;
-
- if (!dmxAllocateColormapPrivates(pColormap))
- return FALSE;
-
- if (dmxScreen->beDisplay) {
- if (!dmxBECreateColormap(pColormap))
- return FALSE;
- }
-
- DMX_UNWRAP(CreateColormap, dmxScreen, pScreen);
- if (pScreen->CreateColormap)
- ret = pScreen->CreateColormap(pColormap);
- DMX_WRAP(CreateColormap, dmxCreateColormap, dmxScreen, pScreen);
-
- return ret;
-}
-
-/** Destroy \a pColormap on the back-end server. */
-Bool dmxBEFreeColormap(ColormapPtr pColormap)
-{
- ScreenPtr pScreen = pColormap->pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxColormapPrivPtr pCmapPriv = DMX_GET_COLORMAP_PRIV(pColormap);
-
- if (pCmapPriv->cmap) {
- XFreeColormap(dmxScreen->beDisplay, pCmapPriv->cmap);
- pCmapPriv->cmap = (Colormap)0;
- return TRUE;
- }
-
- return FALSE;
-}
-
-/** Destroy colormap on back-end server associated with \a pColormap's
- * screen. */
-void dmxDestroyColormap(ColormapPtr pColormap)
-{
- ScreenPtr pScreen = pColormap->pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxColormapPrivPtr pCmapPriv = DMX_GET_COLORMAP_PRIV(pColormap);
-
- if (dmxScreen->beDisplay)
- dmxBEFreeColormap(pColormap);
- xfree(pCmapPriv);
- DMX_SET_COLORMAP_PRIV(pColormap, NULL);
-
- DMX_UNWRAP(DestroyColormap, dmxScreen, pScreen);
- if (pScreen->DestroyColormap)
- pScreen->DestroyColormap(pColormap);
- DMX_WRAP(DestroyColormap, dmxDestroyColormap, dmxScreen, pScreen);
-}
-
-/** Install colormap on back-end server associated with \a pColormap's
- * screen. */
-void dmxInstallColormap(ColormapPtr pColormap)
-{
- ScreenPtr pScreen = pColormap->pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxColormapPrivPtr pCmapPriv = DMX_GET_COLORMAP_PRIV(pColormap);
-
- DMX_UNWRAP(InstallColormap, dmxScreen, pScreen);
- if (pScreen->InstallColormap)
- pScreen->InstallColormap(pColormap);
- DMX_WRAP(InstallColormap, dmxInstallColormap, dmxScreen, pScreen);
-
- if (dmxScreen->beDisplay) {
- XInstallColormap(dmxScreen->beDisplay, pCmapPriv->cmap);
- dmxSync(dmxScreen, FALSE);
- }
-}
-
-/** Store colors in \a pColormap on back-end server associated with \a
- * pColormap's screen. */
-void dmxStoreColors(ColormapPtr pColormap, int ndef, xColorItem *pdef)
-{
- ScreenPtr pScreen = pColormap->pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxColormapPrivPtr pCmapPriv = DMX_GET_COLORMAP_PRIV(pColormap);
-
- if (dmxScreen->beDisplay && (pColormap->pVisual->class & DynamicClass)) {
- XColor *color = xalloc(sizeof(*color) * ndef);
- int i;
-
- if (color) {
- for (i = 0; i < ndef; i++) {
- color[i].pixel = pdef[i].pixel;
- color[i].red = pdef[i].red;
- color[i].blue = pdef[i].blue;
- color[i].green = pdef[i].green;
- color[i].flags = pdef[i].flags;
- color[i].pad = pdef[i].pad;
- }
- XStoreColors(dmxScreen->beDisplay, pCmapPriv->cmap, color, ndef);
- xfree(color);
- } else { /* xalloc failed, so fallback */
- XColor c;
- for (i = 0; i < ndef; i++) {
- c.pixel = pdef[i].pixel;
- c.red = pdef[i].red;
- c.blue = pdef[i].blue;
- c.green = pdef[i].green;
- c.flags = pdef[i].flags;
- c.pad = pdef[i].pad;
- XStoreColor(dmxScreen->beDisplay, pCmapPriv->cmap, &c);
- }
- }
- dmxSync(dmxScreen, FALSE);
- }
-
- DMX_UNWRAP(StoreColors, dmxScreen, pScreen);
- if (pScreen->StoreColors)
- pScreen->StoreColors(pColormap, ndef, pdef);
- DMX_WRAP(StoreColors, dmxStoreColors, dmxScreen, pScreen);
-}
-
-/** Create the DMX server's default colormap. */
-Bool dmxCreateDefColormap(ScreenPtr pScreen)
-{
- return miCreateDefColormap(pScreen);
-}
+/*
+ * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina.
+ *
+ * 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 on 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 (including the
+ * next paragraph) 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
+ * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
+ * 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.
+ */
+
+/*
+ * Authors:
+ * Kevin E. Martin <kem@redhat.com>
+ *
+ */
+
+/** \file
+ * Colormap support. */
+
+#ifdef HAVE_DMX_CONFIG_H
+#include <dmx-config.h>
+#endif
+
+#include "dmx.h"
+#include "dmxlog.h"
+#include "dmxsync.h"
+#include "dmxcmap.h"
+#include "dmxvisual.h"
+
+#include "micmap.h"
+
+static Bool dmxAllocateColormapPrivates(ColormapPtr pColormap)
+{
+ dmxColormapPrivPtr pCmapPriv;
+
+ pCmapPriv = (dmxColormapPrivPtr)malloc(sizeof(*pCmapPriv));
+ if (!pCmapPriv)
+ return FALSE;
+ pCmapPriv->cmap = (Colormap)0;
+
+ DMX_SET_COLORMAP_PRIV(pColormap, pCmapPriv);
+
+ return TRUE;
+}
+
+/** Create \a pColormap on the back-end server. */
+Bool dmxBECreateColormap(ColormapPtr pColormap)
+{
+ ScreenPtr pScreen = pColormap->pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxColormapPrivPtr pCmapPriv = DMX_GET_COLORMAP_PRIV(pColormap);
+ VisualPtr pVisual = pColormap->pVisual;
+ Visual *visual = dmxLookupVisual(pScreen, pVisual);
+
+ if (visual) {
+ pCmapPriv->cmap = XCreateColormap(dmxScreen->beDisplay,
+ dmxScreen->scrnWin,
+ visual,
+ (pVisual->class & DynamicClass ?
+ AllocAll : AllocNone));
+ return (pCmapPriv->cmap != 0);
+ }
+ else {
+ dmxLog(dmxWarning, "dmxBECreateColormap: No visual found\n");
+ return 0;
+ }
+}
+
+/** Create colormap on back-end server associated with \a pColormap's
+ * screen. */
+Bool dmxCreateColormap(ColormapPtr pColormap)
+{
+ ScreenPtr pScreen = pColormap->pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ Bool ret = TRUE;
+
+ if (!dmxAllocateColormapPrivates(pColormap))
+ return FALSE;
+
+ if (dmxScreen->beDisplay) {
+ if (!dmxBECreateColormap(pColormap))
+ return FALSE;
+ }
+
+ DMX_UNWRAP(CreateColormap, dmxScreen, pScreen);
+ if (pScreen->CreateColormap)
+ ret = pScreen->CreateColormap(pColormap);
+ DMX_WRAP(CreateColormap, dmxCreateColormap, dmxScreen, pScreen);
+
+ return ret;
+}
+
+/** Destroy \a pColormap on the back-end server. */
+Bool dmxBEFreeColormap(ColormapPtr pColormap)
+{
+ ScreenPtr pScreen = pColormap->pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxColormapPrivPtr pCmapPriv = DMX_GET_COLORMAP_PRIV(pColormap);
+
+ if (pCmapPriv->cmap) {
+ XFreeColormap(dmxScreen->beDisplay, pCmapPriv->cmap);
+ pCmapPriv->cmap = (Colormap)0;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/** Destroy colormap on back-end server associated with \a pColormap's
+ * screen. */
+void dmxDestroyColormap(ColormapPtr pColormap)
+{
+ ScreenPtr pScreen = pColormap->pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxColormapPrivPtr pCmapPriv = DMX_GET_COLORMAP_PRIV(pColormap);
+
+ if (dmxScreen->beDisplay)
+ dmxBEFreeColormap(pColormap);
+ free(pCmapPriv);
+ DMX_SET_COLORMAP_PRIV(pColormap, NULL);
+
+ DMX_UNWRAP(DestroyColormap, dmxScreen, pScreen);
+ if (pScreen->DestroyColormap)
+ pScreen->DestroyColormap(pColormap);
+ DMX_WRAP(DestroyColormap, dmxDestroyColormap, dmxScreen, pScreen);
+}
+
+/** Install colormap on back-end server associated with \a pColormap's
+ * screen. */
+void dmxInstallColormap(ColormapPtr pColormap)
+{
+ ScreenPtr pScreen = pColormap->pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxColormapPrivPtr pCmapPriv = DMX_GET_COLORMAP_PRIV(pColormap);
+
+ DMX_UNWRAP(InstallColormap, dmxScreen, pScreen);
+ if (pScreen->InstallColormap)
+ pScreen->InstallColormap(pColormap);
+ DMX_WRAP(InstallColormap, dmxInstallColormap, dmxScreen, pScreen);
+
+ if (dmxScreen->beDisplay) {
+ XInstallColormap(dmxScreen->beDisplay, pCmapPriv->cmap);
+ dmxSync(dmxScreen, FALSE);
+ }
+}
+
+/** Store colors in \a pColormap on back-end server associated with \a
+ * pColormap's screen. */
+void dmxStoreColors(ColormapPtr pColormap, int ndef, xColorItem *pdef)
+{
+ ScreenPtr pScreen = pColormap->pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxColormapPrivPtr pCmapPriv = DMX_GET_COLORMAP_PRIV(pColormap);
+
+ if (dmxScreen->beDisplay && (pColormap->pVisual->class & DynamicClass)) {
+ XColor *color = malloc(sizeof(*color) * ndef);
+ int i;
+
+ if (color) {
+ for (i = 0; i < ndef; i++) {
+ color[i].pixel = pdef[i].pixel;
+ color[i].red = pdef[i].red;
+ color[i].blue = pdef[i].blue;
+ color[i].green = pdef[i].green;
+ color[i].flags = pdef[i].flags;
+ color[i].pad = pdef[i].pad;
+ }
+ XStoreColors(dmxScreen->beDisplay, pCmapPriv->cmap, color, ndef);
+ free(color);
+ } else { /* xalloc failed, so fallback */
+ XColor c;
+ for (i = 0; i < ndef; i++) {
+ c.pixel = pdef[i].pixel;
+ c.red = pdef[i].red;
+ c.blue = pdef[i].blue;
+ c.green = pdef[i].green;
+ c.flags = pdef[i].flags;
+ c.pad = pdef[i].pad;
+ XStoreColor(dmxScreen->beDisplay, pCmapPriv->cmap, &c);
+ }
+ }
+ dmxSync(dmxScreen, FALSE);
+ }
+
+ DMX_UNWRAP(StoreColors, dmxScreen, pScreen);
+ if (pScreen->StoreColors)
+ pScreen->StoreColors(pColormap, ndef, pdef);
+ DMX_WRAP(StoreColors, dmxStoreColors, dmxScreen, pScreen);
+}
+
+/** Create the DMX server's default colormap. */
+Bool dmxCreateDefColormap(ScreenPtr pScreen)
+{
+ return miCreateDefColormap(pScreen);
+}
diff --git a/xorg-server/hw/dmx/dmxcursor.c b/xorg-server/hw/dmx/dmxcursor.c
index 37e66d758..2d0243343 100644
--- a/xorg-server/hw/dmx/dmxcursor.c
+++ b/xorg-server/hw/dmx/dmxcursor.c
@@ -1,985 +1,985 @@
-/*
- * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina.
- *
- * 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 on 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 (including the
- * next paragraph) 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
- * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
- * 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.
- */
-
-/*
- * Authors:
- * David H. Dawes <dawes@xfree86.org>
- * Kevin E. Martin <kem@redhat.com>
- * Rickard E. (Rik) Faith <faith@redhat.com>
- *
- */
-
-/** \file
- * This file contains code than supports cursor movement, including the
- * code that initializes and reinitializes the screen positions and
- * computes screen overlap.
- *
- * "This code is based very closely on the XFree86 equivalent
- * (xfree86/common/xf86Cursor.c)." --David Dawes.
- *
- * "This code was then extensively re-written, as explained here."
- * --Rik Faith
- *
- * The code in xf86Cursor.c used edge lists to implement the
- * CursorOffScreen function. The edge list computation was complex
- * (especially in the face of arbitrarily overlapping screens) compared
- * with the speed savings in the CursorOffScreen function. The new
- * implementation has erred on the side of correctness, readability, and
- * maintainability over efficiency. For the common (non-edge) case, the
- * dmxCursorOffScreen function does avoid a loop over all the screens.
- * When the cursor has left the screen, all the screens are searched,
- * and the first screen (in dmxScreens order) containing the cursor will
- * be returned. If run-time profiling shows that this routing is a
- * performance bottle-neck, then an edge list may have to be
- * reimplemented. An edge list algorithm is O(edges) whereas the new
- * algorithm is O(dmxNumScreens). Since edges is usually 1-3 and
- * dmxNumScreens may be 30-60 for large backend walls, this trade off
- * may be compelling.
- *
- * The xf86InitOrigins routine uses bit masks during the computation and
- * is therefore limited to the length of a word (e.g., 32 or 64 bits)
- * screens. Because Xdmx is expected to be used with a large number of
- * backend displays, this limitation was removed. The new
- * implementation has erred on the side of readability over efficiency,
- * using the dmxSL* routines to manage a screen list instead of a
- * bitmap, and a function call to decrease the length of the main
- * routine. Both algorithms are of the same order, and both are called
- * only at server generation time, so trading clarity and long-term
- * maintainability for efficiency does not seem justified in this case.
- */
-
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
-
-#define DMX_CURSOR_DEBUG 0
-
-#include "dmx.h"
-#include "dmxsync.h"
-#include "dmxcursor.h"
-#include "dmxlog.h"
-#include "dmxprop.h"
-#include "dmxinput.h"
-
-#include "mipointer.h"
-#include "windowstr.h"
-#include "globals.h"
-#include "cursorstr.h"
-#include "dixevents.h" /* For GetSpriteCursor() */
-#include "inputstr.h" /* for inputInfo.pointer */
-
-#if DMX_CURSOR_DEBUG
-#define DMXDBG0(f) dmxLog(dmxDebug,f)
-#define DMXDBG1(f,a) dmxLog(dmxDebug,f,a)
-#define DMXDBG2(f,a,b) dmxLog(dmxDebug,f,a,b)
-#define DMXDBG3(f,a,b,c) dmxLog(dmxDebug,f,a,b,c)
-#define DMXDBG4(f,a,b,c,d) dmxLog(dmxDebug,f,a,b,c,d)
-#define DMXDBG5(f,a,b,c,d,e) dmxLog(dmxDebug,f,a,b,c,d,e)
-#define DMXDBG6(f,a,b,c,d,e,g) dmxLog(dmxDebug,f,a,b,c,d,e,g)
-#define DMXDBG7(f,a,b,c,d,e,g,h) dmxLog(dmxDebug,f,a,b,c,d,e,g,h)
-#else
-#define DMXDBG0(f)
-#define DMXDBG1(f,a)
-#define DMXDBG2(f,a,b)
-#define DMXDBG3(f,a,b,c)
-#define DMXDBG4(f,a,b,c,d)
-#define DMXDBG5(f,a,b,c,d,e)
-#define DMXDBG6(f,a,b,c,d,e,g)
-#define DMXDBG7(f,a,b,c,d,e,g,h)
-#endif
-
-static int dmxCursorDoMultiCursors = 1;
-
-/** Turn off support for displaying multiple cursors on overlapped
- back-end displays. See #dmxCursorDoMultiCursors. */
-void dmxCursorNoMulti(void)
-{
- dmxCursorDoMultiCursors = 0;
-}
-
-static Bool dmxCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
-{
- DMXScreenInfo *dmxScreen;
- int i;
- int localX = *x;
- int localY = *y;
- int globalX;
- int globalY;
-
- if (screenInfo.numScreens == 1)
- return FALSE;
-
- /* On current screen? */
- dmxScreen = &dmxScreens[(*ppScreen)->myNum];
- if (localX >= 0
- && localX < dmxScreen->rootWidth
- && localY >= 0
- && localY < dmxScreen->rootHeight)
- return FALSE;
-
- /* Convert to global coordinate space */
- globalX = dmxScreen->rootXOrigin + localX;
- globalY = dmxScreen->rootYOrigin + localY;
-
- /* Is cursor on the current screen?
- * This efficiently exits this routine
- * for the most common case. */
- if (ppScreen && *ppScreen) {
- dmxScreen = &dmxScreens[(*ppScreen)->myNum];
- if (globalX >= dmxScreen->rootXOrigin
- && globalX < dmxScreen->rootXOrigin + dmxScreen->rootWidth
- && globalY >= dmxScreen->rootYOrigin
- && globalY < dmxScreen->rootYOrigin + dmxScreen->rootHeight)
- return FALSE;
- }
-
- /* Find first screen cursor is on */
- for (i = 0; i < dmxNumScreens; i++) {
- dmxScreen = &dmxScreens[i];
- if (globalX >= dmxScreen->rootXOrigin
- && globalX < dmxScreen->rootXOrigin + dmxScreen->rootWidth
- && globalY >= dmxScreen->rootYOrigin
- && globalY < dmxScreen->rootYOrigin + dmxScreen->rootHeight) {
- if (dmxScreen->index == (*ppScreen)->myNum)
- return FALSE;
- *ppScreen = screenInfo.screens[dmxScreen->index];
- *x = globalX - dmxScreen->rootXOrigin;
- *y = globalY - dmxScreen->rootYOrigin;
- return TRUE;
- }
- }
- return FALSE;
-}
-
-static void dmxCrossScreen(ScreenPtr pScreen, Bool entering)
-{
-}
-
-static void dmxWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
-{
- DMXDBG3("dmxWarpCursor(%d,%d,%d)\n", pScreen->myNum, x, y);
-#if 11 /*BP*/
- /* This call is depracated. Replace with???? */
- miPointerWarpCursor(pDev, pScreen, x, y);
-#else
- pScreen->SetCursorPosition(pDev, pScreen, x, y, FALSE);
-#endif
-}
-
-miPointerScreenFuncRec dmxPointerCursorFuncs =
-{
- dmxCursorOffScreen,
- dmxCrossScreen,
- dmxWarpCursor,
- NULL,
- NULL,
-};
-
-
-/** Create a list of screens that we'll manipulate. */
-static int *dmxSLCreate(void)
-{
- int *list = malloc(dmxNumScreens * sizeof(*list));
- int i;
-
- for (i = 0; i < dmxNumScreens; i++)
- list[i] = 1;
- return list;
-}
-
-/** Free list. */
-static void dmxSLFree(int *list)
-{
- free(list);
-}
-
-/** Find next uninitialized entry in list. */
-static int dmxSLFindNext(int *list)
-{
- int i;
- for (i = 0; i < dmxNumScreens; i++)
- if (list[i])
- return i;
- return -1;
-}
-
-/** Make one pass over all the screens and return the number updated. */
-static int dmxTryComputeScreenOrigins(int *screensLeft)
-{
- ScreenPtr pScreen;
- DMXScreenInfo *screen;
- int i, ref;
- int changed = 0;
-
- for (i = 0; i < dmxNumScreens; i++) {
- if (!screensLeft[i])
- continue;
- screen = &dmxScreens[i];
- switch (screen->where) {
- case PosAbsolute:
- dixScreenOrigins[i].x = screen->whereX;
- dixScreenOrigins[i].y = screen->whereY;
- ++changed, screensLeft[i] = 0;
- break;
- case PosRelative:
- ref = screen->whereRefScreen;
- if (screensLeft[ref])
- break;
- dixScreenOrigins[i].x = dixScreenOrigins[ref].x + screen->whereX;
- dixScreenOrigins[i].y = dixScreenOrigins[ref].y + screen->whereY;
- ++changed, screensLeft[i] = 0;
- break;
- case PosRightOf:
- ref = screen->whereRefScreen;
- if (screensLeft[ref])
- break;
- pScreen = screenInfo.screens[ref];
- dixScreenOrigins[i].x = dixScreenOrigins[ref].x + pScreen->width;
- dixScreenOrigins[i].y = dixScreenOrigins[ref].y;
- ++changed, screensLeft[i] = 0;
- break;
- case PosLeftOf:
- ref = screen->whereRefScreen;
- if (screensLeft[ref])
- break;
- pScreen = screenInfo.screens[i];
- dixScreenOrigins[i].x = dixScreenOrigins[ref].x - pScreen->width;
- dixScreenOrigins[i].y = dixScreenOrigins[ref].y;
- ++changed, screensLeft[i] = 0;
- break;
- case PosBelow:
- ref = screen->whereRefScreen;
- if (screensLeft[ref])
- break;
- pScreen = screenInfo.screens[ref];
- dixScreenOrigins[i].x = dixScreenOrigins[ref].x;
- dixScreenOrigins[i].y = dixScreenOrigins[ref].y + pScreen->height;
- ++changed, screensLeft[i] = 0;
- break;
- case PosAbove:
- ref = screen->whereRefScreen;
- if (screensLeft[ref])
- break;
- pScreen = screenInfo.screens[i];
- dixScreenOrigins[i].x = dixScreenOrigins[ref].x;
- dixScreenOrigins[i].y = dixScreenOrigins[ref].y - pScreen->height;
- ++changed, screensLeft[i] = 0;
- break;
- case PosNone:
- dmxLog(dmxFatal, "No position information for screen %d\n", i);
- }
- }
- return changed;
-}
-
-static void dmxComputeScreenOrigins(void)
-{
- int *screensLeft;
- int i, ref;
- int minX, minY;
-
- /* Compute origins based on
- * configuration information. */
- screensLeft = dmxSLCreate();
- while ((i = dmxSLFindNext(screensLeft)) >= 0) {
- while (dmxTryComputeScreenOrigins(screensLeft));
- if ((i = dmxSLFindNext(screensLeft)) >= 0) {
- /* All of the remaining screens are referencing each other.
- * Assign a value to one of them and go through again. This
- * guarantees that we will eventually terminate.
- */
- ref = dmxScreens[i].whereRefScreen;
- dixScreenOrigins[ref].x = dixScreenOrigins[ref].y = 0;
- screensLeft[ref] = 0;
- }
- }
- dmxSLFree(screensLeft);
-
-
- /* Justify the topmost and leftmost to
- * (0,0). */
- minX = dixScreenOrigins[0].x;
- minY = dixScreenOrigins[0].y;
- for (i = 1; i < dmxNumScreens; i++) { /* Compute minX, minY */
- if (dixScreenOrigins[i].x < minX)
- minX = dixScreenOrigins[i].x;
- if (dixScreenOrigins[i].y < minY)
- minY = dixScreenOrigins[i].y;
- }
- if (minX || minY) {
- for (i = 0; i < dmxNumScreens; i++) {
- dixScreenOrigins[i].x -= minX;
- dixScreenOrigins[i].y -= minY;
- }
- }
-}
-
-/** Recompute origin information in the #dmxScreens list. This is
- * called from #dmxInitOrigins. */
-void dmxReInitOrigins(void)
-{
- int i;
-
- if (dmxNumScreens > MAXSCREENS)
- dmxLog(dmxFatal, "dmxNumScreens = %d > MAXSCREENS = %d\n",
- dmxNumScreens, MAXSCREENS);
-
- for (i = 0; i < dmxNumScreens; i++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[i];
- dmxLogOutput(dmxScreen,
- "s=%dx%d%+d%+d r=%dx%d%+d%+d @%d,%d"
- " (be=%dx%d depth=%d bpp=%d)\n",
- dmxScreen->scrnWidth, dmxScreen->scrnHeight,
- dmxScreen->scrnX, dmxScreen->scrnY,
-
- dmxScreen->rootWidth, dmxScreen->rootHeight,
- dmxScreen->rootX, dmxScreen->rootY,
-
- dmxScreen->rootXOrigin, dmxScreen->rootYOrigin,
- dmxScreen->beWidth, dmxScreen->beHeight,
- dmxScreen->beDepth, dmxScreen->beBPP);
- }
-}
-
-/** Initialize screen origins (and relative position). This is called
- * for each server generation. For dynamic reconfiguration, use
- * #dmxReInitOrigins() instead. */
-void dmxInitOrigins(void)
-{
- int i;
-
- if (dmxNumScreens > MAXSCREENS)
- dmxLog(dmxFatal, "dmxNumScreens = %d > MAXSCREENS = %d\n",
- dmxNumScreens, MAXSCREENS);
-
- for (i = 0; i < dmxNumScreens; i++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[i];
- dmxLogOutput(dmxScreen,
- "(request) s=%dx%d%+d%+d r=%dx%d%+d%+d @%d,%d (%d)"
- " (be=%dx%d depth=%d bpp=%d)\n",
- dmxScreen->scrnWidth, dmxScreen->scrnHeight,
- dmxScreen->scrnX, dmxScreen->scrnY,
-
- dmxScreen->rootWidth, dmxScreen->rootHeight,
- dmxScreen->rootX, dmxScreen->rootY,
-
- dmxScreen->whereX, dmxScreen->whereY,
- dmxScreen->where,
-
- dmxScreen->beWidth, dmxScreen->beHeight,
- dmxScreen->beDepth, dmxScreen->beBPP);
- }
-
- dmxComputeScreenOrigins();
-
- for (i = 0; i < dmxNumScreens; i++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[i];
- dmxScreen->rootXOrigin = dixScreenOrigins[i].x;
- dmxScreen->rootYOrigin = dixScreenOrigins[i].y;
- }
-
- dmxReInitOrigins();
-}
-
-/** Returns non-zero if the global \a x, \a y coordinate is on the
- * screen window of the \a dmxScreen. */
-int dmxOnScreen(int x, int y, DMXScreenInfo *dmxScreen)
-{
-#if DMX_CURSOR_DEBUG > 1
- dmxLog(dmxDebug,
- "dmxOnScreen %d %d,%d (r=%dx%d%+d%+d@%d,%d s=%dx%d%+d%+d)\n",
- dmxScreen->index, x, y,
- dmxScreen->rootWidth, dmxScreen->rootHeight,
- dmxScreen->rootX, dmxScreen->rootY,
- dmxScreen->rootXOrigin, dmxScreen->rootYOrigin,
- dmxScreen->scrnWidth, dmxScreen->scrnHeight,
- dmxScreen->scrnX, dmxScreen->scrnY);
-#endif
- if (x >= dmxScreen->rootXOrigin
- && x < dmxScreen->rootXOrigin + dmxScreen->rootWidth
- && y >= dmxScreen->rootYOrigin
- && y < dmxScreen->rootYOrigin + dmxScreen->rootHeight) return 1;
- return 0;
-}
-
-/** Returns non-zero if \a a overlaps \a b. */
-static int dmxDoesOverlap(DMXScreenInfo *a, DMXScreenInfo *b)
-{
- if (dmxOnScreen(a->rootXOrigin,
- a->rootYOrigin, b))
- return 1;
-
- if (dmxOnScreen(a->rootXOrigin,
- a->rootYOrigin + a->scrnWidth, b))
- return 1;
-
- if (dmxOnScreen(a->rootXOrigin + a->scrnHeight,
- a->rootYOrigin, b))
- return 1;
-
- if (dmxOnScreen(a->rootXOrigin + a->scrnHeight,
- a->rootYOrigin + a->scrnWidth, b))
- return 1;
-
- if (dmxOnScreen(b->rootXOrigin,
- b->rootYOrigin, a))
- return 1;
-
- if (dmxOnScreen(b->rootXOrigin,
- b->rootYOrigin + b->scrnWidth, a))
- return 1;
-
- if (dmxOnScreen(b->rootXOrigin + b->scrnHeight,
- b->rootYOrigin, a))
- return 1;
-
- if (dmxOnScreen(b->rootXOrigin + b->scrnHeight,
- b->rootYOrigin + b->scrnWidth, a))
- return 1;
-
- return 0;
-}
-
-/** Used with \a dmxInterateOverlap to print out a list of screens which
- * overlap each other. */
-static void *dmxPrintOverlap(DMXScreenInfo *dmxScreen, void *closure)
-{
- DMXScreenInfo *a = closure;
- if (dmxScreen != a) {
- if (dmxScreen->cursorNotShared)
- dmxLogOutputCont(a, " [%d/%s]", dmxScreen->index, dmxScreen->name);
- else
- dmxLogOutputCont(a, " %d/%s", dmxScreen->index, dmxScreen->name);
- }
- return NULL;
-}
-
-/** Iterate over the screens which overlap with the \a start screen,
- * calling \a f with the \a closure for each argument. Often used with
- * #dmxPrintOverlap. */
-static void *dmxIterateOverlap(DMXScreenInfo *start,
- void *(*f)(DMXScreenInfo *dmxScreen, void *),
- void *closure)
-{
- DMXScreenInfo *pt;
-
- if (!start->over) return f(start, closure);
-
- for (pt = start->over; /* condition at end of loop */; pt = pt->over) {
- void *retval;
- if ((retval = f(pt, closure))) return retval;
- if (pt == start) break;
- }
- return NULL;
-}
-
-/** Used with #dmxPropertyIterate to determine if screen \a a is the
- * same as the screen \a closure. */
-static void *dmxTestSameDisplay(DMXScreenInfo *a, void *closure)
-{
- DMXScreenInfo *b = closure;
-
- if (a == b)
- return a;
- return NULL;
-}
-
-/** Detects overlapping dmxScreens and creates circular lists. This
- * uses an O(dmxNumScreens^2) algorithm, but dmxNumScreens is < 100 and
- * the computation only needs to be performed for every server
- * generation or dynamic reconfiguration . */
-void dmxInitOverlap(void)
-{
- int i, j;
- DMXScreenInfo *a, *b, *pt;
-
- for (i = 0; i < dmxNumScreens; i++)
- dmxScreens[i].over = NULL;
-
- for (i = 0; i < dmxNumScreens; i++) {
- a = &dmxScreens[i];
-
- for (j = i+1; j < dmxNumScreens; j++) {
- b = &dmxScreens[j];
- if (b->over)
- continue;
-
- if (dmxDoesOverlap(a, b)) {
- DMXDBG6("%d overlaps %d: a=%p %p b=%p %p\n",
- a->index, b->index, a, a->over, b, b->over);
- b->over = (a->over ? a->over : a);
- a->over = b;
- }
- }
- }
-
- for (i = 0; i < dmxNumScreens; i++) {
- a = &dmxScreens[i];
-
- if (!a->over)
- continue;
-
- /* Flag all pairs that are on same display */
- for (pt = a->over; pt != a; pt = pt->over) {
- if (dmxPropertyIterate(a, dmxTestSameDisplay, pt)) {
- /* The ->over sets contain the transitive set of screens
- * that overlap. For screens that are on the same
- * backend display, we only want to exclude pairs of
- * screens that mutually overlap on the backend display,
- * so we call dmxDoesOverlap, which is stricter than the
- * ->over set. */
- if (!dmxDoesOverlap(a, pt))
- continue;
- a->cursorNotShared = 1;
- pt->cursorNotShared = 1;
- dmxLog(dmxInfo,
- "Screen %d and %d overlap on %s\n",
- a->index, pt->index, a->name);
- }
- }
- }
-
- for (i = 0; i < dmxNumScreens; i++) {
- a = &dmxScreens[i];
-
- if (a->over) {
- dmxLogOutput(a, "Overlaps");
- dmxIterateOverlap(a, dmxPrintOverlap, a);
- dmxLogOutputCont(a, "\n");
- }
- }
-}
-
-/** Create \a pCursor on the back-end associated with \a pScreen. */
-void dmxBECreateCursor(ScreenPtr pScreen, CursorPtr pCursor)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxCursorPrivPtr pCursorPriv = DMX_GET_CURSOR_PRIV(pCursor, pScreen);
- CursorBitsPtr pBits = pCursor->bits;
- Pixmap src, msk;
- XColor fg, bg;
- XImage *img;
- XlibGC gc = NULL;
- XGCValues v;
- unsigned long m;
- int i;
-
- if (!pCursorPriv)
- return;
-
- m = GCFunction | GCPlaneMask | GCForeground | GCBackground | GCClipMask;
- v.function = GXcopy;
- v.plane_mask = AllPlanes;
- v.foreground = 1L;
- v.background = 0L;
- v.clip_mask = None;
-
- for (i = 0; i < dmxScreen->beNumPixmapFormats; i++) {
- if (dmxScreen->bePixmapFormats[i].depth == 1) {
- /* Create GC in the back-end servers */
- gc = XCreateGC(dmxScreen->beDisplay, dmxScreen->scrnDefDrawables[i],
- m, &v);
- break;
- }
- }
- if (!gc)
- dmxLog(dmxFatal, "dmxRealizeCursor: gc not initialized\n");
-
- src = XCreatePixmap(dmxScreen->beDisplay, dmxScreen->scrnWin,
- pBits->width, pBits->height, 1);
- msk = XCreatePixmap(dmxScreen->beDisplay, dmxScreen->scrnWin,
- pBits->width, pBits->height, 1);
-
- img = XCreateImage(dmxScreen->beDisplay,
- dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual,
- 1, XYBitmap, 0, (char *)pBits->source,
- pBits->width, pBits->height,
- BitmapPad(dmxScreen->beDisplay), 0);
-
- XPutImage(dmxScreen->beDisplay, src, gc, img, 0, 0, 0, 0,
- pBits->width, pBits->height);
-
- XFree(img);
-
- img = XCreateImage(dmxScreen->beDisplay,
- dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual,
- 1, XYBitmap, 0, (char *)pBits->mask,
- pBits->width, pBits->height,
- BitmapPad(dmxScreen->beDisplay), 0);
-
- XPutImage(dmxScreen->beDisplay, msk, gc, img, 0, 0, 0, 0,
- pBits->width, pBits->height);
-
- XFree(img);
-
- fg.red = pCursor->foreRed;
- fg.green = pCursor->foreGreen;
- fg.blue = pCursor->foreBlue;
-
- bg.red = pCursor->backRed;
- bg.green = pCursor->backGreen;
- bg.blue = pCursor->backBlue;
-
- pCursorPriv->cursor = XCreatePixmapCursor(dmxScreen->beDisplay,
- src, msk,
- &fg, &bg,
- pBits->xhot, pBits->yhot);
-
- XFreePixmap(dmxScreen->beDisplay, src);
- XFreePixmap(dmxScreen->beDisplay, msk);
- XFreeGC(dmxScreen->beDisplay, gc);
-
- dmxSync(dmxScreen, FALSE);
-}
-
-static Bool _dmxRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxCursorPrivPtr pCursorPriv;
-
- DMXDBG2("_dmxRealizeCursor(%d,%p)\n", pScreen->myNum, pCursor);
-
- DMX_SET_CURSOR_PRIV(pCursor, pScreen, xalloc(sizeof(*pCursorPriv)));
- if (!DMX_GET_CURSOR_PRIV(pCursor, pScreen))
- return FALSE;
-
- pCursorPriv = DMX_GET_CURSOR_PRIV(pCursor, pScreen);
- pCursorPriv->cursor = (Cursor)0;
-
- if (!dmxScreen->beDisplay)
- return TRUE;
-
- dmxBECreateCursor(pScreen, pCursor);
- return TRUE;
-}
-
-/** Free \a pCursor on the back-end associated with \a pScreen. */
-Bool dmxBEFreeCursor(ScreenPtr pScreen, CursorPtr pCursor)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxCursorPrivPtr pCursorPriv = DMX_GET_CURSOR_PRIV(pCursor, pScreen);
-
- if (pCursorPriv) {
- XFreeCursor(dmxScreen->beDisplay, pCursorPriv->cursor);
- pCursorPriv->cursor = (Cursor)0;
- return TRUE;
- }
-
- return FALSE;
-}
-
-static Bool _dmxUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
-
- DMXDBG2("_dmxUnrealizeCursor(%d,%p)\n",
- pScreen->myNum, pCursor);
-
- if (dmxScreen->beDisplay) {
- if (dmxBEFreeCursor(pScreen, pCursor))
- xfree(DMX_GET_CURSOR_PRIV(pCursor, pScreen));
- }
- DMX_SET_CURSOR_PRIV(pCursor, pScreen, NULL);
-
- return TRUE;
-}
-
-static void _dmxMoveCursor(ScreenPtr pScreen, int x, int y)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- int newX = x + dmxScreen->rootX;
- int newY = y + dmxScreen->rootY;
-
- if (newX < 0) newX = 0;
- if (newY < 0) newY = 0;
-
- DMXDBG5("_dmxMoveCursor(%d,%d,%d) -> %d,%d\n",
- pScreen->myNum, x, y, newX, newY);
- if (dmxScreen->beDisplay) {
- XWarpPointer(dmxScreen->beDisplay, None, dmxScreen->scrnWin,
- 0, 0, 0, 0, newX, newY);
- dmxSync(dmxScreen, TRUE);
- }
-}
-
-static void _dmxSetCursor(ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
-
- DMXDBG4("_dmxSetCursor(%d,%p,%d,%d)\n", pScreen->myNum, pCursor, x, y);
-
- if (pCursor) {
- dmxCursorPrivPtr pCursorPriv = DMX_GET_CURSOR_PRIV(pCursor, pScreen);
- if (pCursorPriv && dmxScreen->curCursor != pCursorPriv->cursor) {
- if (dmxScreen->beDisplay)
- XDefineCursor(dmxScreen->beDisplay, dmxScreen->scrnWin,
- pCursorPriv->cursor);
- dmxScreen->cursor = pCursor;
- dmxScreen->curCursor = pCursorPriv->cursor;
- dmxScreen->cursorVisible = 1;
- }
- _dmxMoveCursor(pScreen, x, y);
- } else {
- if (dmxScreen->beDisplay)
- XDefineCursor(dmxScreen->beDisplay, dmxScreen->scrnWin,
- dmxScreen->noCursor);
- dmxScreen->cursor = NULL;
- dmxScreen->curCursor = (Cursor)0;
- dmxScreen->cursorVisible = 0;
- }
- if (dmxScreen->beDisplay) dmxSync(dmxScreen, TRUE);
-}
-
-static Bool dmxRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
-{
- DMXScreenInfo *start = &dmxScreens[pScreen->myNum];
- DMXScreenInfo *pt;
-
- if (!start->over || !dmxCursorDoMultiCursors || start->cursorNotShared)
- return _dmxRealizeCursor(pScreen, pCursor);
-
- for (pt = start->over; /* condition at end of loop */; pt = pt->over) {
- if (pt->cursorNotShared)
- continue;
- _dmxRealizeCursor(screenInfo.screens[pt->index], pCursor);
- if (pt == start)
- break;
- }
- return TRUE;
-}
-
-static Bool dmxUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
-{
- DMXScreenInfo *start = &dmxScreens[pScreen->myNum];
- DMXScreenInfo *pt;
-
- if (!start->over || !dmxCursorDoMultiCursors || start->cursorNotShared)
- return _dmxUnrealizeCursor(pScreen, pCursor);
-
- for (pt = start->over; /* condition at end of loop */; pt = pt->over) {
- if (pt->cursorNotShared)
- continue;
- _dmxUnrealizeCursor(screenInfo.screens[pt->index], pCursor);
- if (pt == start)
- break;
- }
- return TRUE;
-}
-
-static CursorPtr dmxFindCursor(DMXScreenInfo *start)
-{
- DMXScreenInfo *pt;
-
- if (!start || !start->over)
- return GetSpriteCursor(inputInfo.pointer);
- for (pt = start->over; /* condition at end of loop */; pt = pt->over) {
- if (pt->cursor)
- return pt->cursor;
- if (pt == start)
- break;
- }
- return GetSpriteCursor(inputInfo.pointer);
-}
-
-/** Move the cursor to coordinates (\a x, \a y)on \a pScreen. This
- * function is usually called via #dmxPointerSpriteFuncs, except during
- * reconfiguration when the cursor is repositioned to force an update on
- * newley overlapping screens and on screens that no longer overlap.
- *
- * The coords (x,y) are in global coord space. We'll loop over the
- * back-end screens and see if they contain the global coord. If so, call
- * _dmxMoveCursor() (XWarpPointer) to position the pointer on that screen.
- */
-void dmxMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
-{
- DMXScreenInfo *start = &dmxScreens[pScreen->myNum];
- DMXScreenInfo *pt;
-
- DMXDBG3("dmxMoveCursor(%d,%d,%d)\n", pScreen->myNum, x, y);
-
- if (!start->over || !dmxCursorDoMultiCursors || start->cursorNotShared) {
- _dmxMoveCursor(pScreen, x, y);
- return;
- }
-
- for (pt = start->over; /* condition at end of loop */; pt = pt->over) {
- if (pt->cursorNotShared)
- continue;
- if (dmxOnScreen(x + start->rootXOrigin, y + start->rootYOrigin, pt)) {
- if (/* pt != start && */ !pt->cursorVisible) {
- if (!pt->cursor) {
- /* This only happens during
- * reconfiguration when a new overlap
- * occurs. */
- CursorPtr pCursor;
-
- if ((pCursor = dmxFindCursor(start)))
- _dmxRealizeCursor(screenInfo.screens[pt->index],
- pt->cursor = pCursor);
-
- }
- _dmxSetCursor(screenInfo.screens[pt->index],
- pt->cursor,
- x + start->rootXOrigin - pt->rootXOrigin,
- y + start->rootYOrigin - pt->rootYOrigin);
- }
- _dmxMoveCursor(screenInfo.screens[pt->index],
- x + start->rootXOrigin - pt->rootXOrigin,
- y + start->rootYOrigin - pt->rootYOrigin);
- } else if (/* pt != start && */ pt->cursorVisible) {
- _dmxSetCursor(screenInfo.screens[pt->index],
- NULL,
- x + start->rootXOrigin - pt->rootXOrigin,
- y + start->rootYOrigin - pt->rootYOrigin);
- }
- if (pt == start)
- break;
- }
-}
-
-static void dmxSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
-{
- DMXScreenInfo *start = &dmxScreens[pScreen->myNum];
- DMXScreenInfo *pt;
- int GX, GY, gx, gy;
-
- DMXDBG5("dmxSetCursor(%d %p, %p,%d,%d)\n",
- pScreen->myNum, start, pCursor, x, y);
-
- /* We do this check here because of two cases:
- *
- * 1) if a client calls XWarpPointer()
- * and Xinerama is not running, we can
- * have mi's notion of the pointer
- * position out of phase with DMX's
- * notion.
- *
- * 2) if a down button is held while the
- * cursor moves outside the root window,
- * mi's notion of the pointer position
- * is out of phase with DMX's notion and
- * the cursor can remain visible when it
- * shouldn't be. */
-
- dmxGetGlobalPosition(&GX, &GY);
- gx = start->rootXOrigin + x;
- gy = start->rootYOrigin + y;
- if (x && y && (GX != gx || GY != gy))
- dmxCoreMotion(NULL, gx, gy, 0, DMX_NO_BLOCK);
-
- if (!start->over || !dmxCursorDoMultiCursors || start->cursorNotShared) {
- _dmxSetCursor(pScreen, pCursor, x, y);
- return;
- }
-
- for (pt = start->over; /* condition at end of loop */; pt = pt->over) {
- if (pt->cursorNotShared)
- continue;
- if (dmxOnScreen(x + start->rootXOrigin, y + start->rootYOrigin, pt)) {
- _dmxSetCursor(screenInfo.screens[pt->index], pCursor,
- x + start->rootXOrigin - pt->rootXOrigin,
- y + start->rootYOrigin - pt->rootYOrigin);
- } else {
- _dmxSetCursor(screenInfo.screens[pt->index], NULL,
- x + start->rootXOrigin - pt->rootXOrigin,
- y + start->rootYOrigin - pt->rootYOrigin);
- }
- if (pt == start)
- break;
- }
-}
-
-
-/** This routine is used by the backend input routines to hide the
- * cursor on a screen that is being used for relative input. \see
- * dmxbackend.c */
-void dmxHideCursor(DMXScreenInfo *dmxScreen)
-{
- int x, y;
- ScreenPtr pScreen = screenInfo.screens[dmxScreen->index];
-
- dmxGetGlobalPosition(&x, &y);
- _dmxSetCursor(pScreen, NULL, x, y);
-}
-
-/** This routine is called during reconfiguration to make sure the
- * cursor is visible. */
-void dmxCheckCursor(void)
-{
- int i;
- int x, y;
- ScreenPtr pScreen;
- DMXScreenInfo *firstScreen;
-
- dmxGetGlobalPosition(&x, &y);
- firstScreen = dmxFindFirstScreen(x, y);
-
- DMXDBG2("dmxCheckCursor %d %d\n", x, y);
- for (i = 0; i < dmxNumScreens; i++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[i];
- pScreen = screenInfo.screens[dmxScreen->index];
-
- if (!dmxOnScreen(x, y, dmxScreen)) {
- if (firstScreen && i == miPointerGetScreen(inputInfo.pointer)->myNum)
- miPointerSetScreen(inputInfo.pointer, firstScreen->index, x, y);
- _dmxSetCursor(pScreen, NULL,
- x - dmxScreen->rootXOrigin,
- y - dmxScreen->rootYOrigin);
- } else {
- if (!dmxScreen->cursor) {
- CursorPtr pCursor;
-
- if ((pCursor = dmxFindCursor(dmxScreen))) {
- _dmxRealizeCursor(pScreen, dmxScreen->cursor = pCursor);
- }
- }
- _dmxSetCursor(pScreen, dmxScreen->cursor,
- x - dmxScreen->rootXOrigin,
- y - dmxScreen->rootYOrigin);
- }
- }
- DMXDBG2(" leave dmxCheckCursor %d %d\n", x, y);
-}
-
-static Bool dmxDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScr)
-{
- return TRUE;
-}
-
-static void dmxDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScr)
-{
-}
-
-miPointerSpriteFuncRec dmxPointerSpriteFuncs =
-{
- dmxRealizeCursor,
- dmxUnrealizeCursor,
- dmxSetCursor,
- dmxMoveCursor,
- dmxDeviceCursorInitialize,
- dmxDeviceCursorCleanup
-};
+/*
+ * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina.
+ *
+ * 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 on 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 (including the
+ * next paragraph) 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
+ * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
+ * 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.
+ */
+
+/*
+ * Authors:
+ * David H. Dawes <dawes@xfree86.org>
+ * Kevin E. Martin <kem@redhat.com>
+ * Rickard E. (Rik) Faith <faith@redhat.com>
+ *
+ */
+
+/** \file
+ * This file contains code than supports cursor movement, including the
+ * code that initializes and reinitializes the screen positions and
+ * computes screen overlap.
+ *
+ * "This code is based very closely on the XFree86 equivalent
+ * (xfree86/common/xf86Cursor.c)." --David Dawes.
+ *
+ * "This code was then extensively re-written, as explained here."
+ * --Rik Faith
+ *
+ * The code in xf86Cursor.c used edge lists to implement the
+ * CursorOffScreen function. The edge list computation was complex
+ * (especially in the face of arbitrarily overlapping screens) compared
+ * with the speed savings in the CursorOffScreen function. The new
+ * implementation has erred on the side of correctness, readability, and
+ * maintainability over efficiency. For the common (non-edge) case, the
+ * dmxCursorOffScreen function does avoid a loop over all the screens.
+ * When the cursor has left the screen, all the screens are searched,
+ * and the first screen (in dmxScreens order) containing the cursor will
+ * be returned. If run-time profiling shows that this routing is a
+ * performance bottle-neck, then an edge list may have to be
+ * reimplemented. An edge list algorithm is O(edges) whereas the new
+ * algorithm is O(dmxNumScreens). Since edges is usually 1-3 and
+ * dmxNumScreens may be 30-60 for large backend walls, this trade off
+ * may be compelling.
+ *
+ * The xf86InitOrigins routine uses bit masks during the computation and
+ * is therefore limited to the length of a word (e.g., 32 or 64 bits)
+ * screens. Because Xdmx is expected to be used with a large number of
+ * backend displays, this limitation was removed. The new
+ * implementation has erred on the side of readability over efficiency,
+ * using the dmxSL* routines to manage a screen list instead of a
+ * bitmap, and a function call to decrease the length of the main
+ * routine. Both algorithms are of the same order, and both are called
+ * only at server generation time, so trading clarity and long-term
+ * maintainability for efficiency does not seem justified in this case.
+ */
+
+#ifdef HAVE_DMX_CONFIG_H
+#include <dmx-config.h>
+#endif
+
+#define DMX_CURSOR_DEBUG 0
+
+#include "dmx.h"
+#include "dmxsync.h"
+#include "dmxcursor.h"
+#include "dmxlog.h"
+#include "dmxprop.h"
+#include "dmxinput.h"
+
+#include "mipointer.h"
+#include "windowstr.h"
+#include "globals.h"
+#include "cursorstr.h"
+#include "dixevents.h" /* For GetSpriteCursor() */
+#include "inputstr.h" /* for inputInfo.pointer */
+
+#if DMX_CURSOR_DEBUG
+#define DMXDBG0(f) dmxLog(dmxDebug,f)
+#define DMXDBG1(f,a) dmxLog(dmxDebug,f,a)
+#define DMXDBG2(f,a,b) dmxLog(dmxDebug,f,a,b)
+#define DMXDBG3(f,a,b,c) dmxLog(dmxDebug,f,a,b,c)
+#define DMXDBG4(f,a,b,c,d) dmxLog(dmxDebug,f,a,b,c,d)
+#define DMXDBG5(f,a,b,c,d,e) dmxLog(dmxDebug,f,a,b,c,d,e)
+#define DMXDBG6(f,a,b,c,d,e,g) dmxLog(dmxDebug,f,a,b,c,d,e,g)
+#define DMXDBG7(f,a,b,c,d,e,g,h) dmxLog(dmxDebug,f,a,b,c,d,e,g,h)
+#else
+#define DMXDBG0(f)
+#define DMXDBG1(f,a)
+#define DMXDBG2(f,a,b)
+#define DMXDBG3(f,a,b,c)
+#define DMXDBG4(f,a,b,c,d)
+#define DMXDBG5(f,a,b,c,d,e)
+#define DMXDBG6(f,a,b,c,d,e,g)
+#define DMXDBG7(f,a,b,c,d,e,g,h)
+#endif
+
+static int dmxCursorDoMultiCursors = 1;
+
+/** Turn off support for displaying multiple cursors on overlapped
+ back-end displays. See #dmxCursorDoMultiCursors. */
+void dmxCursorNoMulti(void)
+{
+ dmxCursorDoMultiCursors = 0;
+}
+
+static Bool dmxCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
+{
+ DMXScreenInfo *dmxScreen;
+ int i;
+ int localX = *x;
+ int localY = *y;
+ int globalX;
+ int globalY;
+
+ if (screenInfo.numScreens == 1)
+ return FALSE;
+
+ /* On current screen? */
+ dmxScreen = &dmxScreens[(*ppScreen)->myNum];
+ if (localX >= 0
+ && localX < dmxScreen->rootWidth
+ && localY >= 0
+ && localY < dmxScreen->rootHeight)
+ return FALSE;
+
+ /* Convert to global coordinate space */
+ globalX = dmxScreen->rootXOrigin + localX;
+ globalY = dmxScreen->rootYOrigin + localY;
+
+ /* Is cursor on the current screen?
+ * This efficiently exits this routine
+ * for the most common case. */
+ if (ppScreen && *ppScreen) {
+ dmxScreen = &dmxScreens[(*ppScreen)->myNum];
+ if (globalX >= dmxScreen->rootXOrigin
+ && globalX < dmxScreen->rootXOrigin + dmxScreen->rootWidth
+ && globalY >= dmxScreen->rootYOrigin
+ && globalY < dmxScreen->rootYOrigin + dmxScreen->rootHeight)
+ return FALSE;
+ }
+
+ /* Find first screen cursor is on */
+ for (i = 0; i < dmxNumScreens; i++) {
+ dmxScreen = &dmxScreens[i];
+ if (globalX >= dmxScreen->rootXOrigin
+ && globalX < dmxScreen->rootXOrigin + dmxScreen->rootWidth
+ && globalY >= dmxScreen->rootYOrigin
+ && globalY < dmxScreen->rootYOrigin + dmxScreen->rootHeight) {
+ if (dmxScreen->index == (*ppScreen)->myNum)
+ return FALSE;
+ *ppScreen = screenInfo.screens[dmxScreen->index];
+ *x = globalX - dmxScreen->rootXOrigin;
+ *y = globalY - dmxScreen->rootYOrigin;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+static void dmxCrossScreen(ScreenPtr pScreen, Bool entering)
+{
+}
+
+static void dmxWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
+{
+ DMXDBG3("dmxWarpCursor(%d,%d,%d)\n", pScreen->myNum, x, y);
+#if 11 /*BP*/
+ /* This call is depracated. Replace with???? */
+ miPointerWarpCursor(pDev, pScreen, x, y);
+#else
+ pScreen->SetCursorPosition(pDev, pScreen, x, y, FALSE);
+#endif
+}
+
+miPointerScreenFuncRec dmxPointerCursorFuncs =
+{
+ dmxCursorOffScreen,
+ dmxCrossScreen,
+ dmxWarpCursor,
+ NULL,
+ NULL,
+};
+
+
+/** Create a list of screens that we'll manipulate. */
+static int *dmxSLCreate(void)
+{
+ int *list = malloc(dmxNumScreens * sizeof(*list));
+ int i;
+
+ for (i = 0; i < dmxNumScreens; i++)
+ list[i] = 1;
+ return list;
+}
+
+/** Free list. */
+static void dmxSLFree(int *list)
+{
+ free(list);
+}
+
+/** Find next uninitialized entry in list. */
+static int dmxSLFindNext(int *list)
+{
+ int i;
+ for (i = 0; i < dmxNumScreens; i++)
+ if (list[i])
+ return i;
+ return -1;
+}
+
+/** Make one pass over all the screens and return the number updated. */
+static int dmxTryComputeScreenOrigins(int *screensLeft)
+{
+ ScreenPtr pScreen;
+ DMXScreenInfo *screen;
+ int i, ref;
+ int changed = 0;
+
+ for (i = 0; i < dmxNumScreens; i++) {
+ if (!screensLeft[i])
+ continue;
+ screen = &dmxScreens[i];
+ switch (screen->where) {
+ case PosAbsolute:
+ dixScreenOrigins[i].x = screen->whereX;
+ dixScreenOrigins[i].y = screen->whereY;
+ ++changed, screensLeft[i] = 0;
+ break;
+ case PosRelative:
+ ref = screen->whereRefScreen;
+ if (screensLeft[ref])
+ break;
+ dixScreenOrigins[i].x = dixScreenOrigins[ref].x + screen->whereX;
+ dixScreenOrigins[i].y = dixScreenOrigins[ref].y + screen->whereY;
+ ++changed, screensLeft[i] = 0;
+ break;
+ case PosRightOf:
+ ref = screen->whereRefScreen;
+ if (screensLeft[ref])
+ break;
+ pScreen = screenInfo.screens[ref];
+ dixScreenOrigins[i].x = dixScreenOrigins[ref].x + pScreen->width;
+ dixScreenOrigins[i].y = dixScreenOrigins[ref].y;
+ ++changed, screensLeft[i] = 0;
+ break;
+ case PosLeftOf:
+ ref = screen->whereRefScreen;
+ if (screensLeft[ref])
+ break;
+ pScreen = screenInfo.screens[i];
+ dixScreenOrigins[i].x = dixScreenOrigins[ref].x - pScreen->width;
+ dixScreenOrigins[i].y = dixScreenOrigins[ref].y;
+ ++changed, screensLeft[i] = 0;
+ break;
+ case PosBelow:
+ ref = screen->whereRefScreen;
+ if (screensLeft[ref])
+ break;
+ pScreen = screenInfo.screens[ref];
+ dixScreenOrigins[i].x = dixScreenOrigins[ref].x;
+ dixScreenOrigins[i].y = dixScreenOrigins[ref].y + pScreen->height;
+ ++changed, screensLeft[i] = 0;
+ break;
+ case PosAbove:
+ ref = screen->whereRefScreen;
+ if (screensLeft[ref])
+ break;
+ pScreen = screenInfo.screens[i];
+ dixScreenOrigins[i].x = dixScreenOrigins[ref].x;
+ dixScreenOrigins[i].y = dixScreenOrigins[ref].y - pScreen->height;
+ ++changed, screensLeft[i] = 0;
+ break;
+ case PosNone:
+ dmxLog(dmxFatal, "No position information for screen %d\n", i);
+ }
+ }
+ return changed;
+}
+
+static void dmxComputeScreenOrigins(void)
+{
+ int *screensLeft;
+ int i, ref;
+ int minX, minY;
+
+ /* Compute origins based on
+ * configuration information. */
+ screensLeft = dmxSLCreate();
+ while ((i = dmxSLFindNext(screensLeft)) >= 0) {
+ while (dmxTryComputeScreenOrigins(screensLeft));
+ if ((i = dmxSLFindNext(screensLeft)) >= 0) {
+ /* All of the remaining screens are referencing each other.
+ * Assign a value to one of them and go through again. This
+ * guarantees that we will eventually terminate.
+ */
+ ref = dmxScreens[i].whereRefScreen;
+ dixScreenOrigins[ref].x = dixScreenOrigins[ref].y = 0;
+ screensLeft[ref] = 0;
+ }
+ }
+ dmxSLFree(screensLeft);
+
+
+ /* Justify the topmost and leftmost to
+ * (0,0). */
+ minX = dixScreenOrigins[0].x;
+ minY = dixScreenOrigins[0].y;
+ for (i = 1; i < dmxNumScreens; i++) { /* Compute minX, minY */
+ if (dixScreenOrigins[i].x < minX)
+ minX = dixScreenOrigins[i].x;
+ if (dixScreenOrigins[i].y < minY)
+ minY = dixScreenOrigins[i].y;
+ }
+ if (minX || minY) {
+ for (i = 0; i < dmxNumScreens; i++) {
+ dixScreenOrigins[i].x -= minX;
+ dixScreenOrigins[i].y -= minY;
+ }
+ }
+}
+
+/** Recompute origin information in the #dmxScreens list. This is
+ * called from #dmxInitOrigins. */
+void dmxReInitOrigins(void)
+{
+ int i;
+
+ if (dmxNumScreens > MAXSCREENS)
+ dmxLog(dmxFatal, "dmxNumScreens = %d > MAXSCREENS = %d\n",
+ dmxNumScreens, MAXSCREENS);
+
+ for (i = 0; i < dmxNumScreens; i++) {
+ DMXScreenInfo *dmxScreen = &dmxScreens[i];
+ dmxLogOutput(dmxScreen,
+ "s=%dx%d%+d%+d r=%dx%d%+d%+d @%d,%d"
+ " (be=%dx%d depth=%d bpp=%d)\n",
+ dmxScreen->scrnWidth, dmxScreen->scrnHeight,
+ dmxScreen->scrnX, dmxScreen->scrnY,
+
+ dmxScreen->rootWidth, dmxScreen->rootHeight,
+ dmxScreen->rootX, dmxScreen->rootY,
+
+ dmxScreen->rootXOrigin, dmxScreen->rootYOrigin,
+ dmxScreen->beWidth, dmxScreen->beHeight,
+ dmxScreen->beDepth, dmxScreen->beBPP);
+ }
+}
+
+/** Initialize screen origins (and relative position). This is called
+ * for each server generation. For dynamic reconfiguration, use
+ * #dmxReInitOrigins() instead. */
+void dmxInitOrigins(void)
+{
+ int i;
+
+ if (dmxNumScreens > MAXSCREENS)
+ dmxLog(dmxFatal, "dmxNumScreens = %d > MAXSCREENS = %d\n",
+ dmxNumScreens, MAXSCREENS);
+
+ for (i = 0; i < dmxNumScreens; i++) {
+ DMXScreenInfo *dmxScreen = &dmxScreens[i];
+ dmxLogOutput(dmxScreen,
+ "(request) s=%dx%d%+d%+d r=%dx%d%+d%+d @%d,%d (%d)"
+ " (be=%dx%d depth=%d bpp=%d)\n",
+ dmxScreen->scrnWidth, dmxScreen->scrnHeight,
+ dmxScreen->scrnX, dmxScreen->scrnY,
+
+ dmxScreen->rootWidth, dmxScreen->rootHeight,
+ dmxScreen->rootX, dmxScreen->rootY,
+
+ dmxScreen->whereX, dmxScreen->whereY,
+ dmxScreen->where,
+
+ dmxScreen->beWidth, dmxScreen->beHeight,
+ dmxScreen->beDepth, dmxScreen->beBPP);
+ }
+
+ dmxComputeScreenOrigins();
+
+ for (i = 0; i < dmxNumScreens; i++) {
+ DMXScreenInfo *dmxScreen = &dmxScreens[i];
+ dmxScreen->rootXOrigin = dixScreenOrigins[i].x;
+ dmxScreen->rootYOrigin = dixScreenOrigins[i].y;
+ }
+
+ dmxReInitOrigins();
+}
+
+/** Returns non-zero if the global \a x, \a y coordinate is on the
+ * screen window of the \a dmxScreen. */
+int dmxOnScreen(int x, int y, DMXScreenInfo *dmxScreen)
+{
+#if DMX_CURSOR_DEBUG > 1
+ dmxLog(dmxDebug,
+ "dmxOnScreen %d %d,%d (r=%dx%d%+d%+d@%d,%d s=%dx%d%+d%+d)\n",
+ dmxScreen->index, x, y,
+ dmxScreen->rootWidth, dmxScreen->rootHeight,
+ dmxScreen->rootX, dmxScreen->rootY,
+ dmxScreen->rootXOrigin, dmxScreen->rootYOrigin,
+ dmxScreen->scrnWidth, dmxScreen->scrnHeight,
+ dmxScreen->scrnX, dmxScreen->scrnY);
+#endif
+ if (x >= dmxScreen->rootXOrigin
+ && x < dmxScreen->rootXOrigin + dmxScreen->rootWidth
+ && y >= dmxScreen->rootYOrigin
+ && y < dmxScreen->rootYOrigin + dmxScreen->rootHeight) return 1;
+ return 0;
+}
+
+/** Returns non-zero if \a a overlaps \a b. */
+static int dmxDoesOverlap(DMXScreenInfo *a, DMXScreenInfo *b)
+{
+ if (dmxOnScreen(a->rootXOrigin,
+ a->rootYOrigin, b))
+ return 1;
+
+ if (dmxOnScreen(a->rootXOrigin,
+ a->rootYOrigin + a->scrnWidth, b))
+ return 1;
+
+ if (dmxOnScreen(a->rootXOrigin + a->scrnHeight,
+ a->rootYOrigin, b))
+ return 1;
+
+ if (dmxOnScreen(a->rootXOrigin + a->scrnHeight,
+ a->rootYOrigin + a->scrnWidth, b))
+ return 1;
+
+ if (dmxOnScreen(b->rootXOrigin,
+ b->rootYOrigin, a))
+ return 1;
+
+ if (dmxOnScreen(b->rootXOrigin,
+ b->rootYOrigin + b->scrnWidth, a))
+ return 1;
+
+ if (dmxOnScreen(b->rootXOrigin + b->scrnHeight,
+ b->rootYOrigin, a))
+ return 1;
+
+ if (dmxOnScreen(b->rootXOrigin + b->scrnHeight,
+ b->rootYOrigin + b->scrnWidth, a))
+ return 1;
+
+ return 0;
+}
+
+/** Used with \a dmxInterateOverlap to print out a list of screens which
+ * overlap each other. */
+static void *dmxPrintOverlap(DMXScreenInfo *dmxScreen, void *closure)
+{
+ DMXScreenInfo *a = closure;
+ if (dmxScreen != a) {
+ if (dmxScreen->cursorNotShared)
+ dmxLogOutputCont(a, " [%d/%s]", dmxScreen->index, dmxScreen->name);
+ else
+ dmxLogOutputCont(a, " %d/%s", dmxScreen->index, dmxScreen->name);
+ }
+ return NULL;
+}
+
+/** Iterate over the screens which overlap with the \a start screen,
+ * calling \a f with the \a closure for each argument. Often used with
+ * #dmxPrintOverlap. */
+static void *dmxIterateOverlap(DMXScreenInfo *start,
+ void *(*f)(DMXScreenInfo *dmxScreen, void *),
+ void *closure)
+{
+ DMXScreenInfo *pt;
+
+ if (!start->over) return f(start, closure);
+
+ for (pt = start->over; /* condition at end of loop */; pt = pt->over) {
+ void *retval;
+ if ((retval = f(pt, closure))) return retval;
+ if (pt == start) break;
+ }
+ return NULL;
+}
+
+/** Used with #dmxPropertyIterate to determine if screen \a a is the
+ * same as the screen \a closure. */
+static void *dmxTestSameDisplay(DMXScreenInfo *a, void *closure)
+{
+ DMXScreenInfo *b = closure;
+
+ if (a == b)
+ return a;
+ return NULL;
+}
+
+/** Detects overlapping dmxScreens and creates circular lists. This
+ * uses an O(dmxNumScreens^2) algorithm, but dmxNumScreens is < 100 and
+ * the computation only needs to be performed for every server
+ * generation or dynamic reconfiguration . */
+void dmxInitOverlap(void)
+{
+ int i, j;
+ DMXScreenInfo *a, *b, *pt;
+
+ for (i = 0; i < dmxNumScreens; i++)
+ dmxScreens[i].over = NULL;
+
+ for (i = 0; i < dmxNumScreens; i++) {
+ a = &dmxScreens[i];
+
+ for (j = i+1; j < dmxNumScreens; j++) {
+ b = &dmxScreens[j];
+ if (b->over)
+ continue;
+
+ if (dmxDoesOverlap(a, b)) {
+ DMXDBG6("%d overlaps %d: a=%p %p b=%p %p\n",
+ a->index, b->index, a, a->over, b, b->over);
+ b->over = (a->over ? a->over : a);
+ a->over = b;
+ }
+ }
+ }
+
+ for (i = 0; i < dmxNumScreens; i++) {
+ a = &dmxScreens[i];
+
+ if (!a->over)
+ continue;
+
+ /* Flag all pairs that are on same display */
+ for (pt = a->over; pt != a; pt = pt->over) {
+ if (dmxPropertyIterate(a, dmxTestSameDisplay, pt)) {
+ /* The ->over sets contain the transitive set of screens
+ * that overlap. For screens that are on the same
+ * backend display, we only want to exclude pairs of
+ * screens that mutually overlap on the backend display,
+ * so we call dmxDoesOverlap, which is stricter than the
+ * ->over set. */
+ if (!dmxDoesOverlap(a, pt))
+ continue;
+ a->cursorNotShared = 1;
+ pt->cursorNotShared = 1;
+ dmxLog(dmxInfo,
+ "Screen %d and %d overlap on %s\n",
+ a->index, pt->index, a->name);
+ }
+ }
+ }
+
+ for (i = 0; i < dmxNumScreens; i++) {
+ a = &dmxScreens[i];
+
+ if (a->over) {
+ dmxLogOutput(a, "Overlaps");
+ dmxIterateOverlap(a, dmxPrintOverlap, a);
+ dmxLogOutputCont(a, "\n");
+ }
+ }
+}
+
+/** Create \a pCursor on the back-end associated with \a pScreen. */
+void dmxBECreateCursor(ScreenPtr pScreen, CursorPtr pCursor)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxCursorPrivPtr pCursorPriv = DMX_GET_CURSOR_PRIV(pCursor, pScreen);
+ CursorBitsPtr pBits = pCursor->bits;
+ Pixmap src, msk;
+ XColor fg, bg;
+ XImage *img;
+ XlibGC gc = NULL;
+ XGCValues v;
+ unsigned long m;
+ int i;
+
+ if (!pCursorPriv)
+ return;
+
+ m = GCFunction | GCPlaneMask | GCForeground | GCBackground | GCClipMask;
+ v.function = GXcopy;
+ v.plane_mask = AllPlanes;
+ v.foreground = 1L;
+ v.background = 0L;
+ v.clip_mask = None;
+
+ for (i = 0; i < dmxScreen->beNumPixmapFormats; i++) {
+ if (dmxScreen->bePixmapFormats[i].depth == 1) {
+ /* Create GC in the back-end servers */
+ gc = XCreateGC(dmxScreen->beDisplay, dmxScreen->scrnDefDrawables[i],
+ m, &v);
+ break;
+ }
+ }
+ if (!gc)
+ dmxLog(dmxFatal, "dmxRealizeCursor: gc not initialized\n");
+
+ src = XCreatePixmap(dmxScreen->beDisplay, dmxScreen->scrnWin,
+ pBits->width, pBits->height, 1);
+ msk = XCreatePixmap(dmxScreen->beDisplay, dmxScreen->scrnWin,
+ pBits->width, pBits->height, 1);
+
+ img = XCreateImage(dmxScreen->beDisplay,
+ dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual,
+ 1, XYBitmap, 0, (char *)pBits->source,
+ pBits->width, pBits->height,
+ BitmapPad(dmxScreen->beDisplay), 0);
+
+ XPutImage(dmxScreen->beDisplay, src, gc, img, 0, 0, 0, 0,
+ pBits->width, pBits->height);
+
+ XFree(img);
+
+ img = XCreateImage(dmxScreen->beDisplay,
+ dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual,
+ 1, XYBitmap, 0, (char *)pBits->mask,
+ pBits->width, pBits->height,
+ BitmapPad(dmxScreen->beDisplay), 0);
+
+ XPutImage(dmxScreen->beDisplay, msk, gc, img, 0, 0, 0, 0,
+ pBits->width, pBits->height);
+
+ XFree(img);
+
+ fg.red = pCursor->foreRed;
+ fg.green = pCursor->foreGreen;
+ fg.blue = pCursor->foreBlue;
+
+ bg.red = pCursor->backRed;
+ bg.green = pCursor->backGreen;
+ bg.blue = pCursor->backBlue;
+
+ pCursorPriv->cursor = XCreatePixmapCursor(dmxScreen->beDisplay,
+ src, msk,
+ &fg, &bg,
+ pBits->xhot, pBits->yhot);
+
+ XFreePixmap(dmxScreen->beDisplay, src);
+ XFreePixmap(dmxScreen->beDisplay, msk);
+ XFreeGC(dmxScreen->beDisplay, gc);
+
+ dmxSync(dmxScreen, FALSE);
+}
+
+static Bool _dmxRealizeCursor(ScreenPtr pScreen, CursorPtr pCursor)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxCursorPrivPtr pCursorPriv;
+
+ DMXDBG2("_dmxRealizeCursor(%d,%p)\n", pScreen->myNum, pCursor);
+
+ DMX_SET_CURSOR_PRIV(pCursor, pScreen, malloc(sizeof(*pCursorPriv)));
+ if (!DMX_GET_CURSOR_PRIV(pCursor, pScreen))
+ return FALSE;
+
+ pCursorPriv = DMX_GET_CURSOR_PRIV(pCursor, pScreen);
+ pCursorPriv->cursor = (Cursor)0;
+
+ if (!dmxScreen->beDisplay)
+ return TRUE;
+
+ dmxBECreateCursor(pScreen, pCursor);
+ return TRUE;
+}
+
+/** Free \a pCursor on the back-end associated with \a pScreen. */
+Bool dmxBEFreeCursor(ScreenPtr pScreen, CursorPtr pCursor)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxCursorPrivPtr pCursorPriv = DMX_GET_CURSOR_PRIV(pCursor, pScreen);
+
+ if (pCursorPriv) {
+ XFreeCursor(dmxScreen->beDisplay, pCursorPriv->cursor);
+ pCursorPriv->cursor = (Cursor)0;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static Bool _dmxUnrealizeCursor(ScreenPtr pScreen, CursorPtr pCursor)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+
+ DMXDBG2("_dmxUnrealizeCursor(%d,%p)\n",
+ pScreen->myNum, pCursor);
+
+ if (dmxScreen->beDisplay) {
+ if (dmxBEFreeCursor(pScreen, pCursor))
+ free(DMX_GET_CURSOR_PRIV(pCursor, pScreen));
+ }
+ DMX_SET_CURSOR_PRIV(pCursor, pScreen, NULL);
+
+ return TRUE;
+}
+
+static void _dmxMoveCursor(ScreenPtr pScreen, int x, int y)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ int newX = x + dmxScreen->rootX;
+ int newY = y + dmxScreen->rootY;
+
+ if (newX < 0) newX = 0;
+ if (newY < 0) newY = 0;
+
+ DMXDBG5("_dmxMoveCursor(%d,%d,%d) -> %d,%d\n",
+ pScreen->myNum, x, y, newX, newY);
+ if (dmxScreen->beDisplay) {
+ XWarpPointer(dmxScreen->beDisplay, None, dmxScreen->scrnWin,
+ 0, 0, 0, 0, newX, newY);
+ dmxSync(dmxScreen, TRUE);
+ }
+}
+
+static void _dmxSetCursor(ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+
+ DMXDBG4("_dmxSetCursor(%d,%p,%d,%d)\n", pScreen->myNum, pCursor, x, y);
+
+ if (pCursor) {
+ dmxCursorPrivPtr pCursorPriv = DMX_GET_CURSOR_PRIV(pCursor, pScreen);
+ if (pCursorPriv && dmxScreen->curCursor != pCursorPriv->cursor) {
+ if (dmxScreen->beDisplay)
+ XDefineCursor(dmxScreen->beDisplay, dmxScreen->scrnWin,
+ pCursorPriv->cursor);
+ dmxScreen->cursor = pCursor;
+ dmxScreen->curCursor = pCursorPriv->cursor;
+ dmxScreen->cursorVisible = 1;
+ }
+ _dmxMoveCursor(pScreen, x, y);
+ } else {
+ if (dmxScreen->beDisplay)
+ XDefineCursor(dmxScreen->beDisplay, dmxScreen->scrnWin,
+ dmxScreen->noCursor);
+ dmxScreen->cursor = NULL;
+ dmxScreen->curCursor = (Cursor)0;
+ dmxScreen->cursorVisible = 0;
+ }
+ if (dmxScreen->beDisplay) dmxSync(dmxScreen, TRUE);
+}
+
+static Bool dmxRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
+{
+ DMXScreenInfo *start = &dmxScreens[pScreen->myNum];
+ DMXScreenInfo *pt;
+
+ if (!start->over || !dmxCursorDoMultiCursors || start->cursorNotShared)
+ return _dmxRealizeCursor(pScreen, pCursor);
+
+ for (pt = start->over; /* condition at end of loop */; pt = pt->over) {
+ if (pt->cursorNotShared)
+ continue;
+ _dmxRealizeCursor(screenInfo.screens[pt->index], pCursor);
+ if (pt == start)
+ break;
+ }
+ return TRUE;
+}
+
+static Bool dmxUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
+{
+ DMXScreenInfo *start = &dmxScreens[pScreen->myNum];
+ DMXScreenInfo *pt;
+
+ if (!start->over || !dmxCursorDoMultiCursors || start->cursorNotShared)
+ return _dmxUnrealizeCursor(pScreen, pCursor);
+
+ for (pt = start->over; /* condition at end of loop */; pt = pt->over) {
+ if (pt->cursorNotShared)
+ continue;
+ _dmxUnrealizeCursor(screenInfo.screens[pt->index], pCursor);
+ if (pt == start)
+ break;
+ }
+ return TRUE;
+}
+
+static CursorPtr dmxFindCursor(DMXScreenInfo *start)
+{
+ DMXScreenInfo *pt;
+
+ if (!start || !start->over)
+ return GetSpriteCursor(inputInfo.pointer);
+ for (pt = start->over; /* condition at end of loop */; pt = pt->over) {
+ if (pt->cursor)
+ return pt->cursor;
+ if (pt == start)
+ break;
+ }
+ return GetSpriteCursor(inputInfo.pointer);
+}
+
+/** Move the cursor to coordinates (\a x, \a y)on \a pScreen. This
+ * function is usually called via #dmxPointerSpriteFuncs, except during
+ * reconfiguration when the cursor is repositioned to force an update on
+ * newley overlapping screens and on screens that no longer overlap.
+ *
+ * The coords (x,y) are in global coord space. We'll loop over the
+ * back-end screens and see if they contain the global coord. If so, call
+ * _dmxMoveCursor() (XWarpPointer) to position the pointer on that screen.
+ */
+void dmxMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
+{
+ DMXScreenInfo *start = &dmxScreens[pScreen->myNum];
+ DMXScreenInfo *pt;
+
+ DMXDBG3("dmxMoveCursor(%d,%d,%d)\n", pScreen->myNum, x, y);
+
+ if (!start->over || !dmxCursorDoMultiCursors || start->cursorNotShared) {
+ _dmxMoveCursor(pScreen, x, y);
+ return;
+ }
+
+ for (pt = start->over; /* condition at end of loop */; pt = pt->over) {
+ if (pt->cursorNotShared)
+ continue;
+ if (dmxOnScreen(x + start->rootXOrigin, y + start->rootYOrigin, pt)) {
+ if (/* pt != start && */ !pt->cursorVisible) {
+ if (!pt->cursor) {
+ /* This only happens during
+ * reconfiguration when a new overlap
+ * occurs. */
+ CursorPtr pCursor;
+
+ if ((pCursor = dmxFindCursor(start)))
+ _dmxRealizeCursor(screenInfo.screens[pt->index],
+ pt->cursor = pCursor);
+
+ }
+ _dmxSetCursor(screenInfo.screens[pt->index],
+ pt->cursor,
+ x + start->rootXOrigin - pt->rootXOrigin,
+ y + start->rootYOrigin - pt->rootYOrigin);
+ }
+ _dmxMoveCursor(screenInfo.screens[pt->index],
+ x + start->rootXOrigin - pt->rootXOrigin,
+ y + start->rootYOrigin - pt->rootYOrigin);
+ } else if (/* pt != start && */ pt->cursorVisible) {
+ _dmxSetCursor(screenInfo.screens[pt->index],
+ NULL,
+ x + start->rootXOrigin - pt->rootXOrigin,
+ y + start->rootYOrigin - pt->rootYOrigin);
+ }
+ if (pt == start)
+ break;
+ }
+}
+
+static void dmxSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
+{
+ DMXScreenInfo *start = &dmxScreens[pScreen->myNum];
+ DMXScreenInfo *pt;
+ int GX, GY, gx, gy;
+
+ DMXDBG5("dmxSetCursor(%d %p, %p,%d,%d)\n",
+ pScreen->myNum, start, pCursor, x, y);
+
+ /* We do this check here because of two cases:
+ *
+ * 1) if a client calls XWarpPointer()
+ * and Xinerama is not running, we can
+ * have mi's notion of the pointer
+ * position out of phase with DMX's
+ * notion.
+ *
+ * 2) if a down button is held while the
+ * cursor moves outside the root window,
+ * mi's notion of the pointer position
+ * is out of phase with DMX's notion and
+ * the cursor can remain visible when it
+ * shouldn't be. */
+
+ dmxGetGlobalPosition(&GX, &GY);
+ gx = start->rootXOrigin + x;
+ gy = start->rootYOrigin + y;
+ if (x && y && (GX != gx || GY != gy))
+ dmxCoreMotion(NULL, gx, gy, 0, DMX_NO_BLOCK);
+
+ if (!start->over || !dmxCursorDoMultiCursors || start->cursorNotShared) {
+ _dmxSetCursor(pScreen, pCursor, x, y);
+ return;
+ }
+
+ for (pt = start->over; /* condition at end of loop */; pt = pt->over) {
+ if (pt->cursorNotShared)
+ continue;
+ if (dmxOnScreen(x + start->rootXOrigin, y + start->rootYOrigin, pt)) {
+ _dmxSetCursor(screenInfo.screens[pt->index], pCursor,
+ x + start->rootXOrigin - pt->rootXOrigin,
+ y + start->rootYOrigin - pt->rootYOrigin);
+ } else {
+ _dmxSetCursor(screenInfo.screens[pt->index], NULL,
+ x + start->rootXOrigin - pt->rootXOrigin,
+ y + start->rootYOrigin - pt->rootYOrigin);
+ }
+ if (pt == start)
+ break;
+ }
+}
+
+
+/** This routine is used by the backend input routines to hide the
+ * cursor on a screen that is being used for relative input. \see
+ * dmxbackend.c */
+void dmxHideCursor(DMXScreenInfo *dmxScreen)
+{
+ int x, y;
+ ScreenPtr pScreen = screenInfo.screens[dmxScreen->index];
+
+ dmxGetGlobalPosition(&x, &y);
+ _dmxSetCursor(pScreen, NULL, x, y);
+}
+
+/** This routine is called during reconfiguration to make sure the
+ * cursor is visible. */
+void dmxCheckCursor(void)
+{
+ int i;
+ int x, y;
+ ScreenPtr pScreen;
+ DMXScreenInfo *firstScreen;
+
+ dmxGetGlobalPosition(&x, &y);
+ firstScreen = dmxFindFirstScreen(x, y);
+
+ DMXDBG2("dmxCheckCursor %d %d\n", x, y);
+ for (i = 0; i < dmxNumScreens; i++) {
+ DMXScreenInfo *dmxScreen = &dmxScreens[i];
+ pScreen = screenInfo.screens[dmxScreen->index];
+
+ if (!dmxOnScreen(x, y, dmxScreen)) {
+ if (firstScreen && i == miPointerGetScreen(inputInfo.pointer)->myNum)
+ miPointerSetScreen(inputInfo.pointer, firstScreen->index, x, y);
+ _dmxSetCursor(pScreen, NULL,
+ x - dmxScreen->rootXOrigin,
+ y - dmxScreen->rootYOrigin);
+ } else {
+ if (!dmxScreen->cursor) {
+ CursorPtr pCursor;
+
+ if ((pCursor = dmxFindCursor(dmxScreen))) {
+ _dmxRealizeCursor(pScreen, dmxScreen->cursor = pCursor);
+ }
+ }
+ _dmxSetCursor(pScreen, dmxScreen->cursor,
+ x - dmxScreen->rootXOrigin,
+ y - dmxScreen->rootYOrigin);
+ }
+ }
+ DMXDBG2(" leave dmxCheckCursor %d %d\n", x, y);
+}
+
+static Bool dmxDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScr)
+{
+ return TRUE;
+}
+
+static void dmxDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScr)
+{
+}
+
+miPointerSpriteFuncRec dmxPointerSpriteFuncs =
+{
+ dmxRealizeCursor,
+ dmxUnrealizeCursor,
+ dmxSetCursor,
+ dmxMoveCursor,
+ dmxDeviceCursorInitialize,
+ dmxDeviceCursorCleanup
+};
diff --git a/xorg-server/hw/dmx/dmxfont.c b/xorg-server/hw/dmx/dmxfont.c
index c33aee79a..3f0264edb 100644
--- a/xorg-server/hw/dmx/dmxfont.c
+++ b/xorg-server/hw/dmx/dmxfont.c
@@ -1,559 +1,551 @@
-/*
- * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina.
- *
- * 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 on 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 (including the
- * next paragraph) 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
- * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
- * 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.
- */
-
-/*
- * Authors:
- * Kevin E. Martin <kem@redhat.com>
- *
- */
-
-/** \file
- * This file provides support for fonts. */
-
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
-
-#define DMX_FONTPATH_DEBUG 0
-
-#include "dmx.h"
-#include "dmxsync.h"
-#include "dmxfont.h"
-#include "dmxlog.h"
-
-#include <X11/fonts/fontstruct.h>
-#include "dixfont.h"
-#include "dixstruct.h"
-
-static int (*dmxSaveProcVector[256])(ClientPtr);
-static int dmxFontLastError;
-
-static int dmxFontErrorHandler(Display *dpy, XErrorEvent *ev)
-{
- dmxFontLastError = ev->error_code;
-
- return 0;
-}
-
-static char **dmxGetFontPath(int *npaths)
-{
- char **fp;
- unsigned char *c, *paths;
- char *newfp;
- int len, l, i;
-
- GetFontPath(serverClient, npaths, &len, &paths);
-
- newfp = xalloc(*npaths + len);
- c = (unsigned char *)newfp;
- fp = xalloc(*npaths * sizeof(*fp));
-
- memmove(newfp, paths+1, *npaths + len - 1);
- l = *paths;
- for (i = 0; i < *npaths; i++) {
- fp[i] = (char *)c;
- c += l;
- l = *c;
- *c++ = '\0';
- }
-
-#if DMX_FONTPATH_DEBUG
- for (i = 0; i < *npaths; i++)
- dmxLog(dmxDebug, "FontPath[%d] = %s\n", i, fp[i]);
-#endif
-
- return fp;
-}
-
-static void dmxFreeFontPath(char **fp)
-{
- xfree(fp[0]);
- xfree(fp);
-}
-
-static Bool dmxCheckFontPathElement(DMXScreenInfo *dmxScreen, char *fp)
-{
- int (*oldErrorHandler)(Display *, XErrorEvent *);
-
- if (!dmxScreen->beDisplay)
- return TRUE;
-
- dmxFontLastError = 0;
- oldErrorHandler = XSetErrorHandler(dmxFontErrorHandler);
- XSetFontPath(dmxScreen->beDisplay, &fp, 1);
- dmxSync(dmxScreen, TRUE); /* Must complete before removing handler */
- XSetErrorHandler(oldErrorHandler);
-
- return (dmxFontLastError == 0);
-}
-
-static int dmxSetFontPath(DMXScreenInfo *dmxScreen)
-{
- int (*oldErrorHandler)(Display *, XErrorEvent *);
- char **fp;
- int result = Success;
- int npaths;
-
- if (!dmxScreen->beDisplay)
- return result;
-
- fp = dmxGetFontPath(&npaths);
- if (!fp) return BadAlloc;
-
- dmxFontLastError = 0;
- oldErrorHandler = XSetErrorHandler(dmxFontErrorHandler);
- XSetFontPath(dmxScreen->beDisplay, fp, npaths);
- dmxSync(dmxScreen, TRUE); /* Must complete before removing handler */
- XSetErrorHandler(oldErrorHandler);
-
- if (dmxFontLastError) {
- result = dmxFontLastError;
- /* We could set *error here to the offending path, but it is
- * ignored, so we don't bother figuring out which path is bad.
- * If we do add this support in the future, we'll need to add
- * error to the function's argument list.
- */
- }
-
- dmxFreeFontPath(fp);
-
- return result;
-}
-
-static int dmxCheckFontPath(DMXScreenInfo *dmxScreen, int *error)
-{
- char **oldFontPath;
- int nOldPaths;
- int result = Success;
-
- if (!dmxScreen->beDisplay)
- return result;
-
- /* Save old font path */
- oldFontPath = XGetFontPath(dmxScreen->beDisplay, &nOldPaths);
-
- result = dmxSetFontPath(dmxScreen);
-
- /* Restore old font path */
- XSetFontPath(dmxScreen->beDisplay, oldFontPath, nOldPaths);
- XFreeFontPath(oldFontPath);
- dmxSync(dmxScreen, FALSE);
-
- return result;
-}
-
-static int dmxProcSetFontPath(ClientPtr client)
-{
- unsigned char *ptr;
- unsigned long nbytes, total, n;
- long nfonts;
- int i, result;
- int error;
- unsigned char *oldFontPath, *tmpFontPath;
- int nOldPaths;
- int lenOldPaths;
- REQUEST(xSetFontPathReq);
-
- REQUEST_AT_LEAST_SIZE(xSetFontPathReq);
-
- nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq);
- total = nbytes;
- ptr = (unsigned char *)&stuff[1];
- nfonts = stuff->nFonts;
-
- while (--nfonts >= 0) {
- if ((total == 0) || (total < (n = (*ptr + 1))))
- return BadLength;
- total -= n;
- ptr += n;
- }
- if (total >= 4)
- return BadLength;
-
- GetFontPath(serverClient, &nOldPaths, &lenOldPaths, &tmpFontPath);
- oldFontPath = xalloc(nOldPaths + lenOldPaths);
- memmove(oldFontPath, tmpFontPath, nOldPaths + lenOldPaths);
-
- result = SetFontPath(client, stuff->nFonts, (unsigned char *)&stuff[1],
- &error);
- if (!result) {
- for (i = 0; i < dmxNumScreens; i++)
- if ((result = dmxCheckFontPath(&dmxScreens[i], &error)))
- break;
-
- if (result) {
- int ignoreresult, ignoreerror;
-
- /* Restore old fontpath in the DMX server */
- ignoreresult = SetFontPath(client, nOldPaths, oldFontPath,
- &ignoreerror);
- } else {
- result = client->noClientException;
- client->errorValue = error;
- }
- }
-
- xfree(oldFontPath);
- return result;
-}
-
-/** Initialize font support. In addition to the screen function call
- * pointers, DMX also hooks in at the ProcVector[] level. Here the old
- * ProcVector function pointers are saved and the new ProcVector
- * function pointers are initialized. */
-void dmxInitFonts(void)
-{
- int i;
-
- for (i = 0; i < 256; i++)
- dmxSaveProcVector[i] = ProcVector[i];
-
- ProcVector[X_SetFontPath] = dmxProcSetFontPath;
-}
-
-/** Reset font support by restoring the original ProcVector function
- * pointers. */
-void dmxResetFonts(void)
-{
- int i;
-
- for (i = 0; i < 256; i++)
- ProcVector[i] = dmxSaveProcVector[i];
-}
-
-/** Load the font, \a pFont, on the back-end server associated with \a
- * pScreen. When a font is loaded, the font path on back-end server is
- * first initialized to that specified on the command line with the
- * -fontpath options, and then the font is loaded. */
-Bool dmxBELoadFont(ScreenPtr pScreen, FontPtr pFont)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxFontPrivPtr pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex);
- const char *name;
- char **oldFontPath = NULL;
- int nOldPaths;
- Atom name_atom, value_atom;
- int i;
-
- /* Make sure we have a font private struct to work with */
- if (!pFontPriv)
- return FALSE;
-
- /* Don't load a font over top of itself */
- if (pFontPriv->font[pScreen->myNum]) {
- return TRUE; /* Already loaded font */
- }
-
- /* Save old font path */
- oldFontPath = XGetFontPath(dmxScreen->beDisplay, &nOldPaths);
-
- /* Set the font path for the font about to be loaded on the back-end */
- if (dmxSetFontPath(dmxScreen)) {
- char **fp;
- int npaths;
- Bool *goodfps;
-
- /* This could fail only when first starting the X server and
- * loading the default font. If it fails here, then the default
- * font path is invalid, no default font path will be set, the
- * DMX server will fail to load the default font, and it will
- * exit with an error unless we remove the offending font paths
- * with the -ignorebadfontpaths command line option.
- */
-
- fp = dmxGetFontPath(&npaths);
- if (!fp) {
- dmxLog(dmxError,
- "No default font path set.\n");
- dmxLog(dmxError,
- "Please see the Xdmx man page for information on how to\n");
- dmxLog(dmxError,
- "initialize the DMX server's default font path.\n");
- XFreeFontPath(oldFontPath);
- return FALSE;
- }
-
- if (!dmxFontPath)
- dmxLog(dmxWarning, "No default font path is set.\n");
-
- goodfps = xalloc(npaths * sizeof(*goodfps));
-
- dmxLog(dmxError,
- "The DMX server failed to set the following font paths on "
- "screen #%d:\n", pScreen->myNum);
-
- for (i = 0; i < npaths; i++)
- if (!(goodfps[i] = dmxCheckFontPathElement(dmxScreen, fp[i])))
- dmxLog(dmxError, " %s\n", fp[i]);
-
- if (dmxIgnoreBadFontPaths) {
- char *newfp;
- int newnpaths = 0;
- int len = 0;
- int j = 0;
- int error;
-
- dmxLog(dmxError,
- "These font paths will not be used because the "
- "\"-ignorebadfontpaths\"\n");
- dmxLog(dmxError,
- "option is set.\n");
-
- for (i = 0; i < npaths; i++)
- if (goodfps[i]) {
- len += strlen(fp[i]) + 1;
- newnpaths++;
- }
-
- if (!newnpaths) {
- /* No valid font paths were found */
- dmxLog(dmxError,
- "After removing the font paths above, no valid font "
- "paths were\n");
- dmxLog(dmxError,
- "available. Please check that the font paths set on "
- "the command\n");
- dmxLog(dmxError,
- "line or in the configuration file via the "
- "\"-fontpath\" option\n");
- dmxLog(dmxError,
- "are valid on all back-end servers. See the Xdmx man "
- "page for\n");
- dmxLog(dmxError,
- "more information on font paths.\n");
- dmxFreeFontPath(fp);
- XFreeFontPath(oldFontPath);
- xfree(goodfps);
- return FALSE;
- }
-
- newfp = xalloc(len * sizeof(*newfp));
- for (i = 0; i < npaths; i++) {
- if (goodfps[i]) {
- int n = strlen(fp[i]);
- newfp[j++] = n;
- strncpy(&newfp[j], fp[i], n);
- j += n;
- }
- }
-
- if (SetFontPath(serverClient, newnpaths, (unsigned char *)newfp,
- &error)) {
- /* Note that this should never happen since all of the
- * FPEs were previously valid. */
- dmxLog(dmxError, "Cannot reset the default font path.\n");
- }
- } else if (dmxFontPath) {
- dmxLog(dmxError,
- "Please remove these font paths from the command line "
- "or\n");
- dmxLog(dmxError,
- "configuration file, or set the \"-ignorebadfontpaths\" "
- "option to\n");
- dmxLog(dmxError,
- "ignore them. For more information on these options, see "
- "the\n");
- dmxLog(dmxError,
- "Xdmx man page.\n");
- } else {
- dmxLog(dmxError,
- "Please specify the font paths that are available on all "
- "back-end\n");
- dmxLog(dmxError,
- "servers with the \"-fontpath\" option, or use the "
- "\"-ignorebadfontpaths\"\n");
- dmxLog(dmxError,
- "to ignore bad defaults. For more information on "
- "these and other\n");
- dmxLog(dmxError,
- "font-path-related options, see the Xdmx man page.\n");
- }
-
- if (!dmxIgnoreBadFontPaths ||
- (dmxIgnoreBadFontPaths && dmxSetFontPath(dmxScreen))) {
- /* We still have errors so return with error */
- dmxFreeFontPath(fp);
- XFreeFontPath(oldFontPath);
- xfree(goodfps);
- return FALSE;
- }
- }
-
- /* Find requested font on back-end server */
- name_atom = MakeAtom("FONT", 4, TRUE);
- value_atom = 0L;
-
- for (i = 0; i < pFont->info.nprops; i++) {
- if ((Atom)pFont->info.props[i].name == name_atom) {
- value_atom = pFont->info.props[i].value;
- break;
- }
- }
- if (!value_atom) return FALSE;
-
- name = NameForAtom(value_atom);
- if (!name) return FALSE;
-
- pFontPriv->font[pScreen->myNum] =
- XLoadQueryFont(dmxScreen->beDisplay, name);
-
- /* Restore old font path */
- XSetFontPath(dmxScreen->beDisplay, oldFontPath, nOldPaths);
- XFreeFontPath(oldFontPath);
- dmxSync(dmxScreen, FALSE);
-
- if (!pFontPriv->font[pScreen->myNum]) return FALSE;
-
- return TRUE;
-}
-
-/** Realize the font, \a pFont, on the back-end server associated with
- * \a pScreen. */
-Bool dmxRealizeFont(ScreenPtr pScreen, FontPtr pFont)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxFontPrivPtr pFontPriv;
-
- if (!(pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex))) {
- FontSetPrivate(pFont, dmxFontPrivateIndex, NULL);
- pFontPriv = xalloc(sizeof(dmxFontPrivRec));
- if (!pFontPriv) return FALSE;
- pFontPriv->font = NULL;
- MAXSCREENSALLOC(pFontPriv->font);
- if (!pFontPriv->font) {
- xfree(pFontPriv);
- return FALSE;
- }
- pFontPriv->refcnt = 0;
- }
-
- FontSetPrivate(pFont, dmxFontPrivateIndex, (pointer)pFontPriv);
-
- if (dmxScreen->beDisplay) {
- if (!dmxBELoadFont(pScreen, pFont))
- return FALSE;
-
- pFontPriv->refcnt++;
- } else {
- pFontPriv->font[pScreen->myNum] = NULL;
- }
-
- return TRUE;
-}
-
-/** Free \a pFont on the back-end associated with \a pScreen. */
-Bool dmxBEFreeFont(ScreenPtr pScreen, FontPtr pFont)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxFontPrivPtr pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex);
-
- if (pFontPriv && pFontPriv->font[pScreen->myNum]) {
- XFreeFont(dmxScreen->beDisplay, pFontPriv->font[pScreen->myNum]);
- pFontPriv->font[pScreen->myNum] = NULL;
- return TRUE;
- }
-
- return FALSE;
-}
-
-/** Unrealize the font, \a pFont, on the back-end server associated with
- * \a pScreen. */
-Bool dmxUnrealizeFont(ScreenPtr pScreen, FontPtr pFont)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxFontPrivPtr pFontPriv;
-
- if ((pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex))) {
- /* In case the font failed to load properly */
- if (!pFontPriv->refcnt) {
- MAXSCREENSFREE(pFontPriv->font);
- xfree(pFontPriv);
- FontSetPrivate(pFont, dmxFontPrivateIndex, NULL);
- } else if (pFontPriv->font[pScreen->myNum]) {
- if (dmxScreen->beDisplay)
- dmxBEFreeFont(pScreen, pFont);
-
- /* The code below is non-obvious, so here's an explanation...
- *
- * When creating the default GC, the server opens up the
- * default font once for each screen, which in turn calls
- * the RealizeFont function pointer once for each screen.
- * During this process both dix's font refcnt and DMX's font
- * refcnt are incremented once for each screen.
- *
- * Later, when shutting down the X server, dix shuts down
- * each screen in reverse order. During this shutdown
- * procedure, each screen's default GC is freed and then
- * that screen is closed by calling the CloseScreen function
- * pointer. screenInfo.numScreens is then decremented after
- * closing each screen. This procedure means that the dix's
- * font refcnt for the font used by the default GC's is
- * decremented once for each screen # greater than 0.
- * However, since dix's refcnt for the default font is not
- * yet 0 for each screen greater than 0, no call to the
- * UnrealizeFont function pointer is made for those screens.
- * Then, when screen 0 is being closed, dix's font refcnt
- * for the default GC's font is finally 0 and the font is
- * unrealized. However, since screenInfo.numScreens has
- * been decremented already down to 1, only one call to
- * UnrealizeFont is made (for screen 0). Thus, even though
- * RealizeFont was called once for each screen,
- * UnrealizeFont is only called for screen 0.
- *
- * This is a bug in dix.
- *
- * To avoid the memory leak of pFontPriv for each server
- * generation, we can also free pFontPriv if the refcnt is
- * not yet 0 but the # of screens is 1 -- i.e., the case
- * described in the dix bug above. This is only a temporary
- * workaround until the bug in dix is solved.
- *
- * The other problem is that the font structure allocated by
- * XLoadQueryFont() above is not freed for screens > 0.
- * This problem cannot be worked around here since the back-
- * end displays for screens > 0 have already been closed by
- * the time this code is called from dix.
- *
- * When the bug in dix described above is fixed, then we can
- * remove the "|| screenInfo.numScreens == 1" code below and
- * the memory leaks will be eliminated.
- */
- if (--pFontPriv->refcnt == 0
-#if 1
- /* Remove this code when the dix bug is fixed */
- || screenInfo.numScreens == 1
-#endif
- ) {
- MAXSCREENSFREE(pFontPriv->font);
- xfree(pFontPriv);
- FontSetPrivate(pFont, dmxFontPrivateIndex, NULL);
- }
- }
- }
-
- return TRUE;
-}
+/*
+ * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina.
+ *
+ * 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 on 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 (including the
+ * next paragraph) 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
+ * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
+ * 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.
+ */
+
+/*
+ * Authors:
+ * Kevin E. Martin <kem@redhat.com>
+ *
+ */
+
+/** \file
+ * This file provides support for fonts. */
+
+#ifdef HAVE_DMX_CONFIG_H
+#include <dmx-config.h>
+#endif
+
+#define DMX_FONTPATH_DEBUG 0
+
+#include "dmx.h"
+#include "dmxsync.h"
+#include "dmxfont.h"
+#include "dmxlog.h"
+
+#include <X11/fonts/fontstruct.h>
+#include "dixfont.h"
+#include "dixstruct.h"
+
+static int (*dmxSaveProcVector[256])(ClientPtr);
+static int dmxFontLastError;
+
+static int dmxFontErrorHandler(Display *dpy, XErrorEvent *ev)
+{
+ dmxFontLastError = ev->error_code;
+
+ return 0;
+}
+
+static char **dmxGetFontPath(int *npaths)
+{
+ char **fp;
+ unsigned char *c, *paths;
+ char *newfp;
+ int len, l, i;
+
+ GetFontPath(serverClient, npaths, &len, &paths);
+
+ newfp = malloc(*npaths + len);
+ c = (unsigned char *)newfp;
+ fp = malloc(*npaths * sizeof(*fp));
+
+ memmove(newfp, paths+1, *npaths + len - 1);
+ l = *paths;
+ for (i = 0; i < *npaths; i++) {
+ fp[i] = (char *)c;
+ c += l;
+ l = *c;
+ *c++ = '\0';
+ }
+
+#if DMX_FONTPATH_DEBUG
+ for (i = 0; i < *npaths; i++)
+ dmxLog(dmxDebug, "FontPath[%d] = %s\n", i, fp[i]);
+#endif
+
+ return fp;
+}
+
+static void dmxFreeFontPath(char **fp)
+{
+ free(fp[0]);
+ free(fp);
+}
+
+static Bool dmxCheckFontPathElement(DMXScreenInfo *dmxScreen, char *fp)
+{
+ int (*oldErrorHandler)(Display *, XErrorEvent *);
+
+ if (!dmxScreen->beDisplay)
+ return TRUE;
+
+ dmxFontLastError = 0;
+ oldErrorHandler = XSetErrorHandler(dmxFontErrorHandler);
+ XSetFontPath(dmxScreen->beDisplay, &fp, 1);
+ dmxSync(dmxScreen, TRUE); /* Must complete before removing handler */
+ XSetErrorHandler(oldErrorHandler);
+
+ return (dmxFontLastError == 0);
+}
+
+static int dmxSetFontPath(DMXScreenInfo *dmxScreen)
+{
+ int (*oldErrorHandler)(Display *, XErrorEvent *);
+ char **fp;
+ int result = Success;
+ int npaths;
+
+ if (!dmxScreen->beDisplay)
+ return result;
+
+ fp = dmxGetFontPath(&npaths);
+ if (!fp) return BadAlloc;
+
+ dmxFontLastError = 0;
+ oldErrorHandler = XSetErrorHandler(dmxFontErrorHandler);
+ XSetFontPath(dmxScreen->beDisplay, fp, npaths);
+ dmxSync(dmxScreen, TRUE); /* Must complete before removing handler */
+ XSetErrorHandler(oldErrorHandler);
+
+ if (dmxFontLastError) {
+ result = dmxFontLastError;
+ /* We could set *error here to the offending path, but it is
+ * ignored, so we don't bother figuring out which path is bad.
+ * If we do add this support in the future, we'll need to add
+ * error to the function's argument list.
+ */
+ }
+
+ dmxFreeFontPath(fp);
+
+ return result;
+}
+
+static int dmxCheckFontPath(DMXScreenInfo *dmxScreen, int *error)
+{
+ char **oldFontPath;
+ int nOldPaths;
+ int result = Success;
+
+ if (!dmxScreen->beDisplay)
+ return result;
+
+ /* Save old font path */
+ oldFontPath = XGetFontPath(dmxScreen->beDisplay, &nOldPaths);
+
+ result = dmxSetFontPath(dmxScreen);
+
+ /* Restore old font path */
+ XSetFontPath(dmxScreen->beDisplay, oldFontPath, nOldPaths);
+ XFreeFontPath(oldFontPath);
+ dmxSync(dmxScreen, FALSE);
+
+ return result;
+}
+
+static int dmxProcSetFontPath(ClientPtr client)
+{
+ unsigned char *ptr;
+ unsigned long nbytes, total, n;
+ long nfonts;
+ int i, result;
+ unsigned char *oldFontPath, *tmpFontPath;
+ int nOldPaths;
+ int lenOldPaths;
+ REQUEST(xSetFontPathReq);
+
+ REQUEST_AT_LEAST_SIZE(xSetFontPathReq);
+
+ nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq);
+ total = nbytes;
+ ptr = (unsigned char *)&stuff[1];
+ nfonts = stuff->nFonts;
+
+ while (--nfonts >= 0) {
+ if ((total == 0) || (total < (n = (*ptr + 1))))
+ return BadLength;
+ total -= n;
+ ptr += n;
+ }
+ if (total >= 4)
+ return BadLength;
+
+ GetFontPath(serverClient, &nOldPaths, &lenOldPaths, &tmpFontPath);
+ oldFontPath = malloc(nOldPaths + lenOldPaths);
+ memmove(oldFontPath, tmpFontPath, nOldPaths + lenOldPaths);
+
+ result = SetFontPath(client, stuff->nFonts, (unsigned char *)&stuff[1]);
+ if (!result) {
+ int error = 0;
+ for (i = 0; i < dmxNumScreens; i++)
+ if ((result = dmxCheckFontPath(&dmxScreens[i], &error)))
+ break;
+
+ if (result) {
+ /* Restore old fontpath in the DMX server */
+ SetFontPath(client, nOldPaths, oldFontPath);
+ client->errorValue = error;
+ }
+ }
+
+ free(oldFontPath);
+ return result;
+}
+
+/** Initialize font support. In addition to the screen function call
+ * pointers, DMX also hooks in at the ProcVector[] level. Here the old
+ * ProcVector function pointers are saved and the new ProcVector
+ * function pointers are initialized. */
+void dmxInitFonts(void)
+{
+ int i;
+
+ for (i = 0; i < 256; i++)
+ dmxSaveProcVector[i] = ProcVector[i];
+
+ ProcVector[X_SetFontPath] = dmxProcSetFontPath;
+}
+
+/** Reset font support by restoring the original ProcVector function
+ * pointers. */
+void dmxResetFonts(void)
+{
+ int i;
+
+ for (i = 0; i < 256; i++)
+ ProcVector[i] = dmxSaveProcVector[i];
+}
+
+/** Load the font, \a pFont, on the back-end server associated with \a
+ * pScreen. When a font is loaded, the font path on back-end server is
+ * first initialized to that specified on the command line with the
+ * -fontpath options, and then the font is loaded. */
+Bool dmxBELoadFont(ScreenPtr pScreen, FontPtr pFont)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxFontPrivPtr pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex);
+ const char *name;
+ char **oldFontPath = NULL;
+ int nOldPaths;
+ Atom name_atom, value_atom;
+ int i;
+
+ /* Make sure we have a font private struct to work with */
+ if (!pFontPriv)
+ return FALSE;
+
+ /* Don't load a font over top of itself */
+ if (pFontPriv->font[pScreen->myNum]) {
+ return TRUE; /* Already loaded font */
+ }
+
+ /* Save old font path */
+ oldFontPath = XGetFontPath(dmxScreen->beDisplay, &nOldPaths);
+
+ /* Set the font path for the font about to be loaded on the back-end */
+ if (dmxSetFontPath(dmxScreen)) {
+ char **fp;
+ int npaths;
+ Bool *goodfps;
+
+ /* This could fail only when first starting the X server and
+ * loading the default font. If it fails here, then the default
+ * font path is invalid, no default font path will be set, the
+ * DMX server will fail to load the default font, and it will
+ * exit with an error unless we remove the offending font paths
+ * with the -ignorebadfontpaths command line option.
+ */
+
+ fp = dmxGetFontPath(&npaths);
+ if (!fp) {
+ dmxLog(dmxError,
+ "No default font path set.\n");
+ dmxLog(dmxError,
+ "Please see the Xdmx man page for information on how to\n");
+ dmxLog(dmxError,
+ "initialize the DMX server's default font path.\n");
+ XFreeFontPath(oldFontPath);
+ return FALSE;
+ }
+
+ if (!dmxFontPath)
+ dmxLog(dmxWarning, "No default font path is set.\n");
+
+ goodfps = malloc(npaths * sizeof(*goodfps));
+
+ dmxLog(dmxError,
+ "The DMX server failed to set the following font paths on "
+ "screen #%d:\n", pScreen->myNum);
+
+ for (i = 0; i < npaths; i++)
+ if (!(goodfps[i] = dmxCheckFontPathElement(dmxScreen, fp[i])))
+ dmxLog(dmxError, " %s\n", fp[i]);
+
+ if (dmxIgnoreBadFontPaths) {
+ char *newfp;
+ int newnpaths = 0;
+ int len = 0;
+ int j = 0;
+
+ dmxLog(dmxError,
+ "These font paths will not be used because the "
+ "\"-ignorebadfontpaths\"\n");
+ dmxLog(dmxError,
+ "option is set.\n");
+
+ for (i = 0; i < npaths; i++)
+ if (goodfps[i]) {
+ len += strlen(fp[i]) + 1;
+ newnpaths++;
+ }
+
+ if (!newnpaths) {
+ /* No valid font paths were found */
+ dmxLog(dmxError,
+ "After removing the font paths above, no valid font "
+ "paths were\n");
+ dmxLog(dmxError,
+ "available. Please check that the font paths set on "
+ "the command\n");
+ dmxLog(dmxError,
+ "line or in the configuration file via the "
+ "\"-fontpath\" option\n");
+ dmxLog(dmxError,
+ "are valid on all back-end servers. See the Xdmx man "
+ "page for\n");
+ dmxLog(dmxError,
+ "more information on font paths.\n");
+ dmxFreeFontPath(fp);
+ XFreeFontPath(oldFontPath);
+ free(goodfps);
+ return FALSE;
+ }
+
+ newfp = malloc(len * sizeof(*newfp));
+ for (i = 0; i < npaths; i++) {
+ if (goodfps[i]) {
+ int n = strlen(fp[i]);
+ newfp[j++] = n;
+ strncpy(&newfp[j], fp[i], n);
+ j += n;
+ }
+ }
+
+ if (SetFontPath(serverClient, newnpaths, (unsigned char *)newfp)) {
+ /* Note that this should never happen since all of the
+ * FPEs were previously valid. */
+ dmxLog(dmxError, "Cannot reset the default font path.\n");
+ }
+ } else if (dmxFontPath) {
+ dmxLog(dmxError,
+ "Please remove these font paths from the command line "
+ "or\n");
+ dmxLog(dmxError,
+ "configuration file, or set the \"-ignorebadfontpaths\" "
+ "option to\n");
+ dmxLog(dmxError,
+ "ignore them. For more information on these options, see "
+ "the\n");
+ dmxLog(dmxError,
+ "Xdmx man page.\n");
+ } else {
+ dmxLog(dmxError,
+ "Please specify the font paths that are available on all "
+ "back-end\n");
+ dmxLog(dmxError,
+ "servers with the \"-fontpath\" option, or use the "
+ "\"-ignorebadfontpaths\"\n");
+ dmxLog(dmxError,
+ "to ignore bad defaults. For more information on "
+ "these and other\n");
+ dmxLog(dmxError,
+ "font-path-related options, see the Xdmx man page.\n");
+ }
+
+ if (!dmxIgnoreBadFontPaths ||
+ (dmxIgnoreBadFontPaths && dmxSetFontPath(dmxScreen))) {
+ /* We still have errors so return with error */
+ dmxFreeFontPath(fp);
+ XFreeFontPath(oldFontPath);
+ free(goodfps);
+ return FALSE;
+ }
+ }
+
+ /* Find requested font on back-end server */
+ name_atom = MakeAtom("FONT", 4, TRUE);
+ value_atom = 0L;
+
+ for (i = 0; i < pFont->info.nprops; i++) {
+ if ((Atom)pFont->info.props[i].name == name_atom) {
+ value_atom = pFont->info.props[i].value;
+ break;
+ }
+ }
+ if (!value_atom) return FALSE;
+
+ name = NameForAtom(value_atom);
+ if (!name) return FALSE;
+
+ pFontPriv->font[pScreen->myNum] =
+ XLoadQueryFont(dmxScreen->beDisplay, name);
+
+ /* Restore old font path */
+ XSetFontPath(dmxScreen->beDisplay, oldFontPath, nOldPaths);
+ XFreeFontPath(oldFontPath);
+ dmxSync(dmxScreen, FALSE);
+
+ if (!pFontPriv->font[pScreen->myNum]) return FALSE;
+
+ return TRUE;
+}
+
+/** Realize the font, \a pFont, on the back-end server associated with
+ * \a pScreen. */
+Bool dmxRealizeFont(ScreenPtr pScreen, FontPtr pFont)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxFontPrivPtr pFontPriv;
+
+ if (!(pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex))) {
+ FontSetPrivate(pFont, dmxFontPrivateIndex, NULL);
+ pFontPriv = malloc(sizeof(dmxFontPrivRec));
+ if (!pFontPriv) return FALSE;
+ pFontPriv->font = NULL;
+ MAXSCREENSALLOC(pFontPriv->font);
+ if (!pFontPriv->font) {
+ free(pFontPriv);
+ return FALSE;
+ }
+ pFontPriv->refcnt = 0;
+ }
+
+ FontSetPrivate(pFont, dmxFontPrivateIndex, (pointer)pFontPriv);
+
+ if (dmxScreen->beDisplay) {
+ if (!dmxBELoadFont(pScreen, pFont))
+ return FALSE;
+
+ pFontPriv->refcnt++;
+ } else {
+ pFontPriv->font[pScreen->myNum] = NULL;
+ }
+
+ return TRUE;
+}
+
+/** Free \a pFont on the back-end associated with \a pScreen. */
+Bool dmxBEFreeFont(ScreenPtr pScreen, FontPtr pFont)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxFontPrivPtr pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex);
+
+ if (pFontPriv && pFontPriv->font[pScreen->myNum]) {
+ XFreeFont(dmxScreen->beDisplay, pFontPriv->font[pScreen->myNum]);
+ pFontPriv->font[pScreen->myNum] = NULL;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/** Unrealize the font, \a pFont, on the back-end server associated with
+ * \a pScreen. */
+Bool dmxUnrealizeFont(ScreenPtr pScreen, FontPtr pFont)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxFontPrivPtr pFontPriv;
+
+ if ((pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex))) {
+ /* In case the font failed to load properly */
+ if (!pFontPriv->refcnt) {
+ MAXSCREENSFREE(pFontPriv->font);
+ free(pFontPriv);
+ FontSetPrivate(pFont, dmxFontPrivateIndex, NULL);
+ } else if (pFontPriv->font[pScreen->myNum]) {
+ if (dmxScreen->beDisplay)
+ dmxBEFreeFont(pScreen, pFont);
+
+ /* The code below is non-obvious, so here's an explanation...
+ *
+ * When creating the default GC, the server opens up the
+ * default font once for each screen, which in turn calls
+ * the RealizeFont function pointer once for each screen.
+ * During this process both dix's font refcnt and DMX's font
+ * refcnt are incremented once for each screen.
+ *
+ * Later, when shutting down the X server, dix shuts down
+ * each screen in reverse order. During this shutdown
+ * procedure, each screen's default GC is freed and then
+ * that screen is closed by calling the CloseScreen function
+ * pointer. screenInfo.numScreens is then decremented after
+ * closing each screen. This procedure means that the dix's
+ * font refcnt for the font used by the default GC's is
+ * decremented once for each screen # greater than 0.
+ * However, since dix's refcnt for the default font is not
+ * yet 0 for each screen greater than 0, no call to the
+ * UnrealizeFont function pointer is made for those screens.
+ * Then, when screen 0 is being closed, dix's font refcnt
+ * for the default GC's font is finally 0 and the font is
+ * unrealized. However, since screenInfo.numScreens has
+ * been decremented already down to 1, only one call to
+ * UnrealizeFont is made (for screen 0). Thus, even though
+ * RealizeFont was called once for each screen,
+ * UnrealizeFont is only called for screen 0.
+ *
+ * This is a bug in dix.
+ *
+ * To avoid the memory leak of pFontPriv for each server
+ * generation, we can also free pFontPriv if the refcnt is
+ * not yet 0 but the # of screens is 1 -- i.e., the case
+ * described in the dix bug above. This is only a temporary
+ * workaround until the bug in dix is solved.
+ *
+ * The other problem is that the font structure allocated by
+ * XLoadQueryFont() above is not freed for screens > 0.
+ * This problem cannot be worked around here since the back-
+ * end displays for screens > 0 have already been closed by
+ * the time this code is called from dix.
+ *
+ * When the bug in dix described above is fixed, then we can
+ * remove the "|| screenInfo.numScreens == 1" code below and
+ * the memory leaks will be eliminated.
+ */
+ if (--pFontPriv->refcnt == 0
+#if 1
+ /* Remove this code when the dix bug is fixed */
+ || screenInfo.numScreens == 1
+#endif
+ ) {
+ MAXSCREENSFREE(pFontPriv->font);
+ free(pFontPriv);
+ FontSetPrivate(pFont, dmxFontPrivateIndex, NULL);
+ }
+ }
+ }
+
+ return TRUE;
+}
diff --git a/xorg-server/hw/dmx/dmxgc.c b/xorg-server/hw/dmx/dmxgc.c
index eb21d3c60..82f74b6e6 100644
--- a/xorg-server/hw/dmx/dmxgc.c
+++ b/xorg-server/hw/dmx/dmxgc.c
@@ -1,421 +1,421 @@
-/*
- * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina.
- *
- * 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 on 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 (including the
- * next paragraph) 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
- * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
- * 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.
- */
-
-/*
- * Authors:
- * Kevin E. Martin <kem@redhat.com>
- *
- */
-
-/** \file
- * This file provides support for GCs. */
-
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
-
-#include "dmx.h"
-#include "dmxsync.h"
-#include "dmxgc.h"
-#include "dmxgcops.h"
-#include "dmxpixmap.h"
-#include "dmxfont.h"
-
-#include "gcstruct.h"
-#include "pixmapstr.h"
-#include "migc.h"
-
-static GCFuncs dmxGCFuncs = {
- dmxValidateGC,
- dmxChangeGC,
- dmxCopyGC,
- dmxDestroyGC,
- dmxChangeClip,
- dmxDestroyClip,
- dmxCopyClip,
-};
-
-static GCOps dmxGCOps = {
- dmxFillSpans,
- dmxSetSpans,
- dmxPutImage,
- dmxCopyArea,
- dmxCopyPlane,
- dmxPolyPoint,
- dmxPolylines,
- dmxPolySegment,
- dmxPolyRectangle,
- dmxPolyArc,
- dmxFillPolygon,
- dmxPolyFillRect,
- dmxPolyFillArc,
- dmxPolyText8,
- dmxPolyText16,
- dmxImageText8,
- dmxImageText16,
- dmxImageGlyphBlt,
- dmxPolyGlyphBlt,
- dmxPushPixels
-};
-
-/** Initialize the GC on \a pScreen */
-Bool dmxInitGC(ScreenPtr pScreen)
-{
- if (!dixRequestPrivate(dmxGCPrivateKey, sizeof(dmxGCPrivRec)))
- return FALSE;
- return TRUE;
-}
-
-/** Create the GC on the back-end server. */
-void dmxBECreateGC(ScreenPtr pScreen, GCPtr pGC)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- int i;
-
- for (i = 0; i < dmxScreen->beNumPixmapFormats; i++) {
- if (pGC->depth == dmxScreen->bePixmapFormats[i].depth) {
- unsigned long mask;
- XGCValues gcvals;
-
- mask = GCGraphicsExposures;
- gcvals.graphics_exposures = FALSE;
-
- /* Create GC in the back-end servers */
- pGCPriv->gc = XCreateGC(dmxScreen->beDisplay,
- dmxScreen->scrnDefDrawables[i],
- mask, &gcvals);
- break;
- }
- }
-}
-
-/** Create a graphics context on the back-end server associated /a pGC's
- * screen. */
-Bool dmxCreateGC(GCPtr pGC)
-{
- ScreenPtr pScreen = pGC->pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- Bool ret;
-
- DMX_UNWRAP(CreateGC, dmxScreen, pScreen);
- if ((ret = pScreen->CreateGC(pGC))) {
- /* Save the old funcs */
- pGCPriv->funcs = pGC->funcs;
- pGCPriv->ops = NULL;
-
- pGC->funcs = &dmxGCFuncs;
-
- if (dmxScreen->beDisplay) {
- dmxBECreateGC(pScreen, pGC);
- } else {
- pGCPriv->gc = NULL;
- }
-
- /* Check for "magic special case"
- * 1. see CreateGC in dix/gc.c for more info
- * 2. see dmxChangeGC for more info
- */
- pGCPriv->msc = (!pGC->tileIsPixel && !pGC->tile.pixmap);
- }
- DMX_WRAP(CreateGC, dmxCreateGC, dmxScreen, pScreen);
-
- return ret;
-}
-
-/** Validate a graphics context, \a pGC, locally in the DMX server and
- * recompute the composite clip, if necessary. */
-void dmxValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
-{
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
-
- DMX_GC_FUNC_PROLOGUE(pGC);
-#if 0
- pGC->funcs->ValidateGC(pGC, changes, pDrawable);
-#endif
-
- if (pDrawable->type == DRAWABLE_WINDOW ||
- pDrawable->type == DRAWABLE_PIXMAP) {
- /* Save the old ops, since we're about to change the ops in the
- * epilogue.
- */
- pGCPriv->ops = pGC->ops;
- } else {
- pGCPriv->ops = NULL;
- }
-
- /* If the client clip is different or moved OR the subwindowMode has
- * changed OR the window's clip has changed since the last
- * validation, then we need to recompute the composite clip.
- */
- if ((changes & (GCClipXOrigin |
- GCClipYOrigin |
- GCClipMask |
- GCSubwindowMode)) ||
- (pDrawable->serialNumber !=
- (pGC->serialNumber & DRAWABLE_SERIAL_BITS))) {
- miComputeCompositeClip(pGC, pDrawable);
- }
-
- DMX_GC_FUNC_EPILOGUE(pGC);
-}
-
-/** Set the values in the graphics context on the back-end server
- * associated with \a pGC's screen. */
-void dmxChangeGC(GCPtr pGC, unsigned long mask)
-{
- ScreenPtr pScreen = pGC->pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- XGCValues v;
-
- DMX_GC_FUNC_PROLOGUE(pGC);
-#if 0
- pGC->funcs->ChangeGC(pGC, mask);
-#endif
-
- /* Handle "magic special case" from CreateGC */
- if (pGCPriv->msc) {
- /* The "magic special case" is used to handle the case where a
- * foreground pixel is set when the GC is created so that a
- * "pseudo default-tile" can be created and used in case the
- * fillstyle was set to FillTiled. This specific case is tested
- * in xtest (XCreateGC test #3). What has happened in dix by
- * the time it reaches here is (1) the pGC->tile.pixel has been
- * set to pGC->fgPixel and pGC->tileIsPixel is set, (2) if a
- * tile has also been set, then pGC->tileIsPixel is unset and
- * pGC->tile.pixmap is initialized; else, the default tile is
- * created and pGC->tileIsPixel is unset and pGC->tile.pixmap is
- * initialized to the "pseudo default-tile". In either case,
- * pGC->tile.pixmap is set; however, in the "magic special case"
- * the mask is not updated to allow us to detect that we should
- * initialize the GCTile in the back-end server. Thus, we catch
- * this case in dmxCreateGC and add GCTile to the mask here.
- * Are there any cases that I've missed?
- */
-
- /* Make sure that the tile.pixmap is set, just in case the user
- * set GCTile in the mask but forgot to set vals.pixmap
- */
- if (pGC->tile.pixmap) mask |= GCTile;
-
- /* This only happens once when the GC is created */
- pGCPriv->msc = FALSE;
- }
-
- /* Update back-end server's gc */
- if (mask & GCFunction) v.function = pGC->alu;
- if (mask & GCPlaneMask) v.plane_mask = pGC->planemask;
- if (mask & GCForeground) v.foreground = pGC->fgPixel;
- if (mask & GCBackground) v.background = pGC->bgPixel;
- if (mask & GCLineWidth) v.line_width = pGC->lineWidth;
- if (mask & GCLineStyle) v.line_style = pGC->lineStyle;
- if (mask & GCCapStyle) v.cap_style = pGC->capStyle;
- if (mask & GCJoinStyle) v.join_style = pGC->joinStyle;
- if (mask & GCFillStyle) v.fill_style = pGC->fillStyle;
- if (mask & GCFillRule) v.fill_rule = pGC->fillRule;
- if (mask & GCTile) {
- if (pGC->tileIsPixel) {
- mask &= ~GCTile;
- } else {
- dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pGC->tile.pixmap);
- v.tile = (Drawable)pPixPriv->pixmap;
- }
- }
- if (mask & GCStipple) {
- dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pGC->stipple);
- v.stipple = (Drawable)pPixPriv->pixmap;
- }
- if (mask & GCTileStipXOrigin) v.ts_x_origin = pGC->patOrg.x;
- if (mask & GCTileStipYOrigin) v.ts_y_origin = pGC->patOrg.y;
- if (mask & GCFont) {
- if (dmxScreen->beDisplay) {
- dmxFontPrivPtr pFontPriv;
- pFontPriv = FontGetPrivate(pGC->font, dmxFontPrivateIndex);
- v.font = pFontPriv->font[pScreen->myNum]->fid;
- } else {
- mask &= ~GCFont;
- }
- }
- if (mask & GCSubwindowMode) v.subwindow_mode = pGC->subWindowMode;
-
- /* Graphics exposures are not needed on the back-ends since they can
- be generated on the front-end thereby saving bandwidth. */
- if (mask & GCGraphicsExposures) mask &= ~GCGraphicsExposures;
-
- if (mask & GCClipXOrigin) v.clip_x_origin = pGC->clipOrg.x;
- if (mask & GCClipYOrigin) v.clip_y_origin = pGC->clipOrg.y;
- if (mask & GCClipMask) mask &= ~GCClipMask; /* See ChangeClip */
- if (mask & GCDashOffset) v.dash_offset = pGC->dashOffset;
- if (mask & GCDashList) {
- mask &= ~GCDashList;
- if (dmxScreen->beDisplay)
- XSetDashes(dmxScreen->beDisplay, pGCPriv->gc,
- pGC->dashOffset, (char *)pGC->dash,
- pGC->numInDashList);
- }
- if (mask & GCArcMode) v.arc_mode = pGC->arcMode;
-
- if (mask && dmxScreen->beDisplay) {
- XChangeGC(dmxScreen->beDisplay, pGCPriv->gc, mask, &v);
- dmxSync(dmxScreen, FALSE);
- }
-
- DMX_GC_FUNC_EPILOGUE(pGC);
-}
-
-/** Copy \a pGCSrc to \a pGCDst on the back-end server associated with
- * \a pGCSrc's screen. */
-void dmxCopyGC(GCPtr pGCSrc, unsigned long changes, GCPtr pGCDst)
-{
- ScreenPtr pScreen = pGCSrc->pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxGCPrivPtr pGCSrcPriv = DMX_GET_GC_PRIV(pGCSrc);
- dmxGCPrivPtr pGCDstPriv = DMX_GET_GC_PRIV(pGCDst);
-
- DMX_GC_FUNC_PROLOGUE(pGCDst);
- pGCDst->funcs->CopyGC(pGCSrc, changes, pGCDst);
-
- /* Copy the GC on the back-end server */
- if (dmxScreen->beDisplay)
- XCopyGC(dmxScreen->beDisplay, pGCSrcPriv->gc, changes, pGCDstPriv->gc);
-
- DMX_GC_FUNC_EPILOGUE(pGCDst);
-}
-
-/** Free the \a pGC on the back-end server. */
-Bool dmxBEFreeGC(GCPtr pGC)
-{
- ScreenPtr pScreen = pGC->pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
-
- if (pGCPriv->gc) {
- XFreeGC(dmxScreen->beDisplay, pGCPriv->gc);
- pGCPriv->gc = NULL;
- return TRUE;
- }
-
- return FALSE;
-}
-
-/** Destroy the graphics context, \a pGC and free the corresponding GC
- * on the back-end server. */
-void dmxDestroyGC(GCPtr pGC)
-{
- ScreenPtr pScreen = pGC->pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
-
- DMX_GC_FUNC_PROLOGUE(pGC);
-
- /* Free the GC on the back-end server */
- if (dmxScreen->beDisplay)
- dmxBEFreeGC(pGC);
-
- pGC->funcs->DestroyGC(pGC);
- DMX_GC_FUNC_EPILOGUE(pGC);
-}
-
-/** Change the clip rects for a GC. */
-void dmxChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects)
-{
- ScreenPtr pScreen = pGC->pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
- XRectangle *pRects;
- BoxPtr pBox;
- int i, nRects;
-
- DMX_GC_FUNC_PROLOGUE(pGC);
- pGC->funcs->ChangeClip(pGC, type, pvalue, nrects);
-
- /* Set the client clip on the back-end server */
- switch (pGC->clientClipType) {
- case CT_NONE:
- if (dmxScreen->beDisplay)
- XSetClipMask(dmxScreen->beDisplay, pGCPriv->gc, None);
- break;
-
- case CT_REGION:
- if (dmxScreen->beDisplay) {
- nRects = REGION_NUM_RECTS((RegionPtr)pGC->clientClip);
- pRects = xalloc(nRects * sizeof(*pRects));
- pBox = REGION_RECTS((RegionPtr)pGC->clientClip);
-
- for (i = 0; i < nRects; i++) {
- pRects[i].x = pBox[i].x1;
- pRects[i].y = pBox[i].y1;
- pRects[i].width = pBox[i].x2 - pBox[i].x1;
- pRects[i].height = pBox[i].y2 - pBox[i].y1;
- }
-
- XSetClipRectangles(dmxScreen->beDisplay, pGCPriv->gc,
- pGC->clipOrg.x, pGC->clipOrg.y,
- pRects, nRects, Unsorted);
-
- xfree(pRects);
- }
- break;
-
- case CT_PIXMAP:
- case CT_UNSORTED:
- case CT_YSORTED:
- case CT_YXSORTED:
- case CT_YXBANDED:
- /* These clip types are condensed down to either NONE or REGION
- in the mi code */
- break;
- }
-
- DMX_GC_FUNC_EPILOGUE(pGC);
-}
-
-/** Destroy a GC's clip rects. */
-void dmxDestroyClip(GCPtr pGC)
-{
- ScreenPtr pScreen = pGC->pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
-
- DMX_GC_FUNC_PROLOGUE(pGC);
- pGC->funcs->DestroyClip(pGC);
-
- /* Set the client clip on the back-end server to None */
- if (dmxScreen->beDisplay)
- XSetClipMask(dmxScreen->beDisplay, pGCPriv->gc, None);
-
- DMX_GC_FUNC_EPILOGUE(pGC);
-}
-
-/** Copy a GC's clip rects. */
-void dmxCopyClip(GCPtr pGCDst, GCPtr pGCSrc)
-{
- DMX_GC_FUNC_PROLOGUE(pGCDst);
- pGCDst->funcs->CopyClip(pGCDst, pGCSrc);
- DMX_GC_FUNC_EPILOGUE(pGCDst);
-}
+/*
+ * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina.
+ *
+ * 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 on 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 (including the
+ * next paragraph) 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
+ * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
+ * 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.
+ */
+
+/*
+ * Authors:
+ * Kevin E. Martin <kem@redhat.com>
+ *
+ */
+
+/** \file
+ * This file provides support for GCs. */
+
+#ifdef HAVE_DMX_CONFIG_H
+#include <dmx-config.h>
+#endif
+
+#include "dmx.h"
+#include "dmxsync.h"
+#include "dmxgc.h"
+#include "dmxgcops.h"
+#include "dmxpixmap.h"
+#include "dmxfont.h"
+
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "migc.h"
+
+static GCFuncs dmxGCFuncs = {
+ dmxValidateGC,
+ dmxChangeGC,
+ dmxCopyGC,
+ dmxDestroyGC,
+ dmxChangeClip,
+ dmxDestroyClip,
+ dmxCopyClip,
+};
+
+static GCOps dmxGCOps = {
+ dmxFillSpans,
+ dmxSetSpans,
+ dmxPutImage,
+ dmxCopyArea,
+ dmxCopyPlane,
+ dmxPolyPoint,
+ dmxPolylines,
+ dmxPolySegment,
+ dmxPolyRectangle,
+ dmxPolyArc,
+ dmxFillPolygon,
+ dmxPolyFillRect,
+ dmxPolyFillArc,
+ dmxPolyText8,
+ dmxPolyText16,
+ dmxImageText8,
+ dmxImageText16,
+ dmxImageGlyphBlt,
+ dmxPolyGlyphBlt,
+ dmxPushPixels
+};
+
+/** Initialize the GC on \a pScreen */
+Bool dmxInitGC(ScreenPtr pScreen)
+{
+ if (!dixRequestPrivate(dmxGCPrivateKey, sizeof(dmxGCPrivRec)))
+ return FALSE;
+ return TRUE;
+}
+
+/** Create the GC on the back-end server. */
+void dmxBECreateGC(ScreenPtr pScreen, GCPtr pGC)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
+ int i;
+
+ for (i = 0; i < dmxScreen->beNumPixmapFormats; i++) {
+ if (pGC->depth == dmxScreen->bePixmapFormats[i].depth) {
+ unsigned long mask;
+ XGCValues gcvals;
+
+ mask = GCGraphicsExposures;
+ gcvals.graphics_exposures = FALSE;
+
+ /* Create GC in the back-end servers */
+ pGCPriv->gc = XCreateGC(dmxScreen->beDisplay,
+ dmxScreen->scrnDefDrawables[i],
+ mask, &gcvals);
+ break;
+ }
+ }
+}
+
+/** Create a graphics context on the back-end server associated /a pGC's
+ * screen. */
+Bool dmxCreateGC(GCPtr pGC)
+{
+ ScreenPtr pScreen = pGC->pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
+ Bool ret;
+
+ DMX_UNWRAP(CreateGC, dmxScreen, pScreen);
+ if ((ret = pScreen->CreateGC(pGC))) {
+ /* Save the old funcs */
+ pGCPriv->funcs = pGC->funcs;
+ pGCPriv->ops = NULL;
+
+ pGC->funcs = &dmxGCFuncs;
+
+ if (dmxScreen->beDisplay) {
+ dmxBECreateGC(pScreen, pGC);
+ } else {
+ pGCPriv->gc = NULL;
+ }
+
+ /* Check for "magic special case"
+ * 1. see CreateGC in dix/gc.c for more info
+ * 2. see dmxChangeGC for more info
+ */
+ pGCPriv->msc = (!pGC->tileIsPixel && !pGC->tile.pixmap);
+ }
+ DMX_WRAP(CreateGC, dmxCreateGC, dmxScreen, pScreen);
+
+ return ret;
+}
+
+/** Validate a graphics context, \a pGC, locally in the DMX server and
+ * recompute the composite clip, if necessary. */
+void dmxValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
+{
+ dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
+
+ DMX_GC_FUNC_PROLOGUE(pGC);
+#if 0
+ pGC->funcs->ValidateGC(pGC, changes, pDrawable);
+#endif
+
+ if (pDrawable->type == DRAWABLE_WINDOW ||
+ pDrawable->type == DRAWABLE_PIXMAP) {
+ /* Save the old ops, since we're about to change the ops in the
+ * epilogue.
+ */
+ pGCPriv->ops = pGC->ops;
+ } else {
+ pGCPriv->ops = NULL;
+ }
+
+ /* If the client clip is different or moved OR the subwindowMode has
+ * changed OR the window's clip has changed since the last
+ * validation, then we need to recompute the composite clip.
+ */
+ if ((changes & (GCClipXOrigin |
+ GCClipYOrigin |
+ GCClipMask |
+ GCSubwindowMode)) ||
+ (pDrawable->serialNumber !=
+ (pGC->serialNumber & DRAWABLE_SERIAL_BITS))) {
+ miComputeCompositeClip(pGC, pDrawable);
+ }
+
+ DMX_GC_FUNC_EPILOGUE(pGC);
+}
+
+/** Set the values in the graphics context on the back-end server
+ * associated with \a pGC's screen. */
+void dmxChangeGC(GCPtr pGC, unsigned long mask)
+{
+ ScreenPtr pScreen = pGC->pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
+ XGCValues v;
+
+ DMX_GC_FUNC_PROLOGUE(pGC);
+#if 0
+ pGC->funcs->ChangeGC(pGC, mask);
+#endif
+
+ /* Handle "magic special case" from CreateGC */
+ if (pGCPriv->msc) {
+ /* The "magic special case" is used to handle the case where a
+ * foreground pixel is set when the GC is created so that a
+ * "pseudo default-tile" can be created and used in case the
+ * fillstyle was set to FillTiled. This specific case is tested
+ * in xtest (XCreateGC test #3). What has happened in dix by
+ * the time it reaches here is (1) the pGC->tile.pixel has been
+ * set to pGC->fgPixel and pGC->tileIsPixel is set, (2) if a
+ * tile has also been set, then pGC->tileIsPixel is unset and
+ * pGC->tile.pixmap is initialized; else, the default tile is
+ * created and pGC->tileIsPixel is unset and pGC->tile.pixmap is
+ * initialized to the "pseudo default-tile". In either case,
+ * pGC->tile.pixmap is set; however, in the "magic special case"
+ * the mask is not updated to allow us to detect that we should
+ * initialize the GCTile in the back-end server. Thus, we catch
+ * this case in dmxCreateGC and add GCTile to the mask here.
+ * Are there any cases that I've missed?
+ */
+
+ /* Make sure that the tile.pixmap is set, just in case the user
+ * set GCTile in the mask but forgot to set vals.pixmap
+ */
+ if (pGC->tile.pixmap) mask |= GCTile;
+
+ /* This only happens once when the GC is created */
+ pGCPriv->msc = FALSE;
+ }
+
+ /* Update back-end server's gc */
+ if (mask & GCFunction) v.function = pGC->alu;
+ if (mask & GCPlaneMask) v.plane_mask = pGC->planemask;
+ if (mask & GCForeground) v.foreground = pGC->fgPixel;
+ if (mask & GCBackground) v.background = pGC->bgPixel;
+ if (mask & GCLineWidth) v.line_width = pGC->lineWidth;
+ if (mask & GCLineStyle) v.line_style = pGC->lineStyle;
+ if (mask & GCCapStyle) v.cap_style = pGC->capStyle;
+ if (mask & GCJoinStyle) v.join_style = pGC->joinStyle;
+ if (mask & GCFillStyle) v.fill_style = pGC->fillStyle;
+ if (mask & GCFillRule) v.fill_rule = pGC->fillRule;
+ if (mask & GCTile) {
+ if (pGC->tileIsPixel) {
+ mask &= ~GCTile;
+ } else {
+ dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pGC->tile.pixmap);
+ v.tile = (Drawable)pPixPriv->pixmap;
+ }
+ }
+ if (mask & GCStipple) {
+ dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pGC->stipple);
+ v.stipple = (Drawable)pPixPriv->pixmap;
+ }
+ if (mask & GCTileStipXOrigin) v.ts_x_origin = pGC->patOrg.x;
+ if (mask & GCTileStipYOrigin) v.ts_y_origin = pGC->patOrg.y;
+ if (mask & GCFont) {
+ if (dmxScreen->beDisplay) {
+ dmxFontPrivPtr pFontPriv;
+ pFontPriv = FontGetPrivate(pGC->font, dmxFontPrivateIndex);
+ v.font = pFontPriv->font[pScreen->myNum]->fid;
+ } else {
+ mask &= ~GCFont;
+ }
+ }
+ if (mask & GCSubwindowMode) v.subwindow_mode = pGC->subWindowMode;
+
+ /* Graphics exposures are not needed on the back-ends since they can
+ be generated on the front-end thereby saving bandwidth. */
+ if (mask & GCGraphicsExposures) mask &= ~GCGraphicsExposures;
+
+ if (mask & GCClipXOrigin) v.clip_x_origin = pGC->clipOrg.x;
+ if (mask & GCClipYOrigin) v.clip_y_origin = pGC->clipOrg.y;
+ if (mask & GCClipMask) mask &= ~GCClipMask; /* See ChangeClip */
+ if (mask & GCDashOffset) v.dash_offset = pGC->dashOffset;
+ if (mask & GCDashList) {
+ mask &= ~GCDashList;
+ if (dmxScreen->beDisplay)
+ XSetDashes(dmxScreen->beDisplay, pGCPriv->gc,
+ pGC->dashOffset, (char *)pGC->dash,
+ pGC->numInDashList);
+ }
+ if (mask & GCArcMode) v.arc_mode = pGC->arcMode;
+
+ if (mask && dmxScreen->beDisplay) {
+ XChangeGC(dmxScreen->beDisplay, pGCPriv->gc, mask, &v);
+ dmxSync(dmxScreen, FALSE);
+ }
+
+ DMX_GC_FUNC_EPILOGUE(pGC);
+}
+
+/** Copy \a pGCSrc to \a pGCDst on the back-end server associated with
+ * \a pGCSrc's screen. */
+void dmxCopyGC(GCPtr pGCSrc, unsigned long changes, GCPtr pGCDst)
+{
+ ScreenPtr pScreen = pGCSrc->pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxGCPrivPtr pGCSrcPriv = DMX_GET_GC_PRIV(pGCSrc);
+ dmxGCPrivPtr pGCDstPriv = DMX_GET_GC_PRIV(pGCDst);
+
+ DMX_GC_FUNC_PROLOGUE(pGCDst);
+ pGCDst->funcs->CopyGC(pGCSrc, changes, pGCDst);
+
+ /* Copy the GC on the back-end server */
+ if (dmxScreen->beDisplay)
+ XCopyGC(dmxScreen->beDisplay, pGCSrcPriv->gc, changes, pGCDstPriv->gc);
+
+ DMX_GC_FUNC_EPILOGUE(pGCDst);
+}
+
+/** Free the \a pGC on the back-end server. */
+Bool dmxBEFreeGC(GCPtr pGC)
+{
+ ScreenPtr pScreen = pGC->pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
+
+ if (pGCPriv->gc) {
+ XFreeGC(dmxScreen->beDisplay, pGCPriv->gc);
+ pGCPriv->gc = NULL;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/** Destroy the graphics context, \a pGC and free the corresponding GC
+ * on the back-end server. */
+void dmxDestroyGC(GCPtr pGC)
+{
+ ScreenPtr pScreen = pGC->pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+
+ DMX_GC_FUNC_PROLOGUE(pGC);
+
+ /* Free the GC on the back-end server */
+ if (dmxScreen->beDisplay)
+ dmxBEFreeGC(pGC);
+
+ pGC->funcs->DestroyGC(pGC);
+ DMX_GC_FUNC_EPILOGUE(pGC);
+}
+
+/** Change the clip rects for a GC. */
+void dmxChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects)
+{
+ ScreenPtr pScreen = pGC->pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
+ XRectangle *pRects;
+ BoxPtr pBox;
+ int i, nRects;
+
+ DMX_GC_FUNC_PROLOGUE(pGC);
+ pGC->funcs->ChangeClip(pGC, type, pvalue, nrects);
+
+ /* Set the client clip on the back-end server */
+ switch (pGC->clientClipType) {
+ case CT_NONE:
+ if (dmxScreen->beDisplay)
+ XSetClipMask(dmxScreen->beDisplay, pGCPriv->gc, None);
+ break;
+
+ case CT_REGION:
+ if (dmxScreen->beDisplay) {
+ nRects = REGION_NUM_RECTS((RegionPtr)pGC->clientClip);
+ pRects = malloc(nRects * sizeof(*pRects));
+ pBox = REGION_RECTS((RegionPtr)pGC->clientClip);
+
+ for (i = 0; i < nRects; i++) {
+ pRects[i].x = pBox[i].x1;
+ pRects[i].y = pBox[i].y1;
+ pRects[i].width = pBox[i].x2 - pBox[i].x1;
+ pRects[i].height = pBox[i].y2 - pBox[i].y1;
+ }
+
+ XSetClipRectangles(dmxScreen->beDisplay, pGCPriv->gc,
+ pGC->clipOrg.x, pGC->clipOrg.y,
+ pRects, nRects, Unsorted);
+
+ free(pRects);
+ }
+ break;
+
+ case CT_PIXMAP:
+ case CT_UNSORTED:
+ case CT_YSORTED:
+ case CT_YXSORTED:
+ case CT_YXBANDED:
+ /* These clip types are condensed down to either NONE or REGION
+ in the mi code */
+ break;
+ }
+
+ DMX_GC_FUNC_EPILOGUE(pGC);
+}
+
+/** Destroy a GC's clip rects. */
+void dmxDestroyClip(GCPtr pGC)
+{
+ ScreenPtr pScreen = pGC->pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
+
+ DMX_GC_FUNC_PROLOGUE(pGC);
+ pGC->funcs->DestroyClip(pGC);
+
+ /* Set the client clip on the back-end server to None */
+ if (dmxScreen->beDisplay)
+ XSetClipMask(dmxScreen->beDisplay, pGCPriv->gc, None);
+
+ DMX_GC_FUNC_EPILOGUE(pGC);
+}
+
+/** Copy a GC's clip rects. */
+void dmxCopyClip(GCPtr pGCDst, GCPtr pGCSrc)
+{
+ DMX_GC_FUNC_PROLOGUE(pGCDst);
+ pGCDst->funcs->CopyClip(pGCDst, pGCSrc);
+ DMX_GC_FUNC_EPILOGUE(pGCDst);
+}
diff --git a/xorg-server/hw/dmx/dmxinit.c b/xorg-server/hw/dmx/dmxinit.c
index 617ec5e49..37b302a25 100644
--- a/xorg-server/hw/dmx/dmxinit.c
+++ b/xorg-server/hw/dmx/dmxinit.c
@@ -412,7 +412,7 @@ void dmxGetColormaps(DMXScreenInfo *dmxScreen)
int i;
dmxScreen->beNumDefColormaps = dmxScreen->beNumVisuals;
- dmxScreen->beDefColormaps = xalloc(dmxScreen->beNumDefColormaps *
+ dmxScreen->beDefColormaps = malloc(dmxScreen->beNumDefColormaps *
sizeof(*dmxScreen->beDefColormaps));
for (i = 0; i < dmxScreen->beNumDefColormaps; i++)
@@ -738,7 +738,7 @@ void InitOutput(ScreenInfo *pScreenInfo, int argc, char *argv[])
nconfigs = dmxScreen->numGlxVisuals;
}
- configprivs = xalloc(nconfigs * sizeof(dmxGlxVisualPrivate*));
+ configprivs = malloc(nconfigs * sizeof(dmxGlxVisualPrivate*));
if (configs != NULL && configprivs != NULL) {
@@ -748,7 +748,7 @@ void InitOutput(ScreenInfo *pScreenInfo, int argc, char *argv[])
for (i = 0; i < nconfigs; i++) {
configprivs[i] = (dmxGlxVisualPrivate *)
- xalloc(sizeof(dmxGlxVisualPrivate));
+ malloc(sizeof(dmxGlxVisualPrivate));
configprivs[i]->x_visual_depth = 0;
configprivs[i]->x_visual_class = 0;
@@ -816,11 +816,11 @@ static void dmxSetDefaultFontPath(char *fp)
int len;
len = strlen(dmxFontPath);
- dmxFontPath = xrealloc(dmxFontPath, len+fplen+1);
+ dmxFontPath = realloc(dmxFontPath, len+fplen+1);
dmxFontPath[len] = ',';
strncpy(&dmxFontPath[len+1], fp, fplen);
} else {
- dmxFontPath = xalloc(fplen);
+ dmxFontPath = malloc(fplen);
strncpy(dmxFontPath, fp, fplen);
}
diff --git a/xorg-server/hw/dmx/dmxpict.c b/xorg-server/hw/dmx/dmxpict.c
index efb2e41c9..c7bcd5b91 100644
--- a/xorg-server/hw/dmx/dmxpict.c
+++ b/xorg-server/hw/dmx/dmxpict.c
@@ -274,7 +274,7 @@ static int dmxProcRenderCreateGlyphSet(ClientPtr client)
glyphSet = SecurityLookupIDByType(client, stuff->gsid, GlyphSetType,
DixDestroyAccess);
- glyphPriv = xalloc(sizeof(dmxGlyphPrivRec));
+ glyphPriv = malloc(sizeof(dmxGlyphPrivRec));
if (!glyphPriv) return BadAlloc;
glyphPriv->glyphSets = NULL;
MAXSCREENSALLOC_RETURN(glyphPriv->glyphSets, BadAlloc);
@@ -331,7 +331,7 @@ static int dmxProcRenderFreeGlyphSet(ClientPtr client)
}
MAXSCREENSFREE(glyphPriv->glyphSets);
- xfree(glyphPriv);
+ free(glyphPriv);
DMX_SET_GLYPH_PRIV(glyphSet, NULL);
}
@@ -369,7 +369,7 @@ static int dmxProcRenderAddGlyphs(ClientPtr client)
sizeof(xRenderAddGlyphsReq) -
(sizeof(CARD32) + sizeof(xGlyphInfo)) * nglyphs);
- gidsCopy = xalloc(sizeof(*gidsCopy) * nglyphs);
+ gidsCopy = malloc(sizeof(*gidsCopy) * nglyphs);
for (i = 0; i < nglyphs; i++) gidsCopy[i] = gids[i];
/* FIXME: Will this ever fail? */
@@ -387,7 +387,7 @@ static int dmxProcRenderAddGlyphs(ClientPtr client)
dmxSync(dmxScreen, FALSE);
}
}
- xfree(gidsCopy);
+ free(gidsCopy);
}
return ret;
@@ -411,7 +411,7 @@ static int dmxProcRenderFreeGlyphs(ClientPtr client)
nglyphs = ((client->req_len << 2) - sizeof(xRenderFreeGlyphsReq)) >> 2;
if (nglyphs) {
- gids = xalloc(sizeof(*gids) * nglyphs);
+ gids = malloc(sizeof(*gids) * nglyphs);
for (i = 0; i < nglyphs; i++)
gids[i] = ((CARD32 *)(stuff + 1))[i];
@@ -424,7 +424,7 @@ static int dmxProcRenderFreeGlyphs(ClientPtr client)
dmxSync(dmxScreen, FALSE);
}
}
- xfree(gids);
+ free(gids);
}
}
@@ -531,13 +531,13 @@ static int dmxProcRenderCompositeGlyphs(ClientPtr client)
/* The following only works for Render version > 0.2 */
/* All of the XGlyphElt* structure sizes are identical */
- elts = xalloc(nelt * sizeof(XGlyphElt8));
+ elts = malloc(nelt * sizeof(XGlyphElt8));
if (!elts)
return BadAlloc;
- glyphs = xalloc(nglyph * size);
+ glyphs = malloc(nglyph * size);
if (!glyphs) {
- xfree(elts);
+ free(elts);
return BadAlloc;
}
@@ -605,8 +605,8 @@ static int dmxProcRenderCompositeGlyphs(ClientPtr client)
dmxSync(dmxScreen, FALSE);
- xfree(elts);
- xfree(glyphs);
+ free(elts);
+ free(glyphs);
}
return ret;
@@ -878,7 +878,7 @@ int dmxChangePictureClip(PicturePtr pPicture, int clipType,
int nRects;
nRects = nBox;
- pRects = pRect = xalloc(nRects * sizeof(*pRect));
+ pRects = pRect = malloc(nRects * sizeof(*pRect));
while (nBox--) {
pRect->x = pBox->x1;
@@ -894,7 +894,7 @@ int dmxChangePictureClip(PicturePtr pPicture, int clipType,
0, 0,
pRects,
nRects);
- xfree(pRects);
+ free(pRects);
} else {
XRenderSetPictureClipRectangles(dmxScreen->beDisplay,
pPictPriv->pict,
diff --git a/xorg-server/hw/dmx/dmxpixmap.c b/xorg-server/hw/dmx/dmxpixmap.c
index 66224031a..bcbcc3a88 100644
--- a/xorg-server/hw/dmx/dmxpixmap.c
+++ b/xorg-server/hw/dmx/dmxpixmap.c
@@ -1,253 +1,253 @@
-/*
- * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina.
- *
- * 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 on 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 (including the
- * next paragraph) 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
- * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
- * 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.
- */
-
-/*
- * Authors:
- * Kevin E. Martin <kem@redhat.com>
- *
- */
-
-/** \file
- * Provides pixmap support. */
-
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
-
-#include "dmx.h"
-#include "dmxsync.h"
-#include "dmxpixmap.h"
-
-#include "pixmapstr.h"
-#include "servermd.h"
-#include "privates.h"
-
-/** Initialize a private area in \a pScreen for pixmap information. */
-Bool dmxInitPixmap(ScreenPtr pScreen)
-{
- if (!dixRequestPrivate(dmxPixPrivateKey, sizeof(dmxPixPrivRec)))
- return FALSE;
-
- return TRUE;
-}
-
-/** Create a pixmap on the back-end server. */
-void dmxBECreatePixmap(PixmapPtr pPixmap)
-{
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap);
-
- /* Make sure we haven't already created this pixmap. This can
- * happen when the pixmap is used elsewhere (e.g., as a background
- * or border for a window) and the refcnt > 1.
- */
- if (pPixPriv->pixmap)
- return;
-
- if (pPixmap->drawable.width && pPixmap->drawable.height) {
- pPixPriv->pixmap = XCreatePixmap(dmxScreen->beDisplay,
- dmxScreen->scrnWin,
- pPixmap->drawable.width,
- pPixmap->drawable.height,
- pPixmap->drawable.depth);
- dmxSync(dmxScreen, FALSE);
- }
-}
-
-/** Create a pixmap for \a pScreen with the specified \a width, \a
- * height, and \a depth. */
-PixmapPtr dmxCreatePixmap(ScreenPtr pScreen, int width, int height, int depth,
- unsigned usage_hint)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- PixmapPtr pPixmap;
- int bpp;
- dmxPixPrivPtr pPixPriv;
-
-#if 0
- DMX_UNWRAP(CreatePixmap, dmxScreen, pScreen);
- if (pScreen->CreatePixmap)
- ret = pScreen->CreatePixmap(pPixmap);
-#endif
-
- /* Create pixmap on back-end server */
- if (depth == 24) bpp = 32;
- else bpp = depth;
-
- pPixmap = AllocatePixmap(pScreen, 0);
- if (!pPixmap)
- return NullPixmap;
-
- pPixmap->drawable.type = DRAWABLE_PIXMAP;
- pPixmap->drawable.class = 0;
- pPixmap->drawable.pScreen = pScreen;
- pPixmap->drawable.depth = depth;
- pPixmap->drawable.bitsPerPixel = bpp;
- pPixmap->drawable.id = 0;
- pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
- pPixmap->drawable.x = 0;
- pPixmap->drawable.y = 0;
- pPixmap->drawable.width = width;
- pPixmap->drawable.height = height;
- pPixmap->devKind = PixmapBytePad(width, bpp);
- pPixmap->refcnt = 1;
- pPixmap->usage_hint = usage_hint;
-
- pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap);
- pPixPriv->pixmap = (Pixmap)0;
- pPixPriv->detachedImage = NULL;
-
- /* Create the pixmap on the back-end server */
- if (dmxScreen->beDisplay) {
- dmxBECreatePixmap(pPixmap);
- }
-
-#if 0
- DMX_WRAP(CreatePixmap, dmxCreatePixmap, dmxScreen, pScreen);
-#endif
-
- return pPixmap;
-}
-
-/** Destroy the pixmap on the back-end server. */
-Bool dmxBEFreePixmap(PixmapPtr pPixmap)
-{
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap);
-
- if (pPixPriv->pixmap) {
- XFreePixmap(dmxScreen->beDisplay, pPixPriv->pixmap);
- pPixPriv->pixmap = (Pixmap)0;
- return TRUE;
- }
-
- return FALSE;
-}
-
-/** Destroy the pixmap pointed to by \a pPixmap. */
-Bool dmxDestroyPixmap(PixmapPtr pPixmap)
-{
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- Bool ret = TRUE;
-
-#if 0
- DMX_UNWRAP(DestroyPixmap, dmxScreen, pScreen);
-#endif
-
- if (--pPixmap->refcnt)
- return TRUE;
-
- /* Destroy pixmap on back-end server */
- if (dmxScreen->beDisplay) {
- if (dmxBEFreePixmap(pPixmap)) {
- /* Also make sure that we destroy any detached image */
- dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap);
- if (pPixPriv->detachedImage)
- XDestroyImage(pPixPriv->detachedImage);
- dmxSync(dmxScreen, FALSE);
- }
- }
- dixFreePrivates(pPixmap->devPrivates);
- xfree(pPixmap);
-
-#if 0
- if (pScreen->DestroyPixmap)
- ret = pScreen->DestroyPixmap(pPixmap);
- DMX_WRAP(DestroyPixmap, dmxDestroyPixmap, dmxScreen, pScreen);
-#endif
-
- return ret;
-}
-
-/** Create and return a region based on the pixmap pointed to by \a
- * pPixmap. */
-RegionPtr dmxBitmapToRegion(PixmapPtr pPixmap)
-{
- ScreenPtr pScreen = pPixmap->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap);
- XImage *ximage;
- RegionPtr pReg, pTmpReg;
- int x, y;
- unsigned long previousPixel, currentPixel;
- BoxRec Box;
- Bool overlap;
-
- if (!dmxScreen->beDisplay) {
- pReg = REGION_CREATE(pScreen, NullBox, 1);
- return pReg;
- }
-
- ximage = XGetImage(dmxScreen->beDisplay, pPixPriv->pixmap, 0, 0,
- pPixmap->drawable.width, pPixmap->drawable.height,
- 1, XYPixmap);
-
- pReg = REGION_CREATE(pScreen, NullBox, 1);
- pTmpReg = REGION_CREATE(pScreen, NullBox, 1);
- if(!pReg || !pTmpReg) {
- XDestroyImage(ximage);
- return NullRegion;
- }
-
- for (y = 0; y < pPixmap->drawable.height; y++) {
- Box.y1 = y;
- Box.y2 = y + 1;
- previousPixel = 0L;
- for (x = 0; x < pPixmap->drawable.width; x++) {
- currentPixel = XGetPixel(ximage, x, y);
- if (previousPixel != currentPixel) {
- if (previousPixel == 0L) {
- /* left edge */
- Box.x1 = x;
- } else if (currentPixel == 0L) {
- /* right edge */
- Box.x2 = x;
- REGION_RESET(pScreen, pTmpReg, &Box);
- REGION_APPEND(pScreen, pReg, pTmpReg);
- }
- previousPixel = currentPixel;
- }
- }
- if (previousPixel != 0L) {
- /* right edge because of the end of pixmap */
- Box.x2 = pPixmap->drawable.width;
- REGION_RESET(pScreen, pTmpReg, &Box);
- REGION_APPEND(pScreen, pReg, pTmpReg);
- }
- }
-
- REGION_DESTROY(pScreen, pTmpReg);
- XDestroyImage(ximage);
-
- REGION_VALIDATE(pScreen, pReg, &overlap);
-
- dmxSync(dmxScreen, FALSE);
- return(pReg);
-}
+/*
+ * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina.
+ *
+ * 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 on 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 (including the
+ * next paragraph) 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
+ * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
+ * 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.
+ */
+
+/*
+ * Authors:
+ * Kevin E. Martin <kem@redhat.com>
+ *
+ */
+
+/** \file
+ * Provides pixmap support. */
+
+#ifdef HAVE_DMX_CONFIG_H
+#include <dmx-config.h>
+#endif
+
+#include "dmx.h"
+#include "dmxsync.h"
+#include "dmxpixmap.h"
+
+#include "pixmapstr.h"
+#include "servermd.h"
+#include "privates.h"
+
+/** Initialize a private area in \a pScreen for pixmap information. */
+Bool dmxInitPixmap(ScreenPtr pScreen)
+{
+ if (!dixRequestPrivate(dmxPixPrivateKey, sizeof(dmxPixPrivRec)))
+ return FALSE;
+
+ return TRUE;
+}
+
+/** Create a pixmap on the back-end server. */
+void dmxBECreatePixmap(PixmapPtr pPixmap)
+{
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap);
+
+ /* Make sure we haven't already created this pixmap. This can
+ * happen when the pixmap is used elsewhere (e.g., as a background
+ * or border for a window) and the refcnt > 1.
+ */
+ if (pPixPriv->pixmap)
+ return;
+
+ if (pPixmap->drawable.width && pPixmap->drawable.height) {
+ pPixPriv->pixmap = XCreatePixmap(dmxScreen->beDisplay,
+ dmxScreen->scrnWin,
+ pPixmap->drawable.width,
+ pPixmap->drawable.height,
+ pPixmap->drawable.depth);
+ dmxSync(dmxScreen, FALSE);
+ }
+}
+
+/** Create a pixmap for \a pScreen with the specified \a width, \a
+ * height, and \a depth. */
+PixmapPtr dmxCreatePixmap(ScreenPtr pScreen, int width, int height, int depth,
+ unsigned usage_hint)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ PixmapPtr pPixmap;
+ int bpp;
+ dmxPixPrivPtr pPixPriv;
+
+#if 0
+ DMX_UNWRAP(CreatePixmap, dmxScreen, pScreen);
+ if (pScreen->CreatePixmap)
+ ret = pScreen->CreatePixmap(pPixmap);
+#endif
+
+ /* Create pixmap on back-end server */
+ if (depth == 24) bpp = 32;
+ else bpp = depth;
+
+ pPixmap = AllocatePixmap(pScreen, 0);
+ if (!pPixmap)
+ return NullPixmap;
+
+ pPixmap->drawable.type = DRAWABLE_PIXMAP;
+ pPixmap->drawable.class = 0;
+ pPixmap->drawable.pScreen = pScreen;
+ pPixmap->drawable.depth = depth;
+ pPixmap->drawable.bitsPerPixel = bpp;
+ pPixmap->drawable.id = 0;
+ pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pPixmap->drawable.x = 0;
+ pPixmap->drawable.y = 0;
+ pPixmap->drawable.width = width;
+ pPixmap->drawable.height = height;
+ pPixmap->devKind = PixmapBytePad(width, bpp);
+ pPixmap->refcnt = 1;
+ pPixmap->usage_hint = usage_hint;
+
+ pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap);
+ pPixPriv->pixmap = (Pixmap)0;
+ pPixPriv->detachedImage = NULL;
+
+ /* Create the pixmap on the back-end server */
+ if (dmxScreen->beDisplay) {
+ dmxBECreatePixmap(pPixmap);
+ }
+
+#if 0
+ DMX_WRAP(CreatePixmap, dmxCreatePixmap, dmxScreen, pScreen);
+#endif
+
+ return pPixmap;
+}
+
+/** Destroy the pixmap on the back-end server. */
+Bool dmxBEFreePixmap(PixmapPtr pPixmap)
+{
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap);
+
+ if (pPixPriv->pixmap) {
+ XFreePixmap(dmxScreen->beDisplay, pPixPriv->pixmap);
+ pPixPriv->pixmap = (Pixmap)0;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/** Destroy the pixmap pointed to by \a pPixmap. */
+Bool dmxDestroyPixmap(PixmapPtr pPixmap)
+{
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ Bool ret = TRUE;
+
+#if 0
+ DMX_UNWRAP(DestroyPixmap, dmxScreen, pScreen);
+#endif
+
+ if (--pPixmap->refcnt)
+ return TRUE;
+
+ /* Destroy pixmap on back-end server */
+ if (dmxScreen->beDisplay) {
+ if (dmxBEFreePixmap(pPixmap)) {
+ /* Also make sure that we destroy any detached image */
+ dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap);
+ if (pPixPriv->detachedImage)
+ XDestroyImage(pPixPriv->detachedImage);
+ dmxSync(dmxScreen, FALSE);
+ }
+ }
+ dixFreePrivates(pPixmap->devPrivates);
+ free(pPixmap);
+
+#if 0
+ if (pScreen->DestroyPixmap)
+ ret = pScreen->DestroyPixmap(pPixmap);
+ DMX_WRAP(DestroyPixmap, dmxDestroyPixmap, dmxScreen, pScreen);
+#endif
+
+ return ret;
+}
+
+/** Create and return a region based on the pixmap pointed to by \a
+ * pPixmap. */
+RegionPtr dmxBitmapToRegion(PixmapPtr pPixmap)
+{
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap);
+ XImage *ximage;
+ RegionPtr pReg, pTmpReg;
+ int x, y;
+ unsigned long previousPixel, currentPixel;
+ BoxRec Box;
+ Bool overlap;
+
+ if (!dmxScreen->beDisplay) {
+ pReg = REGION_CREATE(pScreen, NullBox, 1);
+ return pReg;
+ }
+
+ ximage = XGetImage(dmxScreen->beDisplay, pPixPriv->pixmap, 0, 0,
+ pPixmap->drawable.width, pPixmap->drawable.height,
+ 1, XYPixmap);
+
+ pReg = REGION_CREATE(pScreen, NullBox, 1);
+ pTmpReg = REGION_CREATE(pScreen, NullBox, 1);
+ if(!pReg || !pTmpReg) {
+ XDestroyImage(ximage);
+ return NullRegion;
+ }
+
+ for (y = 0; y < pPixmap->drawable.height; y++) {
+ Box.y1 = y;
+ Box.y2 = y + 1;
+ previousPixel = 0L;
+ for (x = 0; x < pPixmap->drawable.width; x++) {
+ currentPixel = XGetPixel(ximage, x, y);
+ if (previousPixel != currentPixel) {
+ if (previousPixel == 0L) {
+ /* left edge */
+ Box.x1 = x;
+ } else if (currentPixel == 0L) {
+ /* right edge */
+ Box.x2 = x;
+ REGION_RESET(pScreen, pTmpReg, &Box);
+ REGION_APPEND(pScreen, pReg, pTmpReg);
+ }
+ previousPixel = currentPixel;
+ }
+ }
+ if (previousPixel != 0L) {
+ /* right edge because of the end of pixmap */
+ Box.x2 = pPixmap->drawable.width;
+ REGION_RESET(pScreen, pTmpReg, &Box);
+ REGION_APPEND(pScreen, pReg, pTmpReg);
+ }
+ }
+
+ REGION_DESTROY(pScreen, pTmpReg);
+ XDestroyImage(ximage);
+
+ REGION_VALIDATE(pScreen, pReg, &overlap);
+
+ dmxSync(dmxScreen, FALSE);
+ return(pReg);
+}
diff --git a/xorg-server/hw/dmx/dmxprop.c b/xorg-server/hw/dmx/dmxprop.c
index 376313d8d..95efcb0e0 100644
--- a/xorg-server/hw/dmx/dmxprop.c
+++ b/xorg-server/hw/dmx/dmxprop.c
@@ -1,347 +1,347 @@
-/*
- * Copyright 2002-2003 Red Hat Inc., Durham, North Carolina.
- *
- * 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 on 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 (including the
- * next paragraph) 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
- * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
- * 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.
- */
-
-/*
- * Authors:
- * Rickard E. (Rik) Faith <faith@redhat.com>
- *
- */
-
-/** \file
- *
- * It is possible for one of the DMX "backend displays" to actually be
- * smaller than the dimensions of the backend X server. Therefore, it
- * is possible for more than one of the DMX "backend displays" to be
- * physically located on the same backend X server. This situation must
- * be detected so that cursor motion can be handled in an expected
- * fashion.
- *
- * We could analyze the names used for the DMX "backend displays" (e.g.,
- * the names passed to the -display command-line parameter), but there
- * are many possible names for a single X display, and failing to detect
- * sameness leads to very unexpected results. Therefore, whenever the
- * DMX server opens a window on a backend X server, a property value is
- * queried and set on that backend to detect when another window is
- * already open on that server.
- *
- * Further, it is possible that two different DMX server instantiations
- * both have windows on the same physical backend X server. This case
- * is also detected so that pointer input is not taken from that
- * particular backend X server.
- *
- * The routines in this file handle the property management. */
-
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
-
-#include "dmx.h"
-#include "dmxprop.h"
-#include "dmxlog.h"
-
-/** Holds the window id of all DMX windows on the backend X server. */
-#define DMX_ATOMNAME "DMX_NAME"
-
-/** The identification string of this DMX server */
-#define DMX_IDENT "Xdmx"
-
-extern char *display;
-
-static int dmxPropertyErrorHandler(Display *dpy, XErrorEvent *ev)
-{
- return 0;
-}
-
-static const unsigned char *dmxPropertyIdentifier(void)
-{
- /* RATS: These buffers are only used in
- * length-limited calls. */
- char hostname[256];
- static char buf[128];
- static int initialized = 0;
-
- if (initialized++) return (unsigned char *)buf;
-
- XmuGetHostname(hostname, sizeof(hostname));
- XmuSnprintf(buf, sizeof(buf), "%s:%s:%s", DMX_IDENT, hostname, display);
- return (unsigned char *)buf;
-}
-
-/** Starting with the \a start screen, iterate over all of the screens
- * on the same physical X server as \a start, calling \a f with the
- * screen and the \a closure. (The common case is that \a start is the
- * only DMX window on the backend X server.) */
-void *dmxPropertyIterate(DMXScreenInfo *start,
- void *(*f)(DMXScreenInfo *dmxScreen, void *),
- void *closure)
-{
- DMXScreenInfo *pt;
-
- if (!start->next) {
- if (!start->beDisplay) return NULL;
- return f(start, closure);
- }
-
- for (pt = start->next; /* condition at end of loop */; pt = pt->next) {
- void *retval;
- /* beDisplay ban be NULL if a screen was detached */
- dmxLog(dmxDebug, "pt = %p\n", pt);
- dmxLog(dmxDebug, "pt->beDisplay = %p\n", pt->beDisplay);
- if (pt->beDisplay && (retval = f(pt, closure))) return retval;
- if (pt == start) break;
- }
- return NULL;
-}
-
-/** Returns 0 if this is the only Xdmx session on the display; 1
- * otherwise. */
-static int dmxPropertyCheckOtherServers(DMXScreenInfo *dmxScreen, Atom atom)
-{
- Display *dpy = dmxScreen->beDisplay;
- XTextProperty tp;
- XTextProperty tproot;
- const char *pt;
- int retcode = 0;
- char **list = NULL;
- int count = 0;
- int i;
- int (*dmxOldHandler)(Display *, XErrorEvent *);
-
- if (!dpy)
- return 0;
-
- if (!XGetTextProperty(dpy, RootWindow(dpy,0), &tproot, atom)
- || !tproot.nitems) return 0;
-
- /* Ignore BadWindow errors for this
- * routine because the window id stored
- * in the property might be old */
- dmxOldHandler = XSetErrorHandler(dmxPropertyErrorHandler);
- for (pt = (const char *)tproot.value; pt && *pt; pt = pt ? pt + 1 : NULL) {
- if ((pt = strchr(pt, ','))) {
- Window win = strtol(pt+1, NULL, 10);
- if (XGetTextProperty(dpy, win, &tp, atom) && tp.nitems) {
- if (!strncmp((char *)tp.value, DMX_IDENT, strlen(DMX_IDENT))) {
- int flag = 0;
- for (i = 0; i < count; i++)
- if (!strcmp(list[i], (char *)tp.value)) {
- ++flag;
- break;
- }
- if (flag) continue;
- ++retcode;
- dmxLogOutputWarning(dmxScreen,
- "%s also running on %s\n",
- tp.value, dmxScreen->name);
- list = xrealloc(list, ++count * sizeof(*list));
- list[count-1] = xalloc(tp.nitems + 2);
- strncpy(list[count-1], (char *)tp.value, tp.nitems + 1);
- }
- XFree(tp.value);
- }
- }
- }
- XSetErrorHandler(dmxOldHandler);
-
- for (i = 0; i < count; i++) xfree(list[i]);
- xfree(list);
- XFree(tproot.value);
- if (!retcode)
- dmxLogOutput(dmxScreen, "No Xdmx server running on backend\n");
- return retcode;
-}
-
-/** Returns NULL if this is the only Xdmx window on the display.
- * Otherwise, returns a pointer to the dmxScreen of the other windows on
- * the display. */
-static DMXScreenInfo *dmxPropertyCheckOtherWindows(DMXScreenInfo *dmxScreen,
- Atom atom)
-{
- Display *dpy = dmxScreen->beDisplay;
- const unsigned char *id = dmxPropertyIdentifier();
- XTextProperty tproot;
- XTextProperty tp;
- const char *pt;
- int (*dmxOldHandler)(Display *, XErrorEvent *);
-
- if (!dpy)
- return NULL;
-
- if (!XGetTextProperty(dpy, RootWindow(dpy,0), &tproot, atom)
- || !tproot.nitems) return 0;
-
- /* Ignore BadWindow errors for this
- * routine because the window id stored
- * in the property might be old */
- dmxOldHandler = XSetErrorHandler(dmxPropertyErrorHandler);
- for (pt = (const char *)tproot.value; pt && *pt; pt = pt ? pt + 1 : NULL) {
- if ((pt = strchr(pt, ','))) {
- Window win = strtol(pt+1, NULL, 10);
- if (XGetTextProperty(dpy, win, &tp, atom) && tp.nitems) {
- dmxLog(dmxDebug,"On %s/%lu: %s\n",
- dmxScreen->name, win, tp.value);
- if (!strncmp((char *)tp.value, (char *)id,
- strlen((char *)id))) {
- int idx;
-
- if (!(pt = strchr((char *)tp.value, ','))) continue;
- idx = strtol(pt+1, NULL, 10);
- if (idx < 0 || idx >= dmxNumScreens) continue;
- if (dmxScreens[idx].scrnWin != win) continue;
- XSetErrorHandler(dmxOldHandler);
- return &dmxScreens[idx];
- }
- XFree(tp.value);
- }
- }
- }
- XSetErrorHandler(dmxOldHandler);
- XFree(tproot.value);
- return 0;
-}
-
-/** Returns 0 if this is the only Xdmx session on the display; 1
- * otherwise. */
-int dmxPropertyDisplay(DMXScreenInfo *dmxScreen)
-{
- Atom atom;
- const unsigned char *id = dmxPropertyIdentifier();
- Display *dpy = dmxScreen->beDisplay;
-
- if (!dpy)
- return 0;
-
- atom = XInternAtom(dpy, DMX_ATOMNAME, False);
- if (dmxPropertyCheckOtherServers(dmxScreen, atom)) {
- dmxScreen->shared = 1;
- return 1;
- }
- XChangeProperty(dpy, RootWindow(dpy,0), atom, XA_STRING, 8,
- PropModeReplace, id, strlen((char *)id));
- return 0;
-}
-
-/** Returns 1 if the dmxScreen and the display in \a name are on the
- * same display, or 0 otherwise. We can't just compare the display
- * names because there can be multiple synonyms for the same display,
- * some of which cannot be determined without accessing the display
- * itself (e.g., domain aliases or machines with multiple NICs). */
-int dmxPropertySameDisplay(DMXScreenInfo *dmxScreen, const char *name)
-{
- Display *dpy0 = dmxScreen->beDisplay;
- Atom atom0;
- XTextProperty tp0;
- Display *dpy1 = NULL;
- Atom atom1;
- XTextProperty tp1;
- int retval = 0;
-
- if (!dpy0)
- return 0;
-
- tp0.nitems = 0;
- tp1.nitems = 0;
-
- if ((atom0 = XInternAtom(dpy0, DMX_ATOMNAME, True)) == None) {
- dmxLog(dmxWarning, "No atom on %s\n", dmxScreen->name);
- return 0;
- }
- if (!XGetTextProperty(dpy0, RootWindow(dpy0,0), &tp0, atom0)
- || !tp0.nitems) {
- dmxLog(dmxWarning, "No text property on %s\n", dmxScreen->name);
- return 0;
- }
-
- if (!(dpy1 = XOpenDisplay(name))) {
- dmxLog(dmxWarning, "Cannot open %s\n", name);
- goto cleanup;
- }
- atom1 = XInternAtom(dpy1, DMX_ATOMNAME, True);
- if (atom1 == None) {
- dmxLog(dmxDebug, "No atom on %s\n", name);
- goto cleanup;
- }
- if (!XGetTextProperty(dpy1, RootWindow(dpy1,0), &tp1, atom1)
- || !tp1.nitems) {
- dmxLog(dmxDebug, "No text property on %s\n", name);
- goto cleanup;
- }
- if (!strcmp((char *)tp0.value, (char *)tp1.value)) retval = 1;
-
- cleanup:
- if (tp0.nitems) XFree(tp0.value);
- if (tp1.nitems) XFree(tp1.value);
- if (dpy1) XCloseDisplay(dpy1);
- return retval;
-}
-
-/** Prints a log message if \a dmxScreen is on the same backend X server
- * as some other DMX backend (output) screen. Modifies the property
- * (#DMX_ATOMNAME) on the backend X server to reflect the creation of \a
- * dmxScreen.
- *
- * The root window of the backend X server holds a list of window ids
- * for all DMX windows (on this DMX server or some other DMX server).
- *
- * This list can then be iterated, and the property for each window can
- * be examined. This property contains the following tuple (no quotes):
- *
- * "#DMX_IDENT:<hostname running DMX>:<display name of DMX>,<screen number>"
- */
-void dmxPropertyWindow(DMXScreenInfo *dmxScreen)
-{
- Atom atom;
- const unsigned char *id = dmxPropertyIdentifier();
- Display *dpy = dmxScreen->beDisplay;
- Window win = dmxScreen->scrnWin;
- DMXScreenInfo *other;
- char buf[128]; /* RATS: only used with XmuSnprintf */
-
- if (!dpy)
- return; /* FIXME: What should be done here if Xdmx is started
- * with this screen initially detached?
- */
-
- atom = XInternAtom(dpy, DMX_ATOMNAME, False);
- if ((other = dmxPropertyCheckOtherWindows(dmxScreen, atom))) {
- DMXScreenInfo *tmp = dmxScreen->next;
- dmxScreen->next = (other->next ? other->next : other);
- other->next = (tmp ? tmp : dmxScreen);
- dmxLog(dmxDebug, "%d/%s/%lu and %d/%s/%lu are on the same backend\n",
- dmxScreen->index, dmxScreen->name, dmxScreen->scrnWin,
- other->index, other->name, other->scrnWin);
- }
-
- XmuSnprintf(buf, sizeof(buf), ".%d,%lu", dmxScreen->index,
- (long unsigned)win);
- XChangeProperty(dpy, RootWindow(dpy,0), atom, XA_STRING, 8,
- PropModeAppend, (unsigned char *)buf, strlen(buf));
-
- XmuSnprintf(buf, sizeof(buf), "%s,%d", id, dmxScreen->index);
- XChangeProperty(dpy, win, atom, XA_STRING, 8,
- PropModeAppend, (unsigned char *)buf, strlen(buf));
-}
+/*
+ * Copyright 2002-2003 Red Hat Inc., Durham, North Carolina.
+ *
+ * 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 on 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 (including the
+ * next paragraph) 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
+ * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
+ * 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.
+ */
+
+/*
+ * Authors:
+ * Rickard E. (Rik) Faith <faith@redhat.com>
+ *
+ */
+
+/** \file
+ *
+ * It is possible for one of the DMX "backend displays" to actually be
+ * smaller than the dimensions of the backend X server. Therefore, it
+ * is possible for more than one of the DMX "backend displays" to be
+ * physically located on the same backend X server. This situation must
+ * be detected so that cursor motion can be handled in an expected
+ * fashion.
+ *
+ * We could analyze the names used for the DMX "backend displays" (e.g.,
+ * the names passed to the -display command-line parameter), but there
+ * are many possible names for a single X display, and failing to detect
+ * sameness leads to very unexpected results. Therefore, whenever the
+ * DMX server opens a window on a backend X server, a property value is
+ * queried and set on that backend to detect when another window is
+ * already open on that server.
+ *
+ * Further, it is possible that two different DMX server instantiations
+ * both have windows on the same physical backend X server. This case
+ * is also detected so that pointer input is not taken from that
+ * particular backend X server.
+ *
+ * The routines in this file handle the property management. */
+
+#ifdef HAVE_DMX_CONFIG_H
+#include <dmx-config.h>
+#endif
+
+#include "dmx.h"
+#include "dmxprop.h"
+#include "dmxlog.h"
+
+/** Holds the window id of all DMX windows on the backend X server. */
+#define DMX_ATOMNAME "DMX_NAME"
+
+/** The identification string of this DMX server */
+#define DMX_IDENT "Xdmx"
+
+extern char *display;
+
+static int dmxPropertyErrorHandler(Display *dpy, XErrorEvent *ev)
+{
+ return 0;
+}
+
+static const unsigned char *dmxPropertyIdentifier(void)
+{
+ /* RATS: These buffers are only used in
+ * length-limited calls. */
+ char hostname[256];
+ static char buf[128];
+ static int initialized = 0;
+
+ if (initialized++) return (unsigned char *)buf;
+
+ XmuGetHostname(hostname, sizeof(hostname));
+ XmuSnprintf(buf, sizeof(buf), "%s:%s:%s", DMX_IDENT, hostname, display);
+ return (unsigned char *)buf;
+}
+
+/** Starting with the \a start screen, iterate over all of the screens
+ * on the same physical X server as \a start, calling \a f with the
+ * screen and the \a closure. (The common case is that \a start is the
+ * only DMX window on the backend X server.) */
+void *dmxPropertyIterate(DMXScreenInfo *start,
+ void *(*f)(DMXScreenInfo *dmxScreen, void *),
+ void *closure)
+{
+ DMXScreenInfo *pt;
+
+ if (!start->next) {
+ if (!start->beDisplay) return NULL;
+ return f(start, closure);
+ }
+
+ for (pt = start->next; /* condition at end of loop */; pt = pt->next) {
+ void *retval;
+ /* beDisplay ban be NULL if a screen was detached */
+ dmxLog(dmxDebug, "pt = %p\n", pt);
+ dmxLog(dmxDebug, "pt->beDisplay = %p\n", pt->beDisplay);
+ if (pt->beDisplay && (retval = f(pt, closure))) return retval;
+ if (pt == start) break;
+ }
+ return NULL;
+}
+
+/** Returns 0 if this is the only Xdmx session on the display; 1
+ * otherwise. */
+static int dmxPropertyCheckOtherServers(DMXScreenInfo *dmxScreen, Atom atom)
+{
+ Display *dpy = dmxScreen->beDisplay;
+ XTextProperty tp;
+ XTextProperty tproot;
+ const char *pt;
+ int retcode = 0;
+ char **list = NULL;
+ int count = 0;
+ int i;
+ int (*dmxOldHandler)(Display *, XErrorEvent *);
+
+ if (!dpy)
+ return 0;
+
+ if (!XGetTextProperty(dpy, RootWindow(dpy,0), &tproot, atom)
+ || !tproot.nitems) return 0;
+
+ /* Ignore BadWindow errors for this
+ * routine because the window id stored
+ * in the property might be old */
+ dmxOldHandler = XSetErrorHandler(dmxPropertyErrorHandler);
+ for (pt = (const char *)tproot.value; pt && *pt; pt = pt ? pt + 1 : NULL) {
+ if ((pt = strchr(pt, ','))) {
+ Window win = strtol(pt+1, NULL, 10);
+ if (XGetTextProperty(dpy, win, &tp, atom) && tp.nitems) {
+ if (!strncmp((char *)tp.value, DMX_IDENT, strlen(DMX_IDENT))) {
+ int flag = 0;
+ for (i = 0; i < count; i++)
+ if (!strcmp(list[i], (char *)tp.value)) {
+ ++flag;
+ break;
+ }
+ if (flag) continue;
+ ++retcode;
+ dmxLogOutputWarning(dmxScreen,
+ "%s also running on %s\n",
+ tp.value, dmxScreen->name);
+ list = realloc(list, ++count * sizeof(*list));
+ list[count-1] = malloc(tp.nitems + 2);
+ strncpy(list[count-1], (char *)tp.value, tp.nitems + 1);
+ }
+ XFree(tp.value);
+ }
+ }
+ }
+ XSetErrorHandler(dmxOldHandler);
+
+ for (i = 0; i < count; i++) free(list[i]);
+ free(list);
+ XFree(tproot.value);
+ if (!retcode)
+ dmxLogOutput(dmxScreen, "No Xdmx server running on backend\n");
+ return retcode;
+}
+
+/** Returns NULL if this is the only Xdmx window on the display.
+ * Otherwise, returns a pointer to the dmxScreen of the other windows on
+ * the display. */
+static DMXScreenInfo *dmxPropertyCheckOtherWindows(DMXScreenInfo *dmxScreen,
+ Atom atom)
+{
+ Display *dpy = dmxScreen->beDisplay;
+ const unsigned char *id = dmxPropertyIdentifier();
+ XTextProperty tproot;
+ XTextProperty tp;
+ const char *pt;
+ int (*dmxOldHandler)(Display *, XErrorEvent *);
+
+ if (!dpy)
+ return NULL;
+
+ if (!XGetTextProperty(dpy, RootWindow(dpy,0), &tproot, atom)
+ || !tproot.nitems) return 0;
+
+ /* Ignore BadWindow errors for this
+ * routine because the window id stored
+ * in the property might be old */
+ dmxOldHandler = XSetErrorHandler(dmxPropertyErrorHandler);
+ for (pt = (const char *)tproot.value; pt && *pt; pt = pt ? pt + 1 : NULL) {
+ if ((pt = strchr(pt, ','))) {
+ Window win = strtol(pt+1, NULL, 10);
+ if (XGetTextProperty(dpy, win, &tp, atom) && tp.nitems) {
+ dmxLog(dmxDebug,"On %s/%lu: %s\n",
+ dmxScreen->name, win, tp.value);
+ if (!strncmp((char *)tp.value, (char *)id,
+ strlen((char *)id))) {
+ int idx;
+
+ if (!(pt = strchr((char *)tp.value, ','))) continue;
+ idx = strtol(pt+1, NULL, 10);
+ if (idx < 0 || idx >= dmxNumScreens) continue;
+ if (dmxScreens[idx].scrnWin != win) continue;
+ XSetErrorHandler(dmxOldHandler);
+ return &dmxScreens[idx];
+ }
+ XFree(tp.value);
+ }
+ }
+ }
+ XSetErrorHandler(dmxOldHandler);
+ XFree(tproot.value);
+ return 0;
+}
+
+/** Returns 0 if this is the only Xdmx session on the display; 1
+ * otherwise. */
+int dmxPropertyDisplay(DMXScreenInfo *dmxScreen)
+{
+ Atom atom;
+ const unsigned char *id = dmxPropertyIdentifier();
+ Display *dpy = dmxScreen->beDisplay;
+
+ if (!dpy)
+ return 0;
+
+ atom = XInternAtom(dpy, DMX_ATOMNAME, False);
+ if (dmxPropertyCheckOtherServers(dmxScreen, atom)) {
+ dmxScreen->shared = 1;
+ return 1;
+ }
+ XChangeProperty(dpy, RootWindow(dpy,0), atom, XA_STRING, 8,
+ PropModeReplace, id, strlen((char *)id));
+ return 0;
+}
+
+/** Returns 1 if the dmxScreen and the display in \a name are on the
+ * same display, or 0 otherwise. We can't just compare the display
+ * names because there can be multiple synonyms for the same display,
+ * some of which cannot be determined without accessing the display
+ * itself (e.g., domain aliases or machines with multiple NICs). */
+int dmxPropertySameDisplay(DMXScreenInfo *dmxScreen, const char *name)
+{
+ Display *dpy0 = dmxScreen->beDisplay;
+ Atom atom0;
+ XTextProperty tp0;
+ Display *dpy1 = NULL;
+ Atom atom1;
+ XTextProperty tp1;
+ int retval = 0;
+
+ if (!dpy0)
+ return 0;
+
+ tp0.nitems = 0;
+ tp1.nitems = 0;
+
+ if ((atom0 = XInternAtom(dpy0, DMX_ATOMNAME, True)) == None) {
+ dmxLog(dmxWarning, "No atom on %s\n", dmxScreen->name);
+ return 0;
+ }
+ if (!XGetTextProperty(dpy0, RootWindow(dpy0,0), &tp0, atom0)
+ || !tp0.nitems) {
+ dmxLog(dmxWarning, "No text property on %s\n", dmxScreen->name);
+ return 0;
+ }
+
+ if (!(dpy1 = XOpenDisplay(name))) {
+ dmxLog(dmxWarning, "Cannot open %s\n", name);
+ goto cleanup;
+ }
+ atom1 = XInternAtom(dpy1, DMX_ATOMNAME, True);
+ if (atom1 == None) {
+ dmxLog(dmxDebug, "No atom on %s\n", name);
+ goto cleanup;
+ }
+ if (!XGetTextProperty(dpy1, RootWindow(dpy1,0), &tp1, atom1)
+ || !tp1.nitems) {
+ dmxLog(dmxDebug, "No text property on %s\n", name);
+ goto cleanup;
+ }
+ if (!strcmp((char *)tp0.value, (char *)tp1.value)) retval = 1;
+
+ cleanup:
+ if (tp0.nitems) XFree(tp0.value);
+ if (tp1.nitems) XFree(tp1.value);
+ if (dpy1) XCloseDisplay(dpy1);
+ return retval;
+}
+
+/** Prints a log message if \a dmxScreen is on the same backend X server
+ * as some other DMX backend (output) screen. Modifies the property
+ * (#DMX_ATOMNAME) on the backend X server to reflect the creation of \a
+ * dmxScreen.
+ *
+ * The root window of the backend X server holds a list of window ids
+ * for all DMX windows (on this DMX server or some other DMX server).
+ *
+ * This list can then be iterated, and the property for each window can
+ * be examined. This property contains the following tuple (no quotes):
+ *
+ * "#DMX_IDENT:<hostname running DMX>:<display name of DMX>,<screen number>"
+ */
+void dmxPropertyWindow(DMXScreenInfo *dmxScreen)
+{
+ Atom atom;
+ const unsigned char *id = dmxPropertyIdentifier();
+ Display *dpy = dmxScreen->beDisplay;
+ Window win = dmxScreen->scrnWin;
+ DMXScreenInfo *other;
+ char buf[128]; /* RATS: only used with XmuSnprintf */
+
+ if (!dpy)
+ return; /* FIXME: What should be done here if Xdmx is started
+ * with this screen initially detached?
+ */
+
+ atom = XInternAtom(dpy, DMX_ATOMNAME, False);
+ if ((other = dmxPropertyCheckOtherWindows(dmxScreen, atom))) {
+ DMXScreenInfo *tmp = dmxScreen->next;
+ dmxScreen->next = (other->next ? other->next : other);
+ other->next = (tmp ? tmp : dmxScreen);
+ dmxLog(dmxDebug, "%d/%s/%lu and %d/%s/%lu are on the same backend\n",
+ dmxScreen->index, dmxScreen->name, dmxScreen->scrnWin,
+ other->index, other->name, other->scrnWin);
+ }
+
+ XmuSnprintf(buf, sizeof(buf), ".%d,%lu", dmxScreen->index,
+ (long unsigned)win);
+ XChangeProperty(dpy, RootWindow(dpy,0), atom, XA_STRING, 8,
+ PropModeAppend, (unsigned char *)buf, strlen(buf));
+
+ XmuSnprintf(buf, sizeof(buf), "%s,%d", id, dmxScreen->index);
+ XChangeProperty(dpy, win, atom, XA_STRING, 8,
+ PropModeAppend, (unsigned char *)buf, strlen(buf));
+}
diff --git a/xorg-server/hw/dmx/dmxscrinit.c b/xorg-server/hw/dmx/dmxscrinit.c
index c1beb9ba5..edb14a23a 100644
--- a/xorg-server/hw/dmx/dmxscrinit.c
+++ b/xorg-server/hw/dmx/dmxscrinit.c
@@ -1,524 +1,524 @@
-/*
- * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina.
- *
- * 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 on 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 (including the
- * next paragraph) 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
- * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
- * 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.
- */
-
-/*
- * Authors:
- * Kevin E. Martin <kem@redhat.com>
- * David H. Dawes <dawes@xfree86.org>
- *
- */
-
-/** \file
- * This file provides support for screen initialization. */
-
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
-
-#include "dmx.h"
-#include "dmxsync.h"
-#include "dmxshadow.h"
-#include "dmxscrinit.h"
-#include "dmxcursor.h"
-#include "dmxgc.h"
-#include "dmxgcops.h"
-#include "dmxwindow.h"
-#include "dmxpixmap.h"
-#include "dmxfont.h"
-#include "dmxcmap.h"
-#include "dmxprop.h"
-#include "dmxdpms.h"
-
-#include "dmxpict.h"
-
-#include "fb.h"
-#include "mipointer.h"
-#include "micmap.h"
-
-extern Bool dmxCloseScreen(int idx, ScreenPtr pScreen);
-static Bool dmxSaveScreen(ScreenPtr pScreen, int what);
-
-static unsigned long dmxGeneration;
-static unsigned long *dmxCursorGeneration;
-
-static int dmxGCPrivateKeyIndex;
-DevPrivateKey dmxGCPrivateKey = &dmxGCPrivateKeyIndex; /**< Private index for GCs */
-static int dmxWinPrivateKeyIndex;
-DevPrivateKey dmxWinPrivateKey = &dmxWinPrivateKeyIndex; /**< Private index for Windows */
-static int dmxPixPrivateKeyIndex;
-DevPrivateKey dmxPixPrivateKey = &dmxPixPrivateKeyIndex; /**< Private index for Pixmaps */
-int dmxFontPrivateIndex; /**< Private index for Fonts */
-static int dmxScreenPrivateKeyIndex;
-DevPrivateKey dmxScreenPrivateKey = &dmxScreenPrivateKeyIndex; /**< Private index for Screens */
-static int dmxColormapPrivateKeyIndex;
-DevPrivateKey dmxColormapPrivateKey = &dmxColormapPrivateKeyIndex; /**< Private index for Colormaps */
-static int dmxPictPrivateKeyIndex;
-DevPrivateKey dmxPictPrivateKey = &dmxPictPrivateKeyIndex; /**< Private index for Picts */
-static int dmxGlyphSetPrivateKeyIndex;
-DevPrivateKey dmxGlyphSetPrivateKey = &dmxGlyphSetPrivateKeyIndex; /**< Private index for GlyphSets */
-
-/** Initialize the parts of screen \a idx that require access to the
- * back-end server. */
-void dmxBEScreenInit(int idx, ScreenPtr pScreen)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[idx];
- XSetWindowAttributes attribs;
- XGCValues gcvals;
- unsigned long mask;
- int i, j;
-
- /* FIXME: The dmxScreenInit() code currently assumes that it will
- * not be called if the Xdmx server is started with this screen
- * detached -- i.e., it assumes that dmxScreen->beDisplay is always
- * valid. This is not necessarily a valid assumption when full
- * addition/removal of screens is implemented, but when this code is
- * broken out for screen reattachment, then we will reevaluate this
- * assumption.
- */
-
- pScreen->mmWidth = DisplayWidthMM(dmxScreen->beDisplay,
- DefaultScreen(dmxScreen->beDisplay));
- pScreen->mmHeight = DisplayHeightMM(dmxScreen->beDisplay,
- DefaultScreen(dmxScreen->beDisplay));
-
- pScreen->whitePixel = dmxScreen->beWhitePixel;
- pScreen->blackPixel = dmxScreen->beBlackPixel;
-
- /* Handle screen savers and DPMS on the backend */
- dmxDPMSInit(dmxScreen);
-
- /* Create root window for screen */
- mask = CWBackPixel | CWEventMask | CWColormap | CWOverrideRedirect;
- attribs.background_pixel = dmxScreen->beBlackPixel;
- attribs.event_mask = (KeyPressMask
- | KeyReleaseMask
- | ButtonPressMask
- | ButtonReleaseMask
- | EnterWindowMask
- | LeaveWindowMask
- | PointerMotionMask
- | KeymapStateMask
- | FocusChangeMask);
- attribs.colormap = dmxScreen->beDefColormaps[dmxScreen->beDefVisualIndex];
- attribs.override_redirect = True;
-
- dmxScreen->scrnWin =
- XCreateWindow(dmxScreen->beDisplay,
- DefaultRootWindow(dmxScreen->beDisplay),
- dmxScreen->scrnX,
- dmxScreen->scrnY,
- dmxScreen->scrnWidth,
- dmxScreen->scrnHeight,
- 0,
- pScreen->rootDepth,
- InputOutput,
- dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual,
- mask,
- &attribs);
- dmxPropertyWindow(dmxScreen);
-
- /*
- * This turns off the cursor by defining a cursor with no visible
- * components.
- */
- {
- char noCursorData[] = {0, 0, 0, 0,
- 0, 0, 0, 0};
- Pixmap pixmap;
- XColor color, tmp;
-
- pixmap = XCreateBitmapFromData(dmxScreen->beDisplay, dmxScreen->scrnWin,
- noCursorData, 8, 8);
- XAllocNamedColor(dmxScreen->beDisplay, dmxScreen->beDefColormaps[0],
- "black", &color, &tmp);
- dmxScreen->noCursor = XCreatePixmapCursor(dmxScreen->beDisplay,
- pixmap, pixmap,
- &color, &color, 0, 0);
- XDefineCursor(dmxScreen->beDisplay, dmxScreen->scrnWin,
- dmxScreen->noCursor);
-
- XFreePixmap(dmxScreen->beDisplay, pixmap);
- }
-
- XMapWindow(dmxScreen->beDisplay, dmxScreen->scrnWin);
-
- if (dmxShadowFB) {
- mask = (GCFunction
- | GCPlaneMask
- | GCClipMask);
- gcvals.function = GXcopy;
- gcvals.plane_mask = AllPlanes;
- gcvals.clip_mask = None;
-
- dmxScreen->shadowGC = XCreateGC(dmxScreen->beDisplay,
- dmxScreen->scrnWin,
- mask, &gcvals);
-
- dmxScreen->shadowFBImage =
- XCreateImage(dmxScreen->beDisplay,
- dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual,
- dmxScreen->beDepth,
- ZPixmap,
- 0,
- (char *)dmxScreen->shadow,
- dmxScreen->scrnWidth, dmxScreen->scrnHeight,
- dmxScreen->beBPP,
- PixmapBytePad(dmxScreen->scrnWidth,
- dmxScreen->beBPP));
- } else {
- /* Create default drawables (used during GC creation) */
- for (i = 0; i < dmxScreen->beNumPixmapFormats; i++)
- for (j = 0; j < dmxScreen->beNumDepths; j++)
- if ((dmxScreen->bePixmapFormats[i].depth == 1) ||
- (dmxScreen->bePixmapFormats[i].depth ==
- dmxScreen->beDepths[j])) {
- dmxScreen->scrnDefDrawables[i] = (Drawable)
- XCreatePixmap(dmxScreen->beDisplay, dmxScreen->scrnWin,
- 1, 1, dmxScreen->bePixmapFormats[i].depth);
- break;
- }
- }
-}
-
-/** Initialize screen number \a idx. */
-Bool dmxScreenInit(int idx, ScreenPtr pScreen, int argc, char *argv[])
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[idx];
- int i, j;
-
- if (dmxGeneration != serverGeneration) {
- /* Allocate font private index */
- dmxFontPrivateIndex = AllocateFontPrivateIndex();
- if (dmxFontPrivateIndex == -1)
- return FALSE;
-
- dmxGeneration = serverGeneration;
- }
-
- if (dmxShadowFB) {
- dmxScreen->shadow = shadowAlloc(dmxScreen->scrnWidth,
- dmxScreen->scrnHeight,
- dmxScreen->beBPP);
- } else {
- if (!dmxInitGC(pScreen)) return FALSE;
- if (!dmxInitWindow(pScreen)) return FALSE;
- if (!dmxInitPixmap(pScreen)) return FALSE;
- }
-
- /*
- * Initalise the visual types. miSetVisualTypesAndMasks() requires
- * that all of the types for each depth be collected together. It's
- * intended for slightly different usage to what we would like here.
- * Maybe a miAddVisualTypeAndMask() function will be added to make
- * things easier here.
- */
- for (i = 0; i < dmxScreen->beNumDepths; i++) {
- int depth;
- int visuals = 0;
- int bitsPerRgb = 0;
- int preferredClass = -1;
- Pixel redMask = 0;
- Pixel greenMask = 0;
- Pixel blueMask = 0;
-
- depth = dmxScreen->beDepths[i];
- for (j = 0; j < dmxScreen->beNumVisuals; j++) {
- XVisualInfo *vi;
-
- vi = &dmxScreen->beVisuals[j];
- if (vi->depth == depth) {
- /* Assume the masks are all the same. */
- visuals |= (1 << vi->class);
- bitsPerRgb = vi->bits_per_rgb;
- redMask = vi->red_mask;
- greenMask = vi->green_mask;
- blueMask = vi->blue_mask;
- if (j == dmxScreen->beDefVisualIndex) {
- preferredClass = vi->class;
- }
- }
- }
- miSetVisualTypesAndMasks(depth, visuals, bitsPerRgb, preferredClass,
- redMask, greenMask, blueMask);
- }
-
- fbScreenInit(pScreen,
- dmxShadowFB ? dmxScreen->shadow : NULL,
- dmxScreen->scrnWidth,
- dmxScreen->scrnHeight,
- dmxScreen->beXDPI,
- dmxScreen->beXDPI,
- dmxScreen->scrnWidth,
- dmxScreen->beBPP);
- (void)dmxPictureInit(pScreen, 0, 0);
-
- /* Not yet... */
- pScreen->GetWindowPixmap = NULL;
- pScreen->SetWindowPixmap = NULL;
-
- if (dmxShadowFB && !shadowInit(pScreen, dmxShadowUpdateProc, NULL))
- return FALSE;
-
- miInitializeBackingStore(pScreen);
-
- if (dmxShadowFB) {
- miDCInitialize(pScreen, &dmxPointerCursorFuncs);
- } else {
- MAXSCREENSALLOC(dmxCursorGeneration);
- if (dmxCursorGeneration[idx] != serverGeneration) {
- if (!(miPointerInitialize(pScreen,
- &dmxPointerSpriteFuncs,
- &dmxPointerCursorFuncs,
- FALSE)))
- return FALSE;
-
- dmxCursorGeneration[idx] = serverGeneration;
- }
- }
-
- DMX_WRAP(CloseScreen, dmxCloseScreen, dmxScreen, pScreen);
- DMX_WRAP(SaveScreen, dmxSaveScreen, dmxScreen, pScreen);
-
- dmxBEScreenInit(idx, pScreen);
-
- if (!dmxShadowFB) {
- /* Wrap GC functions */
- DMX_WRAP(CreateGC, dmxCreateGC, dmxScreen, pScreen);
-
- /* Wrap Window functions */
- DMX_WRAP(CreateWindow, dmxCreateWindow, dmxScreen, pScreen);
- DMX_WRAP(DestroyWindow, dmxDestroyWindow, dmxScreen, pScreen);
- DMX_WRAP(PositionWindow, dmxPositionWindow, dmxScreen, pScreen);
- DMX_WRAP(ChangeWindowAttributes, dmxChangeWindowAttributes, dmxScreen,
- pScreen);
- DMX_WRAP(RealizeWindow, dmxRealizeWindow, dmxScreen, pScreen);
- DMX_WRAP(UnrealizeWindow, dmxUnrealizeWindow, dmxScreen, pScreen);
- DMX_WRAP(RestackWindow, dmxRestackWindow, dmxScreen, pScreen);
- DMX_WRAP(WindowExposures, dmxWindowExposures, dmxScreen, pScreen);
- DMX_WRAP(CopyWindow, dmxCopyWindow, dmxScreen, pScreen);
-
- DMX_WRAP(ResizeWindow, dmxResizeWindow, dmxScreen, pScreen);
- DMX_WRAP(ReparentWindow, dmxReparentWindow, dmxScreen, pScreen);
-
- DMX_WRAP(ChangeBorderWidth, dmxChangeBorderWidth, dmxScreen, pScreen);
-
- /* Wrap Image functions */
- DMX_WRAP(GetImage, dmxGetImage, dmxScreen, pScreen);
- DMX_WRAP(GetSpans, dmxGetSpans, dmxScreen, pScreen);
-
- /* Wrap Pixmap functions */
- DMX_WRAP(CreatePixmap, dmxCreatePixmap, dmxScreen, pScreen);
- DMX_WRAP(DestroyPixmap, dmxDestroyPixmap, dmxScreen, pScreen);
- DMX_WRAP(BitmapToRegion, dmxBitmapToRegion, dmxScreen, pScreen);
-
- /* Wrap Font functions */
- DMX_WRAP(RealizeFont, dmxRealizeFont, dmxScreen, pScreen);
- DMX_WRAP(UnrealizeFont, dmxUnrealizeFont, dmxScreen, pScreen);
-
- /* Wrap Colormap functions */
- DMX_WRAP(CreateColormap, dmxCreateColormap, dmxScreen, pScreen);
- DMX_WRAP(DestroyColormap, dmxDestroyColormap, dmxScreen, pScreen);
- DMX_WRAP(InstallColormap, dmxInstallColormap, dmxScreen, pScreen);
- DMX_WRAP(StoreColors, dmxStoreColors, dmxScreen, pScreen);
-
- /* Wrap Shape functions */
- DMX_WRAP(SetShape, dmxSetShape, dmxScreen, pScreen);
- }
-
- if (!dmxCreateDefColormap(pScreen))
- return FALSE;
-
- return TRUE;
-}
-
-/** Close the \a pScreen resources on the back-end server. */
-void dmxBECloseScreen(ScreenPtr pScreen)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- int i;
-
- /* Restore the back-end screen-saver and DPMS state. */
- dmxDPMSTerm(dmxScreen);
-
- /* Free the screen resources */
-
- XFreeCursor(dmxScreen->beDisplay, dmxScreen->noCursor);
- dmxScreen->noCursor = (Cursor)0;
-
- XUnmapWindow(dmxScreen->beDisplay, dmxScreen->scrnWin);
- XDestroyWindow(dmxScreen->beDisplay, dmxScreen->scrnWin);
- dmxScreen->scrnWin = (Window)0;
-
- if (dmxShadowFB) {
- /* Free the shadow GC and image assocated with the back-end server */
- XFreeGC(dmxScreen->beDisplay, dmxScreen->shadowGC);
- dmxScreen->shadowGC = NULL;
- XFree(dmxScreen->shadowFBImage);
- dmxScreen->shadowFBImage = NULL;
- } else {
- /* Free the default drawables */
- for (i = 0; i < dmxScreen->beNumPixmapFormats; i++) {
- if (dmxScreen->scrnDefDrawables[i]) {
- XFreePixmap(dmxScreen->beDisplay,
- dmxScreen->scrnDefDrawables[i]);
- dmxScreen->scrnDefDrawables[i] = (Drawable)0;
- }
- }
- }
-
- /* Free resources allocated during initialization (in dmxinit.c) */
- for (i = 0; i < dmxScreen->beNumDefColormaps; i++)
- XFreeColormap(dmxScreen->beDisplay, dmxScreen->beDefColormaps[i]);
- xfree(dmxScreen->beDefColormaps);
- dmxScreen->beDefColormaps = NULL;
-
-#if 0
- /* Do not free visuals, depths and pixmap formats here. Free them
- * in dmxCloseScreen() instead -- see comment below. */
- XFree(dmxScreen->beVisuals);
- dmxScreen->beVisuals = NULL;
-
- XFree(dmxScreen->beDepths);
- dmxScreen->beDepths = NULL;
-
- XFree(dmxScreen->bePixmapFormats);
- dmxScreen->bePixmapFormats = NULL;
-#endif
-
-#ifdef GLXEXT
- if (dmxScreen->glxVisuals) {
- XFree(dmxScreen->glxVisuals);
- dmxScreen->glxVisuals = NULL;
- dmxScreen->numGlxVisuals = 0;
- }
-#endif
-
- /* Close display */
- XCloseDisplay(dmxScreen->beDisplay);
- dmxScreen->beDisplay = NULL;
-}
-
-/** Close screen number \a idx. */
-Bool dmxCloseScreen(int idx, ScreenPtr pScreen)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[idx];
-
- /* Reset the proc vectors */
- if (idx == 0) {
- dmxResetRender();
- dmxResetFonts();
- }
-
- if (dmxShadowFB) {
- /* Free the shadow framebuffer */
- xfree(dmxScreen->shadow);
- } else {
-
- /* Unwrap Shape functions */
- DMX_UNWRAP(SetShape, dmxScreen, pScreen);
-
- /* Unwrap the pScreen functions */
- DMX_UNWRAP(CreateGC, dmxScreen, pScreen);
-
- DMX_UNWRAP(CreateWindow, dmxScreen, pScreen);
- DMX_UNWRAP(DestroyWindow, dmxScreen, pScreen);
- DMX_UNWRAP(PositionWindow, dmxScreen, pScreen);
- DMX_UNWRAP(ChangeWindowAttributes, dmxScreen, pScreen);
- DMX_UNWRAP(RealizeWindow, dmxScreen, pScreen);
- DMX_UNWRAP(UnrealizeWindow, dmxScreen, pScreen);
- DMX_UNWRAP(RestackWindow, dmxScreen, pScreen);
- DMX_UNWRAP(WindowExposures, dmxScreen, pScreen);
- DMX_UNWRAP(CopyWindow, dmxScreen, pScreen);
-
- DMX_UNWRAP(ResizeWindow, dmxScreen, pScreen);
- DMX_UNWRAP(ReparentWindow, dmxScreen, pScreen);
-
- DMX_UNWRAP(ChangeBorderWidth, dmxScreen, pScreen);
-
- DMX_UNWRAP(GetImage, dmxScreen, pScreen);
- DMX_UNWRAP(GetSpans, dmxScreen, pScreen);
-
- DMX_UNWRAP(CreatePixmap, dmxScreen, pScreen);
- DMX_UNWRAP(DestroyPixmap, dmxScreen, pScreen);
- DMX_UNWRAP(BitmapToRegion, dmxScreen, pScreen);
-
- DMX_UNWRAP(RealizeFont, dmxScreen, pScreen);
- DMX_UNWRAP(UnrealizeFont, dmxScreen, pScreen);
-
- DMX_UNWRAP(CreateColormap, dmxScreen, pScreen);
- DMX_UNWRAP(DestroyColormap, dmxScreen, pScreen);
- DMX_UNWRAP(InstallColormap, dmxScreen, pScreen);
- DMX_UNWRAP(StoreColors, dmxScreen, pScreen);
- }
-
- DMX_UNWRAP(SaveScreen, dmxScreen, pScreen);
-
- if (dmxScreen->beDisplay) {
- dmxBECloseScreen(pScreen);
-
-#if 1
- /* Free visuals, depths and pixmap formats here so that they
- * won't be freed when a screen is detached, thereby allowing
- * the screen to be reattached to be compared to the one
- * previously removed.
- */
- XFree(dmxScreen->beVisuals);
- dmxScreen->beVisuals = NULL;
-
- XFree(dmxScreen->beDepths);
- dmxScreen->beDepths = NULL;
-
- XFree(dmxScreen->bePixmapFormats);
- dmxScreen->bePixmapFormats = NULL;
-#endif
- }
-
- DMX_UNWRAP(CloseScreen, dmxScreen, pScreen);
- return pScreen->CloseScreen(idx, pScreen);
-}
-
-static Bool dmxSaveScreen(ScreenPtr pScreen, int what)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
-
- if (dmxScreen->beDisplay) {
- switch (what) {
- case SCREEN_SAVER_OFF:
- case SCREEN_SAVER_FORCER:
- XResetScreenSaver(dmxScreen->beDisplay);
- dmxSync(dmxScreen, FALSE);
- break;
- case SCREEN_SAVER_ON:
- case SCREEN_SAVER_CYCLE:
- XActivateScreenSaver(dmxScreen->beDisplay);
- dmxSync(dmxScreen, FALSE);
- break;
- }
- }
-
- return TRUE;
-}
+/*
+ * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina.
+ *
+ * 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 on 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 (including the
+ * next paragraph) 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
+ * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
+ * 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.
+ */
+
+/*
+ * Authors:
+ * Kevin E. Martin <kem@redhat.com>
+ * David H. Dawes <dawes@xfree86.org>
+ *
+ */
+
+/** \file
+ * This file provides support for screen initialization. */
+
+#ifdef HAVE_DMX_CONFIG_H
+#include <dmx-config.h>
+#endif
+
+#include "dmx.h"
+#include "dmxsync.h"
+#include "dmxshadow.h"
+#include "dmxscrinit.h"
+#include "dmxcursor.h"
+#include "dmxgc.h"
+#include "dmxgcops.h"
+#include "dmxwindow.h"
+#include "dmxpixmap.h"
+#include "dmxfont.h"
+#include "dmxcmap.h"
+#include "dmxprop.h"
+#include "dmxdpms.h"
+
+#include "dmxpict.h"
+
+#include "fb.h"
+#include "mipointer.h"
+#include "micmap.h"
+
+extern Bool dmxCloseScreen(int idx, ScreenPtr pScreen);
+static Bool dmxSaveScreen(ScreenPtr pScreen, int what);
+
+static unsigned long dmxGeneration;
+static unsigned long *dmxCursorGeneration;
+
+static int dmxGCPrivateKeyIndex;
+DevPrivateKey dmxGCPrivateKey = &dmxGCPrivateKeyIndex; /**< Private index for GCs */
+static int dmxWinPrivateKeyIndex;
+DevPrivateKey dmxWinPrivateKey = &dmxWinPrivateKeyIndex; /**< Private index for Windows */
+static int dmxPixPrivateKeyIndex;
+DevPrivateKey dmxPixPrivateKey = &dmxPixPrivateKeyIndex; /**< Private index for Pixmaps */
+int dmxFontPrivateIndex; /**< Private index for Fonts */
+static int dmxScreenPrivateKeyIndex;
+DevPrivateKey dmxScreenPrivateKey = &dmxScreenPrivateKeyIndex; /**< Private index for Screens */
+static int dmxColormapPrivateKeyIndex;
+DevPrivateKey dmxColormapPrivateKey = &dmxColormapPrivateKeyIndex; /**< Private index for Colormaps */
+static int dmxPictPrivateKeyIndex;
+DevPrivateKey dmxPictPrivateKey = &dmxPictPrivateKeyIndex; /**< Private index for Picts */
+static int dmxGlyphSetPrivateKeyIndex;
+DevPrivateKey dmxGlyphSetPrivateKey = &dmxGlyphSetPrivateKeyIndex; /**< Private index for GlyphSets */
+
+/** Initialize the parts of screen \a idx that require access to the
+ * back-end server. */
+void dmxBEScreenInit(int idx, ScreenPtr pScreen)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[idx];
+ XSetWindowAttributes attribs;
+ XGCValues gcvals;
+ unsigned long mask;
+ int i, j;
+
+ /* FIXME: The dmxScreenInit() code currently assumes that it will
+ * not be called if the Xdmx server is started with this screen
+ * detached -- i.e., it assumes that dmxScreen->beDisplay is always
+ * valid. This is not necessarily a valid assumption when full
+ * addition/removal of screens is implemented, but when this code is
+ * broken out for screen reattachment, then we will reevaluate this
+ * assumption.
+ */
+
+ pScreen->mmWidth = DisplayWidthMM(dmxScreen->beDisplay,
+ DefaultScreen(dmxScreen->beDisplay));
+ pScreen->mmHeight = DisplayHeightMM(dmxScreen->beDisplay,
+ DefaultScreen(dmxScreen->beDisplay));
+
+ pScreen->whitePixel = dmxScreen->beWhitePixel;
+ pScreen->blackPixel = dmxScreen->beBlackPixel;
+
+ /* Handle screen savers and DPMS on the backend */
+ dmxDPMSInit(dmxScreen);
+
+ /* Create root window for screen */
+ mask = CWBackPixel | CWEventMask | CWColormap | CWOverrideRedirect;
+ attribs.background_pixel = dmxScreen->beBlackPixel;
+ attribs.event_mask = (KeyPressMask
+ | KeyReleaseMask
+ | ButtonPressMask
+ | ButtonReleaseMask
+ | EnterWindowMask
+ | LeaveWindowMask
+ | PointerMotionMask
+ | KeymapStateMask
+ | FocusChangeMask);
+ attribs.colormap = dmxScreen->beDefColormaps[dmxScreen->beDefVisualIndex];
+ attribs.override_redirect = True;
+
+ dmxScreen->scrnWin =
+ XCreateWindow(dmxScreen->beDisplay,
+ DefaultRootWindow(dmxScreen->beDisplay),
+ dmxScreen->scrnX,
+ dmxScreen->scrnY,
+ dmxScreen->scrnWidth,
+ dmxScreen->scrnHeight,
+ 0,
+ pScreen->rootDepth,
+ InputOutput,
+ dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual,
+ mask,
+ &attribs);
+ dmxPropertyWindow(dmxScreen);
+
+ /*
+ * This turns off the cursor by defining a cursor with no visible
+ * components.
+ */
+ {
+ char noCursorData[] = {0, 0, 0, 0,
+ 0, 0, 0, 0};
+ Pixmap pixmap;
+ XColor color, tmp;
+
+ pixmap = XCreateBitmapFromData(dmxScreen->beDisplay, dmxScreen->scrnWin,
+ noCursorData, 8, 8);
+ XAllocNamedColor(dmxScreen->beDisplay, dmxScreen->beDefColormaps[0],
+ "black", &color, &tmp);
+ dmxScreen->noCursor = XCreatePixmapCursor(dmxScreen->beDisplay,
+ pixmap, pixmap,
+ &color, &color, 0, 0);
+ XDefineCursor(dmxScreen->beDisplay, dmxScreen->scrnWin,
+ dmxScreen->noCursor);
+
+ XFreePixmap(dmxScreen->beDisplay, pixmap);
+ }
+
+ XMapWindow(dmxScreen->beDisplay, dmxScreen->scrnWin);
+
+ if (dmxShadowFB) {
+ mask = (GCFunction
+ | GCPlaneMask
+ | GCClipMask);
+ gcvals.function = GXcopy;
+ gcvals.plane_mask = AllPlanes;
+ gcvals.clip_mask = None;
+
+ dmxScreen->shadowGC = XCreateGC(dmxScreen->beDisplay,
+ dmxScreen->scrnWin,
+ mask, &gcvals);
+
+ dmxScreen->shadowFBImage =
+ XCreateImage(dmxScreen->beDisplay,
+ dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual,
+ dmxScreen->beDepth,
+ ZPixmap,
+ 0,
+ (char *)dmxScreen->shadow,
+ dmxScreen->scrnWidth, dmxScreen->scrnHeight,
+ dmxScreen->beBPP,
+ PixmapBytePad(dmxScreen->scrnWidth,
+ dmxScreen->beBPP));
+ } else {
+ /* Create default drawables (used during GC creation) */
+ for (i = 0; i < dmxScreen->beNumPixmapFormats; i++)
+ for (j = 0; j < dmxScreen->beNumDepths; j++)
+ if ((dmxScreen->bePixmapFormats[i].depth == 1) ||
+ (dmxScreen->bePixmapFormats[i].depth ==
+ dmxScreen->beDepths[j])) {
+ dmxScreen->scrnDefDrawables[i] = (Drawable)
+ XCreatePixmap(dmxScreen->beDisplay, dmxScreen->scrnWin,
+ 1, 1, dmxScreen->bePixmapFormats[i].depth);
+ break;
+ }
+ }
+}
+
+/** Initialize screen number \a idx. */
+Bool dmxScreenInit(int idx, ScreenPtr pScreen, int argc, char *argv[])
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[idx];
+ int i, j;
+
+ if (dmxGeneration != serverGeneration) {
+ /* Allocate font private index */
+ dmxFontPrivateIndex = AllocateFontPrivateIndex();
+ if (dmxFontPrivateIndex == -1)
+ return FALSE;
+
+ dmxGeneration = serverGeneration;
+ }
+
+ if (dmxShadowFB) {
+ dmxScreen->shadow = shadowAlloc(dmxScreen->scrnWidth,
+ dmxScreen->scrnHeight,
+ dmxScreen->beBPP);
+ } else {
+ if (!dmxInitGC(pScreen)) return FALSE;
+ if (!dmxInitWindow(pScreen)) return FALSE;
+ if (!dmxInitPixmap(pScreen)) return FALSE;
+ }
+
+ /*
+ * Initalise the visual types. miSetVisualTypesAndMasks() requires
+ * that all of the types for each depth be collected together. It's
+ * intended for slightly different usage to what we would like here.
+ * Maybe a miAddVisualTypeAndMask() function will be added to make
+ * things easier here.
+ */
+ for (i = 0; i < dmxScreen->beNumDepths; i++) {
+ int depth;
+ int visuals = 0;
+ int bitsPerRgb = 0;
+ int preferredClass = -1;
+ Pixel redMask = 0;
+ Pixel greenMask = 0;
+ Pixel blueMask = 0;
+
+ depth = dmxScreen->beDepths[i];
+ for (j = 0; j < dmxScreen->beNumVisuals; j++) {
+ XVisualInfo *vi;
+
+ vi = &dmxScreen->beVisuals[j];
+ if (vi->depth == depth) {
+ /* Assume the masks are all the same. */
+ visuals |= (1 << vi->class);
+ bitsPerRgb = vi->bits_per_rgb;
+ redMask = vi->red_mask;
+ greenMask = vi->green_mask;
+ blueMask = vi->blue_mask;
+ if (j == dmxScreen->beDefVisualIndex) {
+ preferredClass = vi->class;
+ }
+ }
+ }
+ miSetVisualTypesAndMasks(depth, visuals, bitsPerRgb, preferredClass,
+ redMask, greenMask, blueMask);
+ }
+
+ fbScreenInit(pScreen,
+ dmxShadowFB ? dmxScreen->shadow : NULL,
+ dmxScreen->scrnWidth,
+ dmxScreen->scrnHeight,
+ dmxScreen->beXDPI,
+ dmxScreen->beXDPI,
+ dmxScreen->scrnWidth,
+ dmxScreen->beBPP);
+ (void)dmxPictureInit(pScreen, 0, 0);
+
+ /* Not yet... */
+ pScreen->GetWindowPixmap = NULL;
+ pScreen->SetWindowPixmap = NULL;
+
+ if (dmxShadowFB && !shadowInit(pScreen, dmxShadowUpdateProc, NULL))
+ return FALSE;
+
+ miInitializeBackingStore(pScreen);
+
+ if (dmxShadowFB) {
+ miDCInitialize(pScreen, &dmxPointerCursorFuncs);
+ } else {
+ MAXSCREENSALLOC(dmxCursorGeneration);
+ if (dmxCursorGeneration[idx] != serverGeneration) {
+ if (!(miPointerInitialize(pScreen,
+ &dmxPointerSpriteFuncs,
+ &dmxPointerCursorFuncs,
+ FALSE)))
+ return FALSE;
+
+ dmxCursorGeneration[idx] = serverGeneration;
+ }
+ }
+
+ DMX_WRAP(CloseScreen, dmxCloseScreen, dmxScreen, pScreen);
+ DMX_WRAP(SaveScreen, dmxSaveScreen, dmxScreen, pScreen);
+
+ dmxBEScreenInit(idx, pScreen);
+
+ if (!dmxShadowFB) {
+ /* Wrap GC functions */
+ DMX_WRAP(CreateGC, dmxCreateGC, dmxScreen, pScreen);
+
+ /* Wrap Window functions */
+ DMX_WRAP(CreateWindow, dmxCreateWindow, dmxScreen, pScreen);
+ DMX_WRAP(DestroyWindow, dmxDestroyWindow, dmxScreen, pScreen);
+ DMX_WRAP(PositionWindow, dmxPositionWindow, dmxScreen, pScreen);
+ DMX_WRAP(ChangeWindowAttributes, dmxChangeWindowAttributes, dmxScreen,
+ pScreen);
+ DMX_WRAP(RealizeWindow, dmxRealizeWindow, dmxScreen, pScreen);
+ DMX_WRAP(UnrealizeWindow, dmxUnrealizeWindow, dmxScreen, pScreen);
+ DMX_WRAP(RestackWindow, dmxRestackWindow, dmxScreen, pScreen);
+ DMX_WRAP(WindowExposures, dmxWindowExposures, dmxScreen, pScreen);
+ DMX_WRAP(CopyWindow, dmxCopyWindow, dmxScreen, pScreen);
+
+ DMX_WRAP(ResizeWindow, dmxResizeWindow, dmxScreen, pScreen);
+ DMX_WRAP(ReparentWindow, dmxReparentWindow, dmxScreen, pScreen);
+
+ DMX_WRAP(ChangeBorderWidth, dmxChangeBorderWidth, dmxScreen, pScreen);
+
+ /* Wrap Image functions */
+ DMX_WRAP(GetImage, dmxGetImage, dmxScreen, pScreen);
+ DMX_WRAP(GetSpans, dmxGetSpans, dmxScreen, pScreen);
+
+ /* Wrap Pixmap functions */
+ DMX_WRAP(CreatePixmap, dmxCreatePixmap, dmxScreen, pScreen);
+ DMX_WRAP(DestroyPixmap, dmxDestroyPixmap, dmxScreen, pScreen);
+ DMX_WRAP(BitmapToRegion, dmxBitmapToRegion, dmxScreen, pScreen);
+
+ /* Wrap Font functions */
+ DMX_WRAP(RealizeFont, dmxRealizeFont, dmxScreen, pScreen);
+ DMX_WRAP(UnrealizeFont, dmxUnrealizeFont, dmxScreen, pScreen);
+
+ /* Wrap Colormap functions */
+ DMX_WRAP(CreateColormap, dmxCreateColormap, dmxScreen, pScreen);
+ DMX_WRAP(DestroyColormap, dmxDestroyColormap, dmxScreen, pScreen);
+ DMX_WRAP(InstallColormap, dmxInstallColormap, dmxScreen, pScreen);
+ DMX_WRAP(StoreColors, dmxStoreColors, dmxScreen, pScreen);
+
+ /* Wrap Shape functions */
+ DMX_WRAP(SetShape, dmxSetShape, dmxScreen, pScreen);
+ }
+
+ if (!dmxCreateDefColormap(pScreen))
+ return FALSE;
+
+ return TRUE;
+}
+
+/** Close the \a pScreen resources on the back-end server. */
+void dmxBECloseScreen(ScreenPtr pScreen)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ int i;
+
+ /* Restore the back-end screen-saver and DPMS state. */
+ dmxDPMSTerm(dmxScreen);
+
+ /* Free the screen resources */
+
+ XFreeCursor(dmxScreen->beDisplay, dmxScreen->noCursor);
+ dmxScreen->noCursor = (Cursor)0;
+
+ XUnmapWindow(dmxScreen->beDisplay, dmxScreen->scrnWin);
+ XDestroyWindow(dmxScreen->beDisplay, dmxScreen->scrnWin);
+ dmxScreen->scrnWin = (Window)0;
+
+ if (dmxShadowFB) {
+ /* Free the shadow GC and image assocated with the back-end server */
+ XFreeGC(dmxScreen->beDisplay, dmxScreen->shadowGC);
+ dmxScreen->shadowGC = NULL;
+ XFree(dmxScreen->shadowFBImage);
+ dmxScreen->shadowFBImage = NULL;
+ } else {
+ /* Free the default drawables */
+ for (i = 0; i < dmxScreen->beNumPixmapFormats; i++) {
+ if (dmxScreen->scrnDefDrawables[i]) {
+ XFreePixmap(dmxScreen->beDisplay,
+ dmxScreen->scrnDefDrawables[i]);
+ dmxScreen->scrnDefDrawables[i] = (Drawable)0;
+ }
+ }
+ }
+
+ /* Free resources allocated during initialization (in dmxinit.c) */
+ for (i = 0; i < dmxScreen->beNumDefColormaps; i++)
+ XFreeColormap(dmxScreen->beDisplay, dmxScreen->beDefColormaps[i]);
+ free(dmxScreen->beDefColormaps);
+ dmxScreen->beDefColormaps = NULL;
+
+#if 0
+ /* Do not free visuals, depths and pixmap formats here. Free them
+ * in dmxCloseScreen() instead -- see comment below. */
+ XFree(dmxScreen->beVisuals);
+ dmxScreen->beVisuals = NULL;
+
+ XFree(dmxScreen->beDepths);
+ dmxScreen->beDepths = NULL;
+
+ XFree(dmxScreen->bePixmapFormats);
+ dmxScreen->bePixmapFormats = NULL;
+#endif
+
+#ifdef GLXEXT
+ if (dmxScreen->glxVisuals) {
+ XFree(dmxScreen->glxVisuals);
+ dmxScreen->glxVisuals = NULL;
+ dmxScreen->numGlxVisuals = 0;
+ }
+#endif
+
+ /* Close display */
+ XCloseDisplay(dmxScreen->beDisplay);
+ dmxScreen->beDisplay = NULL;
+}
+
+/** Close screen number \a idx. */
+Bool dmxCloseScreen(int idx, ScreenPtr pScreen)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[idx];
+
+ /* Reset the proc vectors */
+ if (idx == 0) {
+ dmxResetRender();
+ dmxResetFonts();
+ }
+
+ if (dmxShadowFB) {
+ /* Free the shadow framebuffer */
+ free(dmxScreen->shadow);
+ } else {
+
+ /* Unwrap Shape functions */
+ DMX_UNWRAP(SetShape, dmxScreen, pScreen);
+
+ /* Unwrap the pScreen functions */
+ DMX_UNWRAP(CreateGC, dmxScreen, pScreen);
+
+ DMX_UNWRAP(CreateWindow, dmxScreen, pScreen);
+ DMX_UNWRAP(DestroyWindow, dmxScreen, pScreen);
+ DMX_UNWRAP(PositionWindow, dmxScreen, pScreen);
+ DMX_UNWRAP(ChangeWindowAttributes, dmxScreen, pScreen);
+ DMX_UNWRAP(RealizeWindow, dmxScreen, pScreen);
+ DMX_UNWRAP(UnrealizeWindow, dmxScreen, pScreen);
+ DMX_UNWRAP(RestackWindow, dmxScreen, pScreen);
+ DMX_UNWRAP(WindowExposures, dmxScreen, pScreen);
+ DMX_UNWRAP(CopyWindow, dmxScreen, pScreen);
+
+ DMX_UNWRAP(ResizeWindow, dmxScreen, pScreen);
+ DMX_UNWRAP(ReparentWindow, dmxScreen, pScreen);
+
+ DMX_UNWRAP(ChangeBorderWidth, dmxScreen, pScreen);
+
+ DMX_UNWRAP(GetImage, dmxScreen, pScreen);
+ DMX_UNWRAP(GetSpans, dmxScreen, pScreen);
+
+ DMX_UNWRAP(CreatePixmap, dmxScreen, pScreen);
+ DMX_UNWRAP(DestroyPixmap, dmxScreen, pScreen);
+ DMX_UNWRAP(BitmapToRegion, dmxScreen, pScreen);
+
+ DMX_UNWRAP(RealizeFont, dmxScreen, pScreen);
+ DMX_UNWRAP(UnrealizeFont, dmxScreen, pScreen);
+
+ DMX_UNWRAP(CreateColormap, dmxScreen, pScreen);
+ DMX_UNWRAP(DestroyColormap, dmxScreen, pScreen);
+ DMX_UNWRAP(InstallColormap, dmxScreen, pScreen);
+ DMX_UNWRAP(StoreColors, dmxScreen, pScreen);
+ }
+
+ DMX_UNWRAP(SaveScreen, dmxScreen, pScreen);
+
+ if (dmxScreen->beDisplay) {
+ dmxBECloseScreen(pScreen);
+
+#if 1
+ /* Free visuals, depths and pixmap formats here so that they
+ * won't be freed when a screen is detached, thereby allowing
+ * the screen to be reattached to be compared to the one
+ * previously removed.
+ */
+ XFree(dmxScreen->beVisuals);
+ dmxScreen->beVisuals = NULL;
+
+ XFree(dmxScreen->beDepths);
+ dmxScreen->beDepths = NULL;
+
+ XFree(dmxScreen->bePixmapFormats);
+ dmxScreen->bePixmapFormats = NULL;
+#endif
+ }
+
+ DMX_UNWRAP(CloseScreen, dmxScreen, pScreen);
+ return pScreen->CloseScreen(idx, pScreen);
+}
+
+static Bool dmxSaveScreen(ScreenPtr pScreen, int what)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+
+ if (dmxScreen->beDisplay) {
+ switch (what) {
+ case SCREEN_SAVER_OFF:
+ case SCREEN_SAVER_FORCER:
+ XResetScreenSaver(dmxScreen->beDisplay);
+ dmxSync(dmxScreen, FALSE);
+ break;
+ case SCREEN_SAVER_ON:
+ case SCREEN_SAVER_CYCLE:
+ XActivateScreenSaver(dmxScreen->beDisplay);
+ dmxSync(dmxScreen, FALSE);
+ break;
+ }
+ }
+
+ return TRUE;
+}
diff --git a/xorg-server/hw/dmx/dmxsync.c b/xorg-server/hw/dmx/dmxsync.c
index 2cec1b97c..8ace59470 100644
--- a/xorg-server/hw/dmx/dmxsync.c
+++ b/xorg-server/hw/dmx/dmxsync.c
@@ -1,193 +1,193 @@
-/*
- * Copyright 2002-2004 Red Hat Inc., Durham, North Carolina.
- *
- * 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 on 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 (including the
- * next paragraph) 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
- * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
- * 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.
- */
-
-/*
- * Authors:
- * Rickard E. (Rik) Faith <faith@redhat.com>
- *
- */
-
-/** \file
- *
- * The DMX server code is written to call #dmxSync() whenever an XSync()
- * might be necessary. However, since XSync() requires a two way
- * communication with the other X server, eliminating unnecessary
- * XSync() calls is a key performance optimization. Support for this
- * optimization is provided here. Statistics about XSync() calls and
- * latency are gathered in \a dmxstat.c.
- *
- * During the initial conversion from calling XSync() immediately to the
- * XSync() batching method implemented in this file, it was noted that,
- * out of more than 300 \a x11perf tests, 8 tests became more than 100
- * times faster, with 68 more than 50X faster, 114 more than 10X faster,
- * and 181 more than 2X faster. */
-
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
-
-#include "dmx.h"
-#include "dmxsync.h"
-#include "dmxstat.h"
-#include "dmxlog.h"
-#include <sys/time.h>
-
-static int dmxSyncInterval = 100; /* Default interval in milliseconds */
-static OsTimerPtr dmxSyncTimer;
-static int dmxSyncPending;
-
-static void dmxDoSync(DMXScreenInfo *dmxScreen)
-{
- dmxScreen->needsSync = FALSE;
-
- if (!dmxScreen->beDisplay)
- return; /* FIXME: Is this correct behavior for sync stats? */
-
- if (!dmxStatInterval) {
- XSync(dmxScreen->beDisplay, False);
- } else {
- struct timeval start, stop;
-
- gettimeofday(&start, 0);
- XSync(dmxScreen->beDisplay, False);
- gettimeofday(&stop, 0);
- dmxStatSync(dmxScreen, &stop, &start, dmxSyncPending);
- }
-}
-
-static CARD32 dmxSyncCallback(OsTimerPtr timer, CARD32 time, pointer arg)
-{
- int i;
-
- if (dmxSyncPending) {
- for (i = 0; i < dmxNumScreens; i++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[i];
- if (dmxScreen->needsSync) dmxDoSync(dmxScreen);
- }
- }
- dmxSyncPending = 0;
- return 0; /* Do not place on queue again */
-}
-
-static void dmxSyncBlockHandler(pointer blockData, OSTimePtr pTimeout,
- pointer pReadMask)
-{
- TimerForce(dmxSyncTimer);
-}
-
-static void dmxSyncWakeupHandler(pointer blockData, int result,
- pointer pReadMask)
-{
-}
-
-/** Request the XSync() batching optimization with the specified \a
- * interval (in mS). If the \a interval is 0, 100mS is used. If the \a
- * interval is less than 0, then the XSync() batching optimization is
- * not requested (e.g., so the -syncbatch -1 command line option can
- * turn off the default 100mS XSync() batching).
- *
- * Note that the parameter to this routine is a string, since it will
- * usually be called from #ddxProcessArgument in \a dmxinit.c */
-void dmxSyncActivate(const char *interval)
-{
- dmxSyncInterval = (interval ? atoi(interval) : 100);
-
- if (dmxSyncInterval < 0) dmxSyncInterval = 0;
-}
-
-/** Initialize the XSync() batching optimization, but only if
- * #dmxSyncActivate was last called with a non-negative value. */
-void dmxSyncInit(void)
-{
- if (dmxSyncInterval) {
- RegisterBlockAndWakeupHandlers(dmxSyncBlockHandler,
- dmxSyncWakeupHandler,
- NULL);
- dmxLog(dmxInfo, "XSync batching with %d ms interval\n",
- dmxSyncInterval);
- } else {
- dmxLog(dmxInfo, "XSync batching disabled\n");
- }
-}
-
-/** Request an XSync() to the display used by \a dmxScreen. If \a now
- * is TRUE, call XSync() immediately instead of waiting for the next
- * XSync() batching point. Note that if XSync() batching was deselected
- * with #dmxSyncActivate() before #dmxSyncInit() was called, then no
- * XSync() batching is performed and this function always calles XSync()
- * immediately.
- *
- * (Note that this function uses TimerSet but works correctly in the
- * face of a server generation. See the source for details.)
- *
- * If \a dmxScreen is \a NULL, then all pending syncs will be flushed
- * immediately.
- */
-void dmxSync(DMXScreenInfo *dmxScreen, Bool now)
-{
- static unsigned long dmxGeneration = 0;
-
- if (dmxSyncInterval) {
- if (dmxGeneration != serverGeneration) {
- /* Server generation does a TimerInit, which frees all
- * timers. So, at this point dmxSyncTimer is either:
- * 1) NULL, iff dmxGeneration == 0,
- * 2) freed, if it was on a queue (dmxSyncPending != 0), or
- * 3) allocated, if it wasn't on a queue (dmxSyncPending == 0)
- */
- if (dmxSyncTimer && !dmxSyncPending) xfree(dmxSyncTimer);
- dmxSyncTimer = NULL;
- now = TRUE;
- dmxGeneration = serverGeneration;
- }
- /* Queue sync */
- if (dmxScreen) {
- dmxScreen->needsSync = TRUE;
- ++dmxSyncPending;
- }
-
- /* Do sync or set time for later */
- if (now || !dmxScreen) {
- if (!TimerForce(dmxSyncTimer)) dmxSyncCallback(NULL, 0, NULL);
- /* At this point, dmxSyncPending == 0 because
- * dmxSyncCallback must have been called. */
- if (dmxSyncPending)
- dmxLog(dmxFatal, "dmxSync(%s,%d): dmxSyncPending = %d\n",
- dmxScreen ? dmxScreen->name : "", now, dmxSyncPending);
- } else {
- dmxScreen->needsSync = TRUE;
- if (dmxSyncPending == 1)
- dmxSyncTimer = TimerSet(dmxSyncTimer, 0, dmxSyncInterval,
- dmxSyncCallback, NULL);
- }
- } else {
- /* If dmxSyncInterval is not being used,
- * then all the backends are already
- * up-to-date. */
- if (dmxScreen) dmxDoSync(dmxScreen);
- }
-}
+/*
+ * Copyright 2002-2004 Red Hat Inc., Durham, North Carolina.
+ *
+ * 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 on 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 (including the
+ * next paragraph) 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
+ * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
+ * 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.
+ */
+
+/*
+ * Authors:
+ * Rickard E. (Rik) Faith <faith@redhat.com>
+ *
+ */
+
+/** \file
+ *
+ * The DMX server code is written to call #dmxSync() whenever an XSync()
+ * might be necessary. However, since XSync() requires a two way
+ * communication with the other X server, eliminating unnecessary
+ * XSync() calls is a key performance optimization. Support for this
+ * optimization is provided here. Statistics about XSync() calls and
+ * latency are gathered in \a dmxstat.c.
+ *
+ * During the initial conversion from calling XSync() immediately to the
+ * XSync() batching method implemented in this file, it was noted that,
+ * out of more than 300 \a x11perf tests, 8 tests became more than 100
+ * times faster, with 68 more than 50X faster, 114 more than 10X faster,
+ * and 181 more than 2X faster. */
+
+#ifdef HAVE_DMX_CONFIG_H
+#include <dmx-config.h>
+#endif
+
+#include "dmx.h"
+#include "dmxsync.h"
+#include "dmxstat.h"
+#include "dmxlog.h"
+#include <sys/time.h>
+
+static int dmxSyncInterval = 100; /* Default interval in milliseconds */
+static OsTimerPtr dmxSyncTimer;
+static int dmxSyncPending;
+
+static void dmxDoSync(DMXScreenInfo *dmxScreen)
+{
+ dmxScreen->needsSync = FALSE;
+
+ if (!dmxScreen->beDisplay)
+ return; /* FIXME: Is this correct behavior for sync stats? */
+
+ if (!dmxStatInterval) {
+ XSync(dmxScreen->beDisplay, False);
+ } else {
+ struct timeval start, stop;
+
+ gettimeofday(&start, 0);
+ XSync(dmxScreen->beDisplay, False);
+ gettimeofday(&stop, 0);
+ dmxStatSync(dmxScreen, &stop, &start, dmxSyncPending);
+ }
+}
+
+static CARD32 dmxSyncCallback(OsTimerPtr timer, CARD32 time, pointer arg)
+{
+ int i;
+
+ if (dmxSyncPending) {
+ for (i = 0; i < dmxNumScreens; i++) {
+ DMXScreenInfo *dmxScreen = &dmxScreens[i];
+ if (dmxScreen->needsSync) dmxDoSync(dmxScreen);
+ }
+ }
+ dmxSyncPending = 0;
+ return 0; /* Do not place on queue again */
+}
+
+static void dmxSyncBlockHandler(pointer blockData, OSTimePtr pTimeout,
+ pointer pReadMask)
+{
+ TimerForce(dmxSyncTimer);
+}
+
+static void dmxSyncWakeupHandler(pointer blockData, int result,
+ pointer pReadMask)
+{
+}
+
+/** Request the XSync() batching optimization with the specified \a
+ * interval (in mS). If the \a interval is 0, 100mS is used. If the \a
+ * interval is less than 0, then the XSync() batching optimization is
+ * not requested (e.g., so the -syncbatch -1 command line option can
+ * turn off the default 100mS XSync() batching).
+ *
+ * Note that the parameter to this routine is a string, since it will
+ * usually be called from #ddxProcessArgument in \a dmxinit.c */
+void dmxSyncActivate(const char *interval)
+{
+ dmxSyncInterval = (interval ? atoi(interval) : 100);
+
+ if (dmxSyncInterval < 0) dmxSyncInterval = 0;
+}
+
+/** Initialize the XSync() batching optimization, but only if
+ * #dmxSyncActivate was last called with a non-negative value. */
+void dmxSyncInit(void)
+{
+ if (dmxSyncInterval) {
+ RegisterBlockAndWakeupHandlers(dmxSyncBlockHandler,
+ dmxSyncWakeupHandler,
+ NULL);
+ dmxLog(dmxInfo, "XSync batching with %d ms interval\n",
+ dmxSyncInterval);
+ } else {
+ dmxLog(dmxInfo, "XSync batching disabled\n");
+ }
+}
+
+/** Request an XSync() to the display used by \a dmxScreen. If \a now
+ * is TRUE, call XSync() immediately instead of waiting for the next
+ * XSync() batching point. Note that if XSync() batching was deselected
+ * with #dmxSyncActivate() before #dmxSyncInit() was called, then no
+ * XSync() batching is performed and this function always calles XSync()
+ * immediately.
+ *
+ * (Note that this function uses TimerSet but works correctly in the
+ * face of a server generation. See the source for details.)
+ *
+ * If \a dmxScreen is \a NULL, then all pending syncs will be flushed
+ * immediately.
+ */
+void dmxSync(DMXScreenInfo *dmxScreen, Bool now)
+{
+ static unsigned long dmxGeneration = 0;
+
+ if (dmxSyncInterval) {
+ if (dmxGeneration != serverGeneration) {
+ /* Server generation does a TimerInit, which frees all
+ * timers. So, at this point dmxSyncTimer is either:
+ * 1) NULL, iff dmxGeneration == 0,
+ * 2) freed, if it was on a queue (dmxSyncPending != 0), or
+ * 3) allocated, if it wasn't on a queue (dmxSyncPending == 0)
+ */
+ if (dmxSyncTimer && !dmxSyncPending) free(dmxSyncTimer);
+ dmxSyncTimer = NULL;
+ now = TRUE;
+ dmxGeneration = serverGeneration;
+ }
+ /* Queue sync */
+ if (dmxScreen) {
+ dmxScreen->needsSync = TRUE;
+ ++dmxSyncPending;
+ }
+
+ /* Do sync or set time for later */
+ if (now || !dmxScreen) {
+ if (!TimerForce(dmxSyncTimer)) dmxSyncCallback(NULL, 0, NULL);
+ /* At this point, dmxSyncPending == 0 because
+ * dmxSyncCallback must have been called. */
+ if (dmxSyncPending)
+ dmxLog(dmxFatal, "dmxSync(%s,%d): dmxSyncPending = %d\n",
+ dmxScreen ? dmxScreen->name : "", now, dmxSyncPending);
+ } else {
+ dmxScreen->needsSync = TRUE;
+ if (dmxSyncPending == 1)
+ dmxSyncTimer = TimerSet(dmxSyncTimer, 0, dmxSyncInterval,
+ dmxSyncCallback, NULL);
+ }
+ } else {
+ /* If dmxSyncInterval is not being used,
+ * then all the backends are already
+ * up-to-date. */
+ if (dmxScreen) dmxDoSync(dmxScreen);
+ }
+}
diff --git a/xorg-server/hw/dmx/dmxwindow.c b/xorg-server/hw/dmx/dmxwindow.c
index ea2f2c579..3466f074f 100644
--- a/xorg-server/hw/dmx/dmxwindow.c
+++ b/xorg-server/hw/dmx/dmxwindow.c
@@ -1,1015 +1,1015 @@
-/*
- * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina.
- *
- * 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 on 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 (including the
- * next paragraph) 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
- * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
- * 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.
- */
-
-/*
- * Authors:
- * Kevin E. Martin <kem@redhat.com>
- *
- */
-
-/** \file
- * This file provides support for window-related functions. */
-
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
-
-#include "dmx.h"
-#include "dmxsync.h"
-#include "dmxwindow.h"
-#include "dmxpixmap.h"
-#include "dmxcmap.h"
-#include "dmxvisual.h"
-#include "dmxinput.h"
-#include "dmxextension.h"
-#include "dmxpict.h"
-
-#include "windowstr.h"
-
-static void dmxDoRestackWindow(WindowPtr pWindow);
-static void dmxDoChangeWindowAttributes(WindowPtr pWindow,
- unsigned long *mask,
- XSetWindowAttributes *attribs);
-
-static void dmxDoSetShape(WindowPtr pWindow);
-
-/** Initialize the private area for the window functions. */
-Bool dmxInitWindow(ScreenPtr pScreen)
-{
- if (!dixRequestPrivate(dmxWinPrivateKey, sizeof(dmxWinPrivRec)))
- return FALSE;
-
- return TRUE;
-}
-
-
-Window dmxCreateRootWindow(WindowPtr pWindow)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
- Window parent;
- Visual *visual;
- unsigned long mask;
- XSetWindowAttributes attribs;
- ColormapPtr pCmap;
- dmxColormapPrivPtr pCmapPriv;
-
- /* Create root window */
-
- parent = dmxScreen->scrnWin; /* This is our "Screen" window */
- visual = dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual;
-
- pCmap = (ColormapPtr)LookupIDByType(wColormap(pWindow), RT_COLORMAP);
- pCmapPriv = DMX_GET_COLORMAP_PRIV(pCmap);
-
- mask = CWEventMask | CWBackingStore | CWColormap | CWBorderPixel;
- attribs.event_mask = ExposureMask;
- attribs.backing_store = NotUseful;
- attribs.colormap = pCmapPriv->cmap;
- attribs.border_pixel = 0;
-
- /* Incorporate new attributes, if needed */
- if (pWinPriv->attribMask) {
- dmxDoChangeWindowAttributes(pWindow, &pWinPriv->attribMask, &attribs);
- mask |= pWinPriv->attribMask;
- }
-
- return XCreateWindow(dmxScreen->beDisplay,
- parent,
- pWindow->origin.x - wBorderWidth(pWindow),
- pWindow->origin.y - wBorderWidth(pWindow),
- pWindow->drawable.width,
- pWindow->drawable.height,
- pWindow->borderWidth,
- pWindow->drawable.depth,
- pWindow->drawable.class,
- visual,
- mask,
- &attribs);
-}
-
-/** Change the location and size of the "screen" window. Called from
- * #dmxConfigureScreenWindow(). */
-void dmxResizeScreenWindow(ScreenPtr pScreen,
- int x, int y, int w, int h)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- unsigned int m;
- XWindowChanges c;
-
- if (!dmxScreen->beDisplay)
- return;
-
- /* Handle resizing on back-end server */
- m = CWX | CWY | CWWidth | CWHeight;
- c.x = x;
- c.y = y;
- c.width = w;
- c.height = h;
-
- XConfigureWindow(dmxScreen->beDisplay, dmxScreen->scrnWin, m, &c);
- dmxSync(dmxScreen, False);
-}
-
-/** Change the location and size of the "root" window. Called from
- * #dmxConfigureRootWindow. */
-void dmxResizeRootWindow(WindowPtr pRoot,
- int x, int y, int w, int h)
-{
- DMXScreenInfo *dmxScreen = &dmxScreens[pRoot->drawable.pScreen->myNum];
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pRoot);
- unsigned int m;
- XWindowChanges c;
-
- /* Handle resizing on back-end server */
- if (dmxScreen->beDisplay) {
- m = CWX | CWY | CWWidth | CWHeight;
- c.x = x;
- c.y = y;
- c.width = (w > 0) ? w : 1;
- c.height = (h > 0) ? h : 1;
-
- XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c);
- }
-
- if (w == 0 || h == 0) {
- if (pWinPriv->mapped) {
- if (dmxScreen->beDisplay)
- XUnmapWindow(dmxScreen->beDisplay, pWinPriv->window);
- pWinPriv->mapped = FALSE;
- }
- } else if (!pWinPriv->mapped) {
- if (dmxScreen->beDisplay)
- XMapWindow(dmxScreen->beDisplay, pWinPriv->window);
- pWinPriv->mapped = TRUE;
- }
-
- if (dmxScreen->beDisplay)
- dmxSync(dmxScreen, False);
-}
-
-void dmxGetDefaultWindowAttributes(WindowPtr pWindow,
- Colormap *cmap,
- Visual **visual)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
-
- if (pWindow->drawable.class != InputOnly &&
- pWindow->optional &&
- pWindow->optional->visual != wVisual(pWindow->parent)) {
-
- /* Find the matching visual */
- *visual = dmxLookupVisualFromID(pScreen, wVisual(pWindow));
-
- /* Handle optional colormaps */
- if (pWindow->optional->colormap) {
- ColormapPtr pCmap;
- dmxColormapPrivPtr pCmapPriv;
-
- pCmap = (ColormapPtr)LookupIDByType(wColormap(pWindow),
- RT_COLORMAP);
- pCmapPriv = DMX_GET_COLORMAP_PRIV(pCmap);
- *cmap = pCmapPriv->cmap;
- } else {
- *cmap = dmxColormapFromDefaultVisual(pScreen, *visual);
- }
- } else {
- *visual = CopyFromParent;
- *cmap = (Colormap)0;
- }
-}
-
-static Window dmxCreateNonRootWindow(WindowPtr pWindow)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
- Window parent;
- unsigned long mask = 0L;
- XSetWindowAttributes attribs;
- dmxWinPrivPtr pParentPriv = DMX_GET_WINDOW_PRIV(pWindow->parent);
-
- /* Create window on back-end server */
-
- parent = pParentPriv->window;
-
- /* The parent won't exist if this call to CreateNonRootWindow came
- from ReparentWindow and the grandparent window has not yet been
- created */
- if (!parent) {
- dmxCreateAndRealizeWindow(pWindow->parent, FALSE);
- parent = pParentPriv->window;
- }
-
- /* Incorporate new attributes, if needed */
- if (pWinPriv->attribMask) {
- dmxDoChangeWindowAttributes(pWindow, &pWinPriv->attribMask, &attribs);
- mask |= pWinPriv->attribMask;
- }
-
- /* Add in default attributes */
- if (pWindow->drawable.class != InputOnly) {
- mask |= CWBackingStore;
- attribs.backing_store = NotUseful;
-
- if (!(mask & CWColormap) && pWinPriv->cmap) {
- mask |= CWColormap;
- attribs.colormap = pWinPriv->cmap;
- if (!(mask & CWBorderPixel)) {
- mask |= CWBorderPixel;
- attribs.border_pixel = 0;
- }
- }
- }
-
- /* Handle case where subwindows are being mapped, but created out of
- order -- if current window has a previous sibling, then it cannot
- be created on top of the stack, so we must restack the windows */
- pWinPriv->restacked = (pWindow->prevSib != NullWindow);
-
- return XCreateWindow(dmxScreen->beDisplay,
- parent,
- pWindow->origin.x - wBorderWidth(pWindow),
- pWindow->origin.y - wBorderWidth(pWindow),
- pWindow->drawable.width,
- pWindow->drawable.height,
- pWindow->borderWidth,
- pWindow->drawable.depth,
- pWindow->drawable.class,
- pWinPriv->visual,
- mask,
- &attribs);
-}
-
-/** This function handles lazy window creation and realization. Window
- * creation is handled by #dmxCreateNonRootWindow(). It also handles
- * any stacking changes that have occured since the window was
- * originally created by calling #dmxDoRestackWindow(). If the window
- * is shaped, the shape is set on the back-end server by calling
- * #dmxDoSetShape(), and if the window has pictures (from RENDER)
- * associated with it, those pictures are created on the back-end
- * server by calling #dmxCreatePictureList(). If \a doSync is TRUE,
- * then #dmxSync() is called. */
-void dmxCreateAndRealizeWindow(WindowPtr pWindow, Bool doSync)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
-
- if (!dmxScreen->beDisplay) return;
-
- pWinPriv->window = dmxCreateNonRootWindow(pWindow);
- if (pWinPriv->restacked) dmxDoRestackWindow(pWindow);
- if (pWinPriv->isShaped) dmxDoSetShape(pWindow);
- if (pWinPriv->hasPict) dmxCreatePictureList(pWindow);
- if (pWinPriv->mapped) XMapWindow(dmxScreen->beDisplay,
- pWinPriv->window);
- if (doSync) dmxSync(dmxScreen, False);
-}
-
-/** Create \a pWindow on the back-end server. If the lazy window
- * creation optimization is enabled, then the actual creation and
- * realization of the window is handled by
- * #dmxCreateAndRealizeWindow(). */
-Bool dmxCreateWindow(WindowPtr pWindow)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
- Bool ret = TRUE;
-
- DMX_UNWRAP(CreateWindow, dmxScreen, pScreen);
-#if 0
- if (pScreen->CreateWindow)
- ret = pScreen->CreateWindow(pWindow);
-#endif
-
- /* Set up the defaults */
- pWinPriv->window = (Window)0;
- pWinPriv->offscreen = TRUE;
- pWinPriv->mapped = FALSE;
- pWinPriv->restacked = FALSE;
- pWinPriv->attribMask = 0;
- pWinPriv->isShaped = FALSE;
- pWinPriv->hasPict = FALSE;
-#ifdef GLXEXT
- pWinPriv->swapGroup = NULL;
- pWinPriv->barrier = 0;
-#endif
-
- if (dmxScreen->beDisplay) {
- /* Only create the root window at this stage -- non-root windows are
- created when they are mapped and are on-screen */
- if (!pWindow->parent) {
- dmxScreen->rootWin = pWinPriv->window
- = dmxCreateRootWindow(pWindow);
- if (dmxScreen->scrnX != dmxScreen->rootX
- || dmxScreen->scrnY != dmxScreen->rootY
- || dmxScreen->scrnWidth != dmxScreen->rootWidth
- || dmxScreen->scrnHeight != dmxScreen->rootHeight) {
- dmxResizeRootWindow(pWindow,
- dmxScreen->rootX,
- dmxScreen->rootY,
- dmxScreen->rootWidth,
- dmxScreen->rootHeight);
- dmxUpdateScreenResources(screenInfo.screens[dmxScreen->index],
- dmxScreen->rootX,
- dmxScreen->rootY,
- dmxScreen->rootWidth,
- dmxScreen->rootHeight);
- pWindow->origin.x = dmxScreen->rootX;
- pWindow->origin.y = dmxScreen->rootY;
- }
- } else {
- dmxGetDefaultWindowAttributes(pWindow,
- &pWinPriv->cmap,
- &pWinPriv->visual);
-
- if (dmxLazyWindowCreation) {
- /* Save parent's visual for use later */
- if (pWinPriv->visual == CopyFromParent)
- pWinPriv->visual =
- dmxLookupVisualFromID(pScreen,
- wVisual(pWindow->parent));
- } else {
- pWinPriv->window = dmxCreateNonRootWindow(pWindow);
- }
- }
-
- dmxSync(dmxScreen, False);
- }
-
- DMX_WRAP(CreateWindow, dmxCreateWindow, dmxScreen, pScreen);
-
- return ret;
-}
-
-/** Destroy \a pWindow on the back-end server. */
-Bool dmxBEDestroyWindow(WindowPtr pWindow)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
-
- if (pWinPriv->window) {
- XDestroyWindow(dmxScreen->beDisplay, pWinPriv->window);
- pWinPriv->window = (Window)0;
- return TRUE;
- }
-
- return FALSE;
-}
-
-/** Destroy \a pWindow on the back-end server. If any RENDER pictures
- were created, destroy them as well. */
-Bool dmxDestroyWindow(WindowPtr pWindow)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- Bool ret = TRUE;
- Bool needSync = FALSE;
-#ifdef GLXEXT
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
-#endif
-
- DMX_UNWRAP(DestroyWindow, dmxScreen, pScreen);
-
- /* Destroy any picture list associated with this window */
- needSync |= dmxDestroyPictureList(pWindow);
-
- /* Destroy window on back-end server */
- needSync |= dmxBEDestroyWindow(pWindow);
- if (needSync) dmxSync(dmxScreen, FALSE);
-
-#ifdef GLXEXT
- if (pWinPriv->swapGroup && pWinPriv->windowDestroyed)
- pWinPriv->windowDestroyed(pWindow);
-#endif
-
- if (pScreen->DestroyWindow)
- ret = pScreen->DestroyWindow(pWindow);
-
- DMX_WRAP(DestroyWindow, dmxDestroyWindow, dmxScreen, pScreen);
-
- return ret;
-}
-
-/** Change the position of \a pWindow to be \a x, \a y. */
-Bool dmxPositionWindow(WindowPtr pWindow, int x, int y)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- Bool ret = TRUE;
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
- unsigned int m;
- XWindowChanges c;
-
- DMX_UNWRAP(PositionWindow, dmxScreen, pScreen);
-#if 0
- if (pScreen->PositionWindow)
- ret = pScreen->PositionWindow(pWindow, x, y);
-#endif
-
- /* Determine if the window is completely off the visible portion of
- the screen */
- pWinPriv->offscreen = DMX_WINDOW_OFFSCREEN(pWindow);
-
- /* If the window is now on-screen and it is mapped and it has not
- been created yet, create it and map it */
- if (!pWinPriv->window && pWinPriv->mapped && !pWinPriv->offscreen) {
- dmxCreateAndRealizeWindow(pWindow, TRUE);
- } else if (pWinPriv->window) {
- /* Position window on back-end server */
- m = CWX | CWY | CWWidth | CWHeight;
- c.x = pWindow->origin.x - wBorderWidth(pWindow);
- c.y = pWindow->origin.y - wBorderWidth(pWindow);
- c.width = pWindow->drawable.width;
- c.height = pWindow->drawable.height;
- if (pWindow->drawable.class != InputOnly) {
- m |= CWBorderWidth;
- c.border_width = pWindow->borderWidth;
- }
-
- XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c);
- dmxSync(dmxScreen, False);
- }
-
- DMX_WRAP(PositionWindow, dmxPositionWindow, dmxScreen, pScreen);
-
- return ret;
-}
-
-static void dmxDoChangeWindowAttributes(WindowPtr pWindow,
- unsigned long *mask,
- XSetWindowAttributes *attribs)
-{
- dmxPixPrivPtr pPixPriv;
-
- if (*mask & CWBackPixmap) {
- switch (pWindow->backgroundState) {
- case None:
- attribs->background_pixmap = None;
- break;
-
- case ParentRelative:
- attribs->background_pixmap = ParentRelative;
- break;
-
- case BackgroundPixmap:
- pPixPriv = DMX_GET_PIXMAP_PRIV(pWindow->background.pixmap);
- attribs->background_pixmap = pPixPriv->pixmap;
- break;
-
- case BackgroundPixel:
- *mask &= ~CWBackPixmap;
- break;
- }
- }
-
- if (*mask & CWBackPixel) {
- if (pWindow->backgroundState == BackgroundPixel)
- attribs->background_pixel = pWindow->background.pixel;
- else
- *mask &= ~CWBackPixel;
- }
-
- if (*mask & CWBorderPixmap) {
- if (pWindow->borderIsPixel)
- *mask &= ~CWBorderPixmap;
- else {
- pPixPriv = DMX_GET_PIXMAP_PRIV(pWindow->border.pixmap);
- attribs->border_pixmap = pPixPriv->pixmap;
- }
- }
-
- if (*mask & CWBorderPixel) {
- if (pWindow->borderIsPixel)
- attribs->border_pixel = pWindow->border.pixel;
- else
- *mask &= ~CWBorderPixel;
- }
-
- if (*mask & CWBitGravity)
- attribs->bit_gravity = pWindow->bitGravity;
-
- if (*mask & CWWinGravity)
- *mask &= ~CWWinGravity; /* Handled by dix */
-
- if (*mask & CWBackingStore)
- *mask &= ~CWBackingStore; /* Backing store not supported */
-
- if (*mask & CWBackingPlanes)
- *mask &= ~CWBackingPlanes; /* Backing store not supported */
-
- if (*mask & CWBackingPixel)
- *mask &= ~CWBackingPixel; /* Backing store not supported */
-
- if (*mask & CWOverrideRedirect)
- attribs->override_redirect = pWindow->overrideRedirect;
-
- if (*mask & CWSaveUnder)
- *mask &= ~CWSaveUnder; /* Save unders not supported */
-
- if (*mask & CWEventMask)
- *mask &= ~CWEventMask; /* Events are handled by dix */
-
- if (*mask & CWDontPropagate)
- *mask &= ~CWDontPropagate; /* Events are handled by dix */
-
- if (*mask & CWColormap) {
- ColormapPtr pCmap;
- dmxColormapPrivPtr pCmapPriv;
-
- pCmap = (ColormapPtr)LookupIDByType(wColormap(pWindow), RT_COLORMAP);
- pCmapPriv = DMX_GET_COLORMAP_PRIV(pCmap);
- attribs->colormap = pCmapPriv->cmap;
- }
-
- if (*mask & CWCursor)
- *mask &= ~CWCursor; /* Handled by the cursor code */
-}
-
-/** Change the window attributes of \a pWindow. */
-Bool dmxChangeWindowAttributes(WindowPtr pWindow, unsigned long mask)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- Bool ret = TRUE;
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
- XSetWindowAttributes attribs;
-
- DMX_UNWRAP(ChangeWindowAttributes, dmxScreen, pScreen);
-#if 0
- if (pScreen->ChangeWindowAttributes)
- ret = pScreen->ChangeWindowAttributes(pWindow, mask);
-#endif
-
- /* Change window attribs on back-end server */
- dmxDoChangeWindowAttributes(pWindow, &mask, &attribs);
-
- /* Save mask for lazy window creation optimization */
- pWinPriv->attribMask |= mask;
-
- if (mask && pWinPriv->window) {
- XChangeWindowAttributes(dmxScreen->beDisplay, pWinPriv->window,
- mask, &attribs);
- dmxSync(dmxScreen, False);
- }
-
- DMX_WRAP(ChangeWindowAttributes, dmxChangeWindowAttributes, dmxScreen,
- pScreen);
-
- return ret;
-}
-
-/** Realize \a pWindow on the back-end server. If the lazy window
- * creation optimization is enabled, the window is only realized when
- * it at least partially overlaps the screen. */
-Bool dmxRealizeWindow(WindowPtr pWindow)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- Bool ret = TRUE;
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
-
- DMX_UNWRAP(RealizeWindow, dmxScreen, pScreen);
-#if 0
- if (pScreen->RealizeWindow)
- ret = pScreen->RealizeWindow(pWindow);
-#endif
-
- /* Determine if the window is completely off the visible portion of
- the screen */
- pWinPriv->offscreen = DMX_WINDOW_OFFSCREEN(pWindow);
-
- /* If the window hasn't been created and it's not offscreen, then
- create it */
- if (!pWinPriv->window && !pWinPriv->offscreen) {
- dmxCreateAndRealizeWindow(pWindow, FALSE);
- }
-
- if (pWinPriv->window) {
- /* Realize window on back-end server */
- XMapWindow(dmxScreen->beDisplay, pWinPriv->window);
- dmxSync(dmxScreen, False);
- }
-
- /* Let the other functions know that the window is now mapped */
- pWinPriv->mapped = TRUE;
-
- DMX_WRAP(RealizeWindow, dmxRealizeWindow, dmxScreen, pScreen);
-
- dmxUpdateWindowInfo(DMX_UPDATE_REALIZE, pWindow);
- return ret;
-}
-
-/** Unrealize \a pWindow on the back-end server. */
-Bool dmxUnrealizeWindow(WindowPtr pWindow)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- Bool ret = TRUE;
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
-
- DMX_UNWRAP(UnrealizeWindow, dmxScreen, pScreen);
-#if 0
- if (pScreen->UnrealizeWindow)
- ret = pScreen->UnrealizeWindow(pWindow);
-#endif
-
- if (pWinPriv->window) {
- /* Unrealize window on back-end server */
- XUnmapWindow(dmxScreen->beDisplay, pWinPriv->window);
- dmxSync(dmxScreen, False);
- }
-
- /* When unrealized (i.e., unmapped), the window is always considered
- off of the visible portion of the screen */
- pWinPriv->offscreen = TRUE;
- pWinPriv->mapped = FALSE;
-
-#ifdef GLXEXT
- if (pWinPriv->swapGroup && pWinPriv->windowUnmapped)
- pWinPriv->windowUnmapped(pWindow);
-#endif
-
- DMX_WRAP(UnrealizeWindow, dmxUnrealizeWindow, dmxScreen, pScreen);
-
- dmxUpdateWindowInfo(DMX_UPDATE_UNREALIZE, pWindow);
- return ret;
-}
-
-static void dmxDoRestackWindow(WindowPtr pWindow)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
- WindowPtr pNextSib = pWindow->nextSib;
- unsigned int m;
- XWindowChanges c;
-
- if (pNextSib == NullWindow) {
- /* Window is at the bottom of the stack */
- m = CWStackMode;
- c.sibling = (Window)0;
- c.stack_mode = Below;
- XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c);
- } else {
- /* Window is not at the bottom of the stack */
- dmxWinPrivPtr pNextSibPriv = DMX_GET_WINDOW_PRIV(pNextSib);
-
- /* Handle case where siblings have not yet been created due to
- lazy window creation optimization by first finding the next
- sibling in the sibling list that has been created (if any)
- and then putting the current window just above that sibling,
- and if no next siblings have been created yet, then put it at
- the bottom of the stack (since it might have a previous
- sibling that should be above it). */
- while (!pNextSibPriv->window) {
- pNextSib = pNextSib->nextSib;
- if (pNextSib == NullWindow) {
- /* Window is at the bottom of the stack */
- m = CWStackMode;
- c.sibling = (Window)0;
- c.stack_mode = Below;
- XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c);
- return;
- }
- pNextSibPriv = DMX_GET_WINDOW_PRIV(pNextSib);
- }
-
- m = CWStackMode | CWSibling;
- c.sibling = pNextSibPriv->window;
- c.stack_mode = Above;
- XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c);
- }
-}
-
-/** Handle window restacking. The actual restacking occurs in
- * #dmxDoRestackWindow(). */
-void dmxRestackWindow(WindowPtr pWindow, WindowPtr pOldNextSib)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
-
- DMX_UNWRAP(RestackWindow, dmxScreen, pScreen);
-#if 0
- if (pScreen->RestackWindow)
- pScreen->RestackWindow(pWindow, pOldNextSib);
-#endif
-
- if (pOldNextSib != pWindow->nextSib) {
- /* Track restacking for lazy window creation optimization */
- pWinPriv->restacked = TRUE;
-
- /* Restack window on back-end server */
- if (pWinPriv->window) {
- dmxDoRestackWindow(pWindow);
- dmxSync(dmxScreen, False);
- }
- }
-
- DMX_WRAP(RestackWindow, dmxRestackWindow, dmxScreen, pScreen);
- dmxUpdateWindowInfo(DMX_UPDATE_RESTACK, pWindow);
-}
-
-static Bool dmxWindowExposurePredicate(Display *dpy, XEvent *ev, XPointer ptr)
-{
- return (ev->type == Expose && ev->xexpose.window == *(Window *)ptr);
-}
-
-/** Handle exposures on \a pWindow. Since window exposures are handled
- * in DMX, the events that are generated by the back-end server are
- * redundant, so we eat them here. */
-void dmxWindowExposures(WindowPtr pWindow, RegionPtr prgn,
- RegionPtr other_exposed)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
- XEvent ev;
-
- DMX_UNWRAP(WindowExposures, dmxScreen, pScreen);
-
- dmxSync(dmxScreen, False);
-
- if (pWinPriv->window) {
- while (XCheckIfEvent(dmxScreen->beDisplay, &ev,
- dmxWindowExposurePredicate,
- (XPointer)&pWinPriv->window)) {
- /* Handle expose events -- this should not be necessary
- since the base window in which the root window was
- created is guaranteed to be on top (override_redirect),
- so we should just swallow these events. If for some
- reason the window is not on top, then we'd need to
- collect these events and send them to the client later
- (e.g., during the block handler as Xnest does). */
- }
- }
-
-#if 1
- if (pScreen->WindowExposures)
- pScreen->WindowExposures(pWindow, prgn, other_exposed);
-#endif
- DMX_WRAP(WindowExposures, dmxWindowExposures, dmxScreen, pScreen);
-}
-
-/** Move \a pWindow on the back-end server. Determine whether or not it
- * is on or offscreen, and realize it if it is newly on screen and the
- * lazy window creation optimization is enabled. */
-void dmxCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
- unsigned int m;
- XWindowChanges c;
-
- DMX_UNWRAP(CopyWindow, dmxScreen, pScreen);
-#if 0
- if (pScreen->CopyWindow)
- pScreen->CopyWindow(pWindow, ptOldOrg, prgnSrc);
-#endif
-
- /* Determine if the window is completely off the visible portion of
- the screen */
- pWinPriv->offscreen = DMX_WINDOW_OFFSCREEN(pWindow);
-
- /* If the window is now on-screen and it is mapped and it has not
- been created yet, create it and map it */
- if (!pWinPriv->window && pWinPriv->mapped && !pWinPriv->offscreen) {
- dmxCreateAndRealizeWindow(pWindow, TRUE);
- } else if (pWinPriv->window) {
- /* Move window on back-end server */
- m = CWX | CWY | CWWidth | CWHeight;
- c.x = pWindow->origin.x - wBorderWidth(pWindow);
- c.y = pWindow->origin.y - wBorderWidth(pWindow);
- c.width = pWindow->drawable.width;
- c.height = pWindow->drawable.height;
-
- XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c);
- dmxSync(dmxScreen, False);
- }
-
- DMX_WRAP(CopyWindow, dmxCopyWindow, dmxScreen, pScreen);
- dmxUpdateWindowInfo(DMX_UPDATE_COPY, pWindow);
-}
-
-/** Resize \a pWindow on the back-end server. Determine whether or not
- * it is on or offscreen, and realize it if it is newly on screen and
- * the lazy window creation optimization is enabled. */
-void dmxResizeWindow(WindowPtr pWindow, int x, int y,
- unsigned int w, unsigned int h, WindowPtr pSib)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
- dmxWinPrivPtr pSibPriv;
- unsigned int m;
- XWindowChanges c;
-
- if (pSib)
- pSibPriv = DMX_GET_WINDOW_PRIV(pSib);
-
- DMX_UNWRAP(ResizeWindow, dmxScreen, pScreen);
-#if 1
- if (pScreen->ResizeWindow)
- pScreen->ResizeWindow(pWindow, x, y, w, h, pSib);
-#endif
-
- /* Determine if the window is completely off the visible portion of
- the screen */
- pWinPriv->offscreen = DMX_WINDOW_OFFSCREEN(pWindow);
-
- /* If the window is now on-screen and it is mapped and it has not
- been created yet, create it and map it */
- if (!pWinPriv->window && pWinPriv->mapped && !pWinPriv->offscreen) {
- dmxCreateAndRealizeWindow(pWindow, TRUE);
- } else if (pWinPriv->window) {
- /* Handle resizing on back-end server */
- m = CWX | CWY | CWWidth | CWHeight;
- c.x = pWindow->origin.x - wBorderWidth(pWindow);
- c.y = pWindow->origin.y - wBorderWidth(pWindow);
- c.width = pWindow->drawable.width;
- c.height = pWindow->drawable.height;
-
- XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c);
- dmxSync(dmxScreen, False);
- }
-
- DMX_WRAP(ResizeWindow, dmxResizeWindow, dmxScreen, pScreen);
- dmxUpdateWindowInfo(DMX_UPDATE_RESIZE, pWindow);
-}
-
-/** Reparent \a pWindow on the back-end server. */
-void dmxReparentWindow(WindowPtr pWindow, WindowPtr pPriorParent)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
- dmxWinPrivPtr pParentPriv = DMX_GET_WINDOW_PRIV(pWindow->parent);
-
- DMX_UNWRAP(ReparentWindow, dmxScreen, pScreen);
-#if 0
- if (pScreen->ReparentWindow)
- pScreen->ReparentWindow(pWindow, pPriorParent);
-#endif
-
- if (pWinPriv->window) {
- if (!pParentPriv->window) {
- dmxCreateAndRealizeWindow(pWindow->parent, FALSE);
- }
-
- /* Handle reparenting on back-end server */
- XReparentWindow(dmxScreen->beDisplay, pWinPriv->window,
- pParentPriv->window,
- pWindow->origin.x - wBorderWidth(pWindow),
- pWindow->origin.x - wBorderWidth(pWindow));
- dmxSync(dmxScreen, False);
- }
-
- DMX_WRAP(ReparentWindow, dmxReparentWindow, dmxScreen, pScreen);
- dmxUpdateWindowInfo(DMX_UPDATE_REPARENT, pWindow);
-}
-
-/** Change border width for \a pWindow to \a width pixels. */
-void dmxChangeBorderWidth(WindowPtr pWindow, unsigned int width)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
- unsigned int m;
- XWindowChanges c;
-
- DMX_UNWRAP(ChangeBorderWidth, dmxScreen, pScreen);
-#if 1
- if (pScreen->ChangeBorderWidth)
- pScreen->ChangeBorderWidth(pWindow, width);
-#endif
-
- /* NOTE: Do we need to check for on/off screen here? */
-
- if (pWinPriv->window) {
- /* Handle border width change on back-end server */
- m = CWBorderWidth;
- c.border_width = width;
-
- XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c);
- dmxSync(dmxScreen, False);
- }
-
- DMX_WRAP(ChangeBorderWidth, dmxChangeBorderWidth, dmxScreen, pScreen);
-}
-
-static void dmxDoSetShape(WindowPtr pWindow)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
- int nBox;
- BoxPtr pBox;
- int nRect;
- XRectangle *pRect;
- XRectangle *pRectFirst;
-
- /* First, set the bounding shape */
- if (wBoundingShape(pWindow)) {
- pBox = REGION_RECTS(wBoundingShape(pWindow));
- nRect = nBox = REGION_NUM_RECTS(wBoundingShape(pWindow));
- pRectFirst = pRect = xalloc(nRect * sizeof(*pRect));
- while (nBox--) {
- pRect->x = pBox->x1;
- pRect->y = pBox->y1;
- pRect->width = pBox->x2 - pBox->x1;
- pRect->height = pBox->y2 - pBox->y1;
- pBox++;
- pRect++;
- }
- XShapeCombineRectangles(dmxScreen->beDisplay, pWinPriv->window,
- ShapeBounding, 0, 0,
- pRectFirst, nRect,
- ShapeSet, YXBanded);
- xfree(pRectFirst);
- } else {
- XShapeCombineMask(dmxScreen->beDisplay, pWinPriv->window,
- ShapeBounding, 0, 0, None, ShapeSet);
- }
-
- /* Next, set the clip shape */
- if (wClipShape(pWindow)) {
- pBox = REGION_RECTS(wClipShape(pWindow));
- nRect = nBox = REGION_NUM_RECTS(wClipShape(pWindow));
- pRectFirst = pRect = xalloc(nRect * sizeof(*pRect));
- while (nBox--) {
- pRect->x = pBox->x1;
- pRect->y = pBox->y1;
- pRect->width = pBox->x2 - pBox->x1;
- pRect->height = pBox->y2 - pBox->y1;
- pBox++;
- pRect++;
- }
- XShapeCombineRectangles(dmxScreen->beDisplay, pWinPriv->window,
- ShapeClip, 0, 0,
- pRectFirst, nRect,
- ShapeSet, YXBanded);
- xfree(pRectFirst);
- } else {
- XShapeCombineMask(dmxScreen->beDisplay, pWinPriv->window,
- ShapeClip, 0, 0, None, ShapeSet);
- }
-
- if (XShapeInputSelected(dmxScreen->beDisplay, pWinPriv->window)) {
- ErrorF("Input selected for window %x on Screen %d\n",
- (unsigned int)pWinPriv->window, pScreen->myNum);
- }
-}
-
-/** Set shape of \a pWindow on the back-end server. */
-void dmxSetShape(WindowPtr pWindow)
-{
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
-
- DMX_UNWRAP(SetShape, dmxScreen, pScreen);
-#if 1
- if (pScreen->SetShape)
- pScreen->SetShape(pWindow);
-#endif
-
- if (pWinPriv->window) {
- /* Handle setting the current shape on the back-end server */
- dmxDoSetShape(pWindow);
- dmxSync(dmxScreen, False);
- } else {
- pWinPriv->isShaped = TRUE;
- }
-
- DMX_WRAP(SetShape, dmxSetShape, dmxScreen, pScreen);
-}
+/*
+ * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina.
+ *
+ * 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 on 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 (including the
+ * next paragraph) 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
+ * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
+ * 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.
+ */
+
+/*
+ * Authors:
+ * Kevin E. Martin <kem@redhat.com>
+ *
+ */
+
+/** \file
+ * This file provides support for window-related functions. */
+
+#ifdef HAVE_DMX_CONFIG_H
+#include <dmx-config.h>
+#endif
+
+#include "dmx.h"
+#include "dmxsync.h"
+#include "dmxwindow.h"
+#include "dmxpixmap.h"
+#include "dmxcmap.h"
+#include "dmxvisual.h"
+#include "dmxinput.h"
+#include "dmxextension.h"
+#include "dmxpict.h"
+
+#include "windowstr.h"
+
+static void dmxDoRestackWindow(WindowPtr pWindow);
+static void dmxDoChangeWindowAttributes(WindowPtr pWindow,
+ unsigned long *mask,
+ XSetWindowAttributes *attribs);
+
+static void dmxDoSetShape(WindowPtr pWindow);
+
+/** Initialize the private area for the window functions. */
+Bool dmxInitWindow(ScreenPtr pScreen)
+{
+ if (!dixRequestPrivate(dmxWinPrivateKey, sizeof(dmxWinPrivRec)))
+ return FALSE;
+
+ return TRUE;
+}
+
+
+Window dmxCreateRootWindow(WindowPtr pWindow)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
+ Window parent;
+ Visual *visual;
+ unsigned long mask;
+ XSetWindowAttributes attribs;
+ ColormapPtr pCmap;
+ dmxColormapPrivPtr pCmapPriv;
+
+ /* Create root window */
+
+ parent = dmxScreen->scrnWin; /* This is our "Screen" window */
+ visual = dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual;
+
+ pCmap = (ColormapPtr)LookupIDByType(wColormap(pWindow), RT_COLORMAP);
+ pCmapPriv = DMX_GET_COLORMAP_PRIV(pCmap);
+
+ mask = CWEventMask | CWBackingStore | CWColormap | CWBorderPixel;
+ attribs.event_mask = ExposureMask;
+ attribs.backing_store = NotUseful;
+ attribs.colormap = pCmapPriv->cmap;
+ attribs.border_pixel = 0;
+
+ /* Incorporate new attributes, if needed */
+ if (pWinPriv->attribMask) {
+ dmxDoChangeWindowAttributes(pWindow, &pWinPriv->attribMask, &attribs);
+ mask |= pWinPriv->attribMask;
+ }
+
+ return XCreateWindow(dmxScreen->beDisplay,
+ parent,
+ pWindow->origin.x - wBorderWidth(pWindow),
+ pWindow->origin.y - wBorderWidth(pWindow),
+ pWindow->drawable.width,
+ pWindow->drawable.height,
+ pWindow->borderWidth,
+ pWindow->drawable.depth,
+ pWindow->drawable.class,
+ visual,
+ mask,
+ &attribs);
+}
+
+/** Change the location and size of the "screen" window. Called from
+ * #dmxConfigureScreenWindow(). */
+void dmxResizeScreenWindow(ScreenPtr pScreen,
+ int x, int y, int w, int h)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ unsigned int m;
+ XWindowChanges c;
+
+ if (!dmxScreen->beDisplay)
+ return;
+
+ /* Handle resizing on back-end server */
+ m = CWX | CWY | CWWidth | CWHeight;
+ c.x = x;
+ c.y = y;
+ c.width = w;
+ c.height = h;
+
+ XConfigureWindow(dmxScreen->beDisplay, dmxScreen->scrnWin, m, &c);
+ dmxSync(dmxScreen, False);
+}
+
+/** Change the location and size of the "root" window. Called from
+ * #dmxConfigureRootWindow. */
+void dmxResizeRootWindow(WindowPtr pRoot,
+ int x, int y, int w, int h)
+{
+ DMXScreenInfo *dmxScreen = &dmxScreens[pRoot->drawable.pScreen->myNum];
+ dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pRoot);
+ unsigned int m;
+ XWindowChanges c;
+
+ /* Handle resizing on back-end server */
+ if (dmxScreen->beDisplay) {
+ m = CWX | CWY | CWWidth | CWHeight;
+ c.x = x;
+ c.y = y;
+ c.width = (w > 0) ? w : 1;
+ c.height = (h > 0) ? h : 1;
+
+ XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c);
+ }
+
+ if (w == 0 || h == 0) {
+ if (pWinPriv->mapped) {
+ if (dmxScreen->beDisplay)
+ XUnmapWindow(dmxScreen->beDisplay, pWinPriv->window);
+ pWinPriv->mapped = FALSE;
+ }
+ } else if (!pWinPriv->mapped) {
+ if (dmxScreen->beDisplay)
+ XMapWindow(dmxScreen->beDisplay, pWinPriv->window);
+ pWinPriv->mapped = TRUE;
+ }
+
+ if (dmxScreen->beDisplay)
+ dmxSync(dmxScreen, False);
+}
+
+void dmxGetDefaultWindowAttributes(WindowPtr pWindow,
+ Colormap *cmap,
+ Visual **visual)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+
+ if (pWindow->drawable.class != InputOnly &&
+ pWindow->optional &&
+ pWindow->optional->visual != wVisual(pWindow->parent)) {
+
+ /* Find the matching visual */
+ *visual = dmxLookupVisualFromID(pScreen, wVisual(pWindow));
+
+ /* Handle optional colormaps */
+ if (pWindow->optional->colormap) {
+ ColormapPtr pCmap;
+ dmxColormapPrivPtr pCmapPriv;
+
+ pCmap = (ColormapPtr)LookupIDByType(wColormap(pWindow),
+ RT_COLORMAP);
+ pCmapPriv = DMX_GET_COLORMAP_PRIV(pCmap);
+ *cmap = pCmapPriv->cmap;
+ } else {
+ *cmap = dmxColormapFromDefaultVisual(pScreen, *visual);
+ }
+ } else {
+ *visual = CopyFromParent;
+ *cmap = (Colormap)0;
+ }
+}
+
+static Window dmxCreateNonRootWindow(WindowPtr pWindow)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
+ Window parent;
+ unsigned long mask = 0L;
+ XSetWindowAttributes attribs;
+ dmxWinPrivPtr pParentPriv = DMX_GET_WINDOW_PRIV(pWindow->parent);
+
+ /* Create window on back-end server */
+
+ parent = pParentPriv->window;
+
+ /* The parent won't exist if this call to CreateNonRootWindow came
+ from ReparentWindow and the grandparent window has not yet been
+ created */
+ if (!parent) {
+ dmxCreateAndRealizeWindow(pWindow->parent, FALSE);
+ parent = pParentPriv->window;
+ }
+
+ /* Incorporate new attributes, if needed */
+ if (pWinPriv->attribMask) {
+ dmxDoChangeWindowAttributes(pWindow, &pWinPriv->attribMask, &attribs);
+ mask |= pWinPriv->attribMask;
+ }
+
+ /* Add in default attributes */
+ if (pWindow->drawable.class != InputOnly) {
+ mask |= CWBackingStore;
+ attribs.backing_store = NotUseful;
+
+ if (!(mask & CWColormap) && pWinPriv->cmap) {
+ mask |= CWColormap;
+ attribs.colormap = pWinPriv->cmap;
+ if (!(mask & CWBorderPixel)) {
+ mask |= CWBorderPixel;
+ attribs.border_pixel = 0;
+ }
+ }
+ }
+
+ /* Handle case where subwindows are being mapped, but created out of
+ order -- if current window has a previous sibling, then it cannot
+ be created on top of the stack, so we must restack the windows */
+ pWinPriv->restacked = (pWindow->prevSib != NullWindow);
+
+ return XCreateWindow(dmxScreen->beDisplay,
+ parent,
+ pWindow->origin.x - wBorderWidth(pWindow),
+ pWindow->origin.y - wBorderWidth(pWindow),
+ pWindow->drawable.width,
+ pWindow->drawable.height,
+ pWindow->borderWidth,
+ pWindow->drawable.depth,
+ pWindow->drawable.class,
+ pWinPriv->visual,
+ mask,
+ &attribs);
+}
+
+/** This function handles lazy window creation and realization. Window
+ * creation is handled by #dmxCreateNonRootWindow(). It also handles
+ * any stacking changes that have occured since the window was
+ * originally created by calling #dmxDoRestackWindow(). If the window
+ * is shaped, the shape is set on the back-end server by calling
+ * #dmxDoSetShape(), and if the window has pictures (from RENDER)
+ * associated with it, those pictures are created on the back-end
+ * server by calling #dmxCreatePictureList(). If \a doSync is TRUE,
+ * then #dmxSync() is called. */
+void dmxCreateAndRealizeWindow(WindowPtr pWindow, Bool doSync)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
+
+ if (!dmxScreen->beDisplay) return;
+
+ pWinPriv->window = dmxCreateNonRootWindow(pWindow);
+ if (pWinPriv->restacked) dmxDoRestackWindow(pWindow);
+ if (pWinPriv->isShaped) dmxDoSetShape(pWindow);
+ if (pWinPriv->hasPict) dmxCreatePictureList(pWindow);
+ if (pWinPriv->mapped) XMapWindow(dmxScreen->beDisplay,
+ pWinPriv->window);
+ if (doSync) dmxSync(dmxScreen, False);
+}
+
+/** Create \a pWindow on the back-end server. If the lazy window
+ * creation optimization is enabled, then the actual creation and
+ * realization of the window is handled by
+ * #dmxCreateAndRealizeWindow(). */
+Bool dmxCreateWindow(WindowPtr pWindow)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
+ Bool ret = TRUE;
+
+ DMX_UNWRAP(CreateWindow, dmxScreen, pScreen);
+#if 0
+ if (pScreen->CreateWindow)
+ ret = pScreen->CreateWindow(pWindow);
+#endif
+
+ /* Set up the defaults */
+ pWinPriv->window = (Window)0;
+ pWinPriv->offscreen = TRUE;
+ pWinPriv->mapped = FALSE;
+ pWinPriv->restacked = FALSE;
+ pWinPriv->attribMask = 0;
+ pWinPriv->isShaped = FALSE;
+ pWinPriv->hasPict = FALSE;
+#ifdef GLXEXT
+ pWinPriv->swapGroup = NULL;
+ pWinPriv->barrier = 0;
+#endif
+
+ if (dmxScreen->beDisplay) {
+ /* Only create the root window at this stage -- non-root windows are
+ created when they are mapped and are on-screen */
+ if (!pWindow->parent) {
+ dmxScreen->rootWin = pWinPriv->window
+ = dmxCreateRootWindow(pWindow);
+ if (dmxScreen->scrnX != dmxScreen->rootX
+ || dmxScreen->scrnY != dmxScreen->rootY
+ || dmxScreen->scrnWidth != dmxScreen->rootWidth
+ || dmxScreen->scrnHeight != dmxScreen->rootHeight) {
+ dmxResizeRootWindow(pWindow,
+ dmxScreen->rootX,
+ dmxScreen->rootY,
+ dmxScreen->rootWidth,
+ dmxScreen->rootHeight);
+ dmxUpdateScreenResources(screenInfo.screens[dmxScreen->index],
+ dmxScreen->rootX,
+ dmxScreen->rootY,
+ dmxScreen->rootWidth,
+ dmxScreen->rootHeight);
+ pWindow->origin.x = dmxScreen->rootX;
+ pWindow->origin.y = dmxScreen->rootY;
+ }
+ } else {
+ dmxGetDefaultWindowAttributes(pWindow,
+ &pWinPriv->cmap,
+ &pWinPriv->visual);
+
+ if (dmxLazyWindowCreation) {
+ /* Save parent's visual for use later */
+ if (pWinPriv->visual == CopyFromParent)
+ pWinPriv->visual =
+ dmxLookupVisualFromID(pScreen,
+ wVisual(pWindow->parent));
+ } else {
+ pWinPriv->window = dmxCreateNonRootWindow(pWindow);
+ }
+ }
+
+ dmxSync(dmxScreen, False);
+ }
+
+ DMX_WRAP(CreateWindow, dmxCreateWindow, dmxScreen, pScreen);
+
+ return ret;
+}
+
+/** Destroy \a pWindow on the back-end server. */
+Bool dmxBEDestroyWindow(WindowPtr pWindow)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
+
+ if (pWinPriv->window) {
+ XDestroyWindow(dmxScreen->beDisplay, pWinPriv->window);
+ pWinPriv->window = (Window)0;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/** Destroy \a pWindow on the back-end server. If any RENDER pictures
+ were created, destroy them as well. */
+Bool dmxDestroyWindow(WindowPtr pWindow)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ Bool ret = TRUE;
+ Bool needSync = FALSE;
+#ifdef GLXEXT
+ dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
+#endif
+
+ DMX_UNWRAP(DestroyWindow, dmxScreen, pScreen);
+
+ /* Destroy any picture list associated with this window */
+ needSync |= dmxDestroyPictureList(pWindow);
+
+ /* Destroy window on back-end server */
+ needSync |= dmxBEDestroyWindow(pWindow);
+ if (needSync) dmxSync(dmxScreen, FALSE);
+
+#ifdef GLXEXT
+ if (pWinPriv->swapGroup && pWinPriv->windowDestroyed)
+ pWinPriv->windowDestroyed(pWindow);
+#endif
+
+ if (pScreen->DestroyWindow)
+ ret = pScreen->DestroyWindow(pWindow);
+
+ DMX_WRAP(DestroyWindow, dmxDestroyWindow, dmxScreen, pScreen);
+
+ return ret;
+}
+
+/** Change the position of \a pWindow to be \a x, \a y. */
+Bool dmxPositionWindow(WindowPtr pWindow, int x, int y)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ Bool ret = TRUE;
+ dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
+ unsigned int m;
+ XWindowChanges c;
+
+ DMX_UNWRAP(PositionWindow, dmxScreen, pScreen);
+#if 0
+ if (pScreen->PositionWindow)
+ ret = pScreen->PositionWindow(pWindow, x, y);
+#endif
+
+ /* Determine if the window is completely off the visible portion of
+ the screen */
+ pWinPriv->offscreen = DMX_WINDOW_OFFSCREEN(pWindow);
+
+ /* If the window is now on-screen and it is mapped and it has not
+ been created yet, create it and map it */
+ if (!pWinPriv->window && pWinPriv->mapped && !pWinPriv->offscreen) {
+ dmxCreateAndRealizeWindow(pWindow, TRUE);
+ } else if (pWinPriv->window) {
+ /* Position window on back-end server */
+ m = CWX | CWY | CWWidth | CWHeight;
+ c.x = pWindow->origin.x - wBorderWidth(pWindow);
+ c.y = pWindow->origin.y - wBorderWidth(pWindow);
+ c.width = pWindow->drawable.width;
+ c.height = pWindow->drawable.height;
+ if (pWindow->drawable.class != InputOnly) {
+ m |= CWBorderWidth;
+ c.border_width = pWindow->borderWidth;
+ }
+
+ XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c);
+ dmxSync(dmxScreen, False);
+ }
+
+ DMX_WRAP(PositionWindow, dmxPositionWindow, dmxScreen, pScreen);
+
+ return ret;
+}
+
+static void dmxDoChangeWindowAttributes(WindowPtr pWindow,
+ unsigned long *mask,
+ XSetWindowAttributes *attribs)
+{
+ dmxPixPrivPtr pPixPriv;
+
+ if (*mask & CWBackPixmap) {
+ switch (pWindow->backgroundState) {
+ case None:
+ attribs->background_pixmap = None;
+ break;
+
+ case ParentRelative:
+ attribs->background_pixmap = ParentRelative;
+ break;
+
+ case BackgroundPixmap:
+ pPixPriv = DMX_GET_PIXMAP_PRIV(pWindow->background.pixmap);
+ attribs->background_pixmap = pPixPriv->pixmap;
+ break;
+
+ case BackgroundPixel:
+ *mask &= ~CWBackPixmap;
+ break;
+ }
+ }
+
+ if (*mask & CWBackPixel) {
+ if (pWindow->backgroundState == BackgroundPixel)
+ attribs->background_pixel = pWindow->background.pixel;
+ else
+ *mask &= ~CWBackPixel;
+ }
+
+ if (*mask & CWBorderPixmap) {
+ if (pWindow->borderIsPixel)
+ *mask &= ~CWBorderPixmap;
+ else {
+ pPixPriv = DMX_GET_PIXMAP_PRIV(pWindow->border.pixmap);
+ attribs->border_pixmap = pPixPriv->pixmap;
+ }
+ }
+
+ if (*mask & CWBorderPixel) {
+ if (pWindow->borderIsPixel)
+ attribs->border_pixel = pWindow->border.pixel;
+ else
+ *mask &= ~CWBorderPixel;
+ }
+
+ if (*mask & CWBitGravity)
+ attribs->bit_gravity = pWindow->bitGravity;
+
+ if (*mask & CWWinGravity)
+ *mask &= ~CWWinGravity; /* Handled by dix */
+
+ if (*mask & CWBackingStore)
+ *mask &= ~CWBackingStore; /* Backing store not supported */
+
+ if (*mask & CWBackingPlanes)
+ *mask &= ~CWBackingPlanes; /* Backing store not supported */
+
+ if (*mask & CWBackingPixel)
+ *mask &= ~CWBackingPixel; /* Backing store not supported */
+
+ if (*mask & CWOverrideRedirect)
+ attribs->override_redirect = pWindow->overrideRedirect;
+
+ if (*mask & CWSaveUnder)
+ *mask &= ~CWSaveUnder; /* Save unders not supported */
+
+ if (*mask & CWEventMask)
+ *mask &= ~CWEventMask; /* Events are handled by dix */
+
+ if (*mask & CWDontPropagate)
+ *mask &= ~CWDontPropagate; /* Events are handled by dix */
+
+ if (*mask & CWColormap) {
+ ColormapPtr pCmap;
+ dmxColormapPrivPtr pCmapPriv;
+
+ pCmap = (ColormapPtr)LookupIDByType(wColormap(pWindow), RT_COLORMAP);
+ pCmapPriv = DMX_GET_COLORMAP_PRIV(pCmap);
+ attribs->colormap = pCmapPriv->cmap;
+ }
+
+ if (*mask & CWCursor)
+ *mask &= ~CWCursor; /* Handled by the cursor code */
+}
+
+/** Change the window attributes of \a pWindow. */
+Bool dmxChangeWindowAttributes(WindowPtr pWindow, unsigned long mask)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ Bool ret = TRUE;
+ dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
+ XSetWindowAttributes attribs;
+
+ DMX_UNWRAP(ChangeWindowAttributes, dmxScreen, pScreen);
+#if 0
+ if (pScreen->ChangeWindowAttributes)
+ ret = pScreen->ChangeWindowAttributes(pWindow, mask);
+#endif
+
+ /* Change window attribs on back-end server */
+ dmxDoChangeWindowAttributes(pWindow, &mask, &attribs);
+
+ /* Save mask for lazy window creation optimization */
+ pWinPriv->attribMask |= mask;
+
+ if (mask && pWinPriv->window) {
+ XChangeWindowAttributes(dmxScreen->beDisplay, pWinPriv->window,
+ mask, &attribs);
+ dmxSync(dmxScreen, False);
+ }
+
+ DMX_WRAP(ChangeWindowAttributes, dmxChangeWindowAttributes, dmxScreen,
+ pScreen);
+
+ return ret;
+}
+
+/** Realize \a pWindow on the back-end server. If the lazy window
+ * creation optimization is enabled, the window is only realized when
+ * it at least partially overlaps the screen. */
+Bool dmxRealizeWindow(WindowPtr pWindow)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ Bool ret = TRUE;
+ dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
+
+ DMX_UNWRAP(RealizeWindow, dmxScreen, pScreen);
+#if 0
+ if (pScreen->RealizeWindow)
+ ret = pScreen->RealizeWindow(pWindow);
+#endif
+
+ /* Determine if the window is completely off the visible portion of
+ the screen */
+ pWinPriv->offscreen = DMX_WINDOW_OFFSCREEN(pWindow);
+
+ /* If the window hasn't been created and it's not offscreen, then
+ create it */
+ if (!pWinPriv->window && !pWinPriv->offscreen) {
+ dmxCreateAndRealizeWindow(pWindow, FALSE);
+ }
+
+ if (pWinPriv->window) {
+ /* Realize window on back-end server */
+ XMapWindow(dmxScreen->beDisplay, pWinPriv->window);
+ dmxSync(dmxScreen, False);
+ }
+
+ /* Let the other functions know that the window is now mapped */
+ pWinPriv->mapped = TRUE;
+
+ DMX_WRAP(RealizeWindow, dmxRealizeWindow, dmxScreen, pScreen);
+
+ dmxUpdateWindowInfo(DMX_UPDATE_REALIZE, pWindow);
+ return ret;
+}
+
+/** Unrealize \a pWindow on the back-end server. */
+Bool dmxUnrealizeWindow(WindowPtr pWindow)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ Bool ret = TRUE;
+ dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
+
+ DMX_UNWRAP(UnrealizeWindow, dmxScreen, pScreen);
+#if 0
+ if (pScreen->UnrealizeWindow)
+ ret = pScreen->UnrealizeWindow(pWindow);
+#endif
+
+ if (pWinPriv->window) {
+ /* Unrealize window on back-end server */
+ XUnmapWindow(dmxScreen->beDisplay, pWinPriv->window);
+ dmxSync(dmxScreen, False);
+ }
+
+ /* When unrealized (i.e., unmapped), the window is always considered
+ off of the visible portion of the screen */
+ pWinPriv->offscreen = TRUE;
+ pWinPriv->mapped = FALSE;
+
+#ifdef GLXEXT
+ if (pWinPriv->swapGroup && pWinPriv->windowUnmapped)
+ pWinPriv->windowUnmapped(pWindow);
+#endif
+
+ DMX_WRAP(UnrealizeWindow, dmxUnrealizeWindow, dmxScreen, pScreen);
+
+ dmxUpdateWindowInfo(DMX_UPDATE_UNREALIZE, pWindow);
+ return ret;
+}
+
+static void dmxDoRestackWindow(WindowPtr pWindow)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
+ WindowPtr pNextSib = pWindow->nextSib;
+ unsigned int m;
+ XWindowChanges c;
+
+ if (pNextSib == NullWindow) {
+ /* Window is at the bottom of the stack */
+ m = CWStackMode;
+ c.sibling = (Window)0;
+ c.stack_mode = Below;
+ XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c);
+ } else {
+ /* Window is not at the bottom of the stack */
+ dmxWinPrivPtr pNextSibPriv = DMX_GET_WINDOW_PRIV(pNextSib);
+
+ /* Handle case where siblings have not yet been created due to
+ lazy window creation optimization by first finding the next
+ sibling in the sibling list that has been created (if any)
+ and then putting the current window just above that sibling,
+ and if no next siblings have been created yet, then put it at
+ the bottom of the stack (since it might have a previous
+ sibling that should be above it). */
+ while (!pNextSibPriv->window) {
+ pNextSib = pNextSib->nextSib;
+ if (pNextSib == NullWindow) {
+ /* Window is at the bottom of the stack */
+ m = CWStackMode;
+ c.sibling = (Window)0;
+ c.stack_mode = Below;
+ XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c);
+ return;
+ }
+ pNextSibPriv = DMX_GET_WINDOW_PRIV(pNextSib);
+ }
+
+ m = CWStackMode | CWSibling;
+ c.sibling = pNextSibPriv->window;
+ c.stack_mode = Above;
+ XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c);
+ }
+}
+
+/** Handle window restacking. The actual restacking occurs in
+ * #dmxDoRestackWindow(). */
+void dmxRestackWindow(WindowPtr pWindow, WindowPtr pOldNextSib)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
+
+ DMX_UNWRAP(RestackWindow, dmxScreen, pScreen);
+#if 0
+ if (pScreen->RestackWindow)
+ pScreen->RestackWindow(pWindow, pOldNextSib);
+#endif
+
+ if (pOldNextSib != pWindow->nextSib) {
+ /* Track restacking for lazy window creation optimization */
+ pWinPriv->restacked = TRUE;
+
+ /* Restack window on back-end server */
+ if (pWinPriv->window) {
+ dmxDoRestackWindow(pWindow);
+ dmxSync(dmxScreen, False);
+ }
+ }
+
+ DMX_WRAP(RestackWindow, dmxRestackWindow, dmxScreen, pScreen);
+ dmxUpdateWindowInfo(DMX_UPDATE_RESTACK, pWindow);
+}
+
+static Bool dmxWindowExposurePredicate(Display *dpy, XEvent *ev, XPointer ptr)
+{
+ return (ev->type == Expose && ev->xexpose.window == *(Window *)ptr);
+}
+
+/** Handle exposures on \a pWindow. Since window exposures are handled
+ * in DMX, the events that are generated by the back-end server are
+ * redundant, so we eat them here. */
+void dmxWindowExposures(WindowPtr pWindow, RegionPtr prgn,
+ RegionPtr other_exposed)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
+ XEvent ev;
+
+ DMX_UNWRAP(WindowExposures, dmxScreen, pScreen);
+
+ dmxSync(dmxScreen, False);
+
+ if (pWinPriv->window) {
+ while (XCheckIfEvent(dmxScreen->beDisplay, &ev,
+ dmxWindowExposurePredicate,
+ (XPointer)&pWinPriv->window)) {
+ /* Handle expose events -- this should not be necessary
+ since the base window in which the root window was
+ created is guaranteed to be on top (override_redirect),
+ so we should just swallow these events. If for some
+ reason the window is not on top, then we'd need to
+ collect these events and send them to the client later
+ (e.g., during the block handler as Xnest does). */
+ }
+ }
+
+#if 1
+ if (pScreen->WindowExposures)
+ pScreen->WindowExposures(pWindow, prgn, other_exposed);
+#endif
+ DMX_WRAP(WindowExposures, dmxWindowExposures, dmxScreen, pScreen);
+}
+
+/** Move \a pWindow on the back-end server. Determine whether or not it
+ * is on or offscreen, and realize it if it is newly on screen and the
+ * lazy window creation optimization is enabled. */
+void dmxCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
+ unsigned int m;
+ XWindowChanges c;
+
+ DMX_UNWRAP(CopyWindow, dmxScreen, pScreen);
+#if 0
+ if (pScreen->CopyWindow)
+ pScreen->CopyWindow(pWindow, ptOldOrg, prgnSrc);
+#endif
+
+ /* Determine if the window is completely off the visible portion of
+ the screen */
+ pWinPriv->offscreen = DMX_WINDOW_OFFSCREEN(pWindow);
+
+ /* If the window is now on-screen and it is mapped and it has not
+ been created yet, create it and map it */
+ if (!pWinPriv->window && pWinPriv->mapped && !pWinPriv->offscreen) {
+ dmxCreateAndRealizeWindow(pWindow, TRUE);
+ } else if (pWinPriv->window) {
+ /* Move window on back-end server */
+ m = CWX | CWY | CWWidth | CWHeight;
+ c.x = pWindow->origin.x - wBorderWidth(pWindow);
+ c.y = pWindow->origin.y - wBorderWidth(pWindow);
+ c.width = pWindow->drawable.width;
+ c.height = pWindow->drawable.height;
+
+ XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c);
+ dmxSync(dmxScreen, False);
+ }
+
+ DMX_WRAP(CopyWindow, dmxCopyWindow, dmxScreen, pScreen);
+ dmxUpdateWindowInfo(DMX_UPDATE_COPY, pWindow);
+}
+
+/** Resize \a pWindow on the back-end server. Determine whether or not
+ * it is on or offscreen, and realize it if it is newly on screen and
+ * the lazy window creation optimization is enabled. */
+void dmxResizeWindow(WindowPtr pWindow, int x, int y,
+ unsigned int w, unsigned int h, WindowPtr pSib)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
+ dmxWinPrivPtr pSibPriv;
+ unsigned int m;
+ XWindowChanges c;
+
+ if (pSib)
+ pSibPriv = DMX_GET_WINDOW_PRIV(pSib);
+
+ DMX_UNWRAP(ResizeWindow, dmxScreen, pScreen);
+#if 1
+ if (pScreen->ResizeWindow)
+ pScreen->ResizeWindow(pWindow, x, y, w, h, pSib);
+#endif
+
+ /* Determine if the window is completely off the visible portion of
+ the screen */
+ pWinPriv->offscreen = DMX_WINDOW_OFFSCREEN(pWindow);
+
+ /* If the window is now on-screen and it is mapped and it has not
+ been created yet, create it and map it */
+ if (!pWinPriv->window && pWinPriv->mapped && !pWinPriv->offscreen) {
+ dmxCreateAndRealizeWindow(pWindow, TRUE);
+ } else if (pWinPriv->window) {
+ /* Handle resizing on back-end server */
+ m = CWX | CWY | CWWidth | CWHeight;
+ c.x = pWindow->origin.x - wBorderWidth(pWindow);
+ c.y = pWindow->origin.y - wBorderWidth(pWindow);
+ c.width = pWindow->drawable.width;
+ c.height = pWindow->drawable.height;
+
+ XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c);
+ dmxSync(dmxScreen, False);
+ }
+
+ DMX_WRAP(ResizeWindow, dmxResizeWindow, dmxScreen, pScreen);
+ dmxUpdateWindowInfo(DMX_UPDATE_RESIZE, pWindow);
+}
+
+/** Reparent \a pWindow on the back-end server. */
+void dmxReparentWindow(WindowPtr pWindow, WindowPtr pPriorParent)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
+ dmxWinPrivPtr pParentPriv = DMX_GET_WINDOW_PRIV(pWindow->parent);
+
+ DMX_UNWRAP(ReparentWindow, dmxScreen, pScreen);
+#if 0
+ if (pScreen->ReparentWindow)
+ pScreen->ReparentWindow(pWindow, pPriorParent);
+#endif
+
+ if (pWinPriv->window) {
+ if (!pParentPriv->window) {
+ dmxCreateAndRealizeWindow(pWindow->parent, FALSE);
+ }
+
+ /* Handle reparenting on back-end server */
+ XReparentWindow(dmxScreen->beDisplay, pWinPriv->window,
+ pParentPriv->window,
+ pWindow->origin.x - wBorderWidth(pWindow),
+ pWindow->origin.x - wBorderWidth(pWindow));
+ dmxSync(dmxScreen, False);
+ }
+
+ DMX_WRAP(ReparentWindow, dmxReparentWindow, dmxScreen, pScreen);
+ dmxUpdateWindowInfo(DMX_UPDATE_REPARENT, pWindow);
+}
+
+/** Change border width for \a pWindow to \a width pixels. */
+void dmxChangeBorderWidth(WindowPtr pWindow, unsigned int width)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
+ unsigned int m;
+ XWindowChanges c;
+
+ DMX_UNWRAP(ChangeBorderWidth, dmxScreen, pScreen);
+#if 1
+ if (pScreen->ChangeBorderWidth)
+ pScreen->ChangeBorderWidth(pWindow, width);
+#endif
+
+ /* NOTE: Do we need to check for on/off screen here? */
+
+ if (pWinPriv->window) {
+ /* Handle border width change on back-end server */
+ m = CWBorderWidth;
+ c.border_width = width;
+
+ XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c);
+ dmxSync(dmxScreen, False);
+ }
+
+ DMX_WRAP(ChangeBorderWidth, dmxChangeBorderWidth, dmxScreen, pScreen);
+}
+
+static void dmxDoSetShape(WindowPtr pWindow)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
+ int nBox;
+ BoxPtr pBox;
+ int nRect;
+ XRectangle *pRect;
+ XRectangle *pRectFirst;
+
+ /* First, set the bounding shape */
+ if (wBoundingShape(pWindow)) {
+ pBox = REGION_RECTS(wBoundingShape(pWindow));
+ nRect = nBox = REGION_NUM_RECTS(wBoundingShape(pWindow));
+ pRectFirst = pRect = malloc(nRect * sizeof(*pRect));
+ while (nBox--) {
+ pRect->x = pBox->x1;
+ pRect->y = pBox->y1;
+ pRect->width = pBox->x2 - pBox->x1;
+ pRect->height = pBox->y2 - pBox->y1;
+ pBox++;
+ pRect++;
+ }
+ XShapeCombineRectangles(dmxScreen->beDisplay, pWinPriv->window,
+ ShapeBounding, 0, 0,
+ pRectFirst, nRect,
+ ShapeSet, YXBanded);
+ free(pRectFirst);
+ } else {
+ XShapeCombineMask(dmxScreen->beDisplay, pWinPriv->window,
+ ShapeBounding, 0, 0, None, ShapeSet);
+ }
+
+ /* Next, set the clip shape */
+ if (wClipShape(pWindow)) {
+ pBox = REGION_RECTS(wClipShape(pWindow));
+ nRect = nBox = REGION_NUM_RECTS(wClipShape(pWindow));
+ pRectFirst = pRect = malloc(nRect * sizeof(*pRect));
+ while (nBox--) {
+ pRect->x = pBox->x1;
+ pRect->y = pBox->y1;
+ pRect->width = pBox->x2 - pBox->x1;
+ pRect->height = pBox->y2 - pBox->y1;
+ pBox++;
+ pRect++;
+ }
+ XShapeCombineRectangles(dmxScreen->beDisplay, pWinPriv->window,
+ ShapeClip, 0, 0,
+ pRectFirst, nRect,
+ ShapeSet, YXBanded);
+ free(pRectFirst);
+ } else {
+ XShapeCombineMask(dmxScreen->beDisplay, pWinPriv->window,
+ ShapeClip, 0, 0, None, ShapeSet);
+ }
+
+ if (XShapeInputSelected(dmxScreen->beDisplay, pWinPriv->window)) {
+ ErrorF("Input selected for window %x on Screen %d\n",
+ (unsigned int)pWinPriv->window, pScreen->myNum);
+ }
+}
+
+/** Set shape of \a pWindow on the back-end server. */
+void dmxSetShape(WindowPtr pWindow)
+{
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
+ dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
+
+ DMX_UNWRAP(SetShape, dmxScreen, pScreen);
+#if 1
+ if (pScreen->SetShape)
+ pScreen->SetShape(pWindow);
+#endif
+
+ if (pWinPriv->window) {
+ /* Handle setting the current shape on the back-end server */
+ dmxDoSetShape(pWindow);
+ dmxSync(dmxScreen, False);
+ } else {
+ pWinPriv->isShaped = TRUE;
+ }
+
+ DMX_WRAP(SetShape, dmxSetShape, dmxScreen, pScreen);
+}
diff --git a/xorg-server/hw/dmx/doc/dmx.sgml b/xorg-server/hw/dmx/doc/dmx.sgml
index ef66d1195..4342c2fce 100644
--- a/xorg-server/hw/dmx/doc/dmx.sgml
+++ b/xorg-server/hw/dmx/doc/dmx.sgml
@@ -1,2778 +1,2777 @@
-<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
- <article>
-
- <!-- Title information -->
- <title>Distributed Multihead X design
- <author>Kevin E. Martin, David H. Dawes, and Rickard E. Faith
- <date>29 June 2004 (created 25 July 2001)
- <abstract>
- This document covers the motivation, background, design, and
- implementation of the distributed multihead X (DMX) system. It
- is a living document and describes the current design and
- implementation details of the DMX system. As the project
- progresses, this document will be continually updated to reflect
- the changes in the code and/or design. <it>Copyright 2001 by VA
- Linux Systems, Inc., Fremont, California. Copyright 2001-2004
- by Red Hat, Inc., Raleigh, North Carolina</it>
- </abstract>
-
- <!-- Table of contents -->
- <toc>
-
-<!-- Begin the document -->
-<sect>Introduction
-
-<sect1>The Distributed Multihead X Server
-
-<p>Current Open Source multihead solutions are limited to a single
-physical machine. A single X server controls multiple display devices,
-which can be arranged as independent heads or unified into a single
-desktop (with Xinerama). These solutions are limited to the number of
-physical devices that can co-exist in a single machine (e.g., due to the
-number of AGP/PCI slots available for graphics cards). Thus, large
-tiled displays are not currently possible. The work described in this
-paper will eliminate the requirement that the display devices reside in
-the same physical machine. This will be accomplished by developing a
-front-end proxy X server that will control multiple back-end X servers
-that make up the large display.
-
-<p>The overall structure of the distributed multihead X (DMX) project is
-as follows: A single front-end X server will act as a proxy to a set of
-back-end X servers, which handle all of the visible rendering. X
-clients will connect to the front-end server just as they normally would
-to a regular X server. The front-end server will present an abstracted
-view to the client of a single large display. This will ensure that all
-standard X clients will continue to operate without modification
-(limited, as always, by the visuals and extensions provided by the X
-server). Clients that are DMX-aware will be able to use an extension to
-obtain information about the back-end servers (e.g., for placement of
-pop-up windows, window alignments by the window manager, etc.).
-
-<p>The architecture of the DMX server is divided into two main sections:
-input (e.g., mouse and keyboard events) and output (e.g., rendering and
-windowing requests). Each of these are describe briefly below, and the
-rest of this design document will describe them in greater detail.
-
-<p>The DMX server can receive input from three general types of input
-devices: "local" devices that are physically attached to the machine on
-which DMX is running, "backend" devices that are physically attached to
-one or more of the back-end X servers (and that generate events via the
-X protocol stream from the backend), and "console" devices that can be
-abstracted from any non-back-end X server. Backend and console devices
-are treated differently because the pointer device on the back-end X
-server also controls the location of the hardware X cursor. Full
-support for XInput extension devices is provided.
-
-<p>Rendering requests will be accepted by the front-end server; however,
-rendering to visible windows will be broken down as needed and sent to
-the appropriate back-end server(s) via X11 library calls for actual
-rendering. The basic framework will follow a Xnest-style approach. GC
-state will be managed in the front-end server and sent to the
-appropriate back-end server(s) as required. Pixmap rendering will (at
-least initially) be handled by the front-end X server. Windowing
-requests (e.g., ordering, mapping, moving, etc.) will handled in the
-front-end server. If the request requires a visible change, the
-windowing operation will be translated into requests for the appropriate
-back-end server(s). Window state will be mirrored in the back-end
-server(s) as needed.
-
-<sect1>Layout of Paper
-
-<p>The next section describes the general development plan that was
-actually used for implementation. The final section discusses
-outstanding issues at the conclusion of development. The first appendix
-provides low-level technical detail that may be of interest to those
-intimately familiar with the X server architecture. The final appendix
-describes the four phases of development that were performed during the
-first two years of development.
-
-<p>The final year of work was divided into 9 tasks that are not
-described in specific sections of this document. The major tasks during
-that time were the enhancement of the reconfiguration ability added in
-Phase IV, addition of support for a dynamic number of back-end displays
-(instead of a hard-coded limit), and the support for back-end display
-and input removal and addition. This work is mentioned in this paper,
-but is not covered in detail.
-
-<!-- ============================================================ -->
-<sect>Development plan
-
-<p>This section describes the development plan from approximately June
-2001 through July 2003.
-
-<sect1>Bootstrap code
-
-<p>To allow for rapid development of the DMX server by multiple
-developers during the first development stage, the problem will be
-broken down into three tasks: the overall DMX framework, back-end
-rendering services and input device handling services. However, before
-the work begins on these tasks, a simple framework that each developer
-could use was implemented to bootstrap the development effort. This
-framework renders to a single back-end server and provides dummy input
-devices (i.e., the keyboard and mouse). The simple back-end rendering
-service was implemented using the shadow framebuffer support currently
-available in the XFree86 environment.
-
-<p>Using this bootstrapping framework, each developer has been able to
-work on each of the tasks listed above independently as follows: the
-framework will be extended to handle arbitrary back-end server
-configurations; the back-end rendering services will be transitioned to
-the more efficient Xnest-style implementation; and, an input device
-framework to handle various input devices via the input extension will
-be developed.
-
-<p>Status: The boot strap code is complete. <!-- August 2001 -->
-
-
-<sect1>Input device handling
-
-<p>An X server (including the front-end X server) requires two core
-input devices -- a keyboard and a pointer (mouse). These core devices
-are handled and required by the core X11 protocol. Additional types of
-input devices may be attached and utilized via the XInput extension.
-These are usually referred to as ``XInput extension devices'',
-
-<p>There are some options as to how the front-end X server gets its core
-input devices:
-
-<enum>
- <item>Local Input. The physical input devices (e.g., keyboard and
- mouse) can be attached directly to the front-end X server. In this
- case, the keyboard and mouse on the machine running the front-end X
- server will be used. The front-end will have drivers to read the
- raw input from those devices and convert it into the required X
- input events (e.g., key press/release, pointer button press/release,
- pointer motion). The front-end keyboard driver will keep track of
- keyboard properties such as key and modifier mappings, autorepeat
- state, keyboard sound and led state. Similarly the front-end
- pointer driver will keep track if pointer properties such as the
- button mapping and movement acceleration parameters. With this
- option, input is handled fully in the front-end X server, and the
- back-end X servers are used in a display-only mode. This option was
- implemented and works for a limited number of Linux-specific
- devices. Adding additional local input devices for other
- architectures is expected to be relatively simple.
-
- <p>The following options are available for implementing local input
- devices:
-
- <enum>
- <item>The XFree86 X server has modular input drivers that could
- be adapted for this purpose. The mouse driver supports a wide
- range of mouse types and interfaces, as well as a range of
- Operating System platforms. The keyboard driver in XFree86 is
- not currently as modular as the mouse driver, but could be made
- so. The XFree86 X server also has a range of other input
- drivers for extended input devices such as tablets and touch
- screens. Unfortunately, the XFree86 drivers are generally
- complex, often simultaneously providing support for multiple
- devices across multiple architectures; and rely so heavily on
- XFree86-specific helper-functions, that this option was not
- pursued.
-
-
- <item>The <tt/kdrive/ X server in XFree86 has built-in drivers that
- support PS/2 mice and keyboard under Linux. The mouse driver
- can indirectly handle other mouse types if the Linux utility
- <tt/gpm/ is used as to translate the native mouse protocol into
- PS/2 mouse format. These drivers could be adapted and built in
- to the front-end X server if this range of hardware and OS
- support is sufficient. While much simpler than the XFree86
- drivers, the <tt/kdrive/ drivers were not used for the DMX
- implementation.
-
- <item>Reimplementation of keyboard and mouse drivers from
- scratch for the DMX framework. Because keyboard and mouse
- drivers are relatively trivial to implement, this pathway was
- selected. Other drivers in the X source tree were referenced,
- and significant contributions from other drivers are noted in
- the DMX source code.
- </enum>
-
- <item>Backend Input. The front-end can make use of the core input
- devices attached to one or more of the back-end X servers. Core
- input events from multiple back-ends are merged into a single input
- event stream. This can work sanely when only a single set of input
- devices is used at any given time. The keyboard and pointer state
- will be handled in the front-end, with changes propagated to the
- back-end servers as needed. This option was implemented and works
- well. Because the core pointer on a back-end controls the hardware
- mouse on that back-end, core pointers cannot be treated as XInput
- extension devices. However, all back-end XInput extensions devices
- can be mapped to either DMX core or DMX XInput extension devices.
-
- <item>Console Input. The front-end server could create a console
- window that is displayed on an X server independent of the back-end
- X servers. This console window could display things like the
- physical screen layout, and the front-end could get its core input
- events from events delivered to the console window. This option was
- implemented and works well. To help the human navigate, window
- outlines are also displayed in the console window. Further, console
- windows can be used as either core or XInput extension devices.
-
- <item>Other options were initially explored, but they were all
- partial subsets of the options listed above and, hence, are
- irrelevant.
-
-</enum>
-
-<p>Although extended input devices are not specifically mentioned in the
-Distributed X requirements, the options above were all implemented so
-that XInput extension devices were supported.
-
-<p>The bootstrap code (Xdmx) had dummy input devices, and these are
-still supported in the final version. These do the necessary
-initialization to satisfy the X server's requirements for core pointer
-and keyboard devices, but no input events are ever generated.
-
-<p>Status: The input code is complete. Because of the complexity of the
-XFree86 input device drivers (and their heavy reliance on XFree86
-infrastructure), separate low-level device drivers were implemented for
-Xdmx. The following kinds of drivers are supported (in general, the
-devices can be treated arbitrarily as "core" input devices or as XInput
-"extension" devices; and multiple instances of different kinds of
-devices can be simultaneously available):
- <enum>
- <item> A "dummy" device drive that never generates events.
-
- <item> "Local" input is from the low-level hardware on which the
- Xdmx binary is running. This is the only area where using the
- XFree86 driver infrastructure would have been helpful, and then
- only partially, since good support for generic USB devices does
- not yet exist in XFree86 (in any case, XFree86 and kdrive driver
- code was used where possible). Currently, the following local
- devices are supported under Linux (porting to other operating
- systems should be fairly straightforward):
- <itemize>
- <item>Linux keyboard
- <item>Linux serial mouse (MS)
- <item>Linux PS/2 mouse
- <item>USB keyboard
- <item>USB mouse
- <item>USB generic device (e.g., joystick, gamepad, etc.)
- </itemize>
-
- <item> "Backend" input is taken from one or more of the back-end
- displays. In this case, events are taken from the back-end X
- server and are converted to Xdmx events. Care must be taken so
- that the sprite moves properly on the display from which input
- is being taken.
-
- <item> "Console" input is taken from an X window that Xdmx
- creates on the operator's display (i.e., on the machine running
- the Xdmx binary). When the operator's mouse is inside the
- console window, then those events are converted to Xdmx events.
- Several special features are available: the console can display
- outlines of windows that are on the Xdmx display (to facilitate
- navigation), the cursor can be confined to the console, and a
- "fine" mode can be activated to allow very precise cursor
- positioning.
- </enum>
-
-
-<!-- May 2002; July 2003 -->
-
-<sect1>Output device handling
-
-<p>The output of the DMX system displays rendering and windowing
-requests across multiple screens. The screens are typically arranged in
-a grid such that together they represent a single large display.
-
-<p>The output section of the DMX code consists of two parts. The first
-is in the front-end proxy X server (Xdmx), which accepts client
-connections, manages the windows, and potentially renders primitives but
-does not actually display any of the drawing primitives. The second
-part is the back-end X server(s), which accept commands from the
-front-end server and display the results on their screens.
-
-<sect2>Initialization
-
-<p>The DMX front-end must first initialize its screens by connecting to
-each of the back-end X servers and collecting information about each of
-these screens. However, the information collected from the back-end X
-servers might be inconsistent. Handling these cases can be difficult
-and/or inefficient. For example, a two screen system has one back-end X
-server running at 16bpp while the second is running at 32bpp.
-Converting rendering requests (e.g., XPutImage() or XGetImage()
-requests) to the appropriate bit depth can be very time consuming.
-Analyzing these cases to determine how or even if it is possible to
-handle them is required. The current Xinerama code handles many of
-these cases (e.g., in PanoramiXConsolidate()) and will be used as a
-starting point. In general, the best solution is to use homogeneous X
-servers and display devices. Using back-end servers with the same depth
-is a requirement of the final DMX implementation.
-
-<p>Once this screen consolidation is finished, the relative position of
-each back-end X server's screen in the unified screen is initialized. A
-full-screen window is opened on each of the back-end X servers, and the
-cursor on each screen is turned off. The final DMX implementation can
-also make use of a partial-screen window, or multiple windows per
-back-end screen.
-
-<sect2>Handling rendering requests
-
-<p>After initialization, X applications connect to the front-end server.
-There are two possible implementations of how rendering and windowing
-requests are handled in the DMX system:
-
-<enum>
- <item>A shadow framebuffer is used in the front-end server as the
- render target. In this option, all protocol requests are completely
- handled in the front-end server. All state and resources are
- maintained in the front-end including a shadow copy of the entire
- framebuffer. The framebuffers attached to the back-end servers are
- updated by XPutImage() calls with data taken directly from the
- shadow framebuffer.
-
- <p>This solution suffers from two main problems. First, it does not
- take advantage of any accelerated hardware available in the system.
- Second, the size of the XPutImage() calls can be quite large and
- thus will be limited by the bandwidth available.
-
- <p>The initial DMX implementation used a shadow framebuffer by
- default.
-
- <item>Rendering requests are sent to each back-end server for
- handling (as is done in the Xnest server described above). In this
- option, certain protocol requests are handled in the front-end
- server and certain requests are repackaged and then sent to the
- back-end servers. The framebuffer is distributed across the
- multiple back-end servers. Rendering to the framebuffer is handled
- on each back-end and can take advantage of any acceleration
- available on the back-end servers' graphics display device. State
- is maintained both in the front and back-end servers.
-
- <p>This solution suffers from two main drawbacks. First, protocol
- requests are sent to all back-end servers -- even those that will
- completely clip the rendering primitive -- which wastes bandwidth
- and processing time. Second, state is maintained both in the front-
- and back-end servers. These drawbacks are not as severe as in
- option 1 (above) and can either be overcome through optimizations or
- are acceptable. Therefore, this option will be used in the final
- implementation.
-
- <p>The final DMX implementation defaults to this mechanism, but also
- supports the shadow framebuffer mechanism. Several optimizations
- were implemented to eliminate the drawbacks of the default
- mechanism. These optimizations are described the section below and
- in Phase II of the Development Results (see appendix).
-
-</enum>
-
-<p>Status: Both the shadow framebuffer and Xnest-style code is complete.
-<!-- May 2002 -->
-
-
-<sect1>Optimizing DMX
-
-<p>Initially, the Xnest-style solution's performance will be measured
-and analyzed to determine where the performance bottlenecks exist.
-There are four main areas that will be addressed.
-
-<p>First, to obtain reasonable interactivity with the first development
-phase, XSync() was called after each protocol request. The XSync()
-function flushes any pending protocol requests. It then waits for the
-back-end to process the request and send a reply that the request has
-completed. This happens with each back-end server and performance
-greatly suffers. As a result of the way XSync() is called in the first
-development phase, the batching that the X11 library performs is
-effectively defeated. The XSync() call usage will be analyzed and
-optimized by batching calls and performing them at regular intervals,
-except where interactivity will suffer (e.g., on cursor movements).
-
-<p>Second, the initial Xnest-style solution described above sends the
-repackaged protocol requests to all back-end servers regardless of
-whether or not they would be completely clipped out. The requests that
-are trivially rejected on the back-end server wastes the limited
-bandwidth available. By tracking clipping changes in the DMX X server's
-windowing code (e.g., by opening, closing, moving or resizing windows),
-we can determine whether or not back-end windows are visible so that
-trivial tests in the front-end server's GC ops drawing functions can
-eliminate these unnecessary protocol requests.
-
-<p>Third, each protocol request will be analyzed to determine if it is
-possible to break the request into smaller pieces at display boundaries.
-The initial ones to be analyzed are put and get image requests since
-they will require the greatest bandwidth to transmit data between the
-front and back-end servers. Other protocol requests will be analyzed
-and those that will benefit from breaking them into smaller requests
-will be implemented.
-
-<p>Fourth, an extension is being considered that will allow font glyphs to
-be transferred from the front-end DMX X server to each back-end server.
-This extension will permit the front-end to handle all font requests and
-eliminate the requirement that all back-end X servers share the exact
-same fonts as the front-end server. We are investigating the
-feasibility of this extension during this development phase.
-
-<p>Other potential optimizations will be determined from the performance
-analysis.
-
-<p>Please note that in our initial design, we proposed optimizing BLT
-operations (e.g., XCopyArea() and window moves) by developing an
-extension that would allow individual back-end servers to directly copy
-pixel data to other back-end servers. This potential optimization was
-in response to the simple image movement implementation that required
-potentially many calls to GetImage() and PutImage(). However, the
-current Xinerama implementation handles these BLT operations
-differently. Instead of copying data to and from screens, they generate
-expose events -- just as happens in the case when a window is moved from
-off a screen to on screen. This approach saves the limited bandwidth
-available between front and back-end servers and is being standardized
-with Xinerama. It also eliminates the potential setup problems and
-security issues resulting from having each back-end server open
-connections to all other back-end servers. Therefore, we suggest
-accepting Xinerama's expose event solution.
-
-<p>Also note that the approach proposed in the second and third
-optimizations might cause backing store algorithms in the back-end to be
-defeated, so a DMX X server configuration flag will be added to disable
-these optimizations.
-
-<p>Status: The optimizations proposed above are complete. It was
-determined that the using the xfs font server was sufficient and
-creating a new mechanism to pass glyphs was redundant; therefore, the
-fourth optimization proposed above was not included in DMX.
-<!-- September 2002 -->
-
-
-<sect1>DMX X extension support
-
-<p>The DMX X server keeps track of all the windowing information on the
-back-end X servers, but does not currently export this information to
-any client applications. An extension will be developed to pass the
-screen information and back-end window IDs to DMX-aware clients. These
-clients can then use this information to directly connect to and render
-to the back-end windows. Bypassing the DMX X server allows DMX-aware
-clients to break up complex rendering requests on their own and send
-them directly to the windows on the back-end server's screens. An
-example of a client that can make effective use of this extension is
-Chromium.
-
-<p>Status: The extension, as implemented, is fully documented in
-"Client-to-Server DMX Extension to the X Protocol". Future changes
-might be required based on feedback and other proposed enhancements to
-DMX. Currently, the following facilities are supported:
-<enum>
- <item>
- Screen information (clipping rectangle for each screen relative
- to the virtual screen)
- <item>
- Window information (window IDs and clipping information for each
- back-end window that corresponds to each DMX window)
- <item>
- Input device information (mappings from DMX device IDs to
- back-end device IDs)
- <item>
- Force window creation (so that a client can override the
- server-side lazy window creation optimization)
- <item>
- Reconfiguration (so that a client can request that a screen
- position be changed)
- <item>
- Addition and removal of back-end servers and back-end and
- console inputs.
-</enum>
-<!-- September 2002; July 2003 -->
-
-
-<sect1>Common X extension support
-
-<p>The XInput, XKeyboard and Shape extensions are commonly used
-extensions to the base X11 protocol. XInput allows multiple and
-non-standard input devices to be accessed simultaneously. These input
-devices can be connected to either the front-end or back-end servers.
-XKeyboard allows much better keyboard mappings control. Shape adds
-support for arbitrarily shaped windows and is used by various window
-managers. Nearly all potential back-end X servers make these extensions
-available, and support for each one will be added to the DMX system.
-
-<p>In addition to the extensions listed above, support for the X
-Rendering extension (Render) is being developed. Render adds digital
-image composition to the rendering model used by the X Window System.
-While this extension is still under development by Keith Packard of HP,
-support for the current version will be added to the DMX system.
-
-<p>Support for the XTest extension was added during the first
-development phase.
-
-<!-- WARNING: this list is duplicated in the Phase IV discussion -->
-<p>Status: The following extensions are supported and are discussed in
-more detail in Phase IV of the Development Results (see appendix):
- BIG-REQUESTS,
- DEC-XTRAP,
- DMX,
- DPMS,
- Extended-Visual-Information,
- GLX,
- LBX,
- RECORD,
- RENDER,
- SECURITY,
- SHAPE,
- SYNC,
- X-Resource,
- XC-APPGROUP,
- XC-MISC,
- XFree86-Bigfont,
- XINERAMA,
- XInputExtension,
- XKEYBOARD, and
- XTEST.
-<!-- November 2002; updated February 2003, July 2003 -->
-
-<sect1>OpenGL support
-
-<p>OpenGL support using the Mesa code base exists in XFree86 release 4
-and later. Currently, the direct rendering infrastructure (DRI)
-provides accelerated OpenGL support for local clients and unaccelerated
-OpenGL support (i.e., software rendering) is provided for non-local
-clients.
-
-<p>The single head OpenGL support in XFree86 4.x will be extended to use
-the DMX system. When the front and back-end servers are on the same
-physical hardware, it is possible to use the DRI to directly render to
-the back-end servers. First, the existing DRI will be extended to
-support multiple display heads, and then to support the DMX system.
-OpenGL rendering requests will be direct rendering to each back-end X
-server. The DRI will request the screen layout (either from the
-existing Xinerama extension or a DMX-specific extension). Support for
-synchronized swap buffers will also be added (on hardware that supports
-it). Note that a single front-end server with a single back-end server
-on the same physical machine can emulate accelerated indirect rendering.
-
-<p>When the front and back-end servers are on different physical
-hardware or are using non-XFree86 4.x X servers, a mechanism to render
-primitives across the back-end servers will be provided. There are
-several options as to how this can be implemented.
-
-<enum>
- <item>The existing OpenGL support in each back-end server can be
- used by repackaging rendering primitives and sending them to each
- back-end server. This option is similar to the unoptimized
- Xnest-style approach mentioned above. Optimization of this solution
- is beyond the scope of this project and is better suited to other
- distributed rendering systems.
-
- <item>Rendering to a pixmap in the front-end server using the
- current XFree86 4.x code, and then displaying to the back-ends via
- calls to XPutImage() is another option. This option is similar to
- the shadow frame buffer approach mentioned above. It is slower and
- bandwidth intensive, but has the advantage that the back-end servers
- are not required to have OpenGL support.
-</enum>
-
-<p>These, and other, options will be investigated in this phase of the
-work.
-
-<p>Work by others have made Chromium DMX-aware. Chromium will use the
-DMX X protocol extension to obtain information about the back-end
-servers and will render directly to those servers, bypassing DMX.
-
-<p>Status: OpenGL support by the glxProxy extension was implemented by
-SGI and has been integrated into the DMX code base.
-<!-- May 2003-->
-
-
-<!-- ============================================================ -->
-<sect>Current issues
-
-<p>In this sections the current issues are outlined that require further
-investigation.
-
-<sect1>Fonts
-
-<p>The font path and glyphs need to be the same for the front-end and
-each of the back-end servers. Font glyphs could be sent to the back-end
-servers as necessary but this would consume a significant amount of
-available bandwidth during font rendering for clients that use many
-different fonts (e.g., Netscape). Initially, the font server (xfs) will
-be used to provide the fonts to both the front-end and back-end servers.
-Other possibilities will be investigated during development.
-
-<sect1>Zero width rendering primitives
-
-<p>To allow pixmap and on-screen rendering to be pixel perfect, all
-back-end servers must render zero width primitives exactly the same as
-the front-end renders the primitives to pixmaps. For those back-end
-servers that do not exactly match, zero width primitives will be
-automatically converted to one width primitives. This can be handled in
-the front-end server via the GC state.
-
-<sect1>Output scaling
-
-<p>With very large tiled displays, it might be difficult to read the
-information on the standard X desktop. In particular, the cursor can be
-easily lost and fonts could be difficult to read. Automatic primitive
-scaling might prove to be very useful. We will investigate the
-possibility of scaling the cursor and providing a set of alternate
-pre-scaled fonts to replace the standard fonts that many applications
-use (e.g., fixed). Other options for automatic scaling will also be
-investigated.
-
-<sect1>Per-screen colormaps
-
-<p>Each screen's default colormap in the set of back-end X servers
-should be able to be adjusted via a configuration utility. This support
-is would allow the back-end screens to be calibrated via custom gamma
-tables. On 24-bit systems that support a DirectColor visual, this type
-of correction can be accommodated. One possible implementation would be
-to advertise to X client of the DMX server a TrueColor visual while
-using DirectColor visuals on the back-end servers to implement this type
-of color correction. Other options will be investigated.
-
-<!-- ============================================================ -->
-<appendix>
-
-<sect>Background
-
-<p>This section describes the existing Open Source architectures that
-can be used to handle multiple screens and upon which this development
-project is based. This section was written before the implementation
-was finished, and may not reflect actual details of the implementation.
-It is left for historical interest only.
-
-<sect1>Core input device handling
-
-<p>The following is a description of how core input devices are handled
-by an X server.
-
-<sect2>InitInput()
-
-<p>InitInput() is a DDX function that is called at the start of each
-server generation from the X server's main() function. Its purpose is
-to determine what input devices are connected to the X server, register
-them with the DIX and MI layers, and initialize the input event queue.
-InitInput() does not have a return value, but the X server will abort if
-either a core keyboard device or a core pointer device are not
-registered. Extended input (XInput) devices can also be registered in
-InitInput().
-
-<p>InitInput() usually has implementation specific code to determine
-which input devices are available. For each input device it will be
-using, it calls AddInputDevice():
-
-<descrip>
-<tag/AddInputDevice()/ This DIX function allocates the device structure,
-registers a callback function (which handles device init, close, on and
-off), and returns the input handle, which can be treated as opaque. It
-is called once for each input device.
-</descrip>
-
-<p>Once input handles for core keyboard and core pointer devices have
-been obtained from AddInputDevice(), they are registered as core devices
-by calling RegisterPointerDevice() and RegisterKeyboardDevice(). Each
-of these should be called once. If both core devices are not
-registered, then the X server will exit with a fatal error when it
-attempts to start the input devices in InitAndStartDevices(), which is
-called directly after InitInput() (see below).
-
-<descrip>
-<tag/Register{Pointer,Keyboard}Device()/ These DIX functions take a
-handle returned from AddInputDevice() and initialize the core input
-device fields in inputInfo, and initialize the input processing and grab
-functions for each core input device.
-</descrip>
-
-<p>The core pointer device is then registered with the miPointer code
-(which does the high level cursor handling). While this registration
-is not necessary for correct miPointer operation in the current XFree86
-code, it is still done mostly for compatibility reasons.
-
-<descrip>
-<tag/miRegisterPointerDevice()/ This MI function registers the core
-pointer's input handle with with the miPointer code.
-</descrip>
-
-<p>The final part of InitInput() is the initialization of the input
-event queue handling. In most cases, the event queue handling provided
-in the MI layer is used. The primary XFree86 X server uses its own
-event queue handling to support some special cases related to the XInput
-extension and the XFree86-specific DGA extension. For our purposes, the
-MI event queue handling should be suitable. It is initialized by
-calling mieqInit():
-
-<descrip>
-<tag/mieqInit()/ This MI function initializes the MI event queue for the
-core devices, and is passed the public component of the input handles
-for the two core devices.
-</descrip>
-
-<p>If a wakeup handler is required to deliver synchronous input
-events, it can be registered here by calling the DIX function
-RegisterBlockAndWakeupHandlers(). (See the devReadInput() description
-below.)
-
-<sect2>InitAndStartDevices()
-
-<p>InitAndStartDevices() is a DIX function that is called immediately
-after InitInput() from the X server's main() function. Its purpose is
-to initialize each input device that was registered with
-AddInputDevice(), enable each input device that was successfully
-initialized, and create the list of enabled input devices. Once each
-registered device is processed in this way, the list of enabled input
-devices is checked to make sure that both a core keyboard device and
-core pointer device were registered and successfully enabled. If not,
-InitAndStartDevices() returns failure, and results in the the X server
-exiting with a fatal error.
-
-<p>Each registered device is initialized by calling its callback
-(dev-&gt;deviceProc) with the DEVICE_INIT argument:
-
-<descrip>
-<tag/(*dev-&gt;deviceProc)(dev, DEVICE_INIT)/ This function initializes the
-device structs with core information relevant to the device.
-
-<p>For pointer devices, this means specifying the number of buttons,
-default button mapping, the function used to get motion events (usually
-miPointerGetMotionEvents()), the function used to change/control the
-core pointer motion parameters (acceleration and threshold), and the
-motion buffer size.
-
-<p>For keyboard devices, this means specifying the keycode range,
-default keycode to keysym mapping, default modifier mapping, and the
-functions used to sound the keyboard bell and modify/control the
-keyboard parameters (LEDs, bell pitch and duration, key click, which
-keys are auto-repeating, etc).
-</descrip>
-
-<p>Each initialized device is enabled by calling EnableDevice():
-
-<descrip>
-<tag/EnableDevice()/ EnableDevice() calls the device callback with
-DEVICE_ON:
- <descrip>
- <tag/(*dev-&gt;deviceProc)(dev, DEVICE_ON)/ This typically opens and
- initializes the relevant physical device, and when appropriate,
- registers the device's file descriptor (or equivalent) as a valid
- input source.
- </descrip>
-
- <p>EnableDevice() then adds the device handle to the X server's
- global list of enabled devices.
-</descrip>
-
-<p>InitAndStartDevices() then verifies that a valid core keyboard and
-pointer has been initialized and enabled. It returns failure if either
-are missing.
-
-<sect2>devReadInput()
-
-<p>Each device will have some function that gets called to read its
-physical input. These may be called in a number of different ways. In
-the case of synchronous I/O, they will be called from a DDX
-wakeup-handler that gets called after the server detects that new input is
-available. In the case of asynchronous I/O, they will be called from a
-(SIGIO) signal handler triggered when new input is available. This
-function should do at least two things: make sure that input events get
-enqueued, and make sure that the cursor gets moved for motion events
-(except if these are handled later by the driver's own event queue
-processing function, which cannot be done when using the MI event queue
-handling).
-
-<p>Events are queued by calling mieqEnqueue():
-
-<descrip>
-<tag/mieqEnqueue()/ This MI function is used to add input events to the
-event queue. It is simply passed the event to be queued.
-</descrip>
-
-<p>The cursor position should be updated when motion events are
-enqueued, by calling either miPointerAbsoluteCursor() or
-miPointerDeltaCursor():
-
-<descrip>
-<tag/miPointerAbsoluteCursor()/ This MI function is used to move the
-cursor to the absolute coordinates provided.
-<tag/miPointerDeltaCursor()/ This MI function is used to move the cursor
-relative to its current position.
-</descrip>
-
-<sect2>ProcessInputEvents()
-
-<p>ProcessInputEvents() is a DDX function that is called from the X
-server's main dispatch loop when new events are available in the input
-event queue. It typically processes the enqueued events, and updates
-the cursor/pointer position. It may also do other DDX-specific event
-processing.
-
-<p>Enqueued events are processed by mieqProcessInputEvents() and passed
-to the DIX layer for transmission to clients:
-
-<descrip>
-<tag/mieqProcessInputEvents()/ This function processes each event in the
-event queue, and passes it to the device's input processing function.
-The DIX layer provides default functions to do this processing, and they
-handle the task of getting the events passed back to the relevant
-clients.
-<tag/miPointerUpdate()/ This function resynchronized the cursor position
-with the new pointer position. It also takes care of moving the cursor
-between screens when needed in multi-head configurations.
-</descrip>
-
-
-<sect2>DisableDevice()
-
-<p>DisableDevice is a DIX function that removes an input device from the
-list of enabled devices. The result of this is that the device no
-longer generates input events. The device's data structures are kept in
-place, and disabling a device like this can be reversed by calling
-EnableDevice(). DisableDevice() may be called from the DDX when it is
-desirable to do so (e.g., the XFree86 server does this when VT
-switching). Except for special cases, this is not normally called for
-core input devices.
-
-<p>DisableDevice() calls the device's callback function with
-<tt/DEVICE_OFF/:
-
-<descrip>
-<tag/(*dev-&gt;deviceProc)(dev, DEVICE_OFF)/ This typically closes the
-relevant physical device, and when appropriate, unregisters the device's
-file descriptor (or equivalent) as a valid input source.
-</descrip>
-
-<p>DisableDevice() then removes the device handle from the X server's
-global list of enabled devices.
-
-
-<sect2>CloseDevice()
-
-<p>CloseDevice is a DIX function that removes an input device from the
-list of available devices. It disables input from the device and frees
-all data structures associated with the device. This function is
-usually called from CloseDownDevices(), which is called from main() at
-the end of each server generation to close all input devices.
-
-<p>CloseDevice() calls the device's callback function with
-<tt/DEVICE_CLOSE/:
-
-<descrip>
-<tag/(*dev-&gt;deviceProc)(dev, DEVICE_CLOSE)/ This typically closes the
-relevant physical device, and when appropriate, unregisters the device's
-file descriptor (or equivalent) as a valid input source. If any device
-specific data structures were allocated when the device was initialized,
-they are freed here.
-</descrip>
-
-<p>CloseDevice() then frees the data structures that were allocated
-for the device when it was registered/initialized.
-
-
-<sect2>LegalModifier()
-<!-- dmx/dmxinput.c - currently returns TRUE -->
-<p>LegalModifier() is a required DDX function that can be used to
-restrict which keys may be modifier keys. This seems to be present for
-historical reasons, so this function should simply return TRUE
-unconditionally.
-
-
-<sect1>Output handling
-
-<p>The following sections describe the main functions required to
-initialize, use and close the output device(s) for each screen in the X
-server.
-
-<sect2>InitOutput()
-
-<p>This DDX function is called near the start of each server generation
-from the X server's main() function. InitOutput()'s main purpose is to
-initialize each screen and fill in the global screenInfo structure for
-each screen. It is passed three arguments: a pointer to the screenInfo
-struct, which it is to initialize, and argc and argv from main(), which
-can be used to determine additional configuration information.
-
-<p>The primary tasks for this function are outlined below:
-
-<enum>
- <item><bf/Parse configuration info:/ The first task of InitOutput()
- is to parses any configuration information from the configuration
- file. In addition to the XF86Config file, other configuration
- information can be taken from the command line. The command line
- options can be gathered either in InitOutput() or earlier in the
- ddxProcessArgument() function, which is called by
- ProcessCommandLine(). The configuration information determines the
- characteristics of the screen(s). For example, in the XFree86 X
- server, the XF86Config file specifies the monitor information, the
- screen resolution, the graphics devices and slots in which they are
- located, and, for Xinerama, the screens' layout.
-
- <item><bf/Initialize screen info:/ The next task is to initialize
- the screen-dependent internal data structures. For example, part of
- what the XFree86 X server does is to allocate its screen and pixmap
- private indices, probe for graphics devices, compare the probed
- devices to the ones listed in the XF86Config file, and add the ones that
- match to the internal xf86Screens&lsqb;&rsqb; structure.
-
- <item><bf/Set pixmap formats:/ The next task is to initialize the
- screenInfo's image byte order, bitmap bit order and bitmap scanline
- unit/pad. The screenInfo's pixmap format's depth, bits per pixel
- and scanline padding is also initialized at this stage.
-
- <item><bf/Unify screen info:/ An optional task that might be done at
- this stage is to compare all of the information from the various
- screens and determines if they are compatible (i.e., if the set of
- screens can be unified into a single desktop). This task has
- potential to be useful to the DMX front-end server, if Xinerama's
- PanoramiXConsolidate() function is not sufficient.
-</enum>
-
-<p>Once these tasks are complete, the valid screens are known and each
-of these screens can be initialized by calling AddScreen().
-
-<sect2>AddScreen()
-
-<p>This DIX function is called from InitOutput(), in the DDX layer, to
-add each new screen to the screenInfo structure. The DDX screen
-initialization function and command line arguments (i.e., argc and argv)
-are passed to it as arguments.
-
-<p>This function first allocates a new Screen structure and any privates
-that are required. It then initializes some of the fields in the Screen
-struct and sets up the pixmap padding information. Finally, it calls
-the DDX screen initialization function ScreenInit(), which is described
-below. It returns the number of the screen that were just added, or -1
-if there is insufficient memory to add the screen or if the DDX screen
-initialization fails.
-
-<sect2>ScreenInit()
-
-<p>This DDX function initializes the rest of the Screen structure with
-either generic or screen-specific functions (as necessary). It also
-fills in various screen attributes (e.g., width and height in
-millimeters, black and white pixel values).
-
-<p>The screen init function usually calls several functions to perform
-certain screen initialization functions. They are described below:
-
-<descrip>
-<tag/{mi,*fb}ScreenInit()/ The DDX layer's ScreenInit() function usually
-calls another layer's ScreenInit() function (e.g., miScreenInit() or
-fbScreenInit()) to initialize the fallbacks that the DDX driver does not
-specifically handle.
-
-<p>After calling another layer's ScreenInit() function, any
-screen-specific functions either wrap or replace the other layer's
-function pointers. If a function is to be wrapped, each of the old
-function pointers from the other layer are stored in a screen private
-area. Common functions to wrap are CloseScreen() and SaveScreen().
-
-<tag/miInitializeBackingStore()/ This MI function initializes the
-screen's backing storage functions, which are used to save areas of
-windows that are currently covered by other windows.
-
-<tag/miDCInitialize()/ This MI function initializes the MI cursor
-display structures and function pointers. If a hardware cursor is used,
-the DDX layer's ScreenInit() function will wrap additional screen and
-the MI cursor display function pointers.
-</descrip>
-
-<p>Another common task for ScreenInit() function is to initialize the
-output device state. For example, in the XFree86 X server, the
-ScreenInit() function saves the original state of the video card and
-then initializes the video mode of the graphics device.
-
-<sect2>CloseScreen()
-
-<p>This function restores any wrapped screen functions (and in
-particular the wrapped CloseScreen() function) and restores the state of
-the output device to its original state. It should also free any
-private data it created during the screen initialization.
-
-<sect2>GC operations
-
-<p>When the X server is requested to render drawing primitives, it does
-so by calling drawing functions through the graphics context's operation
-function pointer table (i.e., the GCOps functions). These functions
-render the basic graphics operations such as drawing rectangles, lines,
-text or copying pixmaps. Default routines are provided either by the MI
-layer, which draws indirectly through a simple span interface, or by the
-framebuffer layers (e.g., CFB, MFB, FB), which draw directly to a
-linearly mapped frame buffer.
-
-<p>To take advantage of special hardware on the graphics device,
-specific GCOps functions can be replaced by device specific code.
-However, many times the graphics devices can handle only a subset of the
-possible states of the GC, so during graphics context validation,
-appropriate routines are selected based on the state and capabilities of
-the hardware. For example, some graphics hardware can accelerate single
-pixel width lines with certain dash patterns. Thus, for dash patterns
-that are not supported by hardware or for width 2 or greater lines, the
-default routine is chosen during GC validation.
-
-<p>Note that some pointers to functions that draw to the screen are
-stored in the Screen structure. They include GetImage(), GetSpans(),
-PaintWindowBackground(), PaintWindowBorder(), CopyWindow() and
-RestoreAreas().
-
-<sect2>Xnest
-
-<p>The Xnest X server is a special proxy X server that relays the X
-protocol requests that it receives to a ``real'' X server that then
-processes the requests and displays the results, if applicable. To the X
-applications, Xnest appears as if it is a regular X server. However,
-Xnest is both server to the X application and client of the real X
-server, which will actually handle the requests.
-
-<p>The Xnest server implements all of the standard input and output
-initialization steps outlined above.
-
-<descrip>
-<tag/InitOutput()/ Xnest takes its configuration information from
-command line arguments via ddxProcessArguments(). This information
-includes the real X server display to connect to, its default visual
-class, the screen depth, the Xnest window's geometry, etc. Xnest then
-connects to the real X server and gathers visual, colormap, depth and
-pixmap information about that server's display, creates a window on that
-server, which will be used as the root window for Xnest.
-
-<p>Next, Xnest initializes its internal data structures and uses the
-data from the real X server's pixmaps to initialize its own pixmap
-formats. Finally, it calls AddScreen(xnestOpenScreen, argc, argv) to
-initialize each of its screens.
-
-<tag/ScreenInit()/ Xnest's ScreenInit() function is called
-xnestOpenScreen(). This function initializes its screen's depth and
-visual information, and then calls miScreenInit() to set up the default
-screen functions. It then calls miInitializeBackingStore() and
-miDCInitialize() to initialize backing store and the software cursor.
-Finally, it replaces many of the screen functions with its own
-functions that repackage and send the requests to the real X server to
-which Xnest is attached.
-
-<tag/CloseScreen()/ This function frees its internal data structure
-allocations. Since it replaces instead of wrapping screen functions,
-there are no function pointers to unwrap. This can potentially lead to
-problems during server regeneration.
-
-<tag/GC operations/ The GC operations in Xnest are very simple since
-they leave all of the drawing to the real X server to which Xnest is
-attached. Each of the GCOps takes the request and sends it to the
-real X server using standard Xlib calls. For example, the X
-application issues a XDrawLines() call. This function turns into a
-protocol request to Xnest, which calls the xnestPolylines() function
-through Xnest's GCOps function pointer table. The xnestPolylines()
-function is only a single line, which calls XDrawLines() using the same
-arguments that were passed into it. Other GCOps functions are very
-similar. Two exceptions to the simple GCOps functions described above
-are the image functions and the BLT operations.
-
-<p>The image functions, GetImage() and PutImage(), must use a temporary
-image to hold the image to be put of the image that was just grabbed
-from the screen while it is in transit to the real X server or the
-client. When the image has been transmitted, the temporary image is
-destroyed.
-
-<p>The BLT operations, CopyArea() and CopyPlane(), handle not only the
-copy function, which is the same as the simple cases described above,
-but also the graphics exposures that result when the GC's graphics
-exposure bit is set to True. Graphics exposures are handled in a helper
-function, xnestBitBlitHelper(). This function collects the exposure
-events from the real X server and, if any resulting in regions being
-exposed, then those regions are passed back to the MI layer so that it
-can generate exposure events for the X application.
-</descrip>
-
-<p>The Xnest server takes its input from the X server to which it is
-connected. When the mouse is in the Xnest server's window, keyboard and
-mouse events are received by the Xnest server, repackaged and sent back
-to any client that requests those events.
-
-<sect2>Shadow framebuffer
-
-<p>The most common type of framebuffer is a linear array memory that
-maps to the video memory on the graphics device. However, accessing
-that video memory over an I/O bus (e.g., ISA or PCI) can be slow. The
-shadow framebuffer layer allows the developer to keep the entire
-framebuffer in main memory and copy it back to video memory at regular
-intervals. It also has been extended to handle planar video memory and
-rotated framebuffers.
-
-<p>There are two main entry points to the shadow framebuffer code:
-
-<descrip>
-<tag/shadowAlloc(width, height, bpp)/ This function allocates the in
-memory copy of the framebuffer of size width*height*bpp. It returns a
-pointer to that memory, which will be used by the framebuffer
-ScreenInit() code during the screen's initialization.
-
-<tag/shadowInit(pScreen, updateProc, windowProc)/ This function
-initializes the shadow framebuffer layer. It wraps several screen
-drawing functions, and registers a block handler that will update the
-screen. The updateProc is a function that will copy the damaged regions
-to the screen, and the windowProc is a function that is used when the
-entire linear video memory range cannot be accessed simultaneously so
-that only a window into that memory is available (e.g., when using the
-VGA aperture).
-</descrip>
-
-<p>The shadow framebuffer code keeps track of the damaged area of each
-screen by calculating the bounding box of all drawing operations that
-have occurred since the last screen update. Then, when the block handler
-is next called, only the damaged portion of the screen is updated.
-
-<p>Note that since the shadow framebuffer is kept in main memory, all
-drawing operations are performed by the CPU and, thus, no accelerated
-hardware drawing operations are possible.
-
-
-<sect1>Xinerama
-
-<p>Xinerama is an X extension that allows multiple physical screens
-controlled by a single X server to appear as a single screen. Although
-the extension allows clients to find the physical screen layout via
-extension requests, it is completely transparent to clients at the core
-X11 protocol level. The original public implementation of Xinerama came
-from Digital/Compaq. XFree86 rewrote it, filling in some missing pieces
-and improving both X11 core protocol compliance and performance. The
-Xinerama extension will be passing through X.Org's standardization
-process in the near future, and the sample implementation will be based
-on this rewritten version.
-
-<p>The current implementation of Xinerama is based primarily in the DIX
-(device independent) and MI (machine independent) layers of the X
-server. With few exceptions the DDX layers do not need any changes to
-support Xinerama. X server extensions often do need modifications to
-provide full Xinerama functionality.
-
-<p>The following is a code-level description of how Xinerama functions.
-
-<p>Note: Because the Xinerama extension was originally called the
-PanoramiX extension, many of the Xinerama functions still have the
-PanoramiX prefix.
-
-<descrip>
- <tag/PanoramiXExtensionInit()/ PanoramiXExtensionInit() is a
- device-independent extension function that is called at the start of
- each server generation from InitExtensions(), which is called from
- the X server's main() function after all output devices have been
- initialized, but before any input devices have been initialized.
-
- <p>PanoramiXNumScreens is set to the number of physical screens. If
- only one physical screen is present, the extension is disabled, and
- PanoramiXExtensionInit() returns without doing anything else.
-
- <p>The Xinerama extension is registered by calling AddExtension().
-
- <p>A local per-screen array of data structures
- (panoramiXdataPtr&lsqb;&rsqb;)
- is allocated for each physical screen, and GC and Screen private
- indexes are allocated, and both GC and Screen private areas are
- allocated for each physical screen. These hold Xinerama-specific
- per-GC and per-Screen data. Each screen's CreateGC and CloseScreen
- functions are wrapped by XineramaCreateGC() and
- XineramaCloseScreen() respectively. Some new resource classes are
- created for Xinerama drawables and GCs, and resource types for
- Xinerama windows, pixmaps and colormaps.
-
- <p>A region (XineramaScreenRegions&lsqb;i&rsqb;) is initialized for each
- physical screen, and single region (PanoramiXScreenRegion) is
- initialized to be the union of the screen regions. The
- panoramiXdataPtr&lsqb;&rsqb; array is also initialized with the size and
- origin of each screen. The relative positioning information for the
- physical screens is taken from the array
- dixScreenOrigins&lsqb;&rsqb;, which
- the DDX layer must initialize in InitOutput(). The bounds of the
- combined screen is also calculated (PanoramiXPixWidth and
- PanoramiXPixHeight).
-
- <p>The DIX layer has a list of function pointers
- (ProcVector&lsqb;&rsqb;) that
- holds the entry points for the functions that process core protocol
- requests. The requests that Xinerama must intercept and break up
- into physical screen-specific requests are wrapped. The original
- set is copied to SavedProcVector&lsqb;&rsqb;. The types of requests
- intercepted are Window requests, GC requests, colormap requests,
- drawing requests, and some geometry-related requests. This wrapping
- allows the bulk of the protocol request processing to be handled
- transparently to the DIX layer. Some operations cannot be dealt with
- in this way and are handled with Xinerama-specific code within the
- DIX layer.
-
- <tag/PanoramiXConsolidate()/ PanoramiXConsolidate() is a
- device-independent extension function that is called directly from
- the X server's main() function after extensions and input/output
- devices have been initialized, and before the root windows are
- defined and initialized.
-
- <p>This function finds the set of depths (PanoramiXDepths&lsqb;&rsqb;) and
- visuals (PanoramiXVisuals&lsqb;&rsqb;)
- common to all of the physical screens.
- PanoramiXNumDepths is set to the number of common depths, and
- PanoramiXNumVisuals is set to the number of common visuals.
- Resources are created for the single root window and the default
- colormap. Each of these resources has per-physical screen entries.
-
- <tag/PanoramiXCreateConnectionBlock()/ PanoramiXConsolidate() is a
- device-independent extension function that is called directly from
- the X server's main() function after the per-physical screen root
- windows are created. It is called instead of the standard DIX
- CreateConnectionBlock() function. If this function returns FALSE,
- the X server exits with a fatal error. This function will return
- FALSE if no common depths were found in PanoramiXConsolidate().
- With no common depths, Xinerama mode is not possible.
-
- <p>The connection block holds the information that clients get when
- they open a connection to the X server. It includes information
- such as the supported pixmap formats, number of screens and the
- sizes, depths, visuals, default colormap information, etc, for each
- of the screens (much of information that <tt/xdpyinfo/ shows). The
- connection block is initialized with the combined single screen
- values that were calculated in the above two functions.
-
- <p>The Xinerama extension allows the registration of connection
- block callback functions. The purpose of these is to allow other
- extensions to do processing at this point. These callbacks can be
- registered by calling XineramaRegisterConnectionBlockCallback() from
- the other extension's ExtensionInit() function. Each registered
- connection block callback is called at the end of
- PanoramiXCreateConnectionBlock().
-</descrip>
-
-<sect2>Xinerama-specific changes to the DIX code
-
-<p>There are a few types of Xinerama-specific changes within the DIX
-code. The main ones are described here.
-
-<p>Functions that deal with colormap or GC -related operations outside of
-the intercepted protocol requests have a test added to only do the
-processing for screen numbers > 0. This is because they are handled for
-the single Xinerama screen and the processing is done once for screen 0.
-
-<p>The handling of motion events does some coordinate translation between
-the physical screen's origin and screen zero's origin. Also, motion
-events must be reported relative to the composite screen origin rather
-than the physical screen origins.
-
-<p>There is some special handling for cursor, window and event processing
-that cannot (either not at all or not conveniently) be done via the
-intercepted protocol requests. A particular case is the handling of
-pointers moving between physical screens.
-
-<sect2>Xinerama-specific changes to the MI code
-
-<p>The only Xinerama-specific change to the MI code is in miSendExposures()
-to handle the coordinate (and window ID) translation for expose events.
-
-<sect2>Intercepted DIX core requests
-
-<p>Xinerama breaks up drawing requests for dispatch to each physical
-screen. It also breaks up windows into pieces for each physical screen.
-GCs are translated into per-screen GCs. Colormaps are replicated on
-each physical screen. The functions handling the intercepted requests
-take care of breaking the requests and repackaging them so that they can
-be passed to the standard request handling functions for each screen in
-turn. In addition, and to aid the repackaging, the information from
-many of the intercepted requests is used to keep up to date the
-necessary state information for the single composite screen. Requests
-(usually those with replies) that can be satisfied completely from this
-stored state information do not call the standard request handling
-functions.
-
-<!-- ============================================================ -->
-
-<sect>Development Results
-
-<p>In this section the results of each phase of development are
-discussed. This development took place between approximately June 2001
-and July 2003.
-
-<sect1>Phase I
-
-<p>The initial development phase dealt with the basic implementation
-including the bootstrap code, which used the shadow framebuffer, and the
-unoptimized implementation, based on an Xnest-style implementation.
-
-<sect2>Scope
-
-<p>The goal of Phase I is to provide fundamental functionality that can
-act as a foundation for ongoing work:
-<enum>
- <item>Develop the proxy X server
- <itemize>
- <item>The proxy X server will operate on the X11 protocol and
- relay requests as necessary to correctly perform the request.
- <item>Work will be based on the existing work for Xinerama and
- Xnest.
- <item>Input events and windowing operations are handled in the
- proxy server and rendering requests are repackaged and sent to
- each of the back-end servers for display.
- <item>The multiple screen layout (including support for
- overlapping screens) will be user configurable via a
- configuration file or through the configuration tool.
- </itemize>
- <item>Develop graphical configuration tool
- <itemize>
- <item>There will be potentially a large number of X servers to
- configure into a single display. The tool will allow the user
- to specify which servers are involved in the configuration and
- how they should be laid out.
- </itemize>
- <item>Pass the X Test Suite
- <itemize>
- <item>The X Test Suite covers the basic X11 operations. All
- tests known to succeed must correctly operate in the distributed
- X environment.
- </itemize>
-</enum>
-
-<p>For this phase, the back-end X servers are assumed to be unmodified X
-servers that do not support any DMX-related protocol extensions; future
-optimization pathways are considered, but are not implemented; and the
-configuration tool is assumed to rely only on libraries in the X source
-tree (e.g., Xt).
-
-<sect2>Results
-
-<p>The proxy X server, Xdmx, was developed to distribute X11 protocol
-requests to the set of back-end X servers. It opens a window on each
-back-end server, which represents the part of the front-end's root
-window that is visible on that screen. It mirrors window, pixmap and
-other state in each back-end server. Drawing requests are sent to
-either windows or pixmaps on each back-end server. This code is based
-on Xnest and uses the existing Xinerama extension.
-
-<p>Input events can be taken from (1) devices attached to the back-end
-server, (2) core devices attached directly to the Xdmx server, or (3)
-from a ``console'' window on another X server. Events for these devices
-are gathered, processed and delivered to clients attached to the Xdmx
-server.
-
-<p>An intuitive configuration format was developed to help the user
-easily configure the multiple back-end X servers. It was defined (see
-grammar in Xdmx man page) and a parser was implemented that is used by
-the Xdmx server and by a standalone xdmxconfig utility. The parsing
-support was implemented such that it can be easily factored out of the X
-source tree for use with other tools (e.g., vdl). Support for
-converting legacy vdl-format configuration files to the DMX format is
-provided by the vdltodmx utility.
-
-<p>Originally, the configuration file was going to be a subsection of
-XFree86's XF86Config file, but that was not possible since Xdmx is a
-completely separate X server. Thus, a separate config file format was
-developed. In addition, a graphical configuration
-tool, xdmxconfig, was developed to allow the user to create and arrange
-the screens in the configuration file. The <bf/-configfile/ and <bf/-config/
-command-line options can be used to start Xdmx using a configuration
-file.
-
-<p>An extension that enables remote input testing is required for the X
-Test Suite to function. During this phase, this extension (XTEST) was
-implemented in the Xdmx server. The results from running the X Test
-Suite are described in detail below.
-
-<sect2>X Test Suite
-
- <sect3> Introduction
- <p>
- The X Test Suite contains tests that verify Xlib functions
- operate correctly. The test suite is designed to run on a
- single X server; however, since X applications will not be
- able to tell the difference between the DMX server and a
- standard X server, the X Test Suite should also run on the
- DMX server.
- <p>
- The Xdmx server was tested with the X Test Suite, and the
- existing failures are noted in this section. To put these
- results in perspective, we first discuss expected X Test
- failures and how errors in underlying systems can impact
- Xdmx test results.
-
- <sect3>Expected Failures for a Single Head
- <p>
- A correctly implemented X server with a single screen is
- expected to fail certain X Test tests. The following
- well-known errors occur because of rounding error in the X
- server code:
- <verb>
-XDrawArc: Tests 42, 63, 66, 73
-XDrawArcs: Tests 45, 66, 69, 76
- </verb>
- <p>
- The following failures occur because of the high-level X
- server implementation:
- <verb>
-XLoadQueryFont: Test 1
-XListFontsWithInfo: Tests 3, 4
-XQueryFont: Tests 1, 2
- </verb>
- <p>
- The following test fails when running the X server as root
- under Linux because of the way directory modes are
- interpreted:
- <verb>
-XWriteBitmapFile: Test 3
- </verb>
- <p>
- Depending on the video card used for the back-end, other
- failures may also occur because of bugs in the low-level
- driver implementation. Over time, failures of this kind
- are usually fixed by XFree86, but will show up in Xdmx
- testing until then.
-
- <sect3>Expected Failures for Xinerama
- <p>
- Xinerama fails several X Test Suite tests because of
- design decisions made for the current implementation of
- Xinerama. Over time, many of these errors will be
- corrected by XFree86 and the group working on a new
- Xinerama implementation. Therefore, Xdmx will also share
- X Suite Test failures with Xinerama.
- <p>
- We may be able to fix or work-around some of these
- failures at the Xdmx level, but this will require
- additional exploration that was not part of Phase I.
- <p>
- Xinerama is constantly improving, and the list of
- Xinerama-related failures depends on XFree86 version and
- the underlying graphics hardware. We tested with a
- variety of hardware, including nVidia, S3, ATI Radeon,
- and Matrox G400 (in dual-head mode). The list below
- includes only those failures that appear to be from the
- Xinerama layer, and does not include failures listed in
- the previous section, or failures that appear to be from
- the low-level graphics driver itself:
- <p>
- These failures were noted with multiple Xinerama
- configurations:
- <verb>
-XCopyPlane: Tests 13, 22, 31 (well-known Xinerama implementation issue)
-XSetFontPath: Test 4
-XGetDefault: Test 5
-XMatchVisualInfo: Test 1
- </verb>
- <p>
- These failures were noted only when using one dual-head
- video card with a 4.2.99.x XFree86 server:
- <verb>
-XListPixmapFormats: Test 1
-XDrawRectangles: Test 45
- </verb>
- <p>
- These failures were noted only when using two video cards
- from different vendors with a 4.1.99.x XFree86 server:
- <verb>
-XChangeWindowAttributes: Test 32
-XCreateWindow: Test 30
-XDrawLine: Test 22
-XFillArc: Test 22
-XChangeKeyboardControl: Tests 9, 10
-XRebindKeysym: Test 1
- </verb>
-
- <sect3>Additional Failures from Xdmx
- <p>
- When running Xdmx, no unexpected failures were noted.
- Since the Xdmx server is based on Xinerama, we expect to
- have most of the Xinerama failures present in the Xdmx
- server. Similarly, since the Xdmx server must rely on the
- low-level device drivers on each back-end server, we also
- expect that Xdmx will exhibit most of the back-end
- failures. Here is a summary:
- <verb>
-XListPixmapFormats: Test 1 (configuration dependent)
-XChangeWindowAttributes: Test 32
-XCreateWindow: Test 30
-XCopyPlane: Test 13, 22, 31
-XSetFontPath: Test 4
-XGetDefault: Test 5 (configuration dependent)
-XMatchVisualInfo: Test 1
-XRebindKeysym: Test 1 (configuration dependent)
- </verb>
- <p>
- Note that this list is shorter than the combined list for
- Xinerama because Xdmx uses different code paths to perform
- some Xinerama operations. Further, some Xinerama failures
- have been fixed in the XFree86 4.2.99.x CVS repository.
-
- <sect3>Summary and Future Work
- <p>
- Running the X Test Suite on Xdmx does not produce any
- failures that cannot be accounted for by the underlying
- Xinerama subsystem used by the front-end or by the
- low-level device-driver code running on the back-end X
- servers. The Xdmx server therefore is as ``correct'' as
- possible with respect to the standard set of X Test Suite
- tests.
- <p>
- During the following phases, we will continue to verify
- Xdmx correctness using the X Test Suite. We may also use
- other tests suites or write additional tests that run
- under the X Test Suite that specifically verify the
- expected behavior of DMX.
-
-<sect2>Fonts
-
-<p>In Phase I, fonts are handled directly by both the front-end and the
-back-end servers, which is required since we must treat each back-end
-server during this phase as a ``black box''. What this requires is that
-<bf/the front- and back-end servers must share the exact same font
-path/. There are two ways to help make sure that all servers share the
-same font path:
-
-<enum>
- <item>First, each server can be configured to use the same font
- server. The font server, xfs, can be configured to serve fonts to
- multiple X servers via TCP.
-
- <item>Second, each server can be configured to use the same font
- path and either those font paths can be copied to each back-end
- machine or they can be mounted (e.g., via NFS) on each back-end
- machine.
-</enum>
-
-<p>One additional concern is that a client program can set its own font
-path, and if it does so, then that font path must be available on each
-back-end machine.
-
-<p>The -fontpath command line option was added to allow users to
-initialize the font path of the front end server. This font path is
-propagated to each back-end server when the default font is loaded. If
-there are any problems, an error message is printed, which will describe
-the problem and list the current font path. For more information about
-setting the font path, see the -fontpath option description in the man
-page.
-
-<sect2>Performance
-
-<p>Phase I of development was not intended to optimize performance. Its
-focus was on completely and correctly handling the base X11 protocol in
-the Xdmx server. However, several insights were gained during Phase I,
-which are listed here for reference during the next phase of
-development.
-
-<enum>
- <item>Calls to XSync() can slow down rendering since it requires a
- complete round trip to and from a back-end server. This is
- especially problematic when communicating over long haul networks.
- <item>Sending drawing requests to only the screens that they overlap
- should improve performance.
-</enum>
-
-<sect2>Pixmaps
-
-<p>Pixmaps were originally expected to be handled entirely in the
-front-end X server; however, it was found that this overly complicated
-the rendering code and would have required sending potentially large
-images to each back server that required them when copying from pixmap
-to screen. Thus, pixmap state is mirrored in the back-end server just
-as it is with regular window state. With this implementation, the same
-rendering code that draws to windows can be used to draw to pixmaps on
-the back-end server, and no large image transfers are required to copy
-from pixmap to window.
-
-<!-- ============================================================ -->
-<sect1>Phase II
-
-<p>The second phase of development concentrates on performance
-optimizations. These optimizations are documented here, with
-<tt/x11perf/ data to show how the optimizations improve performance.
-
-<p>All benchmarks were performed by running Xdmx on a dual processor
-1.4GHz AMD Athlon machine with 1GB of RAM connecting over 100baseT to
-two single-processor 1GHz Pentium III machines with 256MB of RAM and ATI
-Rage 128 (RF) video cards. The front end was running Linux
-2.4.20-pre1-ac1 and the back ends were running Linux 2.4.7-10 and
-version 4.2.99.1 of XFree86 pulled from the XFree86 CVS repository on
-August 7, 2002. All systems were running Red Hat Linux 7.2.
-
-<sect2>Moving from XFree86 4.1.99.1 to 4.2.0.0
-
-<p>For phase II, the working source tree was moved to the branch tagged
-with dmx-1-0-branch and was updated from version 4.1.99.1 (20 August
-2001) of the XFree86 sources to version 4.2.0.0 (18 January 2002).
-After this update, the following tests were noted to be more than 10%
-faster:
- <verb>
-1.13 Fill 300x300 opaque stippled trapezoid (161x145 stipple)
-1.16 Fill 1x1 tiled trapezoid (161x145 tile)
-1.13 Fill 10x10 tiled trapezoid (161x145 tile)
-1.17 Fill 100x100 tiled trapezoid (161x145 tile)
-1.16 Fill 1x1 tiled trapezoid (216x208 tile)
-1.20 Fill 10x10 tiled trapezoid (216x208 tile)
-1.15 Fill 100x100 tiled trapezoid (216x208 tile)
-1.37 Circulate Unmapped window (200 kids)
- </verb>
-And the following tests were noted to be more than 10% slower:
- <verb>
-0.88 Unmap window via parent (25 kids)
-0.75 Circulate Unmapped window (4 kids)
-0.79 Circulate Unmapped window (16 kids)
-0.80 Circulate Unmapped window (25 kids)
-0.82 Circulate Unmapped window (50 kids)
-0.85 Circulate Unmapped window (75 kids)
- </verb>
-<p>These changes were not caused by any changes in the DMX system, and
-may point to changes in the XFree86 tree or to tests that have more
-"jitter" than most other <tt/x11perf/ tests.
-
-<sect2>Global changes
-
-<p>During the development of the Phase II DMX server, several global
-changes were made. These changes were also compared with the Phase I
-server. The following tests were noted to be more than 10% faster:
- <verb>
-1.13 Fill 300x300 opaque stippled trapezoid (161x145 stipple)
-1.15 Fill 1x1 tiled trapezoid (161x145 tile)
-1.13 Fill 10x10 tiled trapezoid (161x145 tile)
-1.17 Fill 100x100 tiled trapezoid (161x145 tile)
-1.16 Fill 1x1 tiled trapezoid (216x208 tile)
-1.19 Fill 10x10 tiled trapezoid (216x208 tile)
-1.15 Fill 100x100 tiled trapezoid (216x208 tile)
-1.15 Circulate Unmapped window (4 kids)
- </verb>
-
-<p>The following tests were noted to be more than 10% slower:
- <verb>
-0.69 Scroll 10x10 pixels
-0.68 Scroll 100x100 pixels
-0.68 Copy 10x10 from window to window
-0.68 Copy 100x100 from window to window
-0.76 Circulate Unmapped window (75 kids)
-0.83 Circulate Unmapped window (100 kids)
- </verb>
-
-<p>For the remainder of this analysis, the baseline of comparison will
-be the Phase II deliverable with all optimizations disabled (unless
-otherwise noted). This will highlight how the optimizations in
-isolation impact performance.
-
-<sect2>XSync() Batching
-
-<p>During the Phase I implementation, XSync() was called after every
-protocol request made by the DMX server. This provided the DMX server
-with an interactive feel, but defeated X11's protocol buffering system
-and introduced round-trip wire latency into every operation. During
-Phase II, DMX was changed so that protocol requests are no longer
-followed by calls to XSync(). Instead, the need for an XSync() is
-noted, and XSync() calls are only made every 100mS or when the DMX
-server specifically needs to make a call to guarantee interactivity.
-With this new system, X11 buffers protocol as much as possible during a
-100mS interval, and many unnecessary XSync() calls are avoided.
-
-<p>Out of more than 300 <tt/x11perf/ tests, 8 tests became more than 100
-times faster, with 68 more than 50X faster, 114 more than 10X faster,
-and 181 more than 2X faster. See table below for summary.
-
-<p>The following tests were noted to be more than 10% slower with
-XSync() batching on:
- <verb>
-0.88 500x500 tiled rectangle (161x145 tile)
-0.89 Copy 500x500 from window to window
- </verb>
-
-<sect2>Offscreen Optimization
-
-<p>Windows span one or more of the back-end servers' screens; however,
-during Phase I development, windows were created on every back-end
-server and every rendering request was sent to every window regardless
-of whether or not that window was visible. With the offscreen
-optimization, the DMX server tracks when a window is completely off of a
-back-end server's screen and, in that case, it does not send rendering
-requests to those back-end windows. This optimization saves bandwidth
-between the front and back-end servers, and it reduces the number of
-XSync() calls. The performance tests were run on a DMX system with only
-two back-end servers. Greater performance gains will be had as the
-number of back-end servers increases.
-
-<p>Out of more than 300 <tt/x11perf/ tests, 3 tests were at least twice as
-fast, and 146 tests were at least 10% faster. Two tests were more than
-10% slower with the offscreen optimization:
- <verb>
-0.88 Hide/expose window via popup (4 kids)
-0.89 Resize unmapped window (75 kids)
- </verb>
-
-<sect2>Lazy Window Creation Optimization
-
-<p>As mentioned above, during Phase I, windows were created on every
-back-end server even if they were not visible on that back-end. With
-the lazy window creation optimization, the DMX server does not create
-windows on a back-end server until they are either visible or they
-become the parents of a visible window. This optimization builds on the
-offscreen optimization (described above) and requires it to be enabled.
-
-<p>The lazy window creation optimization works by creating the window
-data structures in the front-end server when a client creates a window,
-but delays creation of the window on the back-end server(s). A private
-window structure in the DMX server saves the relevant window data and
-tracks changes to the window's attributes and stacking order for later
-use. The only times a window is created on a back-end server are (1)
-when it is mapped and is at least partially overlapping the back-end
-server's screen (tracked by the offscreen optimization), or (2) when the
-window becomes the parent of a previously visible window. The first
-case occurs when a window is mapped or when a visible window is copied,
-moved or resized and now overlaps the back-end server's screen. The
-second case occurs when starting a window manager after having created
-windows to which the window manager needs to add decorations.
-
-<p>When either case occurs, a window on the back-end server is created
-using the data saved in the DMX server's window private data structure.
-The stacking order is then adjusted to correctly place the window on the
-back-end and lastly the window is mapped. From this time forward, the
-window is handled exactly as if the window had been created at the time
-of the client's request.
-
-<p>Note that when a window is no longer visible on a back-end server's
-screen (e.g., it is moved offscreen), the window is not destroyed;
-rather, it is kept and reused later if the window once again becomes
-visible on the back-end server's screen. Originally with this
-optimization, destroying windows was implemented but was later rejected
-because it increased bandwidth when windows were opaquely moved or
-resized, which is common in many window managers.
-
-<p>The performance tests were run on a DMX system with only two back-end
-servers. Greater performance gains will be had as the number of
-back-end servers increases.
-
-<p>This optimization improved the following <tt/x11perf/ tests by more
-than 10%:
- <verb>
-1.10 500x500 rectangle outline
-1.12 Fill 100x100 stippled trapezoid (161x145 stipple)
-1.20 Circulate Unmapped window (50 kids)
-1.19 Circulate Unmapped window (75 kids)
- </verb>
-
-<sect2>Subdividing Rendering Primitives
-
-<p>X11 imaging requests transfer significant data between the client and
-the X server. During Phase I, the DMX server would then transfer the
-image data to each back-end server. Even with the offscreen
-optimization (above), these requests still required transferring
-significant data to each back-end server that contained a visible
-portion of the window. For example, if the client uses XPutImage() to
-copy an image to a window that overlaps the entire DMX screen, then the
-entire image is copied by the DMX server to every back-end server.
-
-<p>To reduce the amount of data transferred between the DMX server and
-the back-end servers when XPutImage() is called, the image data is
-subdivided and only the data that will be visible on a back-end server's
-screen is sent to that back-end server. Xinerama already implements a
-subdivision algorithm for XGetImage() and no further optimization was
-needed.
-
-<p>Other rendering primitives were analyzed, but the time required to
-subdivide these primitives was a significant proportion of the time
-required to send the entire rendering request to the back-end server, so
-this optimization was rejected for the other rendering primitives.
-
-<p>Again, the performance tests were run on a DMX system with only two
-back-end servers. Greater performance gains will be had as the number
-of back-end servers increases.
-
-<p>This optimization improved the following <tt/x11perf/ tests by more
-than 10%:
- <verb>
-1.12 Fill 100x100 stippled trapezoid (161x145 stipple)
-1.26 PutImage 10x10 square
-1.83 PutImage 100x100 square
-1.91 PutImage 500x500 square
-1.40 PutImage XY 10x10 square
-1.48 PutImage XY 100x100 square
-1.50 PutImage XY 500x500 square
-1.45 Circulate Unmapped window (75 kids)
-1.74 Circulate Unmapped window (100 kids)
- </verb>
-
-<p>The following test was noted to be more than 10% slower with this
-optimization:
- <verb>
-0.88 10-pixel fill chord partial circle
- </verb>
-
-<sect2>Summary of x11perf Data
-
-<p>With all of the optimizations on, 53 <tt/x11perf/ tests are more than
-100X faster than the unoptimized Phase II deliverable, with 69 more than
-50X faster, 73 more than 10X faster, and 199 more than twice as fast.
-No tests were more than 10% slower than the unoptimized Phase II
-deliverable. (Compared with the Phase I deliverable, only Circulate
-Unmapped window (100 kids) was more than 10% slower than the Phase II
-deliverable. As noted above, this test seems to have wider variability
-than other <tt/x11perf/ tests.)
-
-<p>The following table summarizes relative <tt/x11perf/ test changes for
-all optimizations individually and collectively. Note that some of the
-optimizations have a synergistic effect when used together.
- <verb>
-
-1: XSync() batching only
-2: Off screen optimizations only
-3: Window optimizations only
-4: Subdivprims only
-5: All optimizations
-
- 1 2 3 4 5 Operation
------- ---- ---- ---- ------ ---------
- 2.14 1.85 1.00 1.00 4.13 Dot
- 1.67 1.80 1.00 1.00 3.31 1x1 rectangle
- 2.38 1.43 1.00 1.00 2.44 10x10 rectangle
- 1.00 1.00 0.92 0.98 1.00 100x100 rectangle
- 1.00 1.00 1.00 1.00 1.00 500x500 rectangle
- 1.83 1.85 1.05 1.06 3.54 1x1 stippled rectangle (8x8 stipple)
- 2.43 1.43 1.00 1.00 2.41 10x10 stippled rectangle (8x8 stipple)
- 0.98 1.00 1.00 1.00 1.00 100x100 stippled rectangle (8x8 stipple)
- 1.00 1.00 1.00 1.00 0.98 500x500 stippled rectangle (8x8 stipple)
- 1.75 1.75 1.00 1.00 3.40 1x1 opaque stippled rectangle (8x8 stipple)
- 2.38 1.42 1.00 1.00 2.34 10x10 opaque stippled rectangle (8x8 stipple)
- 1.00 1.00 0.97 0.97 1.00 100x100 opaque stippled rectangle (8x8 stipple)
- 1.00 1.00 1.00 1.00 0.99 500x500 opaque stippled rectangle (8x8 stipple)
- 1.82 1.82 1.04 1.04 3.56 1x1 tiled rectangle (4x4 tile)
- 2.33 1.42 1.00 1.00 2.37 10x10 tiled rectangle (4x4 tile)
- 1.00 0.92 1.00 1.00 1.00 100x100 tiled rectangle (4x4 tile)
- 1.00 1.00 1.00 1.00 1.00 500x500 tiled rectangle (4x4 tile)
- 1.94 1.62 1.00 1.00 3.66 1x1 stippled rectangle (17x15 stipple)
- 1.74 1.28 1.00 1.00 1.73 10x10 stippled rectangle (17x15 stipple)
- 1.00 1.00 1.00 0.89 0.98 100x100 stippled rectangle (17x15 stipple)
- 1.00 1.00 1.00 1.00 0.98 500x500 stippled rectangle (17x15 stipple)
- 1.94 1.62 1.00 1.00 3.67 1x1 opaque stippled rectangle (17x15 stipple)
- 1.69 1.26 1.00 1.00 1.66 10x10 opaque stippled rectangle (17x15 stipple)
- 1.00 0.95 1.00 1.00 1.00 100x100 opaque stippled rectangle (17x15 stipple)
- 1.00 1.00 1.00 1.00 0.97 500x500 opaque stippled rectangle (17x15 stipple)
- 1.93 1.61 0.99 0.99 3.69 1x1 tiled rectangle (17x15 tile)
- 1.73 1.27 1.00 1.00 1.72 10x10 tiled rectangle (17x15 tile)
- 1.00 1.00 1.00 1.00 0.98 100x100 tiled rectangle (17x15 tile)
- 1.00 1.00 0.97 0.97 1.00 500x500 tiled rectangle (17x15 tile)
- 1.95 1.63 1.00 1.00 3.83 1x1 stippled rectangle (161x145 stipple)
- 1.80 1.30 1.00 1.00 1.83 10x10 stippled rectangle (161x145 stipple)
- 0.97 1.00 1.00 1.00 1.01 100x100 stippled rectangle (161x145 stipple)
- 1.00 1.00 1.00 1.00 0.98 500x500 stippled rectangle (161x145 stipple)
- 1.95 1.63 1.00 1.00 3.56 1x1 opaque stippled rectangle (161x145 stipple)
- 1.65 1.25 1.00 1.00 1.68 10x10 opaque stippled rectangle (161x145 stipple)
- 1.00 1.00 1.00 1.00 1.01 100x100 opaque stippled rectangle (161x145...
- 1.00 1.00 1.00 1.00 0.97 500x500 opaque stippled rectangle (161x145...
- 1.95 1.63 0.98 0.99 3.80 1x1 tiled rectangle (161x145 tile)
- 1.67 1.26 1.00 1.00 1.67 10x10 tiled rectangle (161x145 tile)
- 1.13 1.14 1.14 1.14 1.14 100x100 tiled rectangle (161x145 tile)
- 0.88 1.00 1.00 1.00 0.99 500x500 tiled rectangle (161x145 tile)
- 1.93 1.63 1.00 1.00 3.53 1x1 tiled rectangle (216x208 tile)
- 1.69 1.26 1.00 1.00 1.66 10x10 tiled rectangle (216x208 tile)
- 1.00 1.00 1.00 1.00 1.00 100x100 tiled rectangle (216x208 tile)
- 1.00 1.00 1.00 1.00 1.00 500x500 tiled rectangle (216x208 tile)
- 1.82 1.70 1.00 1.00 3.38 1-pixel line segment
- 2.07 1.56 0.90 1.00 3.31 10-pixel line segment
- 1.29 1.10 1.00 1.00 1.27 100-pixel line segment
- 1.05 1.06 1.03 1.03 1.09 500-pixel line segment
- 1.30 1.13 1.00 1.00 1.29 100-pixel line segment (1 kid)
- 1.32 1.15 1.00 1.00 1.32 100-pixel line segment (2 kids)
- 1.33 1.16 1.00 1.00 1.33 100-pixel line segment (3 kids)
- 1.92 1.64 1.00 1.00 3.73 10-pixel dashed segment
- 1.34 1.16 1.00 1.00 1.34 100-pixel dashed segment
- 1.24 1.11 0.99 0.97 1.23 100-pixel double-dashed segment
- 1.72 1.77 1.00 1.00 3.25 10-pixel horizontal line segment
- 1.83 1.66 1.01 1.00 3.54 100-pixel horizontal line segment
- 1.86 1.30 1.00 1.00 1.84 500-pixel horizontal line segment
- 2.11 1.52 1.00 0.99 3.02 10-pixel vertical line segment
- 1.21 1.10 1.00 1.00 1.20 100-pixel vertical line segment
- 1.03 1.03 1.00 1.00 1.02 500-pixel vertical line segment
- 4.42 1.68 1.00 1.01 4.64 10x1 wide horizontal line segment
- 1.83 1.31 1.00 1.00 1.83 100x10 wide horizontal line segment
- 1.07 1.00 0.96 1.00 1.07 500x50 wide horizontal line segment
- 4.10 1.67 1.00 1.00 4.62 10x1 wide vertical line segment
- 1.50 1.24 1.06 1.06 1.48 100x10 wide vertical line segment
- 1.06 1.03 1.00 1.00 1.05 500x50 wide vertical line segment
- 2.54 1.61 1.00 1.00 3.61 1-pixel line
- 2.71 1.48 1.00 1.00 2.67 10-pixel line
- 1.19 1.09 1.00 1.00 1.19 100-pixel line
- 1.04 1.02 1.00 1.00 1.03 500-pixel line
- 2.68 1.51 0.98 1.00 3.17 10-pixel dashed line
- 1.23 1.11 0.99 0.99 1.23 100-pixel dashed line
- 1.15 1.08 1.00 1.00 1.15 100-pixel double-dashed line
- 2.27 1.39 1.00 1.00 2.23 10x1 wide line
- 1.20 1.09 1.00 1.00 1.20 100x10 wide line
- 1.04 1.02 1.00 1.00 1.04 500x50 wide line
- 1.52 1.45 1.00 1.00 1.52 100x10 wide dashed line
- 1.54 1.47 1.00 1.00 1.54 100x10 wide double-dashed line
- 1.97 1.30 0.96 0.95 1.95 10x10 rectangle outline
- 1.44 1.27 1.00 1.00 1.43 100x100 rectangle outline
- 3.22 2.16 1.10 1.09 3.61 500x500 rectangle outline
- 1.95 1.34 1.00 1.00 1.90 10x10 wide rectangle outline
- 1.14 1.14 1.00 1.00 1.13 100x100 wide rectangle outline
- 1.00 1.00 1.00 1.00 1.00 500x500 wide rectangle outline
- 1.57 1.72 1.00 1.00 3.03 1-pixel circle
- 1.96 1.35 1.00 1.00 1.92 10-pixel circle
- 1.21 1.07 0.86 0.97 1.20 100-pixel circle
- 1.08 1.04 1.00 1.00 1.08 500-pixel circle
- 1.39 1.19 1.03 1.03 1.38 100-pixel dashed circle
- 1.21 1.11 1.00 1.00 1.23 100-pixel double-dashed circle
- 1.59 1.28 1.00 1.00 1.58 10-pixel wide circle
- 1.22 1.12 0.99 1.00 1.22 100-pixel wide circle
- 1.06 1.04 1.00 1.00 1.05 500-pixel wide circle
- 1.87 1.84 1.00 1.00 1.85 100-pixel wide dashed circle
- 1.90 1.93 1.01 1.01 1.90 100-pixel wide double-dashed circle
- 2.13 1.43 1.00 1.00 2.32 10-pixel partial circle
- 1.42 1.18 1.00 1.00 1.42 100-pixel partial circle
- 1.92 1.85 1.01 1.01 1.89 10-pixel wide partial circle
- 1.73 1.67 1.00 1.00 1.73 100-pixel wide partial circle
- 1.36 1.95 1.00 1.00 2.64 1-pixel solid circle
- 2.02 1.37 1.00 1.00 2.03 10-pixel solid circle
- 1.19 1.09 1.00 1.00 1.19 100-pixel solid circle
- 1.02 0.99 1.00 1.00 1.01 500-pixel solid circle
- 1.74 1.28 1.00 0.88 1.73 10-pixel fill chord partial circle
- 1.31 1.13 1.00 1.00 1.31 100-pixel fill chord partial circle
- 1.67 1.31 1.03 1.03 1.72 10-pixel fill slice partial circle
- 1.30 1.13 1.00 1.00 1.28 100-pixel fill slice partial circle
- 2.45 1.49 1.01 1.00 2.71 10-pixel ellipse
- 1.22 1.10 1.00 1.00 1.22 100-pixel ellipse
- 1.09 1.04 1.00 1.00 1.09 500-pixel ellipse
- 1.90 1.28 1.00 1.00 1.89 100-pixel dashed ellipse
- 1.62 1.24 0.96 0.97 1.61 100-pixel double-dashed ellipse
- 2.43 1.50 1.00 1.00 2.42 10-pixel wide ellipse
- 1.61 1.28 1.03 1.03 1.60 100-pixel wide ellipse
- 1.08 1.05 1.00 1.00 1.08 500-pixel wide ellipse
- 1.93 1.88 1.00 1.00 1.88 100-pixel wide dashed ellipse
- 1.94 1.89 1.01 1.00 1.94 100-pixel wide double-dashed ellipse
- 2.31 1.48 1.00 1.00 2.67 10-pixel partial ellipse
- 1.38 1.17 1.00 1.00 1.38 100-pixel partial ellipse
- 2.00 1.85 0.98 0.97 1.98 10-pixel wide partial ellipse
- 1.89 1.86 1.00 1.00 1.89 100-pixel wide partial ellipse
- 3.49 1.60 1.00 1.00 3.65 10-pixel filled ellipse
- 1.67 1.26 1.00 1.00 1.67 100-pixel filled ellipse
- 1.06 1.04 1.00 1.00 1.06 500-pixel filled ellipse
- 2.38 1.43 1.01 1.00 2.32 10-pixel fill chord partial ellipse
- 2.06 1.30 1.00 1.00 2.05 100-pixel fill chord partial ellipse
- 2.27 1.41 1.00 1.00 2.27 10-pixel fill slice partial ellipse
- 1.98 1.33 1.00 0.97 1.97 100-pixel fill slice partial ellipse
- 57.46 1.99 1.01 1.00 114.92 Fill 1x1 equivalent triangle
- 56.94 1.98 1.01 1.00 73.89 Fill 10x10 equivalent triangle
- 6.07 1.75 1.00 1.00 6.07 Fill 100x100 equivalent triangle
- 51.12 1.98 1.00 1.00 102.81 Fill 1x1 trapezoid
- 51.42 1.82 1.01 1.00 94.89 Fill 10x10 trapezoid
- 6.47 1.80 1.00 1.00 6.44 Fill 100x100 trapezoid
- 1.56 1.28 1.00 0.99 1.56 Fill 300x300 trapezoid
- 51.27 1.97 0.96 0.97 102.54 Fill 1x1 stippled trapezoid (8x8 stipple)
- 51.73 2.00 1.02 1.02 67.92 Fill 10x10 stippled trapezoid (8x8 stipple)
- 5.36 1.72 1.00 1.00 5.36 Fill 100x100 stippled trapezoid (8x8 stipple)
- 1.54 1.26 1.00 1.00 1.59 Fill 300x300 stippled trapezoid (8x8 stipple)
- 51.41 1.94 1.01 1.00 102.82 Fill 1x1 opaque stippled trapezoid (8x8 stipple)
- 50.71 1.95 0.99 1.00 65.44 Fill 10x10 opaque stippled trapezoid (8x8...
- 5.33 1.73 1.00 1.00 5.36 Fill 100x100 opaque stippled trapezoid (8x8...
- 1.58 1.25 1.00 1.00 1.58 Fill 300x300 opaque stippled trapezoid (8x8...
- 51.56 1.96 0.99 0.90 103.68 Fill 1x1 tiled trapezoid (4x4 tile)
- 51.59 1.99 1.01 1.01 62.25 Fill 10x10 tiled trapezoid (4x4 tile)
- 5.38 1.72 1.00 1.00 5.38 Fill 100x100 tiled trapezoid (4x4 tile)
- 1.54 1.25 1.00 0.99 1.58 Fill 300x300 tiled trapezoid (4x4 tile)
- 51.70 1.98 1.01 1.01 103.98 Fill 1x1 stippled trapezoid (17x15 stipple)
- 44.86 1.97 1.00 1.00 44.86 Fill 10x10 stippled trapezoid (17x15 stipple)
- 2.74 1.56 1.00 1.00 2.73 Fill 100x100 stippled trapezoid (17x15 stipple)
- 1.29 1.14 1.00 1.00 1.27 Fill 300x300 stippled trapezoid (17x15 stipple)
- 51.41 1.96 0.96 0.95 103.39 Fill 1x1 opaque stippled trapezoid (17x15...
- 45.14 1.96 1.01 1.00 45.14 Fill 10x10 opaque stippled trapezoid (17x15...
- 2.68 1.56 1.00 1.00 2.68 Fill 100x100 opaque stippled trapezoid (17x15...
- 1.26 1.10 1.00 1.00 1.28 Fill 300x300 opaque stippled trapezoid (17x15...
- 51.13 1.97 1.00 0.99 103.39 Fill 1x1 tiled trapezoid (17x15 tile)
- 47.58 1.96 1.00 1.00 47.86 Fill 10x10 tiled trapezoid (17x15 tile)
- 2.74 1.56 1.00 1.00 2.74 Fill 100x100 tiled trapezoid (17x15 tile)
- 1.29 1.14 1.00 1.00 1.28 Fill 300x300 tiled trapezoid (17x15 tile)
- 51.13 1.97 0.99 0.97 103.39 Fill 1x1 stippled trapezoid (161x145 stipple)
- 45.14 1.97 1.00 1.00 44.29 Fill 10x10 stippled trapezoid (161x145 stipple)
- 3.02 1.77 1.12 1.12 3.38 Fill 100x100 stippled trapezoid (161x145 stipple)
- 1.31 1.13 1.00 1.00 1.30 Fill 300x300 stippled trapezoid (161x145 stipple)
- 51.27 1.97 1.00 1.00 103.10 Fill 1x1 opaque stippled trapezoid (161x145...
- 45.01 1.97 1.00 1.00 45.01 Fill 10x10 opaque stippled trapezoid (161x145...
- 2.67 1.56 1.00 1.00 2.69 Fill 100x100 opaque stippled trapezoid (161x145..
- 1.29 1.13 1.00 1.01 1.27 Fill 300x300 opaque stippled trapezoid (161x145..
- 51.41 1.96 1.00 0.99 103.39 Fill 1x1 tiled trapezoid (161x145 tile)
- 45.01 1.96 0.98 1.00 45.01 Fill 10x10 tiled trapezoid (161x145 tile)
- 2.62 1.36 1.00 1.00 2.69 Fill 100x100 tiled trapezoid (161x145 tile)
- 1.27 1.13 1.00 1.00 1.22 Fill 300x300 tiled trapezoid (161x145 tile)
- 51.13 1.98 1.00 1.00 103.39 Fill 1x1 tiled trapezoid (216x208 tile)
- 45.14 1.97 1.01 0.99 45.14 Fill 10x10 tiled trapezoid (216x208 tile)
- 2.62 1.55 1.00 1.00 2.71 Fill 100x100 tiled trapezoid (216x208 tile)
- 1.28 1.13 1.00 1.00 1.20 Fill 300x300 tiled trapezoid (216x208 tile)
- 50.71 1.95 1.00 1.00 54.70 Fill 10x10 equivalent complex polygon
- 5.51 1.71 0.96 0.98 5.47 Fill 100x100 equivalent complex polygons
- 8.39 1.97 1.00 1.00 16.75 Fill 10x10 64-gon (Convex)
- 8.38 1.83 1.00 1.00 8.43 Fill 100x100 64-gon (Convex)
- 8.50 1.96 1.00 1.00 16.64 Fill 10x10 64-gon (Complex)
- 8.26 1.83 1.00 1.00 8.35 Fill 100x100 64-gon (Complex)
- 14.09 1.87 1.00 1.00 14.05 Char in 80-char line (6x13)
- 11.91 1.87 1.00 1.00 11.95 Char in 70-char line (8x13)
- 11.16 1.85 1.01 1.00 11.10 Char in 60-char line (9x15)
- 10.09 1.78 1.00 1.00 10.09 Char16 in 40-char line (k14)
- 6.15 1.75 1.00 1.00 6.31 Char16 in 23-char line (k24)
- 11.92 1.90 1.03 1.03 11.88 Char in 80-char line (TR 10)
- 8.18 1.78 1.00 0.99 8.17 Char in 30-char line (TR 24)
- 42.83 1.44 1.01 1.00 42.11 Char in 20/40/20 line (6x13, TR 10)
- 27.45 1.43 1.01 1.01 27.45 Char16 in 7/14/7 line (k14, k24)
- 12.13 1.85 1.00 1.00 12.05 Char in 80-char image line (6x13)
- 10.00 1.84 1.00 1.00 10.00 Char in 70-char image line (8x13)
- 9.18 1.83 1.00 1.00 9.12 Char in 60-char image line (9x15)
- 9.66 1.82 0.98 0.95 9.66 Char16 in 40-char image line (k14)
- 5.82 1.72 1.00 1.00 5.99 Char16 in 23-char image line (k24)
- 8.70 1.80 1.00 1.00 8.65 Char in 80-char image line (TR 10)
- 4.67 1.66 1.00 1.00 4.67 Char in 30-char image line (TR 24)
- 84.43 1.47 1.00 1.00 124.18 Scroll 10x10 pixels
- 3.73 1.50 1.00 0.98 3.73 Scroll 100x100 pixels
- 1.00 1.00 1.00 1.00 1.00 Scroll 500x500 pixels
- 84.43 1.51 1.00 1.00 134.02 Copy 10x10 from window to window
- 3.62 1.51 0.98 0.98 3.62 Copy 100x100 from window to window
- 0.89 1.00 1.00 1.00 1.00 Copy 500x500 from window to window
- 57.06 1.99 1.00 1.00 88.64 Copy 10x10 from pixmap to window
- 2.49 2.00 1.00 1.00 2.48 Copy 100x100 from pixmap to window
- 1.00 0.91 1.00 1.00 0.98 Copy 500x500 from pixmap to window
- 2.04 1.01 1.00 1.00 2.03 Copy 10x10 from window to pixmap
- 1.05 1.00 1.00 1.00 1.05 Copy 100x100 from window to pixmap
- 1.00 1.00 0.93 1.00 1.04 Copy 500x500 from window to pixmap
- 58.52 1.03 1.03 1.02 57.95 Copy 10x10 from pixmap to pixmap
- 2.40 1.00 1.00 1.00 2.45 Copy 100x100 from pixmap to pixmap
- 1.00 1.00 1.00 1.00 1.00 Copy 500x500 from pixmap to pixmap
- 51.57 1.92 1.00 1.00 85.75 Copy 10x10 1-bit deep plane
- 6.37 1.75 1.01 1.01 6.37 Copy 100x100 1-bit deep plane
- 1.26 1.11 1.00 1.00 1.24 Copy 500x500 1-bit deep plane
- 4.23 1.63 0.98 0.97 4.38 Copy 10x10 n-bit deep plane
- 1.04 1.02 1.00 1.00 1.04 Copy 100x100 n-bit deep plane
- 1.00 1.00 1.00 1.00 1.00 Copy 500x500 n-bit deep plane
- 6.45 1.98 1.00 1.26 12.80 PutImage 10x10 square
- 1.10 1.87 1.00 1.83 2.11 PutImage 100x100 square
- 1.02 1.93 1.00 1.91 1.91 PutImage 500x500 square
- 4.17 1.78 1.00 1.40 7.18 PutImage XY 10x10 square
- 1.27 1.49 0.97 1.48 2.10 PutImage XY 100x100 square
- 1.00 1.50 1.00 1.50 1.52 PutImage XY 500x500 square
- 1.07 1.01 1.00 1.00 1.06 GetImage 10x10 square
- 1.01 1.00 1.00 1.00 1.01 GetImage 100x100 square
- 1.00 1.00 1.00 1.00 1.00 GetImage 500x500 square
- 1.56 1.00 0.99 0.97 1.56 GetImage XY 10x10 square
- 1.02 1.00 1.00 1.00 1.02 GetImage XY 100x100 square
- 1.00 1.00 1.00 1.00 1.00 GetImage XY 500x500 square
- 1.00 1.00 1.01 0.98 0.95 X protocol NoOperation
- 1.02 1.03 1.04 1.03 1.00 QueryPointer
- 1.03 1.02 1.04 1.03 1.00 GetProperty
-100.41 1.51 1.00 1.00 198.76 Change graphics context
- 45.81 1.00 0.99 0.97 57.10 Create and map subwindows (4 kids)
- 78.45 1.01 1.02 1.02 63.07 Create and map subwindows (16 kids)
- 73.91 1.01 1.00 1.00 56.37 Create and map subwindows (25 kids)
- 73.22 1.00 1.00 1.00 49.07 Create and map subwindows (50 kids)
- 72.36 1.01 0.99 1.00 32.14 Create and map subwindows (75 kids)
- 70.34 1.00 1.00 1.00 30.12 Create and map subwindows (100 kids)
- 55.00 1.00 1.00 0.99 23.75 Create and map subwindows (200 kids)
- 55.30 1.01 1.00 1.00 141.03 Create unmapped window (4 kids)
- 55.38 1.01 1.01 1.00 163.25 Create unmapped window (16 kids)
- 54.75 0.96 1.00 0.99 166.95 Create unmapped window (25 kids)
- 54.83 1.00 1.00 0.99 178.81 Create unmapped window (50 kids)
- 55.38 1.01 1.01 1.00 181.20 Create unmapped window (75 kids)
- 55.38 1.01 1.01 1.00 181.20 Create unmapped window (100 kids)
- 54.87 1.01 1.01 1.00 182.05 Create unmapped window (200 kids)
- 28.13 1.00 1.00 1.00 30.75 Map window via parent (4 kids)
- 36.14 1.01 1.01 1.01 32.58 Map window via parent (16 kids)
- 26.13 1.00 0.98 0.95 29.85 Map window via parent (25 kids)
- 40.07 1.00 1.01 1.00 27.57 Map window via parent (50 kids)
- 23.26 0.99 1.00 1.00 18.23 Map window via parent (75 kids)
- 22.91 0.99 1.00 0.99 16.52 Map window via parent (100 kids)
- 27.79 1.00 1.00 0.99 12.50 Map window via parent (200 kids)
- 22.35 1.00 1.00 1.00 56.19 Unmap window via parent (4 kids)
- 9.57 1.00 0.99 1.00 89.78 Unmap window via parent (16 kids)
- 80.77 1.01 1.00 1.00 103.85 Unmap window via parent (25 kids)
- 96.34 1.00 1.00 1.00 116.06 Unmap window via parent (50 kids)
- 99.72 1.00 1.00 1.00 124.93 Unmap window via parent (75 kids)
-112.36 1.00 1.00 1.00 125.27 Unmap window via parent (100 kids)
-105.41 1.00 1.00 0.99 120.00 Unmap window via parent (200 kids)
- 51.29 1.03 1.02 1.02 74.19 Destroy window via parent (4 kids)
- 86.75 0.99 0.99 0.99 116.87 Destroy window via parent (16 kids)
-106.43 1.01 1.01 1.01 127.49 Destroy window via parent (25 kids)
-120.34 1.01 1.01 1.00 140.11 Destroy window via parent (50 kids)
-126.67 1.00 0.99 0.99 145.00 Destroy window via parent (75 kids)
-126.11 1.01 1.01 1.00 140.56 Destroy window via parent (100 kids)
-128.57 1.01 1.00 1.00 137.91 Destroy window via parent (200 kids)
- 16.04 0.88 1.00 1.00 20.36 Hide/expose window via popup (4 kids)
- 19.04 1.01 1.00 1.00 23.48 Hide/expose window via popup (16 kids)
- 19.22 1.00 1.00 1.00 20.44 Hide/expose window via popup (25 kids)
- 17.41 1.00 0.91 0.97 17.68 Hide/expose window via popup (50 kids)
- 17.29 1.01 1.00 1.01 17.07 Hide/expose window via popup (75 kids)
- 16.74 1.00 1.00 1.00 16.17 Hide/expose window via popup (100 kids)
- 10.30 1.00 1.00 1.00 10.51 Hide/expose window via popup (200 kids)
- 16.48 1.01 1.00 1.00 26.05 Move window (4 kids)
- 17.01 0.95 1.00 1.00 23.97 Move window (16 kids)
- 16.95 1.00 1.00 1.00 22.90 Move window (25 kids)
- 16.05 1.01 1.00 1.00 21.32 Move window (50 kids)
- 15.58 1.00 0.98 0.98 19.44 Move window (75 kids)
- 14.98 1.02 1.03 1.03 18.17 Move window (100 kids)
- 10.90 1.01 1.01 1.00 12.68 Move window (200 kids)
- 49.42 1.00 1.00 1.00 198.27 Moved unmapped window (4 kids)
- 50.72 0.97 1.00 1.00 193.66 Moved unmapped window (16 kids)
- 50.87 1.00 0.99 1.00 195.09 Moved unmapped window (25 kids)
- 50.72 1.00 1.00 1.00 189.34 Moved unmapped window (50 kids)
- 50.87 1.00 1.00 1.00 191.33 Moved unmapped window (75 kids)
- 50.87 1.00 1.00 0.90 186.71 Moved unmapped window (100 kids)
- 50.87 1.00 1.00 1.00 179.19 Moved unmapped window (200 kids)
- 41.04 1.00 1.00 1.00 56.61 Move window via parent (4 kids)
- 69.81 1.00 1.00 1.00 130.82 Move window via parent (16 kids)
- 95.81 1.00 1.00 1.00 141.92 Move window via parent (25 kids)
- 95.98 1.00 1.00 1.00 149.43 Move window via parent (50 kids)
- 96.59 1.01 1.01 1.00 153.98 Move window via parent (75 kids)
- 97.19 1.00 1.00 1.00 157.30 Move window via parent (100 kids)
- 96.67 1.00 0.99 0.96 159.44 Move window via parent (200 kids)
- 17.75 1.01 1.00 1.00 27.61 Resize window (4 kids)
- 17.94 1.00 1.00 0.99 25.42 Resize window (16 kids)
- 17.92 1.01 1.00 1.00 24.47 Resize window (25 kids)
- 17.24 0.97 1.00 1.00 24.14 Resize window (50 kids)
- 16.81 1.00 1.00 0.99 22.75 Resize window (75 kids)
- 16.08 1.00 1.00 1.00 21.20 Resize window (100 kids)
- 12.92 1.00 0.99 1.00 16.26 Resize window (200 kids)
- 52.94 1.01 1.00 1.00 327.12 Resize unmapped window (4 kids)
- 53.60 1.01 1.01 1.01 333.71 Resize unmapped window (16 kids)
- 52.99 1.00 1.00 1.00 337.29 Resize unmapped window (25 kids)
- 51.98 1.00 1.00 1.00 329.38 Resize unmapped window (50 kids)
- 53.05 0.89 1.00 1.00 322.60 Resize unmapped window (75 kids)
- 53.05 1.00 1.00 1.00 318.08 Resize unmapped window (100 kids)
- 53.11 1.00 1.00 0.99 306.21 Resize unmapped window (200 kids)
- 16.76 1.00 0.96 1.00 19.46 Circulate window (4 kids)
- 17.24 1.00 1.00 0.97 16.24 Circulate window (16 kids)
- 16.30 1.03 1.03 1.03 15.85 Circulate window (25 kids)
- 13.45 1.00 1.00 1.00 14.90 Circulate window (50 kids)
- 12.91 1.00 1.00 1.00 13.06 Circulate window (75 kids)
- 11.30 0.98 1.00 1.00 11.03 Circulate window (100 kids)
- 7.58 1.01 1.01 0.99 7.47 Circulate window (200 kids)
- 1.01 1.01 0.98 1.00 0.95 Circulate Unmapped window (4 kids)
- 1.07 1.07 1.01 1.07 1.02 Circulate Unmapped window (16 kids)
- 1.04 1.09 1.06 1.05 0.97 Circulate Unmapped window (25 kids)
- 1.04 1.23 1.20 1.18 1.05 Circulate Unmapped window (50 kids)
- 1.18 1.53 1.19 1.45 1.24 Circulate Unmapped window (75 kids)
- 1.08 1.02 1.01 1.74 1.01 Circulate Unmapped window (100 kids)
- 1.01 1.12 0.98 0.91 0.97 Circulate Unmapped window (200 kids)
- </verb>
-
-<sect2>Profiling with OProfile
-
-<p>OProfile (available from http://oprofile.sourceforge.net/) is a
-system-wide profiler for Linux systems that uses processor-level
-counters to collect sampling data. OProfile can provide information
-that is similar to that provided by <tt/gprof/, but without the
-necessity of recompiling the program with special instrumentation (i.e.,
-OProfile can collect statistical profiling information about optimized
-programs). A test harness was developed to collect OProfile data for
-each <tt/x11perf/ test individually.
-
-<p>Test runs were performed using the RETIRED_INSNS counter on the AMD
-Athlon and the CPU_CLK_HALTED counter on the Intel Pentium III (with a
-test configuration different from the one described above). We have
-examined OProfile output and have compared it with <tt/gprof/ output.
-This investigation has not produced results that yield performance
-increases in <tt/x11perf/ numbers.
-
-<!--
-<sect3>Retired Instructions
-
-<p>The initial tests using OProfile were done using the RETIRED_INSNS
-counter with DMX running on the dual-processor AMD Athlon machine - the
-same test configuration that was described above and that was used for
-other tests. The RETIRED_INSNS counter counts retired instructions and
-showed drawing, text, copying, and image tests to be dominated (&gt;
-30%) by calls to Hash(), SecurityLookupIDByClass(),
-SecurityLookupIDByType(), and StandardReadRequestFromClient(). Some of
-these tests also executed significant instructions in
-WaitForSomething().
-
-<p>In contrast, the window tests executed significant
-instructions in SecurityLookupIDByType(), Hash(),
-StandardReadRequestFromClient(), but also executed significant
-instructions in other routines, such as ConfigureWindow(). Some time
-was spent looking at Hash() function, but optimizations in this routine
-did not lead to a dramatic increase in <tt/x11perf/ performance.
--->
-
-<!--
-<sect3>Clock Cycles
-
-<p>Retired instructions can be misleading because Intel/AMD instructions
-execute in variable amounts of time. The OProfile tests were repeated
-using the Intel CPU_CLK_HALTED counter with DMX running on the second
-back-end machine. Note that this is a different test configuration that
-the one described above. However, these tests show the amount of time
-(as measured in CPU cycles) that are spent in each routine. Because
-<tt/x11perf/ was running on the first back-end machine and because
-window optimizations were on, the load on the second back-end machine
-was not significant.
-
-<p>Using CPU_CLK_HALTED, DMX showed simple drawing
-tests spending more than 10% of their time in
-StandardReadRequestFromClient(), with significant time (&gt; 20% total)
-spent in SecurityLookupIDByClass(), WaitForSomething(), and Dispatch().
-For these tests, &lt; 5% of the time was spent in Hash(), which explains
-why optimizing the Hash() routine did not impact <tt/x11perf/ results.
-
-<p>The trapezoid, text, scrolling, copying, and image tests were
-dominated by time in ProcFillPoly(), PanoramiXFillPoly(), dmxFillPolygon(),
-SecurityLookupIDByClass(), SecurityLookupIDByType(), and
-StandardReadRequestFromClient(). Hash() time was generally above 5% but
-less than 10% of total time.
--->
-
-<sect2>X Test Suite
-
-<p>The X Test Suite was run on the fully optimized DMX server using the
-configuration described above. The following failures were noted:
- <verb>
-XListPixmapFormats: Test 1 [1]
-XChangeWindowAttributes: Test 32 [1]
-XCreateWindow: Test 30 [1]
-XFreeColors: Test 4 [3]
-XCopyArea: Test 13, 17, 21, 25, 30 [2]
-XCopyPlane: Test 11, 15, 27, 31 [2]
-XSetFontPath: Test 4 [1]
-XChangeKeyboardControl: Test 9, 10 [1]
-
-[1] Previously documented errors expected from the Xinerama
- implementation (see Phase I discussion).
-[2] Newly noted errors that have been verified as expected
- behavior of the Xinerama implementation.
-[3] Newly noted error that has been verified as a Xinerama
- implementation bug.
- </verb>
-
-<!-- ============================================================ -->
-<sect1>Phase III
-
-<p>During the third phase of development, support was provided for the
-following extensions: SHAPE, RENDER, XKEYBOARD, XInput.
-
-<sect2>SHAPE
-
-<p>The SHAPE extension is supported. Test applications (e.g., xeyes and
-oclock) and window managers that make use of the SHAPE extension will
-work as expected.
-
-<sect2>RENDER
-
-<p>The RENDER extension is supported. The version included in the DMX
-CVS tree is version 0.2, and this version is fully supported by Xdmx.
-Applications using only version 0.2 functions will work correctly;
-however, some apps that make use of functions from later versions do not
-properly check the extension's major/minor version numbers. These apps
-will fail with a Bad Implementation error when using post-version 0.2
-functions. This is expected behavior. When the DMX CVS tree is updated
-to include newer versions of RENDER, support for these newer functions
-will be added to the DMX X server.
-
-<sect2>XKEYBOARD
-
-<p>The XKEYBOARD extension is supported. If present on the back-end X
-servers, the XKEYBOARD extension will be used to obtain information
-about the type of the keyboard for initialization. Otherwise, the
-keyboard will be initialized using defaults. Note that this departs
-from older behavior: when Xdmx is compiled without XKEYBOARD support,
-the map from the back-end X server will be preserved. With XKEYBOARD
-support, the map is not preserved because better information and control
-of the keyboard is available.
-
-<sect2>XInput
-
-<p>The XInput extension is supported. Any device can be used as a core
-device and be used as an XInput extension device, with the exception of
-core devices on the back-end servers. This limitation is present
-because cursor handling on the back-end requires that the back-end
-cursor sometimes track the Xdmx core cursor -- behavior that is
-incompatible with using the back-end pointer as a non-core device.
-
-<p>Currently, back-end extension devices are not available as Xdmx
-extension devices, but this limitation should be removed in the future.
-
-<p>To demonstrate the XInput extension, and to provide more examples for
-low-level input device driver writers, USB device drivers have been
-written for mice (usb-mou), keyboards (usb-kbd), and
-non-mouse/non-keyboard USB devices (usb-oth). Please see the man page
-for information on Linux kernel drivers that are required for using
-these Xdmx drivers.
-
-<sect2>DPMS
-
-<p>The DPMS extension is exported but does not do anything at this time.
-
-<sect2>Other Extensions
-
-<p>The LBX,
- SECURITY,
- XC-APPGROUP, and
- XFree86-Bigfont
-extensions do not require any special Xdmx support and have been exported.
-
-<p>The
- BIG-REQUESTS,
- DEC-XTRAP,
- DOUBLE-BUFFER,
- Extended-Visual-Information,
- FontCache,
- GLX,
- MIT-SCREEN-SAVER,
- MIT-SHM,
- MIT-SUNDRY-NONSTANDARD,
- RECORD,
- SECURITY,
- SGI-GLX,
- SYNC,
- TOG-CUP,
- X-Resource,
- XC-MISC,
- XFree86-DGA,
- XFree86-DRI,
- XFree86-Misc,
- XFree86-VidModeExtension, and
- XVideo
-extensions are <it/not/ supported at this time, but will be evaluated
-for inclusion in future DMX releases. <bf>See below for additional work
-on extensions after Phase III.</bf>
-
-<sect1>Phase IV
-
-<sect2>Moving to XFree86 4.3.0
-
-<p>For Phase IV, the recent release of XFree86 4.3.0 (27 February 2003)
-was merged onto the dmx.sourceforge.net CVS trunk and all work is
-proceeding using this tree.
-
-<sect2>Extensions
-
-<sect3>XC-MISC (supported)
-
-<p>XC-MISC is used internally by the X library to recycle XIDs from the
-X server. This is important for long-running X server sessions. Xdmx
-supports this extension. The X Test Suite passed and failed the exact
-same tests before and after this extension was enabled.
-<!-- Tested February/March 2003 -->
-
-<sect3>Extended-Visual-Information (supported)
-
-<p>The Extended-Visual-Information extension provides a method for an X
-client to obtain detailed visual information. Xdmx supports this
-extension. It was tested using the <tt>hw/dmx/examples/evi</tt> example
-program. <bf/Note that this extension is not Xinerama-aware/ -- it will
-return visual information for each screen even though Xinerama is
-causing the X server to export a single logical screen.
-<!-- Tested March 2003 -->
-
-<sect3>RES (supported)
-
-<p>The X-Resource extension provides a mechanism for a client to obtain
-detailed information about the resources used by other clients. This
-extension was tested with the <tt>hw/dmx/examples/res</tt> program. The
-X Test Suite passed and failed the exact same tests before and after
-this extension was enabled.
-<!-- Tested March 2003 -->
-
-<sect3>BIG-REQUESTS (supported)
-
-<p>This extension enables the X11 protocol to handle requests longer
-than 262140 bytes. The X Test Suite passed and failed the exact same
-tests before and after this extension was enabled.
-<!-- Tested March 2003 -->
-
-<sect3>XSYNC (supported)
-
-<p>This extension provides facilities for two different X clients to
-synchronize their requests. This extension was minimally tested with
-<tt/xdpyinfo/ and the X Test Suite passed and failed the exact same
-tests before and after this extension was enabled.
-<!-- Tested March 2003 -->
-
-<sect3>XTEST, RECORD, DEC-XTRAP (supported) and XTestExtension1 (not supported)
-
-<p>The XTEST and RECORD extension were developed by the X Consortium for
-use in the X Test Suite and are supported as a standard in the X11R6
-tree. They are also supported in Xdmx. When X Test Suite tests that
-make use of the XTEST extension are run, Xdmx passes and fails exactly
-the same tests as does a standard XFree86 X server. When the
-<tt/rcrdtest/ test (a part of the X Test Suite that verifies the RECORD
-extension) is run, Xdmx passes and fails exactly the same tests as does
-a standard XFree86 X server. <!-- Tested February/March 2003 -->
-
-<p>There are two older XTEST-like extensions: DEC-XTRAP and
-XTestExtension1. The XTestExtension1 extension was developed for use by
-the X Testing Consortium for use with a test suite that eventually
-became (part of?) the X Test Suite. Unlike XTEST, which only allows
-events to be sent to the server, the XTestExtension1 extension also
-allowed events to be recorded (similar to the RECORD extension). The
-second is the DEC-XTRAP extension that was developed by the Digital
-Equipment Corporation.
-
-<p>The DEC-XTRAP extension is available from Xdmx and has been tested
-with the <tt/xtrap*/ tools which are distributed as standard X11R6
-clients. <!-- Tested March 2003 -->
-
-<p>The XTestExtension1 is <em/not/ supported because it does not appear
-to be used by any modern X clients (the few that support it also support
-XTEST) and because there are no good methods available for testing that
-it functions correctly (unlike XTEST and DEC-XTRAP, the code for
-XTestExtension1 is not part of the standard X server source tree, so
-additional testing is important). <!-- Tested March 2003 -->
-
-<p>Most of these extensions are documented in the X11R6 source tree.
-Further, several original papers exist that this author was unable to
-locate -- for completeness and historical interest, citations are
-provide:
-<descrip>
-<tag/XRECORD/ Martha Zimet. Extending X For Recording. 8th Annual X
-Technical Conference Boston, MA January 24-26, 1994.
-<tag/DEC-XTRAP/ Dick Annicchiarico, Robert Chesler, Alan Jamison. XTrap
-Architecture. Digital Equipment Corporation, July 1991.
-<tag/XTestExtension1/ Larry Woestman. X11 Input Synthesis Extension
-Proposal. Hewlett Packard, November 1991.
-</descrip>
-
-<sect3>MIT-MISC (not supported)
-
-<p>The MIT-MISC extension is used to control a bug-compatibility flag
-that provides compatibility with xterm programs from X11R1 and X11R2.
-There does not appear to be a single client available that makes use of
-this extension and there is not way to verify that it works correctly.
-The Xdmx server does <em/not/ support MIT-MISC.
-
-<sect3>SCREENSAVER (not supported)
-
-<p>This extension provides special support for the X screen saver. It
-was tested with beforelight, which appears to be the only client that
-works with it. When Xinerama was not active, <tt/beforelight/ behaved
-as expected. However, when Xinerama was active, <tt/beforelight/ did
-not behave as expected. Further, when this extension is not active,
-<tt/xscreensaver/ (a widely-used X screen saver program) did not behave
-as expected. Since this extension is not Xinerama-aware and is not
-commonly used with expected results by clients, we have left this
-extension disabled at this time.
-
-<sect3>GLX (supported)
-
-<p>The GLX extension provides OpenGL and GLX windowing support. In
-Xdmx, the extension is called glxProxy, and it is Xinerama aware. It
-works by either feeding requests forward through Xdmx to each of the
-back-end servers or handling them locally. All rendering requests are
-handled on the back-end X servers. This code was donated to the DMX
-project by SGI. For the X Test Suite results comparison, see below.
-
-<sect3>RENDER (supported)
-
-<p>The X Rendering Extension (RENDER) provides support for digital image
-composition. Geometric and text rendering are supported. RENDER is
-partially Xinerama-aware, with text and the most basic compositing
-operator; however, its higher level primitives (triangles, triangle
-strips, and triangle fans) are not yet Xinerama-aware. The RENDER
-extension is still under development, and is currently at version 0.8.
-Additional support will be required in DMX as more primitives and/or
-requests are added to the extension.
-
-<p>There is currently no test suite for the X Rendering Extension;
-however, there has been discussion of developing a test suite as the
-extension matures. When that test suite becomes available, additional
-testing can be performed with Xdmx. The X Test Suite passed and failed
-the exact same tests before and after this extension was enabled.
-
-<sect3>Summary
-
-<!-- WARNING: this list is duplicated in the "Common X extension
-support" section -->
-<p>To summarize, the following extensions are currently supported:
- BIG-REQUESTS,
- DEC-XTRAP,
- DMX,
- DPMS,
- Extended-Visual-Information,
- GLX,
- LBX,
- RECORD,
- RENDER,
- SECURITY,
- SHAPE,
- SYNC,
- X-Resource,
- XC-APPGROUP,
- XC-MISC,
- XFree86-Bigfont,
- XINERAMA,
- XInputExtension,
- XKEYBOARD, and
- XTEST.
-
-<p>The following extensions are <em/not/ supported at this time:
- DOUBLE-BUFFER,
- FontCache,
- MIT-SCREEN-SAVER,
- MIT-SHM,
- MIT-SUNDRY-NONSTANDARD,
- TOG-CUP,
- XFree86-DGA,
- XFree86-Misc,
- XFree86-VidModeExtension,
- XTestExtensionExt1, and
- XVideo.
-
-<sect2>Additional Testing with the X Test Suite
-
-<sect3>XFree86 without XTEST
-
-<p>After the release of XFree86 4.3.0, we retested the XFree86 X server
-with and without using the XTEST extension. When the XTEST extension
-was <em/not/ used for testing, the XFree86 4.3.0 server running on our
-usual test system with a Radeon VE card reported unexpected failures in
-the following tests:
-<verb>
-XListPixmapFormats: Test 1
-XChangeKeyboardControl: Tests 9, 10
-XGetDefault: Test 5
-XRebindKeysym: Test 1
-</verb>
-
-<sect3>XFree86 with XTEST
-
-<p>When using the XTEST extension, the XFree86 4.3.0 server reported the
-following errors:
-<verb>
-XListPixmapFormats: Test 1
-XChangeKeyboardControl: Tests 9, 10
-XGetDefault: Test 5
-XRebindKeysym: Test 1
-
-XAllowEvents: Tests 20, 21, 24
-XGrabButton: Tests 5, 9-12, 14, 16, 19, 21-25
-XGrabKey: Test 8
-XSetPointerMapping: Test 3
-XUngrabButton: Test 4
-</verb>
-
-<p>While these errors may be important, they will probably be fixed
-eventually in the XFree86 source tree. We are particularly interested
-in demonstrating that the Xdmx server does not introduce additional
-failures that are not known Xinerama failures.
-
-<sect3>Xdmx with XTEST, without Xinerama, without GLX
-
-<p>Without Xinerama, but using the XTEST extension, the following errors
-were reported from Xdmx (note that these are the same as for the XFree86
-4.3.0, except that XGetDefault no longer fails):
-<verb>
-XListPixmapFormats: Test 1
-XChangeKeyboardControl: Tests 9, 10
-XRebindKeysym: Test 1
-
-XAllowEvents: Tests 20, 21, 24
-XGrabButton: Tests 5, 9-12, 14, 16, 19, 21-25
-XGrabKey: Test 8
-XSetPointerMapping: Test 3
-XUngrabButton: Test 4
-</verb>
-
-<sect3>Xdmx with XTEST, with Xinerama, without GLX
-
-<p>With Xinerama, using the XTEST extension, the following errors
-were reported from Xdmx:
-<verb>
-XListPixmapFormats: Test 1
-XChangeKeyboardControl: Tests 9, 10
-XRebindKeysym: Test 1
-
-XAllowEvents: Tests 20, 21, 24
-XGrabButton: Tests 5, 9-12, 14, 16, 19, 21-25
-XGrabKey: Test 8
-XSetPointerMapping: Test 3
-XUngrabButton: Test 4
-
-XCopyPlane: Tests 13, 22, 31 (well-known XTEST/Xinerama interaction issue)
-XDrawLine: Test 67
-XDrawLines: Test 91
-XDrawSegments: Test 68
-</verb>
-Note that the first two sets of errors are the same as for the XFree86
-4.3.0 server, and that the XCopyPlane error is a well-known error
-resulting from an XTEST/Xinerama interaction when the request crosses a
-screen boundary. The XDraw* errors are resolved when the tests are run
-individually and they do not cross a screen boundary. We will
-investigate these errors further to determine their cause.
-
-<sect3>Xdmx with XTEST, with Xinerama, with GLX
-
-<p>With GLX enabled, using the XTEST extension, the following errors
-were reported from Xdmx (these results are from early during the Phase
-IV development, but were confirmed with a late Phase IV snapshot):
-<verb>
-XListPixmapFormats: Test 1
-XChangeKeyboardControl: Tests 9, 10
-XRebindKeysym: Test 1
-
-XAllowEvents: Tests 20, 21, 24
-XGrabButton: Tests 5, 9-12, 14, 16, 19, 21-25
-XGrabKey: Test 8
-XSetPointerMapping: Test 3
-XUngrabButton: Test 4
-
-XClearArea: Test 8
-XCopyArea: Tests 4, 5, 11, 14, 17, 23, 25, 27, 30
-XCopyPlane: Tests 6, 7, 10, 19, 22, 31
-XDrawArcs: Tests 89, 100, 102
-XDrawLine: Test 67
-XDrawSegments: Test 68
-</verb>
-Note that the first two sets of errors are the same as for the XFree86
-4.3.0 server, and that the third set has different failures than when
-Xdmx does not include GLX support. Since the GLX extension adds new
-visuals to support GLX's visual configs and the X Test Suite runs tests
-over the entire set of visuals, additional rendering tests were run and
-presumably more of them crossed a screen boundary. This conclusion is
-supported by the fact that nearly all of the rendering errors reported
-are resolved when the tests are run individually and they do no cross a
-screen boundary.
-
-<p>Further, when hardware rendering is disabled on the back-end displays,
-many of the errors in the third set are eliminated, leaving only:
-<verb>
-XClearArea: Test 8
-XCopyArea: Test 4, 5, 11, 14, 17, 23, 25, 27, 30
-XCopyPlane: Test 6, 7, 10, 19, 22, 31
-</verb>
-
-<sect3>Conclusion
-
-<p>We conclude that all of the X Test Suite errors reported for Xdmx are
-the result of errors in the back-end X server or the Xinerama
-implementation. Further, all of these errors that can be reasonably
-fixed at the Xdmx layer have been. (Where appropriate, we have
-submitted patches to the XFree86 and Xinerama upstream maintainers.)
-
-<sect2>Dynamic Reconfiguration
-
-<p>During this development phase, dynamic reconfiguration support was
-added to DMX. This support allows an application to change the position
-and offset of a back-end server's screen. For example, if the
-application would like to shift a screen slightly to the left, it could
-query Xdmx for the screen's &lt;x,y&gt; position and then dynamically
-reconfigure that screen to be at position &lt;x+10,y&gt;. When a screen
-is dynamically reconfigured, input handling and a screen's root window
-dimensions are adjusted as needed. These adjustments are transparent to
-the user.
-
-<sect3>Dynamic reconfiguration extension
-
-<p>The application interface to DMX's dynamic reconfiguration is through
-a function in the DMX extension library:
-<verb>
-Bool DMXReconfigureScreen(Display *dpy, int screen, int x, int y)
-</verb>
-where <it/dpy/ is DMX server's display, <it/screen/ is the number of the
-screen to be reconfigured, and <it/x/ and <it/y/ are the new upper,
-left-hand coordinates of the screen to be reconfigured.
-
-<p>The coordinates are not limited other than as required by the X
-protocol, which limits all coordinates to a signed 16 bit number. In
-addition, all coordinates within a screen must also be legal values.
-Therefore, setting a screen's upper, left-hand coordinates such that the
-right or bottom edges of the screen is greater than 32,767 is illegal.
-
-<sect3>Bounding box
-
-<p>When the Xdmx server is started, a bounding box is calculated from
-the screens' layout given either on the command line or in the
-configuration file. This bounding box is currently fixed for the
-lifetime of the Xdmx server.
-
-<p>While it is possible to move a screen outside of the bounding box, it
-is currently not possible to change the dimensions of the bounding box.
-For example, it is possible to specify coordinates of &lt;-100,-100&gt;
-for the upper, left-hand corner of the bounding box, which was
-previously at coordinates &lt;0,0&gt;. As expected, the screen is moved
-down and to the right; however, since the bounding box is fixed, the
-left side and upper portions of the screen exposed by the
-reconfiguration are no longer accessible on that screen. Those
-inaccessible regions are filled with black.
-
-<p>This fixed bounding box limitation will be addressed in a future
-development phase.
-
-<sect3>Sample applications
-
-<p>An example of where this extension is useful is in setting up a video
-wall. It is not always possible to get everything perfectly aligned,
-and sometimes the positions are changed (e.g., someone might bump into a
-projector). Instead of physically moving projectors or monitors, it is
-now possible to adjust the positions of the back-end server's screens
-using the dynamic reconfiguration support in DMX.
-
-<p>Other applications, such as automatic setup and calibration tools,
-can make use of dynamic reconfiguration to correct for projector
-alignment problems, as long as the projectors are still arranged
-rectilinearly. Horizontal and vertical keystone correction could be
-applied to projectors to correct for non-rectilinear alignment problems;
-however, this must be done external to Xdmx.
-
-<p>A sample test program is included in the DMX server's examples
-directory to demonstrate the interface and how an application might use
-dynamic reconfiguration. See <tt/dmxreconfig.c/ for details.
-
-<sect3>Additional notes
-
-<p>In the original development plan, Phase IV was primarily devoted to
-adding OpenGL support to DMX; however, SGI became interested in the DMX
-project and developed code to support OpenGL/GLX. This code was later
-donated to the DMX project and integrated into the DMX code base, which
-freed the DMX developers to concentrate on dynamic reconfiguration (as
-described above).
-
-<sect2>Doxygen documentation
-
-<p>Doxygen is an open-source (GPL) documentation system for generating
-browseable documentation from stylized comments in the source code. We
-have placed all of the Xdmx server and DMX protocol source code files
-under Doxygen so that comprehensive documentation for the Xdmx source
-code is available in an easily browseable format.
-
-<sect2>Valgrind
-
-<p>Valgrind, an open-source (GPL) memory debugger for Linux, was used to
-search for memory management errors. Several memory leaks were detected
-and repaired. The following errors were not addressed:
-<enum>
- <item>
- When the X11 transport layer sends a reply to the client, only
- those fields that are required by the protocol are filled in --
- unused fields are left as uninitialized memory and are therefore
- noted by valgrind. These instances are not errors and were not
- repaired.
- <item>
- At each server generation, glxInitVisuals allocates memory that
- is never freed. The amount of memory lost each generation
- approximately equal to 128 bytes for each back-end visual.
- Because the code involved is automatically generated, this bug
- has not been fixed and will be referred to SGI.
- <item>
- At each server generation, dmxRealizeFont calls XLoadQueryFont,
- which allocates a font structure that is not freed.
- dmxUnrealizeFont can free the font structure for the first
- screen, but cannot free it for the other screens since they are
- already closed by the time dmxUnrealizeFont could free them.
- The amount of memory lost each generation is approximately equal
- to 80 bytes per font per back-end. When this bug is fixed in
- the the X server's device-independent (dix) code, DMX will be
- able to properly free the memory allocated by XLoadQueryFont.
-</enum>
-
-<sect2>RATS
-
-<p>RATS (Rough Auditing Tool for Security) is an open-source (GPL)
-security analysis tool that scans source code for common
-security-related programming errors (e.g., buffer overflows and TOCTOU
-races). RATS was used to audit all of the code in the hw/dmx directory
-and all "High" notations were checked manually. The code was either
-re-written to eliminate the warning, or a comment containing "RATS" was
-inserted on the line to indicate that a human had checked the code.
-Unrepaired warnings are as follows:
-<enum>
- <item>
- Fixed-size buffers are used in many areas, but code has been
- added to protect against buffer overflows (e.g., XmuSnprint).
- The only instances that have not yet been fixed are in
- config/xdmxconfig.c (which is not part of the Xdmx server) and
- input/usb-common.c.
- <item>
- vprintf and vfprintf are used in the logging routines. In
- general, all uses of these functions (e.g., dmxLog) provide a
- constant format string from a trusted source, so the use is
- relatively benign.
- <item>
- glxProxy/glxscreens.c uses getenv and strcat. The use of these
- functions is safe and will remain safe as long as
- ExtensionsString is longer then GLXServerExtensions (ensuring
- this may not be ovious to the casual programmer, but this is in
- automatically generated code, so we hope that the generator
- enforces this constraint).
-</enum>
-
- </article>
-
- <!-- Local Variables: -->
- <!-- fill-column: 72 -->
- <!-- End: -->
+<!DOCTYPE linuxdoc PUBLIC "-//XFree86//DTD linuxdoc//EN">
+ <article>
+
+ <!-- Title information -->
+ <title>Distributed Multihead X design
+ <author>Kevin E. Martin, David H. Dawes, and Rickard E. Faith
+ <date>29 June 2004 (created 25 July 2001)
+ <abstract>
+ This document covers the motivation, background, design, and
+ implementation of the distributed multihead X (DMX) system. It
+ is a living document and describes the current design and
+ implementation details of the DMX system. As the project
+ progresses, this document will be continually updated to reflect
+ the changes in the code and/or design. <it>Copyright 2001 by VA
+ Linux Systems, Inc., Fremont, California. Copyright 2001-2004
+ by Red Hat, Inc., Raleigh, North Carolina</it>
+ </abstract>
+
+ <!-- Table of contents -->
+ <toc>
+
+<!-- Begin the document -->
+<sect>Introduction
+
+<sect1>The Distributed Multihead X Server
+
+<p>Current Open Source multihead solutions are limited to a single
+physical machine. A single X server controls multiple display devices,
+which can be arranged as independent heads or unified into a single
+desktop (with Xinerama). These solutions are limited to the number of
+physical devices that can co-exist in a single machine (e.g., due to the
+number of AGP/PCI slots available for graphics cards). Thus, large
+tiled displays are not currently possible. The work described in this
+paper will eliminate the requirement that the display devices reside in
+the same physical machine. This will be accomplished by developing a
+front-end proxy X server that will control multiple back-end X servers
+that make up the large display.
+
+<p>The overall structure of the distributed multihead X (DMX) project is
+as follows: A single front-end X server will act as a proxy to a set of
+back-end X servers, which handle all of the visible rendering. X
+clients will connect to the front-end server just as they normally would
+to a regular X server. The front-end server will present an abstracted
+view to the client of a single large display. This will ensure that all
+standard X clients will continue to operate without modification
+(limited, as always, by the visuals and extensions provided by the X
+server). Clients that are DMX-aware will be able to use an extension to
+obtain information about the back-end servers (e.g., for placement of
+pop-up windows, window alignments by the window manager, etc.).
+
+<p>The architecture of the DMX server is divided into two main sections:
+input (e.g., mouse and keyboard events) and output (e.g., rendering and
+windowing requests). Each of these are describe briefly below, and the
+rest of this design document will describe them in greater detail.
+
+<p>The DMX server can receive input from three general types of input
+devices: "local" devices that are physically attached to the machine on
+which DMX is running, "backend" devices that are physically attached to
+one or more of the back-end X servers (and that generate events via the
+X protocol stream from the backend), and "console" devices that can be
+abstracted from any non-back-end X server. Backend and console devices
+are treated differently because the pointer device on the back-end X
+server also controls the location of the hardware X cursor. Full
+support for XInput extension devices is provided.
+
+<p>Rendering requests will be accepted by the front-end server; however,
+rendering to visible windows will be broken down as needed and sent to
+the appropriate back-end server(s) via X11 library calls for actual
+rendering. The basic framework will follow a Xnest-style approach. GC
+state will be managed in the front-end server and sent to the
+appropriate back-end server(s) as required. Pixmap rendering will (at
+least initially) be handled by the front-end X server. Windowing
+requests (e.g., ordering, mapping, moving, etc.) will handled in the
+front-end server. If the request requires a visible change, the
+windowing operation will be translated into requests for the appropriate
+back-end server(s). Window state will be mirrored in the back-end
+server(s) as needed.
+
+<sect1>Layout of Paper
+
+<p>The next section describes the general development plan that was
+actually used for implementation. The final section discusses
+outstanding issues at the conclusion of development. The first appendix
+provides low-level technical detail that may be of interest to those
+intimately familiar with the X server architecture. The final appendix
+describes the four phases of development that were performed during the
+first two years of development.
+
+<p>The final year of work was divided into 9 tasks that are not
+described in specific sections of this document. The major tasks during
+that time were the enhancement of the reconfiguration ability added in
+Phase IV, addition of support for a dynamic number of back-end displays
+(instead of a hard-coded limit), and the support for back-end display
+and input removal and addition. This work is mentioned in this paper,
+but is not covered in detail.
+
+<!-- ============================================================ -->
+<sect>Development plan
+
+<p>This section describes the development plan from approximately June
+2001 through July 2003.
+
+<sect1>Bootstrap code
+
+<p>To allow for rapid development of the DMX server by multiple
+developers during the first development stage, the problem will be
+broken down into three tasks: the overall DMX framework, back-end
+rendering services and input device handling services. However, before
+the work begins on these tasks, a simple framework that each developer
+could use was implemented to bootstrap the development effort. This
+framework renders to a single back-end server and provides dummy input
+devices (i.e., the keyboard and mouse). The simple back-end rendering
+service was implemented using the shadow framebuffer support currently
+available in the XFree86 environment.
+
+<p>Using this bootstrapping framework, each developer has been able to
+work on each of the tasks listed above independently as follows: the
+framework will be extended to handle arbitrary back-end server
+configurations; the back-end rendering services will be transitioned to
+the more efficient Xnest-style implementation; and, an input device
+framework to handle various input devices via the input extension will
+be developed.
+
+<p>Status: The boot strap code is complete. <!-- August 2001 -->
+
+
+<sect1>Input device handling
+
+<p>An X server (including the front-end X server) requires two core
+input devices -- a keyboard and a pointer (mouse). These core devices
+are handled and required by the core X11 protocol. Additional types of
+input devices may be attached and utilized via the XInput extension.
+These are usually referred to as ``XInput extension devices'',
+
+<p>There are some options as to how the front-end X server gets its core
+input devices:
+
+<enum>
+ <item>Local Input. The physical input devices (e.g., keyboard and
+ mouse) can be attached directly to the front-end X server. In this
+ case, the keyboard and mouse on the machine running the front-end X
+ server will be used. The front-end will have drivers to read the
+ raw input from those devices and convert it into the required X
+ input events (e.g., key press/release, pointer button press/release,
+ pointer motion). The front-end keyboard driver will keep track of
+ keyboard properties such as key and modifier mappings, autorepeat
+ state, keyboard sound and led state. Similarly the front-end
+ pointer driver will keep track if pointer properties such as the
+ button mapping and movement acceleration parameters. With this
+ option, input is handled fully in the front-end X server, and the
+ back-end X servers are used in a display-only mode. This option was
+ implemented and works for a limited number of Linux-specific
+ devices. Adding additional local input devices for other
+ architectures is expected to be relatively simple.
+
+ <p>The following options are available for implementing local input
+ devices:
+
+ <enum>
+ <item>The XFree86 X server has modular input drivers that could
+ be adapted for this purpose. The mouse driver supports a wide
+ range of mouse types and interfaces, as well as a range of
+ Operating System platforms. The keyboard driver in XFree86 is
+ not currently as modular as the mouse driver, but could be made
+ so. The XFree86 X server also has a range of other input
+ drivers for extended input devices such as tablets and touch
+ screens. Unfortunately, the XFree86 drivers are generally
+ complex, often simultaneously providing support for multiple
+ devices across multiple architectures; and rely so heavily on
+ XFree86-specific helper-functions, that this option was not
+ pursued.
+
+
+ <item>The <tt/kdrive/ X server in XFree86 has built-in drivers that
+ support PS/2 mice and keyboard under Linux. The mouse driver
+ can indirectly handle other mouse types if the Linux utility
+ <tt/gpm/ is used as to translate the native mouse protocol into
+ PS/2 mouse format. These drivers could be adapted and built in
+ to the front-end X server if this range of hardware and OS
+ support is sufficient. While much simpler than the XFree86
+ drivers, the <tt/kdrive/ drivers were not used for the DMX
+ implementation.
+
+ <item>Reimplementation of keyboard and mouse drivers from
+ scratch for the DMX framework. Because keyboard and mouse
+ drivers are relatively trivial to implement, this pathway was
+ selected. Other drivers in the X source tree were referenced,
+ and significant contributions from other drivers are noted in
+ the DMX source code.
+ </enum>
+
+ <item>Backend Input. The front-end can make use of the core input
+ devices attached to one or more of the back-end X servers. Core
+ input events from multiple back-ends are merged into a single input
+ event stream. This can work sanely when only a single set of input
+ devices is used at any given time. The keyboard and pointer state
+ will be handled in the front-end, with changes propagated to the
+ back-end servers as needed. This option was implemented and works
+ well. Because the core pointer on a back-end controls the hardware
+ mouse on that back-end, core pointers cannot be treated as XInput
+ extension devices. However, all back-end XInput extensions devices
+ can be mapped to either DMX core or DMX XInput extension devices.
+
+ <item>Console Input. The front-end server could create a console
+ window that is displayed on an X server independent of the back-end
+ X servers. This console window could display things like the
+ physical screen layout, and the front-end could get its core input
+ events from events delivered to the console window. This option was
+ implemented and works well. To help the human navigate, window
+ outlines are also displayed in the console window. Further, console
+ windows can be used as either core or XInput extension devices.
+
+ <item>Other options were initially explored, but they were all
+ partial subsets of the options listed above and, hence, are
+ irrelevant.
+
+</enum>
+
+<p>Although extended input devices are not specifically mentioned in the
+Distributed X requirements, the options above were all implemented so
+that XInput extension devices were supported.
+
+<p>The bootstrap code (Xdmx) had dummy input devices, and these are
+still supported in the final version. These do the necessary
+initialization to satisfy the X server's requirements for core pointer
+and keyboard devices, but no input events are ever generated.
+
+<p>Status: The input code is complete. Because of the complexity of the
+XFree86 input device drivers (and their heavy reliance on XFree86
+infrastructure), separate low-level device drivers were implemented for
+Xdmx. The following kinds of drivers are supported (in general, the
+devices can be treated arbitrarily as "core" input devices or as XInput
+"extension" devices; and multiple instances of different kinds of
+devices can be simultaneously available):
+ <enum>
+ <item> A "dummy" device drive that never generates events.
+
+ <item> "Local" input is from the low-level hardware on which the
+ Xdmx binary is running. This is the only area where using the
+ XFree86 driver infrastructure would have been helpful, and then
+ only partially, since good support for generic USB devices does
+ not yet exist in XFree86 (in any case, XFree86 and kdrive driver
+ code was used where possible). Currently, the following local
+ devices are supported under Linux (porting to other operating
+ systems should be fairly straightforward):
+ <itemize>
+ <item>Linux keyboard
+ <item>Linux serial mouse (MS)
+ <item>Linux PS/2 mouse
+ <item>USB keyboard
+ <item>USB mouse
+ <item>USB generic device (e.g., joystick, gamepad, etc.)
+ </itemize>
+
+ <item> "Backend" input is taken from one or more of the back-end
+ displays. In this case, events are taken from the back-end X
+ server and are converted to Xdmx events. Care must be taken so
+ that the sprite moves properly on the display from which input
+ is being taken.
+
+ <item> "Console" input is taken from an X window that Xdmx
+ creates on the operator's display (i.e., on the machine running
+ the Xdmx binary). When the operator's mouse is inside the
+ console window, then those events are converted to Xdmx events.
+ Several special features are available: the console can display
+ outlines of windows that are on the Xdmx display (to facilitate
+ navigation), the cursor can be confined to the console, and a
+ "fine" mode can be activated to allow very precise cursor
+ positioning.
+ </enum>
+
+
+<!-- May 2002; July 2003 -->
+
+<sect1>Output device handling
+
+<p>The output of the DMX system displays rendering and windowing
+requests across multiple screens. The screens are typically arranged in
+a grid such that together they represent a single large display.
+
+<p>The output section of the DMX code consists of two parts. The first
+is in the front-end proxy X server (Xdmx), which accepts client
+connections, manages the windows, and potentially renders primitives but
+does not actually display any of the drawing primitives. The second
+part is the back-end X server(s), which accept commands from the
+front-end server and display the results on their screens.
+
+<sect2>Initialization
+
+<p>The DMX front-end must first initialize its screens by connecting to
+each of the back-end X servers and collecting information about each of
+these screens. However, the information collected from the back-end X
+servers might be inconsistent. Handling these cases can be difficult
+and/or inefficient. For example, a two screen system has one back-end X
+server running at 16bpp while the second is running at 32bpp.
+Converting rendering requests (e.g., XPutImage() or XGetImage()
+requests) to the appropriate bit depth can be very time consuming.
+Analyzing these cases to determine how or even if it is possible to
+handle them is required. The current Xinerama code handles many of
+these cases (e.g., in PanoramiXConsolidate()) and will be used as a
+starting point. In general, the best solution is to use homogeneous X
+servers and display devices. Using back-end servers with the same depth
+is a requirement of the final DMX implementation.
+
+<p>Once this screen consolidation is finished, the relative position of
+each back-end X server's screen in the unified screen is initialized. A
+full-screen window is opened on each of the back-end X servers, and the
+cursor on each screen is turned off. The final DMX implementation can
+also make use of a partial-screen window, or multiple windows per
+back-end screen.
+
+<sect2>Handling rendering requests
+
+<p>After initialization, X applications connect to the front-end server.
+There are two possible implementations of how rendering and windowing
+requests are handled in the DMX system:
+
+<enum>
+ <item>A shadow framebuffer is used in the front-end server as the
+ render target. In this option, all protocol requests are completely
+ handled in the front-end server. All state and resources are
+ maintained in the front-end including a shadow copy of the entire
+ framebuffer. The framebuffers attached to the back-end servers are
+ updated by XPutImage() calls with data taken directly from the
+ shadow framebuffer.
+
+ <p>This solution suffers from two main problems. First, it does not
+ take advantage of any accelerated hardware available in the system.
+ Second, the size of the XPutImage() calls can be quite large and
+ thus will be limited by the bandwidth available.
+
+ <p>The initial DMX implementation used a shadow framebuffer by
+ default.
+
+ <item>Rendering requests are sent to each back-end server for
+ handling (as is done in the Xnest server described above). In this
+ option, certain protocol requests are handled in the front-end
+ server and certain requests are repackaged and then sent to the
+ back-end servers. The framebuffer is distributed across the
+ multiple back-end servers. Rendering to the framebuffer is handled
+ on each back-end and can take advantage of any acceleration
+ available on the back-end servers' graphics display device. State
+ is maintained both in the front and back-end servers.
+
+ <p>This solution suffers from two main drawbacks. First, protocol
+ requests are sent to all back-end servers -- even those that will
+ completely clip the rendering primitive -- which wastes bandwidth
+ and processing time. Second, state is maintained both in the front-
+ and back-end servers. These drawbacks are not as severe as in
+ option 1 (above) and can either be overcome through optimizations or
+ are acceptable. Therefore, this option will be used in the final
+ implementation.
+
+ <p>The final DMX implementation defaults to this mechanism, but also
+ supports the shadow framebuffer mechanism. Several optimizations
+ were implemented to eliminate the drawbacks of the default
+ mechanism. These optimizations are described the section below and
+ in Phase II of the Development Results (see appendix).
+
+</enum>
+
+<p>Status: Both the shadow framebuffer and Xnest-style code is complete.
+<!-- May 2002 -->
+
+
+<sect1>Optimizing DMX
+
+<p>Initially, the Xnest-style solution's performance will be measured
+and analyzed to determine where the performance bottlenecks exist.
+There are four main areas that will be addressed.
+
+<p>First, to obtain reasonable interactivity with the first development
+phase, XSync() was called after each protocol request. The XSync()
+function flushes any pending protocol requests. It then waits for the
+back-end to process the request and send a reply that the request has
+completed. This happens with each back-end server and performance
+greatly suffers. As a result of the way XSync() is called in the first
+development phase, the batching that the X11 library performs is
+effectively defeated. The XSync() call usage will be analyzed and
+optimized by batching calls and performing them at regular intervals,
+except where interactivity will suffer (e.g., on cursor movements).
+
+<p>Second, the initial Xnest-style solution described above sends the
+repackaged protocol requests to all back-end servers regardless of
+whether or not they would be completely clipped out. The requests that
+are trivially rejected on the back-end server wastes the limited
+bandwidth available. By tracking clipping changes in the DMX X server's
+windowing code (e.g., by opening, closing, moving or resizing windows),
+we can determine whether or not back-end windows are visible so that
+trivial tests in the front-end server's GC ops drawing functions can
+eliminate these unnecessary protocol requests.
+
+<p>Third, each protocol request will be analyzed to determine if it is
+possible to break the request into smaller pieces at display boundaries.
+The initial ones to be analyzed are put and get image requests since
+they will require the greatest bandwidth to transmit data between the
+front and back-end servers. Other protocol requests will be analyzed
+and those that will benefit from breaking them into smaller requests
+will be implemented.
+
+<p>Fourth, an extension is being considered that will allow font glyphs to
+be transferred from the front-end DMX X server to each back-end server.
+This extension will permit the front-end to handle all font requests and
+eliminate the requirement that all back-end X servers share the exact
+same fonts as the front-end server. We are investigating the
+feasibility of this extension during this development phase.
+
+<p>Other potential optimizations will be determined from the performance
+analysis.
+
+<p>Please note that in our initial design, we proposed optimizing BLT
+operations (e.g., XCopyArea() and window moves) by developing an
+extension that would allow individual back-end servers to directly copy
+pixel data to other back-end servers. This potential optimization was
+in response to the simple image movement implementation that required
+potentially many calls to GetImage() and PutImage(). However, the
+current Xinerama implementation handles these BLT operations
+differently. Instead of copying data to and from screens, they generate
+expose events -- just as happens in the case when a window is moved from
+off a screen to on screen. This approach saves the limited bandwidth
+available between front and back-end servers and is being standardized
+with Xinerama. It also eliminates the potential setup problems and
+security issues resulting from having each back-end server open
+connections to all other back-end servers. Therefore, we suggest
+accepting Xinerama's expose event solution.
+
+<p>Also note that the approach proposed in the second and third
+optimizations might cause backing store algorithms in the back-end to be
+defeated, so a DMX X server configuration flag will be added to disable
+these optimizations.
+
+<p>Status: The optimizations proposed above are complete. It was
+determined that the using the xfs font server was sufficient and
+creating a new mechanism to pass glyphs was redundant; therefore, the
+fourth optimization proposed above was not included in DMX.
+<!-- September 2002 -->
+
+
+<sect1>DMX X extension support
+
+<p>The DMX X server keeps track of all the windowing information on the
+back-end X servers, but does not currently export this information to
+any client applications. An extension will be developed to pass the
+screen information and back-end window IDs to DMX-aware clients. These
+clients can then use this information to directly connect to and render
+to the back-end windows. Bypassing the DMX X server allows DMX-aware
+clients to break up complex rendering requests on their own and send
+them directly to the windows on the back-end server's screens. An
+example of a client that can make effective use of this extension is
+Chromium.
+
+<p>Status: The extension, as implemented, is fully documented in
+"Client-to-Server DMX Extension to the X Protocol". Future changes
+might be required based on feedback and other proposed enhancements to
+DMX. Currently, the following facilities are supported:
+<enum>
+ <item>
+ Screen information (clipping rectangle for each screen relative
+ to the virtual screen)
+ <item>
+ Window information (window IDs and clipping information for each
+ back-end window that corresponds to each DMX window)
+ <item>
+ Input device information (mappings from DMX device IDs to
+ back-end device IDs)
+ <item>
+ Force window creation (so that a client can override the
+ server-side lazy window creation optimization)
+ <item>
+ Reconfiguration (so that a client can request that a screen
+ position be changed)
+ <item>
+ Addition and removal of back-end servers and back-end and
+ console inputs.
+</enum>
+<!-- September 2002; July 2003 -->
+
+
+<sect1>Common X extension support
+
+<p>The XInput, XKeyboard and Shape extensions are commonly used
+extensions to the base X11 protocol. XInput allows multiple and
+non-standard input devices to be accessed simultaneously. These input
+devices can be connected to either the front-end or back-end servers.
+XKeyboard allows much better keyboard mappings control. Shape adds
+support for arbitrarily shaped windows and is used by various window
+managers. Nearly all potential back-end X servers make these extensions
+available, and support for each one will be added to the DMX system.
+
+<p>In addition to the extensions listed above, support for the X
+Rendering extension (Render) is being developed. Render adds digital
+image composition to the rendering model used by the X Window System.
+While this extension is still under development by Keith Packard of HP,
+support for the current version will be added to the DMX system.
+
+<p>Support for the XTest extension was added during the first
+development phase.
+
+<!-- WARNING: this list is duplicated in the Phase IV discussion -->
+<p>Status: The following extensions are supported and are discussed in
+more detail in Phase IV of the Development Results (see appendix):
+ BIG-REQUESTS,
+ DEC-XTRAP,
+ DMX,
+ DPMS,
+ Extended-Visual-Information,
+ GLX,
+ LBX,
+ RECORD,
+ RENDER,
+ SECURITY,
+ SHAPE,
+ SYNC,
+ X-Resource,
+ XC-APPGROUP,
+ XC-MISC,
+ XFree86-Bigfont,
+ XINERAMA,
+ XInputExtension,
+ XKEYBOARD, and
+ XTEST.
+<!-- November 2002; updated February 2003, July 2003 -->
+
+<sect1>OpenGL support
+
+<p>OpenGL support using the Mesa code base exists in XFree86 release 4
+and later. Currently, the direct rendering infrastructure (DRI)
+provides accelerated OpenGL support for local clients and unaccelerated
+OpenGL support (i.e., software rendering) is provided for non-local
+clients.
+
+<p>The single head OpenGL support in XFree86 4.x will be extended to use
+the DMX system. When the front and back-end servers are on the same
+physical hardware, it is possible to use the DRI to directly render to
+the back-end servers. First, the existing DRI will be extended to
+support multiple display heads, and then to support the DMX system.
+OpenGL rendering requests will be direct rendering to each back-end X
+server. The DRI will request the screen layout (either from the
+existing Xinerama extension or a DMX-specific extension). Support for
+synchronized swap buffers will also be added (on hardware that supports
+it). Note that a single front-end server with a single back-end server
+on the same physical machine can emulate accelerated indirect rendering.
+
+<p>When the front and back-end servers are on different physical
+hardware or are using non-XFree86 4.x X servers, a mechanism to render
+primitives across the back-end servers will be provided. There are
+several options as to how this can be implemented.
+
+<enum>
+ <item>The existing OpenGL support in each back-end server can be
+ used by repackaging rendering primitives and sending them to each
+ back-end server. This option is similar to the unoptimized
+ Xnest-style approach mentioned above. Optimization of this solution
+ is beyond the scope of this project and is better suited to other
+ distributed rendering systems.
+
+ <item>Rendering to a pixmap in the front-end server using the
+ current XFree86 4.x code, and then displaying to the back-ends via
+ calls to XPutImage() is another option. This option is similar to
+ the shadow frame buffer approach mentioned above. It is slower and
+ bandwidth intensive, but has the advantage that the back-end servers
+ are not required to have OpenGL support.
+</enum>
+
+<p>These, and other, options will be investigated in this phase of the
+work.
+
+<p>Work by others have made Chromium DMX-aware. Chromium will use the
+DMX X protocol extension to obtain information about the back-end
+servers and will render directly to those servers, bypassing DMX.
+
+<p>Status: OpenGL support by the glxProxy extension was implemented by
+SGI and has been integrated into the DMX code base.
+<!-- May 2003-->
+
+
+<!-- ============================================================ -->
+<sect>Current issues
+
+<p>In this sections the current issues are outlined that require further
+investigation.
+
+<sect1>Fonts
+
+<p>The font path and glyphs need to be the same for the front-end and
+each of the back-end servers. Font glyphs could be sent to the back-end
+servers as necessary but this would consume a significant amount of
+available bandwidth during font rendering for clients that use many
+different fonts (e.g., Netscape). Initially, the font server (xfs) will
+be used to provide the fonts to both the front-end and back-end servers.
+Other possibilities will be investigated during development.
+
+<sect1>Zero width rendering primitives
+
+<p>To allow pixmap and on-screen rendering to be pixel perfect, all
+back-end servers must render zero width primitives exactly the same as
+the front-end renders the primitives to pixmaps. For those back-end
+servers that do not exactly match, zero width primitives will be
+automatically converted to one width primitives. This can be handled in
+the front-end server via the GC state.
+
+<sect1>Output scaling
+
+<p>With very large tiled displays, it might be difficult to read the
+information on the standard X desktop. In particular, the cursor can be
+easily lost and fonts could be difficult to read. Automatic primitive
+scaling might prove to be very useful. We will investigate the
+possibility of scaling the cursor and providing a set of alternate
+pre-scaled fonts to replace the standard fonts that many applications
+use (e.g., fixed). Other options for automatic scaling will also be
+investigated.
+
+<sect1>Per-screen colormaps
+
+<p>Each screen's default colormap in the set of back-end X servers
+should be able to be adjusted via a configuration utility. This support
+is would allow the back-end screens to be calibrated via custom gamma
+tables. On 24-bit systems that support a DirectColor visual, this type
+of correction can be accommodated. One possible implementation would be
+to advertise to X client of the DMX server a TrueColor visual while
+using DirectColor visuals on the back-end servers to implement this type
+of color correction. Other options will be investigated.
+
+<!-- ============================================================ -->
+<appendix>
+
+<sect>Background
+
+<p>This section describes the existing Open Source architectures that
+can be used to handle multiple screens and upon which this development
+project is based. This section was written before the implementation
+was finished, and may not reflect actual details of the implementation.
+It is left for historical interest only.
+
+<sect1>Core input device handling
+
+<p>The following is a description of how core input devices are handled
+by an X server.
+
+<sect2>InitInput()
+
+<p>InitInput() is a DDX function that is called at the start of each
+server generation from the X server's main() function. Its purpose is
+to determine what input devices are connected to the X server, register
+them with the DIX and MI layers, and initialize the input event queue.
+InitInput() does not have a return value, but the X server will abort if
+either a core keyboard device or a core pointer device are not
+registered. Extended input (XInput) devices can also be registered in
+InitInput().
+
+<p>InitInput() usually has implementation specific code to determine
+which input devices are available. For each input device it will be
+using, it calls AddInputDevice():
+
+<descrip>
+<tag/AddInputDevice()/ This DIX function allocates the device structure,
+registers a callback function (which handles device init, close, on and
+off), and returns the input handle, which can be treated as opaque. It
+is called once for each input device.
+</descrip>
+
+<p>Once input handles for core keyboard and core pointer devices have
+been obtained from AddInputDevice(), they are registered as core devices
+by calling RegisterPointerDevice() and RegisterKeyboardDevice(). Each
+of these should be called once. If both core devices are not
+registered, then the X server will exit with a fatal error when it
+attempts to start the input devices in InitAndStartDevices(), which is
+called directly after InitInput() (see below).
+
+<descrip>
+<tag/Register{Pointer,Keyboard}Device()/ These DIX functions take a
+handle returned from AddInputDevice() and initialize the core input
+device fields in inputInfo, and initialize the input processing and grab
+functions for each core input device.
+</descrip>
+
+<p>The core pointer device is then registered with the miPointer code
+(which does the high level cursor handling). While this registration
+is not necessary for correct miPointer operation in the current XFree86
+code, it is still done mostly for compatibility reasons.
+
+<descrip>
+<tag/miRegisterPointerDevice()/ This MI function registers the core
+pointer's input handle with with the miPointer code.
+</descrip>
+
+<p>The final part of InitInput() is the initialization of the input
+event queue handling. In most cases, the event queue handling provided
+in the MI layer is used. The primary XFree86 X server uses its own
+event queue handling to support some special cases related to the XInput
+extension and the XFree86-specific DGA extension. For our purposes, the
+MI event queue handling should be suitable. It is initialized by
+calling mieqInit():
+
+<descrip>
+<tag/mieqInit()/ This MI function initializes the MI event queue for the
+core devices, and is passed the public component of the input handles
+for the two core devices.
+</descrip>
+
+<p>If a wakeup handler is required to deliver synchronous input
+events, it can be registered here by calling the DIX function
+RegisterBlockAndWakeupHandlers(). (See the devReadInput() description
+below.)
+
+<sect2>InitAndStartDevices()
+
+<p>InitAndStartDevices() is a DIX function that is called immediately
+after InitInput() from the X server's main() function. Its purpose is
+to initialize each input device that was registered with
+AddInputDevice(), enable each input device that was successfully
+initialized, and create the list of enabled input devices. Once each
+registered device is processed in this way, the list of enabled input
+devices is checked to make sure that both a core keyboard device and
+core pointer device were registered and successfully enabled. If not,
+InitAndStartDevices() returns failure, and results in the the X server
+exiting with a fatal error.
+
+<p>Each registered device is initialized by calling its callback
+(dev-&gt;deviceProc) with the DEVICE_INIT argument:
+
+<descrip>
+<tag/(*dev-&gt;deviceProc)(dev, DEVICE_INIT)/ This function initializes the
+device structs with core information relevant to the device.
+
+<p>For pointer devices, this means specifying the number of buttons,
+default button mapping, the function used to get motion events (usually
+miPointerGetMotionEvents()), the function used to change/control the
+core pointer motion parameters (acceleration and threshold), and the
+motion buffer size.
+
+<p>For keyboard devices, this means specifying the keycode range,
+default keycode to keysym mapping, default modifier mapping, and the
+functions used to sound the keyboard bell and modify/control the
+keyboard parameters (LEDs, bell pitch and duration, key click, which
+keys are auto-repeating, etc).
+</descrip>
+
+<p>Each initialized device is enabled by calling EnableDevice():
+
+<descrip>
+<tag/EnableDevice()/ EnableDevice() calls the device callback with
+DEVICE_ON:
+ <descrip>
+ <tag/(*dev-&gt;deviceProc)(dev, DEVICE_ON)/ This typically opens and
+ initializes the relevant physical device, and when appropriate,
+ registers the device's file descriptor (or equivalent) as a valid
+ input source.
+ </descrip>
+
+ <p>EnableDevice() then adds the device handle to the X server's
+ global list of enabled devices.
+</descrip>
+
+<p>InitAndStartDevices() then verifies that a valid core keyboard and
+pointer has been initialized and enabled. It returns failure if either
+are missing.
+
+<sect2>devReadInput()
+
+<p>Each device will have some function that gets called to read its
+physical input. These may be called in a number of different ways. In
+the case of synchronous I/O, they will be called from a DDX
+wakeup-handler that gets called after the server detects that new input is
+available. In the case of asynchronous I/O, they will be called from a
+(SIGIO) signal handler triggered when new input is available. This
+function should do at least two things: make sure that input events get
+enqueued, and make sure that the cursor gets moved for motion events
+(except if these are handled later by the driver's own event queue
+processing function, which cannot be done when using the MI event queue
+handling).
+
+<p>Events are queued by calling mieqEnqueue():
+
+<descrip>
+<tag/mieqEnqueue()/ This MI function is used to add input events to the
+event queue. It is simply passed the event to be queued.
+</descrip>
+
+<p>The cursor position should be updated when motion events are
+enqueued, by calling either miPointerAbsoluteCursor() or
+miPointerDeltaCursor():
+
+<descrip>
+<tag/miPointerAbsoluteCursor()/ This MI function is used to move the
+cursor to the absolute coordinates provided.
+<tag/miPointerDeltaCursor()/ This MI function is used to move the cursor
+relative to its current position.
+</descrip>
+
+<sect2>ProcessInputEvents()
+
+<p>ProcessInputEvents() is a DDX function that is called from the X
+server's main dispatch loop when new events are available in the input
+event queue. It typically processes the enqueued events, and updates
+the cursor/pointer position. It may also do other DDX-specific event
+processing.
+
+<p>Enqueued events are processed by mieqProcessInputEvents() and passed
+to the DIX layer for transmission to clients:
+
+<descrip>
+<tag/mieqProcessInputEvents()/ This function processes each event in the
+event queue, and passes it to the device's input processing function.
+The DIX layer provides default functions to do this processing, and they
+handle the task of getting the events passed back to the relevant
+clients.
+<tag/miPointerUpdate()/ This function resynchronized the cursor position
+with the new pointer position. It also takes care of moving the cursor
+between screens when needed in multi-head configurations.
+</descrip>
+
+
+<sect2>DisableDevice()
+
+<p>DisableDevice is a DIX function that removes an input device from the
+list of enabled devices. The result of this is that the device no
+longer generates input events. The device's data structures are kept in
+place, and disabling a device like this can be reversed by calling
+EnableDevice(). DisableDevice() may be called from the DDX when it is
+desirable to do so (e.g., the XFree86 server does this when VT
+switching). Except for special cases, this is not normally called for
+core input devices.
+
+<p>DisableDevice() calls the device's callback function with
+<tt/DEVICE_OFF/:
+
+<descrip>
+<tag/(*dev-&gt;deviceProc)(dev, DEVICE_OFF)/ This typically closes the
+relevant physical device, and when appropriate, unregisters the device's
+file descriptor (or equivalent) as a valid input source.
+</descrip>
+
+<p>DisableDevice() then removes the device handle from the X server's
+global list of enabled devices.
+
+
+<sect2>CloseDevice()
+
+<p>CloseDevice is a DIX function that removes an input device from the
+list of available devices. It disables input from the device and frees
+all data structures associated with the device. This function is
+usually called from CloseDownDevices(), which is called from main() at
+the end of each server generation to close all input devices.
+
+<p>CloseDevice() calls the device's callback function with
+<tt/DEVICE_CLOSE/:
+
+<descrip>
+<tag/(*dev-&gt;deviceProc)(dev, DEVICE_CLOSE)/ This typically closes the
+relevant physical device, and when appropriate, unregisters the device's
+file descriptor (or equivalent) as a valid input source. If any device
+specific data structures were allocated when the device was initialized,
+they are freed here.
+</descrip>
+
+<p>CloseDevice() then frees the data structures that were allocated
+for the device when it was registered/initialized.
+
+
+<sect2>LegalModifier()
+<!-- dmx/dmxinput.c - currently returns TRUE -->
+<p>LegalModifier() is a required DDX function that can be used to
+restrict which keys may be modifier keys. This seems to be present for
+historical reasons, so this function should simply return TRUE
+unconditionally.
+
+
+<sect1>Output handling
+
+<p>The following sections describe the main functions required to
+initialize, use and close the output device(s) for each screen in the X
+server.
+
+<sect2>InitOutput()
+
+<p>This DDX function is called near the start of each server generation
+from the X server's main() function. InitOutput()'s main purpose is to
+initialize each screen and fill in the global screenInfo structure for
+each screen. It is passed three arguments: a pointer to the screenInfo
+struct, which it is to initialize, and argc and argv from main(), which
+can be used to determine additional configuration information.
+
+<p>The primary tasks for this function are outlined below:
+
+<enum>
+ <item><bf/Parse configuration info:/ The first task of InitOutput()
+ is to parses any configuration information from the configuration
+ file. In addition to the XF86Config file, other configuration
+ information can be taken from the command line. The command line
+ options can be gathered either in InitOutput() or earlier in the
+ ddxProcessArgument() function, which is called by
+ ProcessCommandLine(). The configuration information determines the
+ characteristics of the screen(s). For example, in the XFree86 X
+ server, the XF86Config file specifies the monitor information, the
+ screen resolution, the graphics devices and slots in which they are
+ located, and, for Xinerama, the screens' layout.
+
+ <item><bf/Initialize screen info:/ The next task is to initialize
+ the screen-dependent internal data structures. For example, part of
+ what the XFree86 X server does is to allocate its screen and pixmap
+ private indices, probe for graphics devices, compare the probed
+ devices to the ones listed in the XF86Config file, and add the ones that
+ match to the internal xf86Screens&lsqb;&rsqb; structure.
+
+ <item><bf/Set pixmap formats:/ The next task is to initialize the
+ screenInfo's image byte order, bitmap bit order and bitmap scanline
+ unit/pad. The screenInfo's pixmap format's depth, bits per pixel
+ and scanline padding is also initialized at this stage.
+
+ <item><bf/Unify screen info:/ An optional task that might be done at
+ this stage is to compare all of the information from the various
+ screens and determines if they are compatible (i.e., if the set of
+ screens can be unified into a single desktop). This task has
+ potential to be useful to the DMX front-end server, if Xinerama's
+ PanoramiXConsolidate() function is not sufficient.
+</enum>
+
+<p>Once these tasks are complete, the valid screens are known and each
+of these screens can be initialized by calling AddScreen().
+
+<sect2>AddScreen()
+
+<p>This DIX function is called from InitOutput(), in the DDX layer, to
+add each new screen to the screenInfo structure. The DDX screen
+initialization function and command line arguments (i.e., argc and argv)
+are passed to it as arguments.
+
+<p>This function first allocates a new Screen structure and any privates
+that are required. It then initializes some of the fields in the Screen
+struct and sets up the pixmap padding information. Finally, it calls
+the DDX screen initialization function ScreenInit(), which is described
+below. It returns the number of the screen that were just added, or -1
+if there is insufficient memory to add the screen or if the DDX screen
+initialization fails.
+
+<sect2>ScreenInit()
+
+<p>This DDX function initializes the rest of the Screen structure with
+either generic or screen-specific functions (as necessary). It also
+fills in various screen attributes (e.g., width and height in
+millimeters, black and white pixel values).
+
+<p>The screen init function usually calls several functions to perform
+certain screen initialization functions. They are described below:
+
+<descrip>
+<tag/{mi,*fb}ScreenInit()/ The DDX layer's ScreenInit() function usually
+calls another layer's ScreenInit() function (e.g., miScreenInit() or
+fbScreenInit()) to initialize the fallbacks that the DDX driver does not
+specifically handle.
+
+<p>After calling another layer's ScreenInit() function, any
+screen-specific functions either wrap or replace the other layer's
+function pointers. If a function is to be wrapped, each of the old
+function pointers from the other layer are stored in a screen private
+area. Common functions to wrap are CloseScreen() and SaveScreen().
+
+<tag/miInitializeBackingStore()/ This MI function initializes the
+screen's backing storage functions, which are used to save areas of
+windows that are currently covered by other windows.
+
+<tag/miDCInitialize()/ This MI function initializes the MI cursor
+display structures and function pointers. If a hardware cursor is used,
+the DDX layer's ScreenInit() function will wrap additional screen and
+the MI cursor display function pointers.
+</descrip>
+
+<p>Another common task for ScreenInit() function is to initialize the
+output device state. For example, in the XFree86 X server, the
+ScreenInit() function saves the original state of the video card and
+then initializes the video mode of the graphics device.
+
+<sect2>CloseScreen()
+
+<p>This function restores any wrapped screen functions (and in
+particular the wrapped CloseScreen() function) and restores the state of
+the output device to its original state. It should also free any
+private data it created during the screen initialization.
+
+<sect2>GC operations
+
+<p>When the X server is requested to render drawing primitives, it does
+so by calling drawing functions through the graphics context's operation
+function pointer table (i.e., the GCOps functions). These functions
+render the basic graphics operations such as drawing rectangles, lines,
+text or copying pixmaps. Default routines are provided either by the MI
+layer, which draws indirectly through a simple span interface, or by the
+framebuffer layers (e.g., CFB, MFB, FB), which draw directly to a
+linearly mapped frame buffer.
+
+<p>To take advantage of special hardware on the graphics device,
+specific GCOps functions can be replaced by device specific code.
+However, many times the graphics devices can handle only a subset of the
+possible states of the GC, so during graphics context validation,
+appropriate routines are selected based on the state and capabilities of
+the hardware. For example, some graphics hardware can accelerate single
+pixel width lines with certain dash patterns. Thus, for dash patterns
+that are not supported by hardware or for width 2 or greater lines, the
+default routine is chosen during GC validation.
+
+<p>Note that some pointers to functions that draw to the screen are
+stored in the Screen structure. They include GetImage(), GetSpans(),
+CopyWindow() and RestoreAreas().
+
+<sect2>Xnest
+
+<p>The Xnest X server is a special proxy X server that relays the X
+protocol requests that it receives to a ``real'' X server that then
+processes the requests and displays the results, if applicable. To the X
+applications, Xnest appears as if it is a regular X server. However,
+Xnest is both server to the X application and client of the real X
+server, which will actually handle the requests.
+
+<p>The Xnest server implements all of the standard input and output
+initialization steps outlined above.
+
+<descrip>
+<tag/InitOutput()/ Xnest takes its configuration information from
+command line arguments via ddxProcessArguments(). This information
+includes the real X server display to connect to, its default visual
+class, the screen depth, the Xnest window's geometry, etc. Xnest then
+connects to the real X server and gathers visual, colormap, depth and
+pixmap information about that server's display, creates a window on that
+server, which will be used as the root window for Xnest.
+
+<p>Next, Xnest initializes its internal data structures and uses the
+data from the real X server's pixmaps to initialize its own pixmap
+formats. Finally, it calls AddScreen(xnestOpenScreen, argc, argv) to
+initialize each of its screens.
+
+<tag/ScreenInit()/ Xnest's ScreenInit() function is called
+xnestOpenScreen(). This function initializes its screen's depth and
+visual information, and then calls miScreenInit() to set up the default
+screen functions. It then calls miInitializeBackingStore() and
+miDCInitialize() to initialize backing store and the software cursor.
+Finally, it replaces many of the screen functions with its own
+functions that repackage and send the requests to the real X server to
+which Xnest is attached.
+
+<tag/CloseScreen()/ This function frees its internal data structure
+allocations. Since it replaces instead of wrapping screen functions,
+there are no function pointers to unwrap. This can potentially lead to
+problems during server regeneration.
+
+<tag/GC operations/ The GC operations in Xnest are very simple since
+they leave all of the drawing to the real X server to which Xnest is
+attached. Each of the GCOps takes the request and sends it to the
+real X server using standard Xlib calls. For example, the X
+application issues a XDrawLines() call. This function turns into a
+protocol request to Xnest, which calls the xnestPolylines() function
+through Xnest's GCOps function pointer table. The xnestPolylines()
+function is only a single line, which calls XDrawLines() using the same
+arguments that were passed into it. Other GCOps functions are very
+similar. Two exceptions to the simple GCOps functions described above
+are the image functions and the BLT operations.
+
+<p>The image functions, GetImage() and PutImage(), must use a temporary
+image to hold the image to be put of the image that was just grabbed
+from the screen while it is in transit to the real X server or the
+client. When the image has been transmitted, the temporary image is
+destroyed.
+
+<p>The BLT operations, CopyArea() and CopyPlane(), handle not only the
+copy function, which is the same as the simple cases described above,
+but also the graphics exposures that result when the GC's graphics
+exposure bit is set to True. Graphics exposures are handled in a helper
+function, xnestBitBlitHelper(). This function collects the exposure
+events from the real X server and, if any resulting in regions being
+exposed, then those regions are passed back to the MI layer so that it
+can generate exposure events for the X application.
+</descrip>
+
+<p>The Xnest server takes its input from the X server to which it is
+connected. When the mouse is in the Xnest server's window, keyboard and
+mouse events are received by the Xnest server, repackaged and sent back
+to any client that requests those events.
+
+<sect2>Shadow framebuffer
+
+<p>The most common type of framebuffer is a linear array memory that
+maps to the video memory on the graphics device. However, accessing
+that video memory over an I/O bus (e.g., ISA or PCI) can be slow. The
+shadow framebuffer layer allows the developer to keep the entire
+framebuffer in main memory and copy it back to video memory at regular
+intervals. It also has been extended to handle planar video memory and
+rotated framebuffers.
+
+<p>There are two main entry points to the shadow framebuffer code:
+
+<descrip>
+<tag/shadowAlloc(width, height, bpp)/ This function allocates the in
+memory copy of the framebuffer of size width*height*bpp. It returns a
+pointer to that memory, which will be used by the framebuffer
+ScreenInit() code during the screen's initialization.
+
+<tag/shadowInit(pScreen, updateProc, windowProc)/ This function
+initializes the shadow framebuffer layer. It wraps several screen
+drawing functions, and registers a block handler that will update the
+screen. The updateProc is a function that will copy the damaged regions
+to the screen, and the windowProc is a function that is used when the
+entire linear video memory range cannot be accessed simultaneously so
+that only a window into that memory is available (e.g., when using the
+VGA aperture).
+</descrip>
+
+<p>The shadow framebuffer code keeps track of the damaged area of each
+screen by calculating the bounding box of all drawing operations that
+have occurred since the last screen update. Then, when the block handler
+is next called, only the damaged portion of the screen is updated.
+
+<p>Note that since the shadow framebuffer is kept in main memory, all
+drawing operations are performed by the CPU and, thus, no accelerated
+hardware drawing operations are possible.
+
+
+<sect1>Xinerama
+
+<p>Xinerama is an X extension that allows multiple physical screens
+controlled by a single X server to appear as a single screen. Although
+the extension allows clients to find the physical screen layout via
+extension requests, it is completely transparent to clients at the core
+X11 protocol level. The original public implementation of Xinerama came
+from Digital/Compaq. XFree86 rewrote it, filling in some missing pieces
+and improving both X11 core protocol compliance and performance. The
+Xinerama extension will be passing through X.Org's standardization
+process in the near future, and the sample implementation will be based
+on this rewritten version.
+
+<p>The current implementation of Xinerama is based primarily in the DIX
+(device independent) and MI (machine independent) layers of the X
+server. With few exceptions the DDX layers do not need any changes to
+support Xinerama. X server extensions often do need modifications to
+provide full Xinerama functionality.
+
+<p>The following is a code-level description of how Xinerama functions.
+
+<p>Note: Because the Xinerama extension was originally called the
+PanoramiX extension, many of the Xinerama functions still have the
+PanoramiX prefix.
+
+<descrip>
+ <tag/PanoramiXExtensionInit()/ PanoramiXExtensionInit() is a
+ device-independent extension function that is called at the start of
+ each server generation from InitExtensions(), which is called from
+ the X server's main() function after all output devices have been
+ initialized, but before any input devices have been initialized.
+
+ <p>PanoramiXNumScreens is set to the number of physical screens. If
+ only one physical screen is present, the extension is disabled, and
+ PanoramiXExtensionInit() returns without doing anything else.
+
+ <p>The Xinerama extension is registered by calling AddExtension().
+
+ <p>A local per-screen array of data structures
+ (panoramiXdataPtr&lsqb;&rsqb;)
+ is allocated for each physical screen, and GC and Screen private
+ indexes are allocated, and both GC and Screen private areas are
+ allocated for each physical screen. These hold Xinerama-specific
+ per-GC and per-Screen data. Each screen's CreateGC and CloseScreen
+ functions are wrapped by XineramaCreateGC() and
+ XineramaCloseScreen() respectively. Some new resource classes are
+ created for Xinerama drawables and GCs, and resource types for
+ Xinerama windows, pixmaps and colormaps.
+
+ <p>A region (XineramaScreenRegions&lsqb;i&rsqb;) is initialized for each
+ physical screen, and single region (PanoramiXScreenRegion) is
+ initialized to be the union of the screen regions. The
+ panoramiXdataPtr&lsqb;&rsqb; array is also initialized with the size and
+ origin of each screen. The relative positioning information for the
+ physical screens is taken from the array
+ dixScreenOrigins&lsqb;&rsqb;, which
+ the DDX layer must initialize in InitOutput(). The bounds of the
+ combined screen is also calculated (PanoramiXPixWidth and
+ PanoramiXPixHeight).
+
+ <p>The DIX layer has a list of function pointers
+ (ProcVector&lsqb;&rsqb;) that
+ holds the entry points for the functions that process core protocol
+ requests. The requests that Xinerama must intercept and break up
+ into physical screen-specific requests are wrapped. The original
+ set is copied to SavedProcVector&lsqb;&rsqb;. The types of requests
+ intercepted are Window requests, GC requests, colormap requests,
+ drawing requests, and some geometry-related requests. This wrapping
+ allows the bulk of the protocol request processing to be handled
+ transparently to the DIX layer. Some operations cannot be dealt with
+ in this way and are handled with Xinerama-specific code within the
+ DIX layer.
+
+ <tag/PanoramiXConsolidate()/ PanoramiXConsolidate() is a
+ device-independent extension function that is called directly from
+ the X server's main() function after extensions and input/output
+ devices have been initialized, and before the root windows are
+ defined and initialized.
+
+ <p>This function finds the set of depths (PanoramiXDepths&lsqb;&rsqb;) and
+ visuals (PanoramiXVisuals&lsqb;&rsqb;)
+ common to all of the physical screens.
+ PanoramiXNumDepths is set to the number of common depths, and
+ PanoramiXNumVisuals is set to the number of common visuals.
+ Resources are created for the single root window and the default
+ colormap. Each of these resources has per-physical screen entries.
+
+ <tag/PanoramiXCreateConnectionBlock()/ PanoramiXConsolidate() is a
+ device-independent extension function that is called directly from
+ the X server's main() function after the per-physical screen root
+ windows are created. It is called instead of the standard DIX
+ CreateConnectionBlock() function. If this function returns FALSE,
+ the X server exits with a fatal error. This function will return
+ FALSE if no common depths were found in PanoramiXConsolidate().
+ With no common depths, Xinerama mode is not possible.
+
+ <p>The connection block holds the information that clients get when
+ they open a connection to the X server. It includes information
+ such as the supported pixmap formats, number of screens and the
+ sizes, depths, visuals, default colormap information, etc, for each
+ of the screens (much of information that <tt/xdpyinfo/ shows). The
+ connection block is initialized with the combined single screen
+ values that were calculated in the above two functions.
+
+ <p>The Xinerama extension allows the registration of connection
+ block callback functions. The purpose of these is to allow other
+ extensions to do processing at this point. These callbacks can be
+ registered by calling XineramaRegisterConnectionBlockCallback() from
+ the other extension's ExtensionInit() function. Each registered
+ connection block callback is called at the end of
+ PanoramiXCreateConnectionBlock().
+</descrip>
+
+<sect2>Xinerama-specific changes to the DIX code
+
+<p>There are a few types of Xinerama-specific changes within the DIX
+code. The main ones are described here.
+
+<p>Functions that deal with colormap or GC -related operations outside of
+the intercepted protocol requests have a test added to only do the
+processing for screen numbers > 0. This is because they are handled for
+the single Xinerama screen and the processing is done once for screen 0.
+
+<p>The handling of motion events does some coordinate translation between
+the physical screen's origin and screen zero's origin. Also, motion
+events must be reported relative to the composite screen origin rather
+than the physical screen origins.
+
+<p>There is some special handling for cursor, window and event processing
+that cannot (either not at all or not conveniently) be done via the
+intercepted protocol requests. A particular case is the handling of
+pointers moving between physical screens.
+
+<sect2>Xinerama-specific changes to the MI code
+
+<p>The only Xinerama-specific change to the MI code is in miSendExposures()
+to handle the coordinate (and window ID) translation for expose events.
+
+<sect2>Intercepted DIX core requests
+
+<p>Xinerama breaks up drawing requests for dispatch to each physical
+screen. It also breaks up windows into pieces for each physical screen.
+GCs are translated into per-screen GCs. Colormaps are replicated on
+each physical screen. The functions handling the intercepted requests
+take care of breaking the requests and repackaging them so that they can
+be passed to the standard request handling functions for each screen in
+turn. In addition, and to aid the repackaging, the information from
+many of the intercepted requests is used to keep up to date the
+necessary state information for the single composite screen. Requests
+(usually those with replies) that can be satisfied completely from this
+stored state information do not call the standard request handling
+functions.
+
+<!-- ============================================================ -->
+
+<sect>Development Results
+
+<p>In this section the results of each phase of development are
+discussed. This development took place between approximately June 2001
+and July 2003.
+
+<sect1>Phase I
+
+<p>The initial development phase dealt with the basic implementation
+including the bootstrap code, which used the shadow framebuffer, and the
+unoptimized implementation, based on an Xnest-style implementation.
+
+<sect2>Scope
+
+<p>The goal of Phase I is to provide fundamental functionality that can
+act as a foundation for ongoing work:
+<enum>
+ <item>Develop the proxy X server
+ <itemize>
+ <item>The proxy X server will operate on the X11 protocol and
+ relay requests as necessary to correctly perform the request.
+ <item>Work will be based on the existing work for Xinerama and
+ Xnest.
+ <item>Input events and windowing operations are handled in the
+ proxy server and rendering requests are repackaged and sent to
+ each of the back-end servers for display.
+ <item>The multiple screen layout (including support for
+ overlapping screens) will be user configurable via a
+ configuration file or through the configuration tool.
+ </itemize>
+ <item>Develop graphical configuration tool
+ <itemize>
+ <item>There will be potentially a large number of X servers to
+ configure into a single display. The tool will allow the user
+ to specify which servers are involved in the configuration and
+ how they should be laid out.
+ </itemize>
+ <item>Pass the X Test Suite
+ <itemize>
+ <item>The X Test Suite covers the basic X11 operations. All
+ tests known to succeed must correctly operate in the distributed
+ X environment.
+ </itemize>
+</enum>
+
+<p>For this phase, the back-end X servers are assumed to be unmodified X
+servers that do not support any DMX-related protocol extensions; future
+optimization pathways are considered, but are not implemented; and the
+configuration tool is assumed to rely only on libraries in the X source
+tree (e.g., Xt).
+
+<sect2>Results
+
+<p>The proxy X server, Xdmx, was developed to distribute X11 protocol
+requests to the set of back-end X servers. It opens a window on each
+back-end server, which represents the part of the front-end's root
+window that is visible on that screen. It mirrors window, pixmap and
+other state in each back-end server. Drawing requests are sent to
+either windows or pixmaps on each back-end server. This code is based
+on Xnest and uses the existing Xinerama extension.
+
+<p>Input events can be taken from (1) devices attached to the back-end
+server, (2) core devices attached directly to the Xdmx server, or (3)
+from a ``console'' window on another X server. Events for these devices
+are gathered, processed and delivered to clients attached to the Xdmx
+server.
+
+<p>An intuitive configuration format was developed to help the user
+easily configure the multiple back-end X servers. It was defined (see
+grammar in Xdmx man page) and a parser was implemented that is used by
+the Xdmx server and by a standalone xdmxconfig utility. The parsing
+support was implemented such that it can be easily factored out of the X
+source tree for use with other tools (e.g., vdl). Support for
+converting legacy vdl-format configuration files to the DMX format is
+provided by the vdltodmx utility.
+
+<p>Originally, the configuration file was going to be a subsection of
+XFree86's XF86Config file, but that was not possible since Xdmx is a
+completely separate X server. Thus, a separate config file format was
+developed. In addition, a graphical configuration
+tool, xdmxconfig, was developed to allow the user to create and arrange
+the screens in the configuration file. The <bf/-configfile/ and <bf/-config/
+command-line options can be used to start Xdmx using a configuration
+file.
+
+<p>An extension that enables remote input testing is required for the X
+Test Suite to function. During this phase, this extension (XTEST) was
+implemented in the Xdmx server. The results from running the X Test
+Suite are described in detail below.
+
+<sect2>X Test Suite
+
+ <sect3> Introduction
+ <p>
+ The X Test Suite contains tests that verify Xlib functions
+ operate correctly. The test suite is designed to run on a
+ single X server; however, since X applications will not be
+ able to tell the difference between the DMX server and a
+ standard X server, the X Test Suite should also run on the
+ DMX server.
+ <p>
+ The Xdmx server was tested with the X Test Suite, and the
+ existing failures are noted in this section. To put these
+ results in perspective, we first discuss expected X Test
+ failures and how errors in underlying systems can impact
+ Xdmx test results.
+
+ <sect3>Expected Failures for a Single Head
+ <p>
+ A correctly implemented X server with a single screen is
+ expected to fail certain X Test tests. The following
+ well-known errors occur because of rounding error in the X
+ server code:
+ <verb>
+XDrawArc: Tests 42, 63, 66, 73
+XDrawArcs: Tests 45, 66, 69, 76
+ </verb>
+ <p>
+ The following failures occur because of the high-level X
+ server implementation:
+ <verb>
+XLoadQueryFont: Test 1
+XListFontsWithInfo: Tests 3, 4
+XQueryFont: Tests 1, 2
+ </verb>
+ <p>
+ The following test fails when running the X server as root
+ under Linux because of the way directory modes are
+ interpreted:
+ <verb>
+XWriteBitmapFile: Test 3
+ </verb>
+ <p>
+ Depending on the video card used for the back-end, other
+ failures may also occur because of bugs in the low-level
+ driver implementation. Over time, failures of this kind
+ are usually fixed by XFree86, but will show up in Xdmx
+ testing until then.
+
+ <sect3>Expected Failures for Xinerama
+ <p>
+ Xinerama fails several X Test Suite tests because of
+ design decisions made for the current implementation of
+ Xinerama. Over time, many of these errors will be
+ corrected by XFree86 and the group working on a new
+ Xinerama implementation. Therefore, Xdmx will also share
+ X Suite Test failures with Xinerama.
+ <p>
+ We may be able to fix or work-around some of these
+ failures at the Xdmx level, but this will require
+ additional exploration that was not part of Phase I.
+ <p>
+ Xinerama is constantly improving, and the list of
+ Xinerama-related failures depends on XFree86 version and
+ the underlying graphics hardware. We tested with a
+ variety of hardware, including nVidia, S3, ATI Radeon,
+ and Matrox G400 (in dual-head mode). The list below
+ includes only those failures that appear to be from the
+ Xinerama layer, and does not include failures listed in
+ the previous section, or failures that appear to be from
+ the low-level graphics driver itself:
+ <p>
+ These failures were noted with multiple Xinerama
+ configurations:
+ <verb>
+XCopyPlane: Tests 13, 22, 31 (well-known Xinerama implementation issue)
+XSetFontPath: Test 4
+XGetDefault: Test 5
+XMatchVisualInfo: Test 1
+ </verb>
+ <p>
+ These failures were noted only when using one dual-head
+ video card with a 4.2.99.x XFree86 server:
+ <verb>
+XListPixmapFormats: Test 1
+XDrawRectangles: Test 45
+ </verb>
+ <p>
+ These failures were noted only when using two video cards
+ from different vendors with a 4.1.99.x XFree86 server:
+ <verb>
+XChangeWindowAttributes: Test 32
+XCreateWindow: Test 30
+XDrawLine: Test 22
+XFillArc: Test 22
+XChangeKeyboardControl: Tests 9, 10
+XRebindKeysym: Test 1
+ </verb>
+
+ <sect3>Additional Failures from Xdmx
+ <p>
+ When running Xdmx, no unexpected failures were noted.
+ Since the Xdmx server is based on Xinerama, we expect to
+ have most of the Xinerama failures present in the Xdmx
+ server. Similarly, since the Xdmx server must rely on the
+ low-level device drivers on each back-end server, we also
+ expect that Xdmx will exhibit most of the back-end
+ failures. Here is a summary:
+ <verb>
+XListPixmapFormats: Test 1 (configuration dependent)
+XChangeWindowAttributes: Test 32
+XCreateWindow: Test 30
+XCopyPlane: Test 13, 22, 31
+XSetFontPath: Test 4
+XGetDefault: Test 5 (configuration dependent)
+XMatchVisualInfo: Test 1
+XRebindKeysym: Test 1 (configuration dependent)
+ </verb>
+ <p>
+ Note that this list is shorter than the combined list for
+ Xinerama because Xdmx uses different code paths to perform
+ some Xinerama operations. Further, some Xinerama failures
+ have been fixed in the XFree86 4.2.99.x CVS repository.
+
+ <sect3>Summary and Future Work
+ <p>
+ Running the X Test Suite on Xdmx does not produce any
+ failures that cannot be accounted for by the underlying
+ Xinerama subsystem used by the front-end or by the
+ low-level device-driver code running on the back-end X
+ servers. The Xdmx server therefore is as ``correct'' as
+ possible with respect to the standard set of X Test Suite
+ tests.
+ <p>
+ During the following phases, we will continue to verify
+ Xdmx correctness using the X Test Suite. We may also use
+ other tests suites or write additional tests that run
+ under the X Test Suite that specifically verify the
+ expected behavior of DMX.
+
+<sect2>Fonts
+
+<p>In Phase I, fonts are handled directly by both the front-end and the
+back-end servers, which is required since we must treat each back-end
+server during this phase as a ``black box''. What this requires is that
+<bf/the front- and back-end servers must share the exact same font
+path/. There are two ways to help make sure that all servers share the
+same font path:
+
+<enum>
+ <item>First, each server can be configured to use the same font
+ server. The font server, xfs, can be configured to serve fonts to
+ multiple X servers via TCP.
+
+ <item>Second, each server can be configured to use the same font
+ path and either those font paths can be copied to each back-end
+ machine or they can be mounted (e.g., via NFS) on each back-end
+ machine.
+</enum>
+
+<p>One additional concern is that a client program can set its own font
+path, and if it does so, then that font path must be available on each
+back-end machine.
+
+<p>The -fontpath command line option was added to allow users to
+initialize the font path of the front end server. This font path is
+propagated to each back-end server when the default font is loaded. If
+there are any problems, an error message is printed, which will describe
+the problem and list the current font path. For more information about
+setting the font path, see the -fontpath option description in the man
+page.
+
+<sect2>Performance
+
+<p>Phase I of development was not intended to optimize performance. Its
+focus was on completely and correctly handling the base X11 protocol in
+the Xdmx server. However, several insights were gained during Phase I,
+which are listed here for reference during the next phase of
+development.
+
+<enum>
+ <item>Calls to XSync() can slow down rendering since it requires a
+ complete round trip to and from a back-end server. This is
+ especially problematic when communicating over long haul networks.
+ <item>Sending drawing requests to only the screens that they overlap
+ should improve performance.
+</enum>
+
+<sect2>Pixmaps
+
+<p>Pixmaps were originally expected to be handled entirely in the
+front-end X server; however, it was found that this overly complicated
+the rendering code and would have required sending potentially large
+images to each back server that required them when copying from pixmap
+to screen. Thus, pixmap state is mirrored in the back-end server just
+as it is with regular window state. With this implementation, the same
+rendering code that draws to windows can be used to draw to pixmaps on
+the back-end server, and no large image transfers are required to copy
+from pixmap to window.
+
+<!-- ============================================================ -->
+<sect1>Phase II
+
+<p>The second phase of development concentrates on performance
+optimizations. These optimizations are documented here, with
+<tt/x11perf/ data to show how the optimizations improve performance.
+
+<p>All benchmarks were performed by running Xdmx on a dual processor
+1.4GHz AMD Athlon machine with 1GB of RAM connecting over 100baseT to
+two single-processor 1GHz Pentium III machines with 256MB of RAM and ATI
+Rage 128 (RF) video cards. The front end was running Linux
+2.4.20-pre1-ac1 and the back ends were running Linux 2.4.7-10 and
+version 4.2.99.1 of XFree86 pulled from the XFree86 CVS repository on
+August 7, 2002. All systems were running Red Hat Linux 7.2.
+
+<sect2>Moving from XFree86 4.1.99.1 to 4.2.0.0
+
+<p>For phase II, the working source tree was moved to the branch tagged
+with dmx-1-0-branch and was updated from version 4.1.99.1 (20 August
+2001) of the XFree86 sources to version 4.2.0.0 (18 January 2002).
+After this update, the following tests were noted to be more than 10%
+faster:
+ <verb>
+1.13 Fill 300x300 opaque stippled trapezoid (161x145 stipple)
+1.16 Fill 1x1 tiled trapezoid (161x145 tile)
+1.13 Fill 10x10 tiled trapezoid (161x145 tile)
+1.17 Fill 100x100 tiled trapezoid (161x145 tile)
+1.16 Fill 1x1 tiled trapezoid (216x208 tile)
+1.20 Fill 10x10 tiled trapezoid (216x208 tile)
+1.15 Fill 100x100 tiled trapezoid (216x208 tile)
+1.37 Circulate Unmapped window (200 kids)
+ </verb>
+And the following tests were noted to be more than 10% slower:
+ <verb>
+0.88 Unmap window via parent (25 kids)
+0.75 Circulate Unmapped window (4 kids)
+0.79 Circulate Unmapped window (16 kids)
+0.80 Circulate Unmapped window (25 kids)
+0.82 Circulate Unmapped window (50 kids)
+0.85 Circulate Unmapped window (75 kids)
+ </verb>
+<p>These changes were not caused by any changes in the DMX system, and
+may point to changes in the XFree86 tree or to tests that have more
+"jitter" than most other <tt/x11perf/ tests.
+
+<sect2>Global changes
+
+<p>During the development of the Phase II DMX server, several global
+changes were made. These changes were also compared with the Phase I
+server. The following tests were noted to be more than 10% faster:
+ <verb>
+1.13 Fill 300x300 opaque stippled trapezoid (161x145 stipple)
+1.15 Fill 1x1 tiled trapezoid (161x145 tile)
+1.13 Fill 10x10 tiled trapezoid (161x145 tile)
+1.17 Fill 100x100 tiled trapezoid (161x145 tile)
+1.16 Fill 1x1 tiled trapezoid (216x208 tile)
+1.19 Fill 10x10 tiled trapezoid (216x208 tile)
+1.15 Fill 100x100 tiled trapezoid (216x208 tile)
+1.15 Circulate Unmapped window (4 kids)
+ </verb>
+
+<p>The following tests were noted to be more than 10% slower:
+ <verb>
+0.69 Scroll 10x10 pixels
+0.68 Scroll 100x100 pixels
+0.68 Copy 10x10 from window to window
+0.68 Copy 100x100 from window to window
+0.76 Circulate Unmapped window (75 kids)
+0.83 Circulate Unmapped window (100 kids)
+ </verb>
+
+<p>For the remainder of this analysis, the baseline of comparison will
+be the Phase II deliverable with all optimizations disabled (unless
+otherwise noted). This will highlight how the optimizations in
+isolation impact performance.
+
+<sect2>XSync() Batching
+
+<p>During the Phase I implementation, XSync() was called after every
+protocol request made by the DMX server. This provided the DMX server
+with an interactive feel, but defeated X11's protocol buffering system
+and introduced round-trip wire latency into every operation. During
+Phase II, DMX was changed so that protocol requests are no longer
+followed by calls to XSync(). Instead, the need for an XSync() is
+noted, and XSync() calls are only made every 100mS or when the DMX
+server specifically needs to make a call to guarantee interactivity.
+With this new system, X11 buffers protocol as much as possible during a
+100mS interval, and many unnecessary XSync() calls are avoided.
+
+<p>Out of more than 300 <tt/x11perf/ tests, 8 tests became more than 100
+times faster, with 68 more than 50X faster, 114 more than 10X faster,
+and 181 more than 2X faster. See table below for summary.
+
+<p>The following tests were noted to be more than 10% slower with
+XSync() batching on:
+ <verb>
+0.88 500x500 tiled rectangle (161x145 tile)
+0.89 Copy 500x500 from window to window
+ </verb>
+
+<sect2>Offscreen Optimization
+
+<p>Windows span one or more of the back-end servers' screens; however,
+during Phase I development, windows were created on every back-end
+server and every rendering request was sent to every window regardless
+of whether or not that window was visible. With the offscreen
+optimization, the DMX server tracks when a window is completely off of a
+back-end server's screen and, in that case, it does not send rendering
+requests to those back-end windows. This optimization saves bandwidth
+between the front and back-end servers, and it reduces the number of
+XSync() calls. The performance tests were run on a DMX system with only
+two back-end servers. Greater performance gains will be had as the
+number of back-end servers increases.
+
+<p>Out of more than 300 <tt/x11perf/ tests, 3 tests were at least twice as
+fast, and 146 tests were at least 10% faster. Two tests were more than
+10% slower with the offscreen optimization:
+ <verb>
+0.88 Hide/expose window via popup (4 kids)
+0.89 Resize unmapped window (75 kids)
+ </verb>
+
+<sect2>Lazy Window Creation Optimization
+
+<p>As mentioned above, during Phase I, windows were created on every
+back-end server even if they were not visible on that back-end. With
+the lazy window creation optimization, the DMX server does not create
+windows on a back-end server until they are either visible or they
+become the parents of a visible window. This optimization builds on the
+offscreen optimization (described above) and requires it to be enabled.
+
+<p>The lazy window creation optimization works by creating the window
+data structures in the front-end server when a client creates a window,
+but delays creation of the window on the back-end server(s). A private
+window structure in the DMX server saves the relevant window data and
+tracks changes to the window's attributes and stacking order for later
+use. The only times a window is created on a back-end server are (1)
+when it is mapped and is at least partially overlapping the back-end
+server's screen (tracked by the offscreen optimization), or (2) when the
+window becomes the parent of a previously visible window. The first
+case occurs when a window is mapped or when a visible window is copied,
+moved or resized and now overlaps the back-end server's screen. The
+second case occurs when starting a window manager after having created
+windows to which the window manager needs to add decorations.
+
+<p>When either case occurs, a window on the back-end server is created
+using the data saved in the DMX server's window private data structure.
+The stacking order is then adjusted to correctly place the window on the
+back-end and lastly the window is mapped. From this time forward, the
+window is handled exactly as if the window had been created at the time
+of the client's request.
+
+<p>Note that when a window is no longer visible on a back-end server's
+screen (e.g., it is moved offscreen), the window is not destroyed;
+rather, it is kept and reused later if the window once again becomes
+visible on the back-end server's screen. Originally with this
+optimization, destroying windows was implemented but was later rejected
+because it increased bandwidth when windows were opaquely moved or
+resized, which is common in many window managers.
+
+<p>The performance tests were run on a DMX system with only two back-end
+servers. Greater performance gains will be had as the number of
+back-end servers increases.
+
+<p>This optimization improved the following <tt/x11perf/ tests by more
+than 10%:
+ <verb>
+1.10 500x500 rectangle outline
+1.12 Fill 100x100 stippled trapezoid (161x145 stipple)
+1.20 Circulate Unmapped window (50 kids)
+1.19 Circulate Unmapped window (75 kids)
+ </verb>
+
+<sect2>Subdividing Rendering Primitives
+
+<p>X11 imaging requests transfer significant data between the client and
+the X server. During Phase I, the DMX server would then transfer the
+image data to each back-end server. Even with the offscreen
+optimization (above), these requests still required transferring
+significant data to each back-end server that contained a visible
+portion of the window. For example, if the client uses XPutImage() to
+copy an image to a window that overlaps the entire DMX screen, then the
+entire image is copied by the DMX server to every back-end server.
+
+<p>To reduce the amount of data transferred between the DMX server and
+the back-end servers when XPutImage() is called, the image data is
+subdivided and only the data that will be visible on a back-end server's
+screen is sent to that back-end server. Xinerama already implements a
+subdivision algorithm for XGetImage() and no further optimization was
+needed.
+
+<p>Other rendering primitives were analyzed, but the time required to
+subdivide these primitives was a significant proportion of the time
+required to send the entire rendering request to the back-end server, so
+this optimization was rejected for the other rendering primitives.
+
+<p>Again, the performance tests were run on a DMX system with only two
+back-end servers. Greater performance gains will be had as the number
+of back-end servers increases.
+
+<p>This optimization improved the following <tt/x11perf/ tests by more
+than 10%:
+ <verb>
+1.12 Fill 100x100 stippled trapezoid (161x145 stipple)
+1.26 PutImage 10x10 square
+1.83 PutImage 100x100 square
+1.91 PutImage 500x500 square
+1.40 PutImage XY 10x10 square
+1.48 PutImage XY 100x100 square
+1.50 PutImage XY 500x500 square
+1.45 Circulate Unmapped window (75 kids)
+1.74 Circulate Unmapped window (100 kids)
+ </verb>
+
+<p>The following test was noted to be more than 10% slower with this
+optimization:
+ <verb>
+0.88 10-pixel fill chord partial circle
+ </verb>
+
+<sect2>Summary of x11perf Data
+
+<p>With all of the optimizations on, 53 <tt/x11perf/ tests are more than
+100X faster than the unoptimized Phase II deliverable, with 69 more than
+50X faster, 73 more than 10X faster, and 199 more than twice as fast.
+No tests were more than 10% slower than the unoptimized Phase II
+deliverable. (Compared with the Phase I deliverable, only Circulate
+Unmapped window (100 kids) was more than 10% slower than the Phase II
+deliverable. As noted above, this test seems to have wider variability
+than other <tt/x11perf/ tests.)
+
+<p>The following table summarizes relative <tt/x11perf/ test changes for
+all optimizations individually and collectively. Note that some of the
+optimizations have a synergistic effect when used together.
+ <verb>
+
+1: XSync() batching only
+2: Off screen optimizations only
+3: Window optimizations only
+4: Subdivprims only
+5: All optimizations
+
+ 1 2 3 4 5 Operation
+------ ---- ---- ---- ------ ---------
+ 2.14 1.85 1.00 1.00 4.13 Dot
+ 1.67 1.80 1.00 1.00 3.31 1x1 rectangle
+ 2.38 1.43 1.00 1.00 2.44 10x10 rectangle
+ 1.00 1.00 0.92 0.98 1.00 100x100 rectangle
+ 1.00 1.00 1.00 1.00 1.00 500x500 rectangle
+ 1.83 1.85 1.05 1.06 3.54 1x1 stippled rectangle (8x8 stipple)
+ 2.43 1.43 1.00 1.00 2.41 10x10 stippled rectangle (8x8 stipple)
+ 0.98 1.00 1.00 1.00 1.00 100x100 stippled rectangle (8x8 stipple)
+ 1.00 1.00 1.00 1.00 0.98 500x500 stippled rectangle (8x8 stipple)
+ 1.75 1.75 1.00 1.00 3.40 1x1 opaque stippled rectangle (8x8 stipple)
+ 2.38 1.42 1.00 1.00 2.34 10x10 opaque stippled rectangle (8x8 stipple)
+ 1.00 1.00 0.97 0.97 1.00 100x100 opaque stippled rectangle (8x8 stipple)
+ 1.00 1.00 1.00 1.00 0.99 500x500 opaque stippled rectangle (8x8 stipple)
+ 1.82 1.82 1.04 1.04 3.56 1x1 tiled rectangle (4x4 tile)
+ 2.33 1.42 1.00 1.00 2.37 10x10 tiled rectangle (4x4 tile)
+ 1.00 0.92 1.00 1.00 1.00 100x100 tiled rectangle (4x4 tile)
+ 1.00 1.00 1.00 1.00 1.00 500x500 tiled rectangle (4x4 tile)
+ 1.94 1.62 1.00 1.00 3.66 1x1 stippled rectangle (17x15 stipple)
+ 1.74 1.28 1.00 1.00 1.73 10x10 stippled rectangle (17x15 stipple)
+ 1.00 1.00 1.00 0.89 0.98 100x100 stippled rectangle (17x15 stipple)
+ 1.00 1.00 1.00 1.00 0.98 500x500 stippled rectangle (17x15 stipple)
+ 1.94 1.62 1.00 1.00 3.67 1x1 opaque stippled rectangle (17x15 stipple)
+ 1.69 1.26 1.00 1.00 1.66 10x10 opaque stippled rectangle (17x15 stipple)
+ 1.00 0.95 1.00 1.00 1.00 100x100 opaque stippled rectangle (17x15 stipple)
+ 1.00 1.00 1.00 1.00 0.97 500x500 opaque stippled rectangle (17x15 stipple)
+ 1.93 1.61 0.99 0.99 3.69 1x1 tiled rectangle (17x15 tile)
+ 1.73 1.27 1.00 1.00 1.72 10x10 tiled rectangle (17x15 tile)
+ 1.00 1.00 1.00 1.00 0.98 100x100 tiled rectangle (17x15 tile)
+ 1.00 1.00 0.97 0.97 1.00 500x500 tiled rectangle (17x15 tile)
+ 1.95 1.63 1.00 1.00 3.83 1x1 stippled rectangle (161x145 stipple)
+ 1.80 1.30 1.00 1.00 1.83 10x10 stippled rectangle (161x145 stipple)
+ 0.97 1.00 1.00 1.00 1.01 100x100 stippled rectangle (161x145 stipple)
+ 1.00 1.00 1.00 1.00 0.98 500x500 stippled rectangle (161x145 stipple)
+ 1.95 1.63 1.00 1.00 3.56 1x1 opaque stippled rectangle (161x145 stipple)
+ 1.65 1.25 1.00 1.00 1.68 10x10 opaque stippled rectangle (161x145 stipple)
+ 1.00 1.00 1.00 1.00 1.01 100x100 opaque stippled rectangle (161x145...
+ 1.00 1.00 1.00 1.00 0.97 500x500 opaque stippled rectangle (161x145...
+ 1.95 1.63 0.98 0.99 3.80 1x1 tiled rectangle (161x145 tile)
+ 1.67 1.26 1.00 1.00 1.67 10x10 tiled rectangle (161x145 tile)
+ 1.13 1.14 1.14 1.14 1.14 100x100 tiled rectangle (161x145 tile)
+ 0.88 1.00 1.00 1.00 0.99 500x500 tiled rectangle (161x145 tile)
+ 1.93 1.63 1.00 1.00 3.53 1x1 tiled rectangle (216x208 tile)
+ 1.69 1.26 1.00 1.00 1.66 10x10 tiled rectangle (216x208 tile)
+ 1.00 1.00 1.00 1.00 1.00 100x100 tiled rectangle (216x208 tile)
+ 1.00 1.00 1.00 1.00 1.00 500x500 tiled rectangle (216x208 tile)
+ 1.82 1.70 1.00 1.00 3.38 1-pixel line segment
+ 2.07 1.56 0.90 1.00 3.31 10-pixel line segment
+ 1.29 1.10 1.00 1.00 1.27 100-pixel line segment
+ 1.05 1.06 1.03 1.03 1.09 500-pixel line segment
+ 1.30 1.13 1.00 1.00 1.29 100-pixel line segment (1 kid)
+ 1.32 1.15 1.00 1.00 1.32 100-pixel line segment (2 kids)
+ 1.33 1.16 1.00 1.00 1.33 100-pixel line segment (3 kids)
+ 1.92 1.64 1.00 1.00 3.73 10-pixel dashed segment
+ 1.34 1.16 1.00 1.00 1.34 100-pixel dashed segment
+ 1.24 1.11 0.99 0.97 1.23 100-pixel double-dashed segment
+ 1.72 1.77 1.00 1.00 3.25 10-pixel horizontal line segment
+ 1.83 1.66 1.01 1.00 3.54 100-pixel horizontal line segment
+ 1.86 1.30 1.00 1.00 1.84 500-pixel horizontal line segment
+ 2.11 1.52 1.00 0.99 3.02 10-pixel vertical line segment
+ 1.21 1.10 1.00 1.00 1.20 100-pixel vertical line segment
+ 1.03 1.03 1.00 1.00 1.02 500-pixel vertical line segment
+ 4.42 1.68 1.00 1.01 4.64 10x1 wide horizontal line segment
+ 1.83 1.31 1.00 1.00 1.83 100x10 wide horizontal line segment
+ 1.07 1.00 0.96 1.00 1.07 500x50 wide horizontal line segment
+ 4.10 1.67 1.00 1.00 4.62 10x1 wide vertical line segment
+ 1.50 1.24 1.06 1.06 1.48 100x10 wide vertical line segment
+ 1.06 1.03 1.00 1.00 1.05 500x50 wide vertical line segment
+ 2.54 1.61 1.00 1.00 3.61 1-pixel line
+ 2.71 1.48 1.00 1.00 2.67 10-pixel line
+ 1.19 1.09 1.00 1.00 1.19 100-pixel line
+ 1.04 1.02 1.00 1.00 1.03 500-pixel line
+ 2.68 1.51 0.98 1.00 3.17 10-pixel dashed line
+ 1.23 1.11 0.99 0.99 1.23 100-pixel dashed line
+ 1.15 1.08 1.00 1.00 1.15 100-pixel double-dashed line
+ 2.27 1.39 1.00 1.00 2.23 10x1 wide line
+ 1.20 1.09 1.00 1.00 1.20 100x10 wide line
+ 1.04 1.02 1.00 1.00 1.04 500x50 wide line
+ 1.52 1.45 1.00 1.00 1.52 100x10 wide dashed line
+ 1.54 1.47 1.00 1.00 1.54 100x10 wide double-dashed line
+ 1.97 1.30 0.96 0.95 1.95 10x10 rectangle outline
+ 1.44 1.27 1.00 1.00 1.43 100x100 rectangle outline
+ 3.22 2.16 1.10 1.09 3.61 500x500 rectangle outline
+ 1.95 1.34 1.00 1.00 1.90 10x10 wide rectangle outline
+ 1.14 1.14 1.00 1.00 1.13 100x100 wide rectangle outline
+ 1.00 1.00 1.00 1.00 1.00 500x500 wide rectangle outline
+ 1.57 1.72 1.00 1.00 3.03 1-pixel circle
+ 1.96 1.35 1.00 1.00 1.92 10-pixel circle
+ 1.21 1.07 0.86 0.97 1.20 100-pixel circle
+ 1.08 1.04 1.00 1.00 1.08 500-pixel circle
+ 1.39 1.19 1.03 1.03 1.38 100-pixel dashed circle
+ 1.21 1.11 1.00 1.00 1.23 100-pixel double-dashed circle
+ 1.59 1.28 1.00 1.00 1.58 10-pixel wide circle
+ 1.22 1.12 0.99 1.00 1.22 100-pixel wide circle
+ 1.06 1.04 1.00 1.00 1.05 500-pixel wide circle
+ 1.87 1.84 1.00 1.00 1.85 100-pixel wide dashed circle
+ 1.90 1.93 1.01 1.01 1.90 100-pixel wide double-dashed circle
+ 2.13 1.43 1.00 1.00 2.32 10-pixel partial circle
+ 1.42 1.18 1.00 1.00 1.42 100-pixel partial circle
+ 1.92 1.85 1.01 1.01 1.89 10-pixel wide partial circle
+ 1.73 1.67 1.00 1.00 1.73 100-pixel wide partial circle
+ 1.36 1.95 1.00 1.00 2.64 1-pixel solid circle
+ 2.02 1.37 1.00 1.00 2.03 10-pixel solid circle
+ 1.19 1.09 1.00 1.00 1.19 100-pixel solid circle
+ 1.02 0.99 1.00 1.00 1.01 500-pixel solid circle
+ 1.74 1.28 1.00 0.88 1.73 10-pixel fill chord partial circle
+ 1.31 1.13 1.00 1.00 1.31 100-pixel fill chord partial circle
+ 1.67 1.31 1.03 1.03 1.72 10-pixel fill slice partial circle
+ 1.30 1.13 1.00 1.00 1.28 100-pixel fill slice partial circle
+ 2.45 1.49 1.01 1.00 2.71 10-pixel ellipse
+ 1.22 1.10 1.00 1.00 1.22 100-pixel ellipse
+ 1.09 1.04 1.00 1.00 1.09 500-pixel ellipse
+ 1.90 1.28 1.00 1.00 1.89 100-pixel dashed ellipse
+ 1.62 1.24 0.96 0.97 1.61 100-pixel double-dashed ellipse
+ 2.43 1.50 1.00 1.00 2.42 10-pixel wide ellipse
+ 1.61 1.28 1.03 1.03 1.60 100-pixel wide ellipse
+ 1.08 1.05 1.00 1.00 1.08 500-pixel wide ellipse
+ 1.93 1.88 1.00 1.00 1.88 100-pixel wide dashed ellipse
+ 1.94 1.89 1.01 1.00 1.94 100-pixel wide double-dashed ellipse
+ 2.31 1.48 1.00 1.00 2.67 10-pixel partial ellipse
+ 1.38 1.17 1.00 1.00 1.38 100-pixel partial ellipse
+ 2.00 1.85 0.98 0.97 1.98 10-pixel wide partial ellipse
+ 1.89 1.86 1.00 1.00 1.89 100-pixel wide partial ellipse
+ 3.49 1.60 1.00 1.00 3.65 10-pixel filled ellipse
+ 1.67 1.26 1.00 1.00 1.67 100-pixel filled ellipse
+ 1.06 1.04 1.00 1.00 1.06 500-pixel filled ellipse
+ 2.38 1.43 1.01 1.00 2.32 10-pixel fill chord partial ellipse
+ 2.06 1.30 1.00 1.00 2.05 100-pixel fill chord partial ellipse
+ 2.27 1.41 1.00 1.00 2.27 10-pixel fill slice partial ellipse
+ 1.98 1.33 1.00 0.97 1.97 100-pixel fill slice partial ellipse
+ 57.46 1.99 1.01 1.00 114.92 Fill 1x1 equivalent triangle
+ 56.94 1.98 1.01 1.00 73.89 Fill 10x10 equivalent triangle
+ 6.07 1.75 1.00 1.00 6.07 Fill 100x100 equivalent triangle
+ 51.12 1.98 1.00 1.00 102.81 Fill 1x1 trapezoid
+ 51.42 1.82 1.01 1.00 94.89 Fill 10x10 trapezoid
+ 6.47 1.80 1.00 1.00 6.44 Fill 100x100 trapezoid
+ 1.56 1.28 1.00 0.99 1.56 Fill 300x300 trapezoid
+ 51.27 1.97 0.96 0.97 102.54 Fill 1x1 stippled trapezoid (8x8 stipple)
+ 51.73 2.00 1.02 1.02 67.92 Fill 10x10 stippled trapezoid (8x8 stipple)
+ 5.36 1.72 1.00 1.00 5.36 Fill 100x100 stippled trapezoid (8x8 stipple)
+ 1.54 1.26 1.00 1.00 1.59 Fill 300x300 stippled trapezoid (8x8 stipple)
+ 51.41 1.94 1.01 1.00 102.82 Fill 1x1 opaque stippled trapezoid (8x8 stipple)
+ 50.71 1.95 0.99 1.00 65.44 Fill 10x10 opaque stippled trapezoid (8x8...
+ 5.33 1.73 1.00 1.00 5.36 Fill 100x100 opaque stippled trapezoid (8x8...
+ 1.58 1.25 1.00 1.00 1.58 Fill 300x300 opaque stippled trapezoid (8x8...
+ 51.56 1.96 0.99 0.90 103.68 Fill 1x1 tiled trapezoid (4x4 tile)
+ 51.59 1.99 1.01 1.01 62.25 Fill 10x10 tiled trapezoid (4x4 tile)
+ 5.38 1.72 1.00 1.00 5.38 Fill 100x100 tiled trapezoid (4x4 tile)
+ 1.54 1.25 1.00 0.99 1.58 Fill 300x300 tiled trapezoid (4x4 tile)
+ 51.70 1.98 1.01 1.01 103.98 Fill 1x1 stippled trapezoid (17x15 stipple)
+ 44.86 1.97 1.00 1.00 44.86 Fill 10x10 stippled trapezoid (17x15 stipple)
+ 2.74 1.56 1.00 1.00 2.73 Fill 100x100 stippled trapezoid (17x15 stipple)
+ 1.29 1.14 1.00 1.00 1.27 Fill 300x300 stippled trapezoid (17x15 stipple)
+ 51.41 1.96 0.96 0.95 103.39 Fill 1x1 opaque stippled trapezoid (17x15...
+ 45.14 1.96 1.01 1.00 45.14 Fill 10x10 opaque stippled trapezoid (17x15...
+ 2.68 1.56 1.00 1.00 2.68 Fill 100x100 opaque stippled trapezoid (17x15...
+ 1.26 1.10 1.00 1.00 1.28 Fill 300x300 opaque stippled trapezoid (17x15...
+ 51.13 1.97 1.00 0.99 103.39 Fill 1x1 tiled trapezoid (17x15 tile)
+ 47.58 1.96 1.00 1.00 47.86 Fill 10x10 tiled trapezoid (17x15 tile)
+ 2.74 1.56 1.00 1.00 2.74 Fill 100x100 tiled trapezoid (17x15 tile)
+ 1.29 1.14 1.00 1.00 1.28 Fill 300x300 tiled trapezoid (17x15 tile)
+ 51.13 1.97 0.99 0.97 103.39 Fill 1x1 stippled trapezoid (161x145 stipple)
+ 45.14 1.97 1.00 1.00 44.29 Fill 10x10 stippled trapezoid (161x145 stipple)
+ 3.02 1.77 1.12 1.12 3.38 Fill 100x100 stippled trapezoid (161x145 stipple)
+ 1.31 1.13 1.00 1.00 1.30 Fill 300x300 stippled trapezoid (161x145 stipple)
+ 51.27 1.97 1.00 1.00 103.10 Fill 1x1 opaque stippled trapezoid (161x145...
+ 45.01 1.97 1.00 1.00 45.01 Fill 10x10 opaque stippled trapezoid (161x145...
+ 2.67 1.56 1.00 1.00 2.69 Fill 100x100 opaque stippled trapezoid (161x145..
+ 1.29 1.13 1.00 1.01 1.27 Fill 300x300 opaque stippled trapezoid (161x145..
+ 51.41 1.96 1.00 0.99 103.39 Fill 1x1 tiled trapezoid (161x145 tile)
+ 45.01 1.96 0.98 1.00 45.01 Fill 10x10 tiled trapezoid (161x145 tile)
+ 2.62 1.36 1.00 1.00 2.69 Fill 100x100 tiled trapezoid (161x145 tile)
+ 1.27 1.13 1.00 1.00 1.22 Fill 300x300 tiled trapezoid (161x145 tile)
+ 51.13 1.98 1.00 1.00 103.39 Fill 1x1 tiled trapezoid (216x208 tile)
+ 45.14 1.97 1.01 0.99 45.14 Fill 10x10 tiled trapezoid (216x208 tile)
+ 2.62 1.55 1.00 1.00 2.71 Fill 100x100 tiled trapezoid (216x208 tile)
+ 1.28 1.13 1.00 1.00 1.20 Fill 300x300 tiled trapezoid (216x208 tile)
+ 50.71 1.95 1.00 1.00 54.70 Fill 10x10 equivalent complex polygon
+ 5.51 1.71 0.96 0.98 5.47 Fill 100x100 equivalent complex polygons
+ 8.39 1.97 1.00 1.00 16.75 Fill 10x10 64-gon (Convex)
+ 8.38 1.83 1.00 1.00 8.43 Fill 100x100 64-gon (Convex)
+ 8.50 1.96 1.00 1.00 16.64 Fill 10x10 64-gon (Complex)
+ 8.26 1.83 1.00 1.00 8.35 Fill 100x100 64-gon (Complex)
+ 14.09 1.87 1.00 1.00 14.05 Char in 80-char line (6x13)
+ 11.91 1.87 1.00 1.00 11.95 Char in 70-char line (8x13)
+ 11.16 1.85 1.01 1.00 11.10 Char in 60-char line (9x15)
+ 10.09 1.78 1.00 1.00 10.09 Char16 in 40-char line (k14)
+ 6.15 1.75 1.00 1.00 6.31 Char16 in 23-char line (k24)
+ 11.92 1.90 1.03 1.03 11.88 Char in 80-char line (TR 10)
+ 8.18 1.78 1.00 0.99 8.17 Char in 30-char line (TR 24)
+ 42.83 1.44 1.01 1.00 42.11 Char in 20/40/20 line (6x13, TR 10)
+ 27.45 1.43 1.01 1.01 27.45 Char16 in 7/14/7 line (k14, k24)
+ 12.13 1.85 1.00 1.00 12.05 Char in 80-char image line (6x13)
+ 10.00 1.84 1.00 1.00 10.00 Char in 70-char image line (8x13)
+ 9.18 1.83 1.00 1.00 9.12 Char in 60-char image line (9x15)
+ 9.66 1.82 0.98 0.95 9.66 Char16 in 40-char image line (k14)
+ 5.82 1.72 1.00 1.00 5.99 Char16 in 23-char image line (k24)
+ 8.70 1.80 1.00 1.00 8.65 Char in 80-char image line (TR 10)
+ 4.67 1.66 1.00 1.00 4.67 Char in 30-char image line (TR 24)
+ 84.43 1.47 1.00 1.00 124.18 Scroll 10x10 pixels
+ 3.73 1.50 1.00 0.98 3.73 Scroll 100x100 pixels
+ 1.00 1.00 1.00 1.00 1.00 Scroll 500x500 pixels
+ 84.43 1.51 1.00 1.00 134.02 Copy 10x10 from window to window
+ 3.62 1.51 0.98 0.98 3.62 Copy 100x100 from window to window
+ 0.89 1.00 1.00 1.00 1.00 Copy 500x500 from window to window
+ 57.06 1.99 1.00 1.00 88.64 Copy 10x10 from pixmap to window
+ 2.49 2.00 1.00 1.00 2.48 Copy 100x100 from pixmap to window
+ 1.00 0.91 1.00 1.00 0.98 Copy 500x500 from pixmap to window
+ 2.04 1.01 1.00 1.00 2.03 Copy 10x10 from window to pixmap
+ 1.05 1.00 1.00 1.00 1.05 Copy 100x100 from window to pixmap
+ 1.00 1.00 0.93 1.00 1.04 Copy 500x500 from window to pixmap
+ 58.52 1.03 1.03 1.02 57.95 Copy 10x10 from pixmap to pixmap
+ 2.40 1.00 1.00 1.00 2.45 Copy 100x100 from pixmap to pixmap
+ 1.00 1.00 1.00 1.00 1.00 Copy 500x500 from pixmap to pixmap
+ 51.57 1.92 1.00 1.00 85.75 Copy 10x10 1-bit deep plane
+ 6.37 1.75 1.01 1.01 6.37 Copy 100x100 1-bit deep plane
+ 1.26 1.11 1.00 1.00 1.24 Copy 500x500 1-bit deep plane
+ 4.23 1.63 0.98 0.97 4.38 Copy 10x10 n-bit deep plane
+ 1.04 1.02 1.00 1.00 1.04 Copy 100x100 n-bit deep plane
+ 1.00 1.00 1.00 1.00 1.00 Copy 500x500 n-bit deep plane
+ 6.45 1.98 1.00 1.26 12.80 PutImage 10x10 square
+ 1.10 1.87 1.00 1.83 2.11 PutImage 100x100 square
+ 1.02 1.93 1.00 1.91 1.91 PutImage 500x500 square
+ 4.17 1.78 1.00 1.40 7.18 PutImage XY 10x10 square
+ 1.27 1.49 0.97 1.48 2.10 PutImage XY 100x100 square
+ 1.00 1.50 1.00 1.50 1.52 PutImage XY 500x500 square
+ 1.07 1.01 1.00 1.00 1.06 GetImage 10x10 square
+ 1.01 1.00 1.00 1.00 1.01 GetImage 100x100 square
+ 1.00 1.00 1.00 1.00 1.00 GetImage 500x500 square
+ 1.56 1.00 0.99 0.97 1.56 GetImage XY 10x10 square
+ 1.02 1.00 1.00 1.00 1.02 GetImage XY 100x100 square
+ 1.00 1.00 1.00 1.00 1.00 GetImage XY 500x500 square
+ 1.00 1.00 1.01 0.98 0.95 X protocol NoOperation
+ 1.02 1.03 1.04 1.03 1.00 QueryPointer
+ 1.03 1.02 1.04 1.03 1.00 GetProperty
+100.41 1.51 1.00 1.00 198.76 Change graphics context
+ 45.81 1.00 0.99 0.97 57.10 Create and map subwindows (4 kids)
+ 78.45 1.01 1.02 1.02 63.07 Create and map subwindows (16 kids)
+ 73.91 1.01 1.00 1.00 56.37 Create and map subwindows (25 kids)
+ 73.22 1.00 1.00 1.00 49.07 Create and map subwindows (50 kids)
+ 72.36 1.01 0.99 1.00 32.14 Create and map subwindows (75 kids)
+ 70.34 1.00 1.00 1.00 30.12 Create and map subwindows (100 kids)
+ 55.00 1.00 1.00 0.99 23.75 Create and map subwindows (200 kids)
+ 55.30 1.01 1.00 1.00 141.03 Create unmapped window (4 kids)
+ 55.38 1.01 1.01 1.00 163.25 Create unmapped window (16 kids)
+ 54.75 0.96 1.00 0.99 166.95 Create unmapped window (25 kids)
+ 54.83 1.00 1.00 0.99 178.81 Create unmapped window (50 kids)
+ 55.38 1.01 1.01 1.00 181.20 Create unmapped window (75 kids)
+ 55.38 1.01 1.01 1.00 181.20 Create unmapped window (100 kids)
+ 54.87 1.01 1.01 1.00 182.05 Create unmapped window (200 kids)
+ 28.13 1.00 1.00 1.00 30.75 Map window via parent (4 kids)
+ 36.14 1.01 1.01 1.01 32.58 Map window via parent (16 kids)
+ 26.13 1.00 0.98 0.95 29.85 Map window via parent (25 kids)
+ 40.07 1.00 1.01 1.00 27.57 Map window via parent (50 kids)
+ 23.26 0.99 1.00 1.00 18.23 Map window via parent (75 kids)
+ 22.91 0.99 1.00 0.99 16.52 Map window via parent (100 kids)
+ 27.79 1.00 1.00 0.99 12.50 Map window via parent (200 kids)
+ 22.35 1.00 1.00 1.00 56.19 Unmap window via parent (4 kids)
+ 9.57 1.00 0.99 1.00 89.78 Unmap window via parent (16 kids)
+ 80.77 1.01 1.00 1.00 103.85 Unmap window via parent (25 kids)
+ 96.34 1.00 1.00 1.00 116.06 Unmap window via parent (50 kids)
+ 99.72 1.00 1.00 1.00 124.93 Unmap window via parent (75 kids)
+112.36 1.00 1.00 1.00 125.27 Unmap window via parent (100 kids)
+105.41 1.00 1.00 0.99 120.00 Unmap window via parent (200 kids)
+ 51.29 1.03 1.02 1.02 74.19 Destroy window via parent (4 kids)
+ 86.75 0.99 0.99 0.99 116.87 Destroy window via parent (16 kids)
+106.43 1.01 1.01 1.01 127.49 Destroy window via parent (25 kids)
+120.34 1.01 1.01 1.00 140.11 Destroy window via parent (50 kids)
+126.67 1.00 0.99 0.99 145.00 Destroy window via parent (75 kids)
+126.11 1.01 1.01 1.00 140.56 Destroy window via parent (100 kids)
+128.57 1.01 1.00 1.00 137.91 Destroy window via parent (200 kids)
+ 16.04 0.88 1.00 1.00 20.36 Hide/expose window via popup (4 kids)
+ 19.04 1.01 1.00 1.00 23.48 Hide/expose window via popup (16 kids)
+ 19.22 1.00 1.00 1.00 20.44 Hide/expose window via popup (25 kids)
+ 17.41 1.00 0.91 0.97 17.68 Hide/expose window via popup (50 kids)
+ 17.29 1.01 1.00 1.01 17.07 Hide/expose window via popup (75 kids)
+ 16.74 1.00 1.00 1.00 16.17 Hide/expose window via popup (100 kids)
+ 10.30 1.00 1.00 1.00 10.51 Hide/expose window via popup (200 kids)
+ 16.48 1.01 1.00 1.00 26.05 Move window (4 kids)
+ 17.01 0.95 1.00 1.00 23.97 Move window (16 kids)
+ 16.95 1.00 1.00 1.00 22.90 Move window (25 kids)
+ 16.05 1.01 1.00 1.00 21.32 Move window (50 kids)
+ 15.58 1.00 0.98 0.98 19.44 Move window (75 kids)
+ 14.98 1.02 1.03 1.03 18.17 Move window (100 kids)
+ 10.90 1.01 1.01 1.00 12.68 Move window (200 kids)
+ 49.42 1.00 1.00 1.00 198.27 Moved unmapped window (4 kids)
+ 50.72 0.97 1.00 1.00 193.66 Moved unmapped window (16 kids)
+ 50.87 1.00 0.99 1.00 195.09 Moved unmapped window (25 kids)
+ 50.72 1.00 1.00 1.00 189.34 Moved unmapped window (50 kids)
+ 50.87 1.00 1.00 1.00 191.33 Moved unmapped window (75 kids)
+ 50.87 1.00 1.00 0.90 186.71 Moved unmapped window (100 kids)
+ 50.87 1.00 1.00 1.00 179.19 Moved unmapped window (200 kids)
+ 41.04 1.00 1.00 1.00 56.61 Move window via parent (4 kids)
+ 69.81 1.00 1.00 1.00 130.82 Move window via parent (16 kids)
+ 95.81 1.00 1.00 1.00 141.92 Move window via parent (25 kids)
+ 95.98 1.00 1.00 1.00 149.43 Move window via parent (50 kids)
+ 96.59 1.01 1.01 1.00 153.98 Move window via parent (75 kids)
+ 97.19 1.00 1.00 1.00 157.30 Move window via parent (100 kids)
+ 96.67 1.00 0.99 0.96 159.44 Move window via parent (200 kids)
+ 17.75 1.01 1.00 1.00 27.61 Resize window (4 kids)
+ 17.94 1.00 1.00 0.99 25.42 Resize window (16 kids)
+ 17.92 1.01 1.00 1.00 24.47 Resize window (25 kids)
+ 17.24 0.97 1.00 1.00 24.14 Resize window (50 kids)
+ 16.81 1.00 1.00 0.99 22.75 Resize window (75 kids)
+ 16.08 1.00 1.00 1.00 21.20 Resize window (100 kids)
+ 12.92 1.00 0.99 1.00 16.26 Resize window (200 kids)
+ 52.94 1.01 1.00 1.00 327.12 Resize unmapped window (4 kids)
+ 53.60 1.01 1.01 1.01 333.71 Resize unmapped window (16 kids)
+ 52.99 1.00 1.00 1.00 337.29 Resize unmapped window (25 kids)
+ 51.98 1.00 1.00 1.00 329.38 Resize unmapped window (50 kids)
+ 53.05 0.89 1.00 1.00 322.60 Resize unmapped window (75 kids)
+ 53.05 1.00 1.00 1.00 318.08 Resize unmapped window (100 kids)
+ 53.11 1.00 1.00 0.99 306.21 Resize unmapped window (200 kids)
+ 16.76 1.00 0.96 1.00 19.46 Circulate window (4 kids)
+ 17.24 1.00 1.00 0.97 16.24 Circulate window (16 kids)
+ 16.30 1.03 1.03 1.03 15.85 Circulate window (25 kids)
+ 13.45 1.00 1.00 1.00 14.90 Circulate window (50 kids)
+ 12.91 1.00 1.00 1.00 13.06 Circulate window (75 kids)
+ 11.30 0.98 1.00 1.00 11.03 Circulate window (100 kids)
+ 7.58 1.01 1.01 0.99 7.47 Circulate window (200 kids)
+ 1.01 1.01 0.98 1.00 0.95 Circulate Unmapped window (4 kids)
+ 1.07 1.07 1.01 1.07 1.02 Circulate Unmapped window (16 kids)
+ 1.04 1.09 1.06 1.05 0.97 Circulate Unmapped window (25 kids)
+ 1.04 1.23 1.20 1.18 1.05 Circulate Unmapped window (50 kids)
+ 1.18 1.53 1.19 1.45 1.24 Circulate Unmapped window (75 kids)
+ 1.08 1.02 1.01 1.74 1.01 Circulate Unmapped window (100 kids)
+ 1.01 1.12 0.98 0.91 0.97 Circulate Unmapped window (200 kids)
+ </verb>
+
+<sect2>Profiling with OProfile
+
+<p>OProfile (available from http://oprofile.sourceforge.net/) is a
+system-wide profiler for Linux systems that uses processor-level
+counters to collect sampling data. OProfile can provide information
+that is similar to that provided by <tt/gprof/, but without the
+necessity of recompiling the program with special instrumentation (i.e.,
+OProfile can collect statistical profiling information about optimized
+programs). A test harness was developed to collect OProfile data for
+each <tt/x11perf/ test individually.
+
+<p>Test runs were performed using the RETIRED_INSNS counter on the AMD
+Athlon and the CPU_CLK_HALTED counter on the Intel Pentium III (with a
+test configuration different from the one described above). We have
+examined OProfile output and have compared it with <tt/gprof/ output.
+This investigation has not produced results that yield performance
+increases in <tt/x11perf/ numbers.
+
+<!--
+<sect3>Retired Instructions
+
+<p>The initial tests using OProfile were done using the RETIRED_INSNS
+counter with DMX running on the dual-processor AMD Athlon machine - the
+same test configuration that was described above and that was used for
+other tests. The RETIRED_INSNS counter counts retired instructions and
+showed drawing, text, copying, and image tests to be dominated (&gt;
+30%) by calls to Hash(), SecurityLookupIDByClass(),
+SecurityLookupIDByType(), and StandardReadRequestFromClient(). Some of
+these tests also executed significant instructions in
+WaitForSomething().
+
+<p>In contrast, the window tests executed significant
+instructions in SecurityLookupIDByType(), Hash(),
+StandardReadRequestFromClient(), but also executed significant
+instructions in other routines, such as ConfigureWindow(). Some time
+was spent looking at Hash() function, but optimizations in this routine
+did not lead to a dramatic increase in <tt/x11perf/ performance.
+-->
+
+<!--
+<sect3>Clock Cycles
+
+<p>Retired instructions can be misleading because Intel/AMD instructions
+execute in variable amounts of time. The OProfile tests were repeated
+using the Intel CPU_CLK_HALTED counter with DMX running on the second
+back-end machine. Note that this is a different test configuration that
+the one described above. However, these tests show the amount of time
+(as measured in CPU cycles) that are spent in each routine. Because
+<tt/x11perf/ was running on the first back-end machine and because
+window optimizations were on, the load on the second back-end machine
+was not significant.
+
+<p>Using CPU_CLK_HALTED, DMX showed simple drawing
+tests spending more than 10% of their time in
+StandardReadRequestFromClient(), with significant time (&gt; 20% total)
+spent in SecurityLookupIDByClass(), WaitForSomething(), and Dispatch().
+For these tests, &lt; 5% of the time was spent in Hash(), which explains
+why optimizing the Hash() routine did not impact <tt/x11perf/ results.
+
+<p>The trapezoid, text, scrolling, copying, and image tests were
+dominated by time in ProcFillPoly(), PanoramiXFillPoly(), dmxFillPolygon(),
+SecurityLookupIDByClass(), SecurityLookupIDByType(), and
+StandardReadRequestFromClient(). Hash() time was generally above 5% but
+less than 10% of total time.
+-->
+
+<sect2>X Test Suite
+
+<p>The X Test Suite was run on the fully optimized DMX server using the
+configuration described above. The following failures were noted:
+ <verb>
+XListPixmapFormats: Test 1 [1]
+XChangeWindowAttributes: Test 32 [1]
+XCreateWindow: Test 30 [1]
+XFreeColors: Test 4 [3]
+XCopyArea: Test 13, 17, 21, 25, 30 [2]
+XCopyPlane: Test 11, 15, 27, 31 [2]
+XSetFontPath: Test 4 [1]
+XChangeKeyboardControl: Test 9, 10 [1]
+
+[1] Previously documented errors expected from the Xinerama
+ implementation (see Phase I discussion).
+[2] Newly noted errors that have been verified as expected
+ behavior of the Xinerama implementation.
+[3] Newly noted error that has been verified as a Xinerama
+ implementation bug.
+ </verb>
+
+<!-- ============================================================ -->
+<sect1>Phase III
+
+<p>During the third phase of development, support was provided for the
+following extensions: SHAPE, RENDER, XKEYBOARD, XInput.
+
+<sect2>SHAPE
+
+<p>The SHAPE extension is supported. Test applications (e.g., xeyes and
+oclock) and window managers that make use of the SHAPE extension will
+work as expected.
+
+<sect2>RENDER
+
+<p>The RENDER extension is supported. The version included in the DMX
+CVS tree is version 0.2, and this version is fully supported by Xdmx.
+Applications using only version 0.2 functions will work correctly;
+however, some apps that make use of functions from later versions do not
+properly check the extension's major/minor version numbers. These apps
+will fail with a Bad Implementation error when using post-version 0.2
+functions. This is expected behavior. When the DMX CVS tree is updated
+to include newer versions of RENDER, support for these newer functions
+will be added to the DMX X server.
+
+<sect2>XKEYBOARD
+
+<p>The XKEYBOARD extension is supported. If present on the back-end X
+servers, the XKEYBOARD extension will be used to obtain information
+about the type of the keyboard for initialization. Otherwise, the
+keyboard will be initialized using defaults. Note that this departs
+from older behavior: when Xdmx is compiled without XKEYBOARD support,
+the map from the back-end X server will be preserved. With XKEYBOARD
+support, the map is not preserved because better information and control
+of the keyboard is available.
+
+<sect2>XInput
+
+<p>The XInput extension is supported. Any device can be used as a core
+device and be used as an XInput extension device, with the exception of
+core devices on the back-end servers. This limitation is present
+because cursor handling on the back-end requires that the back-end
+cursor sometimes track the Xdmx core cursor -- behavior that is
+incompatible with using the back-end pointer as a non-core device.
+
+<p>Currently, back-end extension devices are not available as Xdmx
+extension devices, but this limitation should be removed in the future.
+
+<p>To demonstrate the XInput extension, and to provide more examples for
+low-level input device driver writers, USB device drivers have been
+written for mice (usb-mou), keyboards (usb-kbd), and
+non-mouse/non-keyboard USB devices (usb-oth). Please see the man page
+for information on Linux kernel drivers that are required for using
+these Xdmx drivers.
+
+<sect2>DPMS
+
+<p>The DPMS extension is exported but does not do anything at this time.
+
+<sect2>Other Extensions
+
+<p>The LBX,
+ SECURITY,
+ XC-APPGROUP, and
+ XFree86-Bigfont
+extensions do not require any special Xdmx support and have been exported.
+
+<p>The
+ BIG-REQUESTS,
+ DEC-XTRAP,
+ DOUBLE-BUFFER,
+ Extended-Visual-Information,
+ FontCache,
+ GLX,
+ MIT-SCREEN-SAVER,
+ MIT-SHM,
+ MIT-SUNDRY-NONSTANDARD,
+ RECORD,
+ SECURITY,
+ SGI-GLX,
+ SYNC,
+ TOG-CUP,
+ X-Resource,
+ XC-MISC,
+ XFree86-DGA,
+ XFree86-DRI,
+ XFree86-Misc,
+ XFree86-VidModeExtension, and
+ XVideo
+extensions are <it/not/ supported at this time, but will be evaluated
+for inclusion in future DMX releases. <bf>See below for additional work
+on extensions after Phase III.</bf>
+
+<sect1>Phase IV
+
+<sect2>Moving to XFree86 4.3.0
+
+<p>For Phase IV, the recent release of XFree86 4.3.0 (27 February 2003)
+was merged onto the dmx.sourceforge.net CVS trunk and all work is
+proceeding using this tree.
+
+<sect2>Extensions
+
+<sect3>XC-MISC (supported)
+
+<p>XC-MISC is used internally by the X library to recycle XIDs from the
+X server. This is important for long-running X server sessions. Xdmx
+supports this extension. The X Test Suite passed and failed the exact
+same tests before and after this extension was enabled.
+<!-- Tested February/March 2003 -->
+
+<sect3>Extended-Visual-Information (supported)
+
+<p>The Extended-Visual-Information extension provides a method for an X
+client to obtain detailed visual information. Xdmx supports this
+extension. It was tested using the <tt>hw/dmx/examples/evi</tt> example
+program. <bf/Note that this extension is not Xinerama-aware/ -- it will
+return visual information for each screen even though Xinerama is
+causing the X server to export a single logical screen.
+<!-- Tested March 2003 -->
+
+<sect3>RES (supported)
+
+<p>The X-Resource extension provides a mechanism for a client to obtain
+detailed information about the resources used by other clients. This
+extension was tested with the <tt>hw/dmx/examples/res</tt> program. The
+X Test Suite passed and failed the exact same tests before and after
+this extension was enabled.
+<!-- Tested March 2003 -->
+
+<sect3>BIG-REQUESTS (supported)
+
+<p>This extension enables the X11 protocol to handle requests longer
+than 262140 bytes. The X Test Suite passed and failed the exact same
+tests before and after this extension was enabled.
+<!-- Tested March 2003 -->
+
+<sect3>XSYNC (supported)
+
+<p>This extension provides facilities for two different X clients to
+synchronize their requests. This extension was minimally tested with
+<tt/xdpyinfo/ and the X Test Suite passed and failed the exact same
+tests before and after this extension was enabled.
+<!-- Tested March 2003 -->
+
+<sect3>XTEST, RECORD, DEC-XTRAP (supported) and XTestExtension1 (not supported)
+
+<p>The XTEST and RECORD extension were developed by the X Consortium for
+use in the X Test Suite and are supported as a standard in the X11R6
+tree. They are also supported in Xdmx. When X Test Suite tests that
+make use of the XTEST extension are run, Xdmx passes and fails exactly
+the same tests as does a standard XFree86 X server. When the
+<tt/rcrdtest/ test (a part of the X Test Suite that verifies the RECORD
+extension) is run, Xdmx passes and fails exactly the same tests as does
+a standard XFree86 X server. <!-- Tested February/March 2003 -->
+
+<p>There are two older XTEST-like extensions: DEC-XTRAP and
+XTestExtension1. The XTestExtension1 extension was developed for use by
+the X Testing Consortium for use with a test suite that eventually
+became (part of?) the X Test Suite. Unlike XTEST, which only allows
+events to be sent to the server, the XTestExtension1 extension also
+allowed events to be recorded (similar to the RECORD extension). The
+second is the DEC-XTRAP extension that was developed by the Digital
+Equipment Corporation.
+
+<p>The DEC-XTRAP extension is available from Xdmx and has been tested
+with the <tt/xtrap*/ tools which are distributed as standard X11R6
+clients. <!-- Tested March 2003 -->
+
+<p>The XTestExtension1 is <em/not/ supported because it does not appear
+to be used by any modern X clients (the few that support it also support
+XTEST) and because there are no good methods available for testing that
+it functions correctly (unlike XTEST and DEC-XTRAP, the code for
+XTestExtension1 is not part of the standard X server source tree, so
+additional testing is important). <!-- Tested March 2003 -->
+
+<p>Most of these extensions are documented in the X11R6 source tree.
+Further, several original papers exist that this author was unable to
+locate -- for completeness and historical interest, citations are
+provide:
+<descrip>
+<tag/XRECORD/ Martha Zimet. Extending X For Recording. 8th Annual X
+Technical Conference Boston, MA January 24-26, 1994.
+<tag/DEC-XTRAP/ Dick Annicchiarico, Robert Chesler, Alan Jamison. XTrap
+Architecture. Digital Equipment Corporation, July 1991.
+<tag/XTestExtension1/ Larry Woestman. X11 Input Synthesis Extension
+Proposal. Hewlett Packard, November 1991.
+</descrip>
+
+<sect3>MIT-MISC (not supported)
+
+<p>The MIT-MISC extension is used to control a bug-compatibility flag
+that provides compatibility with xterm programs from X11R1 and X11R2.
+There does not appear to be a single client available that makes use of
+this extension and there is not way to verify that it works correctly.
+The Xdmx server does <em/not/ support MIT-MISC.
+
+<sect3>SCREENSAVER (not supported)
+
+<p>This extension provides special support for the X screen saver. It
+was tested with beforelight, which appears to be the only client that
+works with it. When Xinerama was not active, <tt/beforelight/ behaved
+as expected. However, when Xinerama was active, <tt/beforelight/ did
+not behave as expected. Further, when this extension is not active,
+<tt/xscreensaver/ (a widely-used X screen saver program) did not behave
+as expected. Since this extension is not Xinerama-aware and is not
+commonly used with expected results by clients, we have left this
+extension disabled at this time.
+
+<sect3>GLX (supported)
+
+<p>The GLX extension provides OpenGL and GLX windowing support. In
+Xdmx, the extension is called glxProxy, and it is Xinerama aware. It
+works by either feeding requests forward through Xdmx to each of the
+back-end servers or handling them locally. All rendering requests are
+handled on the back-end X servers. This code was donated to the DMX
+project by SGI. For the X Test Suite results comparison, see below.
+
+<sect3>RENDER (supported)
+
+<p>The X Rendering Extension (RENDER) provides support for digital image
+composition. Geometric and text rendering are supported. RENDER is
+partially Xinerama-aware, with text and the most basic compositing
+operator; however, its higher level primitives (triangles, triangle
+strips, and triangle fans) are not yet Xinerama-aware. The RENDER
+extension is still under development, and is currently at version 0.8.
+Additional support will be required in DMX as more primitives and/or
+requests are added to the extension.
+
+<p>There is currently no test suite for the X Rendering Extension;
+however, there has been discussion of developing a test suite as the
+extension matures. When that test suite becomes available, additional
+testing can be performed with Xdmx. The X Test Suite passed and failed
+the exact same tests before and after this extension was enabled.
+
+<sect3>Summary
+
+<!-- WARNING: this list is duplicated in the "Common X extension
+support" section -->
+<p>To summarize, the following extensions are currently supported:
+ BIG-REQUESTS,
+ DEC-XTRAP,
+ DMX,
+ DPMS,
+ Extended-Visual-Information,
+ GLX,
+ LBX,
+ RECORD,
+ RENDER,
+ SECURITY,
+ SHAPE,
+ SYNC,
+ X-Resource,
+ XC-APPGROUP,
+ XC-MISC,
+ XFree86-Bigfont,
+ XINERAMA,
+ XInputExtension,
+ XKEYBOARD, and
+ XTEST.
+
+<p>The following extensions are <em/not/ supported at this time:
+ DOUBLE-BUFFER,
+ FontCache,
+ MIT-SCREEN-SAVER,
+ MIT-SHM,
+ MIT-SUNDRY-NONSTANDARD,
+ TOG-CUP,
+ XFree86-DGA,
+ XFree86-Misc,
+ XFree86-VidModeExtension,
+ XTestExtensionExt1, and
+ XVideo.
+
+<sect2>Additional Testing with the X Test Suite
+
+<sect3>XFree86 without XTEST
+
+<p>After the release of XFree86 4.3.0, we retested the XFree86 X server
+with and without using the XTEST extension. When the XTEST extension
+was <em/not/ used for testing, the XFree86 4.3.0 server running on our
+usual test system with a Radeon VE card reported unexpected failures in
+the following tests:
+<verb>
+XListPixmapFormats: Test 1
+XChangeKeyboardControl: Tests 9, 10
+XGetDefault: Test 5
+XRebindKeysym: Test 1
+</verb>
+
+<sect3>XFree86 with XTEST
+
+<p>When using the XTEST extension, the XFree86 4.3.0 server reported the
+following errors:
+<verb>
+XListPixmapFormats: Test 1
+XChangeKeyboardControl: Tests 9, 10
+XGetDefault: Test 5
+XRebindKeysym: Test 1
+
+XAllowEvents: Tests 20, 21, 24
+XGrabButton: Tests 5, 9-12, 14, 16, 19, 21-25
+XGrabKey: Test 8
+XSetPointerMapping: Test 3
+XUngrabButton: Test 4
+</verb>
+
+<p>While these errors may be important, they will probably be fixed
+eventually in the XFree86 source tree. We are particularly interested
+in demonstrating that the Xdmx server does not introduce additional
+failures that are not known Xinerama failures.
+
+<sect3>Xdmx with XTEST, without Xinerama, without GLX
+
+<p>Without Xinerama, but using the XTEST extension, the following errors
+were reported from Xdmx (note that these are the same as for the XFree86
+4.3.0, except that XGetDefault no longer fails):
+<verb>
+XListPixmapFormats: Test 1
+XChangeKeyboardControl: Tests 9, 10
+XRebindKeysym: Test 1
+
+XAllowEvents: Tests 20, 21, 24
+XGrabButton: Tests 5, 9-12, 14, 16, 19, 21-25
+XGrabKey: Test 8
+XSetPointerMapping: Test 3
+XUngrabButton: Test 4
+</verb>
+
+<sect3>Xdmx with XTEST, with Xinerama, without GLX
+
+<p>With Xinerama, using the XTEST extension, the following errors
+were reported from Xdmx:
+<verb>
+XListPixmapFormats: Test 1
+XChangeKeyboardControl: Tests 9, 10
+XRebindKeysym: Test 1
+
+XAllowEvents: Tests 20, 21, 24
+XGrabButton: Tests 5, 9-12, 14, 16, 19, 21-25
+XGrabKey: Test 8
+XSetPointerMapping: Test 3
+XUngrabButton: Test 4
+
+XCopyPlane: Tests 13, 22, 31 (well-known XTEST/Xinerama interaction issue)
+XDrawLine: Test 67
+XDrawLines: Test 91
+XDrawSegments: Test 68
+</verb>
+Note that the first two sets of errors are the same as for the XFree86
+4.3.0 server, and that the XCopyPlane error is a well-known error
+resulting from an XTEST/Xinerama interaction when the request crosses a
+screen boundary. The XDraw* errors are resolved when the tests are run
+individually and they do not cross a screen boundary. We will
+investigate these errors further to determine their cause.
+
+<sect3>Xdmx with XTEST, with Xinerama, with GLX
+
+<p>With GLX enabled, using the XTEST extension, the following errors
+were reported from Xdmx (these results are from early during the Phase
+IV development, but were confirmed with a late Phase IV snapshot):
+<verb>
+XListPixmapFormats: Test 1
+XChangeKeyboardControl: Tests 9, 10
+XRebindKeysym: Test 1
+
+XAllowEvents: Tests 20, 21, 24
+XGrabButton: Tests 5, 9-12, 14, 16, 19, 21-25
+XGrabKey: Test 8
+XSetPointerMapping: Test 3
+XUngrabButton: Test 4
+
+XClearArea: Test 8
+XCopyArea: Tests 4, 5, 11, 14, 17, 23, 25, 27, 30
+XCopyPlane: Tests 6, 7, 10, 19, 22, 31
+XDrawArcs: Tests 89, 100, 102
+XDrawLine: Test 67
+XDrawSegments: Test 68
+</verb>
+Note that the first two sets of errors are the same as for the XFree86
+4.3.0 server, and that the third set has different failures than when
+Xdmx does not include GLX support. Since the GLX extension adds new
+visuals to support GLX's visual configs and the X Test Suite runs tests
+over the entire set of visuals, additional rendering tests were run and
+presumably more of them crossed a screen boundary. This conclusion is
+supported by the fact that nearly all of the rendering errors reported
+are resolved when the tests are run individually and they do no cross a
+screen boundary.
+
+<p>Further, when hardware rendering is disabled on the back-end displays,
+many of the errors in the third set are eliminated, leaving only:
+<verb>
+XClearArea: Test 8
+XCopyArea: Test 4, 5, 11, 14, 17, 23, 25, 27, 30
+XCopyPlane: Test 6, 7, 10, 19, 22, 31
+</verb>
+
+<sect3>Conclusion
+
+<p>We conclude that all of the X Test Suite errors reported for Xdmx are
+the result of errors in the back-end X server or the Xinerama
+implementation. Further, all of these errors that can be reasonably
+fixed at the Xdmx layer have been. (Where appropriate, we have
+submitted patches to the XFree86 and Xinerama upstream maintainers.)
+
+<sect2>Dynamic Reconfiguration
+
+<p>During this development phase, dynamic reconfiguration support was
+added to DMX. This support allows an application to change the position
+and offset of a back-end server's screen. For example, if the
+application would like to shift a screen slightly to the left, it could
+query Xdmx for the screen's &lt;x,y&gt; position and then dynamically
+reconfigure that screen to be at position &lt;x+10,y&gt;. When a screen
+is dynamically reconfigured, input handling and a screen's root window
+dimensions are adjusted as needed. These adjustments are transparent to
+the user.
+
+<sect3>Dynamic reconfiguration extension
+
+<p>The application interface to DMX's dynamic reconfiguration is through
+a function in the DMX extension library:
+<verb>
+Bool DMXReconfigureScreen(Display *dpy, int screen, int x, int y)
+</verb>
+where <it/dpy/ is DMX server's display, <it/screen/ is the number of the
+screen to be reconfigured, and <it/x/ and <it/y/ are the new upper,
+left-hand coordinates of the screen to be reconfigured.
+
+<p>The coordinates are not limited other than as required by the X
+protocol, which limits all coordinates to a signed 16 bit number. In
+addition, all coordinates within a screen must also be legal values.
+Therefore, setting a screen's upper, left-hand coordinates such that the
+right or bottom edges of the screen is greater than 32,767 is illegal.
+
+<sect3>Bounding box
+
+<p>When the Xdmx server is started, a bounding box is calculated from
+the screens' layout given either on the command line or in the
+configuration file. This bounding box is currently fixed for the
+lifetime of the Xdmx server.
+
+<p>While it is possible to move a screen outside of the bounding box, it
+is currently not possible to change the dimensions of the bounding box.
+For example, it is possible to specify coordinates of &lt;-100,-100&gt;
+for the upper, left-hand corner of the bounding box, which was
+previously at coordinates &lt;0,0&gt;. As expected, the screen is moved
+down and to the right; however, since the bounding box is fixed, the
+left side and upper portions of the screen exposed by the
+reconfiguration are no longer accessible on that screen. Those
+inaccessible regions are filled with black.
+
+<p>This fixed bounding box limitation will be addressed in a future
+development phase.
+
+<sect3>Sample applications
+
+<p>An example of where this extension is useful is in setting up a video
+wall. It is not always possible to get everything perfectly aligned,
+and sometimes the positions are changed (e.g., someone might bump into a
+projector). Instead of physically moving projectors or monitors, it is
+now possible to adjust the positions of the back-end server's screens
+using the dynamic reconfiguration support in DMX.
+
+<p>Other applications, such as automatic setup and calibration tools,
+can make use of dynamic reconfiguration to correct for projector
+alignment problems, as long as the projectors are still arranged
+rectilinearly. Horizontal and vertical keystone correction could be
+applied to projectors to correct for non-rectilinear alignment problems;
+however, this must be done external to Xdmx.
+
+<p>A sample test program is included in the DMX server's examples
+directory to demonstrate the interface and how an application might use
+dynamic reconfiguration. See <tt/dmxreconfig.c/ for details.
+
+<sect3>Additional notes
+
+<p>In the original development plan, Phase IV was primarily devoted to
+adding OpenGL support to DMX; however, SGI became interested in the DMX
+project and developed code to support OpenGL/GLX. This code was later
+donated to the DMX project and integrated into the DMX code base, which
+freed the DMX developers to concentrate on dynamic reconfiguration (as
+described above).
+
+<sect2>Doxygen documentation
+
+<p>Doxygen is an open-source (GPL) documentation system for generating
+browseable documentation from stylized comments in the source code. We
+have placed all of the Xdmx server and DMX protocol source code files
+under Doxygen so that comprehensive documentation for the Xdmx source
+code is available in an easily browseable format.
+
+<sect2>Valgrind
+
+<p>Valgrind, an open-source (GPL) memory debugger for Linux, was used to
+search for memory management errors. Several memory leaks were detected
+and repaired. The following errors were not addressed:
+<enum>
+ <item>
+ When the X11 transport layer sends a reply to the client, only
+ those fields that are required by the protocol are filled in --
+ unused fields are left as uninitialized memory and are therefore
+ noted by valgrind. These instances are not errors and were not
+ repaired.
+ <item>
+ At each server generation, glxInitVisuals allocates memory that
+ is never freed. The amount of memory lost each generation
+ approximately equal to 128 bytes for each back-end visual.
+ Because the code involved is automatically generated, this bug
+ has not been fixed and will be referred to SGI.
+ <item>
+ At each server generation, dmxRealizeFont calls XLoadQueryFont,
+ which allocates a font structure that is not freed.
+ dmxUnrealizeFont can free the font structure for the first
+ screen, but cannot free it for the other screens since they are
+ already closed by the time dmxUnrealizeFont could free them.
+ The amount of memory lost each generation is approximately equal
+ to 80 bytes per font per back-end. When this bug is fixed in
+ the the X server's device-independent (dix) code, DMX will be
+ able to properly free the memory allocated by XLoadQueryFont.
+</enum>
+
+<sect2>RATS
+
+<p>RATS (Rough Auditing Tool for Security) is an open-source (GPL)
+security analysis tool that scans source code for common
+security-related programming errors (e.g., buffer overflows and TOCTOU
+races). RATS was used to audit all of the code in the hw/dmx directory
+and all "High" notations were checked manually. The code was either
+re-written to eliminate the warning, or a comment containing "RATS" was
+inserted on the line to indicate that a human had checked the code.
+Unrepaired warnings are as follows:
+<enum>
+ <item>
+ Fixed-size buffers are used in many areas, but code has been
+ added to protect against buffer overflows (e.g., XmuSnprint).
+ The only instances that have not yet been fixed are in
+ config/xdmxconfig.c (which is not part of the Xdmx server) and
+ input/usb-common.c.
+ <item>
+ vprintf and vfprintf are used in the logging routines. In
+ general, all uses of these functions (e.g., dmxLog) provide a
+ constant format string from a trusted source, so the use is
+ relatively benign.
+ <item>
+ glxProxy/glxscreens.c uses getenv and strcat. The use of these
+ functions is safe and will remain safe as long as
+ ExtensionsString is longer then GLXServerExtensions (ensuring
+ this may not be ovious to the casual programmer, but this is in
+ automatically generated code, so we hope that the generator
+ enforces this constraint).
+</enum>
+
+ </article>
+
+ <!-- Local Variables: -->
+ <!-- fill-column: 72 -->
+ <!-- End: -->
diff --git a/xorg-server/hw/dmx/glxProxy/glxcmds.c b/xorg-server/hw/dmx/glxProxy/glxcmds.c
index 31fd431e7..a2fe0b27b 100644
--- a/xorg-server/hw/dmx/glxProxy/glxcmds.c
+++ b/xorg-server/hw/dmx/glxProxy/glxcmds.c
@@ -1,3610 +1,3610 @@
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, 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 including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * 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
- * SILICON GRAPHICS, INC. 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 Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
-
-#include "dmx.h"
-#include "dmxwindow.h"
-#include "dmxpixmap.h"
-#include "dmxfont.h"
-#include "dmxsync.h"
-
-#undef Xmalloc
-#undef Xcalloc
-#undef Xrealloc
-#undef Xfree
-
-#include "glxserver.h"
-#include <GL/glxtokens.h>
-#include "g_disptab.h"
-#include <pixmapstr.h>
-#include <windowstr.h>
-#include "glxutil.h"
-#include "glxext.h"
-#include "unpack.h"
-
-#include "GL/glxproto.h"
-#include "glxvendor.h"
-#include "glxvisuals.h"
-#include "glxswap.h"
-
-#ifdef PANORAMIX
-#include "panoramiXsrv.h"
-#endif
-
-extern __GLXFBConfig **__glXFBConfigs;
-extern int __glXNumFBConfigs;
-
-extern __GLXFBConfig *glxLookupFBConfig( GLXFBConfigID id );
-extern __GLXFBConfig *glxLookupFBConfigByVID( VisualID vid );
-extern __GLXFBConfig *glxLookupBackEndFBConfig( GLXFBConfigID id, int screen );
-extern int glxIsExtensionSupported( char *ext );
-extern int __glXGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc);
-
-#define BE_TO_CLIENT_ERROR(x) \
- ( (x) >= __glXerrorBase ? \
- (x) - dmxScreen->glxErrorBase + __glXerrorBase \
- : (x) )
-
-Display *GetBackEndDisplay( __GLXclientState *cl, int s )
-{
- if (! cl->be_displays[s] ) {
- cl->be_displays[s] = XOpenDisplay( DisplayString(dmxScreens[s].beDisplay) );
- }
- return( cl->be_displays[s] );
-}
-
-/*
-** Create a GL context with the given properties.
-*/
-static int CreateContext(__GLXclientState *cl,
- GLXContextID gcId,
- VisualID vid, GLXFBConfigID fbconfigId,
- int screen,
- GLXContextID shareList,
- int isDirect )
-{
- ClientPtr client = cl->client;
- xGLXCreateContextReq *be_req;
- xGLXCreateNewContextReq *be_new_req;
- VisualPtr pVisual;
- ScreenPtr pScreen;
- __GLXcontext *glxc, *shareglxc;
- __GLXvisualConfig *pGlxVisual;
- __GLXscreenInfo *pGlxScreen;
- VisualID visual = vid;
- GLint i;
- int from_screen = screen;
- int to_screen = screen;
- DMXScreenInfo *dmxScreen;
- VisualID be_vid;
- GLXFBConfigID be_fbconfigId;
- int num_be_screens;
- Display *dpy;
-
- /*
- ** Check if screen exists.
- */
- if (screen >= screenInfo.numScreens) {
- client->errorValue = screen;
- return BadValue;
- }
-
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
- /*
- ** Find the display list space that we want to share.
- **
- */
- if (shareList == None) {
- shareglxc = NULL;
- } else {
- shareglxc = (__GLXcontext *) LookupIDByType(shareList, __glXContextRes);
- if (!shareglxc) {
- client->errorValue = shareList;
- return __glXBadContext;
- }
- }
-
- /*
- ** Allocate memory for the new context
- */
- glxc = __glXCalloc(1, sizeof(__GLXcontext));
- if (!glxc) {
- return BadAlloc;
- }
-
- pScreen = screenInfo.screens[screen];
- pGlxScreen = &__glXActiveScreens[screen];
-
- if (fbconfigId != None) {
- glxc->pFBConfig = glxLookupFBConfig( fbconfigId );
- if (!glxc->pFBConfig) {
- client->errorValue = fbconfigId;
- __glXFree( glxc );
- return BadValue;
- }
- visual = glxc->pFBConfig->associatedVisualId;
- }
- else {
- glxc->pFBConfig = NULL;
- }
-
- if (visual != None) {
- /*
- ** Check if the visual ID is valid for this screen.
- */
- pVisual = pScreen->visuals;
- for (i = 0; i < pScreen->numVisuals; i++, pVisual++) {
- if (pVisual->vid == visual) {
- break;
- }
- }
- if (i == pScreen->numVisuals) {
- client->errorValue = visual;
- __glXFree( glxc );
- return BadValue;
- }
-
- pGlxVisual = pGlxScreen->pGlxVisual;
- for (i = 0; i < pGlxScreen->numVisuals; i++, pGlxVisual++) {
- if (pGlxVisual->vid == visual) {
- break;
- }
- }
- if (i == pGlxScreen->numVisuals) {
- /*
- ** Visual not support on this screen by this OpenGL implementation.
- */
- client->errorValue = visual;
- __glXFree( glxc );
- return BadValue;
- }
-
- if ( glxc->pFBConfig == NULL ) {
- glxc->pFBConfig = glxLookupFBConfigByVID( visual );
-
- if ( glxc->pFBConfig == NULL ) {
- /*
- * visual does not have an FBConfig ???
- client->errorValue = visual;
- __glXFree( glxc );
- return BadValue;
- */
- }
- }
- }
- else {
- pVisual = NULL;
- pGlxVisual = NULL;
- }
-
- glxc->pScreen = pScreen;
- glxc->pGlxScreen = pGlxScreen;
- glxc->pVisual = pVisual;
- glxc->pGlxVisual = pGlxVisual;
-
- /*
- * allocate memory for back-end servers info
- */
- num_be_screens = to_screen - from_screen + 1;
- glxc->real_ids = (XID *)__glXMalloc(sizeof(XID) * num_be_screens);
- if (!glxc->real_ids) {
- return BadAlloc;
- }
- glxc->real_vids = (XID *)__glXMalloc(sizeof(XID) * num_be_screens);
- if (!glxc->real_vids) {
- return BadAlloc;
- }
-
- for (screen = from_screen; screen <= to_screen; screen++) {
- int sent = 0;
- pScreen = screenInfo.screens[screen];
- pGlxScreen = &__glXActiveScreens[screen];
- dmxScreen = &dmxScreens[screen];
-
- if (glxc->pFBConfig) {
- __GLXFBConfig *beFBConfig = glxLookupBackEndFBConfig( glxc->pFBConfig->id,
- screen );
- be_fbconfigId = beFBConfig->id;
- }
-
- if (pGlxVisual) {
-
- be_vid = glxMatchGLXVisualInConfigList( pGlxVisual,
- dmxScreen->glxVisuals,
- dmxScreen->numGlxVisuals );
-
- if (!be_vid) {
- /* visual is not supported on the back-end server */
- __glXFree( glxc->real_ids );
- __glXFree( glxc->real_vids );
- __glXFree( glxc );
- return BadValue;
- }
- }
-
- glxc->real_ids[screen-from_screen] = XAllocID(GetBackEndDisplay(cl,screen));
-
- /* send the create context request to the back-end server */
- dpy = GetBackEndDisplay(cl,screen);
- if (glxc->pFBConfig) {
- /*Since for a certain visual both RGB and COLOR INDEX
- *can be on then the only parmeter to choose the renderType
- * should be the class of the colormap since all 4 first
- * classes does not support RGB mode only COLOR INDEX ,
- * and so TrueColor and DirectColor does not support COLOR INDEX*/
- int renderType = glxc->pFBConfig->renderType;
- if ( pVisual ) {
- switch ( pVisual->class ){
- case PseudoColor:
- case StaticColor:
- case GrayScale:
- case StaticGray:
- renderType = GLX_COLOR_INDEX_TYPE;
- break;
- case TrueColor:
- case DirectColor:
- default:
- renderType = GLX_RGBA_TYPE;
- break;
- }
- }
- if ( __GLX_IS_VERSION_SUPPORTED(1,3) ) {
- LockDisplay(dpy);
- GetReq(GLXCreateNewContext,be_new_req);
- be_new_req->reqType = dmxScreen->glxMajorOpcode;
- be_new_req->glxCode = X_GLXCreateNewContext;
- be_new_req->context = (unsigned int)glxc->real_ids[screen-from_screen];
- be_new_req->fbconfig = (unsigned int)be_fbconfigId;
- be_new_req->screen = DefaultScreen(dpy);
- be_new_req->renderType = renderType;
-
- be_new_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0);
- be_new_req->isDirect = 0;
- UnlockDisplay(dpy);
- glxc->real_vids[screen-from_screen] = be_fbconfigId;
- sent = 1;
- }
- else if (glxIsExtensionSupported("GLX_SGIX_fbconfig")) {
-
- xGLXCreateContextWithConfigSGIXReq *ext_req;
- xGLXVendorPrivateReq *vpreq;
- LockDisplay(dpy);
- GetReqExtra(GLXVendorPrivate,
- sz_xGLXCreateContextWithConfigSGIXReq - sz_xGLXVendorPrivateReq,
- vpreq);
- ext_req = (xGLXCreateContextWithConfigSGIXReq *)vpreq;
- ext_req->reqType = dmxScreen->glxMajorOpcode;
- ext_req->glxCode = X_GLXVendorPrivate;
- ext_req->vendorCode = X_GLXvop_CreateContextWithConfigSGIX;
- ext_req->context = (unsigned int)glxc->real_ids[screen-from_screen];
- ext_req->fbconfig = (unsigned int)be_fbconfigId;
- ext_req->screen = DefaultScreen(dpy);
- ext_req->renderType = renderType;
- ext_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0);
- ext_req->isDirect = 0;
- UnlockDisplay(dpy);
- glxc->real_vids[screen-from_screen] = be_fbconfigId;
- sent = 1;
- }
- }
-
- if (!sent) {
- LockDisplay(dpy);
- GetReq(GLXCreateContext,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXCreateContext;
- be_req->context = (unsigned int)glxc->real_ids[screen-from_screen];
- be_req->visual = (unsigned int)be_vid;
- be_req->screen = DefaultScreen(dpy);
- be_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0);
- be_req->isDirect = 0;
- UnlockDisplay(dpy);
- glxc->real_vids[screen-from_screen] = be_vid;
- }
- SyncHandle();
-
- }
-
- /*
- ** Register this context as a resource.
- */
- if (!AddResource(gcId, __glXContextRes, (pointer)glxc)) {
- __glXFree( glxc->real_ids );
- __glXFree( glxc->real_vids );
- __glXFree( glxc );
- client->errorValue = gcId;
- return BadAlloc;
- }
-
- /*
- ** Finally, now that everything is working, setup the rest of the
- ** context.
- */
- glxc->id = gcId;
- glxc->share_id = shareList;
- glxc->idExists = GL_TRUE;
- glxc->isCurrent = GL_FALSE;
-
- return Success;
-}
-
-int __glXCreateContext(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
-
- return( CreateContext(cl, req->context,req->visual, None,
- req->screen, req->shareList, req->isDirect) );
-
-}
-
-int __glXCreateNewContext(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
-
- return( CreateContext(cl, req->context,None, req->fbconfig,
- req->screen, req->shareList, req->isDirect) );
-
-}
-
-int __glXCreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreateContextWithConfigSGIXReq *req = (xGLXCreateContextWithConfigSGIXReq *) pc;
-
- return( CreateContext(cl, req->context, None, req->fbconfig,
- req->screen, req->shareList, req->isDirect) );
-
-}
-
-int __glXQueryMaxSwapBarriersSGIX(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXQueryMaxSwapBarriersSGIXReq *req =
- (xGLXQueryMaxSwapBarriersSGIXReq *)pc;
- xGLXQueryMaxSwapBarriersSGIXReply reply;
-
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
- reply.length = 0;
- reply.max = QueryMaxSwapBarriersSGIX(req->screen);
-
- if (client->swapped) {
- __glXSwapQueryMaxSwapBarriersSGIXReply(client, &reply);
- } else {
- WriteToClient(client, sz_xGLXQueryMaxSwapBarriersSGIXReply,
- (char *)&reply);
- }
-
- return Success;
-}
-
-int __glXBindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXBindSwapBarrierSGIXReq *req = (xGLXBindSwapBarrierSGIXReq *)pc;
- DrawablePtr pDraw;
- __GLXpixmap *pGlxPixmap = NULL;
- __glXWindow *pGlxWindow = NULL;
- int rc;
-
- rc = dixLookupDrawable(&pDraw, req->drawable, client, 0, DixGetAttrAccess);
- if (rc != Success) {
- pGlxPixmap = (__GLXpixmap *) LookupIDByType(req->drawable,
- __glXPixmapRes);
- if (pGlxPixmap) pDraw = pGlxPixmap->pDraw;
- }
-
- if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
- pGlxWindow = (__glXWindow *) LookupIDByType(req->drawable,
- __glXWindowRes);
- if (pGlxWindow) pDraw = pGlxWindow->pDraw;
- }
-
- if (!pDraw) {
- client->errorValue = req->drawable;
- return __glXBadDrawable;
- }
-
- return BindSwapBarrierSGIX(pDraw, req->barrier);
-}
-
-int __glXJoinSwapGroupSGIX(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXJoinSwapGroupSGIXReq *req = (xGLXJoinSwapGroupSGIXReq *)pc;
- DrawablePtr pDraw, pMember = NULL;
- __GLXpixmap *pGlxPixmap = NULL;
- __glXWindow *pGlxWindow = NULL;
- int rc;
-
- rc = dixLookupDrawable(&pDraw, req->drawable, client, 0, DixManageAccess);
- if (rc != Success) {
- pGlxPixmap = (__GLXpixmap *) LookupIDByType(req->drawable,
- __glXPixmapRes);
- if (pGlxPixmap) pDraw = pGlxPixmap->pDraw;
- }
-
- if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
- pGlxWindow = (__glXWindow *) LookupIDByType(req->drawable,
- __glXWindowRes);
- if (pGlxWindow) pDraw = pGlxWindow->pDraw;
- }
-
- if (!pDraw) {
- client->errorValue = req->drawable;
- return __glXBadDrawable;
- }
-
- if (req->member != None) {
- rc = dixLookupDrawable(&pMember, req->member, client, 0,
- DixGetAttrAccess);
- if (rc != Success) {
- pGlxPixmap = (__GLXpixmap *) LookupIDByType(req->member,
- __glXPixmapRes);
- if (pGlxPixmap) pMember = pGlxPixmap->pDraw;
- }
-
- if (!pMember && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
- pGlxWindow = (__glXWindow *) LookupIDByType(req->member,
- __glXWindowRes);
- if (pGlxWindow) pMember = pGlxWindow->pDraw;
- }
-
- if (!pMember) {
- client->errorValue = req->member;
- return __glXBadDrawable;
- }
- }
-
- return JoinSwapGroupSGIX(pDraw, pMember);
-}
-
-
-/*
-** Destroy a GL context as an X resource.
-*/
-int __glXDestroyContext(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc;
- xGLXDestroyContextReq *be_req;
- GLXContextID gcId = req->context;
- __GLXcontext *glxc;
- int from_screen = 0;
- int to_screen = 0;
- int s;
-
- glxc = (__GLXcontext *) LookupIDByType(gcId, __glXContextRes);
- if (glxc) {
- /*
- ** Just free the resource; don't actually destroy the context,
- ** because it might be in use. The
- ** destroy method will be called by the resource destruction routine
- ** if necessary.
- */
- FreeResourceByType(gcId, __glXContextRes, FALSE);
-
- from_screen = to_screen = glxc->pScreen->myNum;
-
- } else {
- client->errorValue = gcId;
- return __glXBadContext;
- }
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
- /*
- * send DestroyContext request to all back-end servers
- */
- for (s=from_screen; s<=to_screen; s++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
- Display *dpy = GetBackEndDisplay(cl,s);
-
- LockDisplay(dpy);
- GetReq(GLXDestroyContext,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXDestroyContext;
- be_req->context = glxc->real_ids[s-from_screen];
- UnlockDisplay(dpy);
- SyncHandle();
- }
-
- return Success;
-}
-
-/*****************************************************************************/
-
-/*
-** For each client, the server keeps a table of all the contexts that are
-** current for that client (each thread of a client may have its own current
-** context). These routines add, change, and lookup contexts in the table.
-*/
-
-/*
-** Add a current context, and return the tag that will be used to refer to it.
-*/
-static int AddCurrentContext(__GLXclientState *cl, __GLXcontext *glxc, DrawablePtr pDraw)
-{
- int i;
- int num = cl->numCurrentContexts;
- __GLXcontext **table = cl->currentContexts;
-
- if (!glxc) return -1;
-
- /*
- ** Try to find an empty slot and use it.
- */
- for (i=0; i < num; i++) {
- if (!table[i]) {
- table[i] = glxc;
- return i+1;
- }
- }
- /*
- ** Didn't find a free slot, so we'll have to grow the table.
- */
- if (!num) {
- table = (__GLXcontext **) __glXMalloc(sizeof(__GLXcontext *));
- cl->currentDrawables = (DrawablePtr *) __glXMalloc(sizeof(DrawablePtr));
- cl->be_currentCTag = (GLXContextTag *) __glXMalloc(screenInfo.numScreens *sizeof(GLXContextTag));
- } else {
- table = (__GLXcontext **) __glXRealloc(table,
- (num+1)*sizeof(__GLXcontext *));
- cl->currentDrawables = (DrawablePtr *) __glXRealloc(
- cl->currentDrawables ,
- (num+1)*sizeof(DrawablePtr));
- cl->be_currentCTag = (GLXContextTag *) __glXRealloc(cl->be_currentCTag,
- (num+1)*screenInfo.numScreens*sizeof(GLXContextTag));
- }
- table[num] = glxc;
- cl->currentDrawables[num] = pDraw;
- cl->currentContexts = table;
- cl->numCurrentContexts++;
-
- memset(cl->be_currentCTag + num*screenInfo.numScreens, 0,
- screenInfo.numScreens * sizeof(GLXContextTag));
-
- return num+1;
-}
-
-/*
-** Given a tag, change the current context for the corresponding entry.
-*/
-static void ChangeCurrentContext(__GLXclientState *cl, __GLXcontext *glxc,
- GLXContextTag tag)
-{
- __GLXcontext **table = cl->currentContexts;
- table[tag-1] = glxc;
-}
-
-/*
-** Given a tag, and back-end screen number, retrives the current back-end
-** tag.
-*/
-int GetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s)
-{
- if (tag >0) {
- return( cl->be_currentCTag[ (tag-1)*screenInfo.numScreens + s ] );
- }
- else {
- return( 0 );
- }
-}
-
-/*
-** Given a tag, and back-end screen number, sets the current back-end
-** tag.
-*/
-static void SetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s, GLXContextTag be_tag)
-{
- if (tag >0) {
- cl->be_currentCTag[ (tag-1)*screenInfo.numScreens + s ] = be_tag;
- }
-}
-
-/*
-** For this implementation we have chosen to simply use the index of the
-** context's entry in the table as the context tag. A tag must be greater
-** than 0.
-*/
-__GLXcontext *__glXLookupContextByTag(__GLXclientState *cl, GLXContextTag tag)
-{
- int num = cl->numCurrentContexts;
-
- if (tag < 1 || tag > num) {
- return 0;
- } else {
- return cl->currentContexts[tag-1];
- }
-}
-
-DrawablePtr __glXLookupDrawableByTag(__GLXclientState *cl, GLXContextTag tag)
-{
- int num = cl->numCurrentContexts;
-
- if (tag < 1 || tag > num) {
- return 0;
- } else {
- return cl->currentDrawables[tag-1];
- }
-}
-
-/*****************************************************************************/
-
-static void StopUsingContext(__GLXcontext *glxc)
-{
- if (glxc) {
- if (glxc == __glXLastContext) {
- /* Tell server GL library */
- __glXLastContext = 0;
- }
- glxc->isCurrent = GL_FALSE;
- if (!glxc->idExists) {
- __glXFreeContext(glxc);
- }
- }
-}
-
-static void StartUsingContext(__GLXclientState *cl, __GLXcontext *glxc)
-{
- glxc->isCurrent = GL_TRUE;
-}
-
-/*****************************************************************************/
-/*
-** Make an OpenGL context and drawable current.
-*/
-static int MakeCurrent(__GLXclientState *cl,
- GLXDrawable drawable,
- GLXDrawable readdrawable,
- GLXContextID context,
- GLXContextTag oldContextTag)
-{
- ClientPtr client = cl->client;
- DrawablePtr pDraw = NULL;
- DrawablePtr pReadDraw = NULL;
- xGLXMakeCurrentReadSGIReply new_reply;
- xGLXMakeCurrentReq *be_req;
- xGLXMakeCurrentReply be_reply;
- xGLXMakeContextCurrentReq *be_new_req;
- xGLXMakeContextCurrentReply be_new_reply;
- GLXDrawable drawId = drawable;
- GLXDrawable readId = readdrawable;
- GLXContextID contextId = context;
- __GLXpixmap *pGlxPixmap = 0;
- __GLXpixmap *pReadGlxPixmap = 0;
- __GLXcontext *glxc, *prevglxc;
- GLXContextTag tag = oldContextTag;
- WindowPtr pWin = NULL;
- WindowPtr pReadWin = NULL;
- __glXWindow *pGlxWindow = NULL;
- __glXWindow *pGlxReadWindow = NULL;
- __glXPbuffer *pGlxPbuffer = NULL;
- __glXPbuffer *pGlxReadPbuffer = NULL;
-#ifdef PANORAMIX
- PanoramiXRes *pXinDraw = NULL;
- PanoramiXRes *pXinReadDraw = NULL;
-#endif
- int from_screen = 0;
- int to_screen = 0;
- int s, rc;
-
- /*
- ** If one is None and the other isn't, it's a bad match.
- */
- if ((drawId == None && contextId != None) ||
- (drawId != None && contextId == None)) {
- return BadMatch;
- }
-
- /*
- ** Lookup old context. If we have one, it must be in a usable state.
- */
- if (tag != 0) {
- prevglxc = __glXLookupContextByTag(cl, tag);
- if (!prevglxc) {
- /*
- ** Tag for previous context is invalid.
- */
- return __glXBadContextTag;
- }
- } else {
- prevglxc = 0;
- }
-
- /*
- ** Lookup new context. It must not be current for someone else.
- */
- if (contextId != None) {
- glxc = (__GLXcontext *) LookupIDByType(contextId, __glXContextRes);
- if (!glxc) {
- client->errorValue = contextId;
- return __glXBadContext;
- }
- if ((glxc != prevglxc) && glxc->isCurrent) {
- /* Context is current to somebody else */
- return BadAccess;
- }
- } else {
- /* Switching to no context. Ignore new drawable. */
- glxc = 0;
- }
-
- if (drawId != None) {
- rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixWriteAccess);
- if (rc == Success) {
- if (pDraw->type == DRAWABLE_WINDOW) {
- /*
- ** Drawable is an X Window.
- */
- VisualID vid;
- pWin = (WindowPtr)pDraw;
- vid = wVisual(pWin);
-
- new_reply.writeVid = (glxc->pFBConfig ? glxc->pFBConfig->id : vid);
- new_reply.writeType = GLX_WINDOW_TYPE;
-
- /*
- ** Check if window and context are similar.
- */
- if ((vid != glxc->pVisual->vid) ||
- (pWin->drawable.pScreen != glxc->pScreen)) {
- client->errorValue = drawId;
- return BadMatch;
- }
-
- from_screen = to_screen = pWin->drawable.pScreen->myNum;
-
- } else {
- /*
- ** An X Pixmap is not allowed as a parameter (a GLX Pixmap
- ** is, but it must first be created with glxCreateGLXPixmap).
- */
- client->errorValue = drawId;
- return __glXBadDrawable;
- }
- }
-
- if (!pDraw) {
- pGlxPixmap = (__GLXpixmap *) LookupIDByType(drawId,
- __glXPixmapRes);
- if (pGlxPixmap) {
- /*
- ** Check if pixmap and context are similar.
- */
- if (pGlxPixmap->pScreen != glxc->pScreen ||
- pGlxPixmap->pGlxVisual != glxc->pGlxVisual) {
- client->errorValue = drawId;
- return BadMatch;
- }
- pDraw = pGlxPixmap->pDraw;
-
- new_reply.writeVid = (glxc->pFBConfig ? glxc->pFBConfig->id :
- pGlxPixmap->pGlxVisual->vid);
-
- new_reply.writeType = GLX_PIXMAP_TYPE;
-
- from_screen = to_screen = pGlxPixmap->pScreen->myNum;
-
- }
- }
-
- if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
- pGlxWindow = (__glXWindow *) LookupIDByType(drawId, __glXWindowRes);
- if (pGlxWindow) {
- /*
- ** Drawable is a GLXWindow.
- **
- ** Check if GLX window and context are similar.
- */
- if (pGlxWindow->pScreen != glxc->pScreen ||
- pGlxWindow->pGlxFBConfig != glxc->pFBConfig) {
- client->errorValue = drawId;
- return BadMatch;
- }
-
- pDraw = pGlxWindow->pDraw;
- new_reply.writeVid = pGlxWindow->pGlxFBConfig->id;
- new_reply.writeType = GLX_GLXWINDOW_TYPE;
- }
-
- }
-
- if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
- pGlxPbuffer = (__glXPbuffer *)LookupIDByType(drawId, __glXPbufferRes);
- if (pGlxPbuffer) {
- if (pGlxPbuffer->pScreen != glxc->pScreen ||
- pGlxPbuffer->pFBConfig != glxc->pFBConfig) {
- client->errorValue = drawId;
- return BadMatch;
- }
-
- pDraw = (DrawablePtr)pGlxPbuffer;
- new_reply.writeVid = pGlxPbuffer->pFBConfig->id;
- new_reply.writeType = GLX_PBUFFER_TYPE;
- }
- }
-
- if (!pDraw) {
- /*
- ** Drawable is not a Window , GLXWindow or a GLXPixmap.
- */
- client->errorValue = drawId;
- return __glXBadDrawable;
- }
-
- } else {
- pDraw = 0;
- }
-
- if (readId != None && readId != drawId ) {
- rc = dixLookupDrawable(&pReadDraw, readId, client, 0, DixReadAccess);
- if (rc == Success) {
- if (pReadDraw->type == DRAWABLE_WINDOW) {
- /*
- ** Drawable is an X Window.
- */
- VisualID vid;
- pReadWin = (WindowPtr)pDraw;
- vid = wVisual(pReadWin);
-
- new_reply.readVid = (glxc->pFBConfig ? glxc->pFBConfig->id : vid);
- new_reply.readType = GLX_WINDOW_TYPE;
-
- /*
- ** Check if window and context are similar.
- */
- if ((vid != glxc->pVisual->vid) ||
- (pReadWin->drawable.pScreen != glxc->pScreen)) {
- client->errorValue = readId;
- return BadMatch;
- }
-
- } else {
-
- /*
- ** An X Pixmap is not allowed as a parameter (a GLX Pixmap
- ** is, but it must first be created with glxCreateGLXPixmap).
- */
- client->errorValue = readId;
- return __glXBadDrawable;
- }
- }
-
- if (!pReadDraw) {
- pReadGlxPixmap = (__GLXpixmap *) LookupIDByType(readId,
- __glXPixmapRes);
- if (pReadGlxPixmap) {
- /*
- ** Check if pixmap and context are similar.
- */
- if (pReadGlxPixmap->pScreen != glxc->pScreen ||
- pReadGlxPixmap->pGlxVisual != glxc->pGlxVisual) {
- client->errorValue = readId;
- return BadMatch;
- }
- pReadDraw = pReadGlxPixmap->pDraw;
-
- new_reply.readVid = (glxc->pFBConfig ? glxc->pFBConfig->id :
- pReadGlxPixmap->pGlxVisual->vid );
- new_reply.readType = GLX_PIXMAP_TYPE;
-
- }
- }
-
- if (!pReadDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
- pGlxReadWindow = (__glXWindow *)
- LookupIDByType(readId, __glXWindowRes);
- if (pGlxReadWindow) {
- /*
- ** Drawable is a GLXWindow.
- **
- ** Check if GLX window and context are similar.
- */
- if (pGlxReadWindow->pScreen != glxc->pScreen ||
- pGlxReadWindow->pGlxFBConfig != glxc->pFBConfig) {
- client->errorValue = readId;
- return BadMatch;
- }
-
- pReadDraw = pGlxReadWindow->pDraw;
- new_reply.readVid = pGlxReadWindow->pGlxFBConfig->id;
- new_reply.readType = GLX_GLXWINDOW_TYPE;
- }
- }
-
- if (!pReadDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
- pGlxReadPbuffer = (__glXPbuffer *)LookupIDByType(readId, __glXPbufferRes);
- if (pGlxReadPbuffer) {
- if (pGlxReadPbuffer->pScreen != glxc->pScreen ||
- pGlxReadPbuffer->pFBConfig != glxc->pFBConfig) {
- client->errorValue = drawId;
- return BadMatch;
- }
-
- pReadDraw = (DrawablePtr)pGlxReadPbuffer;
- new_reply.readVid = pGlxReadPbuffer->pFBConfig->id;
- new_reply.readType = GLX_PBUFFER_TYPE;
- }
- }
-
- if (!pReadDraw) {
- /*
- ** Drawable is neither a Window nor a GLXPixmap.
- */
- client->errorValue = readId;
- return __glXBadDrawable;
- }
-
- } else {
- pReadDraw = pDraw;
- pReadGlxPixmap = pGlxPixmap;
- pReadWin = pWin;
- new_reply.readVid = new_reply.writeVid;
- new_reply.readType = new_reply.writeType;
- }
-
- if (prevglxc) {
-
- if (prevglxc->pGlxPixmap) {
- /*
- ** The previous drawable was a glx pixmap, release it.
- */
- prevglxc->pGlxPixmap->refcnt--;
- __glXFreeGLXPixmap( prevglxc->pGlxPixmap );
- prevglxc->pGlxPixmap = 0;
- }
-
- if (prevglxc->pGlxReadPixmap) {
- /*
- ** The previous drawable was a glx pixmap, release it.
- */
- prevglxc->pGlxReadPixmap->refcnt--;
- __glXFreeGLXPixmap( prevglxc->pGlxReadPixmap );
- prevglxc->pGlxReadPixmap = 0;
- }
-
- if (prevglxc->pGlxWindow) {
- /*
- ** The previous drawable was a glx window, release it.
- */
- prevglxc->pGlxWindow->refcnt--;
- __glXFreeGLXWindow( prevglxc->pGlxWindow );
- prevglxc->pGlxWindow = 0;
- }
-
- if (prevglxc->pGlxReadWindow) {
- /*
- ** The previous drawable was a glx window, release it.
- */
- prevglxc->pGlxReadWindow->refcnt--;
- __glXFreeGLXWindow( prevglxc->pGlxReadWindow );
- prevglxc->pGlxReadWindow = 0;
- }
-
- if (prevglxc->pGlxPbuffer) {
- /*
- ** The previous drawable was a glx Pbuffer, release it.
- */
- prevglxc->pGlxPbuffer->refcnt--;
- __glXFreeGLXPbuffer( prevglxc->pGlxPbuffer );
- prevglxc->pGlxPbuffer = 0;
- }
-
- if (prevglxc->pGlxReadPbuffer) {
- /*
- ** The previous drawable was a glx Pbuffer, release it.
- */
- prevglxc->pGlxReadPbuffer->refcnt--;
- __glXFreeGLXPbuffer( prevglxc->pGlxReadPbuffer );
- prevglxc->pGlxReadPbuffer = 0;
- }
-
- ChangeCurrentContext(cl, glxc, tag);
- ChangeCurrentContext(cl, glxc, tag);
- StopUsingContext(prevglxc);
- } else {
- tag = AddCurrentContext(cl, glxc, pDraw);
- }
- if (glxc) {
-
- glxc->pGlxPixmap = pGlxPixmap;
- glxc->pGlxReadPixmap = pReadGlxPixmap;
- glxc->pGlxWindow = pGlxWindow;
- glxc->pGlxReadWindow = pGlxReadWindow;
- glxc->pGlxPbuffer = pGlxPbuffer;
- glxc->pGlxReadPbuffer = pGlxReadPbuffer;
-
- if (pGlxPixmap) {
- pGlxPixmap->refcnt++;
- }
-
- if (pReadGlxPixmap) {
- pReadGlxPixmap->refcnt++;
- }
-
- if (pGlxWindow) {
- pGlxWindow->refcnt++;
- }
-
- if (pGlxReadWindow) {
- pGlxReadWindow->refcnt++;
- }
-
- if (pGlxPbuffer) {
- pGlxPbuffer->refcnt++;
- }
-
- if (pGlxReadPbuffer) {
- pGlxReadPbuffer->refcnt++;
- }
-
- StartUsingContext(cl, glxc);
- new_reply.contextTag = tag;
- } else {
- new_reply.contextTag = 0;
- }
- new_reply.length = 0;
- new_reply.type = X_Reply;
- new_reply.sequenceNumber = client->sequence;
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
-
- if (pDraw && new_reply.writeType != GLX_PBUFFER_TYPE) {
- pXinDraw = (PanoramiXRes *)
- SecurityLookupIDByClass(client, pDraw->id, XRC_DRAWABLE, DixReadAccess);
- }
-
- if (pReadDraw && pReadDraw != pDraw &&
- new_reply.readType != GLX_PBUFFER_TYPE) {
- pXinReadDraw = (PanoramiXRes *)
- SecurityLookupIDByClass(client, pReadDraw->id, XRC_DRAWABLE, DixReadAccess);
- }
- else {
- pXinReadDraw = pXinDraw;
- }
- }
-#endif
-
-
- /* send the MakeCurrent request to all required
- * back-end servers.
- */
- for (s = from_screen; s<=to_screen; s++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
- Display *dpy = GetBackEndDisplay(cl,s);
- unsigned int be_draw = None;
- unsigned int be_read_draw = None;
-
- if (pGlxPixmap) {
- be_draw = pGlxPixmap->be_xids[s];
- }
- else if (pGlxPbuffer) {
- be_draw = pGlxPbuffer->be_xids[s];
- }
-#ifdef PANORAMIX
- else if (pXinDraw) {
- dixLookupWindow(&pWin, pXinDraw->info[s].id, client, DixReadAccess);
- }
-#endif
- else if (pGlxWindow) {
- pWin = (WindowPtr)pGlxWindow->pDraw;
- }
-
- if (pWin && be_draw == None) {
- be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
- if (!be_draw) {
- /* it might be that the window did not created yet on the */
- /* back-end server (lazy window creation option), force */
- /* creation of the window */
- dmxCreateAndRealizeWindow( pWin, TRUE );
- be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
- }
- }
-
- /*
- * Before sending the MakeCurrent request - sync the
- * X11 connection to the back-end servers to make sure
- * that drawable is already created
- */
- dmxSync( dmxScreen, 1 );
-
- if (drawId == readId) {
- LockDisplay(dpy);
- GetReq(GLXMakeCurrent, be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXMakeCurrent;
- be_req->drawable = be_draw;
- be_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0);
- be_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s);
- if (!_XReply(dpy, (xReply *) &be_reply, 0, False)) {
-
- /* The make current failed */
- UnlockDisplay(dpy);
- SyncHandle();
- return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) );
- }
-
- UnlockDisplay(dpy);
- SyncHandle();
-
- SetCurrentBackEndTag( cl, tag, s, be_reply.contextTag );
- }
- else {
-
- if (pReadGlxPixmap) {
- be_read_draw = pReadGlxPixmap->be_xids[s];
- }
- else if (pGlxReadPbuffer) {
- be_read_draw = pGlxReadPbuffer->be_xids[s];
- }
-#ifdef PANORAMIX
- else if (pXinReadDraw) {
- dixLookupWindow(&pReadWin, pXinReadDraw->info[s].id, client,
- DixReadAccess);
- }
-#endif
- else if (pGlxReadWindow) {
- pReadWin = (WindowPtr)pGlxReadWindow->pDraw;
- }
-
- if (pReadWin && be_read_draw == None) {
- be_read_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pReadWin))->window;
- if (!be_read_draw) {
- /* it might be that the window did not created yet on the */
- /* back-end server (lazy window creation option), force */
- /* creation of the window */
- dmxCreateAndRealizeWindow( pReadWin, TRUE );
- be_read_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pReadWin))->window;
- dmxSync( dmxScreen, 1 );
- }
- }
-
- if ( __GLX_IS_VERSION_SUPPORTED(1,3) ) {
- LockDisplay(dpy);
- GetReq(GLXMakeContextCurrent, be_new_req);
- be_new_req->reqType = dmxScreen->glxMajorOpcode;
- be_new_req->glxCode = X_GLXMakeContextCurrent;
- be_new_req->drawable = be_draw;
- be_new_req->readdrawable = be_read_draw;
- be_new_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0);
- be_new_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s);
- if (!_XReply(dpy, (xReply *) &be_new_reply, 0, False)) {
-
- /* The make current failed */
- UnlockDisplay(dpy);
- SyncHandle();
- return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) );
- }
-
- UnlockDisplay(dpy);
- SyncHandle();
-
- SetCurrentBackEndTag( cl, tag, s, be_new_reply.contextTag );
- }
- else if (glxIsExtensionSupported("GLX_SGI_make_current_read")) {
- xGLXMakeCurrentReadSGIReq *ext_req;
- xGLXVendorPrivateWithReplyReq *vpreq;
- xGLXMakeCurrentReadSGIReply ext_reply;
-
- LockDisplay(dpy);
- GetReqExtra(GLXVendorPrivateWithReply,
- sz_xGLXMakeCurrentReadSGIReq - sz_xGLXVendorPrivateWithReplyReq,
- vpreq);
- ext_req = (xGLXMakeCurrentReadSGIReq *)vpreq;
- ext_req->reqType = dmxScreen->glxMajorOpcode;
- ext_req->glxCode = X_GLXVendorPrivateWithReply;
- ext_req->vendorCode = X_GLXvop_MakeCurrentReadSGI;
- ext_req->drawable = be_draw;
- ext_req->readable = be_read_draw;
- ext_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0);
- ext_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s);
- if (!_XReply(dpy, (xReply *) &ext_reply, 0, False)) {
-
- /* The make current failed */
- UnlockDisplay(dpy);
- SyncHandle();
- return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) );
- }
-
- UnlockDisplay(dpy);
- SyncHandle();
-
- SetCurrentBackEndTag( cl, tag, s, ext_reply.contextTag );
-
- }
- else {
- return BadMatch;
- }
- }
-
- XFlush( dpy );
- }
-
- if (client->swapped) {
- __glXSwapMakeCurrentReply(client, &new_reply);
- } else {
- WriteToClient(client, sz_xGLXMakeContextCurrentReply, (char *)&new_reply);
- }
-
- return Success;
-}
-
-int __glXMakeCurrent(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc;
-
- return( MakeCurrent(cl, req->drawable, req->drawable,
- req->context, req->oldContextTag ) );
-}
-
-int __glXMakeContextCurrent(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc;
-
- return( MakeCurrent(cl, req->drawable, req->readdrawable,
- req->context, req->oldContextTag ) );
-}
-
-int __glXMakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc;
-
- return( MakeCurrent(cl, req->drawable, req->readable,
- req->context, req->oldContextTag ) );
-}
-
-int __glXIsDirect(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc;
- xGLXIsDirectReply reply;
- __GLXcontext *glxc;
-
- /*
- ** Find the GL context.
- */
- glxc = (__GLXcontext *) LookupIDByType(req->context, __glXContextRes);
- if (!glxc) {
- client->errorValue = req->context;
- return __glXBadContext;
- }
-
- reply.isDirect = 0;
- reply.length = 0;
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
-
- if (client->swapped) {
- __glXSwapIsDirectReply(client, &reply);
- } else {
- WriteToClient(client, sz_xGLXIsDirectReply, (char *)&reply);
- }
-
- return Success;
-}
-
-int __glXQueryVersion(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
-/* xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc; */
- xGLXQueryVersionReply reply;
-
- /*
- ** Server should take into consideration the version numbers sent by the
- ** client if it wants to work with older clients; however, in this
- ** implementation the server just returns its version number.
- */
- reply.majorVersion = __glXVersionMajor;
- reply.minorVersion = __glXVersionMinor;
- reply.length = 0;
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
-
- if (client->swapped) {
- __glXSwapQueryVersionReply(client, &reply);
- } else {
- WriteToClient(client, sz_xGLXQueryVersionReply, (char *)&reply);
- }
- return Success;
-}
-
-int __glXWaitGL(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXWaitGLReq *req = (xGLXWaitGLReq *)pc;
- xGLXWaitGLReq *be_req = (xGLXWaitGLReq *)pc;
- int from_screen = 0;
- int to_screen = 0;
- int s;
- __GLXcontext *glxc = NULL;
-
- if (req->contextTag != 0) {
- glxc = __glXLookupContextByTag(cl, req->contextTag);
- if (glxc) {
- from_screen = to_screen = glxc->pScreen->myNum;
- }
- }
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
- for (s=from_screen; s<=to_screen; s++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
- Display *dpy = GetBackEndDisplay(cl,s);
-
- LockDisplay(dpy);
- GetReq(GLXWaitGL,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXWaitGL;
- be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0);
- UnlockDisplay(dpy);
- SyncHandle();
-
- XSync(dpy, False);
- }
-
- return Success;
-}
-
-int __glXWaitX(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXWaitXReq *req = (xGLXWaitXReq *)pc;
- xGLXWaitXReq *be_req;
- int from_screen = 0;
- int to_screen = 0;
- int s;
- __GLXcontext *glxc = NULL;
-
- if (req->contextTag != 0) {
- glxc = __glXLookupContextByTag(cl, req->contextTag);
- if (glxc) {
- from_screen = to_screen = glxc->pScreen->myNum;
- }
- }
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
- for (s=from_screen; s<=to_screen; s++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
- Display *dpy = GetBackEndDisplay(cl,s);
-
- dmxSync( dmxScreen, 1 );
-
- LockDisplay(dpy);
- GetReq(GLXWaitX,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXWaitX;
- be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0);
- UnlockDisplay(dpy);
- SyncHandle();
-
- XFlush( dpy );
- }
-
- return Success;
-}
-
-int __glXCopyContext(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXCopyContextReq *be_req;
- xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc;
- GLXContextID source = req->source;
- GLXContextID dest = req->dest;
- GLXContextTag tag = req->contextTag;
- unsigned long mask = req->mask;
- __GLXcontext *src, *dst;
- int s;
- int from_screen = 0;
- int to_screen = 0;
-
- /*
- ** Check that each context exists.
- */
- src = (__GLXcontext *) LookupIDByType(source, __glXContextRes);
- if (!src) {
- client->errorValue = source;
- return __glXBadContext;
- }
- dst = (__GLXcontext *) LookupIDByType(dest, __glXContextRes);
- if (!dst) {
- client->errorValue = dest;
- return __glXBadContext;
- }
-
- /*
- ** They must be in the same address space, and same screen.
- */
- if (src->pGlxScreen != dst->pGlxScreen) {
- client->errorValue = source;
- return BadMatch;
- }
-
- /*
- ** The destination context must not be current for any client.
- */
- if (dst->isCurrent) {
- client->errorValue = dest;
- return BadAccess;
- }
-
- if (tag) {
- __GLXcontext *tagcx = __glXLookupContextByTag(cl, tag);
-
- if (!tagcx) {
- return __glXBadContextTag;
- }
- if (tagcx != src) {
- /*
- ** This would be caused by a faulty implementation of the client
- ** library.
- */
- return BadMatch;
- }
- }
-
- from_screen = to_screen = src->pScreen->myNum;
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
- for (s=from_screen; s<=to_screen; s++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
- Display *dpy = GetBackEndDisplay(cl,s);
-
- LockDisplay(dpy);
- GetReq(GLXCopyContext,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXCopyContext;
- be_req->source = (unsigned int)src->real_ids[s-from_screen];
- be_req->dest = (unsigned int)dst->real_ids[s-from_screen];
- be_req->mask = mask;
- be_req->contextTag = (tag ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0);
- UnlockDisplay(dpy);
- SyncHandle();
- }
-
- return Success;
-}
-
-int __glXGetVisualConfigs(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc;
- xGLXGetVisualConfigsReply reply;
- __GLXscreenInfo *pGlxScreen;
- __GLXvisualConfig *pGlxVisual;
- CARD32 buf[__GLX_TOTAL_CONFIG];
- unsigned int screen;
- int i, p;
-
- screen = req->screen;
- if (screen > screenInfo.numScreens) {
- /* The client library must send a valid screen number. */
- client->errorValue = screen;
- return BadValue;
- }
- pGlxScreen = &__glXActiveScreens[screen];
-
- reply.numVisuals = pGlxScreen->numGLXVisuals;
- reply.numProps = __GLX_TOTAL_CONFIG;
- reply.length = (pGlxScreen->numGLXVisuals * __GLX_SIZE_CARD32 *
- __GLX_TOTAL_CONFIG) >> 2;
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
-
- WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char *)&reply);
-
- for (i=0; i < pGlxScreen->numVisuals; i++) {
- pGlxVisual = &pGlxScreen->pGlxVisual[i];
- if (!pGlxScreen->isGLXvis[i] || pGlxVisual->vid == 0) {
- /* not a usable visual */
- continue;
- }
- p = 0;
- buf[p++] = pGlxVisual->vid;
- buf[p++] = pGlxVisual->class;
- buf[p++] = pGlxVisual->rgba;
-
- buf[p++] = pGlxVisual->redSize;
- buf[p++] = pGlxVisual->greenSize;
- buf[p++] = pGlxVisual->blueSize;
- buf[p++] = pGlxVisual->alphaSize;
- buf[p++] = pGlxVisual->accumRedSize;
- buf[p++] = pGlxVisual->accumGreenSize;
- buf[p++] = pGlxVisual->accumBlueSize;
- buf[p++] = pGlxVisual->accumAlphaSize;
-
- buf[p++] = pGlxVisual->doubleBuffer;
- buf[p++] = pGlxVisual->stereo;
-
- buf[p++] = pGlxVisual->bufferSize;
- buf[p++] = pGlxVisual->depthSize;
- buf[p++] = pGlxVisual->stencilSize;
- buf[p++] = pGlxVisual->auxBuffers;
- buf[p++] = pGlxVisual->level;
- /*
- ** Add token/value pairs for extensions.
- */
- buf[p++] = GLX_VISUAL_CAVEAT_EXT;
- buf[p++] = pGlxVisual->visualRating;
- buf[p++] = GLX_TRANSPARENT_TYPE_EXT;
- buf[p++] = pGlxVisual->transparentPixel;
- buf[p++] = GLX_TRANSPARENT_RED_VALUE_EXT;
- buf[p++] = pGlxVisual->transparentRed;
- buf[p++] = GLX_TRANSPARENT_GREEN_VALUE_EXT;
- buf[p++] = pGlxVisual->transparentGreen;
- buf[p++] = GLX_TRANSPARENT_BLUE_VALUE_EXT;
- buf[p++] = pGlxVisual->transparentBlue;
- buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE_EXT;
- buf[p++] = pGlxVisual->transparentAlpha;
- buf[p++] = GLX_TRANSPARENT_INDEX_VALUE_EXT;
- buf[p++] = pGlxVisual->transparentIndex;
- buf[p++] = GLX_SAMPLES_SGIS;
- buf[p++] = pGlxVisual->multiSampleSize;
- buf[p++] = GLX_SAMPLE_BUFFERS_SGIS;
- buf[p++] = pGlxVisual->nMultiSampleBuffers;
- buf[p++] = GLX_VISUAL_SELECT_GROUP_SGIX;
- buf[p++] = pGlxVisual->visualSelectGroup;
-
- WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_TOTAL_CONFIG,
- (char *)buf);
- }
- return Success;
-}
-
-/*
-** Create a GLX Pixmap from an X Pixmap.
-*/
-static int CreateGLXPixmap(__GLXclientState *cl,
- VisualID visual, GLXFBConfigID fbconfigId,
- int screenNum, XID pixmapId, XID glxpixmapId )
-{
- ClientPtr client = cl->client;
- xGLXCreateGLXPixmapReq *be_req;
- xGLXCreatePixmapReq *be_new_req;
- DrawablePtr pDraw;
- ScreenPtr pScreen;
- VisualPtr pVisual;
- __GLXpixmap *pGlxPixmap;
- __GLXscreenInfo *pGlxScreen;
- __GLXvisualConfig *pGlxVisual;
- __GLXFBConfig *pFBConfig;
- int i, s, rc;
- int from_screen, to_screen;
-#ifdef PANORAMIX
- PanoramiXRes *pXinDraw = NULL;
-#endif
-
- rc = dixLookupDrawable(&pDraw, pixmapId, client, M_DRAWABLE_PIXMAP,
- DixAddAccess);
- if (rc != Success)
- return rc;
-
- /*
- ** Check if screen of visual matches screen of pixmap.
- */
- pScreen = pDraw->pScreen;
- if (screenNum != pScreen->myNum) {
- return BadMatch;
- }
-
- if (fbconfigId == NULL && visual == NULL) {
- return BadValue;
- }
-
- if (fbconfigId != None) {
- pFBConfig = glxLookupFBConfig( fbconfigId );
- if (!pFBConfig) {
- client->errorValue = fbconfigId;
- return BadValue;
- }
- visual = pFBConfig->associatedVisualId;
- }
- else {
- pFBConfig = NULL;
- }
-
- if (visual != None) {
- /*
- ** Find the VisualRec for this visual.
- */
- pVisual = pScreen->visuals;
- for (i=0; i < pScreen->numVisuals; i++, pVisual++) {
- if (pVisual->vid == visual) {
- break;
- }
- }
- if (i == pScreen->numVisuals) {
- client->errorValue = visual;
- return BadValue;
- }
- /*
- ** Check if depth of visual matches depth of pixmap.
- */
- if (pVisual->nplanes != pDraw->depth) {
- client->errorValue = visual;
- return BadMatch;
- }
-
- /*
- ** Get configuration of the visual.
- */
- pGlxScreen = &__glXActiveScreens[screenNum];
- pGlxVisual = pGlxScreen->pGlxVisual;
- for (i = 0; i < pGlxScreen->numVisuals; i++, pGlxVisual++) {
- if (pGlxVisual->vid == visual) {
- break;
- }
- }
- if (i == pGlxScreen->numVisuals) {
- /*
- ** Visual not support on this screen by this OpenGL implementation.
- */
- client->errorValue = visual;
- return BadValue;
- }
-
-
- /* find the FBConfig for that visual (if any) */
- if ( pFBConfig == NULL ) {
- pFBConfig = glxLookupFBConfigByVID( visual );
-
- if ( pFBConfig == NULL ) {
- /*
- * visual does not have an FBConfig ???
- client->errorValue = visual;
- return BadValue;
- */
- }
- }
- }
- else {
- pVisual = NULL;
- pGlxVisual = NULL;
- }
-
- pGlxPixmap = (__GLXpixmap *) __glXMalloc(sizeof(__GLXpixmap));
- if (!pGlxPixmap) {
- return BadAlloc;
- }
- pGlxPixmap->be_xids = (XID *) __glXMalloc(sizeof(XID) * screenInfo.numScreens);
- if (!pGlxPixmap->be_xids) {
- __glXFree( pGlxPixmap );
- return BadAlloc;
- }
-
- pGlxPixmap->pDraw = pDraw;
- pGlxPixmap->pGlxScreen = pGlxScreen;
- pGlxPixmap->pGlxVisual = pGlxVisual;
- pGlxPixmap->pFBConfig = pFBConfig;
- pGlxPixmap->pScreen = pScreen;
- pGlxPixmap->idExists = True;
- pGlxPixmap->refcnt = 0;
-
- /*
- ** Bump the ref count on the X pixmap so it won't disappear.
- */
- ((PixmapPtr) pDraw)->refcnt++;
-
- /*
- * send the request to the back-end server(s)
- */
- from_screen = to_screen = screenNum;
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
-
- pXinDraw = (PanoramiXRes *)
- SecurityLookupIDByClass(client, pDraw->id, XRC_DRAWABLE, DixReadAccess);
- }
-#endif
-
- for (s=from_screen; s<=to_screen; s++) {
-
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
- Display *dpy = GetBackEndDisplay(cl,s);
- Pixmap be_pixmap;
- DrawablePtr pRealDraw = pDraw;
-
-#ifdef PANORAMIX
- if (pXinDraw) {
- dixLookupDrawable(&pRealDraw, pXinDraw->info[s].id, client, 0,
- DixAddAccess);
- }
-#endif
-
- be_pixmap = (DMX_GET_PIXMAP_PRIV((PixmapPtr)pRealDraw))->pixmap;
-
- /* make sure pixmap already created on back-end */
- dmxSync( dmxScreen, 1 );
-
- if ( pFBConfig && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
- __GLXFBConfig *be_FBConfig = glxLookupBackEndFBConfig( pFBConfig->id, s );
-
- LockDisplay(dpy);
- pGlxPixmap->be_xids[s] = XAllocID(dpy);
- GetReq(GLXCreatePixmap,be_new_req);
- be_new_req->reqType = dmxScreen->glxMajorOpcode;
- be_new_req->glxCode = X_GLXCreatePixmap;
- be_new_req->screen = DefaultScreen(dpy);
- be_new_req->fbconfig = be_FBConfig->id;
- be_new_req->pixmap = (unsigned int)be_pixmap;
- be_new_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s];
- be_new_req->numAttribs = 0;
- UnlockDisplay(dpy);
- SyncHandle();
- }
- else if (pFBConfig && glxIsExtensionSupported("GLX_SGIX_fbconfig")) {
- __GLXFBConfig *be_FBConfig = glxLookupBackEndFBConfig( pFBConfig->id, s );
- xGLXCreateGLXPixmapWithConfigSGIXReq *ext_req;
- xGLXVendorPrivateReq *vpreq;
-
- LockDisplay(dpy);
- pGlxPixmap->be_xids[s] = XAllocID(dpy);
- GetReqExtra(GLXVendorPrivate,
- sz_xGLXCreateGLXPixmapWithConfigSGIXReq-sz_xGLXVendorPrivateReq,
- vpreq);
- ext_req = (xGLXCreateGLXPixmapWithConfigSGIXReq *)vpreq;
- ext_req->reqType = dmxScreen->glxMajorOpcode;
- ext_req->glxCode = X_GLXVendorPrivate;
- ext_req->vendorCode = X_GLXvop_CreateGLXPixmapWithConfigSGIX;
- ext_req->screen = DefaultScreen(dpy);
- ext_req->fbconfig = be_FBConfig->id;
- ext_req->pixmap = (unsigned int)be_pixmap;
- ext_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s];
- UnlockDisplay(dpy);
- SyncHandle();
- }
- else if (pGlxVisual) {
- LockDisplay(dpy);
- pGlxPixmap->be_xids[s] = XAllocID(dpy);
- GetReq(GLXCreateGLXPixmap,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXCreateGLXPixmap;
- be_req->screen = DefaultScreen(dpy);
- be_req->visual = (unsigned int)glxMatchGLXVisualInConfigList(
- pGlxVisual,
- dmxScreen->glxVisuals,
- dmxScreen->numGlxVisuals );
- be_req->pixmap = (unsigned int)be_pixmap;
- be_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s];
- UnlockDisplay(dpy);
- SyncHandle();
- }
- else {
- client->errorValue = ( visual ? visual : fbconfigId );
- __glXFree( pGlxPixmap );
- return BadValue;
- }
-
- XFlush( dpy );
- }
-
- if (!(AddResource(glxpixmapId, __glXPixmapRes, pGlxPixmap))) {
- __glXFree( pGlxPixmap );
- return BadAlloc;
- }
-
- return Success;
-}
-
-int __glXCreateGLXPixmap(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc;
-
- return( CreateGLXPixmap(cl, req->visual, None,
- req->screen, req->pixmap, req->glxpixmap) );
-}
-
-int __glXCreatePixmap(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc;
-
- return( CreateGLXPixmap(cl, None, req->fbconfig,
- req->screen, req->pixmap, req->glxpixmap) );
-}
-
-int __glXDestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc;
- XID glxpixmap = req->glxpixmap;
- __GLXpixmap *pGlxPixmap;
- int s;
- int from_screen, to_screen;
-
- /*
- ** Check if it's a valid GLX pixmap.
- */
- pGlxPixmap = (__GLXpixmap *)LookupIDByType(glxpixmap, __glXPixmapRes);
- if (!pGlxPixmap) {
- client->errorValue = glxpixmap;
- return __glXBadPixmap;
- }
- FreeResource(glxpixmap, FALSE);
-
- /*
- * destroy the pixmap on the back-end server(s).
- */
- from_screen = to_screen = pGlxPixmap->pDraw->pScreen->myNum;
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
- for (s=from_screen; s<=to_screen; s++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
- Display *dpy = GetBackEndDisplay(cl,s);
-
- /* make sure pixmap exist in back-end */
- dmxSync( dmxScreen, 1 );
-
- LockDisplay(dpy);
- GetReq(GLXDestroyGLXPixmap,req);
- req->reqType = dmxScreen->glxMajorOpcode;
- req->glxCode = X_GLXDestroyGLXPixmap;
- req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s];
- UnlockDisplay(dpy);
- SyncHandle();
- }
-
-
- return Success;
-}
-
-/*****************************************************************************/
-
-/*
-** NOTE: There is no portable implementation for swap buffers as of
-** this time that is of value. Consequently, this code must be
-** implemented by somebody other than SGI.
-*/
-int __glXDoSwapBuffers(__GLXclientState *cl, XID drawId, GLXContextTag tag)
-{
- ClientPtr client = cl->client;
- DrawablePtr pDraw;
- xGLXSwapBuffersReq *be_req;
- WindowPtr pWin = NULL;
- __GLXpixmap *pGlxPixmap = NULL;
- __GLXcontext *glxc = NULL;
-#ifdef PANORAMIX
- PanoramiXRes *pXinDraw = NULL;
-#endif
- __glXWindow *pGlxWindow = NULL;
- int from_screen = 0;
- int to_screen = 0;
- int s, rc;
-
- /*
- ** Check that the GLX drawable is valid.
- */
- rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixWriteAccess);
- if (rc == Success) {
- from_screen = to_screen = pDraw->pScreen->myNum;
-
- if (pDraw->type == DRAWABLE_WINDOW) {
- /*
- ** Drawable is an X window.
- */
- pWin = (WindowPtr)pDraw;
- } else {
- /*
- ** Drawable is an X pixmap, which is not allowed.
- */
- client->errorValue = drawId;
- return __glXBadDrawable;
- }
- }
-
- if (!pDraw) {
- pGlxPixmap = (__GLXpixmap *) LookupIDByType(drawId,
- __glXPixmapRes);
- if (pGlxPixmap) {
- /*
- ** Drawable is a GLX pixmap.
- */
- pDraw = pGlxPixmap->pDraw;
- from_screen = to_screen = pGlxPixmap->pScreen->myNum;
- }
- }
-
- if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
- pGlxWindow = (__glXWindow *) LookupIDByType(drawId, __glXWindowRes);
- if (pGlxWindow) {
- /*
- ** Drawable is a GLXWindow.
- */
- pDraw = pGlxWindow->pDraw;
- from_screen = to_screen = pGlxWindow->pScreen->myNum;
- }
- }
-
- if (!pDraw) {
- /*
- ** Drawable is neither a X window nor a GLX pixmap.
- */
- client->errorValue = drawId;
- return __glXBadDrawable;
- }
-
- if (tag) {
- glxc = __glXLookupContextByTag(cl, tag);
- if (!glxc) {
- return __glXBadContextTag;
- }
- }
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- pXinDraw = (PanoramiXRes *)
- SecurityLookupIDByClass(client, pDraw->id, XRC_DRAWABLE, DixReadAccess);
- }
-#endif
-
- /* If requested, send a glFinish to all back-end servers before swapping. */
- if (dmxGLXFinishSwap) {
- for (s=from_screen; s<=to_screen; s++) {
- Display *dpy = GetBackEndDisplay(cl,s);
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
- xGLXSingleReq *finishReq;
- xGLXSingleReply reply;
-
-#define X_GLXSingle 0 /* needed by GetReq below */
-
- LockDisplay(dpy);
- GetReq(GLXSingle,finishReq);
- finishReq->reqType = dmxScreen->glxMajorOpcode;
- finishReq->glxCode = X_GLsop_Finish;
- finishReq->contextTag = (tag ? GetCurrentBackEndTag(cl,tag,s) : 0);
- (void) _XReply(dpy, (xReply*) &reply, 0, False);
- UnlockDisplay(dpy);
- SyncHandle();
- }
- }
-
- /* If requested, send an XSync to all back-end servers before swapping. */
- if (dmxGLXSyncSwap) {
- for (s=from_screen; s<=to_screen; s++)
- XSync(GetBackEndDisplay(cl,s), False);
- }
-
-
- /* send the SwapBuffers request to all back-end servers */
-
- for (s=from_screen; s<=to_screen; s++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
- Display *dpy = GetBackEndDisplay(cl,s);
- unsigned int be_draw = 0;
-
- if (pGlxPixmap) {
- be_draw = (unsigned int)pGlxPixmap->be_xids[s];
- }
-#ifdef PANORAMIX
- else if (pXinDraw) {
- dixLookupWindow(&pWin, pXinDraw->info[s].id, client, DixReadAccess);
- }
-#endif
- else if (pGlxWindow) {
- pWin = (WindowPtr)pGlxWindow->pDraw;
- }
-
- if (pWin && !be_draw) {
- be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
- if (!be_draw) {
- /* it might be that the window did not created yet on the */
- /* back-end server (lazy window creation option), force */
- /* creation of the window */
- dmxCreateAndRealizeWindow( pWin, TRUE );
- be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
- }
- }
-
- dmxSync( dmxScreen, 1 );
-
- LockDisplay(dpy);
- GetReq(GLXSwapBuffers,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXSwapBuffers;
- be_req->drawable = be_draw;
- be_req->contextTag = ( tag ? GetCurrentBackEndTag(cl,tag,s) : 0 );
- UnlockDisplay(dpy);
- SyncHandle();
- XFlush(dpy);
- }
-
- return Success;
-}
-
-int __glXSwapBuffers(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- DrawablePtr pDraw;
- xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc;
- GLXContextTag tag = req->contextTag;
- XID drawId = req->drawable;
- __GLXpixmap *pGlxPixmap = NULL;
- __GLXcontext *glxc = NULL;
- __glXWindow *pGlxWindow = NULL;
- int rc;
-
- /*
- ** Check that the GLX drawable is valid.
- */
- rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixWriteAccess);
- if (rc == Success) {
- if (pDraw->type != DRAWABLE_WINDOW) {
- /*
- ** Drawable is an X pixmap, which is not allowed.
- */
- client->errorValue = drawId;
- return __glXBadDrawable;
- }
- }
-
- if (!pDraw) {
- pGlxPixmap = (__GLXpixmap *) LookupIDByType(drawId,
- __glXPixmapRes);
- if (pGlxPixmap) {
- /*
- ** Drawable is a GLX pixmap.
- */
- pDraw = pGlxPixmap->pDraw;
- }
- }
-
- if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
- pGlxWindow = (__glXWindow *) LookupIDByType(drawId, __glXWindowRes);
- if (pGlxWindow) {
- /*
- ** Drawable is a GLXWindow.
- */
- pDraw = pGlxWindow->pDraw;
- }
- }
-
- if (!pDraw) {
- /*
- ** Drawable is neither a X window nor a GLX pixmap.
- */
- client->errorValue = drawId;
- return __glXBadDrawable;
- }
-
- if (tag) {
- glxc = __glXLookupContextByTag(cl, tag);
- if (!glxc) {
- return __glXBadContextTag;
- }
- }
-
- if (pDraw &&
- pDraw->type == DRAWABLE_WINDOW &&
- DMX_GET_WINDOW_PRIV((WindowPtr)pDraw)->swapGroup) {
- return SGSwapBuffers(cl, drawId, tag, pDraw);
- }
-
- return __glXDoSwapBuffers(cl, drawId, tag);
-}
-
-
-/************************************************************************/
-
-/*
-** Render and Renderlarge are not in the GLX API. They are used by the GLX
-** client library to send batches of GL rendering commands.
-*/
-
-/*
-** Execute all the drawing commands in a request.
-*/
-int __glXRender(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXRenderReq *req;
- xGLXRenderReq *be_req;
- int size;
- __GLXcontext *glxc;
- int from_screen = 0;
- int to_screen = 0;
- int s;
-
- /*
- ** NOTE: much of this code also appears in the byteswapping version of this
- ** routine, __glXSwapRender(). Any changes made here should also be
- ** duplicated there.
- */
-
- req = (xGLXRenderReq *) pc;
-
- glxc = __glXLookupContextByTag(cl, req->contextTag);
- if (!glxc) {
- return 0;
- }
- from_screen = to_screen = glxc->pScreen->myNum;
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
- pc += sz_xGLXRenderReq;
- size = (req->length << 2) - sz_xGLXRenderReq;
-
- /*
- * just forward the request to back-end server(s)
- */
- for (s=from_screen; s<=to_screen; s++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
- Display *dpy = GetBackEndDisplay(cl,s);
-
- LockDisplay(dpy);
- GetReq(GLXRender,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXRender;
- be_req->length = req->length;
- be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s);
- _XSend(dpy, (const char *)pc, size);
- UnlockDisplay(dpy);
- SyncHandle();
- }
-
- return Success;
-}
-
-/*
-** Execute a large rendering request (one that spans multiple X requests).
-*/
-int __glXRenderLarge(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXRenderLargeReq *req;
- xGLXRenderLargeReq *be_req;
- __GLXcontext *glxc;
- int from_screen = 0;
- int to_screen = 0;
- int s;
-
- /*
- ** NOTE: much of this code also appears in the byteswapping version of this
- ** routine, __glXSwapRenderLarge(). Any changes made here should also be
- ** duplicated there.
- */
-
- req = (xGLXRenderLargeReq *) pc;
- glxc = __glXLookupContextByTag(cl, req->contextTag);
- if (!glxc) {
- return 0;
- }
- from_screen = to_screen = glxc->pScreen->myNum;
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
- pc += sz_xGLXRenderLargeReq;
-
- /*
- * just forward the request to back-end server(s)
- */
- for (s=from_screen; s<=to_screen; s++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
- Display *dpy = GetBackEndDisplay(cl,s);
-
- GetReq(GLXRenderLarge,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXRenderLarge;
- be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s);
- be_req->length = req->length;
- be_req->requestNumber = req->requestNumber;
- be_req->requestTotal = req->requestTotal;
- be_req->dataBytes = req->dataBytes;
- Data(dpy, (const char *)pc, req->dataBytes);
- UnlockDisplay(dpy);
- SyncHandle();
-
- }
-
- return Success;
-}
-
-
-/************************************************************************/
-
-int __glXVendorPrivate(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXVendorPrivateReq *req;
-
- req = (xGLXVendorPrivateReq *) pc;
-
- switch( req->vendorCode ) {
-
- case X_GLvop_DeleteTexturesEXT:
- return __glXVForwardSingleReq( cl, pc );
- break;
-
- case X_GLXvop_SwapIntervalSGI:
- if (glxIsExtensionSupported("SGI_swap_control")) {
- return __glXVForwardSingleReq( cl, pc );
- }
- else {
- return Success;
- }
- break;
-
-#if 0 /* glx 1.3 */
- case X_GLXvop_CreateGLXVideoSourceSGIX:
- break;
- case X_GLXvop_DestroyGLXVideoSourceSGIX:
- break;
- case X_GLXvop_CreateGLXPixmapWithConfigSGIX:
- break;
- case X_GLXvop_DestroyGLXPbufferSGIX:
- break;
- case X_GLXvop_ChangeDrawableAttributesSGIX:
- break;
-#endif
-
- case X_GLXvop_BindSwapBarrierSGIX:
- return __glXBindSwapBarrierSGIX( cl, pc );
- break;
-
- case X_GLXvop_JoinSwapGroupSGIX:
- return __glXJoinSwapGroupSGIX( cl, pc );
- break;
-
- case X_GLXvop_CreateContextWithConfigSGIX:
- return __glXCreateContextWithConfigSGIX( cl, pc );
- break;
-
- default:
- /*
- ** unsupported private request
- */
- cl->client->errorValue = req->vendorCode;
- return __glXUnsupportedPrivateRequest;
- }
-
- cl->client->errorValue = req->vendorCode;
- return __glXUnsupportedPrivateRequest;
-
-}
-
-int __glXVendorPrivateWithReply(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXVendorPrivateWithReplyReq *req;
-
- req = (xGLXVendorPrivateWithReplyReq *) pc;
-
- switch( req->vendorCode ) {
-
- case X_GLvop_GetConvolutionFilterEXT:
- case X_GLvop_GetConvolutionParameterfvEXT:
- case X_GLvop_GetConvolutionParameterivEXT:
- case X_GLvop_GetSeparableFilterEXT:
- case X_GLvop_GetHistogramEXT:
- case X_GLvop_GetHistogramParameterivEXT:
- case X_GLvop_GetMinmaxEXT:
- case X_GLvop_GetMinmaxParameterfvEXT:
- case X_GLvop_GetMinmaxParameterivEXT:
- case X_GLvop_AreTexturesResidentEXT:
- case X_GLvop_IsTextureEXT:
- return( __glXVForwardPipe0WithReply(cl, pc) );
- break;
-
- case X_GLvop_GenTexturesEXT:
- return( __glXVForwardAllWithReply(cl, pc) );
- break;
-
-
-#if 0 /* glx1.3 */
- case X_GLvop_GetDetailTexFuncSGIS:
- case X_GLvop_GetSharpenTexFuncSGIS:
- case X_GLvop_GetColorTableSGI:
- case X_GLvop_GetColorTableParameterfvSGI:
- case X_GLvop_GetColorTableParameterivSGI:
- case X_GLvop_GetTexFilterFuncSGIS:
- case X_GLvop_GetInstrumentsSGIX:
- case X_GLvop_InstrumentsBufferSGIX:
- case X_GLvop_PollInstrumentsSGIX:
- case X_GLvop_FlushRasterSGIX:
- case X_GLXvop_CreateGLXPbufferSGIX:
- case X_GLXvop_GetDrawableAttributesSGIX:
- case X_GLXvop_QueryHyperpipeNetworkSGIX:
- case X_GLXvop_QueryHyperpipeConfigSGIX:
- case X_GLXvop_HyperpipeConfigSGIX:
- case X_GLXvop_DestroyHyperpipeConfigSGIX:
-#endif
- case X_GLXvop_QueryMaxSwapBarriersSGIX:
- return( __glXQueryMaxSwapBarriersSGIX(cl, pc) );
- break;
-
- case X_GLXvop_GetFBConfigsSGIX:
- return( __glXGetFBConfigsSGIX(cl, pc) );
- break;
-
- case X_GLXvop_MakeCurrentReadSGI:
- return( __glXMakeCurrentReadSGI(cl, pc) );
- break;
-
- case X_GLXvop_QueryContextInfoEXT:
- return( __glXQueryContextInfoEXT(cl,pc) );
- break;
-
- default:
- /*
- ** unsupported private request
- */
- cl->client->errorValue = req->vendorCode;
- return __glXUnsupportedPrivateRequest;
- }
-
-}
-
-int __glXQueryExtensionsString(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *) pc;
- xGLXQueryExtensionsStringReply reply;
- GLint screen;
- size_t length;
- int len, numbytes;
- char *be_buf;
-
-#ifdef FWD_QUERY_REQ
- xGLXQueryExtensionsStringReq *be_req;
- xGLXQueryExtensionsStringReply be_reply;
- DMXScreenInfo *dmxScreen;
- Display *dpy;
- int slop;
-#endif
-
- screen = req->screen;
-
- /*
- ** Check if screen exists.
- */
- if ((screen < 0) || (screen >= screenInfo.numScreens)) {
- client->errorValue = screen;
- return BadValue;
- }
-
-#ifdef FWD_QUERY_REQ
- dmxScreen = &dmxScreens[screen];
-
- /* Send the glXQueryServerString request */
- dpy = GetBackEndDisplay(cl,screen);
- LockDisplay(dpy);
- GetReq(GLXQueryExtensionsString,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXQueryServerString;
- be_req->screen = DefaultScreen(dpy);
- _XReply(dpy, (xReply*) &be_reply, 0, False);
- len = (int)be_reply.length;
- numbytes = (int)be_reply.n;
- slop = numbytes * __GLX_SIZE_INT8 & 3;
- be_buf = (char *)Xalloc(numbytes);
- if (!be_buf) {
- /* Throw data on the floor */
- _XEatData(dpy, len);
- } else {
- _XRead(dpy, (char *)be_buf, numbytes);
- if (slop) _XEatData(dpy,4-slop);
- }
- UnlockDisplay(dpy);
- SyncHandle();
-
-#else
-
- be_buf = __glXGetServerString(GLX_EXTENSIONS);
- numbytes = strlen(be_buf) + 1;
- len = __GLX_PAD(numbytes) >> 2;
-
-#endif
-
- length = len;
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
- reply.length = len;
- reply.n = numbytes;
-
- if (client->swapped) {
- glxSwapQueryExtensionsStringReply(client, &reply, be_buf);
- } else {
- WriteToClient(client, sz_xGLXQueryExtensionsStringReply,(char *)&reply);
- WriteToClient(client, (int)(length << 2), (char *)be_buf);
- }
-
- return Success;
-}
-
-int __glXQueryServerString(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) pc;
- xGLXQueryServerStringReply reply;
- int name;
- GLint screen;
- size_t length;
- int len, numbytes;
- char *be_buf;
-#ifdef FWD_QUERY_REQ
- xGLXQueryServerStringReq *be_req;
- xGLXQueryServerStringReply be_reply;
- DMXScreenInfo *dmxScreen;
- Display *dpy;
- int slop;
-#endif
-
- name = req->name;
- screen = req->screen;
- /*
- ** Check if screen exists.
- */
- if ((screen < 0) || (screen >= screenInfo.numScreens)) {
- client->errorValue = screen;
- return BadValue;
- }
-
-#ifdef FWD_QUERY_REQ
- dmxScreen = &dmxScreens[screen];
-
- /* Send the glXQueryServerString request */
- dpy = GetBackEndDisplay(cl,screen);
- LockDisplay(dpy);
- GetReq(GLXQueryServerString,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXQueryServerString;
- be_req->screen = DefaultScreen(dpy);
- be_req->name = name;
- _XReply(dpy, (xReply*) &be_reply, 0, False);
- len = (int)be_reply.length;
- numbytes = (int)be_reply.n;
- slop = numbytes * __GLX_SIZE_INT8 & 3;
- be_buf = (char *)Xalloc(numbytes);
- if (!be_buf) {
- /* Throw data on the floor */
- _XEatData(dpy, len);
- } else {
- _XRead(dpy, (char *)be_buf, numbytes);
- if (slop) _XEatData(dpy,4-slop);
- }
- UnlockDisplay(dpy);
- SyncHandle();
-
-#else
- be_buf = __glXGetServerString(name);
- numbytes = strlen(be_buf) + 1;
- len = __GLX_PAD(numbytes) >> 2;
-#endif
-
- length = len;
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
- reply.length = length;
- reply.n = numbytes;
-
- if (client->swapped) {
- glxSwapQueryServerStringReply(client, &reply, be_buf);
- } else {
- WriteToClient(client, sz_xGLXQueryServerStringReply, (char *)&reply);
- WriteToClient(client, (int)(length << 2), be_buf);
- }
-
- return Success;
-}
-
-int __glXClientInfo(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXClientInfoReq *req = (xGLXClientInfoReq *) pc;
- xGLXClientInfoReq *be_req;
- const char *buf;
- int from_screen = 0;
- int to_screen = 0;
- int s;
-
- cl->GLClientmajorVersion = req->major;
- cl->GLClientminorVersion = req->minor;
- if (cl->GLClientextensions) __glXFree(cl->GLClientextensions);
- buf = (const char *)(req+1);
- cl->GLClientextensions = strdup(buf);
-
- to_screen = screenInfo.numScreens - 1;
-
- for (s=from_screen; s<=to_screen; s++)
- {
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
- Display *dpy = GetBackEndDisplay(cl,s);
-
- LockDisplay(dpy);
- GetReq(GLXClientInfo,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXClientInfo;
- be_req->major = req->major;
- be_req->minor = req->minor;
- be_req->length = req->length;
- be_req->numbytes = req->numbytes;
- Data(dpy, buf, req->numbytes);
-
- UnlockDisplay(dpy);
- SyncHandle();
- }
-
- return Success;
-}
-
-int __glXUseXFont(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXUseXFontReq *req;
- xGLXUseXFontReq *be_req;
- FontPtr pFont;
- __GLXcontext *glxc = NULL;
- int from_screen = 0;
- int to_screen = 0;
- int s;
- dmxFontPrivPtr pFontPriv;
- DMXScreenInfo *dmxScreen;
- Display *dpy;
-
- req = (xGLXUseXFontReq *) pc;
-
- if (req->contextTag != 0) {
- glxc = __glXLookupContextByTag(cl, req->contextTag);
- if (glxc) {
- from_screen = to_screen = glxc->pScreen->myNum;
- }
- }
-
- /*
- ** Font can actually be either the ID of a font or the ID of a GC
- ** containing a font.
- */
- pFont = (FontPtr)LookupIDByType(req->font, RT_FONT);
- if (!pFont) {
- GC *pGC = (GC *)LookupIDByType(req->font, RT_GC);
- if (!pGC) {
- client->errorValue = req->font;
- return BadFont;
- }
- pFont = pGC->font;
- }
-
- pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex);
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
-
- for (s=from_screen; s<=to_screen; s++) {
- dmxScreen = &dmxScreens[s];
- dpy = GetBackEndDisplay(cl,s);
-
- dmxSync( dmxScreen, 1 );
-
- LockDisplay(dpy);
- GetReq(GLXUseXFont,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXUseXFont;
- be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0);
- be_req->font = pFontPriv->font[s]->fid;
- be_req->first = req->first;
- be_req->count = req->count;
- be_req->listBase = req->listBase;
- UnlockDisplay(dpy);
- SyncHandle();
-
- XSync( dpy, False );
- }
-
- return Success;
-}
-
-/*
- * start GLX 1.3 here
- */
-
-int __glXGetFBConfigs(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc;
- xGLXGetFBConfigsReply reply;
- __GLXFBConfig *pFBConfig;
- CARD32 buf[2 * __GLX_TOTAL_FBCONFIG_PROPS];
- int numAttribs = __GLX_TOTAL_FBCONFIG_PROPS;
- unsigned int screen = req->screen;
- int numFBConfigs, i, p;
- __GLXscreenInfo *pGlxScreen;
-
- if (screen > screenInfo.numScreens) {
- /* The client library must send a valid screen number. */
- client->errorValue = screen;
- return BadValue;
- }
-
- pGlxScreen = &__glXActiveScreens[screen];
- numFBConfigs = __glXNumFBConfigs;
-
- reply.numFBConfigs = numFBConfigs;
- reply.numAttribs = numAttribs;
- reply.length = (numFBConfigs * 2 * numAttribs * __GLX_SIZE_CARD32) >> 2;
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
-
- if (client->swapped) {
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_SWAP_SHORT(&reply.sequenceNumber);
- __GLX_SWAP_INT(&reply.length);
- __GLX_SWAP_INT(&reply.numFBConfigs);
- __GLX_SWAP_INT(&reply.numAttribs);
- }
- WriteToClient(client, sz_xGLXGetFBConfigsReply, (char *)&reply);
-
- for (i=0; i < numFBConfigs; i++) {
- int associatedVisualId = 0;
- int drawableTypeIndex;
- pFBConfig = __glXFBConfigs[ i * (screenInfo.numScreens+1) ];
-
- p = 0;
- /* core attributes */
- buf[p++] = GLX_FBCONFIG_ID;
- buf[p++] = pFBConfig->id;
- buf[p++] = GLX_BUFFER_SIZE;
- buf[p++] = pFBConfig->indexBits;
- buf[p++] = GLX_LEVEL;
- buf[p++] = pFBConfig->level;
- buf[p++] = GLX_DOUBLEBUFFER;
- buf[p++] = pFBConfig->doubleBufferMode;
- buf[p++] = GLX_STEREO;
- buf[p++] = pFBConfig->stereoMode;
- buf[p++] = GLX_AUX_BUFFERS;
- buf[p++] = pFBConfig->maxAuxBuffers;
- buf[p++] = GLX_RED_SIZE;
- buf[p++] = pFBConfig->redBits;
- buf[p++] = GLX_GREEN_SIZE;
- buf[p++] = pFBConfig->greenBits;
- buf[p++] = GLX_BLUE_SIZE;
- buf[p++] = pFBConfig->blueBits;
- buf[p++] = GLX_ALPHA_SIZE;
- buf[p++] = pFBConfig->alphaBits;
- buf[p++] = GLX_DEPTH_SIZE;
- buf[p++] = pFBConfig->depthBits;
- buf[p++] = GLX_STENCIL_SIZE;
- buf[p++] = pFBConfig->stencilBits;
- buf[p++] = GLX_ACCUM_RED_SIZE;
- buf[p++] = pFBConfig->accumRedBits;
- buf[p++] = GLX_ACCUM_GREEN_SIZE;
- buf[p++] = pFBConfig->accumGreenBits;
- buf[p++] = GLX_ACCUM_BLUE_SIZE;
- buf[p++] = pFBConfig->accumBlueBits;
- buf[p++] = GLX_ACCUM_ALPHA_SIZE;
- buf[p++] = pFBConfig->accumAlphaBits;
- buf[p++] = GLX_RENDER_TYPE;
- buf[p++] = pFBConfig->renderType;
- buf[p++] = GLX_DRAWABLE_TYPE;
- drawableTypeIndex = p;
- buf[p++] = pFBConfig->drawableType;
- buf[p++] = GLX_X_VISUAL_TYPE;
- buf[p++] = pFBConfig->visualType;
- buf[p++] = GLX_CONFIG_CAVEAT;
- buf[p++] = pFBConfig->visualCaveat;
- buf[p++] = GLX_TRANSPARENT_TYPE;
- buf[p++] = pFBConfig->transparentType;
- buf[p++] = GLX_TRANSPARENT_RED_VALUE;
- buf[p++] = pFBConfig->transparentRed;
- buf[p++] = GLX_TRANSPARENT_GREEN_VALUE;
- buf[p++] = pFBConfig->transparentGreen;
- buf[p++] = GLX_TRANSPARENT_BLUE_VALUE;
- buf[p++] = pFBConfig->transparentBlue;
- buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE;
- buf[p++] = pFBConfig->transparentAlpha;
- buf[p++] = GLX_TRANSPARENT_INDEX_VALUE;
- buf[p++] = pFBConfig->transparentIndex;
- buf[p++] = GLX_MAX_PBUFFER_WIDTH;
- buf[p++] = pFBConfig->maxPbufferWidth;
- buf[p++] = GLX_MAX_PBUFFER_HEIGHT;
- buf[p++] = pFBConfig->maxPbufferHeight;
- buf[p++] = GLX_MAX_PBUFFER_PIXELS;
- buf[p++] = pFBConfig->maxPbufferPixels;
-
- /*
- * find the visual of the back-end server and match a visual
- * on the proxy.
- * do only once - if a visual is not yet associated.
- */
- if (pFBConfig->associatedVisualId == (unsigned int)-1) {
- DMXScreenInfo *dmxScreen = &dmxScreens[screen];
- __GLXFBConfig *be_pFBConfig = __glXFBConfigs[ i * (screenInfo.numScreens+1)+screen+1 ];
- __GLXvisualConfig *pGlxVisual = NULL;
- int v;
- int found = 0;
- for (v=0; v<dmxScreen->numGlxVisuals; v++) {
- if (dmxScreen->glxVisuals[v].vid == be_pFBConfig->associatedVisualId) {
- pGlxVisual = &dmxScreen->glxVisuals[v];
- break;
- }
- }
-
- if (pGlxVisual) {
- for (v=0; v<pGlxScreen->numVisuals; v++) {
- if (glxVisualsMatch(&pGlxScreen->pGlxVisual[v], pGlxVisual)) {
- associatedVisualId = pGlxScreen->pGlxVisual[v].vid;
- found = 1;
- break;
- }
- }
- }
-
- if (!found) {
- associatedVisualId = 0;
- pFBConfig->drawableType &= ~(GLX_WINDOW_BIT);
- buf[drawableTypeIndex] = pFBConfig->drawableType;
- }
-#ifdef PANORAMIX
- else if (!noPanoramiXExtension) {
- /* convert the associated visualId to the panoramix one */
- pFBConfig->associatedVisualId =
- PanoramiXTranslateVisualID(screen, v);
- }
-#endif
- }
- else {
- associatedVisualId = pFBConfig->associatedVisualId;
- }
-
- buf[p++] = GLX_VISUAL_ID;
- buf[p++] = associatedVisualId;
-
- /* SGIS_multisample attributes */
- buf[p++] = GLX_SAMPLES_SGIS;
- buf[p++] = pFBConfig->multiSampleSize;
- buf[p++] = GLX_SAMPLE_BUFFERS_SGIS;
- buf[p++] = pFBConfig->nMultiSampleBuffers;
-
- /* SGIX_pbuffer specific attributes */
- buf[p++] = GLX_OPTIMAL_PBUFFER_WIDTH_SGIX;
- buf[p++] = pFBConfig->optimalPbufferWidth;
- buf[p++] = GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX;
- buf[p++] = pFBConfig->optimalPbufferHeight;
-
- buf[p++] = GLX_VISUAL_SELECT_GROUP_SGIX;
- buf[p++] = pFBConfig->visualSelectGroup;
-
- if (client->swapped) {
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_SWAP_INT_ARRAY((int *)buf, 2*numAttribs);
- }
- WriteToClient(client, 2*numAttribs * __GLX_SIZE_CARD32, (char *)buf);
- }
- return Success;
-}
-
-int __glXGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *)pc;
- xGLXGetFBConfigsReq new_req;
-
- new_req.reqType = req->reqType;
- new_req.glxCode = req->glxCode;
- new_req.length = req->length;
- new_req.screen = req->screen;
-
- return( __glXGetFBConfigs( cl, (GLbyte *)&new_req ) );
-}
-
-
-int __glXCreateWindow(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc;
- int screen = req->screen;
- GLXFBConfigID fbconfigId = req->fbconfig;
- XID windowId = req->window;
- XID glxwindowId = req->glxwindow;
- DrawablePtr pDraw;
- ScreenPtr pScreen;
- __glXWindow *pGlxWindow;
- __GLXFBConfig *pGlxFBConfig = NULL;
- VisualPtr pVisual;
- VisualID visId;
- int i, rc;
-
- /*
- ** Check if windowId is valid
- */
- rc = dixLookupDrawable(&pDraw, windowId, client, M_DRAWABLE_WINDOW,
- DixAddAccess);
- if (rc != Success)
- return rc;
-
- /*
- ** Check if screen of window matches screen of fbconfig.
- */
- pScreen = pDraw->pScreen;
- if (screen != pScreen->myNum) {
- return BadMatch;
- }
-
- /*
- ** Find the FBConfigRec for this fbconfigid.
- */
- if (!(pGlxFBConfig = glxLookupFBConfig(fbconfigId))) {
- client->errorValue = fbconfigId;
- return __glXBadFBConfig;
- }
- visId = pGlxFBConfig->associatedVisualId;
-
- /*
- ** Check if the fbconfig supports rendering to windows
- */
- if( !(pGlxFBConfig->drawableType & GLX_WINDOW_BIT) ) {
- return BadMatch;
- }
-
- if (visId != None) {
- /*
- ** Check if the visual ID is valid for this screen.
- */
- pVisual = pScreen->visuals;
- for (i = 0; i < pScreen->numVisuals; i++, pVisual++) {
- if (pVisual->vid == visId) {
- break;
- }
- }
- if (i == pScreen->numVisuals) {
- client->errorValue = visId;
- return BadValue;
- }
-
- /*
- ** Check if color buffer depth of fbconfig matches depth
- ** of window.
- */
- if (pVisual->nplanes != pDraw->depth) {
- return BadMatch;
- }
- } else
- /*
- ** The window was created with no visual that corresponds
- ** to fbconfig
- */
- return BadMatch;
-
- /*
- ** Check if there is already a fbconfig associated with this window
- */
- if ( LookupIDByType(glxwindowId, __glXWindowRes) ) {
- client->errorValue = glxwindowId;
- return BadAlloc;
- }
-
- pGlxWindow = (__glXWindow *) xalloc(sizeof(__glXWindow));
- if (!pGlxWindow) {
- return BadAlloc;
- }
-
- /*
- ** Register this GLX window as a resource
- */
- if (!(AddResource(glxwindowId, __glXWindowRes, pGlxWindow))) {
- return BadAlloc;
- }
-
- pGlxWindow->pDraw = pDraw;
- pGlxWindow->type = GLX_GLXWINDOW_TYPE;
- pGlxWindow->idExists = True;
- pGlxWindow->refcnt = 0;
- pGlxWindow->pGlxFBConfig = pGlxFBConfig;
- pGlxWindow->pScreen = pScreen;
-
- return Success;
-}
-
-int __glXDestroyWindow(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc;
- XID glxwindow = req->glxwindow;
-
- /*
- ** Check if it's a valid GLX window.
- */
- if (!LookupIDByType(glxwindow, __glXWindowRes)) {
- client->errorValue = glxwindow;
- return __glXBadDrawable;
- }
- /*
- ** The glx window destructor will check whether it's current before
- ** freeing anything.
- */
- FreeResource(glxwindow, RT_NONE);
-
- return Success;
-}
-
-int __glXQueryContext(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- __GLXcontext *ctx;
- xGLXQueryContextReq *req;
- xGLXQueryContextReply reply;
- int nProps;
- int *sendBuf, *pSendBuf;
- int nReplyBytes;
-
- req = (xGLXQueryContextReq *)pc;
- ctx = (__GLXcontext *) LookupIDByType(req->context, __glXContextRes);
- if (!ctx) {
- client->errorValue = req->context;
- return __glXBadContext;
- }
-
- nProps = 3;
-
- reply.length = nProps << 1;
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
- reply.n = nProps;
-
- nReplyBytes = reply.length << 2;
- sendBuf = (int *)xalloc(nReplyBytes);
- pSendBuf = sendBuf;
- *pSendBuf++ = GLX_FBCONFIG_ID;
- *pSendBuf++ = (int)(ctx->pFBConfig->id);
- *pSendBuf++ = GLX_RENDER_TYPE;
- *pSendBuf++ = (int)(ctx->pFBConfig->renderType);
- *pSendBuf++ = GLX_SCREEN;
- *pSendBuf++ = (int)(ctx->pScreen->myNum);
-
- if (client->swapped) {
- __glXSwapQueryContextReply(client, &reply, sendBuf);
- } else {
- WriteToClient(client, sz_xGLXQueryContextReply, (char *)&reply);
- WriteToClient(client, nReplyBytes, (char *)sendBuf);
- }
- xfree((char *)sendBuf);
-
- return Success;
-}
-
-int __glXQueryContextInfoEXT(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- __GLXcontext *ctx;
- xGLXQueryContextInfoEXTReq *req;
- xGLXQueryContextInfoEXTReply reply;
- int nProps;
- int *sendBuf, *pSendBuf;
- int nReplyBytes;
-
- req = (xGLXQueryContextInfoEXTReq *)pc;
- ctx = (__GLXcontext *) SecurityLookupIDByType(client, req->context, __glXContextRes, DixReadAccess);
- if (!ctx) {
- client->errorValue = req->context;
- return __glXBadContext;
- }
-
- nProps = 4;
-
- reply.length = nProps << 1;
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
- reply.n = nProps;
-
- nReplyBytes = reply.length << 2;
- sendBuf = (int *)xalloc(nReplyBytes);
- pSendBuf = sendBuf;
- *pSendBuf++ = GLX_SHARE_CONTEXT_EXT;
- *pSendBuf++ = (int)(ctx->share_id);
- *pSendBuf++ = GLX_VISUAL_ID_EXT;
- *pSendBuf++ = (int)(ctx->pVisual ? ctx->pVisual->vid : 0);
- *pSendBuf++ = GLX_SCREEN_EXT;
- *pSendBuf++ = (int)(ctx->pScreen->myNum);
- *pSendBuf++ = GLX_FBCONFIG_ID;
- *pSendBuf++ = (int)(ctx->pFBConfig ? ctx->pFBConfig->id : 0);
-
- if (client->swapped) {
- __glXSwapQueryContextInfoEXTReply(client, &reply, sendBuf);
- } else {
- WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, (char *)&reply);
- WriteToClient(client, nReplyBytes, (char *)sendBuf);
- }
- xfree((char *)sendBuf);
-
- return Success;
-}
-
-int __glXCreatePbuffer(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *)pc;
- xGLXCreatePbufferReq *be_req;
- int screen = req->screen;
- GLXFBConfigID fbconfigId = req->fbconfig;
- GLXPbuffer pbuffer = req->pbuffer;
- __glXPbuffer *pGlxPbuffer;
- int numAttribs = req->numAttribs;
- int *attr;
- ScreenPtr pScreen;
- __GLXFBConfig *pGlxFBConfig;
- __GLXFBConfig *be_pGlxFBConfig;
- XID be_xid;
- Display *dpy;
- DMXScreenInfo *dmxScreen;
- int s;
- int from_screen, to_screen;
-
- /*
- ** Look up screen and FBConfig.
- */
- if (screen > screenInfo.numScreens) {
- /* The client library must send a valid screen number. */
- client->errorValue = screen;
- return BadValue;
- }
- pScreen = screenInfo.screens[screen];
-
- /*
- ** Find the FBConfigRec for this fbconfigid.
- */
- if (!(pGlxFBConfig = glxLookupFBConfig(fbconfigId))) {
- client->errorValue = fbconfigId;
- return __glXBadFBConfig;
- }
-
- /*
- ** Create the GLX part of the Pbuffer.
- */
- pGlxPbuffer = (__glXPbuffer *) xalloc(sizeof(__glXPbuffer));
- if (!pGlxPbuffer) {
- return BadAlloc;
- }
-
- pGlxPbuffer->be_xids = (XID *) xalloc( sizeof(XID) * screenInfo.numScreens );
- if (!pGlxPbuffer->be_xids) {
- xfree(pGlxPbuffer);
- return BadAlloc;
- }
-
- /*
- * Allocate an XID on the back-end server(s) and send him the request
- */
- from_screen = to_screen = screen;
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
- for (s=from_screen; s<=to_screen; s++) {
- dpy = GetBackEndDisplay(cl,s);
- be_xid = XAllocID(dpy);
- dmxScreen = &dmxScreens[s];
- be_pGlxFBConfig = glxLookupBackEndFBConfig( pGlxFBConfig->id, s );
-
- attr = (int *)( req+1 );
-
- LockDisplay(dpy);
- GetReqExtra(GLXCreatePbuffer, 2 * numAttribs * __GLX_SIZE_CARD32, be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXCreatePbuffer;
- be_req->screen = be_pGlxFBConfig->screen;
- be_req->fbconfig = be_pGlxFBConfig->id;
- be_req->pbuffer = be_xid;
- be_req->numAttribs = numAttribs;
-
- /* Send attributes */
- if ( attr != NULL ) {
- CARD32 *pc = (CARD32 *)(be_req + 1);
-
- while (numAttribs-- > 0) {
- *pc++ = *attr++; /* token */
- *pc++ = *attr++; /* value */
- }
- }
-
- UnlockDisplay(dpy);
- SyncHandle();
-
- pGlxPbuffer->be_xids[s] = be_xid;
- }
-
-
- pGlxPbuffer->idExists = True;
- pGlxPbuffer->refcnt = 0;
- pGlxPbuffer->pFBConfig = pGlxFBConfig;
- pGlxPbuffer->pScreen = pScreen;
-
- /*
- ** Register the resource.
- */
- if (!(AddResource(pbuffer, __glXPbufferRes, pGlxPbuffer))) {
- return BadAlloc;
- }
-
- return Success;
-
-}
-
-int __glXDestroyPbuffer(__GLXclientState *cl, GLbyte *pc)
-{
- ClientPtr client = cl->client;
- xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc;
- xGLXDestroyPbufferReq *be_req;
- GLXPbuffer pbuffer = req->pbuffer;
- Display *dpy;
- int screen;
- DMXScreenInfo *dmxScreen;
- __glXPbuffer *pGlxPbuffer;
- int s;
- int from_screen, to_screen;
-
- /*
- ** Check if it's a valid Pbuffer
- */
- pGlxPbuffer = (__glXPbuffer *)LookupIDByType(pbuffer, __glXPbufferRes);
- if (!pGlxPbuffer) {
- client->errorValue = pbuffer;
- return __glXBadPbuffer;
- }
-
- screen = pGlxPbuffer->pScreen->myNum;
-
- from_screen = to_screen = screen;
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
- for (s=from_screen; s<=to_screen; s++) {
- dpy = GetBackEndDisplay(cl,s);
- dmxScreen = &dmxScreens[s];
-
- /* send the destroy request to the back-end server */
- LockDisplay(dpy);
- GetReq(GLXDestroyPbuffer, be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXDestroyPbuffer;
- be_req->pbuffer = pGlxPbuffer->be_xids[s];
- UnlockDisplay(dpy);
- SyncHandle();
- }
-
- FreeResource(pbuffer, RT_NONE);
-
- return Success;
-}
-
-int __glXGetDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *)pc;
- xGLXGetDrawableAttributesReq *be_req;
- xGLXGetDrawableAttributesReply reply;
- ClientPtr client = cl->client;
- GLXDrawable drawId = req->drawable;
- GLXDrawable be_drawable = 0;
- DrawablePtr pDraw = NULL;
- Display *dpy;
- int screen, rc;
- DMXScreenInfo *dmxScreen;
- CARD32 *attribs = NULL;
- int attribs_size;
-#ifdef PANORAMIX
- PanoramiXRes *pXinDraw = NULL;
-#endif
-
- if (drawId != None) {
- rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixGetAttrAccess);
- if (rc == Success) {
- if (pDraw->type == DRAWABLE_WINDOW) {
- WindowPtr pWin = (WindowPtr)pDraw;
- be_drawable = 0;
- screen = pWin->drawable.pScreen->myNum;
-
- }
- else {
- /*
- ** Drawable is not a Window , GLXWindow or a GLXPixmap.
- */
- client->errorValue = drawId;
- return __glXBadDrawable;
- }
- }
-
- if (!pDraw) {
- __GLXpixmap *pGlxPixmap = (__GLXpixmap *) LookupIDByType(drawId,
- __glXPixmapRes);
- if (pGlxPixmap) {
- pDraw = pGlxPixmap->pDraw;
- screen = pGlxPixmap->pScreen->myNum;
- be_drawable = pGlxPixmap->be_xids[screen];
- }
- }
-
- if (!pDraw) {
- __glXWindow *pGlxWindow = (__glXWindow *) LookupIDByType(drawId, __glXWindowRes);
- if (pGlxWindow) {
- pDraw = pGlxWindow->pDraw;
- screen = pGlxWindow->pScreen->myNum;
- be_drawable = 0;
- }
- }
-
- if (!pDraw) {
- __glXPbuffer *pGlxPbuffer = (__glXPbuffer *)LookupIDByType(drawId, __glXPbufferRes);
- if (pGlxPbuffer) {
- pDraw = (DrawablePtr)pGlxPbuffer;
- screen = pGlxPbuffer->pScreen->myNum;
- be_drawable = pGlxPbuffer->be_xids[screen];
- }
- }
-
-
- if (!pDraw) {
- /*
- ** Drawable is not a Window , GLXWindow or a GLXPixmap.
- */
- client->errorValue = drawId;
- return __glXBadDrawable;
- }
- }
-
-
- /* if the drawable is a window or GLXWindow -
- * we need to find the base id on the back-end server
- */
- if (!be_drawable) {
- WindowPtr pWin = (WindowPtr)pDraw;
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- pXinDraw = (PanoramiXRes *)
- SecurityLookupIDByClass(client, pDraw->id, XRC_DRAWABLE, DixReadAccess);
- if (!pXinDraw) {
- client->errorValue = drawId;
- return __glXBadDrawable;
- }
-
- dixLookupWindow(&pWin, pXinDraw->info[screen].id, client,
- DixReadAccess);
- }
-#endif
-
- if (pWin) {
- be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
- if (!be_drawable) {
- /* it might be that the window did not created yet on the */
- /* back-end server (lazy window creation option), force */
- /* creation of the window */
- dmxCreateAndRealizeWindow( pWin, TRUE );
- be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
- }
- }
- else {
- client->errorValue = drawId;
- return __glXBadDrawable;
- }
- }
-
-
- /* send the request to the back-end server */
- dpy = GetBackEndDisplay(cl,screen);
- dmxScreen = &dmxScreens[screen];
-
- /* make sure drawable exists on back-end */
- dmxSync( dmxScreen, 1 );
-
- LockDisplay(dpy);
- GetReq(GLXGetDrawableAttributes, be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXGetDrawableAttributes;
- be_req->drawable = be_drawable;
- be_req->length = req->length;
- if (!_XReply(dpy, (xReply *) &reply, 0, False)) {
- UnlockDisplay(dpy);
- SyncHandle();
- return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) );
- }
-
- if (reply.numAttribs) {
- attribs_size = 2 * reply.numAttribs * __GLX_SIZE_CARD32;
- attribs = (CARD32 *) Xalloc(attribs_size);
- if (attribs == NULL) {
- UnlockDisplay(dpy);
- SyncHandle();
- return BadAlloc;
- }
-
- _XRead(dpy, (char *) attribs, attribs_size);
- }
-
- UnlockDisplay(dpy);
- SyncHandle();
-
-
- /* send the reply back to the client */
- reply.sequenceNumber = client->sequence;
- if (client->swapped) {
- __glXSwapGetDrawableAttributesReply(client, &reply, (int *)attribs);
- }
- else {
- WriteToClient(client, sz_xGLXGetDrawableAttributesReply, (char *)&reply);
- WriteToClient(client, attribs_size, (char *)attribs);
- }
-
- Xfree(attribs);
-
- return Success;
-}
-
-int __glXChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXChangeDrawableAttributesReq *req = (xGLXChangeDrawableAttributesReq *)pc;
- xGLXChangeDrawableAttributesReq *be_req;
- ClientPtr client = cl->client;
- GLXDrawable drawId = req->drawable;
- GLXDrawable be_drawable = 0;
- DrawablePtr pDraw = NULL;
- Display *dpy;
- int screen, rc;
- DMXScreenInfo *dmxScreen;
- char *attrbuf;
-#ifdef PANORAMIX
- PanoramiXRes *pXinDraw = NULL;
- PanoramiXRes *pXinReadDraw = NULL;
-#endif
-
- if (drawId != None) {
- rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixSetAttrAccess);
- if (rc == Success) {
- if (pDraw->type == DRAWABLE_WINDOW) {
- WindowPtr pWin = (WindowPtr)pDraw;
- be_drawable = 0;
- screen = pWin->drawable.pScreen->myNum;
-
- }
- else {
- /*
- ** Drawable is not a Window , GLXWindow or a GLXPixmap.
- */
- client->errorValue = drawId;
- return __glXBadDrawable;
- }
- }
-
- if (!pDraw) {
- __GLXpixmap *pGlxPixmap = (__GLXpixmap *) LookupIDByType(drawId,
- __glXPixmapRes);
- if (pGlxPixmap) {
- pDraw = pGlxPixmap->pDraw;
- screen = pGlxPixmap->pScreen->myNum;
- be_drawable = pGlxPixmap->be_xids[screen];
- }
- }
-
- if (!pDraw) {
- __glXWindow *pGlxWindow = (__glXWindow *) LookupIDByType(drawId, __glXWindowRes);
- if (pGlxWindow) {
- pDraw = pGlxWindow->pDraw;
- screen = pGlxWindow->pScreen->myNum;
- be_drawable = 0;
- }
- }
-
- if (!pDraw) {
- __glXPbuffer *pGlxPbuffer = (__glXPbuffer *)LookupIDByType(drawId, __glXPbufferRes);
- if (pGlxPbuffer) {
- pDraw = (DrawablePtr)pGlxPbuffer;
- screen = pGlxPbuffer->pScreen->myNum;
- be_drawable = pGlxPbuffer->be_xids[screen];
- }
- }
-
-
- if (!pDraw) {
- /*
- ** Drawable is not a Window , GLXWindow or a GLXPixmap.
- */
- client->errorValue = drawId;
- return __glXBadDrawable;
- }
- }
-
-
- /* if the drawable is a window or GLXWindow -
- * we need to find the base id on the back-end server
- */
- if (!be_drawable) {
- WindowPtr pWin = (WindowPtr)pDraw;
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- pXinDraw = (PanoramiXRes *)
- SecurityLookupIDByClass(client, pDraw->id, XRC_DRAWABLE, DixReadAccess);
- if (!pXinDraw) {
- client->errorValue = drawId;
- return __glXBadDrawable;
- }
-
- dixLookupWindow(&pWin, pXinDraw->info[screen].id, client,
- DixReadAccess);
- }
-#endif
-
- if (pWin) {
- be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
- if (!be_drawable) {
- /* it might be that the window did not created yet on the */
- /* back-end server (lazy window creation option), force */
- /* creation of the window */
- dmxCreateAndRealizeWindow( pWin, TRUE );
- be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
- }
- }
- else {
- client->errorValue = drawId;
- return __glXBadDrawable;
- }
- }
-
-
- /* send the request to the back-end server */
- dpy = GetBackEndDisplay(cl,screen);
- dmxScreen = &dmxScreens[screen];
-
- /* make sure drawable exists on back-end */
- dmxSync( dmxScreen, 1 );
-
- LockDisplay(dpy);
- GetReqExtra(GLXChangeDrawableAttributes,
- 2 * req->numAttribs * __GLX_SIZE_CARD32, be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLXChangeDrawableAttributes;
- be_req->drawable = be_drawable;
- be_req->numAttribs = req->numAttribs;
- be_req->length = req->length;
-
- UnlockDisplay(dpy);
- SyncHandle();
-
- return Success;
-}
-
-int __glXSendLargeCommand(__GLXclientState *cl, GLXContextTag contextTag)
-{
- ClientPtr client = cl->client;
- xGLXRenderLargeReq *req;
- GLint maxSize, amount;
- GLint totalRequests, requestNumber;
- GLint dataLen;
- GLbyte *data;
- __GLXcontext *glxc;
- int s;
- int from_screen, to_screen;
-
- maxSize = cl->largeCmdMaxReqDataSize - (GLint)sizeof(xGLXRenderLargeReq);
- dataLen = cl->largeCmdBytesTotal;
- totalRequests = (dataLen / maxSize);
- if (dataLen % maxSize) totalRequests++;
-
- glxc = __glXLookupContextByTag(cl, contextTag);
- if (!glxc) {
- client->errorValue = contextTag;
- return __glXBadContext;
- }
- from_screen = to_screen = glxc->pScreen->myNum;
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
- /*
- ** Send enough requests until the whole array is sent.
- */
- requestNumber = 1;
- data = cl->largeCmdBuf;
- while (dataLen > 0) {
- amount = dataLen;
- if (amount > maxSize) {
- amount = maxSize;
- }
-
- for (s=from_screen; s<=to_screen; s++) {
-
- Display *dpy = GetBackEndDisplay(cl,s);
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
-
- LockDisplay(dpy);
- GetReq(GLXRenderLarge,req);
- req->reqType = dmxScreen->glxMajorOpcode;
- req->glxCode = X_GLXRenderLarge;
- req->contextTag = GetCurrentBackEndTag(cl,contextTag,s);
- req->length += (amount + 3) >> 2;
- req->requestNumber = requestNumber++;
- req->requestTotal = totalRequests;
- req->dataBytes = amount;
- Data(dpy, ((const char*)data), amount);
- dataLen -= amount;
- data = ((GLbyte *) data) + amount;
- UnlockDisplay(dpy);
- SyncHandle();
- }
- }
-
- return Success;
-}
+/*
+ * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
+ * Copyright (C) 1991-2000 Silicon Graphics, 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 including the dates of first publication and
+ * either this permission notice or a reference to
+ * http://oss.sgi.com/projects/FreeB/
+ * 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
+ * SILICON GRAPHICS, INC. 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 Silicon Graphics, Inc.
+ * shall not be used in advertising or otherwise to promote the sale, use or
+ * other dealings in this Software without prior written authorization from
+ * Silicon Graphics, Inc.
+ */
+
+#ifdef HAVE_DMX_CONFIG_H
+#include <dmx-config.h>
+#endif
+
+#include "dmx.h"
+#include "dmxwindow.h"
+#include "dmxpixmap.h"
+#include "dmxfont.h"
+#include "dmxsync.h"
+
+#undef Xmalloc
+#undef Xcalloc
+#undef Xrealloc
+#undef Xfree
+
+#include "glxserver.h"
+#include <GL/glxtokens.h>
+#include "g_disptab.h"
+#include <pixmapstr.h>
+#include <windowstr.h>
+#include "glxutil.h"
+#include "glxext.h"
+#include "unpack.h"
+
+#include "GL/glxproto.h"
+#include "glxvendor.h"
+#include "glxvisuals.h"
+#include "glxswap.h"
+
+#ifdef PANORAMIX
+#include "panoramiXsrv.h"
+#endif
+
+extern __GLXFBConfig **__glXFBConfigs;
+extern int __glXNumFBConfigs;
+
+extern __GLXFBConfig *glxLookupFBConfig( GLXFBConfigID id );
+extern __GLXFBConfig *glxLookupFBConfigByVID( VisualID vid );
+extern __GLXFBConfig *glxLookupBackEndFBConfig( GLXFBConfigID id, int screen );
+extern int glxIsExtensionSupported( char *ext );
+extern int __glXGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc);
+
+#define BE_TO_CLIENT_ERROR(x) \
+ ( (x) >= __glXerrorBase ? \
+ (x) - dmxScreen->glxErrorBase + __glXerrorBase \
+ : (x) )
+
+Display *GetBackEndDisplay( __GLXclientState *cl, int s )
+{
+ if (! cl->be_displays[s] ) {
+ cl->be_displays[s] = XOpenDisplay( DisplayString(dmxScreens[s].beDisplay) );
+ }
+ return( cl->be_displays[s] );
+}
+
+/*
+** Create a GL context with the given properties.
+*/
+static int CreateContext(__GLXclientState *cl,
+ GLXContextID gcId,
+ VisualID vid, GLXFBConfigID fbconfigId,
+ int screen,
+ GLXContextID shareList,
+ int isDirect )
+{
+ ClientPtr client = cl->client;
+ xGLXCreateContextReq *be_req;
+ xGLXCreateNewContextReq *be_new_req;
+ VisualPtr pVisual;
+ ScreenPtr pScreen;
+ __GLXcontext *glxc, *shareglxc;
+ __GLXvisualConfig *pGlxVisual;
+ __GLXscreenInfo *pGlxScreen;
+ VisualID visual = vid;
+ GLint i;
+ int from_screen = screen;
+ int to_screen = screen;
+ DMXScreenInfo *dmxScreen;
+ VisualID be_vid;
+ GLXFBConfigID be_fbconfigId;
+ int num_be_screens;
+ Display *dpy;
+
+ /*
+ ** Check if screen exists.
+ */
+ if (screen >= screenInfo.numScreens) {
+ client->errorValue = screen;
+ return BadValue;
+ }
+
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ from_screen = 0;
+ to_screen = screenInfo.numScreens - 1;
+ }
+#endif
+
+ /*
+ ** Find the display list space that we want to share.
+ **
+ */
+ if (shareList == None) {
+ shareglxc = NULL;
+ } else {
+ shareglxc = (__GLXcontext *) LookupIDByType(shareList, __glXContextRes);
+ if (!shareglxc) {
+ client->errorValue = shareList;
+ return __glXBadContext;
+ }
+ }
+
+ /*
+ ** Allocate memory for the new context
+ */
+ glxc = __glXCalloc(1, sizeof(__GLXcontext));
+ if (!glxc) {
+ return BadAlloc;
+ }
+
+ pScreen = screenInfo.screens[screen];
+ pGlxScreen = &__glXActiveScreens[screen];
+
+ if (fbconfigId != None) {
+ glxc->pFBConfig = glxLookupFBConfig( fbconfigId );
+ if (!glxc->pFBConfig) {
+ client->errorValue = fbconfigId;
+ __glXFree( glxc );
+ return BadValue;
+ }
+ visual = glxc->pFBConfig->associatedVisualId;
+ }
+ else {
+ glxc->pFBConfig = NULL;
+ }
+
+ if (visual != None) {
+ /*
+ ** Check if the visual ID is valid for this screen.
+ */
+ pVisual = pScreen->visuals;
+ for (i = 0; i < pScreen->numVisuals; i++, pVisual++) {
+ if (pVisual->vid == visual) {
+ break;
+ }
+ }
+ if (i == pScreen->numVisuals) {
+ client->errorValue = visual;
+ __glXFree( glxc );
+ return BadValue;
+ }
+
+ pGlxVisual = pGlxScreen->pGlxVisual;
+ for (i = 0; i < pGlxScreen->numVisuals; i++, pGlxVisual++) {
+ if (pGlxVisual->vid == visual) {
+ break;
+ }
+ }
+ if (i == pGlxScreen->numVisuals) {
+ /*
+ ** Visual not support on this screen by this OpenGL implementation.
+ */
+ client->errorValue = visual;
+ __glXFree( glxc );
+ return BadValue;
+ }
+
+ if ( glxc->pFBConfig == NULL ) {
+ glxc->pFBConfig = glxLookupFBConfigByVID( visual );
+
+ if ( glxc->pFBConfig == NULL ) {
+ /*
+ * visual does not have an FBConfig ???
+ client->errorValue = visual;
+ __glXFree( glxc );
+ return BadValue;
+ */
+ }
+ }
+ }
+ else {
+ pVisual = NULL;
+ pGlxVisual = NULL;
+ }
+
+ glxc->pScreen = pScreen;
+ glxc->pGlxScreen = pGlxScreen;
+ glxc->pVisual = pVisual;
+ glxc->pGlxVisual = pGlxVisual;
+
+ /*
+ * allocate memory for back-end servers info
+ */
+ num_be_screens = to_screen - from_screen + 1;
+ glxc->real_ids = (XID *)__glXMalloc(sizeof(XID) * num_be_screens);
+ if (!glxc->real_ids) {
+ return BadAlloc;
+ }
+ glxc->real_vids = (XID *)__glXMalloc(sizeof(XID) * num_be_screens);
+ if (!glxc->real_vids) {
+ return BadAlloc;
+ }
+
+ for (screen = from_screen; screen <= to_screen; screen++) {
+ int sent = 0;
+ pScreen = screenInfo.screens[screen];
+ pGlxScreen = &__glXActiveScreens[screen];
+ dmxScreen = &dmxScreens[screen];
+
+ if (glxc->pFBConfig) {
+ __GLXFBConfig *beFBConfig = glxLookupBackEndFBConfig( glxc->pFBConfig->id,
+ screen );
+ be_fbconfigId = beFBConfig->id;
+ }
+
+ if (pGlxVisual) {
+
+ be_vid = glxMatchGLXVisualInConfigList( pGlxVisual,
+ dmxScreen->glxVisuals,
+ dmxScreen->numGlxVisuals );
+
+ if (!be_vid) {
+ /* visual is not supported on the back-end server */
+ __glXFree( glxc->real_ids );
+ __glXFree( glxc->real_vids );
+ __glXFree( glxc );
+ return BadValue;
+ }
+ }
+
+ glxc->real_ids[screen-from_screen] = XAllocID(GetBackEndDisplay(cl,screen));
+
+ /* send the create context request to the back-end server */
+ dpy = GetBackEndDisplay(cl,screen);
+ if (glxc->pFBConfig) {
+ /*Since for a certain visual both RGB and COLOR INDEX
+ *can be on then the only parmeter to choose the renderType
+ * should be the class of the colormap since all 4 first
+ * classes does not support RGB mode only COLOR INDEX ,
+ * and so TrueColor and DirectColor does not support COLOR INDEX*/
+ int renderType = glxc->pFBConfig->renderType;
+ if ( pVisual ) {
+ switch ( pVisual->class ){
+ case PseudoColor:
+ case StaticColor:
+ case GrayScale:
+ case StaticGray:
+ renderType = GLX_COLOR_INDEX_TYPE;
+ break;
+ case TrueColor:
+ case DirectColor:
+ default:
+ renderType = GLX_RGBA_TYPE;
+ break;
+ }
+ }
+ if ( __GLX_IS_VERSION_SUPPORTED(1,3) ) {
+ LockDisplay(dpy);
+ GetReq(GLXCreateNewContext,be_new_req);
+ be_new_req->reqType = dmxScreen->glxMajorOpcode;
+ be_new_req->glxCode = X_GLXCreateNewContext;
+ be_new_req->context = (unsigned int)glxc->real_ids[screen-from_screen];
+ be_new_req->fbconfig = (unsigned int)be_fbconfigId;
+ be_new_req->screen = DefaultScreen(dpy);
+ be_new_req->renderType = renderType;
+
+ be_new_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0);
+ be_new_req->isDirect = 0;
+ UnlockDisplay(dpy);
+ glxc->real_vids[screen-from_screen] = be_fbconfigId;
+ sent = 1;
+ }
+ else if (glxIsExtensionSupported("GLX_SGIX_fbconfig")) {
+
+ xGLXCreateContextWithConfigSGIXReq *ext_req;
+ xGLXVendorPrivateReq *vpreq;
+ LockDisplay(dpy);
+ GetReqExtra(GLXVendorPrivate,
+ sz_xGLXCreateContextWithConfigSGIXReq - sz_xGLXVendorPrivateReq,
+ vpreq);
+ ext_req = (xGLXCreateContextWithConfigSGIXReq *)vpreq;
+ ext_req->reqType = dmxScreen->glxMajorOpcode;
+ ext_req->glxCode = X_GLXVendorPrivate;
+ ext_req->vendorCode = X_GLXvop_CreateContextWithConfigSGIX;
+ ext_req->context = (unsigned int)glxc->real_ids[screen-from_screen];
+ ext_req->fbconfig = (unsigned int)be_fbconfigId;
+ ext_req->screen = DefaultScreen(dpy);
+ ext_req->renderType = renderType;
+ ext_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0);
+ ext_req->isDirect = 0;
+ UnlockDisplay(dpy);
+ glxc->real_vids[screen-from_screen] = be_fbconfigId;
+ sent = 1;
+ }
+ }
+
+ if (!sent) {
+ LockDisplay(dpy);
+ GetReq(GLXCreateContext,be_req);
+ be_req->reqType = dmxScreen->glxMajorOpcode;
+ be_req->glxCode = X_GLXCreateContext;
+ be_req->context = (unsigned int)glxc->real_ids[screen-from_screen];
+ be_req->visual = (unsigned int)be_vid;
+ be_req->screen = DefaultScreen(dpy);
+ be_req->shareList = (shareglxc ? shareglxc->real_ids[screen-from_screen] : 0);
+ be_req->isDirect = 0;
+ UnlockDisplay(dpy);
+ glxc->real_vids[screen-from_screen] = be_vid;
+ }
+ SyncHandle();
+
+ }
+
+ /*
+ ** Register this context as a resource.
+ */
+ if (!AddResource(gcId, __glXContextRes, (pointer)glxc)) {
+ __glXFree( glxc->real_ids );
+ __glXFree( glxc->real_vids );
+ __glXFree( glxc );
+ client->errorValue = gcId;
+ return BadAlloc;
+ }
+
+ /*
+ ** Finally, now that everything is working, setup the rest of the
+ ** context.
+ */
+ glxc->id = gcId;
+ glxc->share_id = shareList;
+ glxc->idExists = GL_TRUE;
+ glxc->isCurrent = GL_FALSE;
+
+ return Success;
+}
+
+int __glXCreateContext(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
+
+ return( CreateContext(cl, req->context,req->visual, None,
+ req->screen, req->shareList, req->isDirect) );
+
+}
+
+int __glXCreateNewContext(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
+
+ return( CreateContext(cl, req->context,None, req->fbconfig,
+ req->screen, req->shareList, req->isDirect) );
+
+}
+
+int __glXCreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreateContextWithConfigSGIXReq *req = (xGLXCreateContextWithConfigSGIXReq *) pc;
+
+ return( CreateContext(cl, req->context, None, req->fbconfig,
+ req->screen, req->shareList, req->isDirect) );
+
+}
+
+int __glXQueryMaxSwapBarriersSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXQueryMaxSwapBarriersSGIXReq *req =
+ (xGLXQueryMaxSwapBarriersSGIXReq *)pc;
+ xGLXQueryMaxSwapBarriersSGIXReply reply;
+
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.length = 0;
+ reply.max = QueryMaxSwapBarriersSGIX(req->screen);
+
+ if (client->swapped) {
+ __glXSwapQueryMaxSwapBarriersSGIXReply(client, &reply);
+ } else {
+ WriteToClient(client, sz_xGLXQueryMaxSwapBarriersSGIXReply,
+ (char *)&reply);
+ }
+
+ return Success;
+}
+
+int __glXBindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXBindSwapBarrierSGIXReq *req = (xGLXBindSwapBarrierSGIXReq *)pc;
+ DrawablePtr pDraw;
+ __GLXpixmap *pGlxPixmap = NULL;
+ __glXWindow *pGlxWindow = NULL;
+ int rc;
+
+ rc = dixLookupDrawable(&pDraw, req->drawable, client, 0, DixGetAttrAccess);
+ if (rc != Success) {
+ pGlxPixmap = (__GLXpixmap *) LookupIDByType(req->drawable,
+ __glXPixmapRes);
+ if (pGlxPixmap) pDraw = pGlxPixmap->pDraw;
+ }
+
+ if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
+ pGlxWindow = (__glXWindow *) LookupIDByType(req->drawable,
+ __glXWindowRes);
+ if (pGlxWindow) pDraw = pGlxWindow->pDraw;
+ }
+
+ if (!pDraw) {
+ client->errorValue = req->drawable;
+ return __glXBadDrawable;
+ }
+
+ return BindSwapBarrierSGIX(pDraw, req->barrier);
+}
+
+int __glXJoinSwapGroupSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXJoinSwapGroupSGIXReq *req = (xGLXJoinSwapGroupSGIXReq *)pc;
+ DrawablePtr pDraw, pMember = NULL;
+ __GLXpixmap *pGlxPixmap = NULL;
+ __glXWindow *pGlxWindow = NULL;
+ int rc;
+
+ rc = dixLookupDrawable(&pDraw, req->drawable, client, 0, DixManageAccess);
+ if (rc != Success) {
+ pGlxPixmap = (__GLXpixmap *) LookupIDByType(req->drawable,
+ __glXPixmapRes);
+ if (pGlxPixmap) pDraw = pGlxPixmap->pDraw;
+ }
+
+ if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
+ pGlxWindow = (__glXWindow *) LookupIDByType(req->drawable,
+ __glXWindowRes);
+ if (pGlxWindow) pDraw = pGlxWindow->pDraw;
+ }
+
+ if (!pDraw) {
+ client->errorValue = req->drawable;
+ return __glXBadDrawable;
+ }
+
+ if (req->member != None) {
+ rc = dixLookupDrawable(&pMember, req->member, client, 0,
+ DixGetAttrAccess);
+ if (rc != Success) {
+ pGlxPixmap = (__GLXpixmap *) LookupIDByType(req->member,
+ __glXPixmapRes);
+ if (pGlxPixmap) pMember = pGlxPixmap->pDraw;
+ }
+
+ if (!pMember && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
+ pGlxWindow = (__glXWindow *) LookupIDByType(req->member,
+ __glXWindowRes);
+ if (pGlxWindow) pMember = pGlxWindow->pDraw;
+ }
+
+ if (!pMember) {
+ client->errorValue = req->member;
+ return __glXBadDrawable;
+ }
+ }
+
+ return JoinSwapGroupSGIX(pDraw, pMember);
+}
+
+
+/*
+** Destroy a GL context as an X resource.
+*/
+int __glXDestroyContext(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc;
+ xGLXDestroyContextReq *be_req;
+ GLXContextID gcId = req->context;
+ __GLXcontext *glxc;
+ int from_screen = 0;
+ int to_screen = 0;
+ int s;
+
+ glxc = (__GLXcontext *) LookupIDByType(gcId, __glXContextRes);
+ if (glxc) {
+ /*
+ ** Just free the resource; don't actually destroy the context,
+ ** because it might be in use. The
+ ** destroy method will be called by the resource destruction routine
+ ** if necessary.
+ */
+ FreeResourceByType(gcId, __glXContextRes, FALSE);
+
+ from_screen = to_screen = glxc->pScreen->myNum;
+
+ } else {
+ client->errorValue = gcId;
+ return __glXBadContext;
+ }
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ from_screen = 0;
+ to_screen = screenInfo.numScreens - 1;
+ }
+#endif
+
+ /*
+ * send DestroyContext request to all back-end servers
+ */
+ for (s=from_screen; s<=to_screen; s++) {
+ DMXScreenInfo *dmxScreen = &dmxScreens[s];
+ Display *dpy = GetBackEndDisplay(cl,s);
+
+ LockDisplay(dpy);
+ GetReq(GLXDestroyContext,be_req);
+ be_req->reqType = dmxScreen->glxMajorOpcode;
+ be_req->glxCode = X_GLXDestroyContext;
+ be_req->context = glxc->real_ids[s-from_screen];
+ UnlockDisplay(dpy);
+ SyncHandle();
+ }
+
+ return Success;
+}
+
+/*****************************************************************************/
+
+/*
+** For each client, the server keeps a table of all the contexts that are
+** current for that client (each thread of a client may have its own current
+** context). These routines add, change, and lookup contexts in the table.
+*/
+
+/*
+** Add a current context, and return the tag that will be used to refer to it.
+*/
+static int AddCurrentContext(__GLXclientState *cl, __GLXcontext *glxc, DrawablePtr pDraw)
+{
+ int i;
+ int num = cl->numCurrentContexts;
+ __GLXcontext **table = cl->currentContexts;
+
+ if (!glxc) return -1;
+
+ /*
+ ** Try to find an empty slot and use it.
+ */
+ for (i=0; i < num; i++) {
+ if (!table[i]) {
+ table[i] = glxc;
+ return i+1;
+ }
+ }
+ /*
+ ** Didn't find a free slot, so we'll have to grow the table.
+ */
+ if (!num) {
+ table = (__GLXcontext **) __glXMalloc(sizeof(__GLXcontext *));
+ cl->currentDrawables = (DrawablePtr *) __glXMalloc(sizeof(DrawablePtr));
+ cl->be_currentCTag = (GLXContextTag *) __glXMalloc(screenInfo.numScreens *sizeof(GLXContextTag));
+ } else {
+ table = (__GLXcontext **) __glXRealloc(table,
+ (num+1)*sizeof(__GLXcontext *));
+ cl->currentDrawables = (DrawablePtr *) __glXRealloc(
+ cl->currentDrawables ,
+ (num+1)*sizeof(DrawablePtr));
+ cl->be_currentCTag = (GLXContextTag *) __glXRealloc(cl->be_currentCTag,
+ (num+1)*screenInfo.numScreens*sizeof(GLXContextTag));
+ }
+ table[num] = glxc;
+ cl->currentDrawables[num] = pDraw;
+ cl->currentContexts = table;
+ cl->numCurrentContexts++;
+
+ memset(cl->be_currentCTag + num*screenInfo.numScreens, 0,
+ screenInfo.numScreens * sizeof(GLXContextTag));
+
+ return num+1;
+}
+
+/*
+** Given a tag, change the current context for the corresponding entry.
+*/
+static void ChangeCurrentContext(__GLXclientState *cl, __GLXcontext *glxc,
+ GLXContextTag tag)
+{
+ __GLXcontext **table = cl->currentContexts;
+ table[tag-1] = glxc;
+}
+
+/*
+** Given a tag, and back-end screen number, retrives the current back-end
+** tag.
+*/
+int GetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s)
+{
+ if (tag >0) {
+ return( cl->be_currentCTag[ (tag-1)*screenInfo.numScreens + s ] );
+ }
+ else {
+ return( 0 );
+ }
+}
+
+/*
+** Given a tag, and back-end screen number, sets the current back-end
+** tag.
+*/
+static void SetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s, GLXContextTag be_tag)
+{
+ if (tag >0) {
+ cl->be_currentCTag[ (tag-1)*screenInfo.numScreens + s ] = be_tag;
+ }
+}
+
+/*
+** For this implementation we have chosen to simply use the index of the
+** context's entry in the table as the context tag. A tag must be greater
+** than 0.
+*/
+__GLXcontext *__glXLookupContextByTag(__GLXclientState *cl, GLXContextTag tag)
+{
+ int num = cl->numCurrentContexts;
+
+ if (tag < 1 || tag > num) {
+ return 0;
+ } else {
+ return cl->currentContexts[tag-1];
+ }
+}
+
+DrawablePtr __glXLookupDrawableByTag(__GLXclientState *cl, GLXContextTag tag)
+{
+ int num = cl->numCurrentContexts;
+
+ if (tag < 1 || tag > num) {
+ return 0;
+ } else {
+ return cl->currentDrawables[tag-1];
+ }
+}
+
+/*****************************************************************************/
+
+static void StopUsingContext(__GLXcontext *glxc)
+{
+ if (glxc) {
+ if (glxc == __glXLastContext) {
+ /* Tell server GL library */
+ __glXLastContext = 0;
+ }
+ glxc->isCurrent = GL_FALSE;
+ if (!glxc->idExists) {
+ __glXFreeContext(glxc);
+ }
+ }
+}
+
+static void StartUsingContext(__GLXclientState *cl, __GLXcontext *glxc)
+{
+ glxc->isCurrent = GL_TRUE;
+}
+
+/*****************************************************************************/
+/*
+** Make an OpenGL context and drawable current.
+*/
+static int MakeCurrent(__GLXclientState *cl,
+ GLXDrawable drawable,
+ GLXDrawable readdrawable,
+ GLXContextID context,
+ GLXContextTag oldContextTag)
+{
+ ClientPtr client = cl->client;
+ DrawablePtr pDraw = NULL;
+ DrawablePtr pReadDraw = NULL;
+ xGLXMakeCurrentReadSGIReply new_reply;
+ xGLXMakeCurrentReq *be_req;
+ xGLXMakeCurrentReply be_reply;
+ xGLXMakeContextCurrentReq *be_new_req;
+ xGLXMakeContextCurrentReply be_new_reply;
+ GLXDrawable drawId = drawable;
+ GLXDrawable readId = readdrawable;
+ GLXContextID contextId = context;
+ __GLXpixmap *pGlxPixmap = 0;
+ __GLXpixmap *pReadGlxPixmap = 0;
+ __GLXcontext *glxc, *prevglxc;
+ GLXContextTag tag = oldContextTag;
+ WindowPtr pWin = NULL;
+ WindowPtr pReadWin = NULL;
+ __glXWindow *pGlxWindow = NULL;
+ __glXWindow *pGlxReadWindow = NULL;
+ __glXPbuffer *pGlxPbuffer = NULL;
+ __glXPbuffer *pGlxReadPbuffer = NULL;
+#ifdef PANORAMIX
+ PanoramiXRes *pXinDraw = NULL;
+ PanoramiXRes *pXinReadDraw = NULL;
+#endif
+ int from_screen = 0;
+ int to_screen = 0;
+ int s, rc;
+
+ /*
+ ** If one is None and the other isn't, it's a bad match.
+ */
+ if ((drawId == None && contextId != None) ||
+ (drawId != None && contextId == None)) {
+ return BadMatch;
+ }
+
+ /*
+ ** Lookup old context. If we have one, it must be in a usable state.
+ */
+ if (tag != 0) {
+ prevglxc = __glXLookupContextByTag(cl, tag);
+ if (!prevglxc) {
+ /*
+ ** Tag for previous context is invalid.
+ */
+ return __glXBadContextTag;
+ }
+ } else {
+ prevglxc = 0;
+ }
+
+ /*
+ ** Lookup new context. It must not be current for someone else.
+ */
+ if (contextId != None) {
+ glxc = (__GLXcontext *) LookupIDByType(contextId, __glXContextRes);
+ if (!glxc) {
+ client->errorValue = contextId;
+ return __glXBadContext;
+ }
+ if ((glxc != prevglxc) && glxc->isCurrent) {
+ /* Context is current to somebody else */
+ return BadAccess;
+ }
+ } else {
+ /* Switching to no context. Ignore new drawable. */
+ glxc = 0;
+ }
+
+ if (drawId != None) {
+ rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixWriteAccess);
+ if (rc == Success) {
+ if (pDraw->type == DRAWABLE_WINDOW) {
+ /*
+ ** Drawable is an X Window.
+ */
+ VisualID vid;
+ pWin = (WindowPtr)pDraw;
+ vid = wVisual(pWin);
+
+ new_reply.writeVid = (glxc->pFBConfig ? glxc->pFBConfig->id : vid);
+ new_reply.writeType = GLX_WINDOW_TYPE;
+
+ /*
+ ** Check if window and context are similar.
+ */
+ if ((vid != glxc->pVisual->vid) ||
+ (pWin->drawable.pScreen != glxc->pScreen)) {
+ client->errorValue = drawId;
+ return BadMatch;
+ }
+
+ from_screen = to_screen = pWin->drawable.pScreen->myNum;
+
+ } else {
+ /*
+ ** An X Pixmap is not allowed as a parameter (a GLX Pixmap
+ ** is, but it must first be created with glxCreateGLXPixmap).
+ */
+ client->errorValue = drawId;
+ return __glXBadDrawable;
+ }
+ }
+
+ if (!pDraw) {
+ pGlxPixmap = (__GLXpixmap *) LookupIDByType(drawId,
+ __glXPixmapRes);
+ if (pGlxPixmap) {
+ /*
+ ** Check if pixmap and context are similar.
+ */
+ if (pGlxPixmap->pScreen != glxc->pScreen ||
+ pGlxPixmap->pGlxVisual != glxc->pGlxVisual) {
+ client->errorValue = drawId;
+ return BadMatch;
+ }
+ pDraw = pGlxPixmap->pDraw;
+
+ new_reply.writeVid = (glxc->pFBConfig ? glxc->pFBConfig->id :
+ pGlxPixmap->pGlxVisual->vid);
+
+ new_reply.writeType = GLX_PIXMAP_TYPE;
+
+ from_screen = to_screen = pGlxPixmap->pScreen->myNum;
+
+ }
+ }
+
+ if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
+ pGlxWindow = (__glXWindow *) LookupIDByType(drawId, __glXWindowRes);
+ if (pGlxWindow) {
+ /*
+ ** Drawable is a GLXWindow.
+ **
+ ** Check if GLX window and context are similar.
+ */
+ if (pGlxWindow->pScreen != glxc->pScreen ||
+ pGlxWindow->pGlxFBConfig != glxc->pFBConfig) {
+ client->errorValue = drawId;
+ return BadMatch;
+ }
+
+ pDraw = pGlxWindow->pDraw;
+ new_reply.writeVid = pGlxWindow->pGlxFBConfig->id;
+ new_reply.writeType = GLX_GLXWINDOW_TYPE;
+ }
+
+ }
+
+ if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
+ pGlxPbuffer = (__glXPbuffer *)LookupIDByType(drawId, __glXPbufferRes);
+ if (pGlxPbuffer) {
+ if (pGlxPbuffer->pScreen != glxc->pScreen ||
+ pGlxPbuffer->pFBConfig != glxc->pFBConfig) {
+ client->errorValue = drawId;
+ return BadMatch;
+ }
+
+ pDraw = (DrawablePtr)pGlxPbuffer;
+ new_reply.writeVid = pGlxPbuffer->pFBConfig->id;
+ new_reply.writeType = GLX_PBUFFER_TYPE;
+ }
+ }
+
+ if (!pDraw) {
+ /*
+ ** Drawable is not a Window , GLXWindow or a GLXPixmap.
+ */
+ client->errorValue = drawId;
+ return __glXBadDrawable;
+ }
+
+ } else {
+ pDraw = 0;
+ }
+
+ if (readId != None && readId != drawId ) {
+ rc = dixLookupDrawable(&pReadDraw, readId, client, 0, DixReadAccess);
+ if (rc == Success) {
+ if (pReadDraw->type == DRAWABLE_WINDOW) {
+ /*
+ ** Drawable is an X Window.
+ */
+ VisualID vid;
+ pReadWin = (WindowPtr)pDraw;
+ vid = wVisual(pReadWin);
+
+ new_reply.readVid = (glxc->pFBConfig ? glxc->pFBConfig->id : vid);
+ new_reply.readType = GLX_WINDOW_TYPE;
+
+ /*
+ ** Check if window and context are similar.
+ */
+ if ((vid != glxc->pVisual->vid) ||
+ (pReadWin->drawable.pScreen != glxc->pScreen)) {
+ client->errorValue = readId;
+ return BadMatch;
+ }
+
+ } else {
+
+ /*
+ ** An X Pixmap is not allowed as a parameter (a GLX Pixmap
+ ** is, but it must first be created with glxCreateGLXPixmap).
+ */
+ client->errorValue = readId;
+ return __glXBadDrawable;
+ }
+ }
+
+ if (!pReadDraw) {
+ pReadGlxPixmap = (__GLXpixmap *) LookupIDByType(readId,
+ __glXPixmapRes);
+ if (pReadGlxPixmap) {
+ /*
+ ** Check if pixmap and context are similar.
+ */
+ if (pReadGlxPixmap->pScreen != glxc->pScreen ||
+ pReadGlxPixmap->pGlxVisual != glxc->pGlxVisual) {
+ client->errorValue = readId;
+ return BadMatch;
+ }
+ pReadDraw = pReadGlxPixmap->pDraw;
+
+ new_reply.readVid = (glxc->pFBConfig ? glxc->pFBConfig->id :
+ pReadGlxPixmap->pGlxVisual->vid );
+ new_reply.readType = GLX_PIXMAP_TYPE;
+
+ }
+ }
+
+ if (!pReadDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
+ pGlxReadWindow = (__glXWindow *)
+ LookupIDByType(readId, __glXWindowRes);
+ if (pGlxReadWindow) {
+ /*
+ ** Drawable is a GLXWindow.
+ **
+ ** Check if GLX window and context are similar.
+ */
+ if (pGlxReadWindow->pScreen != glxc->pScreen ||
+ pGlxReadWindow->pGlxFBConfig != glxc->pFBConfig) {
+ client->errorValue = readId;
+ return BadMatch;
+ }
+
+ pReadDraw = pGlxReadWindow->pDraw;
+ new_reply.readVid = pGlxReadWindow->pGlxFBConfig->id;
+ new_reply.readType = GLX_GLXWINDOW_TYPE;
+ }
+ }
+
+ if (!pReadDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
+ pGlxReadPbuffer = (__glXPbuffer *)LookupIDByType(readId, __glXPbufferRes);
+ if (pGlxReadPbuffer) {
+ if (pGlxReadPbuffer->pScreen != glxc->pScreen ||
+ pGlxReadPbuffer->pFBConfig != glxc->pFBConfig) {
+ client->errorValue = drawId;
+ return BadMatch;
+ }
+
+ pReadDraw = (DrawablePtr)pGlxReadPbuffer;
+ new_reply.readVid = pGlxReadPbuffer->pFBConfig->id;
+ new_reply.readType = GLX_PBUFFER_TYPE;
+ }
+ }
+
+ if (!pReadDraw) {
+ /*
+ ** Drawable is neither a Window nor a GLXPixmap.
+ */
+ client->errorValue = readId;
+ return __glXBadDrawable;
+ }
+
+ } else {
+ pReadDraw = pDraw;
+ pReadGlxPixmap = pGlxPixmap;
+ pReadWin = pWin;
+ new_reply.readVid = new_reply.writeVid;
+ new_reply.readType = new_reply.writeType;
+ }
+
+ if (prevglxc) {
+
+ if (prevglxc->pGlxPixmap) {
+ /*
+ ** The previous drawable was a glx pixmap, release it.
+ */
+ prevglxc->pGlxPixmap->refcnt--;
+ __glXFreeGLXPixmap( prevglxc->pGlxPixmap );
+ prevglxc->pGlxPixmap = 0;
+ }
+
+ if (prevglxc->pGlxReadPixmap) {
+ /*
+ ** The previous drawable was a glx pixmap, release it.
+ */
+ prevglxc->pGlxReadPixmap->refcnt--;
+ __glXFreeGLXPixmap( prevglxc->pGlxReadPixmap );
+ prevglxc->pGlxReadPixmap = 0;
+ }
+
+ if (prevglxc->pGlxWindow) {
+ /*
+ ** The previous drawable was a glx window, release it.
+ */
+ prevglxc->pGlxWindow->refcnt--;
+ __glXFreeGLXWindow( prevglxc->pGlxWindow );
+ prevglxc->pGlxWindow = 0;
+ }
+
+ if (prevglxc->pGlxReadWindow) {
+ /*
+ ** The previous drawable was a glx window, release it.
+ */
+ prevglxc->pGlxReadWindow->refcnt--;
+ __glXFreeGLXWindow( prevglxc->pGlxReadWindow );
+ prevglxc->pGlxReadWindow = 0;
+ }
+
+ if (prevglxc->pGlxPbuffer) {
+ /*
+ ** The previous drawable was a glx Pbuffer, release it.
+ */
+ prevglxc->pGlxPbuffer->refcnt--;
+ __glXFreeGLXPbuffer( prevglxc->pGlxPbuffer );
+ prevglxc->pGlxPbuffer = 0;
+ }
+
+ if (prevglxc->pGlxReadPbuffer) {
+ /*
+ ** The previous drawable was a glx Pbuffer, release it.
+ */
+ prevglxc->pGlxReadPbuffer->refcnt--;
+ __glXFreeGLXPbuffer( prevglxc->pGlxReadPbuffer );
+ prevglxc->pGlxReadPbuffer = 0;
+ }
+
+ ChangeCurrentContext(cl, glxc, tag);
+ ChangeCurrentContext(cl, glxc, tag);
+ StopUsingContext(prevglxc);
+ } else {
+ tag = AddCurrentContext(cl, glxc, pDraw);
+ }
+ if (glxc) {
+
+ glxc->pGlxPixmap = pGlxPixmap;
+ glxc->pGlxReadPixmap = pReadGlxPixmap;
+ glxc->pGlxWindow = pGlxWindow;
+ glxc->pGlxReadWindow = pGlxReadWindow;
+ glxc->pGlxPbuffer = pGlxPbuffer;
+ glxc->pGlxReadPbuffer = pGlxReadPbuffer;
+
+ if (pGlxPixmap) {
+ pGlxPixmap->refcnt++;
+ }
+
+ if (pReadGlxPixmap) {
+ pReadGlxPixmap->refcnt++;
+ }
+
+ if (pGlxWindow) {
+ pGlxWindow->refcnt++;
+ }
+
+ if (pGlxReadWindow) {
+ pGlxReadWindow->refcnt++;
+ }
+
+ if (pGlxPbuffer) {
+ pGlxPbuffer->refcnt++;
+ }
+
+ if (pGlxReadPbuffer) {
+ pGlxReadPbuffer->refcnt++;
+ }
+
+ StartUsingContext(cl, glxc);
+ new_reply.contextTag = tag;
+ } else {
+ new_reply.contextTag = 0;
+ }
+ new_reply.length = 0;
+ new_reply.type = X_Reply;
+ new_reply.sequenceNumber = client->sequence;
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ from_screen = 0;
+ to_screen = screenInfo.numScreens - 1;
+
+ if (pDraw && new_reply.writeType != GLX_PBUFFER_TYPE) {
+ pXinDraw = (PanoramiXRes *)
+ SecurityLookupIDByClass(client, pDraw->id, XRC_DRAWABLE, DixReadAccess);
+ }
+
+ if (pReadDraw && pReadDraw != pDraw &&
+ new_reply.readType != GLX_PBUFFER_TYPE) {
+ pXinReadDraw = (PanoramiXRes *)
+ SecurityLookupIDByClass(client, pReadDraw->id, XRC_DRAWABLE, DixReadAccess);
+ }
+ else {
+ pXinReadDraw = pXinDraw;
+ }
+ }
+#endif
+
+
+ /* send the MakeCurrent request to all required
+ * back-end servers.
+ */
+ for (s = from_screen; s<=to_screen; s++) {
+ DMXScreenInfo *dmxScreen = &dmxScreens[s];
+ Display *dpy = GetBackEndDisplay(cl,s);
+ unsigned int be_draw = None;
+ unsigned int be_read_draw = None;
+
+ if (pGlxPixmap) {
+ be_draw = pGlxPixmap->be_xids[s];
+ }
+ else if (pGlxPbuffer) {
+ be_draw = pGlxPbuffer->be_xids[s];
+ }
+#ifdef PANORAMIX
+ else if (pXinDraw) {
+ dixLookupWindow(&pWin, pXinDraw->info[s].id, client, DixReadAccess);
+ }
+#endif
+ else if (pGlxWindow) {
+ pWin = (WindowPtr)pGlxWindow->pDraw;
+ }
+
+ if (pWin && be_draw == None) {
+ be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
+ if (!be_draw) {
+ /* it might be that the window did not created yet on the */
+ /* back-end server (lazy window creation option), force */
+ /* creation of the window */
+ dmxCreateAndRealizeWindow( pWin, TRUE );
+ be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
+ }
+ }
+
+ /*
+ * Before sending the MakeCurrent request - sync the
+ * X11 connection to the back-end servers to make sure
+ * that drawable is already created
+ */
+ dmxSync( dmxScreen, 1 );
+
+ if (drawId == readId) {
+ LockDisplay(dpy);
+ GetReq(GLXMakeCurrent, be_req);
+ be_req->reqType = dmxScreen->glxMajorOpcode;
+ be_req->glxCode = X_GLXMakeCurrent;
+ be_req->drawable = be_draw;
+ be_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0);
+ be_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s);
+ if (!_XReply(dpy, (xReply *) &be_reply, 0, False)) {
+
+ /* The make current failed */
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) );
+ }
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ SetCurrentBackEndTag( cl, tag, s, be_reply.contextTag );
+ }
+ else {
+
+ if (pReadGlxPixmap) {
+ be_read_draw = pReadGlxPixmap->be_xids[s];
+ }
+ else if (pGlxReadPbuffer) {
+ be_read_draw = pGlxReadPbuffer->be_xids[s];
+ }
+#ifdef PANORAMIX
+ else if (pXinReadDraw) {
+ dixLookupWindow(&pReadWin, pXinReadDraw->info[s].id, client,
+ DixReadAccess);
+ }
+#endif
+ else if (pGlxReadWindow) {
+ pReadWin = (WindowPtr)pGlxReadWindow->pDraw;
+ }
+
+ if (pReadWin && be_read_draw == None) {
+ be_read_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pReadWin))->window;
+ if (!be_read_draw) {
+ /* it might be that the window did not created yet on the */
+ /* back-end server (lazy window creation option), force */
+ /* creation of the window */
+ dmxCreateAndRealizeWindow( pReadWin, TRUE );
+ be_read_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pReadWin))->window;
+ dmxSync( dmxScreen, 1 );
+ }
+ }
+
+ if ( __GLX_IS_VERSION_SUPPORTED(1,3) ) {
+ LockDisplay(dpy);
+ GetReq(GLXMakeContextCurrent, be_new_req);
+ be_new_req->reqType = dmxScreen->glxMajorOpcode;
+ be_new_req->glxCode = X_GLXMakeContextCurrent;
+ be_new_req->drawable = be_draw;
+ be_new_req->readdrawable = be_read_draw;
+ be_new_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0);
+ be_new_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s);
+ if (!_XReply(dpy, (xReply *) &be_new_reply, 0, False)) {
+
+ /* The make current failed */
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) );
+ }
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ SetCurrentBackEndTag( cl, tag, s, be_new_reply.contextTag );
+ }
+ else if (glxIsExtensionSupported("GLX_SGI_make_current_read")) {
+ xGLXMakeCurrentReadSGIReq *ext_req;
+ xGLXVendorPrivateWithReplyReq *vpreq;
+ xGLXMakeCurrentReadSGIReply ext_reply;
+
+ LockDisplay(dpy);
+ GetReqExtra(GLXVendorPrivateWithReply,
+ sz_xGLXMakeCurrentReadSGIReq - sz_xGLXVendorPrivateWithReplyReq,
+ vpreq);
+ ext_req = (xGLXMakeCurrentReadSGIReq *)vpreq;
+ ext_req->reqType = dmxScreen->glxMajorOpcode;
+ ext_req->glxCode = X_GLXVendorPrivateWithReply;
+ ext_req->vendorCode = X_GLXvop_MakeCurrentReadSGI;
+ ext_req->drawable = be_draw;
+ ext_req->readable = be_read_draw;
+ ext_req->context = (unsigned int)(glxc ? glxc->real_ids[s-from_screen] : 0);
+ ext_req->oldContextTag = GetCurrentBackEndTag(cl, tag, s);
+ if (!_XReply(dpy, (xReply *) &ext_reply, 0, False)) {
+
+ /* The make current failed */
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) );
+ }
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ SetCurrentBackEndTag( cl, tag, s, ext_reply.contextTag );
+
+ }
+ else {
+ return BadMatch;
+ }
+ }
+
+ XFlush( dpy );
+ }
+
+ if (client->swapped) {
+ __glXSwapMakeCurrentReply(client, &new_reply);
+ } else {
+ WriteToClient(client, sz_xGLXMakeContextCurrentReply, (char *)&new_reply);
+ }
+
+ return Success;
+}
+
+int __glXMakeCurrent(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc;
+
+ return( MakeCurrent(cl, req->drawable, req->drawable,
+ req->context, req->oldContextTag ) );
+}
+
+int __glXMakeContextCurrent(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc;
+
+ return( MakeCurrent(cl, req->drawable, req->readdrawable,
+ req->context, req->oldContextTag ) );
+}
+
+int __glXMakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc;
+
+ return( MakeCurrent(cl, req->drawable, req->readable,
+ req->context, req->oldContextTag ) );
+}
+
+int __glXIsDirect(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc;
+ xGLXIsDirectReply reply;
+ __GLXcontext *glxc;
+
+ /*
+ ** Find the GL context.
+ */
+ glxc = (__GLXcontext *) LookupIDByType(req->context, __glXContextRes);
+ if (!glxc) {
+ client->errorValue = req->context;
+ return __glXBadContext;
+ }
+
+ reply.isDirect = 0;
+ reply.length = 0;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+
+ if (client->swapped) {
+ __glXSwapIsDirectReply(client, &reply);
+ } else {
+ WriteToClient(client, sz_xGLXIsDirectReply, (char *)&reply);
+ }
+
+ return Success;
+}
+
+int __glXQueryVersion(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+/* xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc; */
+ xGLXQueryVersionReply reply;
+
+ /*
+ ** Server should take into consideration the version numbers sent by the
+ ** client if it wants to work with older clients; however, in this
+ ** implementation the server just returns its version number.
+ */
+ reply.majorVersion = __glXVersionMajor;
+ reply.minorVersion = __glXVersionMinor;
+ reply.length = 0;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+
+ if (client->swapped) {
+ __glXSwapQueryVersionReply(client, &reply);
+ } else {
+ WriteToClient(client, sz_xGLXQueryVersionReply, (char *)&reply);
+ }
+ return Success;
+}
+
+int __glXWaitGL(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXWaitGLReq *req = (xGLXWaitGLReq *)pc;
+ xGLXWaitGLReq *be_req = (xGLXWaitGLReq *)pc;
+ int from_screen = 0;
+ int to_screen = 0;
+ int s;
+ __GLXcontext *glxc = NULL;
+
+ if (req->contextTag != 0) {
+ glxc = __glXLookupContextByTag(cl, req->contextTag);
+ if (glxc) {
+ from_screen = to_screen = glxc->pScreen->myNum;
+ }
+ }
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ from_screen = 0;
+ to_screen = screenInfo.numScreens - 1;
+ }
+#endif
+
+ for (s=from_screen; s<=to_screen; s++) {
+ DMXScreenInfo *dmxScreen = &dmxScreens[s];
+ Display *dpy = GetBackEndDisplay(cl,s);
+
+ LockDisplay(dpy);
+ GetReq(GLXWaitGL,be_req);
+ be_req->reqType = dmxScreen->glxMajorOpcode;
+ be_req->glxCode = X_GLXWaitGL;
+ be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0);
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ XSync(dpy, False);
+ }
+
+ return Success;
+}
+
+int __glXWaitX(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXWaitXReq *req = (xGLXWaitXReq *)pc;
+ xGLXWaitXReq *be_req;
+ int from_screen = 0;
+ int to_screen = 0;
+ int s;
+ __GLXcontext *glxc = NULL;
+
+ if (req->contextTag != 0) {
+ glxc = __glXLookupContextByTag(cl, req->contextTag);
+ if (glxc) {
+ from_screen = to_screen = glxc->pScreen->myNum;
+ }
+ }
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ from_screen = 0;
+ to_screen = screenInfo.numScreens - 1;
+ }
+#endif
+
+ for (s=from_screen; s<=to_screen; s++) {
+ DMXScreenInfo *dmxScreen = &dmxScreens[s];
+ Display *dpy = GetBackEndDisplay(cl,s);
+
+ dmxSync( dmxScreen, 1 );
+
+ LockDisplay(dpy);
+ GetReq(GLXWaitX,be_req);
+ be_req->reqType = dmxScreen->glxMajorOpcode;
+ be_req->glxCode = X_GLXWaitX;
+ be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0);
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ XFlush( dpy );
+ }
+
+ return Success;
+}
+
+int __glXCopyContext(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXCopyContextReq *be_req;
+ xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc;
+ GLXContextID source = req->source;
+ GLXContextID dest = req->dest;
+ GLXContextTag tag = req->contextTag;
+ unsigned long mask = req->mask;
+ __GLXcontext *src, *dst;
+ int s;
+ int from_screen = 0;
+ int to_screen = 0;
+
+ /*
+ ** Check that each context exists.
+ */
+ src = (__GLXcontext *) LookupIDByType(source, __glXContextRes);
+ if (!src) {
+ client->errorValue = source;
+ return __glXBadContext;
+ }
+ dst = (__GLXcontext *) LookupIDByType(dest, __glXContextRes);
+ if (!dst) {
+ client->errorValue = dest;
+ return __glXBadContext;
+ }
+
+ /*
+ ** They must be in the same address space, and same screen.
+ */
+ if (src->pGlxScreen != dst->pGlxScreen) {
+ client->errorValue = source;
+ return BadMatch;
+ }
+
+ /*
+ ** The destination context must not be current for any client.
+ */
+ if (dst->isCurrent) {
+ client->errorValue = dest;
+ return BadAccess;
+ }
+
+ if (tag) {
+ __GLXcontext *tagcx = __glXLookupContextByTag(cl, tag);
+
+ if (!tagcx) {
+ return __glXBadContextTag;
+ }
+ if (tagcx != src) {
+ /*
+ ** This would be caused by a faulty implementation of the client
+ ** library.
+ */
+ return BadMatch;
+ }
+ }
+
+ from_screen = to_screen = src->pScreen->myNum;
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ from_screen = 0;
+ to_screen = screenInfo.numScreens - 1;
+ }
+#endif
+
+ for (s=from_screen; s<=to_screen; s++) {
+ DMXScreenInfo *dmxScreen = &dmxScreens[s];
+ Display *dpy = GetBackEndDisplay(cl,s);
+
+ LockDisplay(dpy);
+ GetReq(GLXCopyContext,be_req);
+ be_req->reqType = dmxScreen->glxMajorOpcode;
+ be_req->glxCode = X_GLXCopyContext;
+ be_req->source = (unsigned int)src->real_ids[s-from_screen];
+ be_req->dest = (unsigned int)dst->real_ids[s-from_screen];
+ be_req->mask = mask;
+ be_req->contextTag = (tag ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ }
+
+ return Success;
+}
+
+int __glXGetVisualConfigs(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc;
+ xGLXGetVisualConfigsReply reply;
+ __GLXscreenInfo *pGlxScreen;
+ __GLXvisualConfig *pGlxVisual;
+ CARD32 buf[__GLX_TOTAL_CONFIG];
+ unsigned int screen;
+ int i, p;
+
+ screen = req->screen;
+ if (screen > screenInfo.numScreens) {
+ /* The client library must send a valid screen number. */
+ client->errorValue = screen;
+ return BadValue;
+ }
+ pGlxScreen = &__glXActiveScreens[screen];
+
+ reply.numVisuals = pGlxScreen->numGLXVisuals;
+ reply.numProps = __GLX_TOTAL_CONFIG;
+ reply.length = (pGlxScreen->numGLXVisuals * __GLX_SIZE_CARD32 *
+ __GLX_TOTAL_CONFIG) >> 2;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+
+ WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char *)&reply);
+
+ for (i=0; i < pGlxScreen->numVisuals; i++) {
+ pGlxVisual = &pGlxScreen->pGlxVisual[i];
+ if (!pGlxScreen->isGLXvis[i] || pGlxVisual->vid == 0) {
+ /* not a usable visual */
+ continue;
+ }
+ p = 0;
+ buf[p++] = pGlxVisual->vid;
+ buf[p++] = pGlxVisual->class;
+ buf[p++] = pGlxVisual->rgba;
+
+ buf[p++] = pGlxVisual->redSize;
+ buf[p++] = pGlxVisual->greenSize;
+ buf[p++] = pGlxVisual->blueSize;
+ buf[p++] = pGlxVisual->alphaSize;
+ buf[p++] = pGlxVisual->accumRedSize;
+ buf[p++] = pGlxVisual->accumGreenSize;
+ buf[p++] = pGlxVisual->accumBlueSize;
+ buf[p++] = pGlxVisual->accumAlphaSize;
+
+ buf[p++] = pGlxVisual->doubleBuffer;
+ buf[p++] = pGlxVisual->stereo;
+
+ buf[p++] = pGlxVisual->bufferSize;
+ buf[p++] = pGlxVisual->depthSize;
+ buf[p++] = pGlxVisual->stencilSize;
+ buf[p++] = pGlxVisual->auxBuffers;
+ buf[p++] = pGlxVisual->level;
+ /*
+ ** Add token/value pairs for extensions.
+ */
+ buf[p++] = GLX_VISUAL_CAVEAT_EXT;
+ buf[p++] = pGlxVisual->visualRating;
+ buf[p++] = GLX_TRANSPARENT_TYPE_EXT;
+ buf[p++] = pGlxVisual->transparentPixel;
+ buf[p++] = GLX_TRANSPARENT_RED_VALUE_EXT;
+ buf[p++] = pGlxVisual->transparentRed;
+ buf[p++] = GLX_TRANSPARENT_GREEN_VALUE_EXT;
+ buf[p++] = pGlxVisual->transparentGreen;
+ buf[p++] = GLX_TRANSPARENT_BLUE_VALUE_EXT;
+ buf[p++] = pGlxVisual->transparentBlue;
+ buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE_EXT;
+ buf[p++] = pGlxVisual->transparentAlpha;
+ buf[p++] = GLX_TRANSPARENT_INDEX_VALUE_EXT;
+ buf[p++] = pGlxVisual->transparentIndex;
+ buf[p++] = GLX_SAMPLES_SGIS;
+ buf[p++] = pGlxVisual->multiSampleSize;
+ buf[p++] = GLX_SAMPLE_BUFFERS_SGIS;
+ buf[p++] = pGlxVisual->nMultiSampleBuffers;
+ buf[p++] = GLX_VISUAL_SELECT_GROUP_SGIX;
+ buf[p++] = pGlxVisual->visualSelectGroup;
+
+ WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_TOTAL_CONFIG,
+ (char *)buf);
+ }
+ return Success;
+}
+
+/*
+** Create a GLX Pixmap from an X Pixmap.
+*/
+static int CreateGLXPixmap(__GLXclientState *cl,
+ VisualID visual, GLXFBConfigID fbconfigId,
+ int screenNum, XID pixmapId, XID glxpixmapId )
+{
+ ClientPtr client = cl->client;
+ xGLXCreateGLXPixmapReq *be_req;
+ xGLXCreatePixmapReq *be_new_req;
+ DrawablePtr pDraw;
+ ScreenPtr pScreen;
+ VisualPtr pVisual;
+ __GLXpixmap *pGlxPixmap;
+ __GLXscreenInfo *pGlxScreen;
+ __GLXvisualConfig *pGlxVisual;
+ __GLXFBConfig *pFBConfig;
+ int i, s, rc;
+ int from_screen, to_screen;
+#ifdef PANORAMIX
+ PanoramiXRes *pXinDraw = NULL;
+#endif
+
+ rc = dixLookupDrawable(&pDraw, pixmapId, client, M_DRAWABLE_PIXMAP,
+ DixAddAccess);
+ if (rc != Success)
+ return rc;
+
+ /*
+ ** Check if screen of visual matches screen of pixmap.
+ */
+ pScreen = pDraw->pScreen;
+ if (screenNum != pScreen->myNum) {
+ return BadMatch;
+ }
+
+ if (fbconfigId == NULL && visual == NULL) {
+ return BadValue;
+ }
+
+ if (fbconfigId != None) {
+ pFBConfig = glxLookupFBConfig( fbconfigId );
+ if (!pFBConfig) {
+ client->errorValue = fbconfigId;
+ return BadValue;
+ }
+ visual = pFBConfig->associatedVisualId;
+ }
+ else {
+ pFBConfig = NULL;
+ }
+
+ if (visual != None) {
+ /*
+ ** Find the VisualRec for this visual.
+ */
+ pVisual = pScreen->visuals;
+ for (i=0; i < pScreen->numVisuals; i++, pVisual++) {
+ if (pVisual->vid == visual) {
+ break;
+ }
+ }
+ if (i == pScreen->numVisuals) {
+ client->errorValue = visual;
+ return BadValue;
+ }
+ /*
+ ** Check if depth of visual matches depth of pixmap.
+ */
+ if (pVisual->nplanes != pDraw->depth) {
+ client->errorValue = visual;
+ return BadMatch;
+ }
+
+ /*
+ ** Get configuration of the visual.
+ */
+ pGlxScreen = &__glXActiveScreens[screenNum];
+ pGlxVisual = pGlxScreen->pGlxVisual;
+ for (i = 0; i < pGlxScreen->numVisuals; i++, pGlxVisual++) {
+ if (pGlxVisual->vid == visual) {
+ break;
+ }
+ }
+ if (i == pGlxScreen->numVisuals) {
+ /*
+ ** Visual not support on this screen by this OpenGL implementation.
+ */
+ client->errorValue = visual;
+ return BadValue;
+ }
+
+
+ /* find the FBConfig for that visual (if any) */
+ if ( pFBConfig == NULL ) {
+ pFBConfig = glxLookupFBConfigByVID( visual );
+
+ if ( pFBConfig == NULL ) {
+ /*
+ * visual does not have an FBConfig ???
+ client->errorValue = visual;
+ return BadValue;
+ */
+ }
+ }
+ }
+ else {
+ pVisual = NULL;
+ pGlxVisual = NULL;
+ }
+
+ pGlxPixmap = (__GLXpixmap *) __glXMalloc(sizeof(__GLXpixmap));
+ if (!pGlxPixmap) {
+ return BadAlloc;
+ }
+ pGlxPixmap->be_xids = (XID *) __glXMalloc(sizeof(XID) * screenInfo.numScreens);
+ if (!pGlxPixmap->be_xids) {
+ __glXFree( pGlxPixmap );
+ return BadAlloc;
+ }
+
+ pGlxPixmap->pDraw = pDraw;
+ pGlxPixmap->pGlxScreen = pGlxScreen;
+ pGlxPixmap->pGlxVisual = pGlxVisual;
+ pGlxPixmap->pFBConfig = pFBConfig;
+ pGlxPixmap->pScreen = pScreen;
+ pGlxPixmap->idExists = True;
+ pGlxPixmap->refcnt = 0;
+
+ /*
+ ** Bump the ref count on the X pixmap so it won't disappear.
+ */
+ ((PixmapPtr) pDraw)->refcnt++;
+
+ /*
+ * send the request to the back-end server(s)
+ */
+ from_screen = to_screen = screenNum;
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ from_screen = 0;
+ to_screen = screenInfo.numScreens - 1;
+
+ pXinDraw = (PanoramiXRes *)
+ SecurityLookupIDByClass(client, pDraw->id, XRC_DRAWABLE, DixReadAccess);
+ }
+#endif
+
+ for (s=from_screen; s<=to_screen; s++) {
+
+ DMXScreenInfo *dmxScreen = &dmxScreens[s];
+ Display *dpy = GetBackEndDisplay(cl,s);
+ Pixmap be_pixmap;
+ DrawablePtr pRealDraw = pDraw;
+
+#ifdef PANORAMIX
+ if (pXinDraw) {
+ dixLookupDrawable(&pRealDraw, pXinDraw->info[s].id, client, 0,
+ DixAddAccess);
+ }
+#endif
+
+ be_pixmap = (DMX_GET_PIXMAP_PRIV((PixmapPtr)pRealDraw))->pixmap;
+
+ /* make sure pixmap already created on back-end */
+ dmxSync( dmxScreen, 1 );
+
+ if ( pFBConfig && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
+ __GLXFBConfig *be_FBConfig = glxLookupBackEndFBConfig( pFBConfig->id, s );
+
+ LockDisplay(dpy);
+ pGlxPixmap->be_xids[s] = XAllocID(dpy);
+ GetReq(GLXCreatePixmap,be_new_req);
+ be_new_req->reqType = dmxScreen->glxMajorOpcode;
+ be_new_req->glxCode = X_GLXCreatePixmap;
+ be_new_req->screen = DefaultScreen(dpy);
+ be_new_req->fbconfig = be_FBConfig->id;
+ be_new_req->pixmap = (unsigned int)be_pixmap;
+ be_new_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s];
+ be_new_req->numAttribs = 0;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ }
+ else if (pFBConfig && glxIsExtensionSupported("GLX_SGIX_fbconfig")) {
+ __GLXFBConfig *be_FBConfig = glxLookupBackEndFBConfig( pFBConfig->id, s );
+ xGLXCreateGLXPixmapWithConfigSGIXReq *ext_req;
+ xGLXVendorPrivateReq *vpreq;
+
+ LockDisplay(dpy);
+ pGlxPixmap->be_xids[s] = XAllocID(dpy);
+ GetReqExtra(GLXVendorPrivate,
+ sz_xGLXCreateGLXPixmapWithConfigSGIXReq-sz_xGLXVendorPrivateReq,
+ vpreq);
+ ext_req = (xGLXCreateGLXPixmapWithConfigSGIXReq *)vpreq;
+ ext_req->reqType = dmxScreen->glxMajorOpcode;
+ ext_req->glxCode = X_GLXVendorPrivate;
+ ext_req->vendorCode = X_GLXvop_CreateGLXPixmapWithConfigSGIX;
+ ext_req->screen = DefaultScreen(dpy);
+ ext_req->fbconfig = be_FBConfig->id;
+ ext_req->pixmap = (unsigned int)be_pixmap;
+ ext_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s];
+ UnlockDisplay(dpy);
+ SyncHandle();
+ }
+ else if (pGlxVisual) {
+ LockDisplay(dpy);
+ pGlxPixmap->be_xids[s] = XAllocID(dpy);
+ GetReq(GLXCreateGLXPixmap,be_req);
+ be_req->reqType = dmxScreen->glxMajorOpcode;
+ be_req->glxCode = X_GLXCreateGLXPixmap;
+ be_req->screen = DefaultScreen(dpy);
+ be_req->visual = (unsigned int)glxMatchGLXVisualInConfigList(
+ pGlxVisual,
+ dmxScreen->glxVisuals,
+ dmxScreen->numGlxVisuals );
+ be_req->pixmap = (unsigned int)be_pixmap;
+ be_req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s];
+ UnlockDisplay(dpy);
+ SyncHandle();
+ }
+ else {
+ client->errorValue = ( visual ? visual : fbconfigId );
+ __glXFree( pGlxPixmap );
+ return BadValue;
+ }
+
+ XFlush( dpy );
+ }
+
+ if (!(AddResource(glxpixmapId, __glXPixmapRes, pGlxPixmap))) {
+ __glXFree( pGlxPixmap );
+ return BadAlloc;
+ }
+
+ return Success;
+}
+
+int __glXCreateGLXPixmap(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc;
+
+ return( CreateGLXPixmap(cl, req->visual, None,
+ req->screen, req->pixmap, req->glxpixmap) );
+}
+
+int __glXCreatePixmap(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc;
+
+ return( CreateGLXPixmap(cl, None, req->fbconfig,
+ req->screen, req->pixmap, req->glxpixmap) );
+}
+
+int __glXDestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc;
+ XID glxpixmap = req->glxpixmap;
+ __GLXpixmap *pGlxPixmap;
+ int s;
+ int from_screen, to_screen;
+
+ /*
+ ** Check if it's a valid GLX pixmap.
+ */
+ pGlxPixmap = (__GLXpixmap *)LookupIDByType(glxpixmap, __glXPixmapRes);
+ if (!pGlxPixmap) {
+ client->errorValue = glxpixmap;
+ return __glXBadPixmap;
+ }
+ FreeResource(glxpixmap, FALSE);
+
+ /*
+ * destroy the pixmap on the back-end server(s).
+ */
+ from_screen = to_screen = pGlxPixmap->pDraw->pScreen->myNum;
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ from_screen = 0;
+ to_screen = screenInfo.numScreens - 1;
+ }
+#endif
+
+ for (s=from_screen; s<=to_screen; s++) {
+ DMXScreenInfo *dmxScreen = &dmxScreens[s];
+ Display *dpy = GetBackEndDisplay(cl,s);
+
+ /* make sure pixmap exist in back-end */
+ dmxSync( dmxScreen, 1 );
+
+ LockDisplay(dpy);
+ GetReq(GLXDestroyGLXPixmap,req);
+ req->reqType = dmxScreen->glxMajorOpcode;
+ req->glxCode = X_GLXDestroyGLXPixmap;
+ req->glxpixmap = (unsigned int)pGlxPixmap->be_xids[s];
+ UnlockDisplay(dpy);
+ SyncHandle();
+ }
+
+
+ return Success;
+}
+
+/*****************************************************************************/
+
+/*
+** NOTE: There is no portable implementation for swap buffers as of
+** this time that is of value. Consequently, this code must be
+** implemented by somebody other than SGI.
+*/
+int __glXDoSwapBuffers(__GLXclientState *cl, XID drawId, GLXContextTag tag)
+{
+ ClientPtr client = cl->client;
+ DrawablePtr pDraw;
+ xGLXSwapBuffersReq *be_req;
+ WindowPtr pWin = NULL;
+ __GLXpixmap *pGlxPixmap = NULL;
+ __GLXcontext *glxc = NULL;
+#ifdef PANORAMIX
+ PanoramiXRes *pXinDraw = NULL;
+#endif
+ __glXWindow *pGlxWindow = NULL;
+ int from_screen = 0;
+ int to_screen = 0;
+ int s, rc;
+
+ /*
+ ** Check that the GLX drawable is valid.
+ */
+ rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixWriteAccess);
+ if (rc == Success) {
+ from_screen = to_screen = pDraw->pScreen->myNum;
+
+ if (pDraw->type == DRAWABLE_WINDOW) {
+ /*
+ ** Drawable is an X window.
+ */
+ pWin = (WindowPtr)pDraw;
+ } else {
+ /*
+ ** Drawable is an X pixmap, which is not allowed.
+ */
+ client->errorValue = drawId;
+ return __glXBadDrawable;
+ }
+ }
+
+ if (!pDraw) {
+ pGlxPixmap = (__GLXpixmap *) LookupIDByType(drawId,
+ __glXPixmapRes);
+ if (pGlxPixmap) {
+ /*
+ ** Drawable is a GLX pixmap.
+ */
+ pDraw = pGlxPixmap->pDraw;
+ from_screen = to_screen = pGlxPixmap->pScreen->myNum;
+ }
+ }
+
+ if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
+ pGlxWindow = (__glXWindow *) LookupIDByType(drawId, __glXWindowRes);
+ if (pGlxWindow) {
+ /*
+ ** Drawable is a GLXWindow.
+ */
+ pDraw = pGlxWindow->pDraw;
+ from_screen = to_screen = pGlxWindow->pScreen->myNum;
+ }
+ }
+
+ if (!pDraw) {
+ /*
+ ** Drawable is neither a X window nor a GLX pixmap.
+ */
+ client->errorValue = drawId;
+ return __glXBadDrawable;
+ }
+
+ if (tag) {
+ glxc = __glXLookupContextByTag(cl, tag);
+ if (!glxc) {
+ return __glXBadContextTag;
+ }
+ }
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ from_screen = 0;
+ to_screen = screenInfo.numScreens - 1;
+ pXinDraw = (PanoramiXRes *)
+ SecurityLookupIDByClass(client, pDraw->id, XRC_DRAWABLE, DixReadAccess);
+ }
+#endif
+
+ /* If requested, send a glFinish to all back-end servers before swapping. */
+ if (dmxGLXFinishSwap) {
+ for (s=from_screen; s<=to_screen; s++) {
+ Display *dpy = GetBackEndDisplay(cl,s);
+ DMXScreenInfo *dmxScreen = &dmxScreens[s];
+ xGLXSingleReq *finishReq;
+ xGLXSingleReply reply;
+
+#define X_GLXSingle 0 /* needed by GetReq below */
+
+ LockDisplay(dpy);
+ GetReq(GLXSingle,finishReq);
+ finishReq->reqType = dmxScreen->glxMajorOpcode;
+ finishReq->glxCode = X_GLsop_Finish;
+ finishReq->contextTag = (tag ? GetCurrentBackEndTag(cl,tag,s) : 0);
+ (void) _XReply(dpy, (xReply*) &reply, 0, False);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ }
+ }
+
+ /* If requested, send an XSync to all back-end servers before swapping. */
+ if (dmxGLXSyncSwap) {
+ for (s=from_screen; s<=to_screen; s++)
+ XSync(GetBackEndDisplay(cl,s), False);
+ }
+
+
+ /* send the SwapBuffers request to all back-end servers */
+
+ for (s=from_screen; s<=to_screen; s++) {
+ DMXScreenInfo *dmxScreen = &dmxScreens[s];
+ Display *dpy = GetBackEndDisplay(cl,s);
+ unsigned int be_draw = 0;
+
+ if (pGlxPixmap) {
+ be_draw = (unsigned int)pGlxPixmap->be_xids[s];
+ }
+#ifdef PANORAMIX
+ else if (pXinDraw) {
+ dixLookupWindow(&pWin, pXinDraw->info[s].id, client, DixReadAccess);
+ }
+#endif
+ else if (pGlxWindow) {
+ pWin = (WindowPtr)pGlxWindow->pDraw;
+ }
+
+ if (pWin && !be_draw) {
+ be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
+ if (!be_draw) {
+ /* it might be that the window did not created yet on the */
+ /* back-end server (lazy window creation option), force */
+ /* creation of the window */
+ dmxCreateAndRealizeWindow( pWin, TRUE );
+ be_draw = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
+ }
+ }
+
+ dmxSync( dmxScreen, 1 );
+
+ LockDisplay(dpy);
+ GetReq(GLXSwapBuffers,be_req);
+ be_req->reqType = dmxScreen->glxMajorOpcode;
+ be_req->glxCode = X_GLXSwapBuffers;
+ be_req->drawable = be_draw;
+ be_req->contextTag = ( tag ? GetCurrentBackEndTag(cl,tag,s) : 0 );
+ UnlockDisplay(dpy);
+ SyncHandle();
+ XFlush(dpy);
+ }
+
+ return Success;
+}
+
+int __glXSwapBuffers(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ DrawablePtr pDraw;
+ xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc;
+ GLXContextTag tag = req->contextTag;
+ XID drawId = req->drawable;
+ __GLXpixmap *pGlxPixmap = NULL;
+ __GLXcontext *glxc = NULL;
+ __glXWindow *pGlxWindow = NULL;
+ int rc;
+
+ /*
+ ** Check that the GLX drawable is valid.
+ */
+ rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixWriteAccess);
+ if (rc == Success) {
+ if (pDraw->type != DRAWABLE_WINDOW) {
+ /*
+ ** Drawable is an X pixmap, which is not allowed.
+ */
+ client->errorValue = drawId;
+ return __glXBadDrawable;
+ }
+ }
+
+ if (!pDraw) {
+ pGlxPixmap = (__GLXpixmap *) LookupIDByType(drawId,
+ __glXPixmapRes);
+ if (pGlxPixmap) {
+ /*
+ ** Drawable is a GLX pixmap.
+ */
+ pDraw = pGlxPixmap->pDraw;
+ }
+ }
+
+ if (!pDraw && __GLX_IS_VERSION_SUPPORTED(1,3) ) {
+ pGlxWindow = (__glXWindow *) LookupIDByType(drawId, __glXWindowRes);
+ if (pGlxWindow) {
+ /*
+ ** Drawable is a GLXWindow.
+ */
+ pDraw = pGlxWindow->pDraw;
+ }
+ }
+
+ if (!pDraw) {
+ /*
+ ** Drawable is neither a X window nor a GLX pixmap.
+ */
+ client->errorValue = drawId;
+ return __glXBadDrawable;
+ }
+
+ if (tag) {
+ glxc = __glXLookupContextByTag(cl, tag);
+ if (!glxc) {
+ return __glXBadContextTag;
+ }
+ }
+
+ if (pDraw &&
+ pDraw->type == DRAWABLE_WINDOW &&
+ DMX_GET_WINDOW_PRIV((WindowPtr)pDraw)->swapGroup) {
+ return SGSwapBuffers(cl, drawId, tag, pDraw);
+ }
+
+ return __glXDoSwapBuffers(cl, drawId, tag);
+}
+
+
+/************************************************************************/
+
+/*
+** Render and Renderlarge are not in the GLX API. They are used by the GLX
+** client library to send batches of GL rendering commands.
+*/
+
+/*
+** Execute all the drawing commands in a request.
+*/
+int __glXRender(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXRenderReq *req;
+ xGLXRenderReq *be_req;
+ int size;
+ __GLXcontext *glxc;
+ int from_screen = 0;
+ int to_screen = 0;
+ int s;
+
+ /*
+ ** NOTE: much of this code also appears in the byteswapping version of this
+ ** routine, __glXSwapRender(). Any changes made here should also be
+ ** duplicated there.
+ */
+
+ req = (xGLXRenderReq *) pc;
+
+ glxc = __glXLookupContextByTag(cl, req->contextTag);
+ if (!glxc) {
+ return 0;
+ }
+ from_screen = to_screen = glxc->pScreen->myNum;
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ from_screen = 0;
+ to_screen = screenInfo.numScreens - 1;
+ }
+#endif
+
+ pc += sz_xGLXRenderReq;
+ size = (req->length << 2) - sz_xGLXRenderReq;
+
+ /*
+ * just forward the request to back-end server(s)
+ */
+ for (s=from_screen; s<=to_screen; s++) {
+ DMXScreenInfo *dmxScreen = &dmxScreens[s];
+ Display *dpy = GetBackEndDisplay(cl,s);
+
+ LockDisplay(dpy);
+ GetReq(GLXRender,be_req);
+ be_req->reqType = dmxScreen->glxMajorOpcode;
+ be_req->glxCode = X_GLXRender;
+ be_req->length = req->length;
+ be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s);
+ _XSend(dpy, (const char *)pc, size);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ }
+
+ return Success;
+}
+
+/*
+** Execute a large rendering request (one that spans multiple X requests).
+*/
+int __glXRenderLarge(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXRenderLargeReq *req;
+ xGLXRenderLargeReq *be_req;
+ __GLXcontext *glxc;
+ int from_screen = 0;
+ int to_screen = 0;
+ int s;
+
+ /*
+ ** NOTE: much of this code also appears in the byteswapping version of this
+ ** routine, __glXSwapRenderLarge(). Any changes made here should also be
+ ** duplicated there.
+ */
+
+ req = (xGLXRenderLargeReq *) pc;
+ glxc = __glXLookupContextByTag(cl, req->contextTag);
+ if (!glxc) {
+ return 0;
+ }
+ from_screen = to_screen = glxc->pScreen->myNum;
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ from_screen = 0;
+ to_screen = screenInfo.numScreens - 1;
+ }
+#endif
+
+ pc += sz_xGLXRenderLargeReq;
+
+ /*
+ * just forward the request to back-end server(s)
+ */
+ for (s=from_screen; s<=to_screen; s++) {
+ DMXScreenInfo *dmxScreen = &dmxScreens[s];
+ Display *dpy = GetBackEndDisplay(cl,s);
+
+ GetReq(GLXRenderLarge,be_req);
+ be_req->reqType = dmxScreen->glxMajorOpcode;
+ be_req->glxCode = X_GLXRenderLarge;
+ be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s);
+ be_req->length = req->length;
+ be_req->requestNumber = req->requestNumber;
+ be_req->requestTotal = req->requestTotal;
+ be_req->dataBytes = req->dataBytes;
+ Data(dpy, (const char *)pc, req->dataBytes);
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ }
+
+ return Success;
+}
+
+
+/************************************************************************/
+
+int __glXVendorPrivate(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXVendorPrivateReq *req;
+
+ req = (xGLXVendorPrivateReq *) pc;
+
+ switch( req->vendorCode ) {
+
+ case X_GLvop_DeleteTexturesEXT:
+ return __glXVForwardSingleReq( cl, pc );
+ break;
+
+ case X_GLXvop_SwapIntervalSGI:
+ if (glxIsExtensionSupported("SGI_swap_control")) {
+ return __glXVForwardSingleReq( cl, pc );
+ }
+ else {
+ return Success;
+ }
+ break;
+
+#if 0 /* glx 1.3 */
+ case X_GLXvop_CreateGLXVideoSourceSGIX:
+ break;
+ case X_GLXvop_DestroyGLXVideoSourceSGIX:
+ break;
+ case X_GLXvop_CreateGLXPixmapWithConfigSGIX:
+ break;
+ case X_GLXvop_DestroyGLXPbufferSGIX:
+ break;
+ case X_GLXvop_ChangeDrawableAttributesSGIX:
+ break;
+#endif
+
+ case X_GLXvop_BindSwapBarrierSGIX:
+ return __glXBindSwapBarrierSGIX( cl, pc );
+ break;
+
+ case X_GLXvop_JoinSwapGroupSGIX:
+ return __glXJoinSwapGroupSGIX( cl, pc );
+ break;
+
+ case X_GLXvop_CreateContextWithConfigSGIX:
+ return __glXCreateContextWithConfigSGIX( cl, pc );
+ break;
+
+ default:
+ /*
+ ** unsupported private request
+ */
+ cl->client->errorValue = req->vendorCode;
+ return __glXUnsupportedPrivateRequest;
+ }
+
+ cl->client->errorValue = req->vendorCode;
+ return __glXUnsupportedPrivateRequest;
+
+}
+
+int __glXVendorPrivateWithReply(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXVendorPrivateWithReplyReq *req;
+
+ req = (xGLXVendorPrivateWithReplyReq *) pc;
+
+ switch( req->vendorCode ) {
+
+ case X_GLvop_GetConvolutionFilterEXT:
+ case X_GLvop_GetConvolutionParameterfvEXT:
+ case X_GLvop_GetConvolutionParameterivEXT:
+ case X_GLvop_GetSeparableFilterEXT:
+ case X_GLvop_GetHistogramEXT:
+ case X_GLvop_GetHistogramParameterivEXT:
+ case X_GLvop_GetMinmaxEXT:
+ case X_GLvop_GetMinmaxParameterfvEXT:
+ case X_GLvop_GetMinmaxParameterivEXT:
+ case X_GLvop_AreTexturesResidentEXT:
+ case X_GLvop_IsTextureEXT:
+ return( __glXVForwardPipe0WithReply(cl, pc) );
+ break;
+
+ case X_GLvop_GenTexturesEXT:
+ return( __glXVForwardAllWithReply(cl, pc) );
+ break;
+
+
+#if 0 /* glx1.3 */
+ case X_GLvop_GetDetailTexFuncSGIS:
+ case X_GLvop_GetSharpenTexFuncSGIS:
+ case X_GLvop_GetColorTableSGI:
+ case X_GLvop_GetColorTableParameterfvSGI:
+ case X_GLvop_GetColorTableParameterivSGI:
+ case X_GLvop_GetTexFilterFuncSGIS:
+ case X_GLvop_GetInstrumentsSGIX:
+ case X_GLvop_InstrumentsBufferSGIX:
+ case X_GLvop_PollInstrumentsSGIX:
+ case X_GLvop_FlushRasterSGIX:
+ case X_GLXvop_CreateGLXPbufferSGIX:
+ case X_GLXvop_GetDrawableAttributesSGIX:
+ case X_GLXvop_QueryHyperpipeNetworkSGIX:
+ case X_GLXvop_QueryHyperpipeConfigSGIX:
+ case X_GLXvop_HyperpipeConfigSGIX:
+ case X_GLXvop_DestroyHyperpipeConfigSGIX:
+#endif
+ case X_GLXvop_QueryMaxSwapBarriersSGIX:
+ return( __glXQueryMaxSwapBarriersSGIX(cl, pc) );
+ break;
+
+ case X_GLXvop_GetFBConfigsSGIX:
+ return( __glXGetFBConfigsSGIX(cl, pc) );
+ break;
+
+ case X_GLXvop_MakeCurrentReadSGI:
+ return( __glXMakeCurrentReadSGI(cl, pc) );
+ break;
+
+ case X_GLXvop_QueryContextInfoEXT:
+ return( __glXQueryContextInfoEXT(cl,pc) );
+ break;
+
+ default:
+ /*
+ ** unsupported private request
+ */
+ cl->client->errorValue = req->vendorCode;
+ return __glXUnsupportedPrivateRequest;
+ }
+
+}
+
+int __glXQueryExtensionsString(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *) pc;
+ xGLXQueryExtensionsStringReply reply;
+ GLint screen;
+ size_t length;
+ int len, numbytes;
+ char *be_buf;
+
+#ifdef FWD_QUERY_REQ
+ xGLXQueryExtensionsStringReq *be_req;
+ xGLXQueryExtensionsStringReply be_reply;
+ DMXScreenInfo *dmxScreen;
+ Display *dpy;
+ int slop;
+#endif
+
+ screen = req->screen;
+
+ /*
+ ** Check if screen exists.
+ */
+ if ((screen < 0) || (screen >= screenInfo.numScreens)) {
+ client->errorValue = screen;
+ return BadValue;
+ }
+
+#ifdef FWD_QUERY_REQ
+ dmxScreen = &dmxScreens[screen];
+
+ /* Send the glXQueryServerString request */
+ dpy = GetBackEndDisplay(cl,screen);
+ LockDisplay(dpy);
+ GetReq(GLXQueryExtensionsString,be_req);
+ be_req->reqType = dmxScreen->glxMajorOpcode;
+ be_req->glxCode = X_GLXQueryServerString;
+ be_req->screen = DefaultScreen(dpy);
+ _XReply(dpy, (xReply*) &be_reply, 0, False);
+ len = (int)be_reply.length;
+ numbytes = (int)be_reply.n;
+ slop = numbytes * __GLX_SIZE_INT8 & 3;
+ be_buf = (char *)malloc(numbytes);
+ if (!be_buf) {
+ /* Throw data on the floor */
+ _XEatData(dpy, len);
+ } else {
+ _XRead(dpy, (char *)be_buf, numbytes);
+ if (slop) _XEatData(dpy,4-slop);
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+#else
+
+ be_buf = __glXGetServerString(GLX_EXTENSIONS);
+ numbytes = strlen(be_buf) + 1;
+ len = __GLX_PAD(numbytes) >> 2;
+
+#endif
+
+ length = len;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.length = len;
+ reply.n = numbytes;
+
+ if (client->swapped) {
+ glxSwapQueryExtensionsStringReply(client, &reply, be_buf);
+ } else {
+ WriteToClient(client, sz_xGLXQueryExtensionsStringReply,(char *)&reply);
+ WriteToClient(client, (int)(length << 2), (char *)be_buf);
+ }
+
+ return Success;
+}
+
+int __glXQueryServerString(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) pc;
+ xGLXQueryServerStringReply reply;
+ int name;
+ GLint screen;
+ size_t length;
+ int len, numbytes;
+ char *be_buf;
+#ifdef FWD_QUERY_REQ
+ xGLXQueryServerStringReq *be_req;
+ xGLXQueryServerStringReply be_reply;
+ DMXScreenInfo *dmxScreen;
+ Display *dpy;
+ int slop;
+#endif
+
+ name = req->name;
+ screen = req->screen;
+ /*
+ ** Check if screen exists.
+ */
+ if ((screen < 0) || (screen >= screenInfo.numScreens)) {
+ client->errorValue = screen;
+ return BadValue;
+ }
+
+#ifdef FWD_QUERY_REQ
+ dmxScreen = &dmxScreens[screen];
+
+ /* Send the glXQueryServerString request */
+ dpy = GetBackEndDisplay(cl,screen);
+ LockDisplay(dpy);
+ GetReq(GLXQueryServerString,be_req);
+ be_req->reqType = dmxScreen->glxMajorOpcode;
+ be_req->glxCode = X_GLXQueryServerString;
+ be_req->screen = DefaultScreen(dpy);
+ be_req->name = name;
+ _XReply(dpy, (xReply*) &be_reply, 0, False);
+ len = (int)be_reply.length;
+ numbytes = (int)be_reply.n;
+ slop = numbytes * __GLX_SIZE_INT8 & 3;
+ be_buf = (char *)malloc(numbytes);
+ if (!be_buf) {
+ /* Throw data on the floor */
+ _XEatData(dpy, len);
+ } else {
+ _XRead(dpy, (char *)be_buf, numbytes);
+ if (slop) _XEatData(dpy,4-slop);
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+#else
+ be_buf = __glXGetServerString(name);
+ numbytes = strlen(be_buf) + 1;
+ len = __GLX_PAD(numbytes) >> 2;
+#endif
+
+ length = len;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.length = length;
+ reply.n = numbytes;
+
+ if (client->swapped) {
+ glxSwapQueryServerStringReply(client, &reply, be_buf);
+ } else {
+ WriteToClient(client, sz_xGLXQueryServerStringReply, (char *)&reply);
+ WriteToClient(client, (int)(length << 2), be_buf);
+ }
+
+ return Success;
+}
+
+int __glXClientInfo(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXClientInfoReq *req = (xGLXClientInfoReq *) pc;
+ xGLXClientInfoReq *be_req;
+ const char *buf;
+ int from_screen = 0;
+ int to_screen = 0;
+ int s;
+
+ cl->GLClientmajorVersion = req->major;
+ cl->GLClientminorVersion = req->minor;
+ if (cl->GLClientextensions) __glXFree(cl->GLClientextensions);
+ buf = (const char *)(req+1);
+ cl->GLClientextensions = strdup(buf);
+
+ to_screen = screenInfo.numScreens - 1;
+
+ for (s=from_screen; s<=to_screen; s++)
+ {
+ DMXScreenInfo *dmxScreen = &dmxScreens[s];
+ Display *dpy = GetBackEndDisplay(cl,s);
+
+ LockDisplay(dpy);
+ GetReq(GLXClientInfo,be_req);
+ be_req->reqType = dmxScreen->glxMajorOpcode;
+ be_req->glxCode = X_GLXClientInfo;
+ be_req->major = req->major;
+ be_req->minor = req->minor;
+ be_req->length = req->length;
+ be_req->numbytes = req->numbytes;
+ Data(dpy, buf, req->numbytes);
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+ }
+
+ return Success;
+}
+
+int __glXUseXFont(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXUseXFontReq *req;
+ xGLXUseXFontReq *be_req;
+ FontPtr pFont;
+ __GLXcontext *glxc = NULL;
+ int from_screen = 0;
+ int to_screen = 0;
+ int s;
+ dmxFontPrivPtr pFontPriv;
+ DMXScreenInfo *dmxScreen;
+ Display *dpy;
+
+ req = (xGLXUseXFontReq *) pc;
+
+ if (req->contextTag != 0) {
+ glxc = __glXLookupContextByTag(cl, req->contextTag);
+ if (glxc) {
+ from_screen = to_screen = glxc->pScreen->myNum;
+ }
+ }
+
+ /*
+ ** Font can actually be either the ID of a font or the ID of a GC
+ ** containing a font.
+ */
+ pFont = (FontPtr)LookupIDByType(req->font, RT_FONT);
+ if (!pFont) {
+ GC *pGC = (GC *)LookupIDByType(req->font, RT_GC);
+ if (!pGC) {
+ client->errorValue = req->font;
+ return BadFont;
+ }
+ pFont = pGC->font;
+ }
+
+ pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex);
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ from_screen = 0;
+ to_screen = screenInfo.numScreens - 1;
+ }
+#endif
+
+
+ for (s=from_screen; s<=to_screen; s++) {
+ dmxScreen = &dmxScreens[s];
+ dpy = GetBackEndDisplay(cl,s);
+
+ dmxSync( dmxScreen, 1 );
+
+ LockDisplay(dpy);
+ GetReq(GLXUseXFont,be_req);
+ be_req->reqType = dmxScreen->glxMajorOpcode;
+ be_req->glxCode = X_GLXUseXFont;
+ be_req->contextTag = (glxc ? GetCurrentBackEndTag(cl,req->contextTag,s) : 0);
+ be_req->font = pFontPriv->font[s]->fid;
+ be_req->first = req->first;
+ be_req->count = req->count;
+ be_req->listBase = req->listBase;
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ XSync( dpy, False );
+ }
+
+ return Success;
+}
+
+/*
+ * start GLX 1.3 here
+ */
+
+int __glXGetFBConfigs(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc;
+ xGLXGetFBConfigsReply reply;
+ __GLXFBConfig *pFBConfig;
+ CARD32 buf[2 * __GLX_TOTAL_FBCONFIG_PROPS];
+ int numAttribs = __GLX_TOTAL_FBCONFIG_PROPS;
+ unsigned int screen = req->screen;
+ int numFBConfigs, i, p;
+ __GLXscreenInfo *pGlxScreen;
+
+ if (screen > screenInfo.numScreens) {
+ /* The client library must send a valid screen number. */
+ client->errorValue = screen;
+ return BadValue;
+ }
+
+ pGlxScreen = &__glXActiveScreens[screen];
+ numFBConfigs = __glXNumFBConfigs;
+
+ reply.numFBConfigs = numFBConfigs;
+ reply.numAttribs = numAttribs;
+ reply.length = (numFBConfigs * 2 * numAttribs * __GLX_SIZE_CARD32) >> 2;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+
+ if (client->swapped) {
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_SWAP_SHORT(&reply.sequenceNumber);
+ __GLX_SWAP_INT(&reply.length);
+ __GLX_SWAP_INT(&reply.numFBConfigs);
+ __GLX_SWAP_INT(&reply.numAttribs);
+ }
+ WriteToClient(client, sz_xGLXGetFBConfigsReply, (char *)&reply);
+
+ for (i=0; i < numFBConfigs; i++) {
+ int associatedVisualId = 0;
+ int drawableTypeIndex;
+ pFBConfig = __glXFBConfigs[ i * (screenInfo.numScreens+1) ];
+
+ p = 0;
+ /* core attributes */
+ buf[p++] = GLX_FBCONFIG_ID;
+ buf[p++] = pFBConfig->id;
+ buf[p++] = GLX_BUFFER_SIZE;
+ buf[p++] = pFBConfig->indexBits;
+ buf[p++] = GLX_LEVEL;
+ buf[p++] = pFBConfig->level;
+ buf[p++] = GLX_DOUBLEBUFFER;
+ buf[p++] = pFBConfig->doubleBufferMode;
+ buf[p++] = GLX_STEREO;
+ buf[p++] = pFBConfig->stereoMode;
+ buf[p++] = GLX_AUX_BUFFERS;
+ buf[p++] = pFBConfig->maxAuxBuffers;
+ buf[p++] = GLX_RED_SIZE;
+ buf[p++] = pFBConfig->redBits;
+ buf[p++] = GLX_GREEN_SIZE;
+ buf[p++] = pFBConfig->greenBits;
+ buf[p++] = GLX_BLUE_SIZE;
+ buf[p++] = pFBConfig->blueBits;
+ buf[p++] = GLX_ALPHA_SIZE;
+ buf[p++] = pFBConfig->alphaBits;
+ buf[p++] = GLX_DEPTH_SIZE;
+ buf[p++] = pFBConfig->depthBits;
+ buf[p++] = GLX_STENCIL_SIZE;
+ buf[p++] = pFBConfig->stencilBits;
+ buf[p++] = GLX_ACCUM_RED_SIZE;
+ buf[p++] = pFBConfig->accumRedBits;
+ buf[p++] = GLX_ACCUM_GREEN_SIZE;
+ buf[p++] = pFBConfig->accumGreenBits;
+ buf[p++] = GLX_ACCUM_BLUE_SIZE;
+ buf[p++] = pFBConfig->accumBlueBits;
+ buf[p++] = GLX_ACCUM_ALPHA_SIZE;
+ buf[p++] = pFBConfig->accumAlphaBits;
+ buf[p++] = GLX_RENDER_TYPE;
+ buf[p++] = pFBConfig->renderType;
+ buf[p++] = GLX_DRAWABLE_TYPE;
+ drawableTypeIndex = p;
+ buf[p++] = pFBConfig->drawableType;
+ buf[p++] = GLX_X_VISUAL_TYPE;
+ buf[p++] = pFBConfig->visualType;
+ buf[p++] = GLX_CONFIG_CAVEAT;
+ buf[p++] = pFBConfig->visualCaveat;
+ buf[p++] = GLX_TRANSPARENT_TYPE;
+ buf[p++] = pFBConfig->transparentType;
+ buf[p++] = GLX_TRANSPARENT_RED_VALUE;
+ buf[p++] = pFBConfig->transparentRed;
+ buf[p++] = GLX_TRANSPARENT_GREEN_VALUE;
+ buf[p++] = pFBConfig->transparentGreen;
+ buf[p++] = GLX_TRANSPARENT_BLUE_VALUE;
+ buf[p++] = pFBConfig->transparentBlue;
+ buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE;
+ buf[p++] = pFBConfig->transparentAlpha;
+ buf[p++] = GLX_TRANSPARENT_INDEX_VALUE;
+ buf[p++] = pFBConfig->transparentIndex;
+ buf[p++] = GLX_MAX_PBUFFER_WIDTH;
+ buf[p++] = pFBConfig->maxPbufferWidth;
+ buf[p++] = GLX_MAX_PBUFFER_HEIGHT;
+ buf[p++] = pFBConfig->maxPbufferHeight;
+ buf[p++] = GLX_MAX_PBUFFER_PIXELS;
+ buf[p++] = pFBConfig->maxPbufferPixels;
+
+ /*
+ * find the visual of the back-end server and match a visual
+ * on the proxy.
+ * do only once - if a visual is not yet associated.
+ */
+ if (pFBConfig->associatedVisualId == (unsigned int)-1) {
+ DMXScreenInfo *dmxScreen = &dmxScreens[screen];
+ __GLXFBConfig *be_pFBConfig = __glXFBConfigs[ i * (screenInfo.numScreens+1)+screen+1 ];
+ __GLXvisualConfig *pGlxVisual = NULL;
+ int v;
+ int found = 0;
+ for (v=0; v<dmxScreen->numGlxVisuals; v++) {
+ if (dmxScreen->glxVisuals[v].vid == be_pFBConfig->associatedVisualId) {
+ pGlxVisual = &dmxScreen->glxVisuals[v];
+ break;
+ }
+ }
+
+ if (pGlxVisual) {
+ for (v=0; v<pGlxScreen->numVisuals; v++) {
+ if (glxVisualsMatch(&pGlxScreen->pGlxVisual[v], pGlxVisual)) {
+ associatedVisualId = pGlxScreen->pGlxVisual[v].vid;
+ found = 1;
+ break;
+ }
+ }
+ }
+
+ if (!found) {
+ associatedVisualId = 0;
+ pFBConfig->drawableType &= ~(GLX_WINDOW_BIT);
+ buf[drawableTypeIndex] = pFBConfig->drawableType;
+ }
+#ifdef PANORAMIX
+ else if (!noPanoramiXExtension) {
+ /* convert the associated visualId to the panoramix one */
+ pFBConfig->associatedVisualId =
+ PanoramiXTranslateVisualID(screen, v);
+ }
+#endif
+ }
+ else {
+ associatedVisualId = pFBConfig->associatedVisualId;
+ }
+
+ buf[p++] = GLX_VISUAL_ID;
+ buf[p++] = associatedVisualId;
+
+ /* SGIS_multisample attributes */
+ buf[p++] = GLX_SAMPLES_SGIS;
+ buf[p++] = pFBConfig->multiSampleSize;
+ buf[p++] = GLX_SAMPLE_BUFFERS_SGIS;
+ buf[p++] = pFBConfig->nMultiSampleBuffers;
+
+ /* SGIX_pbuffer specific attributes */
+ buf[p++] = GLX_OPTIMAL_PBUFFER_WIDTH_SGIX;
+ buf[p++] = pFBConfig->optimalPbufferWidth;
+ buf[p++] = GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX;
+ buf[p++] = pFBConfig->optimalPbufferHeight;
+
+ buf[p++] = GLX_VISUAL_SELECT_GROUP_SGIX;
+ buf[p++] = pFBConfig->visualSelectGroup;
+
+ if (client->swapped) {
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_SWAP_INT_ARRAY((int *)buf, 2*numAttribs);
+ }
+ WriteToClient(client, 2*numAttribs * __GLX_SIZE_CARD32, (char *)buf);
+ }
+ return Success;
+}
+
+int __glXGetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *)pc;
+ xGLXGetFBConfigsReq new_req;
+
+ new_req.reqType = req->reqType;
+ new_req.glxCode = req->glxCode;
+ new_req.length = req->length;
+ new_req.screen = req->screen;
+
+ return( __glXGetFBConfigs( cl, (GLbyte *)&new_req ) );
+}
+
+
+int __glXCreateWindow(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc;
+ int screen = req->screen;
+ GLXFBConfigID fbconfigId = req->fbconfig;
+ XID windowId = req->window;
+ XID glxwindowId = req->glxwindow;
+ DrawablePtr pDraw;
+ ScreenPtr pScreen;
+ __glXWindow *pGlxWindow;
+ __GLXFBConfig *pGlxFBConfig = NULL;
+ VisualPtr pVisual;
+ VisualID visId;
+ int i, rc;
+
+ /*
+ ** Check if windowId is valid
+ */
+ rc = dixLookupDrawable(&pDraw, windowId, client, M_DRAWABLE_WINDOW,
+ DixAddAccess);
+ if (rc != Success)
+ return rc;
+
+ /*
+ ** Check if screen of window matches screen of fbconfig.
+ */
+ pScreen = pDraw->pScreen;
+ if (screen != pScreen->myNum) {
+ return BadMatch;
+ }
+
+ /*
+ ** Find the FBConfigRec for this fbconfigid.
+ */
+ if (!(pGlxFBConfig = glxLookupFBConfig(fbconfigId))) {
+ client->errorValue = fbconfigId;
+ return __glXBadFBConfig;
+ }
+ visId = pGlxFBConfig->associatedVisualId;
+
+ /*
+ ** Check if the fbconfig supports rendering to windows
+ */
+ if( !(pGlxFBConfig->drawableType & GLX_WINDOW_BIT) ) {
+ return BadMatch;
+ }
+
+ if (visId != None) {
+ /*
+ ** Check if the visual ID is valid for this screen.
+ */
+ pVisual = pScreen->visuals;
+ for (i = 0; i < pScreen->numVisuals; i++, pVisual++) {
+ if (pVisual->vid == visId) {
+ break;
+ }
+ }
+ if (i == pScreen->numVisuals) {
+ client->errorValue = visId;
+ return BadValue;
+ }
+
+ /*
+ ** Check if color buffer depth of fbconfig matches depth
+ ** of window.
+ */
+ if (pVisual->nplanes != pDraw->depth) {
+ return BadMatch;
+ }
+ } else
+ /*
+ ** The window was created with no visual that corresponds
+ ** to fbconfig
+ */
+ return BadMatch;
+
+ /*
+ ** Check if there is already a fbconfig associated with this window
+ */
+ if ( LookupIDByType(glxwindowId, __glXWindowRes) ) {
+ client->errorValue = glxwindowId;
+ return BadAlloc;
+ }
+
+ pGlxWindow = (__glXWindow *) malloc(sizeof(__glXWindow));
+ if (!pGlxWindow) {
+ return BadAlloc;
+ }
+
+ /*
+ ** Register this GLX window as a resource
+ */
+ if (!(AddResource(glxwindowId, __glXWindowRes, pGlxWindow))) {
+ return BadAlloc;
+ }
+
+ pGlxWindow->pDraw = pDraw;
+ pGlxWindow->type = GLX_GLXWINDOW_TYPE;
+ pGlxWindow->idExists = True;
+ pGlxWindow->refcnt = 0;
+ pGlxWindow->pGlxFBConfig = pGlxFBConfig;
+ pGlxWindow->pScreen = pScreen;
+
+ return Success;
+}
+
+int __glXDestroyWindow(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc;
+ XID glxwindow = req->glxwindow;
+
+ /*
+ ** Check if it's a valid GLX window.
+ */
+ if (!LookupIDByType(glxwindow, __glXWindowRes)) {
+ client->errorValue = glxwindow;
+ return __glXBadDrawable;
+ }
+ /*
+ ** The glx window destructor will check whether it's current before
+ ** freeing anything.
+ */
+ FreeResource(glxwindow, RT_NONE);
+
+ return Success;
+}
+
+int __glXQueryContext(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ __GLXcontext *ctx;
+ xGLXQueryContextReq *req;
+ xGLXQueryContextReply reply;
+ int nProps;
+ int *sendBuf, *pSendBuf;
+ int nReplyBytes;
+
+ req = (xGLXQueryContextReq *)pc;
+ ctx = (__GLXcontext *) LookupIDByType(req->context, __glXContextRes);
+ if (!ctx) {
+ client->errorValue = req->context;
+ return __glXBadContext;
+ }
+
+ nProps = 3;
+
+ reply.length = nProps << 1;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.n = nProps;
+
+ nReplyBytes = reply.length << 2;
+ sendBuf = (int *)malloc(nReplyBytes);
+ pSendBuf = sendBuf;
+ *pSendBuf++ = GLX_FBCONFIG_ID;
+ *pSendBuf++ = (int)(ctx->pFBConfig->id);
+ *pSendBuf++ = GLX_RENDER_TYPE;
+ *pSendBuf++ = (int)(ctx->pFBConfig->renderType);
+ *pSendBuf++ = GLX_SCREEN;
+ *pSendBuf++ = (int)(ctx->pScreen->myNum);
+
+ if (client->swapped) {
+ __glXSwapQueryContextReply(client, &reply, sendBuf);
+ } else {
+ WriteToClient(client, sz_xGLXQueryContextReply, (char *)&reply);
+ WriteToClient(client, nReplyBytes, (char *)sendBuf);
+ }
+ free((char *)sendBuf);
+
+ return Success;
+}
+
+int __glXQueryContextInfoEXT(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ __GLXcontext *ctx;
+ xGLXQueryContextInfoEXTReq *req;
+ xGLXQueryContextInfoEXTReply reply;
+ int nProps;
+ int *sendBuf, *pSendBuf;
+ int nReplyBytes;
+
+ req = (xGLXQueryContextInfoEXTReq *)pc;
+ ctx = (__GLXcontext *) SecurityLookupIDByType(client, req->context, __glXContextRes, DixReadAccess);
+ if (!ctx) {
+ client->errorValue = req->context;
+ return __glXBadContext;
+ }
+
+ nProps = 4;
+
+ reply.length = nProps << 1;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.n = nProps;
+
+ nReplyBytes = reply.length << 2;
+ sendBuf = (int *)malloc(nReplyBytes);
+ pSendBuf = sendBuf;
+ *pSendBuf++ = GLX_SHARE_CONTEXT_EXT;
+ *pSendBuf++ = (int)(ctx->share_id);
+ *pSendBuf++ = GLX_VISUAL_ID_EXT;
+ *pSendBuf++ = (int)(ctx->pVisual ? ctx->pVisual->vid : 0);
+ *pSendBuf++ = GLX_SCREEN_EXT;
+ *pSendBuf++ = (int)(ctx->pScreen->myNum);
+ *pSendBuf++ = GLX_FBCONFIG_ID;
+ *pSendBuf++ = (int)(ctx->pFBConfig ? ctx->pFBConfig->id : 0);
+
+ if (client->swapped) {
+ __glXSwapQueryContextInfoEXTReply(client, &reply, sendBuf);
+ } else {
+ WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, (char *)&reply);
+ WriteToClient(client, nReplyBytes, (char *)sendBuf);
+ }
+ free((char *)sendBuf);
+
+ return Success;
+}
+
+int __glXCreatePbuffer(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *)pc;
+ xGLXCreatePbufferReq *be_req;
+ int screen = req->screen;
+ GLXFBConfigID fbconfigId = req->fbconfig;
+ GLXPbuffer pbuffer = req->pbuffer;
+ __glXPbuffer *pGlxPbuffer;
+ int numAttribs = req->numAttribs;
+ int *attr;
+ ScreenPtr pScreen;
+ __GLXFBConfig *pGlxFBConfig;
+ __GLXFBConfig *be_pGlxFBConfig;
+ XID be_xid;
+ Display *dpy;
+ DMXScreenInfo *dmxScreen;
+ int s;
+ int from_screen, to_screen;
+
+ /*
+ ** Look up screen and FBConfig.
+ */
+ if (screen > screenInfo.numScreens) {
+ /* The client library must send a valid screen number. */
+ client->errorValue = screen;
+ return BadValue;
+ }
+ pScreen = screenInfo.screens[screen];
+
+ /*
+ ** Find the FBConfigRec for this fbconfigid.
+ */
+ if (!(pGlxFBConfig = glxLookupFBConfig(fbconfigId))) {
+ client->errorValue = fbconfigId;
+ return __glXBadFBConfig;
+ }
+
+ /*
+ ** Create the GLX part of the Pbuffer.
+ */
+ pGlxPbuffer = (__glXPbuffer *) malloc(sizeof(__glXPbuffer));
+ if (!pGlxPbuffer) {
+ return BadAlloc;
+ }
+
+ pGlxPbuffer->be_xids = (XID *) malloc( sizeof(XID) * screenInfo.numScreens );
+ if (!pGlxPbuffer->be_xids) {
+ free(pGlxPbuffer);
+ return BadAlloc;
+ }
+
+ /*
+ * Allocate an XID on the back-end server(s) and send him the request
+ */
+ from_screen = to_screen = screen;
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ from_screen = 0;
+ to_screen = screenInfo.numScreens - 1;
+ }
+#endif
+
+ for (s=from_screen; s<=to_screen; s++) {
+ dpy = GetBackEndDisplay(cl,s);
+ be_xid = XAllocID(dpy);
+ dmxScreen = &dmxScreens[s];
+ be_pGlxFBConfig = glxLookupBackEndFBConfig( pGlxFBConfig->id, s );
+
+ attr = (int *)( req+1 );
+
+ LockDisplay(dpy);
+ GetReqExtra(GLXCreatePbuffer, 2 * numAttribs * __GLX_SIZE_CARD32, be_req);
+ be_req->reqType = dmxScreen->glxMajorOpcode;
+ be_req->glxCode = X_GLXCreatePbuffer;
+ be_req->screen = be_pGlxFBConfig->screen;
+ be_req->fbconfig = be_pGlxFBConfig->id;
+ be_req->pbuffer = be_xid;
+ be_req->numAttribs = numAttribs;
+
+ /* Send attributes */
+ if ( attr != NULL ) {
+ CARD32 *pc = (CARD32 *)(be_req + 1);
+
+ while (numAttribs-- > 0) {
+ *pc++ = *attr++; /* token */
+ *pc++ = *attr++; /* value */
+ }
+ }
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ pGlxPbuffer->be_xids[s] = be_xid;
+ }
+
+
+ pGlxPbuffer->idExists = True;
+ pGlxPbuffer->refcnt = 0;
+ pGlxPbuffer->pFBConfig = pGlxFBConfig;
+ pGlxPbuffer->pScreen = pScreen;
+
+ /*
+ ** Register the resource.
+ */
+ if (!(AddResource(pbuffer, __glXPbufferRes, pGlxPbuffer))) {
+ return BadAlloc;
+ }
+
+ return Success;
+
+}
+
+int __glXDestroyPbuffer(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc;
+ xGLXDestroyPbufferReq *be_req;
+ GLXPbuffer pbuffer = req->pbuffer;
+ Display *dpy;
+ int screen;
+ DMXScreenInfo *dmxScreen;
+ __glXPbuffer *pGlxPbuffer;
+ int s;
+ int from_screen, to_screen;
+
+ /*
+ ** Check if it's a valid Pbuffer
+ */
+ pGlxPbuffer = (__glXPbuffer *)LookupIDByType(pbuffer, __glXPbufferRes);
+ if (!pGlxPbuffer) {
+ client->errorValue = pbuffer;
+ return __glXBadPbuffer;
+ }
+
+ screen = pGlxPbuffer->pScreen->myNum;
+
+ from_screen = to_screen = screen;
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ from_screen = 0;
+ to_screen = screenInfo.numScreens - 1;
+ }
+#endif
+
+ for (s=from_screen; s<=to_screen; s++) {
+ dpy = GetBackEndDisplay(cl,s);
+ dmxScreen = &dmxScreens[s];
+
+ /* send the destroy request to the back-end server */
+ LockDisplay(dpy);
+ GetReq(GLXDestroyPbuffer, be_req);
+ be_req->reqType = dmxScreen->glxMajorOpcode;
+ be_req->glxCode = X_GLXDestroyPbuffer;
+ be_req->pbuffer = pGlxPbuffer->be_xids[s];
+ UnlockDisplay(dpy);
+ SyncHandle();
+ }
+
+ FreeResource(pbuffer, RT_NONE);
+
+ return Success;
+}
+
+int __glXGetDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *)pc;
+ xGLXGetDrawableAttributesReq *be_req;
+ xGLXGetDrawableAttributesReply reply;
+ ClientPtr client = cl->client;
+ GLXDrawable drawId = req->drawable;
+ GLXDrawable be_drawable = 0;
+ DrawablePtr pDraw = NULL;
+ Display *dpy;
+ int screen, rc;
+ DMXScreenInfo *dmxScreen;
+ CARD32 *attribs = NULL;
+ int attribs_size;
+#ifdef PANORAMIX
+ PanoramiXRes *pXinDraw = NULL;
+#endif
+
+ if (drawId != None) {
+ rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixGetAttrAccess);
+ if (rc == Success) {
+ if (pDraw->type == DRAWABLE_WINDOW) {
+ WindowPtr pWin = (WindowPtr)pDraw;
+ be_drawable = 0;
+ screen = pWin->drawable.pScreen->myNum;
+
+ }
+ else {
+ /*
+ ** Drawable is not a Window , GLXWindow or a GLXPixmap.
+ */
+ client->errorValue = drawId;
+ return __glXBadDrawable;
+ }
+ }
+
+ if (!pDraw) {
+ __GLXpixmap *pGlxPixmap = (__GLXpixmap *) LookupIDByType(drawId,
+ __glXPixmapRes);
+ if (pGlxPixmap) {
+ pDraw = pGlxPixmap->pDraw;
+ screen = pGlxPixmap->pScreen->myNum;
+ be_drawable = pGlxPixmap->be_xids[screen];
+ }
+ }
+
+ if (!pDraw) {
+ __glXWindow *pGlxWindow = (__glXWindow *) LookupIDByType(drawId, __glXWindowRes);
+ if (pGlxWindow) {
+ pDraw = pGlxWindow->pDraw;
+ screen = pGlxWindow->pScreen->myNum;
+ be_drawable = 0;
+ }
+ }
+
+ if (!pDraw) {
+ __glXPbuffer *pGlxPbuffer = (__glXPbuffer *)LookupIDByType(drawId, __glXPbufferRes);
+ if (pGlxPbuffer) {
+ pDraw = (DrawablePtr)pGlxPbuffer;
+ screen = pGlxPbuffer->pScreen->myNum;
+ be_drawable = pGlxPbuffer->be_xids[screen];
+ }
+ }
+
+
+ if (!pDraw) {
+ /*
+ ** Drawable is not a Window , GLXWindow or a GLXPixmap.
+ */
+ client->errorValue = drawId;
+ return __glXBadDrawable;
+ }
+ }
+
+
+ /* if the drawable is a window or GLXWindow -
+ * we need to find the base id on the back-end server
+ */
+ if (!be_drawable) {
+ WindowPtr pWin = (WindowPtr)pDraw;
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ pXinDraw = (PanoramiXRes *)
+ SecurityLookupIDByClass(client, pDraw->id, XRC_DRAWABLE, DixReadAccess);
+ if (!pXinDraw) {
+ client->errorValue = drawId;
+ return __glXBadDrawable;
+ }
+
+ dixLookupWindow(&pWin, pXinDraw->info[screen].id, client,
+ DixReadAccess);
+ }
+#endif
+
+ if (pWin) {
+ be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
+ if (!be_drawable) {
+ /* it might be that the window did not created yet on the */
+ /* back-end server (lazy window creation option), force */
+ /* creation of the window */
+ dmxCreateAndRealizeWindow( pWin, TRUE );
+ be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
+ }
+ }
+ else {
+ client->errorValue = drawId;
+ return __glXBadDrawable;
+ }
+ }
+
+
+ /* send the request to the back-end server */
+ dpy = GetBackEndDisplay(cl,screen);
+ dmxScreen = &dmxScreens[screen];
+
+ /* make sure drawable exists on back-end */
+ dmxSync( dmxScreen, 1 );
+
+ LockDisplay(dpy);
+ GetReq(GLXGetDrawableAttributes, be_req);
+ be_req->reqType = dmxScreen->glxMajorOpcode;
+ be_req->glxCode = X_GLXGetDrawableAttributes;
+ be_req->drawable = be_drawable;
+ be_req->length = req->length;
+ if (!_XReply(dpy, (xReply *) &reply, 0, False)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return( BE_TO_CLIENT_ERROR(dmxLastErrorEvent.error_code) );
+ }
+
+ if (reply.numAttribs) {
+ attribs_size = 2 * reply.numAttribs * __GLX_SIZE_CARD32;
+ attribs = (CARD32 *) malloc(attribs_size);
+ if (attribs == NULL) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return BadAlloc;
+ }
+
+ _XRead(dpy, (char *) attribs, attribs_size);
+ }
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+
+ /* send the reply back to the client */
+ reply.sequenceNumber = client->sequence;
+ if (client->swapped) {
+ __glXSwapGetDrawableAttributesReply(client, &reply, (int *)attribs);
+ }
+ else {
+ WriteToClient(client, sz_xGLXGetDrawableAttributesReply, (char *)&reply);
+ WriteToClient(client, attribs_size, (char *)attribs);
+ }
+
+ Xfree(attribs);
+
+ return Success;
+}
+
+int __glXChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXChangeDrawableAttributesReq *req = (xGLXChangeDrawableAttributesReq *)pc;
+ xGLXChangeDrawableAttributesReq *be_req;
+ ClientPtr client = cl->client;
+ GLXDrawable drawId = req->drawable;
+ GLXDrawable be_drawable = 0;
+ DrawablePtr pDraw = NULL;
+ Display *dpy;
+ int screen, rc;
+ DMXScreenInfo *dmxScreen;
+ char *attrbuf;
+#ifdef PANORAMIX
+ PanoramiXRes *pXinDraw = NULL;
+ PanoramiXRes *pXinReadDraw = NULL;
+#endif
+
+ if (drawId != None) {
+ rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixSetAttrAccess);
+ if (rc == Success) {
+ if (pDraw->type == DRAWABLE_WINDOW) {
+ WindowPtr pWin = (WindowPtr)pDraw;
+ be_drawable = 0;
+ screen = pWin->drawable.pScreen->myNum;
+
+ }
+ else {
+ /*
+ ** Drawable is not a Window , GLXWindow or a GLXPixmap.
+ */
+ client->errorValue = drawId;
+ return __glXBadDrawable;
+ }
+ }
+
+ if (!pDraw) {
+ __GLXpixmap *pGlxPixmap = (__GLXpixmap *) LookupIDByType(drawId,
+ __glXPixmapRes);
+ if (pGlxPixmap) {
+ pDraw = pGlxPixmap->pDraw;
+ screen = pGlxPixmap->pScreen->myNum;
+ be_drawable = pGlxPixmap->be_xids[screen];
+ }
+ }
+
+ if (!pDraw) {
+ __glXWindow *pGlxWindow = (__glXWindow *) LookupIDByType(drawId, __glXWindowRes);
+ if (pGlxWindow) {
+ pDraw = pGlxWindow->pDraw;
+ screen = pGlxWindow->pScreen->myNum;
+ be_drawable = 0;
+ }
+ }
+
+ if (!pDraw) {
+ __glXPbuffer *pGlxPbuffer = (__glXPbuffer *)LookupIDByType(drawId, __glXPbufferRes);
+ if (pGlxPbuffer) {
+ pDraw = (DrawablePtr)pGlxPbuffer;
+ screen = pGlxPbuffer->pScreen->myNum;
+ be_drawable = pGlxPbuffer->be_xids[screen];
+ }
+ }
+
+
+ if (!pDraw) {
+ /*
+ ** Drawable is not a Window , GLXWindow or a GLXPixmap.
+ */
+ client->errorValue = drawId;
+ return __glXBadDrawable;
+ }
+ }
+
+
+ /* if the drawable is a window or GLXWindow -
+ * we need to find the base id on the back-end server
+ */
+ if (!be_drawable) {
+ WindowPtr pWin = (WindowPtr)pDraw;
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ pXinDraw = (PanoramiXRes *)
+ SecurityLookupIDByClass(client, pDraw->id, XRC_DRAWABLE, DixReadAccess);
+ if (!pXinDraw) {
+ client->errorValue = drawId;
+ return __glXBadDrawable;
+ }
+
+ dixLookupWindow(&pWin, pXinDraw->info[screen].id, client,
+ DixReadAccess);
+ }
+#endif
+
+ if (pWin) {
+ be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
+ if (!be_drawable) {
+ /* it might be that the window did not created yet on the */
+ /* back-end server (lazy window creation option), force */
+ /* creation of the window */
+ dmxCreateAndRealizeWindow( pWin, TRUE );
+ be_drawable = (unsigned int)(DMX_GET_WINDOW_PRIV(pWin))->window;
+ }
+ }
+ else {
+ client->errorValue = drawId;
+ return __glXBadDrawable;
+ }
+ }
+
+
+ /* send the request to the back-end server */
+ dpy = GetBackEndDisplay(cl,screen);
+ dmxScreen = &dmxScreens[screen];
+
+ /* make sure drawable exists on back-end */
+ dmxSync( dmxScreen, 1 );
+
+ LockDisplay(dpy);
+ GetReqExtra(GLXChangeDrawableAttributes,
+ 2 * req->numAttribs * __GLX_SIZE_CARD32, be_req);
+ be_req->reqType = dmxScreen->glxMajorOpcode;
+ be_req->glxCode = X_GLXChangeDrawableAttributes;
+ be_req->drawable = be_drawable;
+ be_req->numAttribs = req->numAttribs;
+ be_req->length = req->length;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return Success;
+}
+
+int __glXSendLargeCommand(__GLXclientState *cl, GLXContextTag contextTag)
+{
+ ClientPtr client = cl->client;
+ xGLXRenderLargeReq *req;
+ GLint maxSize, amount;
+ GLint totalRequests, requestNumber;
+ GLint dataLen;
+ GLbyte *data;
+ __GLXcontext *glxc;
+ int s;
+ int from_screen, to_screen;
+
+ maxSize = cl->largeCmdMaxReqDataSize - (GLint)sizeof(xGLXRenderLargeReq);
+ dataLen = cl->largeCmdBytesTotal;
+ totalRequests = (dataLen / maxSize);
+ if (dataLen % maxSize) totalRequests++;
+
+ glxc = __glXLookupContextByTag(cl, contextTag);
+ if (!glxc) {
+ client->errorValue = contextTag;
+ return __glXBadContext;
+ }
+ from_screen = to_screen = glxc->pScreen->myNum;
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ from_screen = 0;
+ to_screen = screenInfo.numScreens - 1;
+ }
+#endif
+
+ /*
+ ** Send enough requests until the whole array is sent.
+ */
+ requestNumber = 1;
+ data = cl->largeCmdBuf;
+ while (dataLen > 0) {
+ amount = dataLen;
+ if (amount > maxSize) {
+ amount = maxSize;
+ }
+
+ for (s=from_screen; s<=to_screen; s++) {
+
+ Display *dpy = GetBackEndDisplay(cl,s);
+ DMXScreenInfo *dmxScreen = &dmxScreens[s];
+
+ LockDisplay(dpy);
+ GetReq(GLXRenderLarge,req);
+ req->reqType = dmxScreen->glxMajorOpcode;
+ req->glxCode = X_GLXRenderLarge;
+ req->contextTag = GetCurrentBackEndTag(cl,contextTag,s);
+ req->length += (amount + 3) >> 2;
+ req->requestNumber = requestNumber++;
+ req->requestTotal = totalRequests;
+ req->dataBytes = amount;
+ Data(dpy, ((const char*)data), amount);
+ dataLen -= amount;
+ data = ((GLbyte *) data) + amount;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ }
+ }
+
+ return Success;
+}
diff --git a/xorg-server/hw/dmx/glxProxy/glxext.c b/xorg-server/hw/dmx/glxProxy/glxext.c
index 6cd8bb41a..6589e43bb 100644
--- a/xorg-server/hw/dmx/glxProxy/glxext.c
+++ b/xorg-server/hw/dmx/glxProxy/glxext.c
@@ -1,532 +1,532 @@
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, 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 including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * 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
- * SILICON GRAPHICS, INC. 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 Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
-
-#include "dmx.h"
-
-#include "glxserver.h"
-#include <windowstr.h>
-#include <propertyst.h>
-#include <os.h>
-#include "g_disptab.h"
-#include "glxutil.h"
-#include "glxext.h"
-#include "glxvisuals.h"
-#include "micmap.h"
-#include "glxswap.h"
-
-/*
-** Stubs to satisfy miinitext.c references.
-*/
-typedef int __GLXprovider;
-__GLXprovider __glXDRISWRastProvider;
-void GlxPushProvider(__GLXprovider *provider) { }
-
-/*
-** Forward declarations.
-*/
-static int __glXSwapDispatch(ClientPtr);
-static int __glXDispatch(ClientPtr);
-
-/*
-** Called when the extension is reset.
-*/
-static void ResetExtension(ExtensionEntry* extEntry)
-{
- __glXFlushContextCache();
- __glXScreenReset();
- SwapBarrierReset();
-}
-
-/*
-** Initialize the per-client context storage.
-*/
-static void ResetClientState(int clientIndex)
-{
- __GLXclientState *cl = __glXClients[clientIndex];
- Display **keep_be_displays;
- int i;
-
- if (cl->returnBuf) __glXFree(cl->returnBuf);
- if (cl->currentContexts) __glXFree(cl->currentContexts);
- if (cl->currentDrawables) __glXFree(cl->currentDrawables);
- if (cl->largeCmdBuf) __glXFree(cl->largeCmdBuf);
-
- for (i=0; i< screenInfo.numScreens; i++) {
- if (cl->be_displays[i])
- XCloseDisplay( cl->be_displays[i] );
- }
-
- keep_be_displays = cl->be_displays;
- memset(cl, 0, sizeof(__GLXclientState));
- cl->be_displays = keep_be_displays;
-
- /*
- ** By default, assume that the client supports
- ** GLX major version 1 minor version 0 protocol.
- */
- cl->GLClientmajorVersion = 1;
- cl->GLClientminorVersion = 0;
- if (cl->GLClientextensions) __glXFree(cl->GLClientextensions);
-
- memset(cl->be_displays, 0, screenInfo.numScreens * sizeof(Display *));
-}
-
-
-/*
-** This procedure is called when the client who created the context goes
-** away OR when glXDestroyContext is called. In either case, all we do is
-** flag that the ID is no longer valid, and (maybe) free the context.
-** use.
-*/
-static int ContextGone(__GLXcontext* cx, XID id)
-{
- cx->idExists = GL_FALSE;
- if (!cx->isCurrent) {
- __glXFreeContext(cx);
- }
-
- return True;
-}
-
-/*
-** Free a client's state.
-*/
-static int ClientGone(int clientIndex, XID id)
-{
- __GLXcontext *cx;
- __GLXclientState *cl = __glXClients[clientIndex];
- int i;
-
- if (cl) {
- /*
- ** Free all the contexts that are current for this client.
- */
- for (i=0; i < cl->numCurrentContexts; i++) {
- cx = cl->currentContexts[i];
- if (cx) {
- cx->isCurrent = GL_FALSE;
- if (!cx->idExists) {
- __glXFreeContext(cx);
- }
- }
- }
- /*
- ** Re-initialize the client state structure. Don't free it because
- ** we'll probably get another client with this index and use the struct
- ** again. There is a maximum of MAXCLIENTS of these structures.
- */
- ResetClientState(clientIndex);
- }
-
- return True;
-}
-
-/*
-** Free a GLX Pixmap.
-*/
-void __glXFreeGLXPixmap( __GLXpixmap *pGlxPixmap )
-{
- if (!pGlxPixmap->idExists &&
- !pGlxPixmap->refcnt) {
-
- PixmapPtr pPixmap = (PixmapPtr) pGlxPixmap->pDraw;
-
- /*
- ** The DestroyPixmap routine should decrement the refcount and free
- ** only if it's zero.
- */
- (*pGlxPixmap->pScreen->DestroyPixmap)(pPixmap);
- __glXFree(pGlxPixmap->be_xids);
- __glXFree(pGlxPixmap);
- }
-
-}
-
-static int PixmapGone(__GLXpixmap *pGlxPixmap, XID id)
-{
-
- pGlxPixmap->idExists = False;
- __glXFreeGLXPixmap( pGlxPixmap );
-
- return True;
-}
-
-void __glXFreeGLXWindow(__glXWindow *pGlxWindow)
-{
- if (!pGlxWindow->idExists && !pGlxWindow->refcnt) {
- WindowPtr pWindow = (WindowPtr) pGlxWindow->pDraw;
-
- if (LookupIDByType(pWindow->drawable.id, RT_WINDOW) == pWindow) {
- (*pGlxWindow->pScreen->DestroyWindow)(pWindow);
- }
-
- xfree(pGlxWindow);
- }
-}
-
-static void WindowGone(__glXWindow *pGlxWindow, XID id)
-{
- pGlxWindow->idExists = False;
- __glXFreeGLXWindow(pGlxWindow);
-}
-
-void __glXFreeGLXPbuffer(__glXPbuffer *pGlxPbuffer)
-{
- if (!pGlxPbuffer->idExists && !pGlxPbuffer->refcnt) {
- xfree(pGlxPbuffer->be_xids);
- xfree(pGlxPbuffer);
- }
-}
-
-static void PbufferGone(__glXPbuffer *pGlxPbuffer, XID id)
-{
- pGlxPbuffer->idExists = False;
- __glXFreeGLXPbuffer(pGlxPbuffer);
-}
-
-/*
-** Free a context.
-*/
-GLboolean __glXFreeContext(__GLXcontext *cx)
-{
- if (cx->idExists || cx->isCurrent) return GL_FALSE;
-
- if (cx->feedbackBuf) __glXFree(cx->feedbackBuf);
- if (cx->selectBuf) __glXFree(cx->selectBuf);
- if (cx->real_ids) __glXFree(cx->real_ids);
- if (cx->real_vids) __glXFree(cx->real_vids);
-
- if (cx->pGlxPixmap) {
- /*
- ** The previous drawable was a glx pixmap, release it.
- */
- cx->pGlxPixmap->refcnt--;
- __glXFreeGLXPixmap( cx->pGlxPixmap );
- cx->pGlxPixmap = 0;
- }
-
- if (cx->pGlxReadPixmap) {
- /*
- ** The previous drawable was a glx pixmap, release it.
- */
- cx->pGlxReadPixmap->refcnt--;
- __glXFreeGLXPixmap( cx->pGlxReadPixmap );
- cx->pGlxReadPixmap = 0;
- }
-
- if (cx->pGlxWindow) {
- /*
- ** The previous drawable was a glx window, release it.
- */
- cx->pGlxWindow->refcnt--;
- __glXFreeGLXWindow( cx->pGlxWindow );
- cx->pGlxWindow = 0;
- }
-
- if (cx->pGlxReadWindow) {
- /*
- ** The previous drawable was a glx window, release it.
- */
- cx->pGlxReadWindow->refcnt--;
- __glXFreeGLXWindow( cx->pGlxReadWindow );
- cx->pGlxReadWindow = 0;
- }
-
- __glXFree(cx);
-
- if (cx == __glXLastContext) {
- __glXFlushContextCache();
- }
-
- return GL_TRUE;
-}
-
-/*
-** Initialize the GLX extension.
-*/
-void GlxExtensionInit(void)
-{
- ExtensionEntry *extEntry;
- int i;
- int glxSupported = 1;
-
- /*
- // do not initialize GLX extension if GLX is not supported
- // by ALL back-end servers.
- */
- for (i=0; i<screenInfo.numScreens; i++) {
- glxSupported &= (dmxScreens[i].glxMajorOpcode > 0);
- }
-
- if (!glxSupported || !dmxGLXProxy) {
- return;
- }
-
- __glXContextRes = CreateNewResourceType((DeleteType)ContextGone,
- "GLXContext");
- __glXClientRes = CreateNewResourceType((DeleteType)ClientGone,
- "GLXClient");
- __glXPixmapRes = CreateNewResourceType((DeleteType)PixmapGone,
- "GLXPixmap");
- __glXWindowRes = CreateNewResourceType((DeleteType)WindowGone,
- "GLXWindow");
- __glXPbufferRes = CreateNewResourceType((DeleteType)PbufferGone,
- "GLXPbuffer");
-
- if (!__glXContextRes || !__glXClientRes || !__glXPixmapRes ||
- !__glXWindowRes || !__glXPbufferRes)
- return;
-
- /*
- ** Add extension to server extensions.
- */
- extEntry = AddExtension(GLX_EXTENSION_NAME, __GLX_NUMBER_EVENTS,
- __GLX_NUMBER_ERRORS, __glXDispatch,
- __glXSwapDispatch, ResetExtension,
- StandardMinorOpcode);
- if (!extEntry) {
- FatalError("__glXExtensionInit: AddExtensions failed\n");
- return;
- }
- /*
- if (!AddExtensionAlias(GLX_EXTENSION_ALIAS, extEntry)) {
- ErrorF("__glXExtensionInit: AddExtensionAlias failed\n");
- return;
- }
- */
-
- __glXerrorBase = extEntry->errorBase;
- __glXBadContext = extEntry->errorBase + GLXBadContext;
- __glXBadContextState = extEntry->errorBase + GLXBadContextState;
- __glXBadDrawable = extEntry->errorBase + GLXBadDrawable;
- __glXBadPixmap = extEntry->errorBase + GLXBadPixmap;
- __glXBadContextTag = extEntry->errorBase + GLXBadContextTag;
- __glXBadCurrentWindow = extEntry->errorBase + GLXBadCurrentWindow;
- __glXBadRenderRequest = extEntry->errorBase + GLXBadRenderRequest;
- __glXBadLargeRequest = extEntry->errorBase + GLXBadLargeRequest;
- __glXUnsupportedPrivateRequest = extEntry->errorBase +
- GLXUnsupportedPrivateRequest;
- __glXBadFBConfig = extEntry->errorBase + GLXBadFBConfig;
- __glXBadPbuffer = extEntry->errorBase + GLXBadPbuffer;
-
- /*
- ** Initialize table of client state. There is never a client 0.
- */
- for (i=1; i <= MAXCLIENTS; i++) {
- __glXClients[i] = 0;
- }
-
- /*
- ** Initialize screen specific data.
- */
- __glXScreenInit(screenInfo.numScreens);
-
- /*
- ** Initialize swap barrier support.
- */
- SwapBarrierInit();
-}
-
-/************************************************************************/
-
-Bool __glXCoreType(void)
-{
- return 0;
-}
-
-/************************************************************************/
-
-void GlxSetVisualConfigs(int nconfigs,
- __GLXvisualConfig *configs, void **privates)
-{
- glxSetVisualConfigs(nconfigs, configs, privates);
-}
-
-static miInitVisualsProcPtr saveInitVisualsProc;
-
-Bool GlxInitVisuals(VisualPtr *visualp, DepthPtr *depthp,
- int *nvisualp, int *ndepthp,
- int *rootDepthp, VisualID *defaultVisp,
- unsigned long sizes, int bitsPerRGB,
- int preferredVis)
-{
- Bool ret;
-
- if (saveInitVisualsProc) {
- ret = saveInitVisualsProc(visualp, depthp, nvisualp, ndepthp,
- rootDepthp, defaultVisp, sizes, bitsPerRGB,
- preferredVis);
- if (!ret)
- return False;
- }
-
- glxInitVisuals(nvisualp, visualp, defaultVisp, *ndepthp, *depthp,*rootDepthp);
-
- return True;
-}
-
-void
-GlxWrapInitVisuals(miInitVisualsProcPtr *initVisProc)
-{
- if (dmxGLXProxy) {
- saveInitVisualsProc = *initVisProc;
- *initVisProc = GlxInitVisuals;
- }
-}
-
-/************************************************************************/
-
-void __glXFlushContextCache(void)
-{
- __glXLastContext = 0;
-}
-
-/************************************************************************/
-
-/*
-** Top level dispatcher; all commands are executed from here down.
-*/
-static int __glXDispatch(ClientPtr client)
-{
- REQUEST(xGLXSingleReq);
- CARD8 opcode;
- int (*proc)(__GLXclientState *cl, GLbyte *pc);
- __GLXclientState *cl;
-
- opcode = stuff->glxCode;
- cl = __glXClients[client->index];
- if (!cl) {
- cl = __glXCalloc(1, sizeof(__GLXclientState));
- __glXClients[client->index] = cl;
- if (!cl) {
- return BadAlloc;
- }
-
- cl->be_displays = __glXCalloc(screenInfo.numScreens, sizeof(Display *));
- if (!cl->be_displays) {
- __glXFree( cl );
- return BadAlloc;
- }
- }
-
- if (!cl->inUse) {
- /*
- ** This is first request from this client. Associate a resource
- ** with the client so we will be notified when the client dies.
- */
- XID xid = FakeClientID(client->index);
- if (!AddResource( xid, __glXClientRes, (pointer)(long)client->index)) {
- return BadAlloc;
- }
- ResetClientState(client->index);
- cl->largeCmdRequestsTotal = 0;
- cl->inUse = GL_TRUE;
- cl->client = client;
- }
-
- /*
- ** Check for valid opcode.
- */
- if (opcode >= __GLX_SINGLE_TABLE_SIZE) {
- return BadRequest;
- }
-
- /*
- ** Use the opcode to index into the procedure table.
- */
- proc = __glXSingleTable[opcode];
- return (*proc)(cl, (GLbyte *) stuff);
-}
-
-static int __glXSwapDispatch(ClientPtr client)
-{
- REQUEST(xGLXSingleReq);
- CARD8 opcode;
- int (*proc)(__GLXclientState *cl, GLbyte *pc);
- __GLXclientState *cl;
-
- opcode = stuff->glxCode;
- cl = __glXClients[client->index];
- if (!cl) {
- cl = __glXCalloc(1, sizeof(__GLXclientState));
- __glXClients[client->index] = cl;
- if (!cl) {
- return BadAlloc;
- }
-
- cl->be_displays = __glXCalloc(screenInfo.numScreens, sizeof(Display *));
- if (!cl->be_displays) {
- __glXFree( cl );
- return BadAlloc;
- }
- }
-
- if (!cl->inUse) {
- /*
- ** This is first request from this client. Associate a resource
- ** with the client so we will be notified when the client dies.
- */
- XID xid = FakeClientID(client->index);
- if (!AddResource( xid, __glXClientRes, (pointer)(long)client->index)) {
- return BadAlloc;
- }
- ResetClientState(client->index);
- cl->inUse = GL_TRUE;
- cl->client = client;
- }
-
- /*
- ** Check for valid opcode.
- */
- if (opcode >= __GLX_SINGLE_TABLE_SIZE) {
- return BadRequest;
- }
-
- /*
- ** Use the opcode to index into the procedure table.
- */
- proc = __glXSwapSingleTable[opcode];
- return (*proc)(cl, (GLbyte *) stuff);
-}
-
-int __glXNoSuchSingleOpcode(__GLXclientState *cl, GLbyte *pc)
-{
- return BadRequest;
-}
-
-void __glXNoSuchRenderOpcode(GLbyte *pc)
-{
- return;
-}
-
+/*
+ * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
+ * Copyright (C) 1991-2000 Silicon Graphics, 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 including the dates of first publication and
+ * either this permission notice or a reference to
+ * http://oss.sgi.com/projects/FreeB/
+ * 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
+ * SILICON GRAPHICS, INC. 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 Silicon Graphics, Inc.
+ * shall not be used in advertising or otherwise to promote the sale, use or
+ * other dealings in this Software without prior written authorization from
+ * Silicon Graphics, Inc.
+ */
+
+#ifdef HAVE_DMX_CONFIG_H
+#include <dmx-config.h>
+#endif
+
+#include "dmx.h"
+
+#include "glxserver.h"
+#include <windowstr.h>
+#include <propertyst.h>
+#include <os.h>
+#include "g_disptab.h"
+#include "glxutil.h"
+#include "glxext.h"
+#include "glxvisuals.h"
+#include "micmap.h"
+#include "glxswap.h"
+
+/*
+** Stubs to satisfy miinitext.c references.
+*/
+typedef int __GLXprovider;
+__GLXprovider __glXDRISWRastProvider;
+void GlxPushProvider(__GLXprovider *provider) { }
+
+/*
+** Forward declarations.
+*/
+static int __glXSwapDispatch(ClientPtr);
+static int __glXDispatch(ClientPtr);
+
+/*
+** Called when the extension is reset.
+*/
+static void ResetExtension(ExtensionEntry* extEntry)
+{
+ __glXFlushContextCache();
+ __glXScreenReset();
+ SwapBarrierReset();
+}
+
+/*
+** Initialize the per-client context storage.
+*/
+static void ResetClientState(int clientIndex)
+{
+ __GLXclientState *cl = __glXClients[clientIndex];
+ Display **keep_be_displays;
+ int i;
+
+ if (cl->returnBuf) __glXFree(cl->returnBuf);
+ if (cl->currentContexts) __glXFree(cl->currentContexts);
+ if (cl->currentDrawables) __glXFree(cl->currentDrawables);
+ if (cl->largeCmdBuf) __glXFree(cl->largeCmdBuf);
+
+ for (i=0; i< screenInfo.numScreens; i++) {
+ if (cl->be_displays[i])
+ XCloseDisplay( cl->be_displays[i] );
+ }
+
+ keep_be_displays = cl->be_displays;
+ memset(cl, 0, sizeof(__GLXclientState));
+ cl->be_displays = keep_be_displays;
+
+ /*
+ ** By default, assume that the client supports
+ ** GLX major version 1 minor version 0 protocol.
+ */
+ cl->GLClientmajorVersion = 1;
+ cl->GLClientminorVersion = 0;
+ if (cl->GLClientextensions) __glXFree(cl->GLClientextensions);
+
+ memset(cl->be_displays, 0, screenInfo.numScreens * sizeof(Display *));
+}
+
+
+/*
+** This procedure is called when the client who created the context goes
+** away OR when glXDestroyContext is called. In either case, all we do is
+** flag that the ID is no longer valid, and (maybe) free the context.
+** use.
+*/
+static int ContextGone(__GLXcontext* cx, XID id)
+{
+ cx->idExists = GL_FALSE;
+ if (!cx->isCurrent) {
+ __glXFreeContext(cx);
+ }
+
+ return True;
+}
+
+/*
+** Free a client's state.
+*/
+static int ClientGone(int clientIndex, XID id)
+{
+ __GLXcontext *cx;
+ __GLXclientState *cl = __glXClients[clientIndex];
+ int i;
+
+ if (cl) {
+ /*
+ ** Free all the contexts that are current for this client.
+ */
+ for (i=0; i < cl->numCurrentContexts; i++) {
+ cx = cl->currentContexts[i];
+ if (cx) {
+ cx->isCurrent = GL_FALSE;
+ if (!cx->idExists) {
+ __glXFreeContext(cx);
+ }
+ }
+ }
+ /*
+ ** Re-initialize the client state structure. Don't free it because
+ ** we'll probably get another client with this index and use the struct
+ ** again. There is a maximum of MAXCLIENTS of these structures.
+ */
+ ResetClientState(clientIndex);
+ }
+
+ return True;
+}
+
+/*
+** Free a GLX Pixmap.
+*/
+void __glXFreeGLXPixmap( __GLXpixmap *pGlxPixmap )
+{
+ if (!pGlxPixmap->idExists &&
+ !pGlxPixmap->refcnt) {
+
+ PixmapPtr pPixmap = (PixmapPtr) pGlxPixmap->pDraw;
+
+ /*
+ ** The DestroyPixmap routine should decrement the refcount and free
+ ** only if it's zero.
+ */
+ (*pGlxPixmap->pScreen->DestroyPixmap)(pPixmap);
+ __glXFree(pGlxPixmap->be_xids);
+ __glXFree(pGlxPixmap);
+ }
+
+}
+
+static int PixmapGone(__GLXpixmap *pGlxPixmap, XID id)
+{
+
+ pGlxPixmap->idExists = False;
+ __glXFreeGLXPixmap( pGlxPixmap );
+
+ return True;
+}
+
+void __glXFreeGLXWindow(__glXWindow *pGlxWindow)
+{
+ if (!pGlxWindow->idExists && !pGlxWindow->refcnt) {
+ WindowPtr pWindow = (WindowPtr) pGlxWindow->pDraw;
+
+ if (LookupIDByType(pWindow->drawable.id, RT_WINDOW) == pWindow) {
+ (*pGlxWindow->pScreen->DestroyWindow)(pWindow);
+ }
+
+ free(pGlxWindow);
+ }
+}
+
+static void WindowGone(__glXWindow *pGlxWindow, XID id)
+{
+ pGlxWindow->idExists = False;
+ __glXFreeGLXWindow(pGlxWindow);
+}
+
+void __glXFreeGLXPbuffer(__glXPbuffer *pGlxPbuffer)
+{
+ if (!pGlxPbuffer->idExists && !pGlxPbuffer->refcnt) {
+ free(pGlxPbuffer->be_xids);
+ free(pGlxPbuffer);
+ }
+}
+
+static void PbufferGone(__glXPbuffer *pGlxPbuffer, XID id)
+{
+ pGlxPbuffer->idExists = False;
+ __glXFreeGLXPbuffer(pGlxPbuffer);
+}
+
+/*
+** Free a context.
+*/
+GLboolean __glXFreeContext(__GLXcontext *cx)
+{
+ if (cx->idExists || cx->isCurrent) return GL_FALSE;
+
+ if (cx->feedbackBuf) __glXFree(cx->feedbackBuf);
+ if (cx->selectBuf) __glXFree(cx->selectBuf);
+ if (cx->real_ids) __glXFree(cx->real_ids);
+ if (cx->real_vids) __glXFree(cx->real_vids);
+
+ if (cx->pGlxPixmap) {
+ /*
+ ** The previous drawable was a glx pixmap, release it.
+ */
+ cx->pGlxPixmap->refcnt--;
+ __glXFreeGLXPixmap( cx->pGlxPixmap );
+ cx->pGlxPixmap = 0;
+ }
+
+ if (cx->pGlxReadPixmap) {
+ /*
+ ** The previous drawable was a glx pixmap, release it.
+ */
+ cx->pGlxReadPixmap->refcnt--;
+ __glXFreeGLXPixmap( cx->pGlxReadPixmap );
+ cx->pGlxReadPixmap = 0;
+ }
+
+ if (cx->pGlxWindow) {
+ /*
+ ** The previous drawable was a glx window, release it.
+ */
+ cx->pGlxWindow->refcnt--;
+ __glXFreeGLXWindow( cx->pGlxWindow );
+ cx->pGlxWindow = 0;
+ }
+
+ if (cx->pGlxReadWindow) {
+ /*
+ ** The previous drawable was a glx window, release it.
+ */
+ cx->pGlxReadWindow->refcnt--;
+ __glXFreeGLXWindow( cx->pGlxReadWindow );
+ cx->pGlxReadWindow = 0;
+ }
+
+ __glXFree(cx);
+
+ if (cx == __glXLastContext) {
+ __glXFlushContextCache();
+ }
+
+ return GL_TRUE;
+}
+
+/*
+** Initialize the GLX extension.
+*/
+void GlxExtensionInit(void)
+{
+ ExtensionEntry *extEntry;
+ int i;
+ int glxSupported = 1;
+
+ /*
+ // do not initialize GLX extension if GLX is not supported
+ // by ALL back-end servers.
+ */
+ for (i=0; i<screenInfo.numScreens; i++) {
+ glxSupported &= (dmxScreens[i].glxMajorOpcode > 0);
+ }
+
+ if (!glxSupported || !dmxGLXProxy) {
+ return;
+ }
+
+ __glXContextRes = CreateNewResourceType((DeleteType)ContextGone,
+ "GLXContext");
+ __glXClientRes = CreateNewResourceType((DeleteType)ClientGone,
+ "GLXClient");
+ __glXPixmapRes = CreateNewResourceType((DeleteType)PixmapGone,
+ "GLXPixmap");
+ __glXWindowRes = CreateNewResourceType((DeleteType)WindowGone,
+ "GLXWindow");
+ __glXPbufferRes = CreateNewResourceType((DeleteType)PbufferGone,
+ "GLXPbuffer");
+
+ if (!__glXContextRes || !__glXClientRes || !__glXPixmapRes ||
+ !__glXWindowRes || !__glXPbufferRes)
+ return;
+
+ /*
+ ** Add extension to server extensions.
+ */
+ extEntry = AddExtension(GLX_EXTENSION_NAME, __GLX_NUMBER_EVENTS,
+ __GLX_NUMBER_ERRORS, __glXDispatch,
+ __glXSwapDispatch, ResetExtension,
+ StandardMinorOpcode);
+ if (!extEntry) {
+ FatalError("__glXExtensionInit: AddExtensions failed\n");
+ return;
+ }
+ /*
+ if (!AddExtensionAlias(GLX_EXTENSION_ALIAS, extEntry)) {
+ ErrorF("__glXExtensionInit: AddExtensionAlias failed\n");
+ return;
+ }
+ */
+
+ __glXerrorBase = extEntry->errorBase;
+ __glXBadContext = extEntry->errorBase + GLXBadContext;
+ __glXBadContextState = extEntry->errorBase + GLXBadContextState;
+ __glXBadDrawable = extEntry->errorBase + GLXBadDrawable;
+ __glXBadPixmap = extEntry->errorBase + GLXBadPixmap;
+ __glXBadContextTag = extEntry->errorBase + GLXBadContextTag;
+ __glXBadCurrentWindow = extEntry->errorBase + GLXBadCurrentWindow;
+ __glXBadRenderRequest = extEntry->errorBase + GLXBadRenderRequest;
+ __glXBadLargeRequest = extEntry->errorBase + GLXBadLargeRequest;
+ __glXUnsupportedPrivateRequest = extEntry->errorBase +
+ GLXUnsupportedPrivateRequest;
+ __glXBadFBConfig = extEntry->errorBase + GLXBadFBConfig;
+ __glXBadPbuffer = extEntry->errorBase + GLXBadPbuffer;
+
+ /*
+ ** Initialize table of client state. There is never a client 0.
+ */
+ for (i=1; i <= MAXCLIENTS; i++) {
+ __glXClients[i] = 0;
+ }
+
+ /*
+ ** Initialize screen specific data.
+ */
+ __glXScreenInit(screenInfo.numScreens);
+
+ /*
+ ** Initialize swap barrier support.
+ */
+ SwapBarrierInit();
+}
+
+/************************************************************************/
+
+Bool __glXCoreType(void)
+{
+ return 0;
+}
+
+/************************************************************************/
+
+void GlxSetVisualConfigs(int nconfigs,
+ __GLXvisualConfig *configs, void **privates)
+{
+ glxSetVisualConfigs(nconfigs, configs, privates);
+}
+
+static miInitVisualsProcPtr saveInitVisualsProc;
+
+Bool GlxInitVisuals(VisualPtr *visualp, DepthPtr *depthp,
+ int *nvisualp, int *ndepthp,
+ int *rootDepthp, VisualID *defaultVisp,
+ unsigned long sizes, int bitsPerRGB,
+ int preferredVis)
+{
+ Bool ret;
+
+ if (saveInitVisualsProc) {
+ ret = saveInitVisualsProc(visualp, depthp, nvisualp, ndepthp,
+ rootDepthp, defaultVisp, sizes, bitsPerRGB,
+ preferredVis);
+ if (!ret)
+ return False;
+ }
+
+ glxInitVisuals(nvisualp, visualp, defaultVisp, *ndepthp, *depthp,*rootDepthp);
+
+ return True;
+}
+
+void
+GlxWrapInitVisuals(miInitVisualsProcPtr *initVisProc)
+{
+ if (dmxGLXProxy) {
+ saveInitVisualsProc = *initVisProc;
+ *initVisProc = GlxInitVisuals;
+ }
+}
+
+/************************************************************************/
+
+void __glXFlushContextCache(void)
+{
+ __glXLastContext = 0;
+}
+
+/************************************************************************/
+
+/*
+** Top level dispatcher; all commands are executed from here down.
+*/
+static int __glXDispatch(ClientPtr client)
+{
+ REQUEST(xGLXSingleReq);
+ CARD8 opcode;
+ int (*proc)(__GLXclientState *cl, GLbyte *pc);
+ __GLXclientState *cl;
+
+ opcode = stuff->glxCode;
+ cl = __glXClients[client->index];
+ if (!cl) {
+ cl = __glXCalloc(1, sizeof(__GLXclientState));
+ __glXClients[client->index] = cl;
+ if (!cl) {
+ return BadAlloc;
+ }
+
+ cl->be_displays = __glXCalloc(screenInfo.numScreens, sizeof(Display *));
+ if (!cl->be_displays) {
+ __glXFree( cl );
+ return BadAlloc;
+ }
+ }
+
+ if (!cl->inUse) {
+ /*
+ ** This is first request from this client. Associate a resource
+ ** with the client so we will be notified when the client dies.
+ */
+ XID xid = FakeClientID(client->index);
+ if (!AddResource( xid, __glXClientRes, (pointer)(long)client->index)) {
+ return BadAlloc;
+ }
+ ResetClientState(client->index);
+ cl->largeCmdRequestsTotal = 0;
+ cl->inUse = GL_TRUE;
+ cl->client = client;
+ }
+
+ /*
+ ** Check for valid opcode.
+ */
+ if (opcode >= __GLX_SINGLE_TABLE_SIZE) {
+ return BadRequest;
+ }
+
+ /*
+ ** Use the opcode to index into the procedure table.
+ */
+ proc = __glXSingleTable[opcode];
+ return (*proc)(cl, (GLbyte *) stuff);
+}
+
+static int __glXSwapDispatch(ClientPtr client)
+{
+ REQUEST(xGLXSingleReq);
+ CARD8 opcode;
+ int (*proc)(__GLXclientState *cl, GLbyte *pc);
+ __GLXclientState *cl;
+
+ opcode = stuff->glxCode;
+ cl = __glXClients[client->index];
+ if (!cl) {
+ cl = __glXCalloc(1, sizeof(__GLXclientState));
+ __glXClients[client->index] = cl;
+ if (!cl) {
+ return BadAlloc;
+ }
+
+ cl->be_displays = __glXCalloc(screenInfo.numScreens, sizeof(Display *));
+ if (!cl->be_displays) {
+ __glXFree( cl );
+ return BadAlloc;
+ }
+ }
+
+ if (!cl->inUse) {
+ /*
+ ** This is first request from this client. Associate a resource
+ ** with the client so we will be notified when the client dies.
+ */
+ XID xid = FakeClientID(client->index);
+ if (!AddResource( xid, __glXClientRes, (pointer)(long)client->index)) {
+ return BadAlloc;
+ }
+ ResetClientState(client->index);
+ cl->inUse = GL_TRUE;
+ cl->client = client;
+ }
+
+ /*
+ ** Check for valid opcode.
+ */
+ if (opcode >= __GLX_SINGLE_TABLE_SIZE) {
+ return BadRequest;
+ }
+
+ /*
+ ** Use the opcode to index into the procedure table.
+ */
+ proc = __glXSwapSingleTable[opcode];
+ return (*proc)(cl, (GLbyte *) stuff);
+}
+
+int __glXNoSuchSingleOpcode(__GLXclientState *cl, GLbyte *pc)
+{
+ return BadRequest;
+}
+
+void __glXNoSuchRenderOpcode(GLbyte *pc)
+{
+ return;
+}
+
diff --git a/xorg-server/hw/dmx/glxProxy/glxscreens.c b/xorg-server/hw/dmx/glxProxy/glxscreens.c
index 39978a74d..4c40d2315 100644
--- a/xorg-server/hw/dmx/glxProxy/glxscreens.c
+++ b/xorg-server/hw/dmx/glxProxy/glxscreens.c
@@ -1,377 +1,377 @@
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, 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 including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * 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
- * SILICON GRAPHICS, INC. 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 Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
-
-#include "dmx.h"
-#include "dmxlog.h"
-
-#undef Xmalloc
-#undef Xcalloc
-#undef Xrealloc
-#undef Xfree
-
-#include "glxserver.h"
-
-#include <windowstr.h>
-
-#include "glxfbconfig.h"
-
-#ifdef PANORAMIX
-#include "panoramiXsrv.h"
-#endif
-
-__GLXscreenInfo *__glXActiveScreens;
-GLint __glXNumActiveScreens;
-
-__GLXFBConfig **__glXFBConfigs;
-int __glXNumFBConfigs;
-
-static char GLXServerVendorName[] = "SGI DMX/glxProxy";
-static char GLXServerVersion[64];
-static char GLXServerExtensions[] =
- "GLX_EXT_visual_info "
- "GLX_EXT_visual_rating "
- "GLX_EXT_import_context "
- "GLX_SGIX_fbconfig "
- "GLX_SGI_make_current_read "
- "GLX_SGI_swap_control "
- ;
-
-static char ExtensionsString[1024];
-
-static void CalcServerVersionAndExtensions( void )
-{
- int s;
- xGLXQueryVersionReq *req;
- xGLXQueryVersionReply reply;
- char **be_extensions;
- char *ext;
- char *denied_extensions;
-
- /*
- * set the server glx version to be the minimum version
- * supported by all back-end servers
- */
- __glXVersionMajor = 0;
- __glXVersionMinor = 0;
- for (s=0; s<__glXNumActiveScreens; s++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
- Display *dpy = dmxScreen->beDisplay;
-
- /* Send the glXQueryVersion request */
- LockDisplay(dpy);
- GetReq(GLXQueryVersion,req);
- req->reqType = dmxScreen->glxMajorOpcode;
- req->glxCode = X_GLXQueryVersion;
- req->majorVersion = GLX_SERVER_MAJOR_VERSION;
- req->minorVersion = GLX_SERVER_MINOR_VERSION;
- _XReply(dpy, (xReply*) &reply, 0, False);
- UnlockDisplay(dpy);
- SyncHandle();
-
- if (s == 0) {
- __glXVersionMajor = reply.majorVersion;
- __glXVersionMinor = reply.minorVersion;
- }
- else {
- if (reply.majorVersion < __glXVersionMajor) {
- __glXVersionMajor = reply.majorVersion;
- __glXVersionMinor = reply.minorVersion;
- }
- else if ( (reply.majorVersion == __glXVersionMajor) &&
- (reply.minorVersion < __glXVersionMinor) ) {
- __glXVersionMinor = reply.minorVersion;
- }
- }
-
- }
-
- if (GLX_SERVER_MAJOR_VERSION < __glXVersionMajor) {
- __glXVersionMajor = GLX_SERVER_MAJOR_VERSION;
- __glXVersionMinor = GLX_SERVER_MINOR_VERSION;
- }
- else if ( (GLX_SERVER_MAJOR_VERSION == __glXVersionMajor) &&
- (GLX_SERVER_MINOR_VERSION < __glXVersionMinor) ) {
- __glXVersionMinor = GLX_SERVER_MINOR_VERSION;
- }
-
- sprintf(GLXServerVersion, "%d.%d DMX %d back-end server(s)",
- __glXVersionMajor, __glXVersionMinor, __glXNumActiveScreens );
- /*
- * set the ExtensionsString to the minimum extensions string
- */
- ExtensionsString[0] = '\0';
-
- /*
- * read extensions strings of all back-end servers
- */
- be_extensions = (char **)Xalloc( __glXNumActiveScreens * sizeof(char *) );
- if (!be_extensions)
- return;
-
- for (s=0; s<__glXNumActiveScreens; s++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
- Display *dpy = dmxScreen->beDisplay;
- xGLXQueryServerStringReq *req;
- xGLXQueryServerStringReply reply;
- int length, numbytes, slop;
-
- /* Send the glXQueryServerString request */
- LockDisplay(dpy);
- GetReq(GLXQueryServerString,req);
- req->reqType = dmxScreen->glxMajorOpcode;
- req->glxCode = X_GLXQueryServerString;
- req->screen = DefaultScreen(dpy);
- req->name = GLX_EXTENSIONS;
- _XReply(dpy, (xReply*) &reply, 0, False);
-
- length = (int)reply.length;
- numbytes = (int)reply.n;
- slop = numbytes * __GLX_SIZE_INT8 & 3;
- be_extensions[s] = (char *)Xalloc(numbytes);
- if (!be_extensions[s]) {
- /* Throw data on the floor */
- _XEatData(dpy, length);
- } else {
- _XRead(dpy, (char *)be_extensions[s], numbytes);
- if (slop) _XEatData(dpy,4-slop);
- }
- UnlockDisplay(dpy);
- SyncHandle();
- }
-
- /*
- * extensions string will include only extensions that our
- * server supports as well as all back-end servers supports.
- * extensions that are in the DMX_DENY_EXTENSIONS string will
- * not be supported.
- */
- denied_extensions = getenv("DMX_DENY_GLX_EXTENSIONS");
- ext = strtok(GLXServerExtensions, " ");
- while( ext ) {
- int supported = 1;
-
- if (denied_extensions && strstr(denied_extensions, ext)) {
- supported = 0;
- }
- else {
- for (s=0; s<__glXNumActiveScreens && supported; s++) {
- if ( !strstr(be_extensions[s], ext) ) {
- supported = 0;
- }
- }
- }
-
- if (supported) {
- strcat(ExtensionsString, ext);
- strcat(ExtensionsString, " ");
- }
-
- ext = strtok(NULL, " ");
- }
-
- /*
- * release temporary storage
- */
- for (s=0; s<__glXNumActiveScreens; s++) {
- if (be_extensions[s]) Xfree(be_extensions[s]);
- }
- Xfree( be_extensions );
-
- if (dmxGLXSwapGroupSupport) {
- if (!denied_extensions ||
- !strstr(denied_extensions, "GLX_SGIX_swap_group")) {
- strcat(ExtensionsString, "GLX_SGIX_swap_group");
- if (!denied_extensions ||
- !strstr(denied_extensions, "GLX_SGIX_swap_barrier")) {
- strcat(ExtensionsString, " GLX_SGIX_swap_barrier");
- }
- }
- }
-
-}
-
-void __glXScreenInit(GLint numscreens)
-{
- int s;
- int c;
- DMXScreenInfo *dmxScreen0 = &dmxScreens[0];
- __glXNumActiveScreens = numscreens;
-
-
- CalcServerVersionAndExtensions();
-
-
- __glXFBConfigs = NULL;
- __glXNumFBConfigs = 0;
-
- if ( (__glXVersionMajor == 1 && __glXVersionMinor >= 3) ||
- (__glXVersionMajor > 1) ||
- ( strstr(ExtensionsString, "GLX_SGIX_fbconfig") ) ) {
-
- /*
- // Initialize FBConfig info.
- // find the set of FBConfigs that are present on all back-end
- // servers - only those configs will be supported
- */
- __glXFBConfigs = (__GLXFBConfig **)Xalloc( dmxScreen0->numFBConfigs *
- (numscreens+1) * sizeof(__GLXFBConfig *) );
- __glXNumFBConfigs = 0;
-
- for (c=0; c<dmxScreen0->numFBConfigs; c++) {
- __GLXFBConfig *cfg = NULL;
-
- if (numscreens > 1) {
- for (s=1; s<numscreens; s++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
- __GLXscreenInfo *glxScreen = &__glXActiveScreens[s];
-
- cfg = FindMatchingFBConfig( &dmxScreen0->fbconfigs[c],
- dmxScreen->fbconfigs,
- dmxScreen->numFBConfigs );
- __glXFBConfigs[ __glXNumFBConfigs * (numscreens+1) + s + 1 ] = cfg;
- if (!cfg) {
- dmxLog(dmxInfo,"screen0 FBConfig 0x%x is missing on screen#%d\n", dmxScreen0->fbconfigs[c].id, s);
- break;
- }
- else {
- dmxLog(dmxInfo,"screen0 FBConfig 0x%x matched to 0x%x on screen#%d\n", dmxScreen0->fbconfigs[c].id, cfg->id, s);
- }
- }
- }
- else {
- cfg = &dmxScreen0->fbconfigs[c];
- }
-
- if (cfg) {
-
- /* filter out overlay visuals */
- if (cfg->level == 0) {
- __GLXFBConfig *proxy_cfg;
-
- __glXFBConfigs[ __glXNumFBConfigs * (numscreens+1) + 1 ] =
- &dmxScreen0->fbconfigs[c];
-
- proxy_cfg = Xalloc( sizeof(__GLXFBConfig) );
- memcpy( proxy_cfg, cfg, sizeof(__GLXFBConfig) );
- proxy_cfg->id = FakeClientID(0);
- /* visual will be associated later in __glXGetFBConfigs */
- proxy_cfg->associatedVisualId = (unsigned int)-1;
-
- __glXFBConfigs[ __glXNumFBConfigs * (numscreens+1) + 0 ] = proxy_cfg;
-
- __glXNumFBConfigs++;
- }
-
- }
-
- }
-
- }
-
-}
-
-void __glXScreenReset(void)
-{
- __glXNumActiveScreens = 0;
-}
-
-char *__glXGetServerString( unsigned int name )
-{
- char *ret = NULL;
-
- switch( name) {
-
- case GLX_VENDOR:
- ret = GLXServerVendorName;
- break;
-
- case GLX_VERSION:
- ret = GLXServerVersion;
- break;
-
- case GLX_EXTENSIONS:
- ret = ExtensionsString;
- break;
-
- default:
- break;
- }
-
- return( ret );
-
-}
-
-
-__GLXFBConfig *glxLookupFBConfig( GLXFBConfigID id )
-{
- int i,j;
-
- for (i=0, j=0; i<__glXNumFBConfigs; i++,j+=(__glXNumActiveScreens+1) ) {
- if ( __glXFBConfigs[j]->id == id)
- return( __glXFBConfigs[j] );
- }
-
- return(NULL);
-}
-
-__GLXFBConfig *glxLookupFBConfigByVID( VisualID vid )
-{
- int i,j;
-
- for (i=0, j=0; i<__glXNumFBConfigs; i++,j+=(__glXNumActiveScreens+1) ) {
- if ( __glXFBConfigs[j]->associatedVisualId == vid)
- return( __glXFBConfigs[j] );
- }
-
- return(NULL);
-}
-
-__GLXFBConfig *glxLookupBackEndFBConfig( GLXFBConfigID id, int screen )
-{
- int i;
- int j;
-
- for (i=0, j=0; i<__glXNumFBConfigs; i++,j+=(__glXNumActiveScreens+1) ) {
- if ( __glXFBConfigs[j]->id == id)
- return( __glXFBConfigs[j+screen+1] );
- }
-
- return(NULL);
-
-}
-
-int glxIsExtensionSupported( char *ext )
-{
- return( strstr(ExtensionsString, ext) != NULL );
-}
+/*
+ * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
+ * Copyright (C) 1991-2000 Silicon Graphics, 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 including the dates of first publication and
+ * either this permission notice or a reference to
+ * http://oss.sgi.com/projects/FreeB/
+ * 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
+ * SILICON GRAPHICS, INC. 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 Silicon Graphics, Inc.
+ * shall not be used in advertising or otherwise to promote the sale, use or
+ * other dealings in this Software without prior written authorization from
+ * Silicon Graphics, Inc.
+ */
+
+#ifdef HAVE_DMX_CONFIG_H
+#include <dmx-config.h>
+#endif
+
+#include "dmx.h"
+#include "dmxlog.h"
+
+#undef Xmalloc
+#undef Xcalloc
+#undef Xrealloc
+#undef Xfree
+
+#include "glxserver.h"
+
+#include <windowstr.h>
+
+#include "glxfbconfig.h"
+
+#ifdef PANORAMIX
+#include "panoramiXsrv.h"
+#endif
+
+__GLXscreenInfo *__glXActiveScreens;
+GLint __glXNumActiveScreens;
+
+__GLXFBConfig **__glXFBConfigs;
+int __glXNumFBConfigs;
+
+static char GLXServerVendorName[] = "SGI DMX/glxProxy";
+static char GLXServerVersion[64];
+static char GLXServerExtensions[] =
+ "GLX_EXT_visual_info "
+ "GLX_EXT_visual_rating "
+ "GLX_EXT_import_context "
+ "GLX_SGIX_fbconfig "
+ "GLX_SGI_make_current_read "
+ "GLX_SGI_swap_control "
+ ;
+
+static char ExtensionsString[1024];
+
+static void CalcServerVersionAndExtensions( void )
+{
+ int s;
+ xGLXQueryVersionReq *req;
+ xGLXQueryVersionReply reply;
+ char **be_extensions;
+ char *ext;
+ char *denied_extensions;
+
+ /*
+ * set the server glx version to be the minimum version
+ * supported by all back-end servers
+ */
+ __glXVersionMajor = 0;
+ __glXVersionMinor = 0;
+ for (s=0; s<__glXNumActiveScreens; s++) {
+ DMXScreenInfo *dmxScreen = &dmxScreens[s];
+ Display *dpy = dmxScreen->beDisplay;
+
+ /* Send the glXQueryVersion request */
+ LockDisplay(dpy);
+ GetReq(GLXQueryVersion,req);
+ req->reqType = dmxScreen->glxMajorOpcode;
+ req->glxCode = X_GLXQueryVersion;
+ req->majorVersion = GLX_SERVER_MAJOR_VERSION;
+ req->minorVersion = GLX_SERVER_MINOR_VERSION;
+ _XReply(dpy, (xReply*) &reply, 0, False);
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ if (s == 0) {
+ __glXVersionMajor = reply.majorVersion;
+ __glXVersionMinor = reply.minorVersion;
+ }
+ else {
+ if (reply.majorVersion < __glXVersionMajor) {
+ __glXVersionMajor = reply.majorVersion;
+ __glXVersionMinor = reply.minorVersion;
+ }
+ else if ( (reply.majorVersion == __glXVersionMajor) &&
+ (reply.minorVersion < __glXVersionMinor) ) {
+ __glXVersionMinor = reply.minorVersion;
+ }
+ }
+
+ }
+
+ if (GLX_SERVER_MAJOR_VERSION < __glXVersionMajor) {
+ __glXVersionMajor = GLX_SERVER_MAJOR_VERSION;
+ __glXVersionMinor = GLX_SERVER_MINOR_VERSION;
+ }
+ else if ( (GLX_SERVER_MAJOR_VERSION == __glXVersionMajor) &&
+ (GLX_SERVER_MINOR_VERSION < __glXVersionMinor) ) {
+ __glXVersionMinor = GLX_SERVER_MINOR_VERSION;
+ }
+
+ sprintf(GLXServerVersion, "%d.%d DMX %d back-end server(s)",
+ __glXVersionMajor, __glXVersionMinor, __glXNumActiveScreens );
+ /*
+ * set the ExtensionsString to the minimum extensions string
+ */
+ ExtensionsString[0] = '\0';
+
+ /*
+ * read extensions strings of all back-end servers
+ */
+ be_extensions = (char **)malloc( __glXNumActiveScreens * sizeof(char *) );
+ if (!be_extensions)
+ return;
+
+ for (s=0; s<__glXNumActiveScreens; s++) {
+ DMXScreenInfo *dmxScreen = &dmxScreens[s];
+ Display *dpy = dmxScreen->beDisplay;
+ xGLXQueryServerStringReq *req;
+ xGLXQueryServerStringReply reply;
+ int length, numbytes, slop;
+
+ /* Send the glXQueryServerString request */
+ LockDisplay(dpy);
+ GetReq(GLXQueryServerString,req);
+ req->reqType = dmxScreen->glxMajorOpcode;
+ req->glxCode = X_GLXQueryServerString;
+ req->screen = DefaultScreen(dpy);
+ req->name = GLX_EXTENSIONS;
+ _XReply(dpy, (xReply*) &reply, 0, False);
+
+ length = (int)reply.length;
+ numbytes = (int)reply.n;
+ slop = numbytes * __GLX_SIZE_INT8 & 3;
+ be_extensions[s] = (char *)malloc(numbytes);
+ if (!be_extensions[s]) {
+ /* Throw data on the floor */
+ _XEatData(dpy, length);
+ } else {
+ _XRead(dpy, (char *)be_extensions[s], numbytes);
+ if (slop) _XEatData(dpy,4-slop);
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ }
+
+ /*
+ * extensions string will include only extensions that our
+ * server supports as well as all back-end servers supports.
+ * extensions that are in the DMX_DENY_EXTENSIONS string will
+ * not be supported.
+ */
+ denied_extensions = getenv("DMX_DENY_GLX_EXTENSIONS");
+ ext = strtok(GLXServerExtensions, " ");
+ while( ext ) {
+ int supported = 1;
+
+ if (denied_extensions && strstr(denied_extensions, ext)) {
+ supported = 0;
+ }
+ else {
+ for (s=0; s<__glXNumActiveScreens && supported; s++) {
+ if ( !strstr(be_extensions[s], ext) ) {
+ supported = 0;
+ }
+ }
+ }
+
+ if (supported) {
+ strcat(ExtensionsString, ext);
+ strcat(ExtensionsString, " ");
+ }
+
+ ext = strtok(NULL, " ");
+ }
+
+ /*
+ * release temporary storage
+ */
+ for (s=0; s<__glXNumActiveScreens; s++) {
+ if (be_extensions[s]) Xfree(be_extensions[s]);
+ }
+ Xfree( be_extensions );
+
+ if (dmxGLXSwapGroupSupport) {
+ if (!denied_extensions ||
+ !strstr(denied_extensions, "GLX_SGIX_swap_group")) {
+ strcat(ExtensionsString, "GLX_SGIX_swap_group");
+ if (!denied_extensions ||
+ !strstr(denied_extensions, "GLX_SGIX_swap_barrier")) {
+ strcat(ExtensionsString, " GLX_SGIX_swap_barrier");
+ }
+ }
+ }
+
+}
+
+void __glXScreenInit(GLint numscreens)
+{
+ int s;
+ int c;
+ DMXScreenInfo *dmxScreen0 = &dmxScreens[0];
+ __glXNumActiveScreens = numscreens;
+
+
+ CalcServerVersionAndExtensions();
+
+
+ __glXFBConfigs = NULL;
+ __glXNumFBConfigs = 0;
+
+ if ( (__glXVersionMajor == 1 && __glXVersionMinor >= 3) ||
+ (__glXVersionMajor > 1) ||
+ ( strstr(ExtensionsString, "GLX_SGIX_fbconfig") ) ) {
+
+ /*
+ // Initialize FBConfig info.
+ // find the set of FBConfigs that are present on all back-end
+ // servers - only those configs will be supported
+ */
+ __glXFBConfigs = (__GLXFBConfig **)malloc( dmxScreen0->numFBConfigs *
+ (numscreens+1) * sizeof(__GLXFBConfig *) );
+ __glXNumFBConfigs = 0;
+
+ for (c=0; c<dmxScreen0->numFBConfigs; c++) {
+ __GLXFBConfig *cfg = NULL;
+
+ if (numscreens > 1) {
+ for (s=1; s<numscreens; s++) {
+ DMXScreenInfo *dmxScreen = &dmxScreens[s];
+ __GLXscreenInfo *glxScreen = &__glXActiveScreens[s];
+
+ cfg = FindMatchingFBConfig( &dmxScreen0->fbconfigs[c],
+ dmxScreen->fbconfigs,
+ dmxScreen->numFBConfigs );
+ __glXFBConfigs[ __glXNumFBConfigs * (numscreens+1) + s + 1 ] = cfg;
+ if (!cfg) {
+ dmxLog(dmxInfo,"screen0 FBConfig 0x%x is missing on screen#%d\n", dmxScreen0->fbconfigs[c].id, s);
+ break;
+ }
+ else {
+ dmxLog(dmxInfo,"screen0 FBConfig 0x%x matched to 0x%x on screen#%d\n", dmxScreen0->fbconfigs[c].id, cfg->id, s);
+ }
+ }
+ }
+ else {
+ cfg = &dmxScreen0->fbconfigs[c];
+ }
+
+ if (cfg) {
+
+ /* filter out overlay visuals */
+ if (cfg->level == 0) {
+ __GLXFBConfig *proxy_cfg;
+
+ __glXFBConfigs[ __glXNumFBConfigs * (numscreens+1) + 1 ] =
+ &dmxScreen0->fbconfigs[c];
+
+ proxy_cfg = malloc( sizeof(__GLXFBConfig) );
+ memcpy( proxy_cfg, cfg, sizeof(__GLXFBConfig) );
+ proxy_cfg->id = FakeClientID(0);
+ /* visual will be associated later in __glXGetFBConfigs */
+ proxy_cfg->associatedVisualId = (unsigned int)-1;
+
+ __glXFBConfigs[ __glXNumFBConfigs * (numscreens+1) + 0 ] = proxy_cfg;
+
+ __glXNumFBConfigs++;
+ }
+
+ }
+
+ }
+
+ }
+
+}
+
+void __glXScreenReset(void)
+{
+ __glXNumActiveScreens = 0;
+}
+
+char *__glXGetServerString( unsigned int name )
+{
+ char *ret = NULL;
+
+ switch( name) {
+
+ case GLX_VENDOR:
+ ret = GLXServerVendorName;
+ break;
+
+ case GLX_VERSION:
+ ret = GLXServerVersion;
+ break;
+
+ case GLX_EXTENSIONS:
+ ret = ExtensionsString;
+ break;
+
+ default:
+ break;
+ }
+
+ return( ret );
+
+}
+
+
+__GLXFBConfig *glxLookupFBConfig( GLXFBConfigID id )
+{
+ int i,j;
+
+ for (i=0, j=0; i<__glXNumFBConfigs; i++,j+=(__glXNumActiveScreens+1) ) {
+ if ( __glXFBConfigs[j]->id == id)
+ return( __glXFBConfigs[j] );
+ }
+
+ return(NULL);
+}
+
+__GLXFBConfig *glxLookupFBConfigByVID( VisualID vid )
+{
+ int i,j;
+
+ for (i=0, j=0; i<__glXNumFBConfigs; i++,j+=(__glXNumActiveScreens+1) ) {
+ if ( __glXFBConfigs[j]->associatedVisualId == vid)
+ return( __glXFBConfigs[j] );
+ }
+
+ return(NULL);
+}
+
+__GLXFBConfig *glxLookupBackEndFBConfig( GLXFBConfigID id, int screen )
+{
+ int i;
+ int j;
+
+ for (i=0, j=0; i<__glXNumFBConfigs; i++,j+=(__glXNumActiveScreens+1) ) {
+ if ( __glXFBConfigs[j]->id == id)
+ return( __glXFBConfigs[j+screen+1] );
+ }
+
+ return(NULL);
+
+}
+
+int glxIsExtensionSupported( char *ext )
+{
+ return( strstr(ExtensionsString, ext) != NULL );
+}
diff --git a/xorg-server/hw/dmx/glxProxy/glxsingle.c b/xorg-server/hw/dmx/glxProxy/glxsingle.c
index dcc604052..19f12ad58 100644
--- a/xorg-server/hw/dmx/glxProxy/glxsingle.c
+++ b/xorg-server/hw/dmx/glxProxy/glxsingle.c
@@ -1,1012 +1,1012 @@
-/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED */
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, 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 including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * 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
- * SILICON GRAPHICS, INC. 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 Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
-
-#include "dmx.h"
-#include "dmxwindow.h"
-#include "dmxpixmap.h"
-#include "dmxfont.h"
-#include "dmxcb.h"
-
-#undef Xmalloc
-#undef Xcalloc
-#undef Xrealloc
-#undef Xfree
-
-#include "glxserver.h"
-#include "glxext.h"
-#include "g_disptab.h"
-/* #include "g_disptab_EXT.h" */
-#include "unpack.h"
-#include "glxutil.h"
-
-#include "GL/glxproto.h"
-
-#ifdef PANORAMIX
-#include "panoramiXsrv.h"
-#endif
-
-/*
- * GetReqSingle - this is the equivalent of GetReq macro
- * from Xlibint.h but it does not set the reqType field (the opcode).
- * this is because the GL single opcodes has different naming convension
- * the other X opcodes (ie. X_GLsop_GetFloatv).
- */
-#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP)
-#define GetReqSingle(name, req) \
- WORD64ALIGN\
- if ((dpy->bufptr + SIZEOF(x##name##Req)) > dpy->bufmax)\
- _XFlush(dpy);\
- req = (x##name##Req *)(dpy->last_req = dpy->bufptr);\
- req->length = (SIZEOF(x##name##Req))>>2;\
- dpy->bufptr += SIZEOF(x##name##Req);\
- dpy->request++
-
-#else /* non-ANSI C uses empty comment instead of "##" for token concatenation */
-#define GetReqSingle(name, req) \
- WORD64ALIGN\
- if ((dpy->bufptr + SIZEOF(x/**/name/**/Req)) > dpy->bufmax)\
- _XFlush(dpy);\
- req = (x/**/name/**/Req *)(dpy->last_req = dpy->bufptr);\
- req->length = (SIZEOF(x/**/name/**/Req))>>2;\
- dpy->bufptr += SIZEOF(x/**/name/**/Req);\
- dpy->request++
-#endif
-
-#define X_GLXSingle 0 /* needed by GetReqExtra */
-
-extern Display *GetBackEndDisplay( __GLXclientState *cl, int s );
-extern int GetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s);
-
-static int swap_vec_element_size = 0;
-
-static void SendSwappedReply( ClientPtr client,
- xGLXSingleReply *reply,
- char *buf,
- int buf_size )
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_SWAP_SHORT(&reply->sequenceNumber);
- __GLX_SWAP_INT(&reply->length);
- __GLX_SWAP_INT(&reply->retval);
- __GLX_SWAP_INT(&reply->size);
-
- if ( (buf_size == 0) && (swap_vec_element_size > 0) ) {
- /*
- * the reply has single component - need to swap pad3
- */
- if (swap_vec_element_size == 2) {
- __GLX_SWAP_SHORT(&reply->pad3);
- }
- else if (swap_vec_element_size == 4) {
- __GLX_SWAP_INT(&reply->pad3);
- __GLX_SWAP_INT(&reply->pad4); /* some requests use also pad4
- * i.e GetConvolutionFilter
- */
- }
- else if (swap_vec_element_size == 8) {
- __GLX_SWAP_DOUBLE(&reply->pad3);
- }
- }
- else if ( (buf_size > 0) && (swap_vec_element_size > 0) ) {
- /*
- * the reply has vector of elements which needs to be swapped
- */
- int vsize = buf_size / swap_vec_element_size;
- char *p = buf;
- int i;
-
- for (i=0; i<vsize; i++) {
- if (swap_vec_element_size == 2) {
- __GLX_SWAP_SHORT(p);
- }
- else if (swap_vec_element_size == 4) {
- __GLX_SWAP_INT(p);
- }
- else if (swap_vec_element_size == 8) {
- __GLX_SWAP_DOUBLE(p);
- }
-
- p += swap_vec_element_size;
- }
-
- /*
- * swap pad words as well - for case that some single reply uses
- * them as well
- */
- __GLX_SWAP_INT(&reply->pad3);
- __GLX_SWAP_INT(&reply->pad4);
- __GLX_SWAP_INT(&reply->pad5);
- __GLX_SWAP_INT(&reply->pad6);
-
- }
-
- WriteToClient(client, sizeof(xGLXSingleReply),(char *)reply);
- if (buf_size > 0)
- WriteToClient(client, buf_size, (char *)buf);
-
-}
-
-int __glXForwardSingleReq( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXSingleReq *req = (xGLXSingleReq *)pc;
- xGLXSingleReq *be_req;
- __GLXcontext *glxc;
- int from_screen = 0;
- int to_screen = 0;
- int buf_size;
- int s;
-
- glxc = __glXLookupContextByTag(cl, req->contextTag);
- if (!glxc) {
- return 0;
- }
- from_screen = to_screen = glxc->pScreen->myNum;
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
- pc += sz_xGLXSingleReq;
- buf_size = (req->length << 2) - sz_xGLXSingleReq;
-
- /*
- * just forward the request to back-end server(s)
- */
- for (s=from_screen; s<=to_screen; s++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
- Display *dpy = GetBackEndDisplay(cl,s);
-
- LockDisplay(dpy);
- GetReqSingle(GLXSingle,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = req->glxCode;
- be_req->length = req->length;
- be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s);
- if (buf_size > 0)
- _XSend(dpy, (const char *)pc, buf_size);
- UnlockDisplay(dpy);
- SyncHandle();
-
- if (req->glxCode == X_GLsop_Flush) {
- XFlush(dpy);
- }
-
- }
-
- return Success;
-}
-
-int __glXForwardPipe0WithReply( __GLXclientState *cl, GLbyte *pc )
-{
- ClientPtr client = cl->client;
- xGLXSingleReq *req = (xGLXSingleReq *)pc;
- xGLXSingleReq *be_req;
- xGLXSingleReply reply;
- xGLXSingleReply be_reply;
- __GLXcontext *glxc;
- int buf_size;
- char *be_buf;
- int be_buf_size;
- DMXScreenInfo *dmxScreen;
- Display *dpy;
-
- glxc = __glXLookupContextByTag(cl, req->contextTag);
- if (!glxc) {
- return __glXBadContext;
- }
-
- pc += sz_xGLXSingleReq;
- buf_size = (req->length << 2) - sz_xGLXSingleReq;
-
- dmxScreen = &dmxScreens[glxc->pScreen->myNum];
- dpy = GetBackEndDisplay(cl, glxc->pScreen->myNum);
-
- /*
- * send the request to the first back-end server
- */
- LockDisplay(dpy);
- GetReqSingle(GLXSingle,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = req->glxCode;
- be_req->length = req->length;
- be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,glxc->pScreen->myNum);
- if (buf_size > 0)
- _XSend(dpy, (const char *)pc, buf_size);
-
- /*
- * get the reply from the back-end server
- */
- _XReply(dpy, (xReply*) &be_reply, 0, False);
- be_buf_size = be_reply.length << 2;
- if (be_buf_size > 0) {
- be_buf = (char *)Xalloc( be_buf_size );
- if (be_buf) {
- _XRead(dpy, be_buf, be_buf_size);
- }
- else {
- /* Throw data on the floor */
- _XEatData(dpy, be_buf_size);
- return BadAlloc;
- }
- }
-
- UnlockDisplay(dpy);
- SyncHandle();
-
- /*
- * send the reply to the client
- */
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
- reply.length = be_reply.length;
- reply.retval = be_reply.retval;
- reply.size = be_reply.size;
- reply.pad3 = be_reply.pad3;
- reply.pad4 = be_reply.pad4;
-
- if (client->swapped) {
- SendSwappedReply( client, &reply, be_buf, be_buf_size );
- }
- else {
- WriteToClient(client, sizeof(xGLXSingleReply),(char *)&reply);
- if (be_buf_size > 0)
- WriteToClient(client, be_buf_size, (char *)be_buf);
- }
-
- if (be_buf_size > 0) Xfree(be_buf);
-
- return Success;
-}
-
-int __glXForwardAllWithReply( __GLXclientState *cl, GLbyte *pc )
-{
- ClientPtr client = cl->client;
- xGLXSingleReq *req = (xGLXSingleReq *)pc;
- xGLXSingleReq *be_req;
- xGLXSingleReply reply;
- xGLXSingleReply be_reply;
- __GLXcontext *glxc;
- int buf_size;
- char *be_buf;
- int be_buf_size;
- int from_screen = 0;
- int to_screen = 0;
- int s;
-
- DMXScreenInfo *dmxScreen;
- Display *dpy;
-
- glxc = __glXLookupContextByTag(cl, req->contextTag);
- if (!glxc) {
- return 0;
- }
- from_screen = to_screen = glxc->pScreen->myNum;
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
- pc += sz_xGLXSingleReq;
- buf_size = (req->length << 2) - sz_xGLXSingleReq;
-
- /*
- * send the request to the first back-end server(s)
- */
- for (s=to_screen; s>=from_screen; s--) {
- dmxScreen = &dmxScreens[s];
- dpy = GetBackEndDisplay(cl,s);
-
- LockDisplay(dpy);
- GetReqSingle(GLXSingle,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = req->glxCode;
- be_req->length = req->length;
- be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s);
- if (buf_size > 0)
- _XSend(dpy, (const char *)pc, buf_size);
-
- /*
- * get the reply from the back-end server
- */
- _XReply(dpy, (xReply*) &be_reply, 0, False);
- be_buf_size = be_reply.length << 2;
- if (be_buf_size > 0) {
- be_buf = (char *)Xalloc( be_buf_size );
- if (be_buf) {
- _XRead(dpy, be_buf, be_buf_size);
- }
- else {
- /* Throw data on the floor */
- _XEatData(dpy, be_buf_size);
- return BadAlloc;
- }
- }
-
- UnlockDisplay(dpy);
- SyncHandle();
-
- if (s > from_screen && be_buf_size > 0) {
- Xfree(be_buf);
- }
- }
-
- /*
- * send the reply to the client
- */
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
- reply.length = be_reply.length;
- reply.retval = be_reply.retval;
- reply.size = be_reply.size;
- reply.pad3 = be_reply.pad3;
- reply.pad4 = be_reply.pad4;
-
- if (client->swapped) {
- SendSwappedReply( client, &reply, be_buf, be_buf_size );
- }
- else {
- WriteToClient(client, sizeof(xGLXSingleReply),(char *)&reply);
- if (be_buf_size > 0)
- WriteToClient(client, be_buf_size, (char *)be_buf);
- }
-
- if (be_buf_size > 0) Xfree(be_buf);
-
- return Success;
-}
-
-int __glXForwardSingleReqSwap( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXSingleReq *req = (xGLXSingleReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 0;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXSingleReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXSingleReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
- return( __glXForwardSingleReq( cl, pc ) );
-}
-
-int __glXForwardPipe0WithReplySwap( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXSingleReq *req = (xGLXSingleReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 0;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXSingleReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXSingleReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
- return( __glXForwardPipe0WithReply( cl, pc ) );
-}
-
-int __glXForwardPipe0WithReplySwapsv( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXSingleReq *req = (xGLXSingleReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 2;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXSingleReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXSingleReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
-
- return( __glXForwardPipe0WithReply( cl, pc ) );
-}
-
-int __glXForwardPipe0WithReplySwapiv( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXSingleReq *req = (xGLXSingleReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 4;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXSingleReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXSingleReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
-
- return( __glXForwardPipe0WithReply( cl, pc ) );
-}
-
-int __glXForwardPipe0WithReplySwapdv( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXSingleReq *req = (xGLXSingleReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 8;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXSingleReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXSingleReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
-
- return( __glXForwardPipe0WithReply( cl, pc ) );
-}
-
-int __glXForwardAllWithReplySwap( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXSingleReq *req = (xGLXSingleReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 0;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXSingleReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXSingleReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
-
- return( __glXForwardAllWithReply( cl, pc ) );
-}
-
-int __glXForwardAllWithReplySwapsv( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXSingleReq *req = (xGLXSingleReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 2;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXSingleReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXSingleReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
-
- return( __glXForwardAllWithReply( cl, pc ) );
-}
-
-int __glXForwardAllWithReplySwapiv( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXSingleReq *req = (xGLXSingleReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 4;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXSingleReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXSingleReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
-
- return( __glXForwardAllWithReply( cl, pc ) );
-}
-
-int __glXForwardAllWithReplySwapdv( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXSingleReq *req = (xGLXSingleReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 8;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXSingleReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXSingleReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
-
- return( __glXForwardAllWithReply( cl, pc ) );
-}
-
-static GLint __glReadPixels_size(GLenum format, GLenum type, GLint w, GLint h,
- int *elementbits_return, int *rowbytes_return )
-{
- GLint elements, esize;
- GLint rowsize, padding;
-
- if (w < 0 || h < 0) {
- return -1;
- }
- switch (format) {
- case GL_COLOR_INDEX:
- case GL_STENCIL_INDEX:
- case GL_DEPTH_COMPONENT:
- elements = 1;
- break;
- case GL_RED:
- case GL_GREEN:
- case GL_BLUE:
- case GL_ALPHA:
- case GL_LUMINANCE:
- elements = 1;
- break;
- case GL_LUMINANCE_ALPHA:
- elements = 2;
- break;
- case GL_RGB:
- case GL_BGR:
- elements = 3;
- break;
- case GL_RGBA:
- case GL_BGRA:
- case GL_ABGR_EXT:
- elements = 4;
- break;
- default:
- return -1;
- }
- /*
- ** According to the GLX protocol, each row must be padded to a multiple of
- ** 4 bytes. 4 bytes also happens to be the default alignment in the pixel
- ** store modes of the GL.
- */
- switch (type) {
- case GL_BITMAP:
- if (format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX) {
- rowsize = ((w * elements)+7)/8;
- padding = rowsize % 4;
- if (padding) {
- rowsize += 4 - padding;
- }
- if (elementbits_return) *elementbits_return = elements;
- if (rowbytes_return) *rowbytes_return = rowsize;
- return (rowsize * h);
- } else {
- return -1;
- }
- case GL_BYTE:
- case GL_UNSIGNED_BYTE:
- esize = 1;
- break;
- case GL_UNSIGNED_BYTE_3_3_2:
- case GL_UNSIGNED_BYTE_2_3_3_REV:
- esize = 1;
- elements = 1;
- break;
- case GL_SHORT:
- case GL_UNSIGNED_SHORT:
- esize = 2;
- break;
- case GL_UNSIGNED_SHORT_5_6_5:
- case GL_UNSIGNED_SHORT_5_6_5_REV:
- case GL_UNSIGNED_SHORT_4_4_4_4:
- case GL_UNSIGNED_SHORT_4_4_4_4_REV:
- case GL_UNSIGNED_SHORT_5_5_5_1:
- case GL_UNSIGNED_SHORT_1_5_5_5_REV:
- esize = 2;
- elements = 1;
- break;
- case GL_INT:
- case GL_UNSIGNED_INT:
- case GL_FLOAT:
- esize = 4;
- break;
- case GL_UNSIGNED_INT_8_8_8_8:
- case GL_UNSIGNED_INT_8_8_8_8_REV:
- case GL_UNSIGNED_INT_10_10_10_2:
- case GL_UNSIGNED_INT_2_10_10_10_REV:
- esize = 4;
- elements = 1;
- break;
- default:
- return -1;
- }
- rowsize = w * elements * esize;
- padding = rowsize % 4;
- if (padding) {
- rowsize += 4 - padding;
- }
-
- if (elementbits_return) *elementbits_return = esize*elements*8;
- if (rowbytes_return) *rowbytes_return = rowsize;
-
- return (rowsize * h);
-}
-
-static int intersectRect( int x1, int x2, int y1, int y2,
- int X1, int X2, int Y1, int Y2,
- int *ix1, int *ix2, int *iy1, int *iy2 )
-{
- int right = (x2 < X2 ? x2 : X2);
- int bottom = (y2 < Y2 ? y2 : Y2);
- int left = (x1 > X1 ? x1 : X1);
- int top = (y1 > Y1 ? y1 : Y1);
- int width = right - left + 1;
- int height = bottom - top + 1;
-
- if ( (width <= 0) || (height <= 0) ) {
- *ix1 = *ix2 = *iy1 = *iy2 = 0;
- return(0);
- }
- else {
- *ix1 = left;
- *ix2 = right;
- *iy1 = top;
- *iy2 = bottom;
- return( width * height );
- }
-
-}
-
-int __glXDisp_ReadPixels(__GLXclientState *cl, GLbyte *pc)
-{
- xGLXSingleReq *req = (xGLXSingleReq *)pc;
- xGLXSingleReq *be_req;
- xGLXReadPixelsReply reply;
- xGLXReadPixelsReply be_reply;
- GLbyte *be_pc;
- GLint x,y;
- GLsizei width, height;
- GLenum format, type;
- GLboolean swapBytes, lsbFirst;
- ClientPtr client = cl->client;
- DrawablePtr pDraw;
- int error;
- __GLXcontext *glxc;
- int from_screen = 0;
- int to_screen = 0;
- char *buf;
- int buf_size;
- int s;
- int win_x1, win_x2;
- int win_y1, win_y2;
- int ebits, rowsize;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- if (client->swapped) {
- __GLX_SWAP_INT(&req->contextTag);
- }
-
- glxc = __glXLookupContextByTag(cl, req->contextTag);
- if (!glxc) {
- return 0;
- }
- from_screen = to_screen = glxc->pScreen->myNum;
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
- pc += sz_xGLXSingleReq;
- x = *(GLint *)(pc + 0);
- y = *(GLint *)(pc + 4);
- width = *(GLsizei *)(pc + 8);
- height = *(GLsizei *)(pc + 12);
- format = *(GLenum *)(pc + 16);
- type = *(GLenum *)(pc + 20);
- swapBytes = *(GLboolean *)(pc + 24);
- lsbFirst = *(GLboolean *)(pc + 25);
-
- if (client->swapped) {
- __GLX_SWAP_INT(&x);
- __GLX_SWAP_INT(&y);
- __GLX_SWAP_INT(&width);
- __GLX_SWAP_INT(&height);
- __GLX_SWAP_INT(&format);
- __GLX_SWAP_INT(&type);
- swapBytes = !swapBytes;
- }
-
- buf_size = __glReadPixels_size(format,type,width,height, &ebits, &rowsize);
- if (buf_size > 0) {
- buf = (char *) Xalloc( buf_size );
- if ( !buf ) {
- return( BadAlloc );
- }
- }
- else {
- buf_size = 0;
- }
-
- if (buf_size > 0) {
- /*
- * Get the current drawable this context is bound to
- */
- pDraw = __glXLookupDrawableByTag( cl, req->contextTag );
- win_x1 = pDraw->x + x;
- win_x2 = win_x1 + width - 1;
- win_y1 = (dmxGlobalHeight - pDraw->y - pDraw->height) + y;
- win_y2 = win_y1 + height - 1;
- if (pDraw->type != DRAWABLE_WINDOW) {
- from_screen = to_screen = 0;
- }
-
- for (s=from_screen; s<=to_screen; s++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
- Display *dpy = GetBackEndDisplay(cl,s);
- int scr_x1 = dmxScreen->rootXOrigin;
- int scr_x2 = dmxScreen->rootXOrigin + dmxScreen->scrnWidth - 1;
- int scr_y1 = dmxScreen->rootYOrigin;
- int scr_y2 = dmxScreen->rootYOrigin + dmxScreen->scrnHeight - 1;
- int wx1, wx2, wy1, wy2;
- int sx, sy, sw, sh;
- int npixels;
-
- /*
- * find the window portion that is on the current screen
- */
- if (pDraw->type == DRAWABLE_WINDOW) {
- npixels = intersectRect( scr_x1, scr_x2, scr_y1, scr_y2,
- win_x1, win_x2, win_y1, win_y2,
- &wx1, &wx2, &wy1, &wy2 );
- }
- else {
- wx1 = win_x1;
- wx2 = win_x2;
- wy1 = win_y1;
- wy2 = win_y2;
- npixels = (wx2-wx1+1) * (wy2-wy1+1);
- }
-
- if (npixels > 0) {
-
- /* send the request to the back-end server */
- LockDisplay(dpy);
- GetReqExtra(GLXSingle,__GLX_PAD(26),be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = X_GLsop_ReadPixels;
- be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s);
- be_pc = ((GLbyte *)(be_req) + sz_xGLXSingleReq);
-
- sx = wx1 - pDraw->x;
- sy = wy1 - (dmxGlobalHeight - pDraw->y - pDraw->height);
- sw = (wx2-wx1+1);
- sh = (wy2-wy1+1);
-
- *(GLint *)(be_pc + 0) = sx; /* x */
- *(GLint *)(be_pc + 4) = sy; /* y */
- *(GLsizei *)(be_pc + 8) = sw; /* width */
- *(GLsizei *)(be_pc + 12) = sh; /* height */
- *(GLenum *)(be_pc + 16) = format;
- *(GLenum *)(be_pc + 20) = type;
- *(GLboolean *)(be_pc + 24) = swapBytes;
- *(GLboolean *)(be_pc + 25) = lsbFirst;
-
- _XReply(dpy, (xReply*) &be_reply, 0, False);
-
- if (be_reply.length > 0) {
- char *be_buf;
- int be_buf_size = be_reply.length << 2;
-
- be_buf = (char *) Xalloc( be_buf_size );
- if (be_buf) {
- _XRead(dpy, be_buf, be_buf_size);
-
- /* copy pixels data to the right location of the */
- /* reply buffer */
- if ( type != GL_BITMAP ) {
- int pbytes = ebits / 8;
- char *dst = buf + (sy-y)*rowsize + (sx-x)*pbytes;
- char *src = be_buf;
- int pad = (pbytes * sw) % 4;
- int r;
-
- for (r=0; r<sh; r++) {
- memcpy( dst, src, pbytes*sw );
- dst += rowsize;
- src += (pbytes*sw + (pad ? 4-pad : 0) );
- }
- }
- else {
- /* this is a GL_BITMAP pixel type, should copy bits */
- int r;
- int src_rowsize = bits_to_bytes(sw * ebits);
- int src_pad = src_rowsize % 4;
- if ( src_pad ) {
- src_rowsize += (4 - src_pad);
- }
-
- for (r=0; r<sh; r++) {
- unsigned char dst_mask = 0x80 >> (sx % 8);
- unsigned char src_mask = 0x80;
- char *dst = buf + (sy-y+r)*rowsize + (sx-x)/8;
- char *src = be_buf + r*src_rowsize;
- int b;
-
- for (b=0; b<sw*ebits; b++) {
- if ( *src & src_mask ) {
- *dst |= dst_mask;
- }
- else {
- *dst &= ~dst_mask;
- }
-
- if (dst_mask > 1) dst_mask >>= 1;
- else {
- dst_mask = 0x80;
- dst++;
- }
-
- if (src_mask > 1) src_mask >>= 1;
- else {
- src_mask = 0x80;
- src++;
- }
- }
- }
-
- }
-
- Xfree( be_buf );
- }
- else {
- /* Throw data on the floor */
- _XEatData(dpy, be_buf_size);
- Xfree( buf );
- return BadAlloc;
- }
- }
-
- UnlockDisplay(dpy);
- SyncHandle();
-
- } /* of npixels > 0 */
-
- } /* of for loop */
-
- } /* of if buf_size > 0 */
-
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
- reply.length = buf_size >> 2;
-
- if (client->swapped) {
- __GLX_SWAP_SHORT(&reply.sequenceNumber);
- __GLX_SWAP_INT(&reply.length);
- }
-
- WriteToClient(client, sizeof(xGLXReadPixelsReply),(char *)&reply);
- if (buf_size > 0) {
- WriteToClient(client, buf_size, (char *)buf);
- Xfree( buf );
- }
-
- return Success;
-}
-
-int __glXDispSwap_GetTexImage(__GLXclientState *cl, GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- GLbyte *lpc = pc;
-
- lpc += sz_xGLXSingleReq;
- __GLX_SWAP_INT(lpc+0);
- __GLX_SWAP_INT(lpc+4);
- __GLX_SWAP_INT(lpc+8);
- __GLX_SWAP_INT(lpc+12);
-
- /* reverse swapBytes */
- *(GLboolean *)(lpc + 16) = ! *(GLboolean *)(lpc + 16);
-
- return( __glXForwardPipe0WithReplySwap( cl, pc ) );
-}
-
-int __glXDispSwap_GetColorTable(__GLXclientState *cl, GLbyte *pc)
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- GLbyte *lpc = pc;
-
- lpc += sz_xGLXSingleReq;
- __GLX_SWAP_INT(lpc+0);
- __GLX_SWAP_INT(lpc+4);
- __GLX_SWAP_INT(lpc+8);
-
- /* reverse swapBytes */
- *(GLboolean *)(lpc + 12) = ! *(GLboolean *)(lpc + 12);
-
- return( __glXForwardPipe0WithReplySwap( cl, pc ) );
-}
-
-
+/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED */
+/*
+ * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
+ * Copyright (C) 1991-2000 Silicon Graphics, 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 including the dates of first publication and
+ * either this permission notice or a reference to
+ * http://oss.sgi.com/projects/FreeB/
+ * 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
+ * SILICON GRAPHICS, INC. 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 Silicon Graphics, Inc.
+ * shall not be used in advertising or otherwise to promote the sale, use or
+ * other dealings in this Software without prior written authorization from
+ * Silicon Graphics, Inc.
+ */
+
+#ifdef HAVE_DMX_CONFIG_H
+#include <dmx-config.h>
+#endif
+
+#include "dmx.h"
+#include "dmxwindow.h"
+#include "dmxpixmap.h"
+#include "dmxfont.h"
+#include "dmxcb.h"
+
+#undef Xmalloc
+#undef Xcalloc
+#undef Xrealloc
+#undef Xfree
+
+#include "glxserver.h"
+#include "glxext.h"
+#include "g_disptab.h"
+/* #include "g_disptab_EXT.h" */
+#include "unpack.h"
+#include "glxutil.h"
+
+#include "GL/glxproto.h"
+
+#ifdef PANORAMIX
+#include "panoramiXsrv.h"
+#endif
+
+/*
+ * GetReqSingle - this is the equivalent of GetReq macro
+ * from Xlibint.h but it does not set the reqType field (the opcode).
+ * this is because the GL single opcodes has different naming convension
+ * the other X opcodes (ie. X_GLsop_GetFloatv).
+ */
+#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP)
+#define GetReqSingle(name, req) \
+ WORD64ALIGN\
+ if ((dpy->bufptr + SIZEOF(x##name##Req)) > dpy->bufmax)\
+ _XFlush(dpy);\
+ req = (x##name##Req *)(dpy->last_req = dpy->bufptr);\
+ req->length = (SIZEOF(x##name##Req))>>2;\
+ dpy->bufptr += SIZEOF(x##name##Req);\
+ dpy->request++
+
+#else /* non-ANSI C uses empty comment instead of "##" for token concatenation */
+#define GetReqSingle(name, req) \
+ WORD64ALIGN\
+ if ((dpy->bufptr + SIZEOF(x/**/name/**/Req)) > dpy->bufmax)\
+ _XFlush(dpy);\
+ req = (x/**/name/**/Req *)(dpy->last_req = dpy->bufptr);\
+ req->length = (SIZEOF(x/**/name/**/Req))>>2;\
+ dpy->bufptr += SIZEOF(x/**/name/**/Req);\
+ dpy->request++
+#endif
+
+#define X_GLXSingle 0 /* needed by GetReqExtra */
+
+extern Display *GetBackEndDisplay( __GLXclientState *cl, int s );
+extern int GetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s);
+
+static int swap_vec_element_size = 0;
+
+static void SendSwappedReply( ClientPtr client,
+ xGLXSingleReply *reply,
+ char *buf,
+ int buf_size )
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_SWAP_SHORT(&reply->sequenceNumber);
+ __GLX_SWAP_INT(&reply->length);
+ __GLX_SWAP_INT(&reply->retval);
+ __GLX_SWAP_INT(&reply->size);
+
+ if ( (buf_size == 0) && (swap_vec_element_size > 0) ) {
+ /*
+ * the reply has single component - need to swap pad3
+ */
+ if (swap_vec_element_size == 2) {
+ __GLX_SWAP_SHORT(&reply->pad3);
+ }
+ else if (swap_vec_element_size == 4) {
+ __GLX_SWAP_INT(&reply->pad3);
+ __GLX_SWAP_INT(&reply->pad4); /* some requests use also pad4
+ * i.e GetConvolutionFilter
+ */
+ }
+ else if (swap_vec_element_size == 8) {
+ __GLX_SWAP_DOUBLE(&reply->pad3);
+ }
+ }
+ else if ( (buf_size > 0) && (swap_vec_element_size > 0) ) {
+ /*
+ * the reply has vector of elements which needs to be swapped
+ */
+ int vsize = buf_size / swap_vec_element_size;
+ char *p = buf;
+ int i;
+
+ for (i=0; i<vsize; i++) {
+ if (swap_vec_element_size == 2) {
+ __GLX_SWAP_SHORT(p);
+ }
+ else if (swap_vec_element_size == 4) {
+ __GLX_SWAP_INT(p);
+ }
+ else if (swap_vec_element_size == 8) {
+ __GLX_SWAP_DOUBLE(p);
+ }
+
+ p += swap_vec_element_size;
+ }
+
+ /*
+ * swap pad words as well - for case that some single reply uses
+ * them as well
+ */
+ __GLX_SWAP_INT(&reply->pad3);
+ __GLX_SWAP_INT(&reply->pad4);
+ __GLX_SWAP_INT(&reply->pad5);
+ __GLX_SWAP_INT(&reply->pad6);
+
+ }
+
+ WriteToClient(client, sizeof(xGLXSingleReply),(char *)reply);
+ if (buf_size > 0)
+ WriteToClient(client, buf_size, (char *)buf);
+
+}
+
+int __glXForwardSingleReq( __GLXclientState *cl, GLbyte *pc )
+{
+ xGLXSingleReq *req = (xGLXSingleReq *)pc;
+ xGLXSingleReq *be_req;
+ __GLXcontext *glxc;
+ int from_screen = 0;
+ int to_screen = 0;
+ int buf_size;
+ int s;
+
+ glxc = __glXLookupContextByTag(cl, req->contextTag);
+ if (!glxc) {
+ return 0;
+ }
+ from_screen = to_screen = glxc->pScreen->myNum;
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ from_screen = 0;
+ to_screen = screenInfo.numScreens - 1;
+ }
+#endif
+
+ pc += sz_xGLXSingleReq;
+ buf_size = (req->length << 2) - sz_xGLXSingleReq;
+
+ /*
+ * just forward the request to back-end server(s)
+ */
+ for (s=from_screen; s<=to_screen; s++) {
+ DMXScreenInfo *dmxScreen = &dmxScreens[s];
+ Display *dpy = GetBackEndDisplay(cl,s);
+
+ LockDisplay(dpy);
+ GetReqSingle(GLXSingle,be_req);
+ be_req->reqType = dmxScreen->glxMajorOpcode;
+ be_req->glxCode = req->glxCode;
+ be_req->length = req->length;
+ be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s);
+ if (buf_size > 0)
+ _XSend(dpy, (const char *)pc, buf_size);
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ if (req->glxCode == X_GLsop_Flush) {
+ XFlush(dpy);
+ }
+
+ }
+
+ return Success;
+}
+
+int __glXForwardPipe0WithReply( __GLXclientState *cl, GLbyte *pc )
+{
+ ClientPtr client = cl->client;
+ xGLXSingleReq *req = (xGLXSingleReq *)pc;
+ xGLXSingleReq *be_req;
+ xGLXSingleReply reply;
+ xGLXSingleReply be_reply;
+ __GLXcontext *glxc;
+ int buf_size;
+ char *be_buf;
+ int be_buf_size;
+ DMXScreenInfo *dmxScreen;
+ Display *dpy;
+
+ glxc = __glXLookupContextByTag(cl, req->contextTag);
+ if (!glxc) {
+ return __glXBadContext;
+ }
+
+ pc += sz_xGLXSingleReq;
+ buf_size = (req->length << 2) - sz_xGLXSingleReq;
+
+ dmxScreen = &dmxScreens[glxc->pScreen->myNum];
+ dpy = GetBackEndDisplay(cl, glxc->pScreen->myNum);
+
+ /*
+ * send the request to the first back-end server
+ */
+ LockDisplay(dpy);
+ GetReqSingle(GLXSingle,be_req);
+ be_req->reqType = dmxScreen->glxMajorOpcode;
+ be_req->glxCode = req->glxCode;
+ be_req->length = req->length;
+ be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,glxc->pScreen->myNum);
+ if (buf_size > 0)
+ _XSend(dpy, (const char *)pc, buf_size);
+
+ /*
+ * get the reply from the back-end server
+ */
+ _XReply(dpy, (xReply*) &be_reply, 0, False);
+ be_buf_size = be_reply.length << 2;
+ if (be_buf_size > 0) {
+ be_buf = (char *)malloc( be_buf_size );
+ if (be_buf) {
+ _XRead(dpy, be_buf, be_buf_size);
+ }
+ else {
+ /* Throw data on the floor */
+ _XEatData(dpy, be_buf_size);
+ return BadAlloc;
+ }
+ }
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ /*
+ * send the reply to the client
+ */
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.length = be_reply.length;
+ reply.retval = be_reply.retval;
+ reply.size = be_reply.size;
+ reply.pad3 = be_reply.pad3;
+ reply.pad4 = be_reply.pad4;
+
+ if (client->swapped) {
+ SendSwappedReply( client, &reply, be_buf, be_buf_size );
+ }
+ else {
+ WriteToClient(client, sizeof(xGLXSingleReply),(char *)&reply);
+ if (be_buf_size > 0)
+ WriteToClient(client, be_buf_size, (char *)be_buf);
+ }
+
+ if (be_buf_size > 0) Xfree(be_buf);
+
+ return Success;
+}
+
+int __glXForwardAllWithReply( __GLXclientState *cl, GLbyte *pc )
+{
+ ClientPtr client = cl->client;
+ xGLXSingleReq *req = (xGLXSingleReq *)pc;
+ xGLXSingleReq *be_req;
+ xGLXSingleReply reply;
+ xGLXSingleReply be_reply;
+ __GLXcontext *glxc;
+ int buf_size;
+ char *be_buf;
+ int be_buf_size;
+ int from_screen = 0;
+ int to_screen = 0;
+ int s;
+
+ DMXScreenInfo *dmxScreen;
+ Display *dpy;
+
+ glxc = __glXLookupContextByTag(cl, req->contextTag);
+ if (!glxc) {
+ return 0;
+ }
+ from_screen = to_screen = glxc->pScreen->myNum;
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ from_screen = 0;
+ to_screen = screenInfo.numScreens - 1;
+ }
+#endif
+
+ pc += sz_xGLXSingleReq;
+ buf_size = (req->length << 2) - sz_xGLXSingleReq;
+
+ /*
+ * send the request to the first back-end server(s)
+ */
+ for (s=to_screen; s>=from_screen; s--) {
+ dmxScreen = &dmxScreens[s];
+ dpy = GetBackEndDisplay(cl,s);
+
+ LockDisplay(dpy);
+ GetReqSingle(GLXSingle,be_req);
+ be_req->reqType = dmxScreen->glxMajorOpcode;
+ be_req->glxCode = req->glxCode;
+ be_req->length = req->length;
+ be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s);
+ if (buf_size > 0)
+ _XSend(dpy, (const char *)pc, buf_size);
+
+ /*
+ * get the reply from the back-end server
+ */
+ _XReply(dpy, (xReply*) &be_reply, 0, False);
+ be_buf_size = be_reply.length << 2;
+ if (be_buf_size > 0) {
+ be_buf = (char *)malloc( be_buf_size );
+ if (be_buf) {
+ _XRead(dpy, be_buf, be_buf_size);
+ }
+ else {
+ /* Throw data on the floor */
+ _XEatData(dpy, be_buf_size);
+ return BadAlloc;
+ }
+ }
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ if (s > from_screen && be_buf_size > 0) {
+ Xfree(be_buf);
+ }
+ }
+
+ /*
+ * send the reply to the client
+ */
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.length = be_reply.length;
+ reply.retval = be_reply.retval;
+ reply.size = be_reply.size;
+ reply.pad3 = be_reply.pad3;
+ reply.pad4 = be_reply.pad4;
+
+ if (client->swapped) {
+ SendSwappedReply( client, &reply, be_buf, be_buf_size );
+ }
+ else {
+ WriteToClient(client, sizeof(xGLXSingleReply),(char *)&reply);
+ if (be_buf_size > 0)
+ WriteToClient(client, be_buf_size, (char *)be_buf);
+ }
+
+ if (be_buf_size > 0) Xfree(be_buf);
+
+ return Success;
+}
+
+int __glXForwardSingleReqSwap( __GLXclientState *cl, GLbyte *pc )
+{
+ xGLXSingleReq *req = (xGLXSingleReq *)pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->contextTag);
+
+ swap_vec_element_size = 0;
+
+ /*
+ * swap extra data in request - assuming all data
+ * (if available) are arrays of 4 bytes components !
+ */
+ if (req->length > sz_xGLXSingleReq/4) {
+ int *data = (int *)(req+1);
+ int count = req->length - sz_xGLXSingleReq/4;
+ __GLX_SWAP_INT_ARRAY(data, count );
+ }
+
+ return( __glXForwardSingleReq( cl, pc ) );
+}
+
+int __glXForwardPipe0WithReplySwap( __GLXclientState *cl, GLbyte *pc )
+{
+ xGLXSingleReq *req = (xGLXSingleReq *)pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->contextTag);
+
+ swap_vec_element_size = 0;
+
+ /*
+ * swap extra data in request - assuming all data
+ * (if available) are arrays of 4 bytes components !
+ */
+ if (req->length > sz_xGLXSingleReq/4) {
+ int *data = (int *)(req+1);
+ int count = req->length - sz_xGLXSingleReq/4;
+ __GLX_SWAP_INT_ARRAY(data, count );
+ }
+
+ return( __glXForwardPipe0WithReply( cl, pc ) );
+}
+
+int __glXForwardPipe0WithReplySwapsv( __GLXclientState *cl, GLbyte *pc )
+{
+ xGLXSingleReq *req = (xGLXSingleReq *)pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->contextTag);
+
+ swap_vec_element_size = 2;
+
+ /*
+ * swap extra data in request - assuming all data
+ * (if available) are arrays of 4 bytes components !
+ */
+ if (req->length > sz_xGLXSingleReq/4) {
+ int *data = (int *)(req+1);
+ int count = req->length - sz_xGLXSingleReq/4;
+ __GLX_SWAP_INT_ARRAY(data, count );
+ }
+
+
+ return( __glXForwardPipe0WithReply( cl, pc ) );
+}
+
+int __glXForwardPipe0WithReplySwapiv( __GLXclientState *cl, GLbyte *pc )
+{
+ xGLXSingleReq *req = (xGLXSingleReq *)pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->contextTag);
+
+ swap_vec_element_size = 4;
+
+ /*
+ * swap extra data in request - assuming all data
+ * (if available) are arrays of 4 bytes components !
+ */
+ if (req->length > sz_xGLXSingleReq/4) {
+ int *data = (int *)(req+1);
+ int count = req->length - sz_xGLXSingleReq/4;
+ __GLX_SWAP_INT_ARRAY(data, count );
+ }
+
+
+ return( __glXForwardPipe0WithReply( cl, pc ) );
+}
+
+int __glXForwardPipe0WithReplySwapdv( __GLXclientState *cl, GLbyte *pc )
+{
+ xGLXSingleReq *req = (xGLXSingleReq *)pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->contextTag);
+
+ swap_vec_element_size = 8;
+
+ /*
+ * swap extra data in request - assuming all data
+ * (if available) are arrays of 4 bytes components !
+ */
+ if (req->length > sz_xGLXSingleReq/4) {
+ int *data = (int *)(req+1);
+ int count = req->length - sz_xGLXSingleReq/4;
+ __GLX_SWAP_INT_ARRAY(data, count );
+ }
+
+
+ return( __glXForwardPipe0WithReply( cl, pc ) );
+}
+
+int __glXForwardAllWithReplySwap( __GLXclientState *cl, GLbyte *pc )
+{
+ xGLXSingleReq *req = (xGLXSingleReq *)pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->contextTag);
+
+ swap_vec_element_size = 0;
+
+ /*
+ * swap extra data in request - assuming all data
+ * (if available) are arrays of 4 bytes components !
+ */
+ if (req->length > sz_xGLXSingleReq/4) {
+ int *data = (int *)(req+1);
+ int count = req->length - sz_xGLXSingleReq/4;
+ __GLX_SWAP_INT_ARRAY(data, count );
+ }
+
+
+ return( __glXForwardAllWithReply( cl, pc ) );
+}
+
+int __glXForwardAllWithReplySwapsv( __GLXclientState *cl, GLbyte *pc )
+{
+ xGLXSingleReq *req = (xGLXSingleReq *)pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->contextTag);
+
+ swap_vec_element_size = 2;
+
+ /*
+ * swap extra data in request - assuming all data
+ * (if available) are arrays of 4 bytes components !
+ */
+ if (req->length > sz_xGLXSingleReq/4) {
+ int *data = (int *)(req+1);
+ int count = req->length - sz_xGLXSingleReq/4;
+ __GLX_SWAP_INT_ARRAY(data, count );
+ }
+
+
+ return( __glXForwardAllWithReply( cl, pc ) );
+}
+
+int __glXForwardAllWithReplySwapiv( __GLXclientState *cl, GLbyte *pc )
+{
+ xGLXSingleReq *req = (xGLXSingleReq *)pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->contextTag);
+
+ swap_vec_element_size = 4;
+
+ /*
+ * swap extra data in request - assuming all data
+ * (if available) are arrays of 4 bytes components !
+ */
+ if (req->length > sz_xGLXSingleReq/4) {
+ int *data = (int *)(req+1);
+ int count = req->length - sz_xGLXSingleReq/4;
+ __GLX_SWAP_INT_ARRAY(data, count );
+ }
+
+
+ return( __glXForwardAllWithReply( cl, pc ) );
+}
+
+int __glXForwardAllWithReplySwapdv( __GLXclientState *cl, GLbyte *pc )
+{
+ xGLXSingleReq *req = (xGLXSingleReq *)pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->contextTag);
+
+ swap_vec_element_size = 8;
+
+ /*
+ * swap extra data in request - assuming all data
+ * (if available) are arrays of 4 bytes components !
+ */
+ if (req->length > sz_xGLXSingleReq/4) {
+ int *data = (int *)(req+1);
+ int count = req->length - sz_xGLXSingleReq/4;
+ __GLX_SWAP_INT_ARRAY(data, count );
+ }
+
+
+ return( __glXForwardAllWithReply( cl, pc ) );
+}
+
+static GLint __glReadPixels_size(GLenum format, GLenum type, GLint w, GLint h,
+ int *elementbits_return, int *rowbytes_return )
+{
+ GLint elements, esize;
+ GLint rowsize, padding;
+
+ if (w < 0 || h < 0) {
+ return -1;
+ }
+ switch (format) {
+ case GL_COLOR_INDEX:
+ case GL_STENCIL_INDEX:
+ case GL_DEPTH_COMPONENT:
+ elements = 1;
+ break;
+ case GL_RED:
+ case GL_GREEN:
+ case GL_BLUE:
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ elements = 1;
+ break;
+ case GL_LUMINANCE_ALPHA:
+ elements = 2;
+ break;
+ case GL_RGB:
+ case GL_BGR:
+ elements = 3;
+ break;
+ case GL_RGBA:
+ case GL_BGRA:
+ case GL_ABGR_EXT:
+ elements = 4;
+ break;
+ default:
+ return -1;
+ }
+ /*
+ ** According to the GLX protocol, each row must be padded to a multiple of
+ ** 4 bytes. 4 bytes also happens to be the default alignment in the pixel
+ ** store modes of the GL.
+ */
+ switch (type) {
+ case GL_BITMAP:
+ if (format == GL_COLOR_INDEX || format == GL_STENCIL_INDEX) {
+ rowsize = ((w * elements)+7)/8;
+ padding = rowsize % 4;
+ if (padding) {
+ rowsize += 4 - padding;
+ }
+ if (elementbits_return) *elementbits_return = elements;
+ if (rowbytes_return) *rowbytes_return = rowsize;
+ return (rowsize * h);
+ } else {
+ return -1;
+ }
+ case GL_BYTE:
+ case GL_UNSIGNED_BYTE:
+ esize = 1;
+ break;
+ case GL_UNSIGNED_BYTE_3_3_2:
+ case GL_UNSIGNED_BYTE_2_3_3_REV:
+ esize = 1;
+ elements = 1;
+ break;
+ case GL_SHORT:
+ case GL_UNSIGNED_SHORT:
+ esize = 2;
+ break;
+ case GL_UNSIGNED_SHORT_5_6_5:
+ case GL_UNSIGNED_SHORT_5_6_5_REV:
+ case GL_UNSIGNED_SHORT_4_4_4_4:
+ case GL_UNSIGNED_SHORT_4_4_4_4_REV:
+ case GL_UNSIGNED_SHORT_5_5_5_1:
+ case GL_UNSIGNED_SHORT_1_5_5_5_REV:
+ esize = 2;
+ elements = 1;
+ break;
+ case GL_INT:
+ case GL_UNSIGNED_INT:
+ case GL_FLOAT:
+ esize = 4;
+ break;
+ case GL_UNSIGNED_INT_8_8_8_8:
+ case GL_UNSIGNED_INT_8_8_8_8_REV:
+ case GL_UNSIGNED_INT_10_10_10_2:
+ case GL_UNSIGNED_INT_2_10_10_10_REV:
+ esize = 4;
+ elements = 1;
+ break;
+ default:
+ return -1;
+ }
+ rowsize = w * elements * esize;
+ padding = rowsize % 4;
+ if (padding) {
+ rowsize += 4 - padding;
+ }
+
+ if (elementbits_return) *elementbits_return = esize*elements*8;
+ if (rowbytes_return) *rowbytes_return = rowsize;
+
+ return (rowsize * h);
+}
+
+static int intersectRect( int x1, int x2, int y1, int y2,
+ int X1, int X2, int Y1, int Y2,
+ int *ix1, int *ix2, int *iy1, int *iy2 )
+{
+ int right = (x2 < X2 ? x2 : X2);
+ int bottom = (y2 < Y2 ? y2 : Y2);
+ int left = (x1 > X1 ? x1 : X1);
+ int top = (y1 > Y1 ? y1 : Y1);
+ int width = right - left + 1;
+ int height = bottom - top + 1;
+
+ if ( (width <= 0) || (height <= 0) ) {
+ *ix1 = *ix2 = *iy1 = *iy2 = 0;
+ return(0);
+ }
+ else {
+ *ix1 = left;
+ *ix2 = right;
+ *iy1 = top;
+ *iy2 = bottom;
+ return( width * height );
+ }
+
+}
+
+int __glXDisp_ReadPixels(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXSingleReq *req = (xGLXSingleReq *)pc;
+ xGLXSingleReq *be_req;
+ xGLXReadPixelsReply reply;
+ xGLXReadPixelsReply be_reply;
+ GLbyte *be_pc;
+ GLint x,y;
+ GLsizei width, height;
+ GLenum format, type;
+ GLboolean swapBytes, lsbFirst;
+ ClientPtr client = cl->client;
+ DrawablePtr pDraw;
+ int error;
+ __GLXcontext *glxc;
+ int from_screen = 0;
+ int to_screen = 0;
+ char *buf;
+ int buf_size;
+ int s;
+ int win_x1, win_x2;
+ int win_y1, win_y2;
+ int ebits, rowsize;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ if (client->swapped) {
+ __GLX_SWAP_INT(&req->contextTag);
+ }
+
+ glxc = __glXLookupContextByTag(cl, req->contextTag);
+ if (!glxc) {
+ return 0;
+ }
+ from_screen = to_screen = glxc->pScreen->myNum;
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ from_screen = 0;
+ to_screen = screenInfo.numScreens - 1;
+ }
+#endif
+
+ pc += sz_xGLXSingleReq;
+ x = *(GLint *)(pc + 0);
+ y = *(GLint *)(pc + 4);
+ width = *(GLsizei *)(pc + 8);
+ height = *(GLsizei *)(pc + 12);
+ format = *(GLenum *)(pc + 16);
+ type = *(GLenum *)(pc + 20);
+ swapBytes = *(GLboolean *)(pc + 24);
+ lsbFirst = *(GLboolean *)(pc + 25);
+
+ if (client->swapped) {
+ __GLX_SWAP_INT(&x);
+ __GLX_SWAP_INT(&y);
+ __GLX_SWAP_INT(&width);
+ __GLX_SWAP_INT(&height);
+ __GLX_SWAP_INT(&format);
+ __GLX_SWAP_INT(&type);
+ swapBytes = !swapBytes;
+ }
+
+ buf_size = __glReadPixels_size(format,type,width,height, &ebits, &rowsize);
+ if (buf_size > 0) {
+ buf = (char *) malloc( buf_size );
+ if ( !buf ) {
+ return( BadAlloc );
+ }
+ }
+ else {
+ buf_size = 0;
+ }
+
+ if (buf_size > 0) {
+ /*
+ * Get the current drawable this context is bound to
+ */
+ pDraw = __glXLookupDrawableByTag( cl, req->contextTag );
+ win_x1 = pDraw->x + x;
+ win_x2 = win_x1 + width - 1;
+ win_y1 = (dmxGlobalHeight - pDraw->y - pDraw->height) + y;
+ win_y2 = win_y1 + height - 1;
+ if (pDraw->type != DRAWABLE_WINDOW) {
+ from_screen = to_screen = 0;
+ }
+
+ for (s=from_screen; s<=to_screen; s++) {
+ DMXScreenInfo *dmxScreen = &dmxScreens[s];
+ Display *dpy = GetBackEndDisplay(cl,s);
+ int scr_x1 = dmxScreen->rootXOrigin;
+ int scr_x2 = dmxScreen->rootXOrigin + dmxScreen->scrnWidth - 1;
+ int scr_y1 = dmxScreen->rootYOrigin;
+ int scr_y2 = dmxScreen->rootYOrigin + dmxScreen->scrnHeight - 1;
+ int wx1, wx2, wy1, wy2;
+ int sx, sy, sw, sh;
+ int npixels;
+
+ /*
+ * find the window portion that is on the current screen
+ */
+ if (pDraw->type == DRAWABLE_WINDOW) {
+ npixels = intersectRect( scr_x1, scr_x2, scr_y1, scr_y2,
+ win_x1, win_x2, win_y1, win_y2,
+ &wx1, &wx2, &wy1, &wy2 );
+ }
+ else {
+ wx1 = win_x1;
+ wx2 = win_x2;
+ wy1 = win_y1;
+ wy2 = win_y2;
+ npixels = (wx2-wx1+1) * (wy2-wy1+1);
+ }
+
+ if (npixels > 0) {
+
+ /* send the request to the back-end server */
+ LockDisplay(dpy);
+ GetReqExtra(GLXSingle,__GLX_PAD(26),be_req);
+ be_req->reqType = dmxScreen->glxMajorOpcode;
+ be_req->glxCode = X_GLsop_ReadPixels;
+ be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s);
+ be_pc = ((GLbyte *)(be_req) + sz_xGLXSingleReq);
+
+ sx = wx1 - pDraw->x;
+ sy = wy1 - (dmxGlobalHeight - pDraw->y - pDraw->height);
+ sw = (wx2-wx1+1);
+ sh = (wy2-wy1+1);
+
+ *(GLint *)(be_pc + 0) = sx; /* x */
+ *(GLint *)(be_pc + 4) = sy; /* y */
+ *(GLsizei *)(be_pc + 8) = sw; /* width */
+ *(GLsizei *)(be_pc + 12) = sh; /* height */
+ *(GLenum *)(be_pc + 16) = format;
+ *(GLenum *)(be_pc + 20) = type;
+ *(GLboolean *)(be_pc + 24) = swapBytes;
+ *(GLboolean *)(be_pc + 25) = lsbFirst;
+
+ _XReply(dpy, (xReply*) &be_reply, 0, False);
+
+ if (be_reply.length > 0) {
+ char *be_buf;
+ int be_buf_size = be_reply.length << 2;
+
+ be_buf = (char *) malloc( be_buf_size );
+ if (be_buf) {
+ _XRead(dpy, be_buf, be_buf_size);
+
+ /* copy pixels data to the right location of the */
+ /* reply buffer */
+ if ( type != GL_BITMAP ) {
+ int pbytes = ebits / 8;
+ char *dst = buf + (sy-y)*rowsize + (sx-x)*pbytes;
+ char *src = be_buf;
+ int pad = (pbytes * sw) % 4;
+ int r;
+
+ for (r=0; r<sh; r++) {
+ memcpy( dst, src, pbytes*sw );
+ dst += rowsize;
+ src += (pbytes*sw + (pad ? 4-pad : 0) );
+ }
+ }
+ else {
+ /* this is a GL_BITMAP pixel type, should copy bits */
+ int r;
+ int src_rowsize = bits_to_bytes(sw * ebits);
+ int src_pad = src_rowsize % 4;
+ if ( src_pad ) {
+ src_rowsize += (4 - src_pad);
+ }
+
+ for (r=0; r<sh; r++) {
+ unsigned char dst_mask = 0x80 >> (sx % 8);
+ unsigned char src_mask = 0x80;
+ char *dst = buf + (sy-y+r)*rowsize + (sx-x)/8;
+ char *src = be_buf + r*src_rowsize;
+ int b;
+
+ for (b=0; b<sw*ebits; b++) {
+ if ( *src & src_mask ) {
+ *dst |= dst_mask;
+ }
+ else {
+ *dst &= ~dst_mask;
+ }
+
+ if (dst_mask > 1) dst_mask >>= 1;
+ else {
+ dst_mask = 0x80;
+ dst++;
+ }
+
+ if (src_mask > 1) src_mask >>= 1;
+ else {
+ src_mask = 0x80;
+ src++;
+ }
+ }
+ }
+
+ }
+
+ Xfree( be_buf );
+ }
+ else {
+ /* Throw data on the floor */
+ _XEatData(dpy, be_buf_size);
+ Xfree( buf );
+ return BadAlloc;
+ }
+ }
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ } /* of npixels > 0 */
+
+ } /* of for loop */
+
+ } /* of if buf_size > 0 */
+
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.length = buf_size >> 2;
+
+ if (client->swapped) {
+ __GLX_SWAP_SHORT(&reply.sequenceNumber);
+ __GLX_SWAP_INT(&reply.length);
+ }
+
+ WriteToClient(client, sizeof(xGLXReadPixelsReply),(char *)&reply);
+ if (buf_size > 0) {
+ WriteToClient(client, buf_size, (char *)buf);
+ Xfree( buf );
+ }
+
+ return Success;
+}
+
+int __glXDispSwap_GetTexImage(__GLXclientState *cl, GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ GLbyte *lpc = pc;
+
+ lpc += sz_xGLXSingleReq;
+ __GLX_SWAP_INT(lpc+0);
+ __GLX_SWAP_INT(lpc+4);
+ __GLX_SWAP_INT(lpc+8);
+ __GLX_SWAP_INT(lpc+12);
+
+ /* reverse swapBytes */
+ *(GLboolean *)(lpc + 16) = ! *(GLboolean *)(lpc + 16);
+
+ return( __glXForwardPipe0WithReplySwap( cl, pc ) );
+}
+
+int __glXDispSwap_GetColorTable(__GLXclientState *cl, GLbyte *pc)
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ GLbyte *lpc = pc;
+
+ lpc += sz_xGLXSingleReq;
+ __GLX_SWAP_INT(lpc+0);
+ __GLX_SWAP_INT(lpc+4);
+ __GLX_SWAP_INT(lpc+8);
+
+ /* reverse swapBytes */
+ *(GLboolean *)(lpc + 12) = ! *(GLboolean *)(lpc + 12);
+
+ return( __glXForwardPipe0WithReplySwap( cl, pc ) );
+}
+
+
diff --git a/xorg-server/hw/dmx/glxProxy/glxswap.c b/xorg-server/hw/dmx/glxProxy/glxswap.c
index 1e184f914..1471d8b5f 100644
--- a/xorg-server/hw/dmx/glxProxy/glxswap.c
+++ b/xorg-server/hw/dmx/glxProxy/glxswap.c
@@ -1,538 +1,538 @@
-/*
- * Copyright 2003 Red Hat Inc., Raleigh, North Carolina.
- *
- * 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 on 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 (including the
- * next paragraph) 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
- * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
- * 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.
- */
-
-/*
- * Authors:
- * Kevin E. Martin <kem@redhat.com>
- *
- */
-
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
-
-#include "dmx.h"
-#include "dmxwindow.h"
-#include "glxserver.h"
-#include "glxswap.h"
-
-extern int __glXDoSwapBuffers(__GLXclientState *cl, XID drawId,
- GLXContextTag tag);
-
-typedef struct _SwapGroup *SwapGroupPtr;
-
-static Bool SwapBarrierIsReadyToSwap(GLuint barrier);
-static void SwapSwapBarrier(GLuint barrier);
-static void UpdateSwapBarrierList(GLuint barrier,
- SwapGroupPtr pOldSwap,
- SwapGroupPtr pNewSwap);
-
-
-/************************************************************************
- *
- * Swap Groups
- *
- ************************************************************************/
-
-typedef struct _SwapGroup {
- WindowPtr pWin;
- SwapGroupPtr pNext;
-
- Bool swapping;
- Bool sleeping;
- GLuint barrier;
-
- XID drawable;
- GLXContextTag tag;
- __GLXclientState *clState;
-} SwapGroupRec;
-
-
-static void SwapSwapGroup(SwapGroupPtr pSwap)
-{
- SwapGroupPtr pCur;
-
- /* All drawables in swap group are ready to swap, so just swap all
- * drawables buffers and then wake up those clients that were
- * previously sleeping */
-
- for (pCur = pSwap; pCur; pCur = pCur->pNext) {
- if (pCur->swapping) {
- /* Swap pCur's buffers */
- __glXDoSwapBuffers(pCur->clState, pCur->drawable, pCur->tag);
- pCur->swapping = FALSE;
- }
-
- /* Wakeup client */
- if (pCur->sleeping) {
- ClientWakeup(pCur->clState->client);
- pCur->sleeping = FALSE;
- }
- }
-}
-
-static Bool SwapGroupIsReadyToSwap(SwapGroupPtr pSwap)
-{
- Bool isReady = TRUE;
-
- /* The swap group is ready to swap when all drawables are ready to
- * swap. NOTE: A drawable is also ready to swap if it is not
- * currently mapped */
- for (; pSwap; pSwap = pSwap->pNext) {
- isReady &= (pSwap->swapping || !pSwap->pWin->mapped);
- /* FIXME: Should we use pSwap->pWin->mapped or ...->realized ??? */
- }
-
- return isReady;
-}
-
-static Bool SGSwapCleanup(ClientPtr client, pointer closure)
-{
- /* SwapGroupPtr pSwap = (SwapGroupPtr)closure; */
-
- /* This should not be called unless the client has died in which
- * case we should remove the buffer from the swap list */
-
- return TRUE;
-}
-
-int SGSwapBuffers(__GLXclientState *cl, XID drawId, GLXContextTag tag,
- DrawablePtr pDraw)
-{
- WindowPtr pWin = (WindowPtr)pDraw;
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWin);
- SwapGroupPtr pSwap = pWinPriv->swapGroup;
- SwapGroupPtr pCur;
-
- for (pCur = pSwap; pCur && pCur->pWin != pWin; pCur = pCur->pNext);
- if (!pCur)
- return BadDrawable;
-
- pCur->clState = cl;
- pCur->drawable = drawId;
- pCur->tag = tag;
-
- /* We are now in the process of swapping */
- pCur->swapping = TRUE;
-
- if (pSwap->barrier && SwapBarrierIsReadyToSwap(pSwap->barrier)) {
- /* The swap group is bound to a barrier and the barrier is ready
- * to swap, so swap all the swap groups that are bound to this
- * group's swap barrier */
- SwapSwapBarrier(pSwap->barrier);
- } else if (!pSwap->barrier && SwapGroupIsReadyToSwap(pSwap)) {
- /* Do the swap if the entire swap group is ready to swap and the
- * group is not bound to a swap barrier */
- SwapSwapGroup(pSwap);
- } else {
- /* The swap group/barrier is not yet ready to swap, so put
- * client to sleep until the rest are ready to swap */
- ClientSleep(cl->client, SGSwapCleanup, (pointer)pWin);
- pCur->sleeping = TRUE;
- }
-
- return Success;
-}
-
-static void SGWindowUnmapped(WindowPtr pWin)
-{
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWin);
- SwapGroupPtr pSwap = pWinPriv->swapGroup;
-
- /* Now that one of the windows in the swap group has been unmapped,
- * see if the entire swap group/barrier is ready to swap */
-
- if (pSwap->barrier && SwapBarrierIsReadyToSwap(pSwap->barrier)) {
- SwapSwapBarrier(pSwap->barrier);
- } else if (!pSwap->barrier && SwapGroupIsReadyToSwap(pSwap)) {
- SwapSwapGroup(pSwap);
- }
-}
-
-static void SGWindowDestroyed(WindowPtr pWin)
-{
- JoinSwapGroupSGIX((DrawablePtr)pWin, NULL);
-}
-
-static SwapGroupPtr CreateSwapEntry(WindowPtr pWin)
-{
- SwapGroupPtr pEntry;
-
- /* Allocate new swap group */
- pEntry = xalloc(sizeof(*pEntry));
- if (!pEntry) return NULL;
-
- /* Initialize swap group */
- pEntry->pWin = pWin;
- pEntry->pNext = NULL;
- pEntry->swapping = FALSE;
- pEntry->sleeping = FALSE;
- pEntry->barrier = 0;
- /* The following are not initialized until SwapBuffers is called:
- * pEntry->drawable
- * pEntry->tag
- * pEntry->clState
- */
-
- return pEntry;
-}
-
-static void FreeSwapEntry(SwapGroupPtr pEntry)
-{
- /* Since we have removed the drawable from its previous swap group
- * and it won't be added to another swap group, the only thing that
- * we need to do is to make sure that the drawable's client is not
- * sleeping. This could happen if one thread is sleeping, while
- * another thread called glxJoinSwapGroup(). Note that all sleeping
- * threads should also be swapping, but there is a small window in
- * the SGSwapBuffer() logic, above, where swapping can be set but
- * sleeping is not. We check both independently here just to be
- * pedantic. */
-
- /* Handle swap buffer request */
- if (pEntry->swapping)
- __glXDoSwapBuffers(pEntry->clState, pEntry->drawable, pEntry->tag);
-
- /* Wake up client */
- if (pEntry->sleeping)
- ClientWakeup(pEntry->clState->client);
-
- /* We can free the pEntry entry since it has already been removed
- * from the swap group list and it won't be needed any longer */
- xfree(pEntry);
-}
-
-int JoinSwapGroupSGIX(DrawablePtr pDraw, DrawablePtr pMember)
-{
- if (pDraw->type == DRAWABLE_WINDOW) {
- WindowPtr pWin = (WindowPtr)pDraw;
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWin);
- SwapGroupPtr pOldSwap = NULL;
- SwapGroupPtr pEntry;
-
- /* If pDraw and pMember are already members of the same swap
- * group, just return Success since there is nothing to do */
- for (pEntry = pWinPriv->swapGroup; pEntry; pEntry = pEntry->pNext)
- if (pEntry->pWin == (WindowPtr)pMember)
- return Success;
-
- /* Remove pDraw from its current swap group */
- if (pWinPriv->swapGroup) {
- SwapGroupPtr pSwapGroup = pWinPriv->swapGroup;
- SwapGroupPtr pPrev;
-
- /* Find old swap entry in swap group and save in pOldSwap
- * for later use */
- for (pOldSwap = pWinPriv->swapGroup, pPrev = NULL;
- pOldSwap && pOldSwap->pWin != pWin;
- pPrev = pOldSwap, pOldSwap = pOldSwap->pNext);
- if (!pOldSwap)
- return BadDrawable;
-
- /* Remove pDraw's swap group entry from swap group list */
- if (pPrev) {
- pPrev->pNext = pOldSwap->pNext;
- } else {
- /* pWin is at the head of the swap group list, so we
- * need to update all other members of this swap
- * group */
- for (pEntry = pOldSwap->pNext; pEntry; pEntry = pEntry->pNext)
- DMX_GET_WINDOW_PRIV(pEntry->pWin)->swapGroup
- = pOldSwap->pNext;
-
- /* Update the barrier list as well */
- if (pOldSwap->barrier)
- UpdateSwapBarrierList(pOldSwap->barrier,
- pOldSwap, pOldSwap->pNext);
-
- /* Set pSwapGroup to point to the swap group without
- * pOldSwap */
- pSwapGroup = pOldSwap->pNext;
- }
-
- /* Check to see if current swap group can now swap since we
- * know at this point that pDraw and pMember are guaranteed
- * to previously be in different swap groups */
- if (pSwapGroup && SwapGroupIsReadyToSwap(pSwapGroup)) {
- SwapSwapGroup(pSwapGroup);
- }
-
- /* Make the old swap entry a standalone group */
- pOldSwap->pNext = NULL;
- pOldSwap->barrier = 0;
-
- /* Reset pWin's swap group */
- pWinPriv->swapGroup = NULL;
- pWinPriv->windowDestroyed = NULL;
- pWinPriv->windowUnmapped = NULL;
- }
-
- if (!pMember || pMember->type != DRAWABLE_WINDOW) {
- /* Free old swap group since it is no longer needed */
- if (pOldSwap) FreeSwapEntry(pOldSwap);
- } else if (pDraw == pMember && pOldSwap) {
- /* Special case where pDraw was previously created and we
- * are now just putting it to its own swap group */
- pWinPriv->swapGroup = pOldSwap;
- pWinPriv->windowDestroyed = SGWindowDestroyed;
- pWinPriv->windowUnmapped = SGWindowUnmapped;
-
- /* Check to see if pDraw is ready to swap */
- if (SwapGroupIsReadyToSwap(pOldSwap))
- SwapSwapGroup(pOldSwap);
- } else if (pMember->type == DRAWABLE_WINDOW) {
- WindowPtr pMemberWin = (WindowPtr)pMember;
- dmxWinPrivPtr pMemberPriv = DMX_GET_WINDOW_PRIV(pMemberWin);
- SwapGroupPtr pMemberSwapGroup = pMemberPriv->swapGroup;
-
- /* Finally, how we can add pDraw to pMember's swap group */
-
- /* If pMember is not currently in a swap group, then create
- * one for it since we are just about to add pDraw to it. */
- if (!pMemberSwapGroup) {
- /* Create new swap group */
- pMemberSwapGroup = CreateSwapEntry(pMemberWin);
- if (!pMemberSwapGroup) {
- if (pOldSwap) FreeSwapEntry(pOldSwap);
- return BadAlloc;
- }
-
- /* Set pMember's swap group */
- pMemberPriv->swapGroup = pMemberSwapGroup;
- pMemberPriv->windowDestroyed = SGWindowDestroyed;
- pMemberPriv->windowUnmapped = SGWindowUnmapped;
- }
-
- /* If pDraw == pMember, that means pDraw was not a member of
- * a group previously (or it would have been handled by the
- * special case above), so no additional work is required
- * since we just created a new swap group for pMember (i.e.,
- * pDraw). */
-
- if (pDraw != pMember) {
- /* If pDraw was not previously in a swap group, then create
- * an entry for it */
- if (!pOldSwap) {
- /* Create new swap group */
- pOldSwap = CreateSwapEntry(pWin);
- if (!pOldSwap) {
- /* If we just created a swap group for pMember, we
- * need to free it here */
- if (pMemberSwapGroup->pNext == NULL) {
- FreeSwapEntry(pMemberSwapGroup);
- pMemberPriv->swapGroup = NULL;
- }
- return BadAlloc;
- }
- }
-
- /* Find last entry in pMember's swap group */
- for (pEntry = pMemberSwapGroup;
- pEntry->pNext;
- pEntry = pEntry->pNext);
-
- /* Add pDraw's swap group entry to pMember's swap group list */
- pEntry->pNext = pOldSwap;
-
- /* Add pDraw to pMember's swap barrier */
- pOldSwap->barrier = pEntry->barrier;
-
- /* Set pDraw's swap group */
- pWinPriv->swapGroup = pMemberSwapGroup;
- pWinPriv->windowDestroyed = SGWindowDestroyed;
- pWinPriv->windowUnmapped = SGWindowUnmapped;
- }
- }
- }
-
- return Success;
-}
-
-
-/************************************************************************
- *
- * Swap Barriers
- *
- ************************************************************************/
-
-#define GLX_MAX_SWAP_BARRIERS 10
-
-typedef struct _SwapBarrier *SwapBarrierPtr;
-typedef struct _SwapBarrier {
- SwapGroupPtr pSwap;
- SwapBarrierPtr pNext;
-} SwapBarrierRec;
-
-static SwapBarrierPtr SwapBarrierList[GLX_MAX_SWAP_BARRIERS+1];
-
-void SwapBarrierInit(void)
-{
- int i;
-
- for (i = 0; i <= GLX_MAX_SWAP_BARRIERS; i++)
- SwapBarrierList[i] = NULL;
-}
-
-void SwapBarrierReset(void)
-{
- int i;
-
- for (i = 0; i <= GLX_MAX_SWAP_BARRIERS; i++) {
- SwapBarrierPtr pBarrier, pNextBarrier;
- for (pBarrier = SwapBarrierList[i];
- pBarrier;
- pBarrier = pNextBarrier) {
- pNextBarrier = pBarrier->pNext;
- xfree(pBarrier);
- }
- SwapBarrierList[i] = NULL;
- }
-}
-
-int QueryMaxSwapBarriersSGIX(int screen)
-{
- return GLX_MAX_SWAP_BARRIERS;
-}
-
-static Bool BindSwapGroupToBarrier(GLuint barrier, SwapGroupPtr pSwapGroup)
-{
- SwapBarrierPtr pBarrier;
-
- pBarrier = xalloc(sizeof(*pBarrier));
- if (!pBarrier) return FALSE;
-
- /* Add the swap group to barrier's list */
- pBarrier->pSwap = pSwapGroup;
- pBarrier->pNext = SwapBarrierList[barrier];
- SwapBarrierList[barrier] = pBarrier;
-
- return TRUE;
-}
-
-static Bool UnbindSwapGroupFromBarrier(GLuint barrier, SwapGroupPtr pSwapGroup)
-{
- SwapBarrierPtr pBarrier, pPrevBarrier;
-
- /* Find the swap group in barrier's list */
- for (pBarrier = SwapBarrierList[barrier], pPrevBarrier = NULL;
- pBarrier && pBarrier->pSwap != pSwapGroup;
- pPrevBarrier = pBarrier, pBarrier = pBarrier->pNext);
- if (!pBarrier) return FALSE;
-
- /* Remove the swap group from barrier's list */
- if (pPrevBarrier) pPrevBarrier->pNext = pBarrier->pNext;
- else SwapBarrierList[barrier] = pBarrier->pNext;
-
- /* Free memory */
- xfree(pBarrier);
-
- return TRUE;
-}
-
-static void UpdateSwapBarrierList(GLuint barrier,
- SwapGroupPtr pOldSwap,
- SwapGroupPtr pNewSwap)
-{
- SwapBarrierPtr pBarrier;
-
- /* If the old swap group is being destroyed, then we need to remove
- * the swap group from the list entirely */
- if (!pNewSwap) {
- UnbindSwapGroupFromBarrier(barrier, pOldSwap);
- return;
- }
-
- /* Otherwise, find the old swap group in the barrier list and change
- * it to the new swap group */
- for (pBarrier = SwapBarrierList[barrier];
- pBarrier;
- pBarrier = pBarrier->pNext) {
- if (pBarrier->pSwap == pOldSwap) {
- pBarrier->pSwap = pNewSwap;
- return;
- }
- }
-}
-
-static Bool SwapBarrierIsReadyToSwap(GLuint barrier)
-{
- SwapBarrierPtr pBarrier;
- Bool isReady = TRUE;
-
- /* The swap barier is ready to swap when swap groups that are bound
- * to barrier are ready to swap */
- for (pBarrier = SwapBarrierList[barrier];
- pBarrier;
- pBarrier = pBarrier->pNext)
- isReady &= SwapGroupIsReadyToSwap(pBarrier->pSwap);
-
- return isReady;
-}
-
-static void SwapSwapBarrier(GLuint barrier)
-{
- SwapBarrierPtr pBarrier;
-
- /* Swap each group that is a member of this barrier */
- for (pBarrier = SwapBarrierList[barrier];
- pBarrier;
- pBarrier = pBarrier->pNext)
- SwapSwapGroup(pBarrier->pSwap);
-}
-
-int BindSwapBarrierSGIX(DrawablePtr pDraw, int barrier)
-{
- /* FIXME: Check for errors when pDraw->type != DRAWABLE_WINDOW */
-
- if (barrier < 0 || barrier > GLX_MAX_SWAP_BARRIERS)
- return BadValue;
-
- if (pDraw->type == DRAWABLE_WINDOW) {
- WindowPtr pWin = (WindowPtr)pDraw;
- dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWin);
- SwapGroupPtr pSwapGroup = pWinPriv->swapGroup;
- SwapGroupPtr pCur;
-
- if (!pSwapGroup) return BadDrawable;
- if (barrier && pSwapGroup->barrier) return BadValue;
-
- /* Update the swap barrier list */
- if (barrier) {
- if (!BindSwapGroupToBarrier(barrier, pSwapGroup))
- return BadAlloc;
- } else {
- if (!UnbindSwapGroupFromBarrier(pSwapGroup->barrier, pSwapGroup))
- return BadDrawable;
- }
-
- /* Set the barrier for each member of this swap group */
- for (pCur = pSwapGroup; pCur; pCur = pCur->pNext)
- pCur->barrier = barrier;
- }
-
- return Success;
-}
+/*
+ * Copyright 2003 Red Hat Inc., Raleigh, North Carolina.
+ *
+ * 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 on 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 (including the
+ * next paragraph) 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
+ * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
+ * 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.
+ */
+
+/*
+ * Authors:
+ * Kevin E. Martin <kem@redhat.com>
+ *
+ */
+
+#ifdef HAVE_DMX_CONFIG_H
+#include <dmx-config.h>
+#endif
+
+#include "dmx.h"
+#include "dmxwindow.h"
+#include "glxserver.h"
+#include "glxswap.h"
+
+extern int __glXDoSwapBuffers(__GLXclientState *cl, XID drawId,
+ GLXContextTag tag);
+
+typedef struct _SwapGroup *SwapGroupPtr;
+
+static Bool SwapBarrierIsReadyToSwap(GLuint barrier);
+static void SwapSwapBarrier(GLuint barrier);
+static void UpdateSwapBarrierList(GLuint barrier,
+ SwapGroupPtr pOldSwap,
+ SwapGroupPtr pNewSwap);
+
+
+/************************************************************************
+ *
+ * Swap Groups
+ *
+ ************************************************************************/
+
+typedef struct _SwapGroup {
+ WindowPtr pWin;
+ SwapGroupPtr pNext;
+
+ Bool swapping;
+ Bool sleeping;
+ GLuint barrier;
+
+ XID drawable;
+ GLXContextTag tag;
+ __GLXclientState *clState;
+} SwapGroupRec;
+
+
+static void SwapSwapGroup(SwapGroupPtr pSwap)
+{
+ SwapGroupPtr pCur;
+
+ /* All drawables in swap group are ready to swap, so just swap all
+ * drawables buffers and then wake up those clients that were
+ * previously sleeping */
+
+ for (pCur = pSwap; pCur; pCur = pCur->pNext) {
+ if (pCur->swapping) {
+ /* Swap pCur's buffers */
+ __glXDoSwapBuffers(pCur->clState, pCur->drawable, pCur->tag);
+ pCur->swapping = FALSE;
+ }
+
+ /* Wakeup client */
+ if (pCur->sleeping) {
+ ClientWakeup(pCur->clState->client);
+ pCur->sleeping = FALSE;
+ }
+ }
+}
+
+static Bool SwapGroupIsReadyToSwap(SwapGroupPtr pSwap)
+{
+ Bool isReady = TRUE;
+
+ /* The swap group is ready to swap when all drawables are ready to
+ * swap. NOTE: A drawable is also ready to swap if it is not
+ * currently mapped */
+ for (; pSwap; pSwap = pSwap->pNext) {
+ isReady &= (pSwap->swapping || !pSwap->pWin->mapped);
+ /* FIXME: Should we use pSwap->pWin->mapped or ...->realized ??? */
+ }
+
+ return isReady;
+}
+
+static Bool SGSwapCleanup(ClientPtr client, pointer closure)
+{
+ /* SwapGroupPtr pSwap = (SwapGroupPtr)closure; */
+
+ /* This should not be called unless the client has died in which
+ * case we should remove the buffer from the swap list */
+
+ return TRUE;
+}
+
+int SGSwapBuffers(__GLXclientState *cl, XID drawId, GLXContextTag tag,
+ DrawablePtr pDraw)
+{
+ WindowPtr pWin = (WindowPtr)pDraw;
+ dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWin);
+ SwapGroupPtr pSwap = pWinPriv->swapGroup;
+ SwapGroupPtr pCur;
+
+ for (pCur = pSwap; pCur && pCur->pWin != pWin; pCur = pCur->pNext);
+ if (!pCur)
+ return BadDrawable;
+
+ pCur->clState = cl;
+ pCur->drawable = drawId;
+ pCur->tag = tag;
+
+ /* We are now in the process of swapping */
+ pCur->swapping = TRUE;
+
+ if (pSwap->barrier && SwapBarrierIsReadyToSwap(pSwap->barrier)) {
+ /* The swap group is bound to a barrier and the barrier is ready
+ * to swap, so swap all the swap groups that are bound to this
+ * group's swap barrier */
+ SwapSwapBarrier(pSwap->barrier);
+ } else if (!pSwap->barrier && SwapGroupIsReadyToSwap(pSwap)) {
+ /* Do the swap if the entire swap group is ready to swap and the
+ * group is not bound to a swap barrier */
+ SwapSwapGroup(pSwap);
+ } else {
+ /* The swap group/barrier is not yet ready to swap, so put
+ * client to sleep until the rest are ready to swap */
+ ClientSleep(cl->client, SGSwapCleanup, (pointer)pWin);
+ pCur->sleeping = TRUE;
+ }
+
+ return Success;
+}
+
+static void SGWindowUnmapped(WindowPtr pWin)
+{
+ dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWin);
+ SwapGroupPtr pSwap = pWinPriv->swapGroup;
+
+ /* Now that one of the windows in the swap group has been unmapped,
+ * see if the entire swap group/barrier is ready to swap */
+
+ if (pSwap->barrier && SwapBarrierIsReadyToSwap(pSwap->barrier)) {
+ SwapSwapBarrier(pSwap->barrier);
+ } else if (!pSwap->barrier && SwapGroupIsReadyToSwap(pSwap)) {
+ SwapSwapGroup(pSwap);
+ }
+}
+
+static void SGWindowDestroyed(WindowPtr pWin)
+{
+ JoinSwapGroupSGIX((DrawablePtr)pWin, NULL);
+}
+
+static SwapGroupPtr CreateSwapEntry(WindowPtr pWin)
+{
+ SwapGroupPtr pEntry;
+
+ /* Allocate new swap group */
+ pEntry = malloc(sizeof(*pEntry));
+ if (!pEntry) return NULL;
+
+ /* Initialize swap group */
+ pEntry->pWin = pWin;
+ pEntry->pNext = NULL;
+ pEntry->swapping = FALSE;
+ pEntry->sleeping = FALSE;
+ pEntry->barrier = 0;
+ /* The following are not initialized until SwapBuffers is called:
+ * pEntry->drawable
+ * pEntry->tag
+ * pEntry->clState
+ */
+
+ return pEntry;
+}
+
+static void FreeSwapEntry(SwapGroupPtr pEntry)
+{
+ /* Since we have removed the drawable from its previous swap group
+ * and it won't be added to another swap group, the only thing that
+ * we need to do is to make sure that the drawable's client is not
+ * sleeping. This could happen if one thread is sleeping, while
+ * another thread called glxJoinSwapGroup(). Note that all sleeping
+ * threads should also be swapping, but there is a small window in
+ * the SGSwapBuffer() logic, above, where swapping can be set but
+ * sleeping is not. We check both independently here just to be
+ * pedantic. */
+
+ /* Handle swap buffer request */
+ if (pEntry->swapping)
+ __glXDoSwapBuffers(pEntry->clState, pEntry->drawable, pEntry->tag);
+
+ /* Wake up client */
+ if (pEntry->sleeping)
+ ClientWakeup(pEntry->clState->client);
+
+ /* We can free the pEntry entry since it has already been removed
+ * from the swap group list and it won't be needed any longer */
+ free(pEntry);
+}
+
+int JoinSwapGroupSGIX(DrawablePtr pDraw, DrawablePtr pMember)
+{
+ if (pDraw->type == DRAWABLE_WINDOW) {
+ WindowPtr pWin = (WindowPtr)pDraw;
+ dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWin);
+ SwapGroupPtr pOldSwap = NULL;
+ SwapGroupPtr pEntry;
+
+ /* If pDraw and pMember are already members of the same swap
+ * group, just return Success since there is nothing to do */
+ for (pEntry = pWinPriv->swapGroup; pEntry; pEntry = pEntry->pNext)
+ if (pEntry->pWin == (WindowPtr)pMember)
+ return Success;
+
+ /* Remove pDraw from its current swap group */
+ if (pWinPriv->swapGroup) {
+ SwapGroupPtr pSwapGroup = pWinPriv->swapGroup;
+ SwapGroupPtr pPrev;
+
+ /* Find old swap entry in swap group and save in pOldSwap
+ * for later use */
+ for (pOldSwap = pWinPriv->swapGroup, pPrev = NULL;
+ pOldSwap && pOldSwap->pWin != pWin;
+ pPrev = pOldSwap, pOldSwap = pOldSwap->pNext);
+ if (!pOldSwap)
+ return BadDrawable;
+
+ /* Remove pDraw's swap group entry from swap group list */
+ if (pPrev) {
+ pPrev->pNext = pOldSwap->pNext;
+ } else {
+ /* pWin is at the head of the swap group list, so we
+ * need to update all other members of this swap
+ * group */
+ for (pEntry = pOldSwap->pNext; pEntry; pEntry = pEntry->pNext)
+ DMX_GET_WINDOW_PRIV(pEntry->pWin)->swapGroup
+ = pOldSwap->pNext;
+
+ /* Update the barrier list as well */
+ if (pOldSwap->barrier)
+ UpdateSwapBarrierList(pOldSwap->barrier,
+ pOldSwap, pOldSwap->pNext);
+
+ /* Set pSwapGroup to point to the swap group without
+ * pOldSwap */
+ pSwapGroup = pOldSwap->pNext;
+ }
+
+ /* Check to see if current swap group can now swap since we
+ * know at this point that pDraw and pMember are guaranteed
+ * to previously be in different swap groups */
+ if (pSwapGroup && SwapGroupIsReadyToSwap(pSwapGroup)) {
+ SwapSwapGroup(pSwapGroup);
+ }
+
+ /* Make the old swap entry a standalone group */
+ pOldSwap->pNext = NULL;
+ pOldSwap->barrier = 0;
+
+ /* Reset pWin's swap group */
+ pWinPriv->swapGroup = NULL;
+ pWinPriv->windowDestroyed = NULL;
+ pWinPriv->windowUnmapped = NULL;
+ }
+
+ if (!pMember || pMember->type != DRAWABLE_WINDOW) {
+ /* Free old swap group since it is no longer needed */
+ if (pOldSwap) FreeSwapEntry(pOldSwap);
+ } else if (pDraw == pMember && pOldSwap) {
+ /* Special case where pDraw was previously created and we
+ * are now just putting it to its own swap group */
+ pWinPriv->swapGroup = pOldSwap;
+ pWinPriv->windowDestroyed = SGWindowDestroyed;
+ pWinPriv->windowUnmapped = SGWindowUnmapped;
+
+ /* Check to see if pDraw is ready to swap */
+ if (SwapGroupIsReadyToSwap(pOldSwap))
+ SwapSwapGroup(pOldSwap);
+ } else if (pMember->type == DRAWABLE_WINDOW) {
+ WindowPtr pMemberWin = (WindowPtr)pMember;
+ dmxWinPrivPtr pMemberPriv = DMX_GET_WINDOW_PRIV(pMemberWin);
+ SwapGroupPtr pMemberSwapGroup = pMemberPriv->swapGroup;
+
+ /* Finally, how we can add pDraw to pMember's swap group */
+
+ /* If pMember is not currently in a swap group, then create
+ * one for it since we are just about to add pDraw to it. */
+ if (!pMemberSwapGroup) {
+ /* Create new swap group */
+ pMemberSwapGroup = CreateSwapEntry(pMemberWin);
+ if (!pMemberSwapGroup) {
+ if (pOldSwap) FreeSwapEntry(pOldSwap);
+ return BadAlloc;
+ }
+
+ /* Set pMember's swap group */
+ pMemberPriv->swapGroup = pMemberSwapGroup;
+ pMemberPriv->windowDestroyed = SGWindowDestroyed;
+ pMemberPriv->windowUnmapped = SGWindowUnmapped;
+ }
+
+ /* If pDraw == pMember, that means pDraw was not a member of
+ * a group previously (or it would have been handled by the
+ * special case above), so no additional work is required
+ * since we just created a new swap group for pMember (i.e.,
+ * pDraw). */
+
+ if (pDraw != pMember) {
+ /* If pDraw was not previously in a swap group, then create
+ * an entry for it */
+ if (!pOldSwap) {
+ /* Create new swap group */
+ pOldSwap = CreateSwapEntry(pWin);
+ if (!pOldSwap) {
+ /* If we just created a swap group for pMember, we
+ * need to free it here */
+ if (pMemberSwapGroup->pNext == NULL) {
+ FreeSwapEntry(pMemberSwapGroup);
+ pMemberPriv->swapGroup = NULL;
+ }
+ return BadAlloc;
+ }
+ }
+
+ /* Find last entry in pMember's swap group */
+ for (pEntry = pMemberSwapGroup;
+ pEntry->pNext;
+ pEntry = pEntry->pNext);
+
+ /* Add pDraw's swap group entry to pMember's swap group list */
+ pEntry->pNext = pOldSwap;
+
+ /* Add pDraw to pMember's swap barrier */
+ pOldSwap->barrier = pEntry->barrier;
+
+ /* Set pDraw's swap group */
+ pWinPriv->swapGroup = pMemberSwapGroup;
+ pWinPriv->windowDestroyed = SGWindowDestroyed;
+ pWinPriv->windowUnmapped = SGWindowUnmapped;
+ }
+ }
+ }
+
+ return Success;
+}
+
+
+/************************************************************************
+ *
+ * Swap Barriers
+ *
+ ************************************************************************/
+
+#define GLX_MAX_SWAP_BARRIERS 10
+
+typedef struct _SwapBarrier *SwapBarrierPtr;
+typedef struct _SwapBarrier {
+ SwapGroupPtr pSwap;
+ SwapBarrierPtr pNext;
+} SwapBarrierRec;
+
+static SwapBarrierPtr SwapBarrierList[GLX_MAX_SWAP_BARRIERS+1];
+
+void SwapBarrierInit(void)
+{
+ int i;
+
+ for (i = 0; i <= GLX_MAX_SWAP_BARRIERS; i++)
+ SwapBarrierList[i] = NULL;
+}
+
+void SwapBarrierReset(void)
+{
+ int i;
+
+ for (i = 0; i <= GLX_MAX_SWAP_BARRIERS; i++) {
+ SwapBarrierPtr pBarrier, pNextBarrier;
+ for (pBarrier = SwapBarrierList[i];
+ pBarrier;
+ pBarrier = pNextBarrier) {
+ pNextBarrier = pBarrier->pNext;
+ free(pBarrier);
+ }
+ SwapBarrierList[i] = NULL;
+ }
+}
+
+int QueryMaxSwapBarriersSGIX(int screen)
+{
+ return GLX_MAX_SWAP_BARRIERS;
+}
+
+static Bool BindSwapGroupToBarrier(GLuint barrier, SwapGroupPtr pSwapGroup)
+{
+ SwapBarrierPtr pBarrier;
+
+ pBarrier = malloc(sizeof(*pBarrier));
+ if (!pBarrier) return FALSE;
+
+ /* Add the swap group to barrier's list */
+ pBarrier->pSwap = pSwapGroup;
+ pBarrier->pNext = SwapBarrierList[barrier];
+ SwapBarrierList[barrier] = pBarrier;
+
+ return TRUE;
+}
+
+static Bool UnbindSwapGroupFromBarrier(GLuint barrier, SwapGroupPtr pSwapGroup)
+{
+ SwapBarrierPtr pBarrier, pPrevBarrier;
+
+ /* Find the swap group in barrier's list */
+ for (pBarrier = SwapBarrierList[barrier], pPrevBarrier = NULL;
+ pBarrier && pBarrier->pSwap != pSwapGroup;
+ pPrevBarrier = pBarrier, pBarrier = pBarrier->pNext);
+ if (!pBarrier) return FALSE;
+
+ /* Remove the swap group from barrier's list */
+ if (pPrevBarrier) pPrevBarrier->pNext = pBarrier->pNext;
+ else SwapBarrierList[barrier] = pBarrier->pNext;
+
+ /* Free memory */
+ free(pBarrier);
+
+ return TRUE;
+}
+
+static void UpdateSwapBarrierList(GLuint barrier,
+ SwapGroupPtr pOldSwap,
+ SwapGroupPtr pNewSwap)
+{
+ SwapBarrierPtr pBarrier;
+
+ /* If the old swap group is being destroyed, then we need to remove
+ * the swap group from the list entirely */
+ if (!pNewSwap) {
+ UnbindSwapGroupFromBarrier(barrier, pOldSwap);
+ return;
+ }
+
+ /* Otherwise, find the old swap group in the barrier list and change
+ * it to the new swap group */
+ for (pBarrier = SwapBarrierList[barrier];
+ pBarrier;
+ pBarrier = pBarrier->pNext) {
+ if (pBarrier->pSwap == pOldSwap) {
+ pBarrier->pSwap = pNewSwap;
+ return;
+ }
+ }
+}
+
+static Bool SwapBarrierIsReadyToSwap(GLuint barrier)
+{
+ SwapBarrierPtr pBarrier;
+ Bool isReady = TRUE;
+
+ /* The swap barier is ready to swap when swap groups that are bound
+ * to barrier are ready to swap */
+ for (pBarrier = SwapBarrierList[barrier];
+ pBarrier;
+ pBarrier = pBarrier->pNext)
+ isReady &= SwapGroupIsReadyToSwap(pBarrier->pSwap);
+
+ return isReady;
+}
+
+static void SwapSwapBarrier(GLuint barrier)
+{
+ SwapBarrierPtr pBarrier;
+
+ /* Swap each group that is a member of this barrier */
+ for (pBarrier = SwapBarrierList[barrier];
+ pBarrier;
+ pBarrier = pBarrier->pNext)
+ SwapSwapGroup(pBarrier->pSwap);
+}
+
+int BindSwapBarrierSGIX(DrawablePtr pDraw, int barrier)
+{
+ /* FIXME: Check for errors when pDraw->type != DRAWABLE_WINDOW */
+
+ if (barrier < 0 || barrier > GLX_MAX_SWAP_BARRIERS)
+ return BadValue;
+
+ if (pDraw->type == DRAWABLE_WINDOW) {
+ WindowPtr pWin = (WindowPtr)pDraw;
+ dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWin);
+ SwapGroupPtr pSwapGroup = pWinPriv->swapGroup;
+ SwapGroupPtr pCur;
+
+ if (!pSwapGroup) return BadDrawable;
+ if (barrier && pSwapGroup->barrier) return BadValue;
+
+ /* Update the swap barrier list */
+ if (barrier) {
+ if (!BindSwapGroupToBarrier(barrier, pSwapGroup))
+ return BadAlloc;
+ } else {
+ if (!UnbindSwapGroupFromBarrier(pSwapGroup->barrier, pSwapGroup))
+ return BadDrawable;
+ }
+
+ /* Set the barrier for each member of this swap group */
+ for (pCur = pSwapGroup; pCur; pCur = pCur->pNext)
+ pCur->barrier = barrier;
+ }
+
+ return Success;
+}
diff --git a/xorg-server/hw/dmx/glxProxy/glxutil.c b/xorg-server/hw/dmx/glxProxy/glxutil.c
index d0ce50486..2460ed0dc 100644
--- a/xorg-server/hw/dmx/glxProxy/glxutil.c
+++ b/xorg-server/hw/dmx/glxProxy/glxutil.c
@@ -1,111 +1,111 @@
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, 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 including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * 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
- * SILICON GRAPHICS, INC. 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 Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-#include "glxserver.h"
-#include <GL/glxtokens.h>
-#include <pixmapstr.h>
-#include <windowstr.h>
-#include "glxutil.h"
-#include <stdlib.h>
-
-/************************************************************************/
-
-void __glXNop(void) {}
-
-/************************************************************************/
-
-/* Memory Allocation for GLX */
-
-void *
-__glXMalloc(size_t size)
-{
- void *addr;
-
- if (size == 0) {
- return NULL;
- }
- addr = malloc(size);
- if (addr == NULL) {
- /* XXX: handle out of memory error */
- return NULL;
- }
- return addr;
-}
-
-void *
-__glXCalloc(size_t numElements, size_t elementSize)
-{
- void *addr;
- size_t size;
-
- if ((numElements == 0) || (elementSize == 0)) {
- return NULL;
- }
- addr = calloc(numElements, elementSize);
- if (addr == NULL) {
- /* XXX: handle out of memory error */
- return NULL;
- }
- return addr;
-}
-
-void *
-__glXRealloc(void *addr, size_t newSize)
-{
- void *newAddr;
-
- if (addr) {
- if (newSize == 0) {
- xfree(addr);
- return NULL;
- } else {
- newAddr = realloc(addr, newSize);
- }
- } else {
- if (newSize == 0) {
- return NULL;
- } else {
- newAddr = malloc(newSize);
- }
- }
- if (newAddr == NULL) {
- return NULL; /* XXX: out of memory */
- }
-
- return newAddr;
-}
-
-void
-__glXFree(void *addr)
-{
- if (addr) {
- free(addr);
- }
-}
+/*
+ * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
+ * Copyright (C) 1991-2000 Silicon Graphics, 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 including the dates of first publication and
+ * either this permission notice or a reference to
+ * http://oss.sgi.com/projects/FreeB/
+ * 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
+ * SILICON GRAPHICS, INC. 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 Silicon Graphics, Inc.
+ * shall not be used in advertising or otherwise to promote the sale, use or
+ * other dealings in this Software without prior written authorization from
+ * Silicon Graphics, Inc.
+ */
+
+#include "glxserver.h"
+#include <GL/glxtokens.h>
+#include <pixmapstr.h>
+#include <windowstr.h>
+#include "glxutil.h"
+#include <stdlib.h>
+
+/************************************************************************/
+
+void __glXNop(void) {}
+
+/************************************************************************/
+
+/* Memory Allocation for GLX */
+
+void *
+__glXMalloc(size_t size)
+{
+ void *addr;
+
+ if (size == 0) {
+ return NULL;
+ }
+ addr = malloc(size);
+ if (addr == NULL) {
+ /* XXX: handle out of memory error */
+ return NULL;
+ }
+ return addr;
+}
+
+void *
+__glXCalloc(size_t numElements, size_t elementSize)
+{
+ void *addr;
+ size_t size;
+
+ if ((numElements == 0) || (elementSize == 0)) {
+ return NULL;
+ }
+ addr = calloc(numElements, elementSize);
+ if (addr == NULL) {
+ /* XXX: handle out of memory error */
+ return NULL;
+ }
+ return addr;
+}
+
+void *
+__glXRealloc(void *addr, size_t newSize)
+{
+ void *newAddr;
+
+ if (addr) {
+ if (newSize == 0) {
+ free(addr);
+ return NULL;
+ } else {
+ newAddr = realloc(addr, newSize);
+ }
+ } else {
+ if (newSize == 0) {
+ return NULL;
+ } else {
+ newAddr = malloc(newSize);
+ }
+ }
+ if (newAddr == NULL) {
+ return NULL; /* XXX: out of memory */
+ }
+
+ return newAddr;
+}
+
+void
+__glXFree(void *addr)
+{
+ if (addr) {
+ free(addr);
+ }
+}
diff --git a/xorg-server/hw/dmx/glxProxy/glxvendor.c b/xorg-server/hw/dmx/glxProxy/glxvendor.c
index 6b1f9a820..e8460fad8 100644
--- a/xorg-server/hw/dmx/glxProxy/glxvendor.c
+++ b/xorg-server/hw/dmx/glxProxy/glxvendor.c
@@ -1,582 +1,582 @@
-/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED */
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, 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 including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * 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
- * SILICON GRAPHICS, INC. 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 Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
-
-#include "dmx.h"
-#include "dmxwindow.h"
-#include "dmxpixmap.h"
-#include "dmxfont.h"
-
-#undef Xmalloc
-#undef Xcalloc
-#undef Xrealloc
-#undef Xfree
-
-#include "glxserver.h"
-#include "glxext.h"
-#include "g_disptab.h"
-/* #include "g_disptab_EXT.h" */
-#include "unpack.h"
-#include "glxutil.h"
-
-#include "GL/glxproto.h"
-
-#ifdef PANORAMIX
-#include "panoramiXsrv.h"
-#endif
-
-/*
- * GetReqVendorPrivate - this is the equivalent of GetReq macro
- * from Xlibint.h but it does not set the reqType field (the opcode).
- * this is because the GL single opcodes has different naming convension
- * the other X opcodes (ie. X_GLsop_GetFloatv).
- */
-#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP)
-#define GetReqVendorPrivate(name, req) \
- WORD64ALIGN\
- if ((dpy->bufptr + SIZEOF(x##name##Req)) > dpy->bufmax)\
- _XFlush(dpy);\
- req = (x##name##Req *)(dpy->last_req = dpy->bufptr);\
- req->length = (SIZEOF(x##name##Req))>>2;\
- dpy->bufptr += SIZEOF(x##name##Req);\
- dpy->request++
-
-#else /* non-ANSI C uses empty comment instead of "##" for token concatenation */
-#define GetReqVendorPrivate(name, req) \
- WORD64ALIGN\
- if ((dpy->bufptr + SIZEOF(x/**/name/**/Req)) > dpy->bufmax)\
- _XFlush(dpy);\
- req = (x/**/name/**/Req *)(dpy->last_req = dpy->bufptr);\
- req->length = (SIZEOF(x/**/name/**/Req))>>2;\
- dpy->bufptr += SIZEOF(x/**/name/**/Req);\
- dpy->request++
-#endif
-
-extern Display *GetBackEndDisplay( __GLXclientState *cl, int s );
-extern int GetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s);
-
-static int swap_vec_element_size = 0;
-
-static void SendSwappedReply( ClientPtr client,
- xGLXVendorPrivReply *reply,
- char *buf,
- int buf_size )
-{
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_SWAP_SHORT(&reply->sequenceNumber);
- __GLX_SWAP_INT(&reply->length);
- __GLX_SWAP_INT(&reply->retval);
- __GLX_SWAP_INT(&reply->size);
-
- if ( (buf_size == 0) && (swap_vec_element_size > 0) ) {
- /*
- * the reply has single component - need to swap pad3
- */
- if (swap_vec_element_size == 2) {
- __GLX_SWAP_SHORT(&reply->pad3);
- }
- else if (swap_vec_element_size == 4) {
- __GLX_SWAP_INT(&reply->pad3);
- __GLX_SWAP_INT(&reply->pad4);
- }
- else if (swap_vec_element_size == 8) {
- __GLX_SWAP_DOUBLE(&reply->pad3);
- }
- }
- else if ( (buf_size > 0) && (swap_vec_element_size > 0) ) {
- /*
- * the reply has vector of elements which needs to be swapped
- */
- int vsize = buf_size / swap_vec_element_size;
- char *p = buf;
- int i;
-
- for (i=0; i<vsize; i++) {
- if (swap_vec_element_size == 2) {
- __GLX_SWAP_SHORT(p);
- }
- else if (swap_vec_element_size == 4) {
- __GLX_SWAP_INT(p);
- }
- else if (swap_vec_element_size == 8) {
- __GLX_SWAP_DOUBLE(p);
- }
-
- p += swap_vec_element_size;
- }
-
- __GLX_SWAP_INT(&reply->pad3);
- __GLX_SWAP_INT(&reply->pad4);
- __GLX_SWAP_INT(&reply->pad5);
- __GLX_SWAP_INT(&reply->pad6);
-
- }
-
- WriteToClient(client, sizeof(xGLXVendorPrivReply),(char *)reply);
- if (buf_size > 0)
- WriteToClient(client, buf_size, (char *)buf);
-
-}
-
-int __glXVForwardSingleReq( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
- xGLXVendorPrivateReq *be_req;
- __GLXcontext *glxc;
- int from_screen = 0;
- int to_screen = 0;
- int buf_size;
- int s;
-
- glxc = __glXLookupContextByTag(cl, req->contextTag);
- if (!glxc) {
- return 0;
- }
- from_screen = to_screen = glxc->pScreen->myNum;
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
- pc += sz_xGLXVendorPrivateReq;
- buf_size = (req->length << 2) - sz_xGLXVendorPrivateReq;
-
- /*
- * just forward the request to back-end server(s)
- */
- for (s=from_screen; s<=to_screen; s++) {
- DMXScreenInfo *dmxScreen = &dmxScreens[s];
- Display *dpy = GetBackEndDisplay(cl,s);
-
- LockDisplay(dpy);
- GetReqVendorPrivate(GLXVendorPrivate,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = req->glxCode;
- be_req->length = req->length;
- be_req->vendorCode = req->vendorCode;
- be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s);
- if (buf_size > 0)
- _XSend(dpy, (const char *)pc, buf_size);
- UnlockDisplay(dpy);
- SyncHandle();
- }
-
- return Success;
-}
-
-int __glXVForwardPipe0WithReply( __GLXclientState *cl, GLbyte *pc )
-{
- ClientPtr client = cl->client;
- xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
- xGLXVendorPrivateReq *be_req;
- xGLXVendorPrivReply reply;
- xGLXVendorPrivReply be_reply;
- __GLXcontext *glxc;
- int buf_size;
- char *be_buf;
- int be_buf_size;
- DMXScreenInfo *dmxScreen;
- Display *dpy;
-
- glxc = __glXLookupContextByTag(cl, req->contextTag);
- if (!glxc) {
- return __glXBadContext;
- }
-
- pc += sz_xGLXVendorPrivateReq;
- buf_size = (req->length << 2) - sz_xGLXVendorPrivateReq;
-
- dmxScreen = &dmxScreens[glxc->pScreen->myNum];
- dpy = GetBackEndDisplay(cl, glxc->pScreen->myNum);
-
- /*
- * send the request to the first back-end server
- */
- LockDisplay(dpy);
- GetReqVendorPrivate(GLXVendorPrivate,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = req->glxCode;
- be_req->length = req->length;
- be_req->vendorCode = req->vendorCode;
- be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag, glxc->pScreen->myNum);
- if (buf_size > 0)
- _XSend(dpy, (const char *)pc, buf_size);
-
- /*
- * get the reply from the back-end server
- */
- _XReply(dpy, (xReply*) &be_reply, 0, False);
- be_buf_size = be_reply.length << 2;
- if (be_buf_size > 0) {
- be_buf = (char *)Xalloc( be_buf_size );
- if (be_buf) {
- _XRead(dpy, be_buf, be_buf_size);
- }
- else {
- /* Throw data on the floor */
- _XEatData(dpy, be_buf_size);
- return BadAlloc;
- }
- }
-
- UnlockDisplay(dpy);
- SyncHandle();
-
- /*
- * send the reply to the client
- */
- memcpy( &reply, &be_reply, sz_xGLXVendorPrivReply );
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
-
- if (client->swapped) {
- SendSwappedReply( client, &reply, be_buf, be_buf_size );
- }
- else {
- WriteToClient(client, sizeof(xGLXVendorPrivReply),(char *)&reply);
- if (be_buf_size > 0)
- WriteToClient(client, be_buf_size, (char *)be_buf);
- }
-
- if (be_buf_size > 0) Xfree(be_buf);
-
- return Success;
-}
-
-int __glXVForwardAllWithReply( __GLXclientState *cl, GLbyte *pc )
-{
- ClientPtr client = cl->client;
- xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
- xGLXVendorPrivateReq *be_req;
- xGLXVendorPrivReply reply;
- xGLXVendorPrivReply be_reply;
- __GLXcontext *glxc;
- int buf_size;
- char *be_buf;
- int be_buf_size;
- int from_screen = 0;
- int to_screen = 0;
- int s;
-
- DMXScreenInfo *dmxScreen;
- Display *dpy;
-
- glxc = __glXLookupContextByTag(cl, req->contextTag);
- if (!glxc) {
- return 0;
- }
- from_screen = to_screen = glxc->pScreen->myNum;
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension) {
- from_screen = 0;
- to_screen = screenInfo.numScreens - 1;
- }
-#endif
-
- pc += sz_xGLXVendorPrivateReq;
- buf_size = (req->length << 2) - sz_xGLXVendorPrivateReq;
-
- /*
- * send the request to the first back-end server(s)
- */
- for (s=to_screen; s>=from_screen; s--) {
- dmxScreen = &dmxScreens[s];
- dpy = GetBackEndDisplay(cl,s);
-
- LockDisplay(dpy);
- GetReqVendorPrivate(GLXVendorPrivate,be_req);
- be_req->reqType = dmxScreen->glxMajorOpcode;
- be_req->glxCode = req->glxCode;
- be_req->length = req->length;
- be_req->vendorCode = req->vendorCode;
- be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s);
- if (buf_size > 0)
- _XSend(dpy, (const char *)pc, buf_size);
-
- /*
- * get the reply from the back-end server
- */
- _XReply(dpy, (xReply*) &be_reply, 0, False);
- be_buf_size = be_reply.length << 2;
- if (be_buf_size > 0) {
- be_buf = (char *)Xalloc( be_buf_size );
- if (be_buf) {
- _XRead(dpy, be_buf, be_buf_size);
- }
- else {
- /* Throw data on the floor */
- _XEatData(dpy, be_buf_size);
- return BadAlloc;
- }
- }
-
- UnlockDisplay(dpy);
- SyncHandle();
-
- if (s > from_screen && be_buf_size > 0) {
- Xfree(be_buf);
- }
- }
-
- /*
- * send the reply to the client
- */
- memcpy( &reply, &be_reply, sz_xGLXVendorPrivReply );
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
-
- if (client->swapped) {
- SendSwappedReply( client, &reply, be_buf, be_buf_size );
- }
- else {
- WriteToClient(client, sizeof(xGLXVendorPrivReply),(char *)&reply);
- if (be_buf_size > 0)
- WriteToClient(client, be_buf_size, (char *)be_buf);
- }
-
- if (be_buf_size > 0) Xfree(be_buf);
-
- return Success;
-}
-
-int __glXVForwardSingleReqSwap( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->vendorCode);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 0;
-
- return( __glXVForwardSingleReq( cl, pc ) );
-}
-
-int __glXVForwardPipe0WithReplySwap( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->vendorCode);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 0;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXVendorPrivateReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXVendorPrivateReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
- return( __glXVForwardPipe0WithReply( cl, pc ) );
-}
-
-int __glXVForwardPipe0WithReplySwapsv( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->vendorCode);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 2;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXVendorPrivateReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXVendorPrivateReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
- return( __glXVForwardPipe0WithReply( cl, pc ) );
-}
-
-int __glXVForwardPipe0WithReplySwapiv( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->vendorCode);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 4;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXVendorPrivateReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXVendorPrivateReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
- return( __glXVForwardPipe0WithReply( cl, pc ) );
-}
-
-int __glXVForwardPipe0WithReplySwapdv( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->vendorCode);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 8;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXVendorPrivateReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXVendorPrivateReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
- return( __glXVForwardPipe0WithReply( cl, pc ) );
-}
-
-int __glXVForwardAllWithReplySwap( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->vendorCode);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 0;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXVendorPrivateReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXVendorPrivateReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
- return( __glXVForwardAllWithReply( cl, pc ) );
-}
-
-int __glXVForwardAllWithReplySwapsv( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->vendorCode);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 2;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXVendorPrivateReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXVendorPrivateReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
- return( __glXVForwardAllWithReply( cl, pc ) );
-}
-
-int __glXVForwardAllWithReplySwapiv( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->vendorCode);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 4;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXVendorPrivateReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXVendorPrivateReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
- return( __glXVForwardAllWithReply( cl, pc ) );
-}
-
-int __glXVForwardAllWithReplySwapdv( __GLXclientState *cl, GLbyte *pc )
-{
- xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT(&req->length);
- __GLX_SWAP_INT(&req->vendorCode);
- __GLX_SWAP_INT(&req->contextTag);
-
- swap_vec_element_size = 8;
-
- /*
- * swap extra data in request - assuming all data
- * (if available) are arrays of 4 bytes components !
- */
- if (req->length > sz_xGLXVendorPrivateReq/4) {
- int *data = (int *)(req+1);
- int count = req->length - sz_xGLXVendorPrivateReq/4;
- __GLX_SWAP_INT_ARRAY(data, count );
- }
-
- return( __glXVForwardAllWithReply( cl, pc ) );
-}
-
+/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED */
+/*
+ * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
+ * Copyright (C) 1991-2000 Silicon Graphics, 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 including the dates of first publication and
+ * either this permission notice or a reference to
+ * http://oss.sgi.com/projects/FreeB/
+ * 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
+ * SILICON GRAPHICS, INC. 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 Silicon Graphics, Inc.
+ * shall not be used in advertising or otherwise to promote the sale, use or
+ * other dealings in this Software without prior written authorization from
+ * Silicon Graphics, Inc.
+ */
+
+#ifdef HAVE_DMX_CONFIG_H
+#include <dmx-config.h>
+#endif
+
+#include "dmx.h"
+#include "dmxwindow.h"
+#include "dmxpixmap.h"
+#include "dmxfont.h"
+
+#undef Xmalloc
+#undef Xcalloc
+#undef Xrealloc
+#undef Xfree
+
+#include "glxserver.h"
+#include "glxext.h"
+#include "g_disptab.h"
+/* #include "g_disptab_EXT.h" */
+#include "unpack.h"
+#include "glxutil.h"
+
+#include "GL/glxproto.h"
+
+#ifdef PANORAMIX
+#include "panoramiXsrv.h"
+#endif
+
+/*
+ * GetReqVendorPrivate - this is the equivalent of GetReq macro
+ * from Xlibint.h but it does not set the reqType field (the opcode).
+ * this is because the GL single opcodes has different naming convension
+ * the other X opcodes (ie. X_GLsop_GetFloatv).
+ */
+#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP)
+#define GetReqVendorPrivate(name, req) \
+ WORD64ALIGN\
+ if ((dpy->bufptr + SIZEOF(x##name##Req)) > dpy->bufmax)\
+ _XFlush(dpy);\
+ req = (x##name##Req *)(dpy->last_req = dpy->bufptr);\
+ req->length = (SIZEOF(x##name##Req))>>2;\
+ dpy->bufptr += SIZEOF(x##name##Req);\
+ dpy->request++
+
+#else /* non-ANSI C uses empty comment instead of "##" for token concatenation */
+#define GetReqVendorPrivate(name, req) \
+ WORD64ALIGN\
+ if ((dpy->bufptr + SIZEOF(x/**/name/**/Req)) > dpy->bufmax)\
+ _XFlush(dpy);\
+ req = (x/**/name/**/Req *)(dpy->last_req = dpy->bufptr);\
+ req->length = (SIZEOF(x/**/name/**/Req))>>2;\
+ dpy->bufptr += SIZEOF(x/**/name/**/Req);\
+ dpy->request++
+#endif
+
+extern Display *GetBackEndDisplay( __GLXclientState *cl, int s );
+extern int GetCurrentBackEndTag(__GLXclientState *cl, GLXContextTag tag, int s);
+
+static int swap_vec_element_size = 0;
+
+static void SendSwappedReply( ClientPtr client,
+ xGLXVendorPrivReply *reply,
+ char *buf,
+ int buf_size )
+{
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_SWAP_SHORT(&reply->sequenceNumber);
+ __GLX_SWAP_INT(&reply->length);
+ __GLX_SWAP_INT(&reply->retval);
+ __GLX_SWAP_INT(&reply->size);
+
+ if ( (buf_size == 0) && (swap_vec_element_size > 0) ) {
+ /*
+ * the reply has single component - need to swap pad3
+ */
+ if (swap_vec_element_size == 2) {
+ __GLX_SWAP_SHORT(&reply->pad3);
+ }
+ else if (swap_vec_element_size == 4) {
+ __GLX_SWAP_INT(&reply->pad3);
+ __GLX_SWAP_INT(&reply->pad4);
+ }
+ else if (swap_vec_element_size == 8) {
+ __GLX_SWAP_DOUBLE(&reply->pad3);
+ }
+ }
+ else if ( (buf_size > 0) && (swap_vec_element_size > 0) ) {
+ /*
+ * the reply has vector of elements which needs to be swapped
+ */
+ int vsize = buf_size / swap_vec_element_size;
+ char *p = buf;
+ int i;
+
+ for (i=0; i<vsize; i++) {
+ if (swap_vec_element_size == 2) {
+ __GLX_SWAP_SHORT(p);
+ }
+ else if (swap_vec_element_size == 4) {
+ __GLX_SWAP_INT(p);
+ }
+ else if (swap_vec_element_size == 8) {
+ __GLX_SWAP_DOUBLE(p);
+ }
+
+ p += swap_vec_element_size;
+ }
+
+ __GLX_SWAP_INT(&reply->pad3);
+ __GLX_SWAP_INT(&reply->pad4);
+ __GLX_SWAP_INT(&reply->pad5);
+ __GLX_SWAP_INT(&reply->pad6);
+
+ }
+
+ WriteToClient(client, sizeof(xGLXVendorPrivReply),(char *)reply);
+ if (buf_size > 0)
+ WriteToClient(client, buf_size, (char *)buf);
+
+}
+
+int __glXVForwardSingleReq( __GLXclientState *cl, GLbyte *pc )
+{
+ xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
+ xGLXVendorPrivateReq *be_req;
+ __GLXcontext *glxc;
+ int from_screen = 0;
+ int to_screen = 0;
+ int buf_size;
+ int s;
+
+ glxc = __glXLookupContextByTag(cl, req->contextTag);
+ if (!glxc) {
+ return 0;
+ }
+ from_screen = to_screen = glxc->pScreen->myNum;
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ from_screen = 0;
+ to_screen = screenInfo.numScreens - 1;
+ }
+#endif
+
+ pc += sz_xGLXVendorPrivateReq;
+ buf_size = (req->length << 2) - sz_xGLXVendorPrivateReq;
+
+ /*
+ * just forward the request to back-end server(s)
+ */
+ for (s=from_screen; s<=to_screen; s++) {
+ DMXScreenInfo *dmxScreen = &dmxScreens[s];
+ Display *dpy = GetBackEndDisplay(cl,s);
+
+ LockDisplay(dpy);
+ GetReqVendorPrivate(GLXVendorPrivate,be_req);
+ be_req->reqType = dmxScreen->glxMajorOpcode;
+ be_req->glxCode = req->glxCode;
+ be_req->length = req->length;
+ be_req->vendorCode = req->vendorCode;
+ be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s);
+ if (buf_size > 0)
+ _XSend(dpy, (const char *)pc, buf_size);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ }
+
+ return Success;
+}
+
+int __glXVForwardPipe0WithReply( __GLXclientState *cl, GLbyte *pc )
+{
+ ClientPtr client = cl->client;
+ xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
+ xGLXVendorPrivateReq *be_req;
+ xGLXVendorPrivReply reply;
+ xGLXVendorPrivReply be_reply;
+ __GLXcontext *glxc;
+ int buf_size;
+ char *be_buf;
+ int be_buf_size;
+ DMXScreenInfo *dmxScreen;
+ Display *dpy;
+
+ glxc = __glXLookupContextByTag(cl, req->contextTag);
+ if (!glxc) {
+ return __glXBadContext;
+ }
+
+ pc += sz_xGLXVendorPrivateReq;
+ buf_size = (req->length << 2) - sz_xGLXVendorPrivateReq;
+
+ dmxScreen = &dmxScreens[glxc->pScreen->myNum];
+ dpy = GetBackEndDisplay(cl, glxc->pScreen->myNum);
+
+ /*
+ * send the request to the first back-end server
+ */
+ LockDisplay(dpy);
+ GetReqVendorPrivate(GLXVendorPrivate,be_req);
+ be_req->reqType = dmxScreen->glxMajorOpcode;
+ be_req->glxCode = req->glxCode;
+ be_req->length = req->length;
+ be_req->vendorCode = req->vendorCode;
+ be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag, glxc->pScreen->myNum);
+ if (buf_size > 0)
+ _XSend(dpy, (const char *)pc, buf_size);
+
+ /*
+ * get the reply from the back-end server
+ */
+ _XReply(dpy, (xReply*) &be_reply, 0, False);
+ be_buf_size = be_reply.length << 2;
+ if (be_buf_size > 0) {
+ be_buf = (char *)malloc( be_buf_size );
+ if (be_buf) {
+ _XRead(dpy, be_buf, be_buf_size);
+ }
+ else {
+ /* Throw data on the floor */
+ _XEatData(dpy, be_buf_size);
+ return BadAlloc;
+ }
+ }
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ /*
+ * send the reply to the client
+ */
+ memcpy( &reply, &be_reply, sz_xGLXVendorPrivReply );
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+
+ if (client->swapped) {
+ SendSwappedReply( client, &reply, be_buf, be_buf_size );
+ }
+ else {
+ WriteToClient(client, sizeof(xGLXVendorPrivReply),(char *)&reply);
+ if (be_buf_size > 0)
+ WriteToClient(client, be_buf_size, (char *)be_buf);
+ }
+
+ if (be_buf_size > 0) Xfree(be_buf);
+
+ return Success;
+}
+
+int __glXVForwardAllWithReply( __GLXclientState *cl, GLbyte *pc )
+{
+ ClientPtr client = cl->client;
+ xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
+ xGLXVendorPrivateReq *be_req;
+ xGLXVendorPrivReply reply;
+ xGLXVendorPrivReply be_reply;
+ __GLXcontext *glxc;
+ int buf_size;
+ char *be_buf;
+ int be_buf_size;
+ int from_screen = 0;
+ int to_screen = 0;
+ int s;
+
+ DMXScreenInfo *dmxScreen;
+ Display *dpy;
+
+ glxc = __glXLookupContextByTag(cl, req->contextTag);
+ if (!glxc) {
+ return 0;
+ }
+ from_screen = to_screen = glxc->pScreen->myNum;
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ from_screen = 0;
+ to_screen = screenInfo.numScreens - 1;
+ }
+#endif
+
+ pc += sz_xGLXVendorPrivateReq;
+ buf_size = (req->length << 2) - sz_xGLXVendorPrivateReq;
+
+ /*
+ * send the request to the first back-end server(s)
+ */
+ for (s=to_screen; s>=from_screen; s--) {
+ dmxScreen = &dmxScreens[s];
+ dpy = GetBackEndDisplay(cl,s);
+
+ LockDisplay(dpy);
+ GetReqVendorPrivate(GLXVendorPrivate,be_req);
+ be_req->reqType = dmxScreen->glxMajorOpcode;
+ be_req->glxCode = req->glxCode;
+ be_req->length = req->length;
+ be_req->vendorCode = req->vendorCode;
+ be_req->contextTag = GetCurrentBackEndTag(cl,req->contextTag,s);
+ if (buf_size > 0)
+ _XSend(dpy, (const char *)pc, buf_size);
+
+ /*
+ * get the reply from the back-end server
+ */
+ _XReply(dpy, (xReply*) &be_reply, 0, False);
+ be_buf_size = be_reply.length << 2;
+ if (be_buf_size > 0) {
+ be_buf = (char *)malloc( be_buf_size );
+ if (be_buf) {
+ _XRead(dpy, be_buf, be_buf_size);
+ }
+ else {
+ /* Throw data on the floor */
+ _XEatData(dpy, be_buf_size);
+ return BadAlloc;
+ }
+ }
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ if (s > from_screen && be_buf_size > 0) {
+ Xfree(be_buf);
+ }
+ }
+
+ /*
+ * send the reply to the client
+ */
+ memcpy( &reply, &be_reply, sz_xGLXVendorPrivReply );
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+
+ if (client->swapped) {
+ SendSwappedReply( client, &reply, be_buf, be_buf_size );
+ }
+ else {
+ WriteToClient(client, sizeof(xGLXVendorPrivReply),(char *)&reply);
+ if (be_buf_size > 0)
+ WriteToClient(client, be_buf_size, (char *)be_buf);
+ }
+
+ if (be_buf_size > 0) Xfree(be_buf);
+
+ return Success;
+}
+
+int __glXVForwardSingleReqSwap( __GLXclientState *cl, GLbyte *pc )
+{
+ xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->vendorCode);
+ __GLX_SWAP_INT(&req->contextTag);
+
+ swap_vec_element_size = 0;
+
+ return( __glXVForwardSingleReq( cl, pc ) );
+}
+
+int __glXVForwardPipe0WithReplySwap( __GLXclientState *cl, GLbyte *pc )
+{
+ xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->vendorCode);
+ __GLX_SWAP_INT(&req->contextTag);
+
+ swap_vec_element_size = 0;
+
+ /*
+ * swap extra data in request - assuming all data
+ * (if available) are arrays of 4 bytes components !
+ */
+ if (req->length > sz_xGLXVendorPrivateReq/4) {
+ int *data = (int *)(req+1);
+ int count = req->length - sz_xGLXVendorPrivateReq/4;
+ __GLX_SWAP_INT_ARRAY(data, count );
+ }
+
+ return( __glXVForwardPipe0WithReply( cl, pc ) );
+}
+
+int __glXVForwardPipe0WithReplySwapsv( __GLXclientState *cl, GLbyte *pc )
+{
+ xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->vendorCode);
+ __GLX_SWAP_INT(&req->contextTag);
+
+ swap_vec_element_size = 2;
+
+ /*
+ * swap extra data in request - assuming all data
+ * (if available) are arrays of 4 bytes components !
+ */
+ if (req->length > sz_xGLXVendorPrivateReq/4) {
+ int *data = (int *)(req+1);
+ int count = req->length - sz_xGLXVendorPrivateReq/4;
+ __GLX_SWAP_INT_ARRAY(data, count );
+ }
+
+ return( __glXVForwardPipe0WithReply( cl, pc ) );
+}
+
+int __glXVForwardPipe0WithReplySwapiv( __GLXclientState *cl, GLbyte *pc )
+{
+ xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->vendorCode);
+ __GLX_SWAP_INT(&req->contextTag);
+
+ swap_vec_element_size = 4;
+
+ /*
+ * swap extra data in request - assuming all data
+ * (if available) are arrays of 4 bytes components !
+ */
+ if (req->length > sz_xGLXVendorPrivateReq/4) {
+ int *data = (int *)(req+1);
+ int count = req->length - sz_xGLXVendorPrivateReq/4;
+ __GLX_SWAP_INT_ARRAY(data, count );
+ }
+
+ return( __glXVForwardPipe0WithReply( cl, pc ) );
+}
+
+int __glXVForwardPipe0WithReplySwapdv( __GLXclientState *cl, GLbyte *pc )
+{
+ xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->vendorCode);
+ __GLX_SWAP_INT(&req->contextTag);
+
+ swap_vec_element_size = 8;
+
+ /*
+ * swap extra data in request - assuming all data
+ * (if available) are arrays of 4 bytes components !
+ */
+ if (req->length > sz_xGLXVendorPrivateReq/4) {
+ int *data = (int *)(req+1);
+ int count = req->length - sz_xGLXVendorPrivateReq/4;
+ __GLX_SWAP_INT_ARRAY(data, count );
+ }
+
+ return( __glXVForwardPipe0WithReply( cl, pc ) );
+}
+
+int __glXVForwardAllWithReplySwap( __GLXclientState *cl, GLbyte *pc )
+{
+ xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->vendorCode);
+ __GLX_SWAP_INT(&req->contextTag);
+
+ swap_vec_element_size = 0;
+
+ /*
+ * swap extra data in request - assuming all data
+ * (if available) are arrays of 4 bytes components !
+ */
+ if (req->length > sz_xGLXVendorPrivateReq/4) {
+ int *data = (int *)(req+1);
+ int count = req->length - sz_xGLXVendorPrivateReq/4;
+ __GLX_SWAP_INT_ARRAY(data, count );
+ }
+
+ return( __glXVForwardAllWithReply( cl, pc ) );
+}
+
+int __glXVForwardAllWithReplySwapsv( __GLXclientState *cl, GLbyte *pc )
+{
+ xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->vendorCode);
+ __GLX_SWAP_INT(&req->contextTag);
+
+ swap_vec_element_size = 2;
+
+ /*
+ * swap extra data in request - assuming all data
+ * (if available) are arrays of 4 bytes components !
+ */
+ if (req->length > sz_xGLXVendorPrivateReq/4) {
+ int *data = (int *)(req+1);
+ int count = req->length - sz_xGLXVendorPrivateReq/4;
+ __GLX_SWAP_INT_ARRAY(data, count );
+ }
+
+ return( __glXVForwardAllWithReply( cl, pc ) );
+}
+
+int __glXVForwardAllWithReplySwapiv( __GLXclientState *cl, GLbyte *pc )
+{
+ xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->vendorCode);
+ __GLX_SWAP_INT(&req->contextTag);
+
+ swap_vec_element_size = 4;
+
+ /*
+ * swap extra data in request - assuming all data
+ * (if available) are arrays of 4 bytes components !
+ */
+ if (req->length > sz_xGLXVendorPrivateReq/4) {
+ int *data = (int *)(req+1);
+ int count = req->length - sz_xGLXVendorPrivateReq/4;
+ __GLX_SWAP_INT_ARRAY(data, count );
+ }
+
+ return( __glXVForwardAllWithReply( cl, pc ) );
+}
+
+int __glXVForwardAllWithReplySwapdv( __GLXclientState *cl, GLbyte *pc )
+{
+ xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *)pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->vendorCode);
+ __GLX_SWAP_INT(&req->contextTag);
+
+ swap_vec_element_size = 8;
+
+ /*
+ * swap extra data in request - assuming all data
+ * (if available) are arrays of 4 bytes components !
+ */
+ if (req->length > sz_xGLXVendorPrivateReq/4) {
+ int *data = (int *)(req+1);
+ int count = req->length - sz_xGLXVendorPrivateReq/4;
+ __GLX_SWAP_INT_ARRAY(data, count );
+ }
+
+ return( __glXVForwardAllWithReply( cl, pc ) );
+}
+
diff --git a/xorg-server/hw/dmx/glxProxy/glxvisuals.c b/xorg-server/hw/dmx/glxProxy/glxvisuals.c
index 898c6be7b..6e30b4edc 100644
--- a/xorg-server/hw/dmx/glxProxy/glxvisuals.c
+++ b/xorg-server/hw/dmx/glxProxy/glxvisuals.c
@@ -1,539 +1,539 @@
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, 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 including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * 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
- * SILICON GRAPHICS, INC. 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 Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
-
-#include <assert.h>
-#include "dmx.h"
-#include "glxserver.h"
-#include "glxutil.h"
-#include "dmx_glxvisuals.h"
-#include <stdlib.h>
-
-static int numConfigs = 0;
-static __GLXvisualConfig *visualConfigs = NULL;
-static void **visualPrivates = NULL;
-
-int glxVisualsMatch( __GLXvisualConfig *v1, __GLXvisualConfig *v2 )
-{
- if ( (v1->class == v2->class) &&
- (v1->rgba == v2->rgba) &&
- (v1->redSize == v2->redSize) &&
- (v1->greenSize == v2->greenSize) &&
- (v1->blueSize == v2->blueSize) &&
- (v1->alphaSize == v2->alphaSize) &&
- (v1->redMask == v2->redMask) &&
- (v1->greenMask == v2->greenMask) &&
- (v1->blueMask == v2->blueMask) &&
- (v1->alphaMask == v2->alphaMask) &&
- (v1->accumRedSize == v2->accumRedSize) &&
- (v1->accumGreenSize == v2->accumGreenSize) &&
- (v1->accumBlueSize == v2->accumBlueSize) &&
- (v1->accumAlphaSize == v2->accumAlphaSize) &&
- (v1->doubleBuffer == v2->doubleBuffer) &&
- (v1->stereo == v2->stereo) &&
- (v1->bufferSize == v2->bufferSize) &&
- (v1->depthSize == v2->depthSize) &&
- (v1->stencilSize == v2->stencilSize) &&
- (v1->auxBuffers == v2->auxBuffers) &&
- (v1->level == v2->level) &&
- (v1->visualRating == v2->visualRating) &&
- (v1->transparentPixel == v2->transparentPixel) &&
- (v1->transparentRed == v2->transparentRed) &&
- (v1->transparentGreen == v2->transparentGreen) &&
- (v1->transparentBlue == v2->transparentBlue) &&
- (v1->transparentAlpha == v2->transparentAlpha) &&
- (v1->transparentIndex == v2->transparentIndex) &&
- (v1->multiSampleSize == v2->multiSampleSize) &&
- (v1->nMultiSampleBuffers == v2->nMultiSampleBuffers) &&
- (v1->visualSelectGroup == v2->visualSelectGroup) ) {
-
- return(1);
-
- }
-
- return(0);
-
-}
-
-VisualID glxMatchGLXVisualInConfigList( __GLXvisualConfig *pGlxVisual, __GLXvisualConfig *configs, int nconfigs )
-{
- int i;
-
- for (i=0; i<nconfigs; i++) {
-
- if (glxVisualsMatch( pGlxVisual, &configs[i] )) {
-
- return( configs[i].vid );
-
- }
- }
-
- return(0);
-}
-
-VisualID glxMatchVisualInConfigList( ScreenPtr pScreen, VisualPtr pVisual, __GLXvisualConfig *configs, int nconfigs )
-{
- __GLXscreenInfo *pGlxScreen;
- __GLXvisualConfig *pGlxVisual;
- int i;
-
- /* check that the glx extension has been initialized */
- if ( !__glXActiveScreens )
- return(0);
-
- pGlxScreen = &__glXActiveScreens[pScreen->myNum];
- pGlxVisual = pGlxScreen->pGlxVisual;
-
- /* find the glx visual info for pVisual */
- for (i = 0; i < pGlxScreen->numVisuals; i++, pGlxVisual++) {
- if (pGlxVisual->vid == pVisual->vid) {
- break;
- }
- }
- if (i == pGlxScreen->numVisuals) {
- /*
- * the visual is not supported by glx
- */
- return(0);
- }
-
- return( glxMatchGLXVisualInConfigList(pGlxVisual, configs, nconfigs) );
-}
-
-VisualPtr glxMatchVisual( ScreenPtr pScreen, VisualPtr pVisual, ScreenPtr pMatchScreen )
-{
- __GLXscreenInfo *pGlxScreen2;
- int j;
- VisualID vid;
-
- /* check that the glx extension has been initialized */
- if ( !__glXActiveScreens )
- return NULL;
-
- pGlxScreen2 = &__glXActiveScreens[pMatchScreen->myNum];
-
- vid = glxMatchVisualInConfigList( pScreen, pVisual,
- pGlxScreen2->pGlxVisual,
- pGlxScreen2->numVisuals );
- if (vid) {
- /*
- * find the X visual of the matching glx visual
- */
- for (j=0; j<pMatchScreen->numVisuals; j++) {
- if (vid == pMatchScreen->visuals[j].vid) {
- return( &pMatchScreen->visuals[j] );
- }
- }
- }
-
- return(0);
-}
-
-void glxSetVisualConfigs(int nconfigs, __GLXvisualConfig *configs,
- void **privates)
-{
- numConfigs = nconfigs;
- visualConfigs = configs;
- visualPrivates = privates;
-}
-
-static int count_bits(unsigned int n)
-{
- int bits = 0;
-
- while (n > 0) {
- if (n & 1) bits++;
- n >>= 1;
- }
- return bits;
-}
-
-static VisualID FindClosestVisual( VisualPtr pVisual, int rootDepth,
- DepthPtr pdepth, int ndepths,
- VisualPtr pNewVisual, int numNewVisuals)
-{
- int d, v;
- VisualPtr vis;
-
- /*
- * find the first visual with the same or deeper depth
- * of the same class.
- */
- for (d=0; d<ndepths; d++) {
- if (pdepth[d].depth >= rootDepth) {
- for (v=0; v<pdepth[d].numVids; v++) {
-
- /* find the new visual structure */
- vis = pNewVisual;
- while( pdepth[d].vids[v] != vis->vid ) vis++;
-
- if (vis->class == pVisual->class) {
- return( pdepth[d].vids[v] );
- }
- }
- }
- }
-
- /*
- * did not find any.
- * try to look for the same class only.
- */
- for (d=0; d<ndepths; d++) {
- for (v=0; v<pdepth[d].numVids; v++) {
-
- /* find the new visual structure */
- vis = pNewVisual;
- while( pdepth[d].vids[v] != vis->vid ) vis++;
-
- if (vis->class == pVisual->class) {
- return( pdepth[d].vids[v] );
- }
- }
- }
-
- /*
- * if not found - just take the first visual
- */
- return( pdepth[0].vids[0] );
-}
-
-Bool glxInitVisuals(int *nvisualp, VisualPtr *visualp,
- VisualID *defaultVisp,
- int ndepth, DepthPtr pdepth,
- int rootDepth)
-{
- int numRGBconfigs;
- int numCIconfigs;
- int numVisuals = *nvisualp;
- int numNewVisuals;
- int numNewConfigs;
- VisualPtr pVisual = *visualp;
- VisualPtr pVisualNew = NULL;
- VisualID *orig_vid = NULL;
- __GLXvisualConfig *glXVisualPtr = NULL;
- __GLXvisualConfig *pNewVisualConfigs = NULL;
- void **glXVisualPriv;
- dmxGlxVisualPrivate **pNewVisualPriv;
- int found_default;
- int i, j, k;
- int numGLXvis = 0;
- GLint *isGLXvis;
-
- if (numConfigs > 0)
- numNewConfigs = numConfigs;
- else
- return False;
-
- MAXSCREENSALLOC(__glXActiveScreens);
- if (!__glXActiveScreens)
- return False;
-
- /* Alloc space for the list of new GLX visuals */
- pNewVisualConfigs = (__GLXvisualConfig *)
- __glXMalloc(numNewConfigs * sizeof(__GLXvisualConfig));
- if (!pNewVisualConfigs) {
- return FALSE;
- }
-
- /* Alloc space for the list of new GLX visual privates */
- pNewVisualPriv = (dmxGlxVisualPrivate **) __glXMalloc(numNewConfigs * sizeof(dmxGlxVisualPrivate *));
- if (!pNewVisualPriv) {
- __glXFree(pNewVisualConfigs);
- return FALSE;
- }
-
- /* copy driver's visual config info */
- for (i = 0; i < numConfigs; i++) {
- pNewVisualConfigs[i] = visualConfigs[i];
- pNewVisualPriv[i] = (dmxGlxVisualPrivate *)visualPrivates[i];
- }
-
-#if 1
- /* FIXME: This is a hack to workaround a hang in xtest caused by a
- * mismatch between what the front end (i.e., DMX) server calculates
- * for the visual configs and what the back-end servers have.
- */
- {
- int numTCRGBconfigs = 0;
- int numDCRGBconfigs = 0;
-
- numRGBconfigs = 0;
- numCIconfigs = 0;
-
- for (i = 0; i < numNewConfigs; i++) {
- if (pNewVisualConfigs[i].rgba) {
- if (pNewVisualConfigs[i].class == TrueColor)
- numTCRGBconfigs++;
- else
- numDCRGBconfigs++;
- numRGBconfigs++;
- } else
- numCIconfigs++;
- }
-
- /* Count the total number of visuals to compute */
- numNewVisuals = 0;
- for (i = 0; i < numVisuals; i++) {
- numNewVisuals +=
- (pVisual[i].class == TrueColor) ? numTCRGBconfigs :
- (pVisual[i].class == DirectColor) ? numDCRGBconfigs :
- numCIconfigs;
- }
- }
-#else
- /* Count the number of RGB and CI visual configs */
- numRGBconfigs = 0;
- numCIconfigs = 0;
- for (i = 0; i < numNewConfigs; i++) {
- if (pNewVisualConfigs[i].rgba)
- numRGBconfigs++;
- else
- numCIconfigs++;
- }
-
- /* Count the total number of visuals to compute */
- numNewVisuals = 0;
- for (i = 0; i < numVisuals; i++) {
- numNewVisuals +=
- (pVisual[i].class == TrueColor || pVisual[i].class == DirectColor)
- ? numRGBconfigs : numCIconfigs;
- }
-#endif
-
- /* Reset variables for use with the next screen/driver's visual configs */
- visualConfigs = NULL;
- numConfigs = 0;
-
- /* Alloc temp space for the list of orig VisualIDs for each new visual */
- orig_vid = (VisualID *)__glXMalloc(numNewVisuals * sizeof(VisualID));
- if (!orig_vid) {
- __glXFree(pNewVisualPriv);
- __glXFree(pNewVisualConfigs);
- return FALSE;
- }
-
- /* Alloc space for the list of glXVisuals */
- glXVisualPtr = (__GLXvisualConfig *)__glXMalloc(numNewVisuals *
- sizeof(__GLXvisualConfig));
- if (!glXVisualPtr) {
- __glXFree(orig_vid);
- __glXFree(pNewVisualPriv);
- __glXFree(pNewVisualConfigs);
- return FALSE;
- }
-
- /* Alloc space for the list of glXVisualPrivates */
- glXVisualPriv = (void **)__glXMalloc(numNewVisuals * sizeof(void *));
- if (!glXVisualPriv) {
- __glXFree(glXVisualPtr);
- __glXFree(orig_vid);
- __glXFree(pNewVisualPriv);
- __glXFree(pNewVisualConfigs);
- return FALSE;
- }
-
- /* Alloc space for the new list of the X server's visuals */
- pVisualNew = (VisualPtr)__glXMalloc(numNewVisuals * sizeof(VisualRec));
- if (!pVisualNew) {
- __glXFree(glXVisualPriv);
- __glXFree(glXVisualPtr);
- __glXFree(orig_vid);
- __glXFree(pNewVisualPriv);
- __glXFree(pNewVisualConfigs);
- return FALSE;
- }
-
- isGLXvis = (GLint *) __glXMalloc(numNewVisuals * sizeof(GLint));
- if (!isGLXvis) {
- __glXFree(glXVisualPriv);
- __glXFree(glXVisualPtr);
- __glXFree(orig_vid);
- __glXFree(pNewVisualPriv);
- __glXFree(pNewVisualConfigs);
- __glXFree(pVisualNew);
- return FALSE;
- }
-
- /* Initialize the new visuals */
- found_default = FALSE;
- for (i = j = 0; i < numVisuals; i++) {
-
- for (k = 0; k < numNewConfigs; k++) {
-
- int new_depth;
- int depth;
- int d,v;
-
- /* find the depth of the new visual config */
- new_depth = pNewVisualPriv[k]->x_visual_depth;
-
- /* find the depth of the original visual */
- depth = 0;
- d = 0;
- while( (depth==0) && (d < ndepth) ) {
- v = 0;
- while( (depth==0) && (v < pdepth[d].numVids) ) {
- if (pdepth[d].vids[v] == pVisual[i].vid) {
- depth = pdepth[d].depth;
- }
- v++;
- }
- d++;
- }
-
- /* check that the visual has the same class and depth
- * as the new config
- */
- if ( pVisual[i].class != pNewVisualPriv[k]->x_visual_class ||
- (depth != new_depth) )
- continue;
-
- /* Initialize the new visual */
- pVisualNew[j] = pVisual[i];
- pVisualNew[j].vid = FakeClientID(0);
-
- /* Check for the default visual */
- if (!found_default && pVisual[i].vid == *defaultVisp) {
- *defaultVisp = pVisualNew[j].vid;
- found_default = TRUE;
- }
-
- /* Save the old VisualID */
- orig_vid[j] = pVisual[i].vid;
-
- /* Initialize the glXVisual */
- glXVisualPtr[j] = pNewVisualConfigs[k];
- glXVisualPtr[j].vid = pVisualNew[j].vid;
-
- /*
- * If the class is -1, then assume the X visual information
- * is identical to what GLX needs, and take them from the X
- * visual. NOTE: if class != -1, then all other fields MUST
- * be initialized.
- */
- if (glXVisualPtr[j].class == -1) {
- glXVisualPtr[j].class = pVisual[i].class;
- glXVisualPtr[j].redSize = count_bits(pVisual[i].redMask);
- glXVisualPtr[j].greenSize = count_bits(pVisual[i].greenMask);
- glXVisualPtr[j].blueSize = count_bits(pVisual[i].blueMask);
- glXVisualPtr[j].alphaSize = glXVisualPtr[j].alphaSize;
- glXVisualPtr[j].redMask = pVisual[i].redMask;
- glXVisualPtr[j].greenMask = pVisual[i].greenMask;
- glXVisualPtr[j].blueMask = pVisual[i].blueMask;
- glXVisualPtr[j].alphaMask = glXVisualPtr[j].alphaMask;
- glXVisualPtr[j].bufferSize = rootDepth;
- }
-
- /* Save the device-dependent private for this visual */
- glXVisualPriv[j] = pNewVisualPriv[k];
-
- isGLXvis[j] = glxMatchGLXVisualInConfigList( &glXVisualPtr[j],
- dmxScreens[screenInfo.numScreens-1].glxVisuals,
- dmxScreens[screenInfo.numScreens-1].numGlxVisuals );
- if (isGLXvis[j]) numGLXvis++;
-
- j++;
- }
- }
-
- assert(j <= numNewVisuals);
- numNewVisuals = j; /* correct number of new visuals */
-
- /* Save the GLX visuals in the screen structure */
- __glXActiveScreens[screenInfo.numScreens-1].numVisuals = numNewVisuals;
- __glXActiveScreens[screenInfo.numScreens-1].numGLXVisuals = numGLXvis;
- __glXActiveScreens[screenInfo.numScreens-1].isGLXvis = isGLXvis;
- __glXActiveScreens[screenInfo.numScreens-1].pGlxVisual = glXVisualPtr;
-
-
- /* Set up depth's VisualIDs */
- for (i = 0; i < ndepth; i++) {
- int numVids = 0;
- VisualID *pVids = NULL;
- int k, n = 0;
-
- /* Count the new number of VisualIDs at this depth */
- for (j = 0; j < pdepth[i].numVids; j++)
- for (k = 0; k < numNewVisuals; k++)
- if (pdepth[i].vids[j] == orig_vid[k])
- numVids++;
-
- /* Allocate a new list of VisualIDs for this depth */
- pVids = (VisualID *)__glXMalloc(numVids * sizeof(VisualID));
-
- /* Initialize the new list of VisualIDs for this depth */
- for (j = 0; j < pdepth[i].numVids; j++)
- for (k = 0; k < numNewVisuals; k++)
- if (pdepth[i].vids[j] == orig_vid[k])
- pVids[n++] = pVisualNew[k].vid;
-
- /* Update this depth's list of VisualIDs */
- __glXFree(pdepth[i].vids);
- pdepth[i].vids = pVids;
- pdepth[i].numVids = numVids;
- }
-
- /*
- * if the default visual was rejected - need to choose new
- * default visual !
- */
- if ( !found_default ) {
-
- for (i=0; i<numVisuals; i++)
- if (pVisual[i].vid == *defaultVisp)
- break;
-
- if (i < numVisuals) {
- *defaultVisp = FindClosestVisual( &pVisual[i], rootDepth, pdepth, ndepth, pVisualNew, numNewVisuals );
- }
- }
-
- /* Update the X server's visuals */
- *nvisualp = numNewVisuals;
- *visualp = pVisualNew;
-
- /* Free the old list of the X server's visuals */
- __glXFree(pVisual);
-
- /* Clean up temporary allocations */
- __glXFree(orig_vid);
- __glXFree(pNewVisualPriv);
- __glXFree(pNewVisualConfigs);
-
- /* Free the private list created by DDX HW driver */
- if (visualPrivates)
- xfree(visualPrivates);
- visualPrivates = NULL;
-
- return TRUE;
-}
+/*
+ * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
+ * Copyright (C) 1991-2000 Silicon Graphics, 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 including the dates of first publication and
+ * either this permission notice or a reference to
+ * http://oss.sgi.com/projects/FreeB/
+ * 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
+ * SILICON GRAPHICS, INC. 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 Silicon Graphics, Inc.
+ * shall not be used in advertising or otherwise to promote the sale, use or
+ * other dealings in this Software without prior written authorization from
+ * Silicon Graphics, Inc.
+ */
+
+#ifdef HAVE_DMX_CONFIG_H
+#include <dmx-config.h>
+#endif
+
+#include <assert.h>
+#include "dmx.h"
+#include "glxserver.h"
+#include "glxutil.h"
+#include "dmx_glxvisuals.h"
+#include <stdlib.h>
+
+static int numConfigs = 0;
+static __GLXvisualConfig *visualConfigs = NULL;
+static void **visualPrivates = NULL;
+
+int glxVisualsMatch( __GLXvisualConfig *v1, __GLXvisualConfig *v2 )
+{
+ if ( (v1->class == v2->class) &&
+ (v1->rgba == v2->rgba) &&
+ (v1->redSize == v2->redSize) &&
+ (v1->greenSize == v2->greenSize) &&
+ (v1->blueSize == v2->blueSize) &&
+ (v1->alphaSize == v2->alphaSize) &&
+ (v1->redMask == v2->redMask) &&
+ (v1->greenMask == v2->greenMask) &&
+ (v1->blueMask == v2->blueMask) &&
+ (v1->alphaMask == v2->alphaMask) &&
+ (v1->accumRedSize == v2->accumRedSize) &&
+ (v1->accumGreenSize == v2->accumGreenSize) &&
+ (v1->accumBlueSize == v2->accumBlueSize) &&
+ (v1->accumAlphaSize == v2->accumAlphaSize) &&
+ (v1->doubleBuffer == v2->doubleBuffer) &&
+ (v1->stereo == v2->stereo) &&
+ (v1->bufferSize == v2->bufferSize) &&
+ (v1->depthSize == v2->depthSize) &&
+ (v1->stencilSize == v2->stencilSize) &&
+ (v1->auxBuffers == v2->auxBuffers) &&
+ (v1->level == v2->level) &&
+ (v1->visualRating == v2->visualRating) &&
+ (v1->transparentPixel == v2->transparentPixel) &&
+ (v1->transparentRed == v2->transparentRed) &&
+ (v1->transparentGreen == v2->transparentGreen) &&
+ (v1->transparentBlue == v2->transparentBlue) &&
+ (v1->transparentAlpha == v2->transparentAlpha) &&
+ (v1->transparentIndex == v2->transparentIndex) &&
+ (v1->multiSampleSize == v2->multiSampleSize) &&
+ (v1->nMultiSampleBuffers == v2->nMultiSampleBuffers) &&
+ (v1->visualSelectGroup == v2->visualSelectGroup) ) {
+
+ return(1);
+
+ }
+
+ return(0);
+
+}
+
+VisualID glxMatchGLXVisualInConfigList( __GLXvisualConfig *pGlxVisual, __GLXvisualConfig *configs, int nconfigs )
+{
+ int i;
+
+ for (i=0; i<nconfigs; i++) {
+
+ if (glxVisualsMatch( pGlxVisual, &configs[i] )) {
+
+ return( configs[i].vid );
+
+ }
+ }
+
+ return(0);
+}
+
+VisualID glxMatchVisualInConfigList( ScreenPtr pScreen, VisualPtr pVisual, __GLXvisualConfig *configs, int nconfigs )
+{
+ __GLXscreenInfo *pGlxScreen;
+ __GLXvisualConfig *pGlxVisual;
+ int i;
+
+ /* check that the glx extension has been initialized */
+ if ( !__glXActiveScreens )
+ return(0);
+
+ pGlxScreen = &__glXActiveScreens[pScreen->myNum];
+ pGlxVisual = pGlxScreen->pGlxVisual;
+
+ /* find the glx visual info for pVisual */
+ for (i = 0; i < pGlxScreen->numVisuals; i++, pGlxVisual++) {
+ if (pGlxVisual->vid == pVisual->vid) {
+ break;
+ }
+ }
+ if (i == pGlxScreen->numVisuals) {
+ /*
+ * the visual is not supported by glx
+ */
+ return(0);
+ }
+
+ return( glxMatchGLXVisualInConfigList(pGlxVisual, configs, nconfigs) );
+}
+
+VisualPtr glxMatchVisual( ScreenPtr pScreen, VisualPtr pVisual, ScreenPtr pMatchScreen )
+{
+ __GLXscreenInfo *pGlxScreen2;
+ int j;
+ VisualID vid;
+
+ /* check that the glx extension has been initialized */
+ if ( !__glXActiveScreens )
+ return NULL;
+
+ pGlxScreen2 = &__glXActiveScreens[pMatchScreen->myNum];
+
+ vid = glxMatchVisualInConfigList( pScreen, pVisual,
+ pGlxScreen2->pGlxVisual,
+ pGlxScreen2->numVisuals );
+ if (vid) {
+ /*
+ * find the X visual of the matching glx visual
+ */
+ for (j=0; j<pMatchScreen->numVisuals; j++) {
+ if (vid == pMatchScreen->visuals[j].vid) {
+ return( &pMatchScreen->visuals[j] );
+ }
+ }
+ }
+
+ return(0);
+}
+
+void glxSetVisualConfigs(int nconfigs, __GLXvisualConfig *configs,
+ void **privates)
+{
+ numConfigs = nconfigs;
+ visualConfigs = configs;
+ visualPrivates = privates;
+}
+
+static int count_bits(unsigned int n)
+{
+ int bits = 0;
+
+ while (n > 0) {
+ if (n & 1) bits++;
+ n >>= 1;
+ }
+ return bits;
+}
+
+static VisualID FindClosestVisual( VisualPtr pVisual, int rootDepth,
+ DepthPtr pdepth, int ndepths,
+ VisualPtr pNewVisual, int numNewVisuals)
+{
+ int d, v;
+ VisualPtr vis;
+
+ /*
+ * find the first visual with the same or deeper depth
+ * of the same class.
+ */
+ for (d=0; d<ndepths; d++) {
+ if (pdepth[d].depth >= rootDepth) {
+ for (v=0; v<pdepth[d].numVids; v++) {
+
+ /* find the new visual structure */
+ vis = pNewVisual;
+ while( pdepth[d].vids[v] != vis->vid ) vis++;
+
+ if (vis->class == pVisual->class) {
+ return( pdepth[d].vids[v] );
+ }
+ }
+ }
+ }
+
+ /*
+ * did not find any.
+ * try to look for the same class only.
+ */
+ for (d=0; d<ndepths; d++) {
+ for (v=0; v<pdepth[d].numVids; v++) {
+
+ /* find the new visual structure */
+ vis = pNewVisual;
+ while( pdepth[d].vids[v] != vis->vid ) vis++;
+
+ if (vis->class == pVisual->class) {
+ return( pdepth[d].vids[v] );
+ }
+ }
+ }
+
+ /*
+ * if not found - just take the first visual
+ */
+ return( pdepth[0].vids[0] );
+}
+
+Bool glxInitVisuals(int *nvisualp, VisualPtr *visualp,
+ VisualID *defaultVisp,
+ int ndepth, DepthPtr pdepth,
+ int rootDepth)
+{
+ int numRGBconfigs;
+ int numCIconfigs;
+ int numVisuals = *nvisualp;
+ int numNewVisuals;
+ int numNewConfigs;
+ VisualPtr pVisual = *visualp;
+ VisualPtr pVisualNew = NULL;
+ VisualID *orig_vid = NULL;
+ __GLXvisualConfig *glXVisualPtr = NULL;
+ __GLXvisualConfig *pNewVisualConfigs = NULL;
+ void **glXVisualPriv;
+ dmxGlxVisualPrivate **pNewVisualPriv;
+ int found_default;
+ int i, j, k;
+ int numGLXvis = 0;
+ GLint *isGLXvis;
+
+ if (numConfigs > 0)
+ numNewConfigs = numConfigs;
+ else
+ return False;
+
+ MAXSCREENSALLOC(__glXActiveScreens);
+ if (!__glXActiveScreens)
+ return False;
+
+ /* Alloc space for the list of new GLX visuals */
+ pNewVisualConfigs = (__GLXvisualConfig *)
+ __glXMalloc(numNewConfigs * sizeof(__GLXvisualConfig));
+ if (!pNewVisualConfigs) {
+ return FALSE;
+ }
+
+ /* Alloc space for the list of new GLX visual privates */
+ pNewVisualPriv = (dmxGlxVisualPrivate **) __glXMalloc(numNewConfigs * sizeof(dmxGlxVisualPrivate *));
+ if (!pNewVisualPriv) {
+ __glXFree(pNewVisualConfigs);
+ return FALSE;
+ }
+
+ /* copy driver's visual config info */
+ for (i = 0; i < numConfigs; i++) {
+ pNewVisualConfigs[i] = visualConfigs[i];
+ pNewVisualPriv[i] = (dmxGlxVisualPrivate *)visualPrivates[i];
+ }
+
+#if 1
+ /* FIXME: This is a hack to workaround a hang in xtest caused by a
+ * mismatch between what the front end (i.e., DMX) server calculates
+ * for the visual configs and what the back-end servers have.
+ */
+ {
+ int numTCRGBconfigs = 0;
+ int numDCRGBconfigs = 0;
+
+ numRGBconfigs = 0;
+ numCIconfigs = 0;
+
+ for (i = 0; i < numNewConfigs; i++) {
+ if (pNewVisualConfigs[i].rgba) {
+ if (pNewVisualConfigs[i].class == TrueColor)
+ numTCRGBconfigs++;
+ else
+ numDCRGBconfigs++;
+ numRGBconfigs++;
+ } else
+ numCIconfigs++;
+ }
+
+ /* Count the total number of visuals to compute */
+ numNewVisuals = 0;
+ for (i = 0; i < numVisuals; i++) {
+ numNewVisuals +=
+ (pVisual[i].class == TrueColor) ? numTCRGBconfigs :
+ (pVisual[i].class == DirectColor) ? numDCRGBconfigs :
+ numCIconfigs;
+ }
+ }
+#else
+ /* Count the number of RGB and CI visual configs */
+ numRGBconfigs = 0;
+ numCIconfigs = 0;
+ for (i = 0; i < numNewConfigs; i++) {
+ if (pNewVisualConfigs[i].rgba)
+ numRGBconfigs++;
+ else
+ numCIconfigs++;
+ }
+
+ /* Count the total number of visuals to compute */
+ numNewVisuals = 0;
+ for (i = 0; i < numVisuals; i++) {
+ numNewVisuals +=
+ (pVisual[i].class == TrueColor || pVisual[i].class == DirectColor)
+ ? numRGBconfigs : numCIconfigs;
+ }
+#endif
+
+ /* Reset variables for use with the next screen/driver's visual configs */
+ visualConfigs = NULL;
+ numConfigs = 0;
+
+ /* Alloc temp space for the list of orig VisualIDs for each new visual */
+ orig_vid = (VisualID *)__glXMalloc(numNewVisuals * sizeof(VisualID));
+ if (!orig_vid) {
+ __glXFree(pNewVisualPriv);
+ __glXFree(pNewVisualConfigs);
+ return FALSE;
+ }
+
+ /* Alloc space for the list of glXVisuals */
+ glXVisualPtr = (__GLXvisualConfig *)__glXMalloc(numNewVisuals *
+ sizeof(__GLXvisualConfig));
+ if (!glXVisualPtr) {
+ __glXFree(orig_vid);
+ __glXFree(pNewVisualPriv);
+ __glXFree(pNewVisualConfigs);
+ return FALSE;
+ }
+
+ /* Alloc space for the list of glXVisualPrivates */
+ glXVisualPriv = (void **)__glXMalloc(numNewVisuals * sizeof(void *));
+ if (!glXVisualPriv) {
+ __glXFree(glXVisualPtr);
+ __glXFree(orig_vid);
+ __glXFree(pNewVisualPriv);
+ __glXFree(pNewVisualConfigs);
+ return FALSE;
+ }
+
+ /* Alloc space for the new list of the X server's visuals */
+ pVisualNew = (VisualPtr)__glXMalloc(numNewVisuals * sizeof(VisualRec));
+ if (!pVisualNew) {
+ __glXFree(glXVisualPriv);
+ __glXFree(glXVisualPtr);
+ __glXFree(orig_vid);
+ __glXFree(pNewVisualPriv);
+ __glXFree(pNewVisualConfigs);
+ return FALSE;
+ }
+
+ isGLXvis = (GLint *) __glXMalloc(numNewVisuals * sizeof(GLint));
+ if (!isGLXvis) {
+ __glXFree(glXVisualPriv);
+ __glXFree(glXVisualPtr);
+ __glXFree(orig_vid);
+ __glXFree(pNewVisualPriv);
+ __glXFree(pNewVisualConfigs);
+ __glXFree(pVisualNew);
+ return FALSE;
+ }
+
+ /* Initialize the new visuals */
+ found_default = FALSE;
+ for (i = j = 0; i < numVisuals; i++) {
+
+ for (k = 0; k < numNewConfigs; k++) {
+
+ int new_depth;
+ int depth;
+ int d,v;
+
+ /* find the depth of the new visual config */
+ new_depth = pNewVisualPriv[k]->x_visual_depth;
+
+ /* find the depth of the original visual */
+ depth = 0;
+ d = 0;
+ while( (depth==0) && (d < ndepth) ) {
+ v = 0;
+ while( (depth==0) && (v < pdepth[d].numVids) ) {
+ if (pdepth[d].vids[v] == pVisual[i].vid) {
+ depth = pdepth[d].depth;
+ }
+ v++;
+ }
+ d++;
+ }
+
+ /* check that the visual has the same class and depth
+ * as the new config
+ */
+ if ( pVisual[i].class != pNewVisualPriv[k]->x_visual_class ||
+ (depth != new_depth) )
+ continue;
+
+ /* Initialize the new visual */
+ pVisualNew[j] = pVisual[i];
+ pVisualNew[j].vid = FakeClientID(0);
+
+ /* Check for the default visual */
+ if (!found_default && pVisual[i].vid == *defaultVisp) {
+ *defaultVisp = pVisualNew[j].vid;
+ found_default = TRUE;
+ }
+
+ /* Save the old VisualID */
+ orig_vid[j] = pVisual[i].vid;
+
+ /* Initialize the glXVisual */
+ glXVisualPtr[j] = pNewVisualConfigs[k];
+ glXVisualPtr[j].vid = pVisualNew[j].vid;
+
+ /*
+ * If the class is -1, then assume the X visual information
+ * is identical to what GLX needs, and take them from the X
+ * visual. NOTE: if class != -1, then all other fields MUST
+ * be initialized.
+ */
+ if (glXVisualPtr[j].class == -1) {
+ glXVisualPtr[j].class = pVisual[i].class;
+ glXVisualPtr[j].redSize = count_bits(pVisual[i].redMask);
+ glXVisualPtr[j].greenSize = count_bits(pVisual[i].greenMask);
+ glXVisualPtr[j].blueSize = count_bits(pVisual[i].blueMask);
+ glXVisualPtr[j].alphaSize = glXVisualPtr[j].alphaSize;
+ glXVisualPtr[j].redMask = pVisual[i].redMask;
+ glXVisualPtr[j].greenMask = pVisual[i].greenMask;
+ glXVisualPtr[j].blueMask = pVisual[i].blueMask;
+ glXVisualPtr[j].alphaMask = glXVisualPtr[j].alphaMask;
+ glXVisualPtr[j].bufferSize = rootDepth;
+ }
+
+ /* Save the device-dependent private for this visual */
+ glXVisualPriv[j] = pNewVisualPriv[k];
+
+ isGLXvis[j] = glxMatchGLXVisualInConfigList( &glXVisualPtr[j],
+ dmxScreens[screenInfo.numScreens-1].glxVisuals,
+ dmxScreens[screenInfo.numScreens-1].numGlxVisuals );
+ if (isGLXvis[j]) numGLXvis++;
+
+ j++;
+ }
+ }
+
+ assert(j <= numNewVisuals);
+ numNewVisuals = j; /* correct number of new visuals */
+
+ /* Save the GLX visuals in the screen structure */
+ __glXActiveScreens[screenInfo.numScreens-1].numVisuals = numNewVisuals;
+ __glXActiveScreens[screenInfo.numScreens-1].numGLXVisuals = numGLXvis;
+ __glXActiveScreens[screenInfo.numScreens-1].isGLXvis = isGLXvis;
+ __glXActiveScreens[screenInfo.numScreens-1].pGlxVisual = glXVisualPtr;
+
+
+ /* Set up depth's VisualIDs */
+ for (i = 0; i < ndepth; i++) {
+ int numVids = 0;
+ VisualID *pVids = NULL;
+ int k, n = 0;
+
+ /* Count the new number of VisualIDs at this depth */
+ for (j = 0; j < pdepth[i].numVids; j++)
+ for (k = 0; k < numNewVisuals; k++)
+ if (pdepth[i].vids[j] == orig_vid[k])
+ numVids++;
+
+ /* Allocate a new list of VisualIDs for this depth */
+ pVids = (VisualID *)__glXMalloc(numVids * sizeof(VisualID));
+
+ /* Initialize the new list of VisualIDs for this depth */
+ for (j = 0; j < pdepth[i].numVids; j++)
+ for (k = 0; k < numNewVisuals; k++)
+ if (pdepth[i].vids[j] == orig_vid[k])
+ pVids[n++] = pVisualNew[k].vid;
+
+ /* Update this depth's list of VisualIDs */
+ __glXFree(pdepth[i].vids);
+ pdepth[i].vids = pVids;
+ pdepth[i].numVids = numVids;
+ }
+
+ /*
+ * if the default visual was rejected - need to choose new
+ * default visual !
+ */
+ if ( !found_default ) {
+
+ for (i=0; i<numVisuals; i++)
+ if (pVisual[i].vid == *defaultVisp)
+ break;
+
+ if (i < numVisuals) {
+ *defaultVisp = FindClosestVisual( &pVisual[i], rootDepth, pdepth, ndepth, pVisualNew, numNewVisuals );
+ }
+ }
+
+ /* Update the X server's visuals */
+ *nvisualp = numNewVisuals;
+ *visualp = pVisualNew;
+
+ /* Free the old list of the X server's visuals */
+ __glXFree(pVisual);
+
+ /* Clean up temporary allocations */
+ __glXFree(orig_vid);
+ __glXFree(pNewVisualPriv);
+ __glXFree(pNewVisualConfigs);
+
+ /* Free the private list created by DDX HW driver */
+ if (visualPrivates)
+ free(visualPrivates);
+ visualPrivates = NULL;
+
+ return TRUE;
+}
diff --git a/xorg-server/hw/dmx/glxProxy/unpack.h b/xorg-server/hw/dmx/glxProxy/unpack.h
index 98fa10ee7..73d0485e3 100644
--- a/xorg-server/hw/dmx/glxProxy/unpack.h
+++ b/xorg-server/hw/dmx/glxProxy/unpack.h
@@ -1,228 +1,228 @@
-#ifndef __GLX_unpack_h__
-#define __GLX_unpack_h__
-
-/*
- * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
- * Copyright (C) 1991-2000 Silicon Graphics, 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 including the dates of first publication and
- * either this permission notice or a reference to
- * http://oss.sgi.com/projects/FreeB/
- * 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
- * SILICON GRAPHICS, INC. 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 Silicon Graphics, Inc.
- * shall not be used in advertising or otherwise to promote the sale, use or
- * other dealings in this Software without prior written authorization from
- * Silicon Graphics, Inc.
- */
-
-#define __GLX_PAD(s) (((s)+3) & (GLuint)~3)
-
-/*
-** Fetch the context-id out of a SingleReq request pointed to by pc.
-*/
-#define __GLX_GET_SINGLE_CONTEXT_TAG(pc) (((xGLXSingleReq*)pc)->contextTag)
-#define __GLX_GET_VENDPRIV_CONTEXT_TAG(pc) (((xGLXVendorPrivateReq*)pc)->contextTag)
-
-/*
-** Fetch a double from potentially unaligned memory.
-*/
-#ifdef __GLX_ALIGN64
-#define __GLX_MEM_COPY(dst,src,n) memcpy(dst,src,n)
-#define __GLX_GET_DOUBLE(dst,src) __GLX_MEM_COPY(&dst,src,8)
-#else
-#define __GLX_GET_DOUBLE(dst,src) (dst) = *((GLdouble*)(src))
-#endif
-
-extern void __glXMemInit(void);
-
-extern xGLXSingleReply __glXReply;
-
-#define __GLX_BEGIN_REPLY(size) \
- __glXReply.length = __GLX_PAD(size) >> 2; \
- __glXReply.type = X_Reply; \
- __glXReply.sequenceNumber = client->sequence;
-
-#define __GLX_SEND_HEADER() \
- WriteToClient( client, sz_xGLXSingleReply, (char *)&__glXReply);
-
-#define __GLX_PUT_RETVAL(a) \
- __glXReply.retval = (a);
-
-#define __GLX_PUT_SIZE(a) \
- __glXReply.size = (a);
-
-#define __GLX_PUT_RENDERMODE(m) \
- __glXReply.pad3 = (m)
-
-/*
-** Get a buffer to hold returned data, with the given alignment. If we have
-** to realloc, allocate size+align, in case the pointer has to be bumped for
-** alignment. The answerBuffer should already be aligned.
-**
-** NOTE: the cast (long)res below assumes a long is large enough to hold a
-** pointer.
-*/
-#define __GLX_GET_ANSWER_BUFFER(res,cl,size,align) \
- if ((size) > sizeof(answerBuffer)) { \
- int bump; \
- if ((cl)->returnBufSize < (size)+(align)) { \
- (cl)->returnBuf = (GLbyte*)Xrealloc((cl)->returnBuf, \
- (size)+(align)); \
- if (!(cl)->returnBuf) { \
- return BadAlloc; \
- } \
- (cl)->returnBufSize = (size)+(align); \
- } \
- res = (char*)cl->returnBuf; \
- bump = (long)(res) % (align); \
- if (bump) res += (align) - (bump); \
- } else { \
- res = (char *)answerBuffer; \
- }
-
-#define __GLX_PUT_BYTE() \
- *(GLbyte *)&__glXReply.pad3 = *(GLbyte *)answer
-
-#define __GLX_PUT_SHORT() \
- *(GLshort *)&__glXReply.pad3 = *(GLshort *)answer
-
-#define __GLX_PUT_INT() \
- *(GLint *)&__glXReply.pad3 = *(GLint *)answer
-
-#define __GLX_PUT_FLOAT() \
- *(GLfloat *)&__glXReply.pad3 = *(GLfloat *)answer
-
-#define __GLX_PUT_DOUBLE() \
- *(GLdouble *)&__glXReply.pad3 = *(GLdouble *)answer
-
-#define __GLX_SEND_BYTE_ARRAY(len) \
- WriteToClient(client, __GLX_PAD((len)*__GLX_SIZE_INT8), (char *)answer)
-
-#define __GLX_SEND_SHORT_ARRAY(len) \
- WriteToClient(client, __GLX_PAD((len)*__GLX_SIZE_INT16), (char *)answer)
-
-#define __GLX_SEND_INT_ARRAY(len) \
- WriteToClient(client, (len)*__GLX_SIZE_INT32, (char *)answer)
-
-#define __GLX_SEND_FLOAT_ARRAY(len) \
- WriteToClient(client, (len)*__GLX_SIZE_FLOAT32, (char *)answer)
-
-#define __GLX_SEND_DOUBLE_ARRAY(len) \
- WriteToClient(client, (len)*__GLX_SIZE_FLOAT64, (char *)answer)
-
-
-#define __GLX_SEND_VOID_ARRAY(len) __GLX_SEND_BYTE_ARRAY(len)
-#define __GLX_SEND_UBYTE_ARRAY(len) __GLX_SEND_BYTE_ARRAY(len)
-#define __GLX_SEND_USHORT_ARRAY(len) __GLX_SEND_SHORT_ARRAY(len)
-#define __GLX_SEND_UINT_ARRAY(len) __GLX_SEND_INT_ARRAY(len)
-
-/*
-** PERFORMANCE NOTE:
-** Machine dependent optimizations abound here; these swapping macros can
-** conceivably be replaced with routines that do the job faster.
-*/
-#define __GLX_DECLARE_SWAP_VARIABLES \
- GLbyte sw; \
- GLbyte *swapPC; \
- GLbyte *swapEnd
-
-
-#define __GLX_SWAP_INT(pc) \
- sw = ((GLbyte *)(pc))[0]; \
- ((GLbyte *)(pc))[0] = ((GLbyte *)(pc))[3]; \
- ((GLbyte *)(pc))[3] = sw; \
- sw = ((GLbyte *)(pc))[1]; \
- ((GLbyte *)(pc))[1] = ((GLbyte *)(pc))[2]; \
- ((GLbyte *)(pc))[2] = sw;
-
-#define __GLX_SWAP_SHORT(pc) \
- sw = ((GLbyte *)(pc))[0]; \
- ((GLbyte *)(pc))[0] = ((GLbyte *)(pc))[1]; \
- ((GLbyte *)(pc))[1] = sw;
-
-#define __GLX_SWAP_DOUBLE(pc) \
- sw = ((GLbyte *)(pc))[0]; \
- ((GLbyte *)(pc))[0] = ((GLbyte *)(pc))[7]; \
- ((GLbyte *)(pc))[7] = sw; \
- sw = ((GLbyte *)(pc))[1]; \
- ((GLbyte *)(pc))[1] = ((GLbyte *)(pc))[6]; \
- ((GLbyte *)(pc))[6] = sw; \
- sw = ((GLbyte *)(pc))[2]; \
- ((GLbyte *)(pc))[2] = ((GLbyte *)(pc))[5]; \
- ((GLbyte *)(pc))[5] = sw; \
- sw = ((GLbyte *)(pc))[3]; \
- ((GLbyte *)(pc))[3] = ((GLbyte *)(pc))[4]; \
- ((GLbyte *)(pc))[4] = sw;
-
-#define __GLX_SWAP_FLOAT(pc) \
- sw = ((GLbyte *)(pc))[0]; \
- ((GLbyte *)(pc))[0] = ((GLbyte *)(pc))[3]; \
- ((GLbyte *)(pc))[3] = sw; \
- sw = ((GLbyte *)(pc))[1]; \
- ((GLbyte *)(pc))[1] = ((GLbyte *)(pc))[2]; \
- ((GLbyte *)(pc))[2] = sw;
-
-#define __GLX_SWAP_INT_ARRAY(pc, count) \
- swapPC = ((GLbyte *)(pc)); \
- swapEnd = ((GLbyte *)(pc)) + (count)*__GLX_SIZE_INT32;\
- while (swapPC < swapEnd) { \
- __GLX_SWAP_INT(swapPC); \
- swapPC += __GLX_SIZE_INT32; \
- }
-
-#define __GLX_SWAP_SHORT_ARRAY(pc, count) \
- swapPC = ((GLbyte *)(pc)); \
- swapEnd = ((GLbyte *)(pc)) + (count)*__GLX_SIZE_INT16;\
- while (swapPC < swapEnd) { \
- __GLX_SWAP_SHORT(swapPC); \
- swapPC += __GLX_SIZE_INT16; \
- }
-
-#define __GLX_SWAP_DOUBLE_ARRAY(pc, count) \
- swapPC = ((GLbyte *)(pc)); \
- swapEnd = ((GLbyte *)(pc)) + (count)*__GLX_SIZE_FLOAT64;\
- while (swapPC < swapEnd) { \
- __GLX_SWAP_DOUBLE(swapPC); \
- swapPC += __GLX_SIZE_FLOAT64; \
- }
-
-#define __GLX_SWAP_FLOAT_ARRAY(pc, count) \
- swapPC = ((GLbyte *)(pc)); \
- swapEnd = ((GLbyte *)(pc)) + (count)*__GLX_SIZE_FLOAT32;\
- while (swapPC < swapEnd) { \
- __GLX_SWAP_FLOAT(swapPC); \
- swapPC += __GLX_SIZE_FLOAT32; \
- }
-
-#define __GLX_SWAP_REPLY_HEADER() \
- __GLX_SWAP_SHORT(&__glXReply.sequenceNumber); \
- __GLX_SWAP_INT(&__glXReply.length);
-
-#define __GLX_SWAP_REPLY_RETVAL() \
- __GLX_SWAP_INT(&__glXReply.retval)
-
-#define __GLX_SWAP_REPLY_SIZE() \
- __GLX_SWAP_INT(&__glXReply.size)
-
-#endif /* !__GLX_unpack_h__ */
-
-
-
-
-
+#ifndef __GLX_unpack_h__
+#define __GLX_unpack_h__
+
+/*
+ * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
+ * Copyright (C) 1991-2000 Silicon Graphics, 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 including the dates of first publication and
+ * either this permission notice or a reference to
+ * http://oss.sgi.com/projects/FreeB/
+ * 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
+ * SILICON GRAPHICS, INC. 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 Silicon Graphics, Inc.
+ * shall not be used in advertising or otherwise to promote the sale, use or
+ * other dealings in this Software without prior written authorization from
+ * Silicon Graphics, Inc.
+ */
+
+#define __GLX_PAD(s) (((s)+3) & (GLuint)~3)
+
+/*
+** Fetch the context-id out of a SingleReq request pointed to by pc.
+*/
+#define __GLX_GET_SINGLE_CONTEXT_TAG(pc) (((xGLXSingleReq*)pc)->contextTag)
+#define __GLX_GET_VENDPRIV_CONTEXT_TAG(pc) (((xGLXVendorPrivateReq*)pc)->contextTag)
+
+/*
+** Fetch a double from potentially unaligned memory.
+*/
+#ifdef __GLX_ALIGN64
+#define __GLX_MEM_COPY(dst,src,n) memcpy(dst,src,n)
+#define __GLX_GET_DOUBLE(dst,src) __GLX_MEM_COPY(&dst,src,8)
+#else
+#define __GLX_GET_DOUBLE(dst,src) (dst) = *((GLdouble*)(src))
+#endif
+
+extern void __glXMemInit(void);
+
+extern xGLXSingleReply __glXReply;
+
+#define __GLX_BEGIN_REPLY(size) \
+ __glXReply.length = __GLX_PAD(size) >> 2; \
+ __glXReply.type = X_Reply; \
+ __glXReply.sequenceNumber = client->sequence;
+
+#define __GLX_SEND_HEADER() \
+ WriteToClient( client, sz_xGLXSingleReply, (char *)&__glXReply);
+
+#define __GLX_PUT_RETVAL(a) \
+ __glXReply.retval = (a);
+
+#define __GLX_PUT_SIZE(a) \
+ __glXReply.size = (a);
+
+#define __GLX_PUT_RENDERMODE(m) \
+ __glXReply.pad3 = (m)
+
+/*
+** Get a buffer to hold returned data, with the given alignment. If we have
+** to realloc, allocate size+align, in case the pointer has to be bumped for
+** alignment. The answerBuffer should already be aligned.
+**
+** NOTE: the cast (long)res below assumes a long is large enough to hold a
+** pointer.
+*/
+#define __GLX_GET_ANSWER_BUFFER(res,cl,size,align) \
+ if ((size) > sizeof(answerBuffer)) { \
+ int bump; \
+ if ((cl)->returnBufSize < (size)+(align)) { \
+ (cl)->returnBuf = (GLbyte*)realloc((cl)->returnBuf, \
+ (size)+(align)); \
+ if (!(cl)->returnBuf) { \
+ return BadAlloc; \
+ } \
+ (cl)->returnBufSize = (size)+(align); \
+ } \
+ res = (char*)cl->returnBuf; \
+ bump = (long)(res) % (align); \
+ if (bump) res += (align) - (bump); \
+ } else { \
+ res = (char *)answerBuffer; \
+ }
+
+#define __GLX_PUT_BYTE() \
+ *(GLbyte *)&__glXReply.pad3 = *(GLbyte *)answer
+
+#define __GLX_PUT_SHORT() \
+ *(GLshort *)&__glXReply.pad3 = *(GLshort *)answer
+
+#define __GLX_PUT_INT() \
+ *(GLint *)&__glXReply.pad3 = *(GLint *)answer
+
+#define __GLX_PUT_FLOAT() \
+ *(GLfloat *)&__glXReply.pad3 = *(GLfloat *)answer
+
+#define __GLX_PUT_DOUBLE() \
+ *(GLdouble *)&__glXReply.pad3 = *(GLdouble *)answer
+
+#define __GLX_SEND_BYTE_ARRAY(len) \
+ WriteToClient(client, __GLX_PAD((len)*__GLX_SIZE_INT8), (char *)answer)
+
+#define __GLX_SEND_SHORT_ARRAY(len) \
+ WriteToClient(client, __GLX_PAD((len)*__GLX_SIZE_INT16), (char *)answer)
+
+#define __GLX_SEND_INT_ARRAY(len) \
+ WriteToClient(client, (len)*__GLX_SIZE_INT32, (char *)answer)
+
+#define __GLX_SEND_FLOAT_ARRAY(len) \
+ WriteToClient(client, (len)*__GLX_SIZE_FLOAT32, (char *)answer)
+
+#define __GLX_SEND_DOUBLE_ARRAY(len) \
+ WriteToClient(client, (len)*__GLX_SIZE_FLOAT64, (char *)answer)
+
+
+#define __GLX_SEND_VOID_ARRAY(len) __GLX_SEND_BYTE_ARRAY(len)
+#define __GLX_SEND_UBYTE_ARRAY(len) __GLX_SEND_BYTE_ARRAY(len)
+#define __GLX_SEND_USHORT_ARRAY(len) __GLX_SEND_SHORT_ARRAY(len)
+#define __GLX_SEND_UINT_ARRAY(len) __GLX_SEND_INT_ARRAY(len)
+
+/*
+** PERFORMANCE NOTE:
+** Machine dependent optimizations abound here; these swapping macros can
+** conceivably be replaced with routines that do the job faster.
+*/
+#define __GLX_DECLARE_SWAP_VARIABLES \
+ GLbyte sw; \
+ GLbyte *swapPC; \
+ GLbyte *swapEnd
+
+
+#define __GLX_SWAP_INT(pc) \
+ sw = ((GLbyte *)(pc))[0]; \
+ ((GLbyte *)(pc))[0] = ((GLbyte *)(pc))[3]; \
+ ((GLbyte *)(pc))[3] = sw; \
+ sw = ((GLbyte *)(pc))[1]; \
+ ((GLbyte *)(pc))[1] = ((GLbyte *)(pc))[2]; \
+ ((GLbyte *)(pc))[2] = sw;
+
+#define __GLX_SWAP_SHORT(pc) \
+ sw = ((GLbyte *)(pc))[0]; \
+ ((GLbyte *)(pc))[0] = ((GLbyte *)(pc))[1]; \
+ ((GLbyte *)(pc))[1] = sw;
+
+#define __GLX_SWAP_DOUBLE(pc) \
+ sw = ((GLbyte *)(pc))[0]; \
+ ((GLbyte *)(pc))[0] = ((GLbyte *)(pc))[7]; \
+ ((GLbyte *)(pc))[7] = sw; \
+ sw = ((GLbyte *)(pc))[1]; \
+ ((GLbyte *)(pc))[1] = ((GLbyte *)(pc))[6]; \
+ ((GLbyte *)(pc))[6] = sw; \
+ sw = ((GLbyte *)(pc))[2]; \
+ ((GLbyte *)(pc))[2] = ((GLbyte *)(pc))[5]; \
+ ((GLbyte *)(pc))[5] = sw; \
+ sw = ((GLbyte *)(pc))[3]; \
+ ((GLbyte *)(pc))[3] = ((GLbyte *)(pc))[4]; \
+ ((GLbyte *)(pc))[4] = sw;
+
+#define __GLX_SWAP_FLOAT(pc) \
+ sw = ((GLbyte *)(pc))[0]; \
+ ((GLbyte *)(pc))[0] = ((GLbyte *)(pc))[3]; \
+ ((GLbyte *)(pc))[3] = sw; \
+ sw = ((GLbyte *)(pc))[1]; \
+ ((GLbyte *)(pc))[1] = ((GLbyte *)(pc))[2]; \
+ ((GLbyte *)(pc))[2] = sw;
+
+#define __GLX_SWAP_INT_ARRAY(pc, count) \
+ swapPC = ((GLbyte *)(pc)); \
+ swapEnd = ((GLbyte *)(pc)) + (count)*__GLX_SIZE_INT32;\
+ while (swapPC < swapEnd) { \
+ __GLX_SWAP_INT(swapPC); \
+ swapPC += __GLX_SIZE_INT32; \
+ }
+
+#define __GLX_SWAP_SHORT_ARRAY(pc, count) \
+ swapPC = ((GLbyte *)(pc)); \
+ swapEnd = ((GLbyte *)(pc)) + (count)*__GLX_SIZE_INT16;\
+ while (swapPC < swapEnd) { \
+ __GLX_SWAP_SHORT(swapPC); \
+ swapPC += __GLX_SIZE_INT16; \
+ }
+
+#define __GLX_SWAP_DOUBLE_ARRAY(pc, count) \
+ swapPC = ((GLbyte *)(pc)); \
+ swapEnd = ((GLbyte *)(pc)) + (count)*__GLX_SIZE_FLOAT64;\
+ while (swapPC < swapEnd) { \
+ __GLX_SWAP_DOUBLE(swapPC); \
+ swapPC += __GLX_SIZE_FLOAT64; \
+ }
+
+#define __GLX_SWAP_FLOAT_ARRAY(pc, count) \
+ swapPC = ((GLbyte *)(pc)); \
+ swapEnd = ((GLbyte *)(pc)) + (count)*__GLX_SIZE_FLOAT32;\
+ while (swapPC < swapEnd) { \
+ __GLX_SWAP_FLOAT(swapPC); \
+ swapPC += __GLX_SIZE_FLOAT32; \
+ }
+
+#define __GLX_SWAP_REPLY_HEADER() \
+ __GLX_SWAP_SHORT(&__glXReply.sequenceNumber); \
+ __GLX_SWAP_INT(&__glXReply.length);
+
+#define __GLX_SWAP_REPLY_RETVAL() \
+ __GLX_SWAP_INT(&__glXReply.retval)
+
+#define __GLX_SWAP_REPLY_SIZE() \
+ __GLX_SWAP_INT(&__glXReply.size)
+
+#endif /* !__GLX_unpack_h__ */
+
+
+
+
+
diff --git a/xorg-server/hw/dmx/input/dmxinputinit.c b/xorg-server/hw/dmx/input/dmxinputinit.c
index 5a486a464..f9acaa039 100644
--- a/xorg-server/hw/dmx/input/dmxinputinit.c
+++ b/xorg-server/hw/dmx/input/dmxinputinit.c
@@ -1,1311 +1,1311 @@
-/*
- * Copyright 2002-2003 Red Hat Inc., Durham, North Carolina.
- *
- * 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 on 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 (including the
- * next paragraph) 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
- * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
- * 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.
- */
-
-/*
- * Authors:
- * Rickard E. (Rik) Faith <faith@redhat.com>
- *
- */
-
-/** \file
- * This file provides generic input support. Functions here set up
- * input and lead to the calling of low-level device drivers for
- * input. */
-
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
-
-#define DMX_WINDOW_DEBUG 0
-
-#include "dmxinputinit.h"
-#include "dmxextension.h" /* For dmxInputCount */
-
-#include "dmxdummy.h"
-#include "dmxbackend.h"
-#include "dmxconsole.h"
-#include "dmxcommon.h"
-#include "dmxevents.h"
-#include "dmxmotion.h"
-#include "dmxprop.h"
-#include "config/dmxconfig.h"
-#include "dmxcursor.h"
-
-#include "lnx-keyboard.h"
-#include "lnx-ms.h"
-#include "lnx-ps2.h"
-#include "usb-keyboard.h"
-#include "usb-mouse.h"
-#include "usb-other.h"
-#include "usb-common.h"
-
-#include "dmxsigio.h"
-#include "dmxarg.h"
-
-#include "inputstr.h"
-#include "input.h"
-#include "mipointer.h"
-#include "windowstr.h"
-#include "mi.h"
-#include "xkbsrv.h"
-
-#include <X11/extensions/XI.h>
-#include <X11/extensions/XIproto.h>
-#include "exevents.h"
-#include "extinit.h"
-
-DMXLocalInputInfoPtr dmxLocalCorePointer, dmxLocalCoreKeyboard;
-
-static DMXLocalInputInfoRec DMXDummyMou = {
- "dummy-mou", DMX_LOCAL_MOUSE, DMX_LOCAL_TYPE_LOCAL, 1,
- NULL, NULL, NULL, NULL, NULL, dmxDummyMouGetInfo
-};
-
-static DMXLocalInputInfoRec DMXDummyKbd = {
- "dummy-kbd", DMX_LOCAL_KEYBOARD, DMX_LOCAL_TYPE_LOCAL, 1,
- NULL, NULL, NULL, NULL, NULL, dmxDummyKbdGetInfo
-};
-
-static DMXLocalInputInfoRec DMXBackendMou = {
- "backend-mou", DMX_LOCAL_MOUSE, DMX_LOCAL_TYPE_BACKEND, 2,
- dmxBackendCreatePrivate, dmxBackendDestroyPrivate,
- dmxBackendInit, NULL, dmxBackendLateReInit, dmxBackendMouGetInfo,
- dmxCommonMouOn, dmxCommonMouOff, dmxBackendUpdatePosition,
- NULL, NULL, NULL,
- dmxBackendCollectEvents, dmxBackendProcessInput, dmxBackendFunctions, NULL,
- dmxCommonMouCtrl
-};
-
-static DMXLocalInputInfoRec DMXBackendKbd = {
- "backend-kbd", DMX_LOCAL_KEYBOARD, DMX_LOCAL_TYPE_BACKEND,
- 1, /* With backend-mou or console-mou */
- dmxCommonCopyPrivate, NULL,
- dmxBackendInit, NULL, NULL, dmxBackendKbdGetInfo,
- dmxCommonKbdOn, dmxCommonKbdOff, NULL,
- NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, dmxCommonKbdCtrl, dmxCommonKbdBell
-};
-
-static DMXLocalInputInfoRec DMXConsoleMou = {
- "console-mou", DMX_LOCAL_MOUSE, DMX_LOCAL_TYPE_CONSOLE, 2,
- dmxConsoleCreatePrivate, dmxConsoleDestroyPrivate,
- dmxConsoleInit, dmxConsoleReInit, NULL, dmxConsoleMouGetInfo,
- dmxCommonMouOn, dmxCommonMouOff, dmxConsoleUpdatePosition,
- NULL, NULL, NULL,
- dmxConsoleCollectEvents, NULL, dmxConsoleFunctions, dmxConsoleUpdateInfo,
- dmxCommonMouCtrl
-};
-
-static DMXLocalInputInfoRec DMXConsoleKbd = {
- "console-kbd", DMX_LOCAL_KEYBOARD, DMX_LOCAL_TYPE_CONSOLE,
- 1, /* With backend-mou or console-mou */
- dmxCommonCopyPrivate, NULL,
- dmxConsoleInit, dmxConsoleReInit, NULL, dmxConsoleKbdGetInfo,
- dmxCommonKbdOn, dmxCommonKbdOff, NULL,
- NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL, dmxCommonKbdCtrl, dmxCommonKbdBell
-};
-
-static DMXLocalInputInfoRec DMXCommonOth = {
- "common-oth", DMX_LOCAL_OTHER, DMX_LOCAL_TYPE_COMMON, 1,
- dmxCommonCopyPrivate, NULL,
- NULL, NULL, NULL, dmxCommonOthGetInfo,
- dmxCommonOthOn, dmxCommonOthOff
-};
-
-
-static DMXLocalInputInfoRec DMXLocalDevices[] = {
- /* Dummy drivers that can compile on any OS */
-#ifdef __linux__
- /* Linux-specific drivers */
- {
- "kbd", DMX_LOCAL_KEYBOARD, DMX_LOCAL_TYPE_LOCAL, 1,
- kbdLinuxCreatePrivate, kbdLinuxDestroyPrivate,
- kbdLinuxInit, NULL, NULL, kbdLinuxGetInfo,
- kbdLinuxOn, kbdLinuxOff, NULL,
- kbdLinuxVTPreSwitch, kbdLinuxVTPostSwitch, kbdLinuxVTSwitch,
- kbdLinuxRead, NULL, NULL, NULL,
- NULL, kbdLinuxCtrl, kbdLinuxBell
- },
- {
- "ms", DMX_LOCAL_MOUSE, DMX_LOCAL_TYPE_LOCAL, 1,
- msLinuxCreatePrivate, msLinuxDestroyPrivate,
- msLinuxInit, NULL, NULL, msLinuxGetInfo,
- msLinuxOn, msLinuxOff, NULL,
- msLinuxVTPreSwitch, msLinuxVTPostSwitch, NULL,
- msLinuxRead
- },
- {
- "ps2", DMX_LOCAL_MOUSE, DMX_LOCAL_TYPE_LOCAL, 1,
- ps2LinuxCreatePrivate, ps2LinuxDestroyPrivate,
- ps2LinuxInit, NULL, NULL, ps2LinuxGetInfo,
- ps2LinuxOn, ps2LinuxOff, NULL,
- ps2LinuxVTPreSwitch, ps2LinuxVTPostSwitch, NULL,
- ps2LinuxRead
- },
-#endif
-#ifdef __linux__
- /* USB drivers, currently only for
- Linux, but relatively easy to port to
- other OSs */
- {
- "usb-kbd", DMX_LOCAL_KEYBOARD, DMX_LOCAL_TYPE_LOCAL, 1,
- usbCreatePrivate, usbDestroyPrivate,
- kbdUSBInit, NULL, NULL, kbdUSBGetInfo,
- kbdUSBOn, usbOff, NULL,
- NULL, NULL, NULL,
- kbdUSBRead, NULL, NULL, NULL,
- NULL, kbdUSBCtrl
- },
- {
- "usb-mou", DMX_LOCAL_MOUSE, DMX_LOCAL_TYPE_LOCAL, 1,
- usbCreatePrivate, usbDestroyPrivate,
- mouUSBInit, NULL, NULL, mouUSBGetInfo,
- mouUSBOn, usbOff, NULL,
- NULL, NULL, NULL,
- mouUSBRead
- },
- {
- "usb-oth", DMX_LOCAL_OTHER, DMX_LOCAL_TYPE_LOCAL, 1,
- usbCreatePrivate, usbDestroyPrivate,
- othUSBInit, NULL, NULL, othUSBGetInfo,
- othUSBOn, usbOff, NULL,
- NULL, NULL, NULL,
- othUSBRead
- },
-#endif
- {
- "dummy-mou", DMX_LOCAL_MOUSE, DMX_LOCAL_TYPE_LOCAL, 1,
- NULL, NULL, NULL, NULL, NULL, dmxDummyMouGetInfo
- },
- {
- "dummy-kbd", DMX_LOCAL_KEYBOARD, DMX_LOCAL_TYPE_LOCAL, 1,
- NULL, NULL, NULL, NULL, NULL, dmxDummyKbdGetInfo
- },
- { NULL } /* Must be last */
-};
-
-
-#if 11 /*BP*/
-void
-DDXRingBell(int volume, int pitch, int duration)
-{
- /* NO-OP */
-}
-
-/* taken from kdrive/src/kinput.c: */
-static void
-dmxKbdCtrl (DeviceIntPtr pDevice, KeybdCtrl *ctrl)
-{
-#if 0
- KdKeyboardInfo *ki;
-
- for (ki = kdKeyboards; ki; ki = ki->next) {
- if (ki->dixdev && ki->dixdev->id == pDevice->id)
- break;
- }
-
- if (!ki || !ki->dixdev || ki->dixdev->id != pDevice->id || !ki->driver)
- return;
-
- KdSetLeds(ki, ctrl->leds);
- ki->bellPitch = ctrl->bell_pitch;
- ki->bellDuration = ctrl->bell_duration;
-#endif
-}
-
-/* taken from kdrive/src/kinput.c: */
-static void
-dmxBell(int volume, DeviceIntPtr pDev, pointer arg, int something)
-{
-#if 0
- KeybdCtrl *ctrl = arg;
- KdKeyboardInfo *ki = NULL;
-
- for (ki = kdKeyboards; ki; ki = ki->next) {
- if (ki->dixdev && ki->dixdev->id == pDev->id)
- break;
- }
-
- if (!ki || !ki->dixdev || ki->dixdev->id != pDev->id || !ki->driver)
- return;
-
- KdRingBell(ki, volume, ctrl->bell_pitch, ctrl->bell_duration);
-#endif
-}
-
-#endif /*BP*/
-
-static void _dmxChangePointerControl(DMXLocalInputInfoPtr dmxLocal,
- PtrCtrl *ctrl)
-{
- if (!dmxLocal) return;
- dmxLocal->mctrl = *ctrl;
- if (dmxLocal->mCtrl) dmxLocal->mCtrl(&dmxLocal->pDevice->public, ctrl);
-}
-
-/** Change the pointer control information for the \a pDevice. If the
- * device sends core events, then also change the control information
- * for all of the pointer devices that send core events. */
-void dmxChangePointerControl(DeviceIntPtr pDevice, PtrCtrl *ctrl)
-{
- GETDMXLOCALFROMPDEVICE;
- int i, j;
-
- if (dmxLocal->sendsCore) { /* Do for all core devices */
- for (i = 0; i < dmxNumInputs; i++) {
- DMXInputInfo *dmxInput = &dmxInputs[i];
- if (dmxInput->detached) continue;
- for (j = 0; j < dmxInput->numDevs; j++)
- if (dmxInput->devs[j]->sendsCore)
- _dmxChangePointerControl(dmxInput->devs[j], ctrl);
- }
- } else { /* Do for this device only */
- _dmxChangePointerControl(dmxLocal, ctrl);
- }
-}
-
-static void _dmxKeyboardKbdCtrlProc(DMXLocalInputInfoPtr dmxLocal,
- KeybdCtrl *ctrl)
-{
- dmxLocal->kctrl = *ctrl;
- if (dmxLocal->kCtrl) {
- dmxLocal->kCtrl(&dmxLocal->pDevice->public, ctrl);
- if (dmxLocal->pDevice->kbdfeed) {
- XkbEventCauseRec cause;
- XkbSetCauseUnknown(&cause);
- /* Generate XKB events, as necessary */
- XkbUpdateIndicators(dmxLocal->pDevice, XkbAllIndicatorsMask, False,
- NULL, &cause);
- }
- }
-}
-
-
-/** Change the keyboard control information for the \a pDevice. If the
- * device sends core events, then also change the control information
- * for all of the keyboard devices that send core events. */
-void dmxKeyboardKbdCtrlProc(DeviceIntPtr pDevice, KeybdCtrl *ctrl)
-{
- GETDMXLOCALFROMPDEVICE;
- int i, j;
-
- if (dmxLocal->sendsCore) { /* Do for all core devices */
- for (i = 0; i < dmxNumInputs; i++) {
- DMXInputInfo *dmxInput = &dmxInputs[i];
- if (dmxInput->detached) continue;
- for (j = 0; j < dmxInput->numDevs; j++)
- if (dmxInput->devs[j]->sendsCore)
- _dmxKeyboardKbdCtrlProc(dmxInput->devs[j], ctrl);
- }
- } else { /* Do for this device only */
- _dmxKeyboardKbdCtrlProc(dmxLocal, ctrl);
- }
-}
-
-static void _dmxKeyboardBellProc(DMXLocalInputInfoPtr dmxLocal, int percent)
-{
- if (dmxLocal->kBell) dmxLocal->kBell(&dmxLocal->pDevice->public,
- percent,
- dmxLocal->kctrl.bell,
- dmxLocal->kctrl.bell_pitch,
- dmxLocal->kctrl.bell_duration);
-}
-
-/** Sound the bell on the device. If the device send core events, then
- * sound the bell on all of the devices that send core events. */
-void dmxKeyboardBellProc(int percent, DeviceIntPtr pDevice,
- pointer ctrl, int unknown)
-{
- GETDMXLOCALFROMPDEVICE;
- int i, j;
-
- if (dmxLocal->sendsCore) { /* Do for all core devices */
- for (i = 0; i < dmxNumInputs; i++) {
- DMXInputInfo *dmxInput = &dmxInputs[i];
- if (dmxInput->detached) continue;
- for (j = 0; j < dmxInput->numDevs; j++)
- if (dmxInput->devs[j]->sendsCore)
- _dmxKeyboardBellProc(dmxInput->devs[j], percent);
- }
- } else { /* Do for this device only */
- _dmxKeyboardBellProc(dmxLocal, percent);
- }
-}
-
-static void dmxKeyboardFreeNames(XkbComponentNamesPtr names)
-{
- if (names->keycodes) XFree(names->keycodes);
- if (names->types) XFree(names->types);
- if (names->compat) XFree(names->compat);
- if (names->symbols) XFree(names->symbols);
- if (names->geometry) XFree(names->geometry);
-}
-
-
-static int dmxKeyboardOn(DeviceIntPtr pDevice, DMXLocalInitInfo *info)
-{
- GETDMXINPUTFROMPDEVICE;
- XkbRMLVOSet rmlvo;
-
- rmlvo.rules = dmxConfigGetXkbRules();
- rmlvo.model = dmxConfigGetXkbModel();
- rmlvo.layout = dmxConfigGetXkbLayout();
- rmlvo.variant = dmxConfigGetXkbVariant();
- rmlvo.options = dmxConfigGetXkbOptions();
-
- XkbSetRulesDflts(&rmlvo);
- if (!info->force && (dmxInput->keycodes
- || dmxInput->symbols
- || dmxInput->geometry)) {
- if (info->freenames) dmxKeyboardFreeNames(&info->names);
- info->freenames = 0;
- info->names.keycodes = dmxInput->keycodes;
- info->names.types = NULL;
- info->names.compat = NULL;
- info->names.symbols = dmxInput->symbols;
- info->names.geometry = dmxInput->geometry;
-
- dmxLogInput(dmxInput, "XKEYBOARD: From command line: %s",
- info->names.keycodes);
- if (info->names.symbols && *info->names.symbols)
- dmxLogInputCont(dmxInput, " %s", info->names.symbols);
- if (info->names.geometry && *info->names.geometry)
- dmxLogInputCont(dmxInput, " %s", info->names.geometry);
- dmxLogInputCont(dmxInput, "\n");
- } else if (info->names.keycodes) {
- dmxLogInput(dmxInput, "XKEYBOARD: From device: %s",
- info->names.keycodes);
- if (info->names.symbols && *info->names.symbols)
- dmxLogInputCont(dmxInput, " %s", info->names.symbols);
- if (info->names.geometry && *info->names.geometry)
- dmxLogInputCont(dmxInput, " %s", info->names.geometry);
- dmxLogInputCont(dmxInput, "\n");
- } else {
- dmxLogInput(dmxInput, "XKEYBOARD: Defaults: %s %s %s %s %s\n",
- dmxConfigGetXkbRules(),
- dmxConfigGetXkbLayout(),
- dmxConfigGetXkbModel(),
- dmxConfigGetXkbVariant()
- ? dmxConfigGetXkbVariant() : "",
- dmxConfigGetXkbOptions()
- ? dmxConfigGetXkbOptions() : "");
- }
- InitKeyboardDeviceStruct(pDevice, &rmlvo,
- dmxKeyboardBellProc,
- dmxKeyboardKbdCtrlProc);
-
- if (info->freenames) dmxKeyboardFreeNames(&info->names);
-
- return Success;
-}
-
-
-static int dmxDeviceOnOff(DeviceIntPtr pDevice, int what)
-{
- GETDMXINPUTFROMPDEVICE;
- int fd;
- DMXLocalInitInfo info;
- int i;
- Atom btn_labels[MAX_BUTTONS] = {0}; /* FIXME */
- Atom axis_labels[MAX_VALUATORS] = {0}; /* FIXME */
-
- if (dmxInput->detached) return Success;
-
- memset(&info, 0, sizeof(info));
- switch (what) {
- case DEVICE_INIT:
- if (dmxLocal->init)
- dmxLocal->init(pDev);
- if (dmxLocal->get_info)
- dmxLocal->get_info(pDev, &info);
- if (info.keyboard) { /* XKEYBOARD makes this a special case */
- dmxKeyboardOn(pDevice, &info);
- break;
- }
- if (info.keyClass) {
- XkbRMLVOSet rmlvo;
-
- rmlvo.rules = dmxConfigGetXkbRules();
- rmlvo.model = dmxConfigGetXkbModel();
- rmlvo.layout = dmxConfigGetXkbLayout();
- rmlvo.variant = dmxConfigGetXkbVariant();
- rmlvo.options = dmxConfigGetXkbOptions();
-
- InitKeyboardDeviceStruct(pDevice,
- &rmlvo,
- dmxBell, dmxKbdCtrl);
- }
- if (info.buttonClass) {
- InitButtonClassDeviceStruct(pDevice, info.numButtons,
- btn_labels, info.map);
- }
- if (info.valuatorClass) {
- if (info.numRelAxes && dmxLocal->sendsCore) {
- InitValuatorClassDeviceStruct(pDevice, info.numRelAxes,
- axis_labels,
- GetMaximumEventsNum(),
- Relative);
- for (i = 0; i < info.numRelAxes; i++)
- InitValuatorAxisStruct(pDevice, i, axis_labels[i],
- info.minval[i], info.maxval[i],
- info.res[i],
- info.minres[i], info.maxres[i]);
- } else if (info.numRelAxes) {
- InitValuatorClassDeviceStruct(pDevice, info.numRelAxes,
- axis_labels,
- dmxPointerGetMotionBufferSize(),
- Relative);
- for (i = 0; i < info.numRelAxes; i++)
- InitValuatorAxisStruct(pDevice, i, axis_labels[i],
- info.minval[i],
- info.maxval[i], info.res[i],
- info.minres[i], info.maxres[i]);
- } else if (info.numAbsAxes) {
- InitValuatorClassDeviceStruct(pDevice, info.numAbsAxes,
- axis_labels,
- dmxPointerGetMotionBufferSize(),
- Absolute);
- for (i = 0; i < info.numAbsAxes; i++)
- InitValuatorAxisStruct(pDevice, i,
- axis_labels[i],
- info.minval[i], info.maxval[i],
- info.res[i], info.minres[i],
- info.maxres[i]);
- }
- }
- if (info.focusClass) InitFocusClassDeviceStruct(pDevice);
- if (info.proximityClass) InitProximityClassDeviceStruct(pDevice);
- if (info.ptrFeedbackClass)
- InitPtrFeedbackClassDeviceStruct(pDevice, dmxChangePointerControl);
- if (info.intFeedbackClass || info.strFeedbackClass)
- dmxLog(dmxWarning,
- "Integer and string feedback not supported for %s\n",
- pDevice->name);
- if (!info.keyboard && (info.ledFeedbackClass || info.belFeedbackClass))
- dmxLog(dmxWarning,
- "Led and bel feedback not supported for non-keyboard %s\n",
- pDevice->name);
- break;
- case DEVICE_ON:
- if (!pDev->on) {
- if (dmxLocal->on && (fd = dmxLocal->on(pDev)) >= 0)
- dmxSigioRegister(dmxInput, fd);
- pDev->on = TRUE;
- }
- break;
- case DEVICE_OFF:
- case DEVICE_CLOSE:
- /* This can get called twice consecutively: once for a
- * detached screen (DEVICE_OFF), and then again at server
- * generation time (DEVICE_CLOSE). */
- if (pDev->on) {
- dmxSigioUnregister(dmxInput);
- if (dmxLocal->off) dmxLocal->off(pDev);
- pDev->on = FALSE;
- }
- break;
- }
- if (info.keySyms.map && info.freemap) {
- XFree(info.keySyms.map);
- info.keySyms.map = NULL;
- }
- if (info.xkb) XkbFreeKeyboard(info.xkb, 0, True);
- return Success;
-}
-
-static void dmxProcessInputEvents(DMXInputInfo *dmxInput)
-{
- int i;
-
- mieqProcessInputEvents();
-#if 00 /*BP*/
- miPointerUpdate();
-#endif
- if (dmxInput->detached)
- return;
- for (i = 0; i < dmxInput->numDevs; i += dmxInput->devs[i]->binding)
- if (dmxInput->devs[i]->process_input) {
-#if 11 /*BP*/
- miPointerUpdateSprite(dmxInput->devs[i]->pDevice);
-#endif
- dmxInput->devs[i]->process_input(dmxInput->devs[i]->private);
- }
-
-#if 11 /*BP*/
- mieqProcessInputEvents();
-#endif
-}
-
-static void dmxUpdateWindowInformation(DMXInputInfo *dmxInput,
- DMXUpdateType type,
- WindowPtr pWindow)
-{
- int i;
-
-#ifdef PANORAMIX
- if (!noPanoramiXExtension && pWindow && pWindow->parent != WindowTable[0])
- return;
-#endif
-#if DMX_WINDOW_DEBUG
- {
- const char *name = "Unknown";
- switch (type) {
- case DMX_UPDATE_REALIZE: name = "Realize"; break;
- case DMX_UPDATE_UNREALIZE: name = "Unrealize"; break;
- case DMX_UPDATE_RESTACK: name = "Restack"; break;
- case DMX_UPDATE_COPY: name = "Copy"; break;
- case DMX_UPDATE_RESIZE: name = "Resize"; break;
- case DMX_UPDATE_REPARENT: name = "Repaint"; break;
- }
- dmxLog(dmxDebug, "Window %p changed: %s\n", pWindow, name);
- }
-#endif
-
- if (dmxInput->detached)
- return;
- for (i = 0; i < dmxInput->numDevs; i += dmxInput->devs[i]->binding)
- if (dmxInput->devs[i]->update_info)
- dmxInput->devs[i]->update_info(dmxInput->devs[i]->private,
- type, pWindow);
-}
-
-static void dmxCollectAll(DMXInputInfo *dmxInput)
-{
- int i;
-
- if (dmxInput->detached)
- return;
- for (i = 0; i < dmxInput->numDevs; i += dmxInput->devs[i]->binding)
- if (dmxInput->devs[i]->collect_events)
- dmxInput->devs[i]->collect_events(&dmxInput->devs[i]->pDevice->public,
- dmxMotion,
- dmxEnqueue,
- dmxCheckSpecialKeys, DMX_BLOCK);
-}
-
-static void dmxBlockHandler(pointer blockData, OSTimePtr pTimeout,
- pointer pReadMask)
-{
- DMXInputInfo *dmxInput = &dmxInputs[(int)blockData];
- static unsigned long generation = 0;
-
- if (generation != serverGeneration) {
- generation = serverGeneration;
- dmxCollectAll(dmxInput);
- }
-}
-
-static void dmxSwitchReturn(pointer p)
-{
- DMXInputInfo *dmxInput = p;
- int i;
-
- dmxLog(dmxInfo, "Returning from VT %d\n", dmxInput->vt_switched);
-
- if (!dmxInput->vt_switched)
- dmxLog(dmxFatal, "dmxSwitchReturn called, but not switched\n");
- dmxSigioEnableInput();
- for (i = 0; i < dmxInput->numDevs; i++)
- if (dmxInput->devs[i]->vt_post_switch)
- dmxInput->devs[i]->vt_post_switch(dmxInput->devs[i]->private);
- dmxInput->vt_switched = 0;
-}
-
-static void dmxWakeupHandler(pointer blockData, int result, pointer pReadMask)
-{
- DMXInputInfo *dmxInput = &dmxInputs[(int)blockData];
- int i;
-
- if (dmxInput->vt_switch_pending) {
- dmxLog(dmxInfo, "Switching to VT %d\n", dmxInput->vt_switch_pending);
- for (i = 0; i < dmxInput->numDevs; i++)
- if (dmxInput->devs[i]->vt_pre_switch)
- dmxInput->devs[i]->vt_pre_switch(dmxInput->devs[i]->private);
- dmxInput->vt_switched = dmxInput->vt_switch_pending;
- dmxInput->vt_switch_pending = 0;
- for (i = 0; i < dmxInput->numDevs; i++) {
- if (dmxInput->devs[i]->vt_switch) {
- dmxSigioDisableInput();
- if (!dmxInput->devs[i]->vt_switch(dmxInput->devs[i]->private,
- dmxInput->vt_switched,
- dmxSwitchReturn,
- dmxInput))
- dmxSwitchReturn(dmxInput);
- break; /* Only call one vt_switch routine */
- }
- }
- }
- dmxCollectAll(dmxInput);
-}
-
-static char *dmxMakeUniqueDeviceName(DMXLocalInputInfoPtr dmxLocal)
-{
- static int k = 0;
- static int m = 0;
- static int o = 0;
- static unsigned long dmxGeneration = 0;
-#define LEN 32
- char * buf = xalloc(LEN);
-
- if (dmxGeneration != serverGeneration) {
- k = m = o = 0;
- dmxGeneration = serverGeneration;
- }
-
- switch (dmxLocal->type) {
- case DMX_LOCAL_KEYBOARD: XmuSnprintf(buf, LEN, "Keyboard%d", k++); break;
- case DMX_LOCAL_MOUSE: XmuSnprintf(buf, LEN, "Mouse%d", m++); break;
- default: XmuSnprintf(buf, LEN, "Other%d", o++); break;
- }
-
- return buf;
-}
-
-static DeviceIntPtr dmxAddDevice(DMXLocalInputInfoPtr dmxLocal)
-{
- DeviceIntPtr pDevice;
- Atom atom;
- const char *name = NULL;
- void (*registerProcPtr)(DeviceIntPtr) = NULL;
- char *devname;
- DMXInputInfo *dmxInput;
-
- if (!dmxLocal)
- return NULL;
- dmxInput = &dmxInputs[dmxLocal->inputIdx];
-
- if (dmxLocal->sendsCore) {
- if (dmxLocal->type == DMX_LOCAL_KEYBOARD && !dmxLocalCoreKeyboard) {
- dmxLocal->isCore = 1;
- dmxLocalCoreKeyboard = dmxLocal;
- name = "keyboard";
- registerProcPtr = RegisterKeyboardDevice;
- }
- if (dmxLocal->type == DMX_LOCAL_MOUSE && !dmxLocalCorePointer) {
- dmxLocal->isCore = 1;
- dmxLocalCorePointer = dmxLocal;
- name = "pointer";
- registerProcPtr = RegisterPointerDevice;
- }
- }
-
- if (!name) {
- name = "extension";
- registerProcPtr = RegisterOtherDevice;
- }
-
- if (!name || !registerProcPtr)
- dmxLog(dmxFatal, "Cannot add device %s\n", dmxLocal->name);
-
- pDevice = AddInputDevice(serverClient, dmxDeviceOnOff, TRUE);
- if (!pDevice) {
- dmxLog(dmxError, "Too many devices -- cannot add device %s\n",
- dmxLocal->name);
- return NULL;
- }
- pDevice->public.devicePrivate = dmxLocal;
- dmxLocal->pDevice = pDevice;
-
- devname = dmxMakeUniqueDeviceName(dmxLocal);
- atom = MakeAtom((char *)devname, strlen(devname), TRUE);
- pDevice->type = atom;
- pDevice->name = devname;
-
- registerProcPtr(pDevice);
-
- if (dmxLocal->isCore && dmxLocal->type == DMX_LOCAL_MOUSE) {
-#if 00 /*BP*/
- miRegisterPointerDevice(screenInfo.screens[0], pDevice);
-#else
- /* Nothing? dmxDeviceOnOff() should get called to init, right? */
-#endif
- }
-
- if (dmxLocal->create_private)
- dmxLocal->private = dmxLocal->create_private(pDevice);
-
- dmxLogInput(dmxInput, "Added %s as %s device called %s%s\n",
- dmxLocal->name, name, devname,
- dmxLocal->isCore
- ? " [core]"
- : (dmxLocal->sendsCore
- ? " [sends core events]"
- : ""));
-
- return pDevice;
-}
-
-static DMXLocalInputInfoPtr dmxLookupLocal(const char *name)
-{
- DMXLocalInputInfoPtr pt;
-
- for (pt = &DMXLocalDevices[0]; pt->name; ++pt)
- if (!strcmp(pt->name, name)) return pt; /* search for device name */
- return NULL;
-}
-
-/** Copy the local input information from \a s into a new \a devs slot
- * in \a dmxInput. */
-DMXLocalInputInfoPtr dmxInputCopyLocal(DMXInputInfo *dmxInput,
- DMXLocalInputInfoPtr s)
-{
- DMXLocalInputInfoPtr dmxLocal = xalloc(sizeof(*dmxLocal));
-
- if (!dmxLocal)
- dmxLog(dmxFatal, "DMXLocalInputInfoPtr: out of memory\n");
-
- memcpy(dmxLocal, s, sizeof(*dmxLocal));
- dmxLocal->inputIdx = dmxInput->inputIdx;
- dmxLocal->sendsCore = dmxInput->core;
- dmxLocal->savedSendsCore = dmxInput->core;
- dmxLocal->deviceId = -1;
-
- ++dmxInput->numDevs;
- dmxInput->devs = xrealloc(dmxInput->devs,
- dmxInput->numDevs * sizeof(*dmxInput->devs));
- dmxInput->devs[dmxInput->numDevs-1] = dmxLocal;
-
- return dmxLocal;
-}
-
-static void dmxPopulateLocal(DMXInputInfo *dmxInput, dmxArg a)
-{
- int i;
- int help = 0;
- DMXLocalInputInfoRec *pt;
-
- for (i = 1; i < dmxArgC(a); i++) {
- const char *name = dmxArgV(a, i);
- if ((pt = dmxLookupLocal(name))) {
- dmxInputCopyLocal(dmxInput, pt);
- } else {
- if (strlen(name))
- dmxLog(dmxWarning,
- "Could not find a driver called %s\n", name);
- ++help;
- }
- }
- if (help) {
- dmxLog(dmxInfo, "Available local device drivers:\n");
- for (pt = &DMXLocalDevices[0]; pt->name; ++pt) {
- const char *type;
- switch (pt->type) {
- case DMX_LOCAL_KEYBOARD: type = "keyboard"; break;
- case DMX_LOCAL_MOUSE: type = "pointer"; break;
- default: type = "unknown"; break;
- }
- dmxLog(dmxInfo, " %s (%s)\n", pt->name, type);
- }
- dmxLog(dmxFatal, "Must have valid local device driver\n");
- }
-}
-
-int dmxInputExtensionErrorHandler(Display *dsp, char *name, char *reason)
-{
- return 0;
-}
-
-static void dmxInputScanForExtensions(DMXInputInfo *dmxInput, int doXI)
-{
- XExtensionVersion *ext;
- XDeviceInfo *devices;
- Display *display;
- int num;
- int i, j;
- DMXLocalInputInfoPtr dmxLocal;
- int (*handler)(Display *, char *, char *);
-
- if (!(display = XOpenDisplay(dmxInput->name))) return;
-
- /* Print out information about the XInput Extension. */
- handler = XSetExtensionErrorHandler(dmxInputExtensionErrorHandler);
- ext = XGetExtensionVersion(display, INAME);
- XSetExtensionErrorHandler(handler);
-
- if (!ext || ext == (XExtensionVersion *)NoSuchExtension) {
- dmxLogInput(dmxInput, "%s is not available\n", INAME);
- } else {
- dmxLogInput(dmxInput, "Locating devices on %s (%s version %d.%d)\n",
- dmxInput->name, INAME,
- ext->major_version, ext->minor_version);
- devices = XListInputDevices(display, &num);
-
- XFree(ext);
- ext = NULL;
-
- /* Print a list of all devices */
- for (i = 0; i < num; i++) {
- const char *use = "Unknown";
- switch (devices[i].use) {
- case IsXPointer: use = "XPointer"; break;
- case IsXKeyboard: use = "XKeyboard"; break;
- case IsXExtensionDevice: use = "XExtensionDevice"; break;
- case IsXExtensionPointer: use = "XExtensionPointer"; break;
- case IsXExtensionKeyboard: use = "XExtensionKeyboard"; break;
- }
- dmxLogInput(dmxInput, " %2d %-10.10s %-16.16s\n",
- devices[i].id,
- devices[i].name ? devices[i].name : "",
- use);
- }
-
- /* Search for extensions */
- for (i = 0; i < num; i++) {
- switch (devices[i].use) {
- case IsXKeyboard:
- for (j = 0; j < dmxInput->numDevs; j++) {
- DMXLocalInputInfoPtr dmxL = dmxInput->devs[j];
- if (dmxL->type == DMX_LOCAL_KEYBOARD
- && dmxL->deviceId < 0) {
- dmxL->deviceId = devices[i].id;
- dmxL->deviceName = (devices[i].name
- ? xstrdup(devices[i].name)
- : NULL);
- }
- }
- break;
- case IsXPointer:
- for (j = 0; j < dmxInput->numDevs; j++) {
- DMXLocalInputInfoPtr dmxL = dmxInput->devs[j];
- if (dmxL->type == DMX_LOCAL_MOUSE && dmxL->deviceId < 0) {
- dmxL->deviceId = devices[i].id;
- dmxL->deviceName = (devices[i].name
- ? xstrdup(devices[i].name)
- : NULL);
- }
- }
- break;
-#if 0
- case IsXExtensionDevice:
- case IsXExtensionKeyboard:
- case IsXExtensionPointer:
- if (doXI) {
- if (!dmxInput->numDevs) {
- dmxLog(dmxWarning,
- "Cannot use remote (%s) XInput devices if"
- " not also using core devices\n",
- dmxInput->name);
- } else {
- dmxLocal = dmxInputCopyLocal(dmxInput,
- &DMXCommonOth);
- dmxLocal->isCore = FALSE;
- dmxLocal->sendsCore = FALSE;
- dmxLocal->deviceId = devices[i].id;
- dmxLocal->deviceName = (devices[i].name
- ? xstrdup(devices[i].name)
- : NULL);
- }
- }
- break;
-#endif
- }
- }
- XFreeDeviceList(devices);
- }
- XCloseDisplay(display);
-}
-
-/** Re-initialize all the devices described in \a dmxInput. Called from
- #dmxAdjustCursorBoundaries before the cursor is redisplayed. */
-void dmxInputReInit(DMXInputInfo *dmxInput)
-{
- int i;
-
- for (i = 0; i < dmxInput->numDevs; i++) {
- DMXLocalInputInfoPtr dmxLocal = dmxInput->devs[i];
- if (dmxLocal->reinit)
- dmxLocal->reinit(&dmxLocal->pDevice->public);
- }
-}
-
-/** Re-initialize all the devices described in \a dmxInput. Called from
- #dmxAdjustCursorBoundaries after the cursor is redisplayed. */
-void dmxInputLateReInit(DMXInputInfo *dmxInput)
-{
- int i;
-
- for (i = 0; i < dmxInput->numDevs; i++) {
- DMXLocalInputInfoPtr dmxLocal = dmxInput->devs[i];
- if (dmxLocal->latereinit)
- dmxLocal->latereinit(&dmxLocal->pDevice->public);
- }
-}
-
-/** Initialize all of the devices described in \a dmxInput. */
-void dmxInputInit(DMXInputInfo *dmxInput)
-{
- DeviceIntPtr pPointer = NULL, pKeyboard = NULL;
- dmxArg a;
- const char *name;
- int i;
- int doXI = 1; /* Include by default */
- int forceConsole = 0;
- int doWindows = 1; /* On by default */
- int hasXkb = 0;
-
- a = dmxArgParse(dmxInput->name);
-
- for (i = 1; i < dmxArgC(a); i++) {
- switch (hasXkb) {
- case 1:
- dmxInput->keycodes = xstrdup(dmxArgV(a, i));
- ++hasXkb;
- break;
- case 2:
- dmxInput->symbols = xstrdup(dmxArgV(a, i));
- ++hasXkb;
- break;
- case 3:
- dmxInput->geometry = xstrdup(dmxArgV(a, i));
- hasXkb = 0;
- break;
- case 0:
- if (!strcmp(dmxArgV(a, i), "noxi")) doXI = 0;
- else if (!strcmp(dmxArgV(a, i), "xi")) doXI = 1;
- else if (!strcmp(dmxArgV(a, i), "console")) forceConsole = 1;
- else if (!strcmp(dmxArgV(a, i), "noconsole")) forceConsole = 0;
- else if (!strcmp(dmxArgV(a, i), "windows")) doWindows = 1;
- else if (!strcmp(dmxArgV(a, i), "nowindows")) doWindows = 0;
- else if (!strcmp(dmxArgV(a, i), "xkb")) hasXkb = 1;
- else {
- dmxLog(dmxFatal,
- "Unknown input argument: %s\n", dmxArgV(a, i));
- }
- }
- }
-
- name = dmxArgV(a, 0);
-
- if (!strcmp(name, "local")) {
- dmxPopulateLocal(dmxInput, a);
- } else if (!strcmp(name, "dummy")) {
- dmxInputCopyLocal(dmxInput, &DMXDummyMou);
- dmxInputCopyLocal(dmxInput, &DMXDummyKbd);
- dmxLogInput(dmxInput, "Using dummy input\n");
- } else {
- int found;
-
- for (found = 0, i = 0; i < dmxNumScreens; i++) {
- if (dmxPropertySameDisplay(&dmxScreens[i], name)) {
- if (dmxScreens[i].shared)
- dmxLog(dmxFatal,
- "Cannot take input from shared backend (%s)\n",
- name);
- if (!dmxInput->core) {
- dmxLog(dmxWarning,
- "Cannot use core devices on a backend (%s)"
- " as XInput devices\n", name);
- } else {
- char *pt;
- for (pt = (char *)dmxInput->name; pt && *pt; pt++)
- if (*pt == ',') *pt = '\0';
- dmxInputCopyLocal(dmxInput, &DMXBackendMou);
- dmxInputCopyLocal(dmxInput, &DMXBackendKbd);
- dmxInput->scrnIdx = i;
- dmxLogInput(dmxInput,
- "Using backend input from %s\n", name);
- }
- ++found;
- break;
- }
- }
- if (!found || forceConsole) {
- char *pt;
- if (found) dmxInput->console = TRUE;
- for (pt = (char *)dmxInput->name; pt && *pt; pt++)
- if (*pt == ',') *pt = '\0';
- dmxInputCopyLocal(dmxInput, &DMXConsoleMou);
- dmxInputCopyLocal(dmxInput, &DMXConsoleKbd);
- if (doWindows) {
- dmxInput->windows = TRUE;
- dmxInput->updateWindowInfo = dmxUpdateWindowInformation;
- }
- dmxLogInput(dmxInput,
- "Using console input from %s (%s windows)\n",
- name, doWindows ? "with" : "without");
- }
- }
-
- dmxArgFree(a);
-
- /* Locate extensions we may be interested in */
- dmxInputScanForExtensions(dmxInput, doXI);
-
- for (i = 0; i < dmxInput->numDevs; i++) {
- DMXLocalInputInfoPtr dmxLocal = dmxInput->devs[i];
- dmxLocal->pDevice = dmxAddDevice(dmxLocal);
- if (dmxLocal->isCore) {
- if (dmxLocal->type == DMX_LOCAL_MOUSE)
- pPointer = dmxLocal->pDevice;
- if (dmxLocal->type == DMX_LOCAL_KEYBOARD)
- pKeyboard = dmxLocal->pDevice;
- }
- }
-
- dmxInput->processInputEvents = dmxProcessInputEvents;
- dmxInput->detached = False;
-
- RegisterBlockAndWakeupHandlers(dmxBlockHandler,
- dmxWakeupHandler,
- (void *)dmxInput->inputIdx);
-}
-
-static void dmxInputFreeLocal(DMXLocalInputInfoRec *local)
-{
- if (!local) return;
- if (local->isCore && local->type == DMX_LOCAL_MOUSE)
- dmxLocalCorePointer = NULL;
- if (local->isCore && local->type == DMX_LOCAL_KEYBOARD)
- dmxLocalCoreKeyboard = NULL;
- if (local->destroy_private) local->destroy_private(local->private);
- if (local->history) xfree(local->history);
- if (local->valuators) xfree(local->valuators);
- if (local->deviceName) xfree(local->deviceName);
- local->private = NULL;
- local->history = NULL;
- local->deviceName = NULL;
- xfree(local);
-}
-
-/** Free all of the memory associated with \a dmxInput */
-void dmxInputFree(DMXInputInfo *dmxInput)
-{
- int i;
-
- if (!dmxInput) return;
-
- if (dmxInput->keycodes) xfree(dmxInput->keycodes);
- if (dmxInput->symbols) xfree(dmxInput->symbols);
- if (dmxInput->geometry) xfree(dmxInput->geometry);
-
- for (i = 0; i < dmxInput->numDevs; i++) {
- dmxInputFreeLocal(dmxInput->devs[i]);
- dmxInput->devs[i] = NULL;
- }
- xfree(dmxInput->devs);
- dmxInput->devs = NULL;
- dmxInput->numDevs = 0;
- if (dmxInput->freename) xfree(dmxInput->name);
- dmxInput->name = NULL;
-}
-
-/** Log information about all of the known devices using #dmxLog(). */
-void dmxInputLogDevices(void)
-{
- int i, j;
-
- dmxLog(dmxInfo, "%d devices:\n", dmxGetInputCount());
- dmxLog(dmxInfo, " Id Name Classes\n");
- for (j = 0; j < dmxNumInputs; j++) {
- DMXInputInfo *dmxInput = &dmxInputs[j];
- const char *pt = strchr(dmxInput->name, ',');
- int len = (pt
- ? (size_t)(pt-dmxInput->name)
- : strlen(dmxInput->name));
-
- for (i = 0; i < dmxInput->numDevs; i++) {
- DeviceIntPtr pDevice = dmxInput->devs[i]->pDevice;
- if (pDevice) {
- dmxLog(dmxInfo, " %2d%c %-20.20s",
- pDevice->id,
- dmxInput->detached ? 'D' : ' ',
- pDevice->name);
- if (pDevice->key) dmxLogCont(dmxInfo, " key");
- if (pDevice->valuator) dmxLogCont(dmxInfo, " val");
- if (pDevice->button) dmxLogCont(dmxInfo, " btn");
- if (pDevice->focus) dmxLogCont(dmxInfo, " foc");
- if (pDevice->kbdfeed) dmxLogCont(dmxInfo, " fb/kbd");
- if (pDevice->ptrfeed) dmxLogCont(dmxInfo, " fb/ptr");
- if (pDevice->intfeed) dmxLogCont(dmxInfo, " fb/int");
- if (pDevice->stringfeed) dmxLogCont(dmxInfo, " fb/str");
- if (pDevice->bell) dmxLogCont(dmxInfo, " fb/bel");
- if (pDevice->leds) dmxLogCont(dmxInfo, " fb/led");
- if (!pDevice->key && !pDevice->valuator && !pDevice->button
- && !pDevice->focus && !pDevice->kbdfeed
- && !pDevice->ptrfeed && !pDevice->intfeed
- && !pDevice->stringfeed && !pDevice->bell
- && !pDevice->leds) dmxLogCont(dmxInfo, " (none)");
-
- dmxLogCont(dmxInfo, "\t[i%d/%*.*s",
- dmxInput->inputIdx, len, len, dmxInput->name);
- if (dmxInput->devs[i]->deviceId >= 0)
- dmxLogCont(dmxInfo, "/id%d", dmxInput->devs[i]->deviceId);
- if (dmxInput->devs[i]->deviceName)
- dmxLogCont(dmxInfo, "=%s", dmxInput->devs[i]->deviceName);
- dmxLogCont(dmxInfo, "] %s\n",
- dmxInput->devs[i]->isCore
- ? "core"
- : (dmxInput->devs[i]->sendsCore
- ? "extension (sends core events)"
- : "extension"));
- }
- }
- }
-}
-
-/** Detach an input */
-int dmxInputDetach(DMXInputInfo *dmxInput)
-{
- int i;
-
- if (dmxInput->detached) return BadAccess;
-
- for (i = 0; i < dmxInput->numDevs; i++) {
- DMXLocalInputInfoPtr dmxLocal = dmxInput->devs[i];
- dmxLogInput(dmxInput, "Detaching device id %d: %s%s\n",
- dmxLocal->pDevice->id,
- dmxLocal->pDevice->name,
- dmxLocal->isCore
- ? " [core]"
- : (dmxLocal->sendsCore
- ? " [sends core events]"
- : ""));
- DisableDevice(dmxLocal->pDevice, TRUE);
- }
- dmxInput->detached = True;
- dmxInputLogDevices();
- return 0;
-}
-
-/** Search for input associated with \a dmxScreen, and detach. */
-void dmxInputDetachAll(DMXScreenInfo *dmxScreen)
-{
- int i;
-
- for (i = 0; i < dmxNumInputs; i++) {
- DMXInputInfo *dmxInput = &dmxInputs[i];
- if (dmxInput->scrnIdx == dmxScreen->index) dmxInputDetach(dmxInput);
- }
-}
-
-/** Search for input associated with \a deviceId, and detach. */
-int dmxInputDetachId(int id)
-{
- DMXInputInfo *dmxInput = dmxInputLocateId(id);
-
- if (!dmxInput) return BadValue;
-
- return dmxInputDetach(dmxInput);
-}
-
-DMXInputInfo *dmxInputLocateId(int id)
-{
- int i, j;
-
- for (i = 0; i < dmxNumInputs; i++) {
- DMXInputInfo *dmxInput = &dmxInputs[i];
- for (j = 0; j < dmxInput->numDevs; j++) {
- DMXLocalInputInfoPtr dmxLocal = dmxInput->devs[j];
- if (dmxLocal->pDevice->id == id) return dmxInput;
- }
- }
- return NULL;
-}
-
-static int dmxInputAttachNew(DMXInputInfo *dmxInput, int *id)
-{
- dmxInputInit(dmxInput);
- InitAndStartDevices();
- if (id && dmxInput->devs) *id = dmxInput->devs[0]->pDevice->id;
- dmxInputLogDevices();
- return 0;
-}
-
-static int dmxInputAttachOld(DMXInputInfo *dmxInput, int *id)
-{
- int i;
-
- dmxInput->detached = False;
- for (i = 0; i < dmxInput->numDevs; i++) {
- DMXLocalInputInfoPtr dmxLocal = dmxInput->devs[i];
- if (id) *id = dmxLocal->pDevice->id;
- dmxLogInput(dmxInput,
- "Attaching device id %d: %s%s\n",
- dmxLocal->pDevice->id,
- dmxLocal->pDevice->name,
- dmxLocal->isCore
- ? " [core]"
- : (dmxLocal->sendsCore
- ? " [sends core events]"
- : ""));
- EnableDevice(dmxLocal->pDevice, TRUE);
- }
- dmxInputLogDevices();
- return 0;
-}
-
-int dmxInputAttachConsole(const char *name, int isCore, int *id)
-{
- DMXInputInfo *dmxInput;
- int i;
-
- for (i = 0; i < dmxNumInputs; i++) {
- dmxInput = &dmxInputs[i];
- if (dmxInput->scrnIdx == -1
- && dmxInput->detached
- && !strcmp(dmxInput->name, name)) {
- /* Found match */
- dmxLogInput(dmxInput, "Reattaching detached console input\n");
- return dmxInputAttachOld(dmxInput, id);
- }
- }
-
- /* No match found */
- dmxInput = dmxConfigAddInput(xstrdup(name), isCore);
- dmxInput->freename = TRUE;
- dmxLogInput(dmxInput, "Attaching new console input\n");
- return dmxInputAttachNew(dmxInput, id);
-}
-
-int dmxInputAttachBackend(int physicalScreen, int isCore, int *id)
-{
- DMXInputInfo *dmxInput;
- DMXScreenInfo *dmxScreen;
- int i;
-
- if (physicalScreen < 0 || physicalScreen >= dmxNumScreens) return BadValue;
- for (i = 0; i < dmxNumInputs; i++) {
- dmxInput = &dmxInputs[i];
- if (dmxInput->scrnIdx != -1 && dmxInput->scrnIdx == physicalScreen) {
- /* Found match */
- if (!dmxInput->detached) return BadAccess; /* Already attached */
- dmxScreen = &dmxScreens[physicalScreen];
- if (!dmxScreen->beDisplay) return BadAccess; /* Screen detached */
- dmxLogInput(dmxInput, "Reattaching detached backend input\n");
- return dmxInputAttachOld(dmxInput, id);
- }
- }
- /* No match found */
- dmxScreen = &dmxScreens[physicalScreen];
- if (!dmxScreen->beDisplay) return BadAccess; /* Screen detached */
- dmxInput = dmxConfigAddInput(dmxScreen->name, isCore);
- dmxLogInput(dmxInput, "Attaching new backend input\n");
- return dmxInputAttachNew(dmxInput, id);
-}
+/*
+ * Copyright 2002-2003 Red Hat Inc., Durham, North Carolina.
+ *
+ * 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 on 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 (including the
+ * next paragraph) 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
+ * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
+ * 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.
+ */
+
+/*
+ * Authors:
+ * Rickard E. (Rik) Faith <faith@redhat.com>
+ *
+ */
+
+/** \file
+ * This file provides generic input support. Functions here set up
+ * input and lead to the calling of low-level device drivers for
+ * input. */
+
+#ifdef HAVE_DMX_CONFIG_H
+#include <dmx-config.h>
+#endif
+
+#define DMX_WINDOW_DEBUG 0
+
+#include "dmxinputinit.h"
+#include "dmxextension.h" /* For dmxInputCount */
+
+#include "dmxdummy.h"
+#include "dmxbackend.h"
+#include "dmxconsole.h"
+#include "dmxcommon.h"
+#include "dmxevents.h"
+#include "dmxmotion.h"
+#include "dmxprop.h"
+#include "config/dmxconfig.h"
+#include "dmxcursor.h"
+
+#include "lnx-keyboard.h"
+#include "lnx-ms.h"
+#include "lnx-ps2.h"
+#include "usb-keyboard.h"
+#include "usb-mouse.h"
+#include "usb-other.h"
+#include "usb-common.h"
+
+#include "dmxsigio.h"
+#include "dmxarg.h"
+
+#include "inputstr.h"
+#include "input.h"
+#include "mipointer.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "xkbsrv.h"
+
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XIproto.h>
+#include "exevents.h"
+#include "extinit.h"
+
+DMXLocalInputInfoPtr dmxLocalCorePointer, dmxLocalCoreKeyboard;
+
+static DMXLocalInputInfoRec DMXDummyMou = {
+ "dummy-mou", DMX_LOCAL_MOUSE, DMX_LOCAL_TYPE_LOCAL, 1,
+ NULL, NULL, NULL, NULL, NULL, dmxDummyMouGetInfo
+};
+
+static DMXLocalInputInfoRec DMXDummyKbd = {
+ "dummy-kbd", DMX_LOCAL_KEYBOARD, DMX_LOCAL_TYPE_LOCAL, 1,
+ NULL, NULL, NULL, NULL, NULL, dmxDummyKbdGetInfo
+};
+
+static DMXLocalInputInfoRec DMXBackendMou = {
+ "backend-mou", DMX_LOCAL_MOUSE, DMX_LOCAL_TYPE_BACKEND, 2,
+ dmxBackendCreatePrivate, dmxBackendDestroyPrivate,
+ dmxBackendInit, NULL, dmxBackendLateReInit, dmxBackendMouGetInfo,
+ dmxCommonMouOn, dmxCommonMouOff, dmxBackendUpdatePosition,
+ NULL, NULL, NULL,
+ dmxBackendCollectEvents, dmxBackendProcessInput, dmxBackendFunctions, NULL,
+ dmxCommonMouCtrl
+};
+
+static DMXLocalInputInfoRec DMXBackendKbd = {
+ "backend-kbd", DMX_LOCAL_KEYBOARD, DMX_LOCAL_TYPE_BACKEND,
+ 1, /* With backend-mou or console-mou */
+ dmxCommonCopyPrivate, NULL,
+ dmxBackendInit, NULL, NULL, dmxBackendKbdGetInfo,
+ dmxCommonKbdOn, dmxCommonKbdOff, NULL,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, dmxCommonKbdCtrl, dmxCommonKbdBell
+};
+
+static DMXLocalInputInfoRec DMXConsoleMou = {
+ "console-mou", DMX_LOCAL_MOUSE, DMX_LOCAL_TYPE_CONSOLE, 2,
+ dmxConsoleCreatePrivate, dmxConsoleDestroyPrivate,
+ dmxConsoleInit, dmxConsoleReInit, NULL, dmxConsoleMouGetInfo,
+ dmxCommonMouOn, dmxCommonMouOff, dmxConsoleUpdatePosition,
+ NULL, NULL, NULL,
+ dmxConsoleCollectEvents, NULL, dmxConsoleFunctions, dmxConsoleUpdateInfo,
+ dmxCommonMouCtrl
+};
+
+static DMXLocalInputInfoRec DMXConsoleKbd = {
+ "console-kbd", DMX_LOCAL_KEYBOARD, DMX_LOCAL_TYPE_CONSOLE,
+ 1, /* With backend-mou or console-mou */
+ dmxCommonCopyPrivate, NULL,
+ dmxConsoleInit, dmxConsoleReInit, NULL, dmxConsoleKbdGetInfo,
+ dmxCommonKbdOn, dmxCommonKbdOff, NULL,
+ NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL,
+ NULL, dmxCommonKbdCtrl, dmxCommonKbdBell
+};
+
+static DMXLocalInputInfoRec DMXCommonOth = {
+ "common-oth", DMX_LOCAL_OTHER, DMX_LOCAL_TYPE_COMMON, 1,
+ dmxCommonCopyPrivate, NULL,
+ NULL, NULL, NULL, dmxCommonOthGetInfo,
+ dmxCommonOthOn, dmxCommonOthOff
+};
+
+
+static DMXLocalInputInfoRec DMXLocalDevices[] = {
+ /* Dummy drivers that can compile on any OS */
+#ifdef __linux__
+ /* Linux-specific drivers */
+ {
+ "kbd", DMX_LOCAL_KEYBOARD, DMX_LOCAL_TYPE_LOCAL, 1,
+ kbdLinuxCreatePrivate, kbdLinuxDestroyPrivate,
+ kbdLinuxInit, NULL, NULL, kbdLinuxGetInfo,
+ kbdLinuxOn, kbdLinuxOff, NULL,
+ kbdLinuxVTPreSwitch, kbdLinuxVTPostSwitch, kbdLinuxVTSwitch,
+ kbdLinuxRead, NULL, NULL, NULL,
+ NULL, kbdLinuxCtrl, kbdLinuxBell
+ },
+ {
+ "ms", DMX_LOCAL_MOUSE, DMX_LOCAL_TYPE_LOCAL, 1,
+ msLinuxCreatePrivate, msLinuxDestroyPrivate,
+ msLinuxInit, NULL, NULL, msLinuxGetInfo,
+ msLinuxOn, msLinuxOff, NULL,
+ msLinuxVTPreSwitch, msLinuxVTPostSwitch, NULL,
+ msLinuxRead
+ },
+ {
+ "ps2", DMX_LOCAL_MOUSE, DMX_LOCAL_TYPE_LOCAL, 1,
+ ps2LinuxCreatePrivate, ps2LinuxDestroyPrivate,
+ ps2LinuxInit, NULL, NULL, ps2LinuxGetInfo,
+ ps2LinuxOn, ps2LinuxOff, NULL,
+ ps2LinuxVTPreSwitch, ps2LinuxVTPostSwitch, NULL,
+ ps2LinuxRead
+ },
+#endif
+#ifdef __linux__
+ /* USB drivers, currently only for
+ Linux, but relatively easy to port to
+ other OSs */
+ {
+ "usb-kbd", DMX_LOCAL_KEYBOARD, DMX_LOCAL_TYPE_LOCAL, 1,
+ usbCreatePrivate, usbDestroyPrivate,
+ kbdUSBInit, NULL, NULL, kbdUSBGetInfo,
+ kbdUSBOn, usbOff, NULL,
+ NULL, NULL, NULL,
+ kbdUSBRead, NULL, NULL, NULL,
+ NULL, kbdUSBCtrl
+ },
+ {
+ "usb-mou", DMX_LOCAL_MOUSE, DMX_LOCAL_TYPE_LOCAL, 1,
+ usbCreatePrivate, usbDestroyPrivate,
+ mouUSBInit, NULL, NULL, mouUSBGetInfo,
+ mouUSBOn, usbOff, NULL,
+ NULL, NULL, NULL,
+ mouUSBRead
+ },
+ {
+ "usb-oth", DMX_LOCAL_OTHER, DMX_LOCAL_TYPE_LOCAL, 1,
+ usbCreatePrivate, usbDestroyPrivate,
+ othUSBInit, NULL, NULL, othUSBGetInfo,
+ othUSBOn, usbOff, NULL,
+ NULL, NULL, NULL,
+ othUSBRead
+ },
+#endif
+ {
+ "dummy-mou", DMX_LOCAL_MOUSE, DMX_LOCAL_TYPE_LOCAL, 1,
+ NULL, NULL, NULL, NULL, NULL, dmxDummyMouGetInfo
+ },
+ {
+ "dummy-kbd", DMX_LOCAL_KEYBOARD, DMX_LOCAL_TYPE_LOCAL, 1,
+ NULL, NULL, NULL, NULL, NULL, dmxDummyKbdGetInfo
+ },
+ { NULL } /* Must be last */
+};
+
+
+#if 11 /*BP*/
+void
+DDXRingBell(int volume, int pitch, int duration)
+{
+ /* NO-OP */
+}
+
+/* taken from kdrive/src/kinput.c: */
+static void
+dmxKbdCtrl (DeviceIntPtr pDevice, KeybdCtrl *ctrl)
+{
+#if 0
+ KdKeyboardInfo *ki;
+
+ for (ki = kdKeyboards; ki; ki = ki->next) {
+ if (ki->dixdev && ki->dixdev->id == pDevice->id)
+ break;
+ }
+
+ if (!ki || !ki->dixdev || ki->dixdev->id != pDevice->id || !ki->driver)
+ return;
+
+ KdSetLeds(ki, ctrl->leds);
+ ki->bellPitch = ctrl->bell_pitch;
+ ki->bellDuration = ctrl->bell_duration;
+#endif
+}
+
+/* taken from kdrive/src/kinput.c: */
+static void
+dmxBell(int volume, DeviceIntPtr pDev, pointer arg, int something)
+{
+#if 0
+ KeybdCtrl *ctrl = arg;
+ KdKeyboardInfo *ki = NULL;
+
+ for (ki = kdKeyboards; ki; ki = ki->next) {
+ if (ki->dixdev && ki->dixdev->id == pDev->id)
+ break;
+ }
+
+ if (!ki || !ki->dixdev || ki->dixdev->id != pDev->id || !ki->driver)
+ return;
+
+ KdRingBell(ki, volume, ctrl->bell_pitch, ctrl->bell_duration);
+#endif
+}
+
+#endif /*BP*/
+
+static void _dmxChangePointerControl(DMXLocalInputInfoPtr dmxLocal,
+ PtrCtrl *ctrl)
+{
+ if (!dmxLocal) return;
+ dmxLocal->mctrl = *ctrl;
+ if (dmxLocal->mCtrl) dmxLocal->mCtrl(&dmxLocal->pDevice->public, ctrl);
+}
+
+/** Change the pointer control information for the \a pDevice. If the
+ * device sends core events, then also change the control information
+ * for all of the pointer devices that send core events. */
+void dmxChangePointerControl(DeviceIntPtr pDevice, PtrCtrl *ctrl)
+{
+ GETDMXLOCALFROMPDEVICE;
+ int i, j;
+
+ if (dmxLocal->sendsCore) { /* Do for all core devices */
+ for (i = 0; i < dmxNumInputs; i++) {
+ DMXInputInfo *dmxInput = &dmxInputs[i];
+ if (dmxInput->detached) continue;
+ for (j = 0; j < dmxInput->numDevs; j++)
+ if (dmxInput->devs[j]->sendsCore)
+ _dmxChangePointerControl(dmxInput->devs[j], ctrl);
+ }
+ } else { /* Do for this device only */
+ _dmxChangePointerControl(dmxLocal, ctrl);
+ }
+}
+
+static void _dmxKeyboardKbdCtrlProc(DMXLocalInputInfoPtr dmxLocal,
+ KeybdCtrl *ctrl)
+{
+ dmxLocal->kctrl = *ctrl;
+ if (dmxLocal->kCtrl) {
+ dmxLocal->kCtrl(&dmxLocal->pDevice->public, ctrl);
+ if (dmxLocal->pDevice->kbdfeed) {
+ XkbEventCauseRec cause;
+ XkbSetCauseUnknown(&cause);
+ /* Generate XKB events, as necessary */
+ XkbUpdateIndicators(dmxLocal->pDevice, XkbAllIndicatorsMask, False,
+ NULL, &cause);
+ }
+ }
+}
+
+
+/** Change the keyboard control information for the \a pDevice. If the
+ * device sends core events, then also change the control information
+ * for all of the keyboard devices that send core events. */
+void dmxKeyboardKbdCtrlProc(DeviceIntPtr pDevice, KeybdCtrl *ctrl)
+{
+ GETDMXLOCALFROMPDEVICE;
+ int i, j;
+
+ if (dmxLocal->sendsCore) { /* Do for all core devices */
+ for (i = 0; i < dmxNumInputs; i++) {
+ DMXInputInfo *dmxInput = &dmxInputs[i];
+ if (dmxInput->detached) continue;
+ for (j = 0; j < dmxInput->numDevs; j++)
+ if (dmxInput->devs[j]->sendsCore)
+ _dmxKeyboardKbdCtrlProc(dmxInput->devs[j], ctrl);
+ }
+ } else { /* Do for this device only */
+ _dmxKeyboardKbdCtrlProc(dmxLocal, ctrl);
+ }
+}
+
+static void _dmxKeyboardBellProc(DMXLocalInputInfoPtr dmxLocal, int percent)
+{
+ if (dmxLocal->kBell) dmxLocal->kBell(&dmxLocal->pDevice->public,
+ percent,
+ dmxLocal->kctrl.bell,
+ dmxLocal->kctrl.bell_pitch,
+ dmxLocal->kctrl.bell_duration);
+}
+
+/** Sound the bell on the device. If the device send core events, then
+ * sound the bell on all of the devices that send core events. */
+void dmxKeyboardBellProc(int percent, DeviceIntPtr pDevice,
+ pointer ctrl, int unknown)
+{
+ GETDMXLOCALFROMPDEVICE;
+ int i, j;
+
+ if (dmxLocal->sendsCore) { /* Do for all core devices */
+ for (i = 0; i < dmxNumInputs; i++) {
+ DMXInputInfo *dmxInput = &dmxInputs[i];
+ if (dmxInput->detached) continue;
+ for (j = 0; j < dmxInput->numDevs; j++)
+ if (dmxInput->devs[j]->sendsCore)
+ _dmxKeyboardBellProc(dmxInput->devs[j], percent);
+ }
+ } else { /* Do for this device only */
+ _dmxKeyboardBellProc(dmxLocal, percent);
+ }
+}
+
+static void dmxKeyboardFreeNames(XkbComponentNamesPtr names)
+{
+ if (names->keycodes) XFree(names->keycodes);
+ if (names->types) XFree(names->types);
+ if (names->compat) XFree(names->compat);
+ if (names->symbols) XFree(names->symbols);
+ if (names->geometry) XFree(names->geometry);
+}
+
+
+static int dmxKeyboardOn(DeviceIntPtr pDevice, DMXLocalInitInfo *info)
+{
+ GETDMXINPUTFROMPDEVICE;
+ XkbRMLVOSet rmlvo;
+
+ rmlvo.rules = dmxConfigGetXkbRules();
+ rmlvo.model = dmxConfigGetXkbModel();
+ rmlvo.layout = dmxConfigGetXkbLayout();
+ rmlvo.variant = dmxConfigGetXkbVariant();
+ rmlvo.options = dmxConfigGetXkbOptions();
+
+ XkbSetRulesDflts(&rmlvo);
+ if (!info->force && (dmxInput->keycodes
+ || dmxInput->symbols
+ || dmxInput->geometry)) {
+ if (info->freenames) dmxKeyboardFreeNames(&info->names);
+ info->freenames = 0;
+ info->names.keycodes = dmxInput->keycodes;
+ info->names.types = NULL;
+ info->names.compat = NULL;
+ info->names.symbols = dmxInput->symbols;
+ info->names.geometry = dmxInput->geometry;
+
+ dmxLogInput(dmxInput, "XKEYBOARD: From command line: %s",
+ info->names.keycodes);
+ if (info->names.symbols && *info->names.symbols)
+ dmxLogInputCont(dmxInput, " %s", info->names.symbols);
+ if (info->names.geometry && *info->names.geometry)
+ dmxLogInputCont(dmxInput, " %s", info->names.geometry);
+ dmxLogInputCont(dmxInput, "\n");
+ } else if (info->names.keycodes) {
+ dmxLogInput(dmxInput, "XKEYBOARD: From device: %s",
+ info->names.keycodes);
+ if (info->names.symbols && *info->names.symbols)
+ dmxLogInputCont(dmxInput, " %s", info->names.symbols);
+ if (info->names.geometry && *info->names.geometry)
+ dmxLogInputCont(dmxInput, " %s", info->names.geometry);
+ dmxLogInputCont(dmxInput, "\n");
+ } else {
+ dmxLogInput(dmxInput, "XKEYBOARD: Defaults: %s %s %s %s %s\n",
+ dmxConfigGetXkbRules(),
+ dmxConfigGetXkbLayout(),
+ dmxConfigGetXkbModel(),
+ dmxConfigGetXkbVariant()
+ ? dmxConfigGetXkbVariant() : "",
+ dmxConfigGetXkbOptions()
+ ? dmxConfigGetXkbOptions() : "");
+ }
+ InitKeyboardDeviceStruct(pDevice, &rmlvo,
+ dmxKeyboardBellProc,
+ dmxKeyboardKbdCtrlProc);
+
+ if (info->freenames) dmxKeyboardFreeNames(&info->names);
+
+ return Success;
+}
+
+
+static int dmxDeviceOnOff(DeviceIntPtr pDevice, int what)
+{
+ GETDMXINPUTFROMPDEVICE;
+ int fd;
+ DMXLocalInitInfo info;
+ int i;
+ Atom btn_labels[MAX_BUTTONS] = {0}; /* FIXME */
+ Atom axis_labels[MAX_VALUATORS] = {0}; /* FIXME */
+
+ if (dmxInput->detached) return Success;
+
+ memset(&info, 0, sizeof(info));
+ switch (what) {
+ case DEVICE_INIT:
+ if (dmxLocal->init)
+ dmxLocal->init(pDev);
+ if (dmxLocal->get_info)
+ dmxLocal->get_info(pDev, &info);
+ if (info.keyboard) { /* XKEYBOARD makes this a special case */
+ dmxKeyboardOn(pDevice, &info);
+ break;
+ }
+ if (info.keyClass) {
+ XkbRMLVOSet rmlvo;
+
+ rmlvo.rules = dmxConfigGetXkbRules();
+ rmlvo.model = dmxConfigGetXkbModel();
+ rmlvo.layout = dmxConfigGetXkbLayout();
+ rmlvo.variant = dmxConfigGetXkbVariant();
+ rmlvo.options = dmxConfigGetXkbOptions();
+
+ InitKeyboardDeviceStruct(pDevice,
+ &rmlvo,
+ dmxBell, dmxKbdCtrl);
+ }
+ if (info.buttonClass) {
+ InitButtonClassDeviceStruct(pDevice, info.numButtons,
+ btn_labels, info.map);
+ }
+ if (info.valuatorClass) {
+ if (info.numRelAxes && dmxLocal->sendsCore) {
+ InitValuatorClassDeviceStruct(pDevice, info.numRelAxes,
+ axis_labels,
+ GetMaximumEventsNum(),
+ Relative);
+ for (i = 0; i < info.numRelAxes; i++)
+ InitValuatorAxisStruct(pDevice, i, axis_labels[i],
+ info.minval[i], info.maxval[i],
+ info.res[i],
+ info.minres[i], info.maxres[i]);
+ } else if (info.numRelAxes) {
+ InitValuatorClassDeviceStruct(pDevice, info.numRelAxes,
+ axis_labels,
+ dmxPointerGetMotionBufferSize(),
+ Relative);
+ for (i = 0; i < info.numRelAxes; i++)
+ InitValuatorAxisStruct(pDevice, i, axis_labels[i],
+ info.minval[i],
+ info.maxval[i], info.res[i],
+ info.minres[i], info.maxres[i]);
+ } else if (info.numAbsAxes) {
+ InitValuatorClassDeviceStruct(pDevice, info.numAbsAxes,
+ axis_labels,
+ dmxPointerGetMotionBufferSize(),
+ Absolute);
+ for (i = 0; i < info.numAbsAxes; i++)
+ InitValuatorAxisStruct(pDevice, i,
+ axis_labels[i],
+ info.minval[i], info.maxval[i],
+ info.res[i], info.minres[i],
+ info.maxres[i]);
+ }
+ }
+ if (info.focusClass) InitFocusClassDeviceStruct(pDevice);
+ if (info.proximityClass) InitProximityClassDeviceStruct(pDevice);
+ if (info.ptrFeedbackClass)
+ InitPtrFeedbackClassDeviceStruct(pDevice, dmxChangePointerControl);
+ if (info.intFeedbackClass || info.strFeedbackClass)
+ dmxLog(dmxWarning,
+ "Integer and string feedback not supported for %s\n",
+ pDevice->name);
+ if (!info.keyboard && (info.ledFeedbackClass || info.belFeedbackClass))
+ dmxLog(dmxWarning,
+ "Led and bel feedback not supported for non-keyboard %s\n",
+ pDevice->name);
+ break;
+ case DEVICE_ON:
+ if (!pDev->on) {
+ if (dmxLocal->on && (fd = dmxLocal->on(pDev)) >= 0)
+ dmxSigioRegister(dmxInput, fd);
+ pDev->on = TRUE;
+ }
+ break;
+ case DEVICE_OFF:
+ case DEVICE_CLOSE:
+ /* This can get called twice consecutively: once for a
+ * detached screen (DEVICE_OFF), and then again at server
+ * generation time (DEVICE_CLOSE). */
+ if (pDev->on) {
+ dmxSigioUnregister(dmxInput);
+ if (dmxLocal->off) dmxLocal->off(pDev);
+ pDev->on = FALSE;
+ }
+ break;
+ }
+ if (info.keySyms.map && info.freemap) {
+ XFree(info.keySyms.map);
+ info.keySyms.map = NULL;
+ }
+ if (info.xkb) XkbFreeKeyboard(info.xkb, 0, True);
+ return Success;
+}
+
+static void dmxProcessInputEvents(DMXInputInfo *dmxInput)
+{
+ int i;
+
+ mieqProcessInputEvents();
+#if 00 /*BP*/
+ miPointerUpdate();
+#endif
+ if (dmxInput->detached)
+ return;
+ for (i = 0; i < dmxInput->numDevs; i += dmxInput->devs[i]->binding)
+ if (dmxInput->devs[i]->process_input) {
+#if 11 /*BP*/
+ miPointerUpdateSprite(dmxInput->devs[i]->pDevice);
+#endif
+ dmxInput->devs[i]->process_input(dmxInput->devs[i]->private);
+ }
+
+#if 11 /*BP*/
+ mieqProcessInputEvents();
+#endif
+}
+
+static void dmxUpdateWindowInformation(DMXInputInfo *dmxInput,
+ DMXUpdateType type,
+ WindowPtr pWindow)
+{
+ int i;
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension && pWindow && pWindow->parent != WindowTable[0])
+ return;
+#endif
+#if DMX_WINDOW_DEBUG
+ {
+ const char *name = "Unknown";
+ switch (type) {
+ case DMX_UPDATE_REALIZE: name = "Realize"; break;
+ case DMX_UPDATE_UNREALIZE: name = "Unrealize"; break;
+ case DMX_UPDATE_RESTACK: name = "Restack"; break;
+ case DMX_UPDATE_COPY: name = "Copy"; break;
+ case DMX_UPDATE_RESIZE: name = "Resize"; break;
+ case DMX_UPDATE_REPARENT: name = "Repaint"; break;
+ }
+ dmxLog(dmxDebug, "Window %p changed: %s\n", pWindow, name);
+ }
+#endif
+
+ if (dmxInput->detached)
+ return;
+ for (i = 0; i < dmxInput->numDevs; i += dmxInput->devs[i]->binding)
+ if (dmxInput->devs[i]->update_info)
+ dmxInput->devs[i]->update_info(dmxInput->devs[i]->private,
+ type, pWindow);
+}
+
+static void dmxCollectAll(DMXInputInfo *dmxInput)
+{
+ int i;
+
+ if (dmxInput->detached)
+ return;
+ for (i = 0; i < dmxInput->numDevs; i += dmxInput->devs[i]->binding)
+ if (dmxInput->devs[i]->collect_events)
+ dmxInput->devs[i]->collect_events(&dmxInput->devs[i]->pDevice->public,
+ dmxMotion,
+ dmxEnqueue,
+ dmxCheckSpecialKeys, DMX_BLOCK);
+}
+
+static void dmxBlockHandler(pointer blockData, OSTimePtr pTimeout,
+ pointer pReadMask)
+{
+ DMXInputInfo *dmxInput = &dmxInputs[(int)blockData];
+ static unsigned long generation = 0;
+
+ if (generation != serverGeneration) {
+ generation = serverGeneration;
+ dmxCollectAll(dmxInput);
+ }
+}
+
+static void dmxSwitchReturn(pointer p)
+{
+ DMXInputInfo *dmxInput = p;
+ int i;
+
+ dmxLog(dmxInfo, "Returning from VT %d\n", dmxInput->vt_switched);
+
+ if (!dmxInput->vt_switched)
+ dmxLog(dmxFatal, "dmxSwitchReturn called, but not switched\n");
+ dmxSigioEnableInput();
+ for (i = 0; i < dmxInput->numDevs; i++)
+ if (dmxInput->devs[i]->vt_post_switch)
+ dmxInput->devs[i]->vt_post_switch(dmxInput->devs[i]->private);
+ dmxInput->vt_switched = 0;
+}
+
+static void dmxWakeupHandler(pointer blockData, int result, pointer pReadMask)
+{
+ DMXInputInfo *dmxInput = &dmxInputs[(int)blockData];
+ int i;
+
+ if (dmxInput->vt_switch_pending) {
+ dmxLog(dmxInfo, "Switching to VT %d\n", dmxInput->vt_switch_pending);
+ for (i = 0; i < dmxInput->numDevs; i++)
+ if (dmxInput->devs[i]->vt_pre_switch)
+ dmxInput->devs[i]->vt_pre_switch(dmxInput->devs[i]->private);
+ dmxInput->vt_switched = dmxInput->vt_switch_pending;
+ dmxInput->vt_switch_pending = 0;
+ for (i = 0; i < dmxInput->numDevs; i++) {
+ if (dmxInput->devs[i]->vt_switch) {
+ dmxSigioDisableInput();
+ if (!dmxInput->devs[i]->vt_switch(dmxInput->devs[i]->private,
+ dmxInput->vt_switched,
+ dmxSwitchReturn,
+ dmxInput))
+ dmxSwitchReturn(dmxInput);
+ break; /* Only call one vt_switch routine */
+ }
+ }
+ }
+ dmxCollectAll(dmxInput);
+}
+
+static char *dmxMakeUniqueDeviceName(DMXLocalInputInfoPtr dmxLocal)
+{
+ static int k = 0;
+ static int m = 0;
+ static int o = 0;
+ static unsigned long dmxGeneration = 0;
+#define LEN 32
+ char * buf = malloc(LEN);
+
+ if (dmxGeneration != serverGeneration) {
+ k = m = o = 0;
+ dmxGeneration = serverGeneration;
+ }
+
+ switch (dmxLocal->type) {
+ case DMX_LOCAL_KEYBOARD: XmuSnprintf(buf, LEN, "Keyboard%d", k++); break;
+ case DMX_LOCAL_MOUSE: XmuSnprintf(buf, LEN, "Mouse%d", m++); break;
+ default: XmuSnprintf(buf, LEN, "Other%d", o++); break;
+ }
+
+ return buf;
+}
+
+static DeviceIntPtr dmxAddDevice(DMXLocalInputInfoPtr dmxLocal)
+{
+ DeviceIntPtr pDevice;
+ Atom atom;
+ const char *name = NULL;
+ void (*registerProcPtr)(DeviceIntPtr) = NULL;
+ char *devname;
+ DMXInputInfo *dmxInput;
+
+ if (!dmxLocal)
+ return NULL;
+ dmxInput = &dmxInputs[dmxLocal->inputIdx];
+
+ if (dmxLocal->sendsCore) {
+ if (dmxLocal->type == DMX_LOCAL_KEYBOARD && !dmxLocalCoreKeyboard) {
+ dmxLocal->isCore = 1;
+ dmxLocalCoreKeyboard = dmxLocal;
+ name = "keyboard";
+ registerProcPtr = RegisterKeyboardDevice;
+ }
+ if (dmxLocal->type == DMX_LOCAL_MOUSE && !dmxLocalCorePointer) {
+ dmxLocal->isCore = 1;
+ dmxLocalCorePointer = dmxLocal;
+ name = "pointer";
+ registerProcPtr = RegisterPointerDevice;
+ }
+ }
+
+ if (!name) {
+ name = "extension";
+ registerProcPtr = RegisterOtherDevice;
+ }
+
+ if (!name || !registerProcPtr)
+ dmxLog(dmxFatal, "Cannot add device %s\n", dmxLocal->name);
+
+ pDevice = AddInputDevice(serverClient, dmxDeviceOnOff, TRUE);
+ if (!pDevice) {
+ dmxLog(dmxError, "Too many devices -- cannot add device %s\n",
+ dmxLocal->name);
+ return NULL;
+ }
+ pDevice->public.devicePrivate = dmxLocal;
+ dmxLocal->pDevice = pDevice;
+
+ devname = dmxMakeUniqueDeviceName(dmxLocal);
+ atom = MakeAtom((char *)devname, strlen(devname), TRUE);
+ pDevice->type = atom;
+ pDevice->name = devname;
+
+ registerProcPtr(pDevice);
+
+ if (dmxLocal->isCore && dmxLocal->type == DMX_LOCAL_MOUSE) {
+#if 00 /*BP*/
+ miRegisterPointerDevice(screenInfo.screens[0], pDevice);
+#else
+ /* Nothing? dmxDeviceOnOff() should get called to init, right? */
+#endif
+ }
+
+ if (dmxLocal->create_private)
+ dmxLocal->private = dmxLocal->create_private(pDevice);
+
+ dmxLogInput(dmxInput, "Added %s as %s device called %s%s\n",
+ dmxLocal->name, name, devname,
+ dmxLocal->isCore
+ ? " [core]"
+ : (dmxLocal->sendsCore
+ ? " [sends core events]"
+ : ""));
+
+ return pDevice;
+}
+
+static DMXLocalInputInfoPtr dmxLookupLocal(const char *name)
+{
+ DMXLocalInputInfoPtr pt;
+
+ for (pt = &DMXLocalDevices[0]; pt->name; ++pt)
+ if (!strcmp(pt->name, name)) return pt; /* search for device name */
+ return NULL;
+}
+
+/** Copy the local input information from \a s into a new \a devs slot
+ * in \a dmxInput. */
+DMXLocalInputInfoPtr dmxInputCopyLocal(DMXInputInfo *dmxInput,
+ DMXLocalInputInfoPtr s)
+{
+ DMXLocalInputInfoPtr dmxLocal = malloc(sizeof(*dmxLocal));
+
+ if (!dmxLocal)
+ dmxLog(dmxFatal, "DMXLocalInputInfoPtr: out of memory\n");
+
+ memcpy(dmxLocal, s, sizeof(*dmxLocal));
+ dmxLocal->inputIdx = dmxInput->inputIdx;
+ dmxLocal->sendsCore = dmxInput->core;
+ dmxLocal->savedSendsCore = dmxInput->core;
+ dmxLocal->deviceId = -1;
+
+ ++dmxInput->numDevs;
+ dmxInput->devs = realloc(dmxInput->devs,
+ dmxInput->numDevs * sizeof(*dmxInput->devs));
+ dmxInput->devs[dmxInput->numDevs-1] = dmxLocal;
+
+ return dmxLocal;
+}
+
+static void dmxPopulateLocal(DMXInputInfo *dmxInput, dmxArg a)
+{
+ int i;
+ int help = 0;
+ DMXLocalInputInfoRec *pt;
+
+ for (i = 1; i < dmxArgC(a); i++) {
+ const char *name = dmxArgV(a, i);
+ if ((pt = dmxLookupLocal(name))) {
+ dmxInputCopyLocal(dmxInput, pt);
+ } else {
+ if (strlen(name))
+ dmxLog(dmxWarning,
+ "Could not find a driver called %s\n", name);
+ ++help;
+ }
+ }
+ if (help) {
+ dmxLog(dmxInfo, "Available local device drivers:\n");
+ for (pt = &DMXLocalDevices[0]; pt->name; ++pt) {
+ const char *type;
+ switch (pt->type) {
+ case DMX_LOCAL_KEYBOARD: type = "keyboard"; break;
+ case DMX_LOCAL_MOUSE: type = "pointer"; break;
+ default: type = "unknown"; break;
+ }
+ dmxLog(dmxInfo, " %s (%s)\n", pt->name, type);
+ }
+ dmxLog(dmxFatal, "Must have valid local device driver\n");
+ }
+}
+
+int dmxInputExtensionErrorHandler(Display *dsp, char *name, char *reason)
+{
+ return 0;
+}
+
+static void dmxInputScanForExtensions(DMXInputInfo *dmxInput, int doXI)
+{
+ XExtensionVersion *ext;
+ XDeviceInfo *devices;
+ Display *display;
+ int num;
+ int i, j;
+ DMXLocalInputInfoPtr dmxLocal;
+ int (*handler)(Display *, char *, char *);
+
+ if (!(display = XOpenDisplay(dmxInput->name))) return;
+
+ /* Print out information about the XInput Extension. */
+ handler = XSetExtensionErrorHandler(dmxInputExtensionErrorHandler);
+ ext = XGetExtensionVersion(display, INAME);
+ XSetExtensionErrorHandler(handler);
+
+ if (!ext || ext == (XExtensionVersion *)NoSuchExtension) {
+ dmxLogInput(dmxInput, "%s is not available\n", INAME);
+ } else {
+ dmxLogInput(dmxInput, "Locating devices on %s (%s version %d.%d)\n",
+ dmxInput->name, INAME,
+ ext->major_version, ext->minor_version);
+ devices = XListInputDevices(display, &num);
+
+ XFree(ext);
+ ext = NULL;
+
+ /* Print a list of all devices */
+ for (i = 0; i < num; i++) {
+ const char *use = "Unknown";
+ switch (devices[i].use) {
+ case IsXPointer: use = "XPointer"; break;
+ case IsXKeyboard: use = "XKeyboard"; break;
+ case IsXExtensionDevice: use = "XExtensionDevice"; break;
+ case IsXExtensionPointer: use = "XExtensionPointer"; break;
+ case IsXExtensionKeyboard: use = "XExtensionKeyboard"; break;
+ }
+ dmxLogInput(dmxInput, " %2d %-10.10s %-16.16s\n",
+ devices[i].id,
+ devices[i].name ? devices[i].name : "",
+ use);
+ }
+
+ /* Search for extensions */
+ for (i = 0; i < num; i++) {
+ switch (devices[i].use) {
+ case IsXKeyboard:
+ for (j = 0; j < dmxInput->numDevs; j++) {
+ DMXLocalInputInfoPtr dmxL = dmxInput->devs[j];
+ if (dmxL->type == DMX_LOCAL_KEYBOARD
+ && dmxL->deviceId < 0) {
+ dmxL->deviceId = devices[i].id;
+ dmxL->deviceName = (devices[i].name
+ ? xstrdup(devices[i].name)
+ : NULL);
+ }
+ }
+ break;
+ case IsXPointer:
+ for (j = 0; j < dmxInput->numDevs; j++) {
+ DMXLocalInputInfoPtr dmxL = dmxInput->devs[j];
+ if (dmxL->type == DMX_LOCAL_MOUSE && dmxL->deviceId < 0) {
+ dmxL->deviceId = devices[i].id;
+ dmxL->deviceName = (devices[i].name
+ ? xstrdup(devices[i].name)
+ : NULL);
+ }
+ }
+ break;
+#if 0
+ case IsXExtensionDevice:
+ case IsXExtensionKeyboard:
+ case IsXExtensionPointer:
+ if (doXI) {
+ if (!dmxInput->numDevs) {
+ dmxLog(dmxWarning,
+ "Cannot use remote (%s) XInput devices if"
+ " not also using core devices\n",
+ dmxInput->name);
+ } else {
+ dmxLocal = dmxInputCopyLocal(dmxInput,
+ &DMXCommonOth);
+ dmxLocal->isCore = FALSE;
+ dmxLocal->sendsCore = FALSE;
+ dmxLocal->deviceId = devices[i].id;
+ dmxLocal->deviceName = (devices[i].name
+ ? xstrdup(devices[i].name)
+ : NULL);
+ }
+ }
+ break;
+#endif
+ }
+ }
+ XFreeDeviceList(devices);
+ }
+ XCloseDisplay(display);
+}
+
+/** Re-initialize all the devices described in \a dmxInput. Called from
+ #dmxAdjustCursorBoundaries before the cursor is redisplayed. */
+void dmxInputReInit(DMXInputInfo *dmxInput)
+{
+ int i;
+
+ for (i = 0; i < dmxInput->numDevs; i++) {
+ DMXLocalInputInfoPtr dmxLocal = dmxInput->devs[i];
+ if (dmxLocal->reinit)
+ dmxLocal->reinit(&dmxLocal->pDevice->public);
+ }
+}
+
+/** Re-initialize all the devices described in \a dmxInput. Called from
+ #dmxAdjustCursorBoundaries after the cursor is redisplayed. */
+void dmxInputLateReInit(DMXInputInfo *dmxInput)
+{
+ int i;
+
+ for (i = 0; i < dmxInput->numDevs; i++) {
+ DMXLocalInputInfoPtr dmxLocal = dmxInput->devs[i];
+ if (dmxLocal->latereinit)
+ dmxLocal->latereinit(&dmxLocal->pDevice->public);
+ }
+}
+
+/** Initialize all of the devices described in \a dmxInput. */
+void dmxInputInit(DMXInputInfo *dmxInput)
+{
+ DeviceIntPtr pPointer = NULL, pKeyboard = NULL;
+ dmxArg a;
+ const char *name;
+ int i;
+ int doXI = 1; /* Include by default */
+ int forceConsole = 0;
+ int doWindows = 1; /* On by default */
+ int hasXkb = 0;
+
+ a = dmxArgParse(dmxInput->name);
+
+ for (i = 1; i < dmxArgC(a); i++) {
+ switch (hasXkb) {
+ case 1:
+ dmxInput->keycodes = xstrdup(dmxArgV(a, i));
+ ++hasXkb;
+ break;
+ case 2:
+ dmxInput->symbols = xstrdup(dmxArgV(a, i));
+ ++hasXkb;
+ break;
+ case 3:
+ dmxInput->geometry = xstrdup(dmxArgV(a, i));
+ hasXkb = 0;
+ break;
+ case 0:
+ if (!strcmp(dmxArgV(a, i), "noxi")) doXI = 0;
+ else if (!strcmp(dmxArgV(a, i), "xi")) doXI = 1;
+ else if (!strcmp(dmxArgV(a, i), "console")) forceConsole = 1;
+ else if (!strcmp(dmxArgV(a, i), "noconsole")) forceConsole = 0;
+ else if (!strcmp(dmxArgV(a, i), "windows")) doWindows = 1;
+ else if (!strcmp(dmxArgV(a, i), "nowindows")) doWindows = 0;
+ else if (!strcmp(dmxArgV(a, i), "xkb")) hasXkb = 1;
+ else {
+ dmxLog(dmxFatal,
+ "Unknown input argument: %s\n", dmxArgV(a, i));
+ }
+ }
+ }
+
+ name = dmxArgV(a, 0);
+
+ if (!strcmp(name, "local")) {
+ dmxPopulateLocal(dmxInput, a);
+ } else if (!strcmp(name, "dummy")) {
+ dmxInputCopyLocal(dmxInput, &DMXDummyMou);
+ dmxInputCopyLocal(dmxInput, &DMXDummyKbd);
+ dmxLogInput(dmxInput, "Using dummy input\n");
+ } else {
+ int found;
+
+ for (found = 0, i = 0; i < dmxNumScreens; i++) {
+ if (dmxPropertySameDisplay(&dmxScreens[i], name)) {
+ if (dmxScreens[i].shared)
+ dmxLog(dmxFatal,
+ "Cannot take input from shared backend (%s)\n",
+ name);
+ if (!dmxInput->core) {
+ dmxLog(dmxWarning,
+ "Cannot use core devices on a backend (%s)"
+ " as XInput devices\n", name);
+ } else {
+ char *pt;
+ for (pt = (char *)dmxInput->name; pt && *pt; pt++)
+ if (*pt == ',') *pt = '\0';
+ dmxInputCopyLocal(dmxInput, &DMXBackendMou);
+ dmxInputCopyLocal(dmxInput, &DMXBackendKbd);
+ dmxInput->scrnIdx = i;
+ dmxLogInput(dmxInput,
+ "Using backend input from %s\n", name);
+ }
+ ++found;
+ break;
+ }
+ }
+ if (!found || forceConsole) {
+ char *pt;
+ if (found) dmxInput->console = TRUE;
+ for (pt = (char *)dmxInput->name; pt && *pt; pt++)
+ if (*pt == ',') *pt = '\0';
+ dmxInputCopyLocal(dmxInput, &DMXConsoleMou);
+ dmxInputCopyLocal(dmxInput, &DMXConsoleKbd);
+ if (doWindows) {
+ dmxInput->windows = TRUE;
+ dmxInput->updateWindowInfo = dmxUpdateWindowInformation;
+ }
+ dmxLogInput(dmxInput,
+ "Using console input from %s (%s windows)\n",
+ name, doWindows ? "with" : "without");
+ }
+ }
+
+ dmxArgFree(a);
+
+ /* Locate extensions we may be interested in */
+ dmxInputScanForExtensions(dmxInput, doXI);
+
+ for (i = 0; i < dmxInput->numDevs; i++) {
+ DMXLocalInputInfoPtr dmxLocal = dmxInput->devs[i];
+ dmxLocal->pDevice = dmxAddDevice(dmxLocal);
+ if (dmxLocal->isCore) {
+ if (dmxLocal->type == DMX_LOCAL_MOUSE)
+ pPointer = dmxLocal->pDevice;
+ if (dmxLocal->type == DMX_LOCAL_KEYBOARD)
+ pKeyboard = dmxLocal->pDevice;
+ }
+ }
+
+ dmxInput->processInputEvents = dmxProcessInputEvents;
+ dmxInput->detached = False;
+
+ RegisterBlockAndWakeupHandlers(dmxBlockHandler,
+ dmxWakeupHandler,
+ (void *)dmxInput->inputIdx);
+}
+
+static void dmxInputFreeLocal(DMXLocalInputInfoRec *local)
+{
+ if (!local) return;
+ if (local->isCore && local->type == DMX_LOCAL_MOUSE)
+ dmxLocalCorePointer = NULL;
+ if (local->isCore && local->type == DMX_LOCAL_KEYBOARD)
+ dmxLocalCoreKeyboard = NULL;
+ if (local->destroy_private) local->destroy_private(local->private);
+ if (local->history) free(local->history);
+ if (local->valuators) free(local->valuators);
+ if (local->deviceName) free(local->deviceName);
+ local->private = NULL;
+ local->history = NULL;
+ local->deviceName = NULL;
+ free(local);
+}
+
+/** Free all of the memory associated with \a dmxInput */
+void dmxInputFree(DMXInputInfo *dmxInput)
+{
+ int i;
+
+ if (!dmxInput) return;
+
+ if (dmxInput->keycodes) free(dmxInput->keycodes);
+ if (dmxInput->symbols) free(dmxInput->symbols);
+ if (dmxInput->geometry) free(dmxInput->geometry);
+
+ for (i = 0; i < dmxInput->numDevs; i++) {
+ dmxInputFreeLocal(dmxInput->devs[i]);
+ dmxInput->devs[i] = NULL;
+ }
+ free(dmxInput->devs);
+ dmxInput->devs = NULL;
+ dmxInput->numDevs = 0;
+ if (dmxInput->freename) free(dmxInput->name);
+ dmxInput->name = NULL;
+}
+
+/** Log information about all of the known devices using #dmxLog(). */
+void dmxInputLogDevices(void)
+{
+ int i, j;
+
+ dmxLog(dmxInfo, "%d devices:\n", dmxGetInputCount());
+ dmxLog(dmxInfo, " Id Name Classes\n");
+ for (j = 0; j < dmxNumInputs; j++) {
+ DMXInputInfo *dmxInput = &dmxInputs[j];
+ const char *pt = strchr(dmxInput->name, ',');
+ int len = (pt
+ ? (size_t)(pt-dmxInput->name)
+ : strlen(dmxInput->name));
+
+ for (i = 0; i < dmxInput->numDevs; i++) {
+ DeviceIntPtr pDevice = dmxInput->devs[i]->pDevice;
+ if (pDevice) {
+ dmxLog(dmxInfo, " %2d%c %-20.20s",
+ pDevice->id,
+ dmxInput->detached ? 'D' : ' ',
+ pDevice->name);
+ if (pDevice->key) dmxLogCont(dmxInfo, " key");
+ if (pDevice->valuator) dmxLogCont(dmxInfo, " val");
+ if (pDevice->button) dmxLogCont(dmxInfo, " btn");
+ if (pDevice->focus) dmxLogCont(dmxInfo, " foc");
+ if (pDevice->kbdfeed) dmxLogCont(dmxInfo, " fb/kbd");
+ if (pDevice->ptrfeed) dmxLogCont(dmxInfo, " fb/ptr");
+ if (pDevice->intfeed) dmxLogCont(dmxInfo, " fb/int");
+ if (pDevice->stringfeed) dmxLogCont(dmxInfo, " fb/str");
+ if (pDevice->bell) dmxLogCont(dmxInfo, " fb/bel");
+ if (pDevice->leds) dmxLogCont(dmxInfo, " fb/led");
+ if (!pDevice->key && !pDevice->valuator && !pDevice->button
+ && !pDevice->focus && !pDevice->kbdfeed
+ && !pDevice->ptrfeed && !pDevice->intfeed
+ && !pDevice->stringfeed && !pDevice->bell
+ && !pDevice->leds) dmxLogCont(dmxInfo, " (none)");
+
+ dmxLogCont(dmxInfo, "\t[i%d/%*.*s",
+ dmxInput->inputIdx, len, len, dmxInput->name);
+ if (dmxInput->devs[i]->deviceId >= 0)
+ dmxLogCont(dmxInfo, "/id%d", dmxInput->devs[i]->deviceId);
+ if (dmxInput->devs[i]->deviceName)
+ dmxLogCont(dmxInfo, "=%s", dmxInput->devs[i]->deviceName);
+ dmxLogCont(dmxInfo, "] %s\n",
+ dmxInput->devs[i]->isCore
+ ? "core"
+ : (dmxInput->devs[i]->sendsCore
+ ? "extension (sends core events)"
+ : "extension"));
+ }
+ }
+ }
+}
+
+/** Detach an input */
+int dmxInputDetach(DMXInputInfo *dmxInput)
+{
+ int i;
+
+ if (dmxInput->detached) return BadAccess;
+
+ for (i = 0; i < dmxInput->numDevs; i++) {
+ DMXLocalInputInfoPtr dmxLocal = dmxInput->devs[i];
+ dmxLogInput(dmxInput, "Detaching device id %d: %s%s\n",
+ dmxLocal->pDevice->id,
+ dmxLocal->pDevice->name,
+ dmxLocal->isCore
+ ? " [core]"
+ : (dmxLocal->sendsCore
+ ? " [sends core events]"
+ : ""));
+ DisableDevice(dmxLocal->pDevice, TRUE);
+ }
+ dmxInput->detached = True;
+ dmxInputLogDevices();
+ return 0;
+}
+
+/** Search for input associated with \a dmxScreen, and detach. */
+void dmxInputDetachAll(DMXScreenInfo *dmxScreen)
+{
+ int i;
+
+ for (i = 0; i < dmxNumInputs; i++) {
+ DMXInputInfo *dmxInput = &dmxInputs[i];
+ if (dmxInput->scrnIdx == dmxScreen->index) dmxInputDetach(dmxInput);
+ }
+}
+
+/** Search for input associated with \a deviceId, and detach. */
+int dmxInputDetachId(int id)
+{
+ DMXInputInfo *dmxInput = dmxInputLocateId(id);
+
+ if (!dmxInput) return BadValue;
+
+ return dmxInputDetach(dmxInput);
+}
+
+DMXInputInfo *dmxInputLocateId(int id)
+{
+ int i, j;
+
+ for (i = 0; i < dmxNumInputs; i++) {
+ DMXInputInfo *dmxInput = &dmxInputs[i];
+ for (j = 0; j < dmxInput->numDevs; j++) {
+ DMXLocalInputInfoPtr dmxLocal = dmxInput->devs[j];
+ if (dmxLocal->pDevice->id == id) return dmxInput;
+ }
+ }
+ return NULL;
+}
+
+static int dmxInputAttachNew(DMXInputInfo *dmxInput, int *id)
+{
+ dmxInputInit(dmxInput);
+ InitAndStartDevices();
+ if (id && dmxInput->devs) *id = dmxInput->devs[0]->pDevice->id;
+ dmxInputLogDevices();
+ return 0;
+}
+
+static int dmxInputAttachOld(DMXInputInfo *dmxInput, int *id)
+{
+ int i;
+
+ dmxInput->detached = False;
+ for (i = 0; i < dmxInput->numDevs; i++) {
+ DMXLocalInputInfoPtr dmxLocal = dmxInput->devs[i];
+ if (id) *id = dmxLocal->pDevice->id;
+ dmxLogInput(dmxInput,
+ "Attaching device id %d: %s%s\n",
+ dmxLocal->pDevice->id,
+ dmxLocal->pDevice->name,
+ dmxLocal->isCore
+ ? " [core]"
+ : (dmxLocal->sendsCore
+ ? " [sends core events]"
+ : ""));
+ EnableDevice(dmxLocal->pDevice, TRUE);
+ }
+ dmxInputLogDevices();
+ return 0;
+}
+
+int dmxInputAttachConsole(const char *name, int isCore, int *id)
+{
+ DMXInputInfo *dmxInput;
+ int i;
+
+ for (i = 0; i < dmxNumInputs; i++) {
+ dmxInput = &dmxInputs[i];
+ if (dmxInput->scrnIdx == -1
+ && dmxInput->detached
+ && !strcmp(dmxInput->name, name)) {
+ /* Found match */
+ dmxLogInput(dmxInput, "Reattaching detached console input\n");
+ return dmxInputAttachOld(dmxInput, id);
+ }
+ }
+
+ /* No match found */
+ dmxInput = dmxConfigAddInput(xstrdup(name), isCore);
+ dmxInput->freename = TRUE;
+ dmxLogInput(dmxInput, "Attaching new console input\n");
+ return dmxInputAttachNew(dmxInput, id);
+}
+
+int dmxInputAttachBackend(int physicalScreen, int isCore, int *id)
+{
+ DMXInputInfo *dmxInput;
+ DMXScreenInfo *dmxScreen;
+ int i;
+
+ if (physicalScreen < 0 || physicalScreen >= dmxNumScreens) return BadValue;
+ for (i = 0; i < dmxNumInputs; i++) {
+ dmxInput = &dmxInputs[i];
+ if (dmxInput->scrnIdx != -1 && dmxInput->scrnIdx == physicalScreen) {
+ /* Found match */
+ if (!dmxInput->detached) return BadAccess; /* Already attached */
+ dmxScreen = &dmxScreens[physicalScreen];
+ if (!dmxScreen->beDisplay) return BadAccess; /* Screen detached */
+ dmxLogInput(dmxInput, "Reattaching detached backend input\n");
+ return dmxInputAttachOld(dmxInput, id);
+ }
+ }
+ /* No match found */
+ dmxScreen = &dmxScreens[physicalScreen];
+ if (!dmxScreen->beDisplay) return BadAccess; /* Screen detached */
+ dmxInput = dmxConfigAddInput(dmxScreen->name, isCore);
+ dmxLogInput(dmxInput, "Attaching new backend input\n");
+ return dmxInputAttachNew(dmxInput, id);
+}
diff --git a/xorg-server/hw/dmx/input/dmxmotion.c b/xorg-server/hw/dmx/input/dmxmotion.c
index 73580a215..d1c79f126 100644
--- a/xorg-server/hw/dmx/input/dmxmotion.c
+++ b/xorg-server/hw/dmx/input/dmxmotion.c
@@ -1,142 +1,142 @@
-/*
- * Copyright 2002-2003 Red Hat Inc., Durham, North Carolina.
- *
- * 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 on 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 (including the
- * next paragraph) 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
- * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
- * 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.
- */
-
-/*
- * Authors:
- * Rickard E. (Rik) Faith <faith@redhat.com>
- *
- */
-
-/** \file
- * This file provides functions similar to miPointerGetMotionEvents and
- * miPointerPutMotionEvents, with the exception that devices with more
- * than two axes are fully supported. These routines may be used only
- * for motion buffers for extension devices, and are \a not compatible
- * replacements for the mi routines. */
-
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
-
-#include "inputstr.h"
-#include "dmxinputinit.h"
-#include "dmxcommon.h"
-#include "dmxmotion.h"
-
-#define OFFSET(offset,element) ((offset) * (numAxes + 1) + (element))
-
-/** Return size of motion buffer. \see DMX_MOTION_SIZE */
-int dmxPointerGetMotionBufferSize(void)
-{
- return DMX_MOTION_SIZE;
-}
-
-/** This routine performs the same function as \a miPointerGetMotionEvents:
- * the events in the motion history that are between the start and stop
- * times (in mS) are placed in the coords vector, and the count of the
- * number of items so placed is returned. This routine is called from
- * dix/devices.c so that coords can hold valuator->numMotionEvents
- * events. This routine is called from \a Xi/gtmotion.c with coords large
- * enough to hold the same number of events in a variable-length
- * extended \a xTimecoord structure. This provides sufficient data for the
- * \a XGetDeviceMotionEvents library call, and would be identical to
- * \a miPointerGetMotionEvents for devices with only 2 axes (i.e., core
- * pointers) if \a xTimecoord used 32bit integers.
- *
- * Because DMX uses the mi* routines for all core devices, this routine
- * only has to support extension devices using the polymorphic coords.
- * Because compatibility with miPointerGetMotionEvents is not possible,
- * it is not provided. */
-int dmxPointerGetMotionEvents(DeviceIntPtr pDevice,
- xTimecoord *coords,
- unsigned long start,
- unsigned long stop,
- ScreenPtr pScreen)
-{
- GETDMXLOCALFROMPDEVICE;
- int numAxes = pDevice->valuator->numAxes;
- unsigned long *c = (unsigned long *)coords;
- int count = 0;
- int i, j;
-
- if (!dmxLocal->history) return 0;
- for (i = dmxLocal->head; i != dmxLocal->tail;) {
- if (dmxLocal->history[OFFSET(i,0)] >= stop) break;
- if (dmxLocal->history[OFFSET(i,0)] >= start) {
- for (j = 0; j < numAxes + 1; j++)
- c[OFFSET(count,j)] = dmxLocal->history[OFFSET(i,j)];
- ++count;
- }
- if (++i >= DMX_MOTION_SIZE) i = 0;
- }
- return count;
-}
-
-/** This routine adds an event to the motion history. A similar
- * function is performed by miPointerMove for the mi versions of these
- * routines. */
-void dmxPointerPutMotionEvent(DeviceIntPtr pDevice,
- int firstAxis, int axesCount, int *v,
- unsigned long time)
-{
- GETDMXLOCALFROMPDEVICE;
- int numAxes = pDevice->valuator->numAxes;
- int i;
-
- if (!dmxLocal->history) {
- dmxLocal->history = xalloc(sizeof(*dmxLocal->history)
- * (numAxes + 1)
- * DMX_MOTION_SIZE);
- dmxLocal->head = 0;
- dmxLocal->tail = 0;
- dmxLocal->valuators = calloc(sizeof(*dmxLocal->valuators), numAxes);
- } else {
- if (++dmxLocal->tail >= DMX_MOTION_SIZE) dmxLocal->tail = 0;
- if (dmxLocal->head == dmxLocal->tail)
- if (++dmxLocal->head >= DMX_MOTION_SIZE) dmxLocal->head = 0;
- }
-
- dmxLocal->history[OFFSET(dmxLocal->tail,0)] = time;
-
- /* Initialize the data from the known
- * values (if Absolute) or to zero (if
- * Relative) */
- if (pDevice->valuator->mode == Absolute) {
- for (i = 0; i < numAxes; i++)
- dmxLocal->history[OFFSET(dmxLocal->tail,i+1)]
- = dmxLocal->valuators[i];
- } else {
- for (i = 0; i < numAxes; i++)
- dmxLocal->history[OFFSET(dmxLocal->tail,i+1)] = 0;
- }
-
- for (i = firstAxis; i < axesCount; i++) {
- dmxLocal->history[OFFSET(dmxLocal->tail,i+i)]
- = (unsigned long)v[i-firstAxis];
- dmxLocal->valuators[i] = v[i-firstAxis];
- }
-}
+/*
+ * Copyright 2002-2003 Red Hat Inc., Durham, North Carolina.
+ *
+ * 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 on 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 (including the
+ * next paragraph) 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
+ * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
+ * 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.
+ */
+
+/*
+ * Authors:
+ * Rickard E. (Rik) Faith <faith@redhat.com>
+ *
+ */
+
+/** \file
+ * This file provides functions similar to miPointerGetMotionEvents and
+ * miPointerPutMotionEvents, with the exception that devices with more
+ * than two axes are fully supported. These routines may be used only
+ * for motion buffers for extension devices, and are \a not compatible
+ * replacements for the mi routines. */
+
+#ifdef HAVE_DMX_CONFIG_H
+#include <dmx-config.h>
+#endif
+
+#include "inputstr.h"
+#include "dmxinputinit.h"
+#include "dmxcommon.h"
+#include "dmxmotion.h"
+
+#define OFFSET(offset,element) ((offset) * (numAxes + 1) + (element))
+
+/** Return size of motion buffer. \see DMX_MOTION_SIZE */
+int dmxPointerGetMotionBufferSize(void)
+{
+ return DMX_MOTION_SIZE;
+}
+
+/** This routine performs the same function as \a miPointerGetMotionEvents:
+ * the events in the motion history that are between the start and stop
+ * times (in mS) are placed in the coords vector, and the count of the
+ * number of items so placed is returned. This routine is called from
+ * dix/devices.c so that coords can hold valuator->numMotionEvents
+ * events. This routine is called from \a Xi/gtmotion.c with coords large
+ * enough to hold the same number of events in a variable-length
+ * extended \a xTimecoord structure. This provides sufficient data for the
+ * \a XGetDeviceMotionEvents library call, and would be identical to
+ * \a miPointerGetMotionEvents for devices with only 2 axes (i.e., core
+ * pointers) if \a xTimecoord used 32bit integers.
+ *
+ * Because DMX uses the mi* routines for all core devices, this routine
+ * only has to support extension devices using the polymorphic coords.
+ * Because compatibility with miPointerGetMotionEvents is not possible,
+ * it is not provided. */
+int dmxPointerGetMotionEvents(DeviceIntPtr pDevice,
+ xTimecoord *coords,
+ unsigned long start,
+ unsigned long stop,
+ ScreenPtr pScreen)
+{
+ GETDMXLOCALFROMPDEVICE;
+ int numAxes = pDevice->valuator->numAxes;
+ unsigned long *c = (unsigned long *)coords;
+ int count = 0;
+ int i, j;
+
+ if (!dmxLocal->history) return 0;
+ for (i = dmxLocal->head; i != dmxLocal->tail;) {
+ if (dmxLocal->history[OFFSET(i,0)] >= stop) break;
+ if (dmxLocal->history[OFFSET(i,0)] >= start) {
+ for (j = 0; j < numAxes + 1; j++)
+ c[OFFSET(count,j)] = dmxLocal->history[OFFSET(i,j)];
+ ++count;
+ }
+ if (++i >= DMX_MOTION_SIZE) i = 0;
+ }
+ return count;
+}
+
+/** This routine adds an event to the motion history. A similar
+ * function is performed by miPointerMove for the mi versions of these
+ * routines. */
+void dmxPointerPutMotionEvent(DeviceIntPtr pDevice,
+ int firstAxis, int axesCount, int *v,
+ unsigned long time)
+{
+ GETDMXLOCALFROMPDEVICE;
+ int numAxes = pDevice->valuator->numAxes;
+ int i;
+
+ if (!dmxLocal->history) {
+ dmxLocal->history = malloc(sizeof(*dmxLocal->history)
+ * (numAxes + 1)
+ * DMX_MOTION_SIZE);
+ dmxLocal->head = 0;
+ dmxLocal->tail = 0;
+ dmxLocal->valuators = calloc(sizeof(*dmxLocal->valuators), numAxes);
+ } else {
+ if (++dmxLocal->tail >= DMX_MOTION_SIZE) dmxLocal->tail = 0;
+ if (dmxLocal->head == dmxLocal->tail)
+ if (++dmxLocal->head >= DMX_MOTION_SIZE) dmxLocal->head = 0;
+ }
+
+ dmxLocal->history[OFFSET(dmxLocal->tail,0)] = time;
+
+ /* Initialize the data from the known
+ * values (if Absolute) or to zero (if
+ * Relative) */
+ if (pDevice->valuator->mode == Absolute) {
+ for (i = 0; i < numAxes; i++)
+ dmxLocal->history[OFFSET(dmxLocal->tail,i+1)]
+ = dmxLocal->valuators[i];
+ } else {
+ for (i = 0; i < numAxes; i++)
+ dmxLocal->history[OFFSET(dmxLocal->tail,i+1)] = 0;
+ }
+
+ for (i = firstAxis; i < axesCount; i++) {
+ dmxLocal->history[OFFSET(dmxLocal->tail,i+i)]
+ = (unsigned long)v[i-firstAxis];
+ dmxLocal->valuators[i] = v[i-firstAxis];
+ }
+}
diff --git a/xorg-server/hw/dmx/input/lnx-keyboard.c b/xorg-server/hw/dmx/input/lnx-keyboard.c
index 939a32f07..11f21e25c 100644
--- a/xorg-server/hw/dmx/input/lnx-keyboard.c
+++ b/xorg-server/hw/dmx/input/lnx-keyboard.c
@@ -1,990 +1,990 @@
-/* Portions of this file were derived from the following files:
- *
- **********************************************************************
- *
- * xfree86/common/{xf86Io.c,xf86Kbd.c,xf86Events.c}
- *
- * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Thomas Roell not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Thomas Roell makes no representations
- * about the suitability of this software for any purpose. It is provided
- * "as is" without express or implied warranty.
- *
- * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- **********************************************************************
- *
- * xfree86/common/xf86KbdLnx.c
- *
- * Linux version of keymapping setup. The kernel (since 0.99.14) has support
- * for fully remapping the keyboard, but there are some differences between
- * the Linux map and the SVR4 map (esp. in the extended keycodes). We also
- * remove the restriction on what keycodes can be remapped.
- * Orest Zborowski.
- *
- * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Thomas Roell not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Thomas Roell makes no representations
- * about the suitability of this software for any purpose. It is provided
- * "as is" without express or implied warranty.
- *
- * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- **********************************************************************
- *
- * xfree86/os-support/linux/lnx_io.c
- *
- * Copyright 1992 by Orest Zborowski <obz@Kodak.com>
- * Copyright 1993 by David Dawes <dawes@xfree86.org>
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the names of Orest Zborowski and David Dawes
- * not be used in advertising or publicity pertaining to distribution of
- * the software without specific, written prior permission. Orest Zborowski
- * and David Dawes 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 DAWES DISCLAIMS ALL WARRANTIES WITH REGARD
- * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL OREST ZBOROWSKI OR DAVID DAWES BE LIABLE
- * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-
-/*
- * Copyright 2001-2003 Red Hat Inc., Durham, North Carolina.
- *
- * 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 on 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 (including the
- * next paragraph) 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
- * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
- * 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.
- */
-
-/*
- * Authors:
- * Rickard E. (Rik) Faith <faith@redhat.com>
- *
- */
-
-/** \file
- *
- * This code implements a low-level device driver for the Linux
- * keyboard. The code is derived from code by Thomas Roell, Orest
- * Zborowski, and David Dawes (see the source code for complete
- * references). */
-
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
-
-/*****************************************************************************/
-/* Define some macros to make it easier to move this file to another
- * part of the Xserver tree. All calls to the dmx* layer are #defined
- * here for the .c file. The .h file will also have to be edited. */
-#include "dmxinputinit.h"
-#include "lnx-keyboard.h"
-
-#define GETPRIV myPrivate *priv \
- = ((DMXLocalInputInfoPtr)(pDev->devicePrivate))->private
-
-#define LOG0(f) dmxLog(dmxDebug,f)
-#define LOG1(f,a) dmxLog(dmxDebug,f,a)
-#define LOG2(f,a,b) dmxLog(dmxDebug,f,a,b)
-#define LOG3(f,a,b,c) dmxLog(dmxDebug,f,a,b,c)
-#define FATAL0(f) dmxLog(dmxFatal,f)
-#define FATAL1(f,a) dmxLog(dmxFatal,f,a)
-#define FATAL2(f,a,b) dmxLog(dmxFatal,f,a,b)
-#define MOTIONPROC dmxMotionProcPtr
-#define ENQUEUEPROC dmxEnqueueProcPtr
-#define CHECKPROC dmxCheckSpecialProcPtr
-#define SWITCHRETPROC dmxVTSwitchReturnProcPtr
-#define BLOCK DMXBlockType
-#define MESSAGE "\033c\n\n\nDMX taking input from this console..."
-#define FINALMESSAGE "\033cDMX terminated."
-
-/* End of interface definitions. */
-/*****************************************************************************/
-
-#include "inputstr.h"
-#include <X11/Xos.h>
-#include <sys/ioctl.h>
-#include <errno.h>
-#include <signal.h>
-#include <sys/vt.h>
-#include <sys/kd.h>
-#include <termios.h>
-#include "atKeynames.h"
-#if 00
-#include "xf86Keymap.h"
-#endif
-#include <linux/keyboard.h>
-#include <xkbsrv.h>
-
-#define NUM_AT2LNX (sizeof(at2lnx) / sizeof(at2lnx[0]))
-#define NUM_STATE_ENTRIES (256/32)
-
-
-/* Private area for Linux-style keyboards. */
-typedef struct _myPrivate {
- int fd;
- int vtno;
- int vtcurrent;
- int kbdtrans;
- struct termios kbdtty;
- int kbdType;
- CARD32 kbdState[NUM_STATE_ENTRIES];
- DeviceIntPtr pKeyboard;
- unsigned char prefix;
-
- int switched;
- SWITCHRETPROC switch_return;
- void *switch_return_data;
-
- /* For bell */
- int pitch;
- unsigned long duration;
-} myPrivate;
-
-static myPrivate *PRIV = NULL;
-
-#undef SYSCALL
-#define SYSCALL(call) while(((call) == -1) && (errno == EINTR))
-
-static int kbdLinuxKeyDown(myPrivate *priv, int keyCode)
-{
- CARD8 byte = keyCode >> 5;
- CARD32 bit = 1 << (keyCode & 0x1f);
-
- if (byte > NUM_STATE_ENTRIES) return 0;
- return priv->kbdState[byte] & bit;
-}
-
-static void kbdLinuxKeyState(myPrivate *priv, int type, int keyCode)
-{
- CARD8 byte = keyCode >> 5;
- CARD32 bit = 1 << (keyCode & 0x1f);
-
- if (byte > NUM_STATE_ENTRIES) return;
- if (type == KeyPress) priv->kbdState[byte] |= bit;
- else priv->kbdState[byte] &= ~bit;
-}
-
-static KeySym linux_to_x[256] = {
- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- XK_BackSpace, XK_Tab, XK_Linefeed, NoSymbol,
- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- NoSymbol, NoSymbol, NoSymbol, XK_Escape,
- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- XK_space, XK_exclam, XK_quotedbl, XK_numbersign,
- XK_dollar, XK_percent, XK_ampersand, XK_apostrophe,
- XK_parenleft, XK_parenright, XK_asterisk, XK_plus,
- XK_comma, XK_minus, XK_period, XK_slash,
- XK_0, XK_1, XK_2, XK_3,
- XK_4, XK_5, XK_6, XK_7,
- XK_8, XK_9, XK_colon, XK_semicolon,
- XK_less, XK_equal, XK_greater, XK_question,
- XK_at, XK_A, XK_B, XK_C,
- XK_D, XK_E, XK_F, XK_G,
- XK_H, XK_I, XK_J, XK_K,
- XK_L, XK_M, XK_N, XK_O,
- XK_P, XK_Q, XK_R, XK_S,
- XK_T, XK_U, XK_V, XK_W,
- XK_X, XK_Y, XK_Z, XK_bracketleft,
- XK_backslash, XK_bracketright,XK_asciicircum, XK_underscore,
- XK_grave, XK_a, XK_b, XK_c,
- XK_d, XK_e, XK_f, XK_g,
- XK_h, XK_i, XK_j, XK_k,
- XK_l, XK_m, XK_n, XK_o,
- XK_p, XK_q, XK_r, XK_s,
- XK_t, XK_u, XK_v, XK_w,
- XK_x, XK_y, XK_z, XK_braceleft,
- XK_bar, XK_braceright, XK_asciitilde, XK_BackSpace,
- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- XK_nobreakspace,XK_exclamdown, XK_cent, XK_sterling,
- XK_currency, XK_yen, XK_brokenbar, XK_section,
- XK_diaeresis, XK_copyright, XK_ordfeminine, XK_guillemotleft,
- XK_notsign, XK_hyphen, XK_registered, XK_macron,
- XK_degree, XK_plusminus, XK_twosuperior, XK_threesuperior,
- XK_acute, XK_mu, XK_paragraph, XK_periodcentered,
- XK_cedilla, XK_onesuperior, XK_masculine, XK_guillemotright,
- XK_onequarter, XK_onehalf, XK_threequarters,XK_questiondown,
- XK_Agrave, XK_Aacute, XK_Acircumflex, XK_Atilde,
- XK_Adiaeresis, XK_Aring, XK_AE, XK_Ccedilla,
- XK_Egrave, XK_Eacute, XK_Ecircumflex, XK_Ediaeresis,
- XK_Igrave, XK_Iacute, XK_Icircumflex, XK_Idiaeresis,
- XK_ETH, XK_Ntilde, XK_Ograve, XK_Oacute,
- XK_Ocircumflex, XK_Otilde, XK_Odiaeresis, XK_multiply,
- XK_Ooblique, XK_Ugrave, XK_Uacute, XK_Ucircumflex,
- XK_Udiaeresis, XK_Yacute, XK_THORN, XK_ssharp,
- XK_agrave, XK_aacute, XK_acircumflex, XK_atilde,
- XK_adiaeresis, XK_aring, XK_ae, XK_ccedilla,
- XK_egrave, XK_eacute, XK_ecircumflex, XK_ediaeresis,
- XK_igrave, XK_iacute, XK_icircumflex, XK_idiaeresis,
- XK_eth, XK_ntilde, XK_ograve, XK_oacute,
- XK_ocircumflex, XK_otilde, XK_odiaeresis, XK_division,
- XK_oslash, XK_ugrave, XK_uacute, XK_ucircumflex,
- XK_udiaeresis, XK_yacute, XK_thorn, XK_ydiaeresis
-};
-
-/*
- * Maps the AT keycodes to Linux keycodes
- */
-static unsigned char at2lnx[NUM_KEYCODES] =
-{
- 0x01, /* KEY_Escape */ 0x02, /* KEY_1 */
- 0x03, /* KEY_2 */ 0x04, /* KEY_3 */
- 0x05, /* KEY_4 */ 0x06, /* KEY_5 */
- 0x07, /* KEY_6 */ 0x08, /* KEY_7 */
- 0x09, /* KEY_8 */ 0x0a, /* KEY_9 */
- 0x0b, /* KEY_0 */ 0x0c, /* KEY_Minus */
- 0x0d, /* KEY_Equal */ 0x0e, /* KEY_BackSpace */
- 0x0f, /* KEY_Tab */ 0x10, /* KEY_Q */
- 0x11, /* KEY_W */ 0x12, /* KEY_E */
- 0x13, /* KEY_R */ 0x14, /* KEY_T */
- 0x15, /* KEY_Y */ 0x16, /* KEY_U */
- 0x17, /* KEY_I */ 0x18, /* KEY_O */
- 0x19, /* KEY_P */ 0x1a, /* KEY_LBrace */
- 0x1b, /* KEY_RBrace */ 0x1c, /* KEY_Enter */
- 0x1d, /* KEY_LCtrl */ 0x1e, /* KEY_A */
- 0x1f, /* KEY_S */ 0x20, /* KEY_D */
- 0x21, /* KEY_F */ 0x22, /* KEY_G */
- 0x23, /* KEY_H */ 0x24, /* KEY_J */
- 0x25, /* KEY_K */ 0x26, /* KEY_L */
- 0x27, /* KEY_SemiColon */ 0x28, /* KEY_Quote */
- 0x29, /* KEY_Tilde */ 0x2a, /* KEY_ShiftL */
- 0x2b, /* KEY_BSlash */ 0x2c, /* KEY_Z */
- 0x2d, /* KEY_X */ 0x2e, /* KEY_C */
- 0x2f, /* KEY_V */ 0x30, /* KEY_B */
- 0x31, /* KEY_N */ 0x32, /* KEY_M */
- 0x33, /* KEY_Comma */ 0x34, /* KEY_Period */
- 0x35, /* KEY_Slash */ 0x36, /* KEY_ShiftR */
- 0x37, /* KEY_KP_Multiply */ 0x38, /* KEY_Alt */
- 0x39, /* KEY_Space */ 0x3a, /* KEY_CapsLock */
- 0x3b, /* KEY_F1 */ 0x3c, /* KEY_F2 */
- 0x3d, /* KEY_F3 */ 0x3e, /* KEY_F4 */
- 0x3f, /* KEY_F5 */ 0x40, /* KEY_F6 */
- 0x41, /* KEY_F7 */ 0x42, /* KEY_F8 */
- 0x43, /* KEY_F9 */ 0x44, /* KEY_F10 */
- 0x45, /* KEY_NumLock */ 0x46, /* KEY_ScrollLock */
- 0x47, /* KEY_KP_7 */ 0x48, /* KEY_KP_8 */
- 0x49, /* KEY_KP_9 */ 0x4a, /* KEY_KP_Minus */
- 0x4b, /* KEY_KP_4 */ 0x4c, /* KEY_KP_5 */
- 0x4d, /* KEY_KP_6 */ 0x4e, /* KEY_KP_Plus */
- 0x4f, /* KEY_KP_1 */ 0x50, /* KEY_KP_2 */
- 0x51, /* KEY_KP_3 */ 0x52, /* KEY_KP_0 */
- 0x53, /* KEY_KP_Decimal */ 0x54, /* KEY_SysReqest */
- 0x00, /* 0x55 */ 0x56, /* KEY_Less */
- 0x57, /* KEY_F11 */ 0x58, /* KEY_F12 */
- 0x66, /* KEY_Home */ 0x67, /* KEY_Up */
- 0x68, /* KEY_PgUp */ 0x69, /* KEY_Left */
- 0x5d, /* KEY_Begin */ 0x6a, /* KEY_Right */
- 0x6b, /* KEY_End */ 0x6c, /* KEY_Down */
- 0x6d, /* KEY_PgDown */ 0x6e, /* KEY_Insert */
- 0x6f, /* KEY_Delete */ 0x60, /* KEY_KP_Enter */
- 0x61, /* KEY_RCtrl */ 0x77, /* KEY_Pause */
- 0x63, /* KEY_Print */ 0x62, /* KEY_KP_Divide */
- 0x64, /* KEY_AltLang */ 0x65, /* KEY_Break */
- 0x00, /* KEY_LMeta */ 0x00, /* KEY_RMeta */
- 0x7A, /* KEY_Menu/FOCUS_PF11*/0x00, /* 0x6e */
- 0x7B, /* FOCUS_PF12 */ 0x00, /* 0x70 */
- 0x00, /* 0x71 */ 0x00, /* 0x72 */
- 0x59, /* FOCUS_PF2 */ 0x78, /* FOCUS_PF9 */
- 0x00, /* 0x75 */ 0x00, /* 0x76 */
- 0x5A, /* FOCUS_PF3 */ 0x5B, /* FOCUS_PF4 */
- 0x5C, /* FOCUS_PF5 */ 0x5D, /* FOCUS_PF6 */
- 0x5E, /* FOCUS_PF7 */ 0x5F, /* FOCUS_PF8 */
- 0x7C, /* JAP_86 */ 0x79, /* FOCUS_PF10 */
- 0x00, /* 0x7f */
-};
-
-/** Create a private structure for use within this file. */
-pointer kbdLinuxCreatePrivate(DeviceIntPtr pKeyboard)
-{
- myPrivate *priv = calloc(1, sizeof(*priv));
- priv->fd = -1;
- priv->pKeyboard = pKeyboard;
- return priv;
-}
-
-/** Destroy a private structure. */
-void kbdLinuxDestroyPrivate(pointer priv)
-{
- if (priv) free(priv);
-}
-
-/** Ring the bell.
- *
- * Note: we completely ignore the \a volume, since Linux's ioctl()
- * interface does not provide a way to control it. If it did, the XBell
- * manpage tells how the actual volume is a function of the percent and
- * the (base) volume.
- *
- * Note that most of the other PC-based bell drivers compute the
- * duration for KDMKTONE as a function of the volume and the duration.
- * For some drivers, the duration is only measured in mS if the volume
- * is 50, and is scaled by the volume for other values. This seems
- * confusing and possibly incorrect (the xset man page says that the
- * bell will be "as closely as it can to the user's specifications" --
- * if we ignore the volume and set the duration correctly, then we'll
- * get one parameter "wrong" -- but if we use the volume to scale the
- * duration, then we'll get both parameters "wrong"). */
-void kbdLinuxBell(DevicePtr pDev, int percent,
- int volume, int pitch, int duration)
-{
- GETPRIV;
-
- if (duration && pitch) {
- ioctl(priv->fd,
- KDMKTONE,
- ((1193190 / pitch) & 0xffff) /* Low bits specify cycle time */
- | (duration << 16)); /* High bits are duration in msec */
- }
-}
-
-/** Set the LEDs. */
-void kbdLinuxCtrl(DevicePtr pDev, KeybdCtrl *ctrl)
-{
- GETPRIV;
-
- ioctl(priv->fd, KDSETLED, ctrl->leds & 0x07);
-}
-
-static int kbdLinuxGetFreeVTNumber(void)
-{
- int fd = -1;
- int vtno;
- int i;
- const char *tty0[] = { "/dev/tty0", "/dev/vc/0", NULL };
-
- for (i = 0; tty0[i]; i++)
- if ((fd = open(tty0[i], O_WRONLY, 0)) >= 0) break;
- if (fd < 0)
- FATAL1("kbdLinuxGetFreeVTNumber: Cannot open tty0 (%s)\n",
- strerror(errno));
- if (ioctl(fd, VT_OPENQRY, &vtno) < 0 || vtno < 0)
- FATAL0("kbdLinuxGetFreeVTNumber: Cannot find a free VT\n");
- return vtno;
-}
-
-static int kbdLinuxOpenVT(int vtno)
-{
- int fd = -1;
- int i;
- const char *vcs[] = { "/dev/vc/%d", "/dev/tty%d", NULL };
- char name[64]; /* RATS: Only used in XmuSnprintf */
-
- for (i = 0; vcs[i]; i++) {
- XmuSnprintf(name, sizeof(name), vcs[i], vtno);
- if ((fd = open(name, O_RDWR | O_NONBLOCK, 0)) >= 0) break;
- }
- if (fd < 0)
- FATAL2("kbdLinuxOpenVT: Cannot open VT %d (%s)\n",
- vtno, strerror(errno));
- return fd;
-}
-
-static int kbdLinuxGetCurrentVTNumber(int fd)
-{
- struct vt_stat vts;
-
- if (!ioctl(fd, VT_GETSTATE, &vts)) return vts.v_active;
- return -1;
-}
-
-static int kbdLinuxActivate(int fd, int vtno, int setSig);
-
-/** Currently unused hook called prior to an VT switch. */
-void kbdLinuxVTPreSwitch(pointer p)
-{
-}
-
-/** Currently unused hook called after returning from a VT switch. */
-void kbdLinuxVTPostSwitch(pointer p)
-{
-}
-
-/** Tell the operating system to switch to \a vt. The \a switch_return
- * function is called with the \a switch_return_data when the VT is
- * switched back to the pre-switch VT (i.e., the user returns to the DMX
- * session). */
-int kbdLinuxVTSwitch(pointer p, int vt,
- void (*switch_return)(pointer),
- pointer switch_return_data)
-{
- myPrivate *priv = p;
-
- if (priv->switched) FATAL0("kbdLinuxVTSwitch: already switched...\n");
- if (priv->vtno == vt) return 0;
-
- PRIV = priv;
- priv->switched = 0; /* Will switch to 1 in handler */
- priv->switch_return = switch_return;
- priv->switch_return_data = switch_return_data;
- kbdLinuxActivate(priv->fd, vt, 0);
- return 1;
-}
-
-/* RATS: This function is only ever used to handle SIGUSR1. */
-static void kbdLinuxVTSignalHandler(int sig)
-{
- myPrivate *priv = PRIV;
-
- signal(sig, kbdLinuxVTSignalHandler);
- if (priv) {
- ioctl(priv->fd, VT_RELDISP, VT_ACKACQ);
- priv->switched = !priv->switched;
- LOG2("kbdLinuxVTSignalHandler: got signal %d, switched = %d\n",
- sig, priv->switched);
- if (!priv->switched && priv->switch_return)
- priv->switch_return(priv->switch_return_data);
- }
-}
-
-static int kbdLinuxActivate(int fd, int vtno, int setSig)
-{
- int result;
- struct vt_mode VT;
-
- SYSCALL(result = ioctl(fd, VT_ACTIVATE, vtno));
- if (result) FATAL0("kbdLinuxActivate: VT_ACTIVATE failed\n");
- SYSCALL(result = ioctl(fd, VT_WAITACTIVE, vtno));
- if (result) FATAL0("kbdLinuxActivate: VT_WAITACTIVE failed\n");
- if (setSig) {
- SYSCALL(result = ioctl(fd, VT_GETMODE, &VT));
- if (result < 0) FATAL0("kbdLinuxActivate: VT_GETMODE failed\n");
- VT.mode = VT_PROCESS;
- VT.relsig = SIGUSR1;
- VT.acqsig = SIGUSR1;
- if (ioctl(fd, VT_SETMODE, &VT))
- FATAL0("kbdLinuxActivate: VT_SETMODE VT_PROCESS failed\n");
- signal(SIGUSR1, kbdLinuxVTSignalHandler);
- }
- return Success;
-}
-
-static void kbdLinuxOpenConsole(DevicePtr pDev)
-{
- GETPRIV;
- const char *msg = MESSAGE;
-
- if (priv->fd >= 0) return;
- priv->vtno = kbdLinuxGetFreeVTNumber();
- priv->fd = kbdLinuxOpenVT(priv->vtno);
- priv->vtcurrent = kbdLinuxGetCurrentVTNumber(priv->fd);
- LOG2("kbdLinuxOpenConsole: current VT %d; using free VT %d\n",
- priv->vtcurrent, priv->vtno);
- kbdLinuxActivate(priv->fd, priv->vtno, 1);
- ioctl(priv->fd, KDSETMODE, KD_GRAPHICS); /* To turn off gpm */
- if (msg) write(priv->fd, msg, strlen(msg));
-}
-
-static void kbdLinuxCloseConsole(DevicePtr pDev)
-{
- GETPRIV;
- struct vt_mode VT;
- const char *msg = FINALMESSAGE;
-
- if (priv->fd < 0) return;
-
- ioctl(priv->fd, KDSETMODE, KD_TEXT);
- if (msg) write(priv->fd, msg, strlen(msg));
- if (ioctl(priv->fd, VT_GETMODE, &VT) != -1) {
- VT.mode = VT_AUTO;
- ioctl(priv->fd, VT_SETMODE, &VT);
- }
-
- LOG1("kbdLinuxCloseConsole: switching to VT %d\n", priv->vtcurrent);
- if (priv->vtcurrent >= 0) kbdLinuxActivate(priv->fd, priv->vtcurrent, 0);
-
- close(priv->fd);
- priv->fd = -1;
-}
-
-/** Initialize the \a pDev as a Linux keyboard. */
-void kbdLinuxInit(DevicePtr pDev)
-{
- GETPRIV;
-
- if (priv->fd <= 0) kbdLinuxOpenConsole(pDev);
-
- ioctl(priv->fd, KDGKBMODE, &priv->kbdtrans);
- if (tcgetattr(priv->fd, &priv->kbdtty) < 0)
- FATAL1("kbdLinuxInit: tcgetattr failed (%s)\n", strerror(errno));
-}
-
-static int kbdLinuxPrefix0Mapping(unsigned char *scanCode)
-{
- /* Table from xfree86/common/xf86Events.c */
- switch (*scanCode) {
- case KEY_KP_7: *scanCode = KEY_Home; break; /* curs home */
- case KEY_KP_8: *scanCode = KEY_Up; break; /* curs up */
- case KEY_KP_9: *scanCode = KEY_PgUp; break; /* curs pgup */
- case KEY_KP_4: *scanCode = KEY_Left; break; /* curs left */
- case KEY_KP_5: *scanCode = KEY_Begin; break; /* curs begin */
- case KEY_KP_6: *scanCode = KEY_Right; break; /* curs right */
- case KEY_KP_1: *scanCode = KEY_End; break; /* curs end */
- case KEY_KP_2: *scanCode = KEY_Down; break; /* curs down */
- case KEY_KP_3: *scanCode = KEY_PgDown; break; /* curs pgdown */
- case KEY_KP_0: *scanCode = KEY_Insert; break; /* curs insert */
- case KEY_KP_Decimal: *scanCode = KEY_Delete; break; /* curs delete */
- case KEY_Enter: *scanCode = KEY_KP_Enter; break; /* keypad enter */
- case KEY_LCtrl: *scanCode = KEY_RCtrl; break; /* right ctrl */
- case KEY_KP_Multiply: *scanCode = KEY_Print; break; /* print */
- case KEY_Slash: *scanCode = KEY_KP_Divide; break; /* keyp divide */
- case KEY_Alt: *scanCode = KEY_AltLang; break; /* right alt */
- case KEY_ScrollLock: *scanCode = KEY_Break; break; /* curs break */
- case 0x5b: *scanCode = KEY_LMeta; break;
- case 0x5c: *scanCode = KEY_RMeta; break;
- case 0x5d: *scanCode = KEY_Menu; break;
- case KEY_F3: *scanCode = KEY_F13; break;
- case KEY_F4: *scanCode = KEY_F14; break;
- case KEY_F5: *scanCode = KEY_F15; break;
- case KEY_F6: *scanCode = KEY_F16; break;
- case KEY_F7: *scanCode = KEY_F17; break;
- case KEY_KP_Plus: *scanCode = KEY_KP_DEC; break;
- /*
- * Ignore virtual shifts (E0 2A, E0 AA, E0 36, E0 B6)
- */
- case 0x2A:
- case 0x36:
- return 1;
- default:
- /*
- * "Internet" keyboards are generating lots of new codes.
- * Let them pass. There is little consistency between them,
- * so don't bother with symbolic names at this level.
- */
- scanCode += 0x78;
- }
- return 0;
-}
-
-static int kbdLinuxPrefixMapping(myPrivate *priv, unsigned char *scanCode)
-{
- int pressed = *scanCode & 0x80;
- unsigned char code = *scanCode & 0x7f;
-
- /* If we don't have a prefix, check for one */
- if (!priv->prefix) {
- switch (code) {
- case KEY_Prefix0:
- case KEY_Prefix1:
- priv->prefix = code;
- return 1;
- }
- return 0; /* No change */
- }
-
- /* We have a prefix from the last scanCode */
- switch (priv->prefix) {
- case KEY_Prefix0:
- priv->prefix = 0;
- if (kbdLinuxPrefix0Mapping(&code)) return 1; /* Skip sequence */
- break;
- case KEY_Prefix1:
- priv->prefix = (code = KEY_LCtrl) ? KEY_LCtrl : 0;
- return 1; /* Use new prefix */
- case KEY_LCtrl:
- priv->prefix = 0;
- if (code != KEY_NumLock) return 1; /* Skip sequence*/
- code = KEY_Pause;
- break;
- }
-
- *scanCode = code | (pressed ? 0x80 : 0x00);
- return 0; /* Use old scanCode */
-}
-
-static void kbdLinuxConvert(DevicePtr pDev,
- unsigned char scanCode,
- ENQUEUEPROC enqueue,
- CHECKPROC checkspecial,
- BLOCK block)
-{
- GETPRIV;
- XkbSrvInfoPtr xkbi = priv->pKeyboard->key->xkbInfo;
- int type;
- KeySym keySym = NoSymbol;
- int keyCode;
- int switching;
-
- /* Do special PC/AT prefix mapping -- may change scanCode! */
- if (kbdLinuxPrefixMapping(priv, &scanCode)) return;
-
- type = (scanCode & 0x80) ? KeyRelease : KeyPress;
- keyCode = (scanCode & 0x7f) + MIN_KEYCODE;
-
- /* Handle repeats */
-
- if (keyCode >= xkbi->desc->min_key_code &&
- keyCode <= xkbi->desc->max_key_code) {
-
- int effectiveGroup = XkbGetEffectiveGroup(xkbi,
- &xkbi->state,
- scanCode);
- keySym = XkbKeySym(xkbi->desc, scanCode, effectiveGroup);
-#if 0
- switch (keySym) {
- case XK_Num_Lock:
- case XK_Scroll_Lock:
- case XK_Shift_Lock:
- case XK_Caps_Lock:
- /* Ignore releases and all but first press */
- if (kbdLinuxModIgnore(priv, &xE, keySym)) return;
- if (kbdLinuxKeyDown(priv, &xE)) xE.u.u.type = KeyRelease;
- else xE.u.u.type = KeyPress;
- break;
- }
-#endif
-
- /* If key is already down, ignore or autorepeat */
- if (type == KeyPress && kbdLinuxKeyDown(priv, keyCode)) {
- KbdFeedbackClassRec *feed = priv->pKeyboard->kbdfeed;
-
- /* No auto-repeat? */
- if ((feed && !feed->ctrl.autoRepeat)
- || priv->pKeyboard->key->xkbInfo->desc->map->modmap[keyCode]
- || (feed
- && !(feed->ctrl.autoRepeats[keyCode >> 3]
- & (1 << (keyCode & 7))))) return; /* Ignore */
-
- /* Do auto-repeat */
- enqueue(pDev, KeyRelease, keyCode, keySym, NULL, block);
- type = KeyPress;
- }
-
- /* If key is already up, ignore */
- if (type == KeyRelease && !kbdLinuxKeyDown(priv, keyCode)) return;
- }
-
- switching = 0;
- if (checkspecial && type == KeyPress)
- switching = checkspecial(pDev, keySym);
- if (!switching) {
- if (enqueue)
- enqueue(pDev, type, keyCode, keySym, NULL, block);
- kbdLinuxKeyState(priv, type, keyCode); /* Update our state bitmap */
- }
-}
-
-/** Read an event from the \a pDev device. If the event is a motion
- * event, enqueue it with the \a motion function. Otherwise, check for
- * special keys with the \a checkspecial function and enqueue the event
- * with the \a enqueue function. The \a block type is passed to the
- * functions so that they may block SIGIO handling as appropriate to the
- * caller of this function. */
-void kbdLinuxRead(DevicePtr pDev,
- MOTIONPROC motion,
- ENQUEUEPROC enqueue,
- CHECKPROC checkspecial,
- BLOCK block)
-{
- GETPRIV;
- unsigned char buf[256]; /* RATS: Only used in length-limited call */
- unsigned char *pt;
- int n;
-
- while ((n = read(priv->fd, buf, sizeof(buf))) > 0)
- for (pt = buf; n; --n, ++pt)
- kbdLinuxConvert(pDev, *pt, enqueue, checkspecial, block);
-}
-
-/** Turn \a pDev on (i.e., take input from \a pDev). */
-int kbdLinuxOn(DevicePtr pDev)
-{
- GETPRIV;
- struct termios nTty;
-
- ioctl(priv->fd, KDSKBMODE, K_RAW);
-
- nTty = priv->kbdtty;
- nTty.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP);
- nTty.c_oflag = 0;
- nTty.c_cflag = CREAD | CS8;
- nTty.c_lflag = 0;
- nTty.c_cc[VTIME] = 0;
- nTty.c_cc[VMIN] = 1;
- cfsetispeed(&nTty, B9600);
- cfsetospeed(&nTty, B9600);
- if (tcsetattr(priv->fd, TCSANOW, &nTty) < 0)
- FATAL1("kbdLinuxOn: tcsetattr failed (%s)\n", strerror(errno));
- return priv->fd;
-}
-
-/** Turn \a pDev off (i.e., stop taking input from \a pDev). */
-void kbdLinuxOff(DevicePtr pDev)
-{
- GETPRIV;
-
- ioctl(priv->fd, KDSKBMODE, priv->kbdtrans);
- tcsetattr(priv->fd, TCSANOW, &priv->kbdtty);
- kbdLinuxCloseConsole(pDev);
-}
-
-
-static void kbdLinuxReadKernelMapping(int fd, KeySymsPtr pKeySyms)
-{
- KeySym *k;
- int i;
- int maxkey;
- static unsigned char tbl[GLYPHS_PER_KEY] = { /* RATS: Use ok */
- 0, /* unshifted */
- 1, /* shifted */
- 0, /* modeswitch unshifted */
- 0 /* modeswitch shifted */
- };
-
- /*
- * Read the mapping from the kernel.
- * Since we're still using the XFree86 scancode->AT keycode mapping
- * routines, we need to convert the AT keycodes to Linux keycodes,
- * then translate the Linux keysyms into X keysyms.
- *
- * First, figure out which tables to use for the modeswitch columns
- * above, from the XF86Config fields.
- */
- tbl[2] = 8; /* alt */
- tbl[3] = tbl[2] | 1;
-
-#if 00/*BP*/
- k = map+GLYPHS_PER_KEY;
-#else
- ErrorF("kbdLinuxReadKernelMapping() is broken/no-op'd\n");
- return;
-#endif
- maxkey = NUM_AT2LNX;
-
- for (i = 0; i < maxkey; ++i) {
- struct kbentry kbe;
- int j;
-
- kbe.kb_index = at2lnx[i];
-
- for (j = 0; j < GLYPHS_PER_KEY; ++j, ++k) {
- unsigned short kval;
-
- *k = NoSymbol;
-
- kbe.kb_table = tbl[j];
- if (kbe.kb_index == 0 || ioctl(fd, KDGKBENT, &kbe)) continue;
-
- kval = KVAL(kbe.kb_value);
- switch (KTYP(kbe.kb_value)) {
- case KT_LATIN:
- case KT_LETTER: *k = linux_to_x[kval]; break;
- case KT_FN:
- if (kval <= 19) *k = XK_F1 + kval;
- else switch (kbe.kb_value) {
- case K_FIND: *k = XK_Home; /* or XK_Find */ break;
- case K_INSERT: *k = XK_Insert; break;
- case K_REMOVE: *k = XK_Delete; break;
- case K_SELECT: *k = XK_End; /* or XK_Select */ break;
- case K_PGUP: *k = XK_Prior; break;
- case K_PGDN: *k = XK_Next; break;
- case K_HELP: *k = XK_Help; break;
- case K_DO: *k = XK_Execute; break;
- case K_PAUSE: *k = XK_Pause; break;
- case K_MACRO: *k = XK_Menu; break;
- default: break;
- }
- break;
- case KT_SPEC:
- switch (kbe.kb_value) {
- case K_ENTER: *k = XK_Return; break;
- case K_BREAK: *k = XK_Break; break;
- case K_CAPS: *k = XK_Caps_Lock; break;
- case K_NUM: *k = XK_Num_Lock; break;
- case K_HOLD: *k = XK_Scroll_Lock; break;
- case K_COMPOSE: *k = XK_Multi_key; break;
- default: break;
- }
- break;
- case KT_PAD:
- switch (kbe.kb_value) {
- case K_PPLUS: *k = XK_KP_Add; break;
- case K_PMINUS: *k = XK_KP_Subtract; break;
- case K_PSTAR: *k = XK_KP_Multiply; break;
- case K_PSLASH: *k = XK_KP_Divide; break;
- case K_PENTER: *k = XK_KP_Enter; break;
- case K_PCOMMA: *k = XK_KP_Separator; break;
- case K_PDOT: *k = XK_KP_Decimal; break;
- case K_PPLUSMINUS: *k = XK_KP_Subtract; break;
- default: if (kval <= 9) *k = XK_KP_0 + kval; break;
- }
- break;
- case KT_DEAD:
- /* KT_DEAD keys are for accelerated diacritical creation. */
- switch (kbe.kb_value) {
- case K_DGRAVE: *k = XK_dead_grave; break;
- case K_DACUTE: *k = XK_dead_acute; break;
- case K_DCIRCM: *k = XK_dead_circumflex; break;
- case K_DTILDE: *k = XK_dead_tilde; break;
- case K_DDIERE: *k = XK_dead_diaeresis; break;
- }
- break;
- case KT_CUR:
- switch (kbe.kb_value) {
- case K_DOWN: *k = XK_Down; break;
- case K_LEFT: *k = XK_Left; break;
- case K_RIGHT: *k = XK_Right; break;
- case K_UP: *k = XK_Up; break;
- }
- break;
- case KT_SHIFT:
- switch (kbe.kb_value) {
- case K_ALTGR: *k = XK_Alt_R; break;
- case K_ALT:
- *k = (kbe.kb_index == 0x64 ? XK_Alt_R : XK_Alt_L);
- break;
- case K_CTRL:
- *k = (kbe.kb_index == 0x61 ? XK_Control_R : XK_Control_L);
- break;
- case K_CTRLL: *k = XK_Control_L; break;
- case K_CTRLR: *k = XK_Control_R; break;
- case K_SHIFT:
- *k = (kbe.kb_index == 0x36 ? XK_Shift_R : XK_Shift_L);
- break;
- case K_SHIFTL: *k = XK_Shift_L; break;
- case K_SHIFTR: *k = XK_Shift_R; break;
- default: break;
- }
- break;
- case KT_ASCII:
- /* KT_ASCII keys accumulate a 3 digit decimal number that
- * gets emitted when the shift state changes. We can't
- * emulate that.
- */
- break;
- case KT_LOCK:
- if (kbe.kb_value == K_SHIFTLOCK) *k = XK_Shift_Lock;
- break;
- default: break;
- }
- }
-
- if (k[-1] == k[-2]) k[-1] = NoSymbol;
- if (k[-2] == k[-3]) k[-2] = NoSymbol;
- if (k[-3] == k[-4]) k[-3] = NoSymbol;
- if (k[-4] == k[-2] && k[-3] == k[-1]) k[-2] = k[-1] = NoSymbol;
- if (k[-1] == k[-4] && k[-2] == k[-3]
- && k[-2] == NoSymbol) k[-1] = NoSymbol;
- }
-}
-
-static void kbdLinuxGetMap(DevicePtr pDev, KeySymsPtr pKeySyms, CARD8 *pModMap)
-{
- GETPRIV;
- KeySym *k, *mapCopy;
- char type;
- int i;
-
-#if 00/*BP*/
- mapCopy = xalloc(sizeof(map));
- memcpy(mapCopy, map, sizeof(map));
-#else
- ErrorF("kbdLinuxGetMap() is broken/no-op'd\n");
- return;
-#endif
-
- kbdLinuxReadKernelMapping(priv->fd, pKeySyms);
-
- /* compute the modifier map */
- for (i = 0; i < MAP_LENGTH; i++)
- pModMap[i] = NoSymbol; /* make sure it is restored */
-
- for (k = mapCopy, i = MIN_KEYCODE;
- i < NUM_KEYCODES + MIN_KEYCODE;
- i++, k += 4) {
- switch(*k) {
- case XK_Shift_L:
- case XK_Shift_R: pModMap[i] = ShiftMask; break;
- case XK_Control_L:
- case XK_Control_R: pModMap[i] = ControlMask; break;
- case XK_Caps_Lock: pModMap[i] = LockMask; break;
- case XK_Alt_L:
- case XK_Alt_R: pModMap[i] = AltMask; break;
- case XK_Num_Lock: pModMap[i] = NumLockMask; break;
- case XK_Scroll_Lock: pModMap[i] = ScrollLockMask; break;
- case XK_Kana_Lock:
- case XK_Kana_Shift: pModMap[i] = KanaMask; break;
- case XK_Mode_switch: pModMap[i] = AltLangMask; break;
- }
- }
-
- priv->kbdType = (ioctl(priv->fd, KDGKBTYPE, &type) < 0) ? KB_101 : type;
-
- pKeySyms->map = mapCopy; /* Must be XFree'able */
- pKeySyms->mapWidth = GLYPHS_PER_KEY;
- pKeySyms->minKeyCode = MIN_KEYCODE;
- pKeySyms->maxKeyCode = MAX_KEYCODE;
-}
-
-/** Fill the \a info structure with information needed to initialize \a
- * pDev. */
-void kbdLinuxGetInfo(DevicePtr pDev, DMXLocalInitInfoPtr info)
-{
- info->keyboard = 1;
- info->keyClass = 1;
- kbdLinuxGetMap(pDev, &info->keySyms, info->modMap);
- info->focusClass = 1;
- info->kbdFeedbackClass = 1;
-}
+/* Portions of this file were derived from the following files:
+ *
+ **********************************************************************
+ *
+ * xfree86/common/{xf86Io.c,xf86Kbd.c,xf86Events.c}
+ *
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Thomas Roell not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Thomas Roell makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ **********************************************************************
+ *
+ * xfree86/common/xf86KbdLnx.c
+ *
+ * Linux version of keymapping setup. The kernel (since 0.99.14) has support
+ * for fully remapping the keyboard, but there are some differences between
+ * the Linux map and the SVR4 map (esp. in the extended keycodes). We also
+ * remove the restriction on what keycodes can be remapped.
+ * Orest Zborowski.
+ *
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Thomas Roell not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Thomas Roell makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ **********************************************************************
+ *
+ * xfree86/os-support/linux/lnx_io.c
+ *
+ * Copyright 1992 by Orest Zborowski <obz@Kodak.com>
+ * Copyright 1993 by David Dawes <dawes@xfree86.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the names of Orest Zborowski and David Dawes
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. Orest Zborowski
+ * and David Dawes 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 DAWES DISCLAIMS ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL OREST ZBOROWSKI OR DAVID DAWES BE LIABLE
+ * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/*
+ * Copyright 2001-2003 Red Hat Inc., Durham, North Carolina.
+ *
+ * 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 on 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 (including the
+ * next paragraph) 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
+ * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
+ * 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.
+ */
+
+/*
+ * Authors:
+ * Rickard E. (Rik) Faith <faith@redhat.com>
+ *
+ */
+
+/** \file
+ *
+ * This code implements a low-level device driver for the Linux
+ * keyboard. The code is derived from code by Thomas Roell, Orest
+ * Zborowski, and David Dawes (see the source code for complete
+ * references). */
+
+#ifdef HAVE_DMX_CONFIG_H
+#include <dmx-config.h>
+#endif
+
+/*****************************************************************************/
+/* Define some macros to make it easier to move this file to another
+ * part of the Xserver tree. All calls to the dmx* layer are #defined
+ * here for the .c file. The .h file will also have to be edited. */
+#include "dmxinputinit.h"
+#include "lnx-keyboard.h"
+
+#define GETPRIV myPrivate *priv \
+ = ((DMXLocalInputInfoPtr)(pDev->devicePrivate))->private
+
+#define LOG0(f) dmxLog(dmxDebug,f)
+#define LOG1(f,a) dmxLog(dmxDebug,f,a)
+#define LOG2(f,a,b) dmxLog(dmxDebug,f,a,b)
+#define LOG3(f,a,b,c) dmxLog(dmxDebug,f,a,b,c)
+#define FATAL0(f) dmxLog(dmxFatal,f)
+#define FATAL1(f,a) dmxLog(dmxFatal,f,a)
+#define FATAL2(f,a,b) dmxLog(dmxFatal,f,a,b)
+#define MOTIONPROC dmxMotionProcPtr
+#define ENQUEUEPROC dmxEnqueueProcPtr
+#define CHECKPROC dmxCheckSpecialProcPtr
+#define SWITCHRETPROC dmxVTSwitchReturnProcPtr
+#define BLOCK DMXBlockType
+#define MESSAGE "\033c\n\n\nDMX taking input from this console..."
+#define FINALMESSAGE "\033cDMX terminated."
+
+/* End of interface definitions. */
+/*****************************************************************************/
+
+#include "inputstr.h"
+#include <X11/Xos.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <signal.h>
+#include <sys/vt.h>
+#include <sys/kd.h>
+#include <termios.h>
+#include "atKeynames.h"
+#if 00
+#include "xf86Keymap.h"
+#endif
+#include <linux/keyboard.h>
+#include <xkbsrv.h>
+
+#define NUM_AT2LNX (sizeof(at2lnx) / sizeof(at2lnx[0]))
+#define NUM_STATE_ENTRIES (256/32)
+
+
+/* Private area for Linux-style keyboards. */
+typedef struct _myPrivate {
+ int fd;
+ int vtno;
+ int vtcurrent;
+ int kbdtrans;
+ struct termios kbdtty;
+ int kbdType;
+ CARD32 kbdState[NUM_STATE_ENTRIES];
+ DeviceIntPtr pKeyboard;
+ unsigned char prefix;
+
+ int switched;
+ SWITCHRETPROC switch_return;
+ void *switch_return_data;
+
+ /* For bell */
+ int pitch;
+ unsigned long duration;
+} myPrivate;
+
+static myPrivate *PRIV = NULL;
+
+#undef SYSCALL
+#define SYSCALL(call) while(((call) == -1) && (errno == EINTR))
+
+static int kbdLinuxKeyDown(myPrivate *priv, int keyCode)
+{
+ CARD8 byte = keyCode >> 5;
+ CARD32 bit = 1 << (keyCode & 0x1f);
+
+ if (byte > NUM_STATE_ENTRIES) return 0;
+ return priv->kbdState[byte] & bit;
+}
+
+static void kbdLinuxKeyState(myPrivate *priv, int type, int keyCode)
+{
+ CARD8 byte = keyCode >> 5;
+ CARD32 bit = 1 << (keyCode & 0x1f);
+
+ if (byte > NUM_STATE_ENTRIES) return;
+ if (type == KeyPress) priv->kbdState[byte] |= bit;
+ else priv->kbdState[byte] &= ~bit;
+}
+
+static KeySym linux_to_x[256] = {
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ XK_BackSpace, XK_Tab, XK_Linefeed, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, XK_Escape,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ XK_space, XK_exclam, XK_quotedbl, XK_numbersign,
+ XK_dollar, XK_percent, XK_ampersand, XK_apostrophe,
+ XK_parenleft, XK_parenright, XK_asterisk, XK_plus,
+ XK_comma, XK_minus, XK_period, XK_slash,
+ XK_0, XK_1, XK_2, XK_3,
+ XK_4, XK_5, XK_6, XK_7,
+ XK_8, XK_9, XK_colon, XK_semicolon,
+ XK_less, XK_equal, XK_greater, XK_question,
+ XK_at, XK_A, XK_B, XK_C,
+ XK_D, XK_E, XK_F, XK_G,
+ XK_H, XK_I, XK_J, XK_K,
+ XK_L, XK_M, XK_N, XK_O,
+ XK_P, XK_Q, XK_R, XK_S,
+ XK_T, XK_U, XK_V, XK_W,
+ XK_X, XK_Y, XK_Z, XK_bracketleft,
+ XK_backslash, XK_bracketright,XK_asciicircum, XK_underscore,
+ XK_grave, XK_a, XK_b, XK_c,
+ XK_d, XK_e, XK_f, XK_g,
+ XK_h, XK_i, XK_j, XK_k,
+ XK_l, XK_m, XK_n, XK_o,
+ XK_p, XK_q, XK_r, XK_s,
+ XK_t, XK_u, XK_v, XK_w,
+ XK_x, XK_y, XK_z, XK_braceleft,
+ XK_bar, XK_braceright, XK_asciitilde, XK_BackSpace,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ XK_nobreakspace,XK_exclamdown, XK_cent, XK_sterling,
+ XK_currency, XK_yen, XK_brokenbar, XK_section,
+ XK_diaeresis, XK_copyright, XK_ordfeminine, XK_guillemotleft,
+ XK_notsign, XK_hyphen, XK_registered, XK_macron,
+ XK_degree, XK_plusminus, XK_twosuperior, XK_threesuperior,
+ XK_acute, XK_mu, XK_paragraph, XK_periodcentered,
+ XK_cedilla, XK_onesuperior, XK_masculine, XK_guillemotright,
+ XK_onequarter, XK_onehalf, XK_threequarters,XK_questiondown,
+ XK_Agrave, XK_Aacute, XK_Acircumflex, XK_Atilde,
+ XK_Adiaeresis, XK_Aring, XK_AE, XK_Ccedilla,
+ XK_Egrave, XK_Eacute, XK_Ecircumflex, XK_Ediaeresis,
+ XK_Igrave, XK_Iacute, XK_Icircumflex, XK_Idiaeresis,
+ XK_ETH, XK_Ntilde, XK_Ograve, XK_Oacute,
+ XK_Ocircumflex, XK_Otilde, XK_Odiaeresis, XK_multiply,
+ XK_Ooblique, XK_Ugrave, XK_Uacute, XK_Ucircumflex,
+ XK_Udiaeresis, XK_Yacute, XK_THORN, XK_ssharp,
+ XK_agrave, XK_aacute, XK_acircumflex, XK_atilde,
+ XK_adiaeresis, XK_aring, XK_ae, XK_ccedilla,
+ XK_egrave, XK_eacute, XK_ecircumflex, XK_ediaeresis,
+ XK_igrave, XK_iacute, XK_icircumflex, XK_idiaeresis,
+ XK_eth, XK_ntilde, XK_ograve, XK_oacute,
+ XK_ocircumflex, XK_otilde, XK_odiaeresis, XK_division,
+ XK_oslash, XK_ugrave, XK_uacute, XK_ucircumflex,
+ XK_udiaeresis, XK_yacute, XK_thorn, XK_ydiaeresis
+};
+
+/*
+ * Maps the AT keycodes to Linux keycodes
+ */
+static unsigned char at2lnx[NUM_KEYCODES] =
+{
+ 0x01, /* KEY_Escape */ 0x02, /* KEY_1 */
+ 0x03, /* KEY_2 */ 0x04, /* KEY_3 */
+ 0x05, /* KEY_4 */ 0x06, /* KEY_5 */
+ 0x07, /* KEY_6 */ 0x08, /* KEY_7 */
+ 0x09, /* KEY_8 */ 0x0a, /* KEY_9 */
+ 0x0b, /* KEY_0 */ 0x0c, /* KEY_Minus */
+ 0x0d, /* KEY_Equal */ 0x0e, /* KEY_BackSpace */
+ 0x0f, /* KEY_Tab */ 0x10, /* KEY_Q */
+ 0x11, /* KEY_W */ 0x12, /* KEY_E */
+ 0x13, /* KEY_R */ 0x14, /* KEY_T */
+ 0x15, /* KEY_Y */ 0x16, /* KEY_U */
+ 0x17, /* KEY_I */ 0x18, /* KEY_O */
+ 0x19, /* KEY_P */ 0x1a, /* KEY_LBrace */
+ 0x1b, /* KEY_RBrace */ 0x1c, /* KEY_Enter */
+ 0x1d, /* KEY_LCtrl */ 0x1e, /* KEY_A */
+ 0x1f, /* KEY_S */ 0x20, /* KEY_D */
+ 0x21, /* KEY_F */ 0x22, /* KEY_G */
+ 0x23, /* KEY_H */ 0x24, /* KEY_J */
+ 0x25, /* KEY_K */ 0x26, /* KEY_L */
+ 0x27, /* KEY_SemiColon */ 0x28, /* KEY_Quote */
+ 0x29, /* KEY_Tilde */ 0x2a, /* KEY_ShiftL */
+ 0x2b, /* KEY_BSlash */ 0x2c, /* KEY_Z */
+ 0x2d, /* KEY_X */ 0x2e, /* KEY_C */
+ 0x2f, /* KEY_V */ 0x30, /* KEY_B */
+ 0x31, /* KEY_N */ 0x32, /* KEY_M */
+ 0x33, /* KEY_Comma */ 0x34, /* KEY_Period */
+ 0x35, /* KEY_Slash */ 0x36, /* KEY_ShiftR */
+ 0x37, /* KEY_KP_Multiply */ 0x38, /* KEY_Alt */
+ 0x39, /* KEY_Space */ 0x3a, /* KEY_CapsLock */
+ 0x3b, /* KEY_F1 */ 0x3c, /* KEY_F2 */
+ 0x3d, /* KEY_F3 */ 0x3e, /* KEY_F4 */
+ 0x3f, /* KEY_F5 */ 0x40, /* KEY_F6 */
+ 0x41, /* KEY_F7 */ 0x42, /* KEY_F8 */
+ 0x43, /* KEY_F9 */ 0x44, /* KEY_F10 */
+ 0x45, /* KEY_NumLock */ 0x46, /* KEY_ScrollLock */
+ 0x47, /* KEY_KP_7 */ 0x48, /* KEY_KP_8 */
+ 0x49, /* KEY_KP_9 */ 0x4a, /* KEY_KP_Minus */
+ 0x4b, /* KEY_KP_4 */ 0x4c, /* KEY_KP_5 */
+ 0x4d, /* KEY_KP_6 */ 0x4e, /* KEY_KP_Plus */
+ 0x4f, /* KEY_KP_1 */ 0x50, /* KEY_KP_2 */
+ 0x51, /* KEY_KP_3 */ 0x52, /* KEY_KP_0 */
+ 0x53, /* KEY_KP_Decimal */ 0x54, /* KEY_SysReqest */
+ 0x00, /* 0x55 */ 0x56, /* KEY_Less */
+ 0x57, /* KEY_F11 */ 0x58, /* KEY_F12 */
+ 0x66, /* KEY_Home */ 0x67, /* KEY_Up */
+ 0x68, /* KEY_PgUp */ 0x69, /* KEY_Left */
+ 0x5d, /* KEY_Begin */ 0x6a, /* KEY_Right */
+ 0x6b, /* KEY_End */ 0x6c, /* KEY_Down */
+ 0x6d, /* KEY_PgDown */ 0x6e, /* KEY_Insert */
+ 0x6f, /* KEY_Delete */ 0x60, /* KEY_KP_Enter */
+ 0x61, /* KEY_RCtrl */ 0x77, /* KEY_Pause */
+ 0x63, /* KEY_Print */ 0x62, /* KEY_KP_Divide */
+ 0x64, /* KEY_AltLang */ 0x65, /* KEY_Break */
+ 0x00, /* KEY_LMeta */ 0x00, /* KEY_RMeta */
+ 0x7A, /* KEY_Menu/FOCUS_PF11*/0x00, /* 0x6e */
+ 0x7B, /* FOCUS_PF12 */ 0x00, /* 0x70 */
+ 0x00, /* 0x71 */ 0x00, /* 0x72 */
+ 0x59, /* FOCUS_PF2 */ 0x78, /* FOCUS_PF9 */
+ 0x00, /* 0x75 */ 0x00, /* 0x76 */
+ 0x5A, /* FOCUS_PF3 */ 0x5B, /* FOCUS_PF4 */
+ 0x5C, /* FOCUS_PF5 */ 0x5D, /* FOCUS_PF6 */
+ 0x5E, /* FOCUS_PF7 */ 0x5F, /* FOCUS_PF8 */
+ 0x7C, /* JAP_86 */ 0x79, /* FOCUS_PF10 */
+ 0x00, /* 0x7f */
+};
+
+/** Create a private structure for use within this file. */
+pointer kbdLinuxCreatePrivate(DeviceIntPtr pKeyboard)
+{
+ myPrivate *priv = calloc(1, sizeof(*priv));
+ priv->fd = -1;
+ priv->pKeyboard = pKeyboard;
+ return priv;
+}
+
+/** Destroy a private structure. */
+void kbdLinuxDestroyPrivate(pointer priv)
+{
+ if (priv) free(priv);
+}
+
+/** Ring the bell.
+ *
+ * Note: we completely ignore the \a volume, since Linux's ioctl()
+ * interface does not provide a way to control it. If it did, the XBell
+ * manpage tells how the actual volume is a function of the percent and
+ * the (base) volume.
+ *
+ * Note that most of the other PC-based bell drivers compute the
+ * duration for KDMKTONE as a function of the volume and the duration.
+ * For some drivers, the duration is only measured in mS if the volume
+ * is 50, and is scaled by the volume for other values. This seems
+ * confusing and possibly incorrect (the xset man page says that the
+ * bell will be "as closely as it can to the user's specifications" --
+ * if we ignore the volume and set the duration correctly, then we'll
+ * get one parameter "wrong" -- but if we use the volume to scale the
+ * duration, then we'll get both parameters "wrong"). */
+void kbdLinuxBell(DevicePtr pDev, int percent,
+ int volume, int pitch, int duration)
+{
+ GETPRIV;
+
+ if (duration && pitch) {
+ ioctl(priv->fd,
+ KDMKTONE,
+ ((1193190 / pitch) & 0xffff) /* Low bits specify cycle time */
+ | (duration << 16)); /* High bits are duration in msec */
+ }
+}
+
+/** Set the LEDs. */
+void kbdLinuxCtrl(DevicePtr pDev, KeybdCtrl *ctrl)
+{
+ GETPRIV;
+
+ ioctl(priv->fd, KDSETLED, ctrl->leds & 0x07);
+}
+
+static int kbdLinuxGetFreeVTNumber(void)
+{
+ int fd = -1;
+ int vtno;
+ int i;
+ const char *tty0[] = { "/dev/tty0", "/dev/vc/0", NULL };
+
+ for (i = 0; tty0[i]; i++)
+ if ((fd = open(tty0[i], O_WRONLY, 0)) >= 0) break;
+ if (fd < 0)
+ FATAL1("kbdLinuxGetFreeVTNumber: Cannot open tty0 (%s)\n",
+ strerror(errno));
+ if (ioctl(fd, VT_OPENQRY, &vtno) < 0 || vtno < 0)
+ FATAL0("kbdLinuxGetFreeVTNumber: Cannot find a free VT\n");
+ return vtno;
+}
+
+static int kbdLinuxOpenVT(int vtno)
+{
+ int fd = -1;
+ int i;
+ const char *vcs[] = { "/dev/vc/%d", "/dev/tty%d", NULL };
+ char name[64]; /* RATS: Only used in XmuSnprintf */
+
+ for (i = 0; vcs[i]; i++) {
+ XmuSnprintf(name, sizeof(name), vcs[i], vtno);
+ if ((fd = open(name, O_RDWR | O_NONBLOCK, 0)) >= 0) break;
+ }
+ if (fd < 0)
+ FATAL2("kbdLinuxOpenVT: Cannot open VT %d (%s)\n",
+ vtno, strerror(errno));
+ return fd;
+}
+
+static int kbdLinuxGetCurrentVTNumber(int fd)
+{
+ struct vt_stat vts;
+
+ if (!ioctl(fd, VT_GETSTATE, &vts)) return vts.v_active;
+ return -1;
+}
+
+static int kbdLinuxActivate(int fd, int vtno, int setSig);
+
+/** Currently unused hook called prior to an VT switch. */
+void kbdLinuxVTPreSwitch(pointer p)
+{
+}
+
+/** Currently unused hook called after returning from a VT switch. */
+void kbdLinuxVTPostSwitch(pointer p)
+{
+}
+
+/** Tell the operating system to switch to \a vt. The \a switch_return
+ * function is called with the \a switch_return_data when the VT is
+ * switched back to the pre-switch VT (i.e., the user returns to the DMX
+ * session). */
+int kbdLinuxVTSwitch(pointer p, int vt,
+ void (*switch_return)(pointer),
+ pointer switch_return_data)
+{
+ myPrivate *priv = p;
+
+ if (priv->switched) FATAL0("kbdLinuxVTSwitch: already switched...\n");
+ if (priv->vtno == vt) return 0;
+
+ PRIV = priv;
+ priv->switched = 0; /* Will switch to 1 in handler */
+ priv->switch_return = switch_return;
+ priv->switch_return_data = switch_return_data;
+ kbdLinuxActivate(priv->fd, vt, 0);
+ return 1;
+}
+
+/* RATS: This function is only ever used to handle SIGUSR1. */
+static void kbdLinuxVTSignalHandler(int sig)
+{
+ myPrivate *priv = PRIV;
+
+ signal(sig, kbdLinuxVTSignalHandler);
+ if (priv) {
+ ioctl(priv->fd, VT_RELDISP, VT_ACKACQ);
+ priv->switched = !priv->switched;
+ LOG2("kbdLinuxVTSignalHandler: got signal %d, switched = %d\n",
+ sig, priv->switched);
+ if (!priv->switched && priv->switch_return)
+ priv->switch_return(priv->switch_return_data);
+ }
+}
+
+static int kbdLinuxActivate(int fd, int vtno, int setSig)
+{
+ int result;
+ struct vt_mode VT;
+
+ SYSCALL(result = ioctl(fd, VT_ACTIVATE, vtno));
+ if (result) FATAL0("kbdLinuxActivate: VT_ACTIVATE failed\n");
+ SYSCALL(result = ioctl(fd, VT_WAITACTIVE, vtno));
+ if (result) FATAL0("kbdLinuxActivate: VT_WAITACTIVE failed\n");
+ if (setSig) {
+ SYSCALL(result = ioctl(fd, VT_GETMODE, &VT));
+ if (result < 0) FATAL0("kbdLinuxActivate: VT_GETMODE failed\n");
+ VT.mode = VT_PROCESS;
+ VT.relsig = SIGUSR1;
+ VT.acqsig = SIGUSR1;
+ if (ioctl(fd, VT_SETMODE, &VT))
+ FATAL0("kbdLinuxActivate: VT_SETMODE VT_PROCESS failed\n");
+ signal(SIGUSR1, kbdLinuxVTSignalHandler);
+ }
+ return Success;
+}
+
+static void kbdLinuxOpenConsole(DevicePtr pDev)
+{
+ GETPRIV;
+ const char *msg = MESSAGE;
+
+ if (priv->fd >= 0) return;
+ priv->vtno = kbdLinuxGetFreeVTNumber();
+ priv->fd = kbdLinuxOpenVT(priv->vtno);
+ priv->vtcurrent = kbdLinuxGetCurrentVTNumber(priv->fd);
+ LOG2("kbdLinuxOpenConsole: current VT %d; using free VT %d\n",
+ priv->vtcurrent, priv->vtno);
+ kbdLinuxActivate(priv->fd, priv->vtno, 1);
+ ioctl(priv->fd, KDSETMODE, KD_GRAPHICS); /* To turn off gpm */
+ if (msg) write(priv->fd, msg, strlen(msg));
+}
+
+static void kbdLinuxCloseConsole(DevicePtr pDev)
+{
+ GETPRIV;
+ struct vt_mode VT;
+ const char *msg = FINALMESSAGE;
+
+ if (priv->fd < 0) return;
+
+ ioctl(priv->fd, KDSETMODE, KD_TEXT);
+ if (msg) write(priv->fd, msg, strlen(msg));
+ if (ioctl(priv->fd, VT_GETMODE, &VT) != -1) {
+ VT.mode = VT_AUTO;
+ ioctl(priv->fd, VT_SETMODE, &VT);
+ }
+
+ LOG1("kbdLinuxCloseConsole: switching to VT %d\n", priv->vtcurrent);
+ if (priv->vtcurrent >= 0) kbdLinuxActivate(priv->fd, priv->vtcurrent, 0);
+
+ close(priv->fd);
+ priv->fd = -1;
+}
+
+/** Initialize the \a pDev as a Linux keyboard. */
+void kbdLinuxInit(DevicePtr pDev)
+{
+ GETPRIV;
+
+ if (priv->fd <= 0) kbdLinuxOpenConsole(pDev);
+
+ ioctl(priv->fd, KDGKBMODE, &priv->kbdtrans);
+ if (tcgetattr(priv->fd, &priv->kbdtty) < 0)
+ FATAL1("kbdLinuxInit: tcgetattr failed (%s)\n", strerror(errno));
+}
+
+static int kbdLinuxPrefix0Mapping(unsigned char *scanCode)
+{
+ /* Table from xfree86/common/xf86Events.c */
+ switch (*scanCode) {
+ case KEY_KP_7: *scanCode = KEY_Home; break; /* curs home */
+ case KEY_KP_8: *scanCode = KEY_Up; break; /* curs up */
+ case KEY_KP_9: *scanCode = KEY_PgUp; break; /* curs pgup */
+ case KEY_KP_4: *scanCode = KEY_Left; break; /* curs left */
+ case KEY_KP_5: *scanCode = KEY_Begin; break; /* curs begin */
+ case KEY_KP_6: *scanCode = KEY_Right; break; /* curs right */
+ case KEY_KP_1: *scanCode = KEY_End; break; /* curs end */
+ case KEY_KP_2: *scanCode = KEY_Down; break; /* curs down */
+ case KEY_KP_3: *scanCode = KEY_PgDown; break; /* curs pgdown */
+ case KEY_KP_0: *scanCode = KEY_Insert; break; /* curs insert */
+ case KEY_KP_Decimal: *scanCode = KEY_Delete; break; /* curs delete */
+ case KEY_Enter: *scanCode = KEY_KP_Enter; break; /* keypad enter */
+ case KEY_LCtrl: *scanCode = KEY_RCtrl; break; /* right ctrl */
+ case KEY_KP_Multiply: *scanCode = KEY_Print; break; /* print */
+ case KEY_Slash: *scanCode = KEY_KP_Divide; break; /* keyp divide */
+ case KEY_Alt: *scanCode = KEY_AltLang; break; /* right alt */
+ case KEY_ScrollLock: *scanCode = KEY_Break; break; /* curs break */
+ case 0x5b: *scanCode = KEY_LMeta; break;
+ case 0x5c: *scanCode = KEY_RMeta; break;
+ case 0x5d: *scanCode = KEY_Menu; break;
+ case KEY_F3: *scanCode = KEY_F13; break;
+ case KEY_F4: *scanCode = KEY_F14; break;
+ case KEY_F5: *scanCode = KEY_F15; break;
+ case KEY_F6: *scanCode = KEY_F16; break;
+ case KEY_F7: *scanCode = KEY_F17; break;
+ case KEY_KP_Plus: *scanCode = KEY_KP_DEC; break;
+ /*
+ * Ignore virtual shifts (E0 2A, E0 AA, E0 36, E0 B6)
+ */
+ case 0x2A:
+ case 0x36:
+ return 1;
+ default:
+ /*
+ * "Internet" keyboards are generating lots of new codes.
+ * Let them pass. There is little consistency between them,
+ * so don't bother with symbolic names at this level.
+ */
+ scanCode += 0x78;
+ }
+ return 0;
+}
+
+static int kbdLinuxPrefixMapping(myPrivate *priv, unsigned char *scanCode)
+{
+ int pressed = *scanCode & 0x80;
+ unsigned char code = *scanCode & 0x7f;
+
+ /* If we don't have a prefix, check for one */
+ if (!priv->prefix) {
+ switch (code) {
+ case KEY_Prefix0:
+ case KEY_Prefix1:
+ priv->prefix = code;
+ return 1;
+ }
+ return 0; /* No change */
+ }
+
+ /* We have a prefix from the last scanCode */
+ switch (priv->prefix) {
+ case KEY_Prefix0:
+ priv->prefix = 0;
+ if (kbdLinuxPrefix0Mapping(&code)) return 1; /* Skip sequence */
+ break;
+ case KEY_Prefix1:
+ priv->prefix = (code = KEY_LCtrl) ? KEY_LCtrl : 0;
+ return 1; /* Use new prefix */
+ case KEY_LCtrl:
+ priv->prefix = 0;
+ if (code != KEY_NumLock) return 1; /* Skip sequence*/
+ code = KEY_Pause;
+ break;
+ }
+
+ *scanCode = code | (pressed ? 0x80 : 0x00);
+ return 0; /* Use old scanCode */
+}
+
+static void kbdLinuxConvert(DevicePtr pDev,
+ unsigned char scanCode,
+ ENQUEUEPROC enqueue,
+ CHECKPROC checkspecial,
+ BLOCK block)
+{
+ GETPRIV;
+ XkbSrvInfoPtr xkbi = priv->pKeyboard->key->xkbInfo;
+ int type;
+ KeySym keySym = NoSymbol;
+ int keyCode;
+ int switching;
+
+ /* Do special PC/AT prefix mapping -- may change scanCode! */
+ if (kbdLinuxPrefixMapping(priv, &scanCode)) return;
+
+ type = (scanCode & 0x80) ? KeyRelease : KeyPress;
+ keyCode = (scanCode & 0x7f) + MIN_KEYCODE;
+
+ /* Handle repeats */
+
+ if (keyCode >= xkbi->desc->min_key_code &&
+ keyCode <= xkbi->desc->max_key_code) {
+
+ int effectiveGroup = XkbGetEffectiveGroup(xkbi,
+ &xkbi->state,
+ scanCode);
+ keySym = XkbKeySym(xkbi->desc, scanCode, effectiveGroup);
+#if 0
+ switch (keySym) {
+ case XK_Num_Lock:
+ case XK_Scroll_Lock:
+ case XK_Shift_Lock:
+ case XK_Caps_Lock:
+ /* Ignore releases and all but first press */
+ if (kbdLinuxModIgnore(priv, &xE, keySym)) return;
+ if (kbdLinuxKeyDown(priv, &xE)) xE.u.u.type = KeyRelease;
+ else xE.u.u.type = KeyPress;
+ break;
+ }
+#endif
+
+ /* If key is already down, ignore or autorepeat */
+ if (type == KeyPress && kbdLinuxKeyDown(priv, keyCode)) {
+ KbdFeedbackClassRec *feed = priv->pKeyboard->kbdfeed;
+
+ /* No auto-repeat? */
+ if ((feed && !feed->ctrl.autoRepeat)
+ || priv->pKeyboard->key->xkbInfo->desc->map->modmap[keyCode]
+ || (feed
+ && !(feed->ctrl.autoRepeats[keyCode >> 3]
+ & (1 << (keyCode & 7))))) return; /* Ignore */
+
+ /* Do auto-repeat */
+ enqueue(pDev, KeyRelease, keyCode, keySym, NULL, block);
+ type = KeyPress;
+ }
+
+ /* If key is already up, ignore */
+ if (type == KeyRelease && !kbdLinuxKeyDown(priv, keyCode)) return;
+ }
+
+ switching = 0;
+ if (checkspecial && type == KeyPress)
+ switching = checkspecial(pDev, keySym);
+ if (!switching) {
+ if (enqueue)
+ enqueue(pDev, type, keyCode, keySym, NULL, block);
+ kbdLinuxKeyState(priv, type, keyCode); /* Update our state bitmap */
+ }
+}
+
+/** Read an event from the \a pDev device. If the event is a motion
+ * event, enqueue it with the \a motion function. Otherwise, check for
+ * special keys with the \a checkspecial function and enqueue the event
+ * with the \a enqueue function. The \a block type is passed to the
+ * functions so that they may block SIGIO handling as appropriate to the
+ * caller of this function. */
+void kbdLinuxRead(DevicePtr pDev,
+ MOTIONPROC motion,
+ ENQUEUEPROC enqueue,
+ CHECKPROC checkspecial,
+ BLOCK block)
+{
+ GETPRIV;
+ unsigned char buf[256]; /* RATS: Only used in length-limited call */
+ unsigned char *pt;
+ int n;
+
+ while ((n = read(priv->fd, buf, sizeof(buf))) > 0)
+ for (pt = buf; n; --n, ++pt)
+ kbdLinuxConvert(pDev, *pt, enqueue, checkspecial, block);
+}
+
+/** Turn \a pDev on (i.e., take input from \a pDev). */
+int kbdLinuxOn(DevicePtr pDev)
+{
+ GETPRIV;
+ struct termios nTty;
+
+ ioctl(priv->fd, KDSKBMODE, K_RAW);
+
+ nTty = priv->kbdtty;
+ nTty.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP);
+ nTty.c_oflag = 0;
+ nTty.c_cflag = CREAD | CS8;
+ nTty.c_lflag = 0;
+ nTty.c_cc[VTIME] = 0;
+ nTty.c_cc[VMIN] = 1;
+ cfsetispeed(&nTty, B9600);
+ cfsetospeed(&nTty, B9600);
+ if (tcsetattr(priv->fd, TCSANOW, &nTty) < 0)
+ FATAL1("kbdLinuxOn: tcsetattr failed (%s)\n", strerror(errno));
+ return priv->fd;
+}
+
+/** Turn \a pDev off (i.e., stop taking input from \a pDev). */
+void kbdLinuxOff(DevicePtr pDev)
+{
+ GETPRIV;
+
+ ioctl(priv->fd, KDSKBMODE, priv->kbdtrans);
+ tcsetattr(priv->fd, TCSANOW, &priv->kbdtty);
+ kbdLinuxCloseConsole(pDev);
+}
+
+
+static void kbdLinuxReadKernelMapping(int fd, KeySymsPtr pKeySyms)
+{
+ KeySym *k;
+ int i;
+ int maxkey;
+ static unsigned char tbl[GLYPHS_PER_KEY] = { /* RATS: Use ok */
+ 0, /* unshifted */
+ 1, /* shifted */
+ 0, /* modeswitch unshifted */
+ 0 /* modeswitch shifted */
+ };
+
+ /*
+ * Read the mapping from the kernel.
+ * Since we're still using the XFree86 scancode->AT keycode mapping
+ * routines, we need to convert the AT keycodes to Linux keycodes,
+ * then translate the Linux keysyms into X keysyms.
+ *
+ * First, figure out which tables to use for the modeswitch columns
+ * above, from the XF86Config fields.
+ */
+ tbl[2] = 8; /* alt */
+ tbl[3] = tbl[2] | 1;
+
+#if 00/*BP*/
+ k = map+GLYPHS_PER_KEY;
+#else
+ ErrorF("kbdLinuxReadKernelMapping() is broken/no-op'd\n");
+ return;
+#endif
+ maxkey = NUM_AT2LNX;
+
+ for (i = 0; i < maxkey; ++i) {
+ struct kbentry kbe;
+ int j;
+
+ kbe.kb_index = at2lnx[i];
+
+ for (j = 0; j < GLYPHS_PER_KEY; ++j, ++k) {
+ unsigned short kval;
+
+ *k = NoSymbol;
+
+ kbe.kb_table = tbl[j];
+ if (kbe.kb_index == 0 || ioctl(fd, KDGKBENT, &kbe)) continue;
+
+ kval = KVAL(kbe.kb_value);
+ switch (KTYP(kbe.kb_value)) {
+ case KT_LATIN:
+ case KT_LETTER: *k = linux_to_x[kval]; break;
+ case KT_FN:
+ if (kval <= 19) *k = XK_F1 + kval;
+ else switch (kbe.kb_value) {
+ case K_FIND: *k = XK_Home; /* or XK_Find */ break;
+ case K_INSERT: *k = XK_Insert; break;
+ case K_REMOVE: *k = XK_Delete; break;
+ case K_SELECT: *k = XK_End; /* or XK_Select */ break;
+ case K_PGUP: *k = XK_Prior; break;
+ case K_PGDN: *k = XK_Next; break;
+ case K_HELP: *k = XK_Help; break;
+ case K_DO: *k = XK_Execute; break;
+ case K_PAUSE: *k = XK_Pause; break;
+ case K_MACRO: *k = XK_Menu; break;
+ default: break;
+ }
+ break;
+ case KT_SPEC:
+ switch (kbe.kb_value) {
+ case K_ENTER: *k = XK_Return; break;
+ case K_BREAK: *k = XK_Break; break;
+ case K_CAPS: *k = XK_Caps_Lock; break;
+ case K_NUM: *k = XK_Num_Lock; break;
+ case K_HOLD: *k = XK_Scroll_Lock; break;
+ case K_COMPOSE: *k = XK_Multi_key; break;
+ default: break;
+ }
+ break;
+ case KT_PAD:
+ switch (kbe.kb_value) {
+ case K_PPLUS: *k = XK_KP_Add; break;
+ case K_PMINUS: *k = XK_KP_Subtract; break;
+ case K_PSTAR: *k = XK_KP_Multiply; break;
+ case K_PSLASH: *k = XK_KP_Divide; break;
+ case K_PENTER: *k = XK_KP_Enter; break;
+ case K_PCOMMA: *k = XK_KP_Separator; break;
+ case K_PDOT: *k = XK_KP_Decimal; break;
+ case K_PPLUSMINUS: *k = XK_KP_Subtract; break;
+ default: if (kval <= 9) *k = XK_KP_0 + kval; break;
+ }
+ break;
+ case KT_DEAD:
+ /* KT_DEAD keys are for accelerated diacritical creation. */
+ switch (kbe.kb_value) {
+ case K_DGRAVE: *k = XK_dead_grave; break;
+ case K_DACUTE: *k = XK_dead_acute; break;
+ case K_DCIRCM: *k = XK_dead_circumflex; break;
+ case K_DTILDE: *k = XK_dead_tilde; break;
+ case K_DDIERE: *k = XK_dead_diaeresis; break;
+ }
+ break;
+ case KT_CUR:
+ switch (kbe.kb_value) {
+ case K_DOWN: *k = XK_Down; break;
+ case K_LEFT: *k = XK_Left; break;
+ case K_RIGHT: *k = XK_Right; break;
+ case K_UP: *k = XK_Up; break;
+ }
+ break;
+ case KT_SHIFT:
+ switch (kbe.kb_value) {
+ case K_ALTGR: *k = XK_Alt_R; break;
+ case K_ALT:
+ *k = (kbe.kb_index == 0x64 ? XK_Alt_R : XK_Alt_L);
+ break;
+ case K_CTRL:
+ *k = (kbe.kb_index == 0x61 ? XK_Control_R : XK_Control_L);
+ break;
+ case K_CTRLL: *k = XK_Control_L; break;
+ case K_CTRLR: *k = XK_Control_R; break;
+ case K_SHIFT:
+ *k = (kbe.kb_index == 0x36 ? XK_Shift_R : XK_Shift_L);
+ break;
+ case K_SHIFTL: *k = XK_Shift_L; break;
+ case K_SHIFTR: *k = XK_Shift_R; break;
+ default: break;
+ }
+ break;
+ case KT_ASCII:
+ /* KT_ASCII keys accumulate a 3 digit decimal number that
+ * gets emitted when the shift state changes. We can't
+ * emulate that.
+ */
+ break;
+ case KT_LOCK:
+ if (kbe.kb_value == K_SHIFTLOCK) *k = XK_Shift_Lock;
+ break;
+ default: break;
+ }
+ }
+
+ if (k[-1] == k[-2]) k[-1] = NoSymbol;
+ if (k[-2] == k[-3]) k[-2] = NoSymbol;
+ if (k[-3] == k[-4]) k[-3] = NoSymbol;
+ if (k[-4] == k[-2] && k[-3] == k[-1]) k[-2] = k[-1] = NoSymbol;
+ if (k[-1] == k[-4] && k[-2] == k[-3]
+ && k[-2] == NoSymbol) k[-1] = NoSymbol;
+ }
+}
+
+static void kbdLinuxGetMap(DevicePtr pDev, KeySymsPtr pKeySyms, CARD8 *pModMap)
+{
+ GETPRIV;
+ KeySym *k, *mapCopy;
+ char type;
+ int i;
+
+#if 00/*BP*/
+ mapCopy = malloc(sizeof(map));
+ memcpy(mapCopy, map, sizeof(map));
+#else
+ ErrorF("kbdLinuxGetMap() is broken/no-op'd\n");
+ return;
+#endif
+
+ kbdLinuxReadKernelMapping(priv->fd, pKeySyms);
+
+ /* compute the modifier map */
+ for (i = 0; i < MAP_LENGTH; i++)
+ pModMap[i] = NoSymbol; /* make sure it is restored */
+
+ for (k = mapCopy, i = MIN_KEYCODE;
+ i < NUM_KEYCODES + MIN_KEYCODE;
+ i++, k += 4) {
+ switch(*k) {
+ case XK_Shift_L:
+ case XK_Shift_R: pModMap[i] = ShiftMask; break;
+ case XK_Control_L:
+ case XK_Control_R: pModMap[i] = ControlMask; break;
+ case XK_Caps_Lock: pModMap[i] = LockMask; break;
+ case XK_Alt_L:
+ case XK_Alt_R: pModMap[i] = AltMask; break;
+ case XK_Num_Lock: pModMap[i] = NumLockMask; break;
+ case XK_Scroll_Lock: pModMap[i] = ScrollLockMask; break;
+ case XK_Kana_Lock:
+ case XK_Kana_Shift: pModMap[i] = KanaMask; break;
+ case XK_Mode_switch: pModMap[i] = AltLangMask; break;
+ }
+ }
+
+ priv->kbdType = (ioctl(priv->fd, KDGKBTYPE, &type) < 0) ? KB_101 : type;
+
+ pKeySyms->map = mapCopy; /* Must be XFree'able */
+ pKeySyms->mapWidth = GLYPHS_PER_KEY;
+ pKeySyms->minKeyCode = MIN_KEYCODE;
+ pKeySyms->maxKeyCode = MAX_KEYCODE;
+}
+
+/** Fill the \a info structure with information needed to initialize \a
+ * pDev. */
+void kbdLinuxGetInfo(DevicePtr pDev, DMXLocalInitInfoPtr info)
+{
+ info->keyboard = 1;
+ info->keyClass = 1;
+ kbdLinuxGetMap(pDev, &info->keySyms, info->modMap);
+ info->focusClass = 1;
+ info->kbdFeedbackClass = 1;
+}
diff --git a/xorg-server/hw/dmx/input/usb-keyboard.c b/xorg-server/hw/dmx/input/usb-keyboard.c
index c4667a3c3..fcbea47f9 100644
--- a/xorg-server/hw/dmx/input/usb-keyboard.c
+++ b/xorg-server/hw/dmx/input/usb-keyboard.c
@@ -1,444 +1,444 @@
-/* Portions of this file were derived from the following files:
- *
- **********************************************************************
- *
- * xfree86/common/xf86KbdLnx.c
- *
- * Linux version of keymapping setup. The kernel (since 0.99.14) has support
- * for fully remapping the keyboard, but there are some differences between
- * the Linux map and the SVR4 map (esp. in the extended keycodes). We also
- * remove the restriction on what keycodes can be remapped.
- * Orest Zborowski.
- *
- * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Thomas Roell not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Thomas Roell makes no representations
- * about the suitability of this software for any purpose. It is provided
- * "as is" without express or implied warranty.
- *
- * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- */
-
-/*
- * Copyright 2001,2002 Red Hat Inc., Durham, North Carolina.
- *
- * 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 on 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 (including the
- * next paragraph) 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
- * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
- * 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.
- */
-
-/*
- * Authors:
- * Rickard E. (Rik) Faith <faith@redhat.com>
- *
- */
-
-/** \file
- *
- * This code implements a low-level device driver for a USB keyboard
- * under Linux. The keymap description is derived from code by Thomas
- * Roell, Orest Zborowski. */
-
-#ifdef HAVE_DMX_CONFIG_H
-#include <dmx-config.h>
-#endif
-
-#include "atKeynames.h"
-#include "usb-private.h"
-
-#define USB_KEYBOARD_DEBUG 0
-
-/*****************************************************************************/
-/* Define some macros to make it easier to move this file to another
- * part of the Xserver tree. All calls to the dmx* layer are #defined
- * here for the .c file. The .h file will also have to be edited. */
-#include "usb-keyboard.h"
-#include <xkbsrv.h>
-
-#define GETPRIV myPrivate *priv \
- = ((DMXLocalInputInfoPtr)(pDev->devicePrivate))->private
-
-#define LOG0(f) dmxLog(dmxDebug,f)
-#define LOG1(f,a) dmxLog(dmxDebug,f,a)
-#define LOG2(f,a,b) dmxLog(dmxDebug,f,a,b)
-#define LOG3(f,a,b,c) dmxLog(dmxDebug,f,a,b,c)
-#define FATAL0(f) dmxLog(dmxFatal,f)
-#define FATAL1(f,a) dmxLog(dmxFatal,f,a)
-#define FATAL2(f,a,b) dmxLog(dmxFatal,f,a,b)
-#define MOTIONPROC dmxMotionProcPtr
-#define ENQUEUEPROC dmxEnqueueProcPtr
-#define CHECKPROC dmxCheckSpecialProcPtr
-#define BLOCK DMXBlockType
-
-/* End of interface definitions. */
-/*****************************************************************************/
-
-#define GLYPHS_PER_KEY 4
-#define NUM_KEYCODES 248
-#define MIN_KEYCODE 8
-#define MAX_KEYCODE (NUM_KEYCODES + MIN_KEYCODE - 1)
-
-static KeySym map[NUM_KEYCODES * GLYPHS_PER_KEY] = {
-/* Table modified from xc/programs/Xserver/hw/xfree86/common/xf86Keymap.h */
- /* 0x00 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- /* 0x01 */ XK_Escape, NoSymbol, NoSymbol, NoSymbol,
- /* 0x02 */ XK_1, XK_exclam, NoSymbol, NoSymbol,
- /* 0x03 */ XK_2, XK_at, NoSymbol, NoSymbol,
- /* 0x04 */ XK_3, XK_numbersign, NoSymbol, NoSymbol,
- /* 0x05 */ XK_4, XK_dollar, NoSymbol, NoSymbol,
- /* 0x06 */ XK_5, XK_percent, NoSymbol, NoSymbol,
- /* 0x07 */ XK_6, XK_asciicircum, NoSymbol, NoSymbol,
- /* 0x08 */ XK_7, XK_ampersand, NoSymbol, NoSymbol,
- /* 0x09 */ XK_8, XK_asterisk, NoSymbol, NoSymbol,
- /* 0x0a */ XK_9, XK_parenleft, NoSymbol, NoSymbol,
- /* 0x0b */ XK_0, XK_parenright, NoSymbol, NoSymbol,
- /* 0x0c */ XK_minus, XK_underscore, NoSymbol, NoSymbol,
- /* 0x0d */ XK_equal, XK_plus, NoSymbol, NoSymbol,
- /* 0x0e */ XK_BackSpace, NoSymbol, NoSymbol, NoSymbol,
- /* 0x0f */ XK_Tab, XK_ISO_Left_Tab,NoSymbol, NoSymbol,
- /* 0x10 */ XK_Q, NoSymbol, NoSymbol, NoSymbol,
- /* 0x11 */ XK_W, NoSymbol, NoSymbol, NoSymbol,
- /* 0x12 */ XK_E, NoSymbol, NoSymbol, NoSymbol,
- /* 0x13 */ XK_R, NoSymbol, NoSymbol, NoSymbol,
- /* 0x14 */ XK_T, NoSymbol, NoSymbol, NoSymbol,
- /* 0x15 */ XK_Y, NoSymbol, NoSymbol, NoSymbol,
- /* 0x16 */ XK_U, NoSymbol, NoSymbol, NoSymbol,
- /* 0x17 */ XK_I, NoSymbol, NoSymbol, NoSymbol,
- /* 0x18 */ XK_O, NoSymbol, NoSymbol, NoSymbol,
- /* 0x19 */ XK_P, NoSymbol, NoSymbol, NoSymbol,
- /* 0x1a */ XK_bracketleft, XK_braceleft, NoSymbol, NoSymbol,
- /* 0x1b */ XK_bracketright,XK_braceright, NoSymbol, NoSymbol,
- /* 0x1c */ XK_Return, NoSymbol, NoSymbol, NoSymbol,
- /* 0x1d */ XK_Control_L, NoSymbol, NoSymbol, NoSymbol,
- /* 0x1e */ XK_A, NoSymbol, NoSymbol, NoSymbol,
- /* 0x1f */ XK_S, NoSymbol, NoSymbol, NoSymbol,
- /* 0x20 */ XK_D, NoSymbol, NoSymbol, NoSymbol,
- /* 0x21 */ XK_F, NoSymbol, NoSymbol, NoSymbol,
- /* 0x22 */ XK_G, NoSymbol, NoSymbol, NoSymbol,
- /* 0x23 */ XK_H, NoSymbol, NoSymbol, NoSymbol,
- /* 0x24 */ XK_J, NoSymbol, NoSymbol, NoSymbol,
- /* 0x25 */ XK_K, NoSymbol, NoSymbol, NoSymbol,
- /* 0x26 */ XK_L, NoSymbol, NoSymbol, NoSymbol,
- /* 0x27 */ XK_semicolon, XK_colon, NoSymbol, NoSymbol,
- /* 0x28 */ XK_quoteright, XK_quotedbl, NoSymbol, NoSymbol,
- /* 0x29 */ XK_quoteleft, XK_asciitilde, NoSymbol, NoSymbol,
- /* 0x2a */ XK_Shift_L, NoSymbol, NoSymbol, NoSymbol,
- /* 0x2b */ XK_backslash, XK_bar, NoSymbol, NoSymbol,
- /* 0x2c */ XK_Z, NoSymbol, NoSymbol, NoSymbol,
- /* 0x2d */ XK_X, NoSymbol, NoSymbol, NoSymbol,
- /* 0x2e */ XK_C, NoSymbol, NoSymbol, NoSymbol,
- /* 0x2f */ XK_V, NoSymbol, NoSymbol, NoSymbol,
- /* 0x30 */ XK_B, NoSymbol, NoSymbol, NoSymbol,
- /* 0x31 */ XK_N, NoSymbol, NoSymbol, NoSymbol,
- /* 0x32 */ XK_M, NoSymbol, NoSymbol, NoSymbol,
- /* 0x33 */ XK_comma, XK_less, NoSymbol, NoSymbol,
- /* 0x34 */ XK_period, XK_greater, NoSymbol, NoSymbol,
- /* 0x35 */ XK_slash, XK_question, NoSymbol, NoSymbol,
- /* 0x36 */ XK_Shift_R, NoSymbol, NoSymbol, NoSymbol,
- /* 0x37 */ XK_KP_Multiply, NoSymbol, NoSymbol, NoSymbol,
- /* 0x38 */ XK_Alt_L, XK_Meta_L, NoSymbol, NoSymbol,
- /* 0x39 */ XK_space, NoSymbol, NoSymbol, NoSymbol,
- /* 0x3a */ XK_Caps_Lock, NoSymbol, NoSymbol, NoSymbol,
- /* 0x3b */ XK_F1, NoSymbol, NoSymbol, NoSymbol,
- /* 0x3c */ XK_F2, NoSymbol, NoSymbol, NoSymbol,
- /* 0x3d */ XK_F3, NoSymbol, NoSymbol, NoSymbol,
- /* 0x3e */ XK_F4, NoSymbol, NoSymbol, NoSymbol,
- /* 0x3f */ XK_F5, NoSymbol, NoSymbol, NoSymbol,
- /* 0x40 */ XK_F6, NoSymbol, NoSymbol, NoSymbol,
- /* 0x41 */ XK_F7, NoSymbol, NoSymbol, NoSymbol,
- /* 0x42 */ XK_F8, NoSymbol, NoSymbol, NoSymbol,
- /* 0x43 */ XK_F9, NoSymbol, NoSymbol, NoSymbol,
- /* 0x44 */ XK_F10, NoSymbol, NoSymbol, NoSymbol,
- /* 0x45 */ XK_Num_Lock, NoSymbol, NoSymbol, NoSymbol,
- /* 0x46 */ XK_Scroll_Lock, NoSymbol, NoSymbol, NoSymbol,
- /* 0x47 */ XK_KP_Home, XK_KP_7, NoSymbol, NoSymbol,
- /* 0x48 */ XK_KP_Up, XK_KP_8, NoSymbol, NoSymbol,
- /* 0x49 */ XK_KP_Prior, XK_KP_9, NoSymbol, NoSymbol,
- /* 0x4a */ XK_KP_Subtract, NoSymbol, NoSymbol, NoSymbol,
- /* 0x4b */ XK_KP_Left, XK_KP_4, NoSymbol, NoSymbol,
- /* 0x4c */ XK_KP_Begin, XK_KP_5, NoSymbol, NoSymbol,
- /* 0x4d */ XK_KP_Right, XK_KP_6, NoSymbol, NoSymbol,
- /* 0x4e */ XK_KP_Add, NoSymbol, NoSymbol, NoSymbol,
- /* 0x4f */ XK_KP_End, XK_KP_1, NoSymbol, NoSymbol,
- /* 0x50 */ XK_KP_Down, XK_KP_2, NoSymbol, NoSymbol,
- /* 0x51 */ XK_KP_Next, XK_KP_3, NoSymbol, NoSymbol,
- /* 0x52 */ XK_KP_Insert, XK_KP_0, NoSymbol, NoSymbol,
- /* 0x53 */ XK_KP_Delete, XK_KP_Decimal, NoSymbol, NoSymbol,
- /* 0x54 */ XK_Sys_Req, NoSymbol, NoSymbol, NoSymbol,
- /* 0x55 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- /* 0x56 */ XK_less, XK_greater, NoSymbol, NoSymbol,
- /* 0x57 */ XK_F11, NoSymbol, NoSymbol, NoSymbol,
- /* 0x58 */ XK_F12, NoSymbol, NoSymbol, NoSymbol,
- /* 0x59 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- /* 0x5a */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- /* 0x5b */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- /* 0x5c */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- /* 0x5d */ XK_Begin, NoSymbol, NoSymbol, NoSymbol,
- /* 0x5e */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- /* 0x5f */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- /* 0x60 */ XK_KP_Enter, NoSymbol, NoSymbol, NoSymbol,
- /* 0x61 */ XK_Control_R, NoSymbol, NoSymbol, NoSymbol,
- /* 0x62 */ XK_KP_Divide, NoSymbol, NoSymbol, NoSymbol,
- /* 0x63 */ XK_Print, NoSymbol, NoSymbol, NoSymbol,
- /* 0x64 */ XK_Alt_R, XK_Meta_R, NoSymbol, NoSymbol,
- /* 0x65 */ XK_Break, NoSymbol, NoSymbol, NoSymbol,
- /* 0x66 */ XK_Home, NoSymbol, NoSymbol, NoSymbol,
- /* 0x67 */ XK_Up, NoSymbol, NoSymbol, NoSymbol,
- /* 0x68 */ XK_Prior, NoSymbol, NoSymbol, NoSymbol,
- /* 0x69 */ XK_Left, NoSymbol, NoSymbol, NoSymbol,
- /* 0x6a */ XK_Right, NoSymbol, NoSymbol, NoSymbol,
- /* 0x6b */ XK_End, NoSymbol, NoSymbol, NoSymbol,
- /* 0x6c */ XK_Down, NoSymbol, NoSymbol, NoSymbol,
- /* 0x6d */ XK_Next, NoSymbol, NoSymbol, NoSymbol,
- /* 0x6e */ XK_Insert, NoSymbol, NoSymbol, NoSymbol,
- /* 0x6f */ XK_Delete, NoSymbol, NoSymbol, NoSymbol,
- /* 0x70 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- /* 0x71 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- /* 0x72 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- /* 0x73 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- /* 0x74 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- /* 0x75 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- /* 0x76 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- /* 0x77 */ XK_Pause, NoSymbol, NoSymbol, NoSymbol,
- /* 0x78 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- /* 0x79 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- /* 0x7a */ XK_Menu, NoSymbol, NoSymbol, NoSymbol,
- /* 0x7b */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- /* 0x7c */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- /* 0x7d */ XK_Super_L, NoSymbol, NoSymbol, NoSymbol,
- /* 0x7e */ XK_Super_R, NoSymbol, NoSymbol, NoSymbol,
- /* 0x7f */ XK_Menu, NoSymbol, NoSymbol, NoSymbol,
-};
-
-static int kbdUSBKeyDown(myPrivate *priv, int keyCode)
-{
- CARD8 byte = keyCode >> 5;
- CARD32 bit = 1 << (keyCode & 0x1f);
-
- if (byte > NUM_STATE_ENTRIES) return 0;
- return priv->kbdState[byte] & bit;
-}
-
-static void kbdUSBKeyState(myPrivate *priv, int type, int keyCode)
-{
- CARD8 byte = keyCode >> 5;
- CARD32 bit = 1 << (keyCode & 0x1f);
-
- if (byte > NUM_STATE_ENTRIES) return;
- if (type == KeyPress) priv->kbdState[byte] |= bit;
- else priv->kbdState[byte] &= ~bit;
-}
-
-/** Set the LEDs. */
-void kbdUSBCtrl(DevicePtr pDev, KeybdCtrl *ctrl)
-{
- GETPRIV;
- struct timeval tv;
- struct input_event event;
- int i, led;
-
- gettimeofday(&tv, NULL);
- for (i = 0; i < 5; i++) {
- event.time.tv_sec = tv.tv_sec;
- event.time.tv_usec = tv.tv_usec;
- event.type = EV_LED;
- if (i == 0) led = 1; /* LED_CAPSL == 0x01 */
- else if (i == 1) led = 0; /* LED_NUML == 0x00 */
- else led = i;
- event.code = led;
- event.value = !!(ctrl->leds & (1 << led));
- write(priv->fd, &event, sizeof(event));
- }
-}
-
-/** Initialize \a pDev using #usbInit. */
-void kbdUSBInit(DevicePtr pDev)
-{
- usbInit(pDev, usbKeyboard);
-}
-
-static void kbdUSBConvert(DevicePtr pDev,
- unsigned int scanCode,
- int value,
- ENQUEUEPROC enqueue,
- CHECKPROC checkspecial,
- BLOCK block)
-{
- GETPRIV;
- XkbSrvInfoPtr xkbi = priv->pKeyboard->key->xkbInfo;
- int type;
- int keyCode;
- KeySym keySym = NoSymbol;
- int switching;
-
- /* Set up xEvent information */
- type = value ? KeyPress : KeyRelease;
- keyCode = (scanCode & 0xff) + MIN_KEYCODE;
-
- /* Handle repeats */
-
- if (keyCode >= xkbi->desc->min_key_code &&
- keyCode <= xkbi->desc->max_key_code) {
-
- int effectiveGroup = XkbGetEffectiveGroup(xkbi,
- &xkbi->state,
- scanCode);
- keySym = XkbKeySym(xkbi->desc, scanCode, effectiveGroup);
-#if 0
- switch (keySym) {
- case XK_Num_Lock:
- case XK_Scroll_Lock:
- case XK_Shift_Lock:
- case XK_Caps_Lock:
- /* Ignore releases and all but first press */
- if (kbdLinuxModIgnore(priv, &xE, keySym)) return;
- if (kbdLinuxKeyDown(priv, &xE)) xE.u.u.type = KeyRelease;
- else xE.u.u.type = KeyPress;
- break;
- }
-#endif
-
- /* If key is already down, ignore or autorepeat */
- if (type == KeyPress && kbdUSBKeyDown(priv, keyCode)) {
- KbdFeedbackClassRec *feed = priv->pDevice->kbdfeed;
-
- /* No auto-repeat? */
- if ((feed && !feed->ctrl.autoRepeat)
- || priv->pDevice->key->xkbInfo->desc->map->modmap[keyCode]
- || (feed
- && !(feed->ctrl.autoRepeats[keyCode >> 3]
- & (1 << (keyCode & 7))))) return; /* Ignore */
-
- /* Do auto-repeat */
- enqueue(pDev, KeyRelease, keyCode, keySym, NULL, block);
- type = KeyPress;
- }
-
- /* If key is already up, ignore */
- if (type == KeyRelease && !kbdUSBKeyDown(priv, keyCode)) return;
- }
-
- switching = 0;
- if (checkspecial && type == KeyPress)
- switching = checkspecial(pDev, keySym);
- if (!switching) {
- if (enqueue)
- enqueue(pDev, type, keyCode, keySym, NULL, block);
- kbdUSBKeyState(priv, type, keyCode); /* Update our state bitmap */
- }
-}
-
-/** Read an event from the \a pDev device. If the event is a motion
- * event, enqueue it with the \a motion function. Otherwise, check for
- * special keys with the \a checkspecial function and enqueue the event
- * with the \a enqueue function. The \a block type is passed to the
- * functions so that they may block SIGIO handling as appropriate to the
- * caller of this function. */
-void kbdUSBRead(DevicePtr pDev,
- MOTIONPROC motion,
- ENQUEUEPROC enqueue,
- CHECKPROC checkspecial,
- BLOCK block)
-{
- GETPRIV;
- struct input_event raw;
-
- while (read(priv->fd, &raw, sizeof(raw)) > 0) {
-#if USB_KEYBOARD_DEBUG
- LOG3("KBD: type = %d, code = 0x%02x, value = %d\n",
- raw.type, raw.code, raw.value);
-#endif
- kbdUSBConvert(pDev, raw.code, raw.value, enqueue, checkspecial, block);
- }
-}
-
-/** Turn \a pDev on (i.e., take input from \a pDev). */
-int kbdUSBOn(DevicePtr pDev)
-{
- GETPRIV;
-
- if (priv->fd < 0) kbdUSBInit(pDev);
- return priv->fd;
-}
-
-static void kbdUSBGetMap(DevicePtr pDev, KeySymsPtr pKeySyms, CARD8 *pModMap)
-{
- KeySym *k, *mapCopy;
- int i;
-
- mapCopy = xalloc(sizeof(map));
- memcpy(mapCopy, map, sizeof(map));
-
- /* compute the modifier map */
- for (i = 0; i < MAP_LENGTH; i++)
- pModMap[i] = NoSymbol; /* make sure it is restored */
-
- for (k = mapCopy, i = MIN_KEYCODE;
- i < NUM_KEYCODES + MIN_KEYCODE;
- i++, k += 4) {
- switch(*k) {
- case XK_Shift_L:
- case XK_Shift_R: pModMap[i] = ShiftMask; break;
- case XK_Control_L:
- case XK_Control_R: pModMap[i] = ControlMask; break;
- case XK_Caps_Lock: pModMap[i] = LockMask; break;
- case XK_Alt_L:
- case XK_Alt_R: pModMap[i] = AltMask; break;
- case XK_Num_Lock: pModMap[i] = NumLockMask; break;
- case XK_Scroll_Lock: pModMap[i] = ScrollLockMask; break;
- case XK_Kana_Lock:
- case XK_Kana_Shift: pModMap[i] = KanaMask; break;
- case XK_Mode_switch: pModMap[i] = AltLangMask; break;
- }
- }
-
- pKeySyms->map = mapCopy; /* Must be XFree'able */
- pKeySyms->mapWidth = GLYPHS_PER_KEY;
- pKeySyms->minKeyCode = MIN_KEYCODE;
- pKeySyms->maxKeyCode = MAX_KEYCODE;
-}
-
-/** Fill the \a info structure with information needed to initialize \a
- * pDev. */
-void kbdUSBGetInfo(DevicePtr pDev, DMXLocalInitInfoPtr info)
-{
- info->keyboard = 1;
- info->keyClass = 1;
- kbdUSBGetMap(pDev, &info->keySyms, info->modMap);
- info->focusClass = 1;
- info->kbdFeedbackClass = 1;
- info->names.keycodes = xstrdup("powerpcps2");
- info->force = 1;
-}
+/* Portions of this file were derived from the following files:
+ *
+ **********************************************************************
+ *
+ * xfree86/common/xf86KbdLnx.c
+ *
+ * Linux version of keymapping setup. The kernel (since 0.99.14) has support
+ * for fully remapping the keyboard, but there are some differences between
+ * the Linux map and the SVR4 map (esp. in the extended keycodes). We also
+ * remove the restriction on what keycodes can be remapped.
+ * Orest Zborowski.
+ *
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Thomas Roell not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Thomas Roell makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+/*
+ * Copyright 2001,2002 Red Hat Inc., Durham, North Carolina.
+ *
+ * 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 on 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 (including the
+ * next paragraph) 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
+ * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
+ * 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.
+ */
+
+/*
+ * Authors:
+ * Rickard E. (Rik) Faith <faith@redhat.com>
+ *
+ */
+
+/** \file
+ *
+ * This code implements a low-level device driver for a USB keyboard
+ * under Linux. The keymap description is derived from code by Thomas
+ * Roell, Orest Zborowski. */
+
+#ifdef HAVE_DMX_CONFIG_H
+#include <dmx-config.h>
+#endif
+
+#include "atKeynames.h"
+#include "usb-private.h"
+
+#define USB_KEYBOARD_DEBUG 0
+
+/*****************************************************************************/
+/* Define some macros to make it easier to move this file to another
+ * part of the Xserver tree. All calls to the dmx* layer are #defined
+ * here for the .c file. The .h file will also have to be edited. */
+#include "usb-keyboard.h"
+#include <xkbsrv.h>
+
+#define GETPRIV myPrivate *priv \
+ = ((DMXLocalInputInfoPtr)(pDev->devicePrivate))->private
+
+#define LOG0(f) dmxLog(dmxDebug,f)
+#define LOG1(f,a) dmxLog(dmxDebug,f,a)
+#define LOG2(f,a,b) dmxLog(dmxDebug,f,a,b)
+#define LOG3(f,a,b,c) dmxLog(dmxDebug,f,a,b,c)
+#define FATAL0(f) dmxLog(dmxFatal,f)
+#define FATAL1(f,a) dmxLog(dmxFatal,f,a)
+#define FATAL2(f,a,b) dmxLog(dmxFatal,f,a,b)
+#define MOTIONPROC dmxMotionProcPtr
+#define ENQUEUEPROC dmxEnqueueProcPtr
+#define CHECKPROC dmxCheckSpecialProcPtr
+#define BLOCK DMXBlockType
+
+/* End of interface definitions. */
+/*****************************************************************************/
+
+#define GLYPHS_PER_KEY 4
+#define NUM_KEYCODES 248
+#define MIN_KEYCODE 8
+#define MAX_KEYCODE (NUM_KEYCODES + MIN_KEYCODE - 1)
+
+static KeySym map[NUM_KEYCODES * GLYPHS_PER_KEY] = {
+/* Table modified from xc/programs/Xserver/hw/xfree86/common/xf86Keymap.h */
+ /* 0x00 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x01 */ XK_Escape, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x02 */ XK_1, XK_exclam, NoSymbol, NoSymbol,
+ /* 0x03 */ XK_2, XK_at, NoSymbol, NoSymbol,
+ /* 0x04 */ XK_3, XK_numbersign, NoSymbol, NoSymbol,
+ /* 0x05 */ XK_4, XK_dollar, NoSymbol, NoSymbol,
+ /* 0x06 */ XK_5, XK_percent, NoSymbol, NoSymbol,
+ /* 0x07 */ XK_6, XK_asciicircum, NoSymbol, NoSymbol,
+ /* 0x08 */ XK_7, XK_ampersand, NoSymbol, NoSymbol,
+ /* 0x09 */ XK_8, XK_asterisk, NoSymbol, NoSymbol,
+ /* 0x0a */ XK_9, XK_parenleft, NoSymbol, NoSymbol,
+ /* 0x0b */ XK_0, XK_parenright, NoSymbol, NoSymbol,
+ /* 0x0c */ XK_minus, XK_underscore, NoSymbol, NoSymbol,
+ /* 0x0d */ XK_equal, XK_plus, NoSymbol, NoSymbol,
+ /* 0x0e */ XK_BackSpace, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x0f */ XK_Tab, XK_ISO_Left_Tab,NoSymbol, NoSymbol,
+ /* 0x10 */ XK_Q, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x11 */ XK_W, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x12 */ XK_E, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x13 */ XK_R, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x14 */ XK_T, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x15 */ XK_Y, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x16 */ XK_U, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x17 */ XK_I, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x18 */ XK_O, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x19 */ XK_P, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x1a */ XK_bracketleft, XK_braceleft, NoSymbol, NoSymbol,
+ /* 0x1b */ XK_bracketright,XK_braceright, NoSymbol, NoSymbol,
+ /* 0x1c */ XK_Return, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x1d */ XK_Control_L, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x1e */ XK_A, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x1f */ XK_S, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x20 */ XK_D, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x21 */ XK_F, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x22 */ XK_G, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x23 */ XK_H, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x24 */ XK_J, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x25 */ XK_K, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x26 */ XK_L, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x27 */ XK_semicolon, XK_colon, NoSymbol, NoSymbol,
+ /* 0x28 */ XK_quoteright, XK_quotedbl, NoSymbol, NoSymbol,
+ /* 0x29 */ XK_quoteleft, XK_asciitilde, NoSymbol, NoSymbol,
+ /* 0x2a */ XK_Shift_L, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x2b */ XK_backslash, XK_bar, NoSymbol, NoSymbol,
+ /* 0x2c */ XK_Z, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x2d */ XK_X, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x2e */ XK_C, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x2f */ XK_V, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x30 */ XK_B, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x31 */ XK_N, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x32 */ XK_M, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x33 */ XK_comma, XK_less, NoSymbol, NoSymbol,
+ /* 0x34 */ XK_period, XK_greater, NoSymbol, NoSymbol,
+ /* 0x35 */ XK_slash, XK_question, NoSymbol, NoSymbol,
+ /* 0x36 */ XK_Shift_R, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x37 */ XK_KP_Multiply, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x38 */ XK_Alt_L, XK_Meta_L, NoSymbol, NoSymbol,
+ /* 0x39 */ XK_space, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x3a */ XK_Caps_Lock, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x3b */ XK_F1, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x3c */ XK_F2, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x3d */ XK_F3, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x3e */ XK_F4, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x3f */ XK_F5, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x40 */ XK_F6, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x41 */ XK_F7, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x42 */ XK_F8, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x43 */ XK_F9, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x44 */ XK_F10, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x45 */ XK_Num_Lock, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x46 */ XK_Scroll_Lock, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x47 */ XK_KP_Home, XK_KP_7, NoSymbol, NoSymbol,
+ /* 0x48 */ XK_KP_Up, XK_KP_8, NoSymbol, NoSymbol,
+ /* 0x49 */ XK_KP_Prior, XK_KP_9, NoSymbol, NoSymbol,
+ /* 0x4a */ XK_KP_Subtract, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x4b */ XK_KP_Left, XK_KP_4, NoSymbol, NoSymbol,
+ /* 0x4c */ XK_KP_Begin, XK_KP_5, NoSymbol, NoSymbol,
+ /* 0x4d */ XK_KP_Right, XK_KP_6, NoSymbol, NoSymbol,
+ /* 0x4e */ XK_KP_Add, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x4f */ XK_KP_End, XK_KP_1, NoSymbol, NoSymbol,
+ /* 0x50 */ XK_KP_Down, XK_KP_2, NoSymbol, NoSymbol,
+ /* 0x51 */ XK_KP_Next, XK_KP_3, NoSymbol, NoSymbol,
+ /* 0x52 */ XK_KP_Insert, XK_KP_0, NoSymbol, NoSymbol,
+ /* 0x53 */ XK_KP_Delete, XK_KP_Decimal, NoSymbol, NoSymbol,
+ /* 0x54 */ XK_Sys_Req, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x55 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x56 */ XK_less, XK_greater, NoSymbol, NoSymbol,
+ /* 0x57 */ XK_F11, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x58 */ XK_F12, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x59 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x5a */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x5b */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x5c */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x5d */ XK_Begin, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x5e */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x5f */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x60 */ XK_KP_Enter, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x61 */ XK_Control_R, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x62 */ XK_KP_Divide, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x63 */ XK_Print, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x64 */ XK_Alt_R, XK_Meta_R, NoSymbol, NoSymbol,
+ /* 0x65 */ XK_Break, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x66 */ XK_Home, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x67 */ XK_Up, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x68 */ XK_Prior, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x69 */ XK_Left, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x6a */ XK_Right, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x6b */ XK_End, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x6c */ XK_Down, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x6d */ XK_Next, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x6e */ XK_Insert, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x6f */ XK_Delete, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x70 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x71 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x72 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x73 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x74 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x75 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x76 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x77 */ XK_Pause, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x78 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x79 */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x7a */ XK_Menu, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x7b */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x7c */ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x7d */ XK_Super_L, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x7e */ XK_Super_R, NoSymbol, NoSymbol, NoSymbol,
+ /* 0x7f */ XK_Menu, NoSymbol, NoSymbol, NoSymbol,
+};
+
+static int kbdUSBKeyDown(myPrivate *priv, int keyCode)
+{
+ CARD8 byte = keyCode >> 5;
+ CARD32 bit = 1 << (keyCode & 0x1f);
+
+ if (byte > NUM_STATE_ENTRIES) return 0;
+ return priv->kbdState[byte] & bit;
+}
+
+static void kbdUSBKeyState(myPrivate *priv, int type, int keyCode)
+{
+ CARD8 byte = keyCode >> 5;
+ CARD32 bit = 1 << (keyCode & 0x1f);
+
+ if (byte > NUM_STATE_ENTRIES) return;
+ if (type == KeyPress) priv->kbdState[byte] |= bit;
+ else priv->kbdState[byte] &= ~bit;
+}
+
+/** Set the LEDs. */
+void kbdUSBCtrl(DevicePtr pDev, KeybdCtrl *ctrl)
+{
+ GETPRIV;
+ struct timeval tv;
+ struct input_event event;
+ int i, led;
+
+ gettimeofday(&tv, NULL);
+ for (i = 0; i < 5; i++) {
+ event.time.tv_sec = tv.tv_sec;
+ event.time.tv_usec = tv.tv_usec;
+ event.type = EV_LED;
+ if (i == 0) led = 1; /* LED_CAPSL == 0x01 */
+ else if (i == 1) led = 0; /* LED_NUML == 0x00 */
+ else led = i;
+ event.code = led;
+ event.value = !!(ctrl->leds & (1 << led));
+ write(priv->fd, &event, sizeof(event));
+ }
+}
+
+/** Initialize \a pDev using #usbInit. */
+void kbdUSBInit(DevicePtr pDev)
+{
+ usbInit(pDev, usbKeyboard);
+}
+
+static void kbdUSBConvert(DevicePtr pDev,
+ unsigned int scanCode,
+ int value,
+ ENQUEUEPROC enqueue,
+ CHECKPROC checkspecial,
+ BLOCK block)
+{
+ GETPRIV;
+ XkbSrvInfoPtr xkbi = priv->pKeyboard->key->xkbInfo;
+ int type;
+ int keyCode;
+ KeySym keySym = NoSymbol;
+ int switching;
+
+ /* Set up xEvent information */
+ type = value ? KeyPress : KeyRelease;
+ keyCode = (scanCode & 0xff) + MIN_KEYCODE;
+
+ /* Handle repeats */
+
+ if (keyCode >= xkbi->desc->min_key_code &&
+ keyCode <= xkbi->desc->max_key_code) {
+
+ int effectiveGroup = XkbGetEffectiveGroup(xkbi,
+ &xkbi->state,
+ scanCode);
+ keySym = XkbKeySym(xkbi->desc, scanCode, effectiveGroup);
+#if 0
+ switch (keySym) {
+ case XK_Num_Lock:
+ case XK_Scroll_Lock:
+ case XK_Shift_Lock:
+ case XK_Caps_Lock:
+ /* Ignore releases and all but first press */
+ if (kbdLinuxModIgnore(priv, &xE, keySym)) return;
+ if (kbdLinuxKeyDown(priv, &xE)) xE.u.u.type = KeyRelease;
+ else xE.u.u.type = KeyPress;
+ break;
+ }
+#endif
+
+ /* If key is already down, ignore or autorepeat */
+ if (type == KeyPress && kbdUSBKeyDown(priv, keyCode)) {
+ KbdFeedbackClassRec *feed = priv->pDevice->kbdfeed;
+
+ /* No auto-repeat? */
+ if ((feed && !feed->ctrl.autoRepeat)
+ || priv->pDevice->key->xkbInfo->desc->map->modmap[keyCode]
+ || (feed
+ && !(feed->ctrl.autoRepeats[keyCode >> 3]
+ & (1 << (keyCode & 7))))) return; /* Ignore */
+
+ /* Do auto-repeat */
+ enqueue(pDev, KeyRelease, keyCode, keySym, NULL, block);
+ type = KeyPress;
+ }
+
+ /* If key is already up, ignore */
+ if (type == KeyRelease && !kbdUSBKeyDown(priv, keyCode)) return;
+ }
+
+ switching = 0;
+ if (checkspecial && type == KeyPress)
+ switching = checkspecial(pDev, keySym);
+ if (!switching) {
+ if (enqueue)
+ enqueue(pDev, type, keyCode, keySym, NULL, block);
+ kbdUSBKeyState(priv, type, keyCode); /* Update our state bitmap */
+ }
+}
+
+/** Read an event from the \a pDev device. If the event is a motion
+ * event, enqueue it with the \a motion function. Otherwise, check for
+ * special keys with the \a checkspecial function and enqueue the event
+ * with the \a enqueue function. The \a block type is passed to the
+ * functions so that they may block SIGIO handling as appropriate to the
+ * caller of this function. */
+void kbdUSBRead(DevicePtr pDev,
+ MOTIONPROC motion,
+ ENQUEUEPROC enqueue,
+ CHECKPROC checkspecial,
+ BLOCK block)
+{
+ GETPRIV;
+ struct input_event raw;
+
+ while (read(priv->fd, &raw, sizeof(raw)) > 0) {
+#if USB_KEYBOARD_DEBUG
+ LOG3("KBD: type = %d, code = 0x%02x, value = %d\n",
+ raw.type, raw.code, raw.value);
+#endif
+ kbdUSBConvert(pDev, raw.code, raw.value, enqueue, checkspecial, block);
+ }
+}
+
+/** Turn \a pDev on (i.e., take input from \a pDev). */
+int kbdUSBOn(DevicePtr pDev)
+{
+ GETPRIV;
+
+ if (priv->fd < 0) kbdUSBInit(pDev);
+ return priv->fd;
+}
+
+static void kbdUSBGetMap(DevicePtr pDev, KeySymsPtr pKeySyms, CARD8 *pModMap)
+{
+ KeySym *k, *mapCopy;
+ int i;
+
+ mapCopy = malloc(sizeof(map));
+ memcpy(mapCopy, map, sizeof(map));
+
+ /* compute the modifier map */
+ for (i = 0; i < MAP_LENGTH; i++)
+ pModMap[i] = NoSymbol; /* make sure it is restored */
+
+ for (k = mapCopy, i = MIN_KEYCODE;
+ i < NUM_KEYCODES + MIN_KEYCODE;
+ i++, k += 4) {
+ switch(*k) {
+ case XK_Shift_L:
+ case XK_Shift_R: pModMap[i] = ShiftMask; break;
+ case XK_Control_L:
+ case XK_Control_R: pModMap[i] = ControlMask; break;
+ case XK_Caps_Lock: pModMap[i] = LockMask; break;
+ case XK_Alt_L:
+ case XK_Alt_R: pModMap[i] = AltMask; break;
+ case XK_Num_Lock: pModMap[i] = NumLockMask; break;
+ case XK_Scroll_Lock: pModMap[i] = ScrollLockMask; break;
+ case XK_Kana_Lock:
+ case XK_Kana_Shift: pModMap[i] = KanaMask; break;
+ case XK_Mode_switch: pModMap[i] = AltLangMask; break;
+ }
+ }
+
+ pKeySyms->map = mapCopy; /* Must be XFree'able */
+ pKeySyms->mapWidth = GLYPHS_PER_KEY;
+ pKeySyms->minKeyCode = MIN_KEYCODE;
+ pKeySyms->maxKeyCode = MAX_KEYCODE;
+}
+
+/** Fill the \a info structure with information needed to initialize \a
+ * pDev. */
+void kbdUSBGetInfo(DevicePtr pDev, DMXLocalInitInfoPtr info)
+{
+ info->keyboard = 1;
+ info->keyClass = 1;
+ kbdUSBGetMap(pDev, &info->keySyms, info->modMap);
+ info->focusClass = 1;
+ info->kbdFeedbackClass = 1;
+ info->names.keycodes = xstrdup("powerpcps2");
+ info->force = 1;
+}
diff --git a/xorg-server/hw/kdrive/ephyr/ephyr.c b/xorg-server/hw/kdrive/ephyr/ephyr.c
index 6e61b8c5d..21c696c20 100644
--- a/xorg-server/hw/kdrive/ephyr/ephyr.c
+++ b/xorg-server/hw/kdrive/ephyr/ephyr.c
@@ -76,13 +76,13 @@ ephyrCardInit (KdCardInfo *card)
{
EphyrPriv *priv;
- priv = (EphyrPriv *) xalloc (sizeof (EphyrPriv));
+ priv = (EphyrPriv *) malloc(sizeof (EphyrPriv));
if (!priv)
return FALSE;
if (!ephyrInitialize (card, priv))
{
- xfree (priv);
+ free(priv);
return FALSE;
}
card->driver = priv;
@@ -188,7 +188,7 @@ ephyrScreenInit (KdScreenInfo *screen)
{
EphyrScrPriv *scrpriv;
- scrpriv = xcalloc (1, sizeof (EphyrScrPriv));
+ scrpriv = calloc(1, sizeof (EphyrScrPriv));
if (!scrpriv)
return FALSE;
@@ -198,7 +198,7 @@ ephyrScreenInit (KdScreenInfo *screen)
if (!ephyrScreenInitialize (screen, scrpriv))
{
screen->driver = 0;
- xfree (scrpriv);
+ free(scrpriv);
return FALSE;
}
@@ -740,7 +740,7 @@ ephyrScreenFini (KdScreenInfo *screen)
if (scrpriv->shadow) {
KdShadowFbFree (screen);
}
- xfree(screen->driver);
+ free(screen->driver);
screen->driver = NULL;
}
@@ -1034,7 +1034,7 @@ void
ephyrCardFini (KdCardInfo *card)
{
EphyrPriv *priv = card->driver;
- xfree (priv);
+ free(priv);
}
void
@@ -1086,11 +1086,11 @@ static Status
MouseInit (KdPointerInfo *pi)
{
pi->driverPrivate = (EphyrPointerPrivate *)
- xcalloc(sizeof(EphyrPointerPrivate), 1);
+ calloc(sizeof(EphyrPointerPrivate), 1);
((EphyrPointerPrivate *)pi->driverPrivate)->enabled = FALSE;
pi->nAxes = 3;
pi->nButtons = 32;
- xfree(pi->name);
+ free(pi->name);
pi->name = strdup("Xephyr virtual mouse");
ephyrMouse = pi;
return Success;
@@ -1132,7 +1132,7 @@ static Status
EphyrKeyboardInit (KdKeyboardInfo *ki)
{
ki->driverPrivate = (EphyrKbdPrivate *)
- xcalloc(sizeof(EphyrKbdPrivate), 1);
+ calloc(sizeof(EphyrKbdPrivate), 1);
hostx_load_keymap();
if (!ephyrKeySyms.map) {
ErrorF("Couldn't load keymap from host\n");
@@ -1140,7 +1140,7 @@ EphyrKeyboardInit (KdKeyboardInfo *ki)
}
ki->minScanCode = ephyrKeySyms.minKeyCode;
ki->maxScanCode = ephyrKeySyms.maxKeyCode;
- xfree(ki->name);
+ free(ki->name);
ki->name = strdup("Xephyr virtual keyboard");
ephyrKbd = ki;
return Success;
diff --git a/xorg-server/hw/kdrive/ephyr/ephyr_draw.c b/xorg-server/hw/kdrive/ephyr/ephyr_draw.c
index f9fac8007..f3e2be6eb 100644
--- a/xorg-server/hw/kdrive/ephyr/ephyr_draw.c
+++ b/xorg-server/hw/kdrive/ephyr/ephyr_draw.c
@@ -1,524 +1,523 @@
-/*
- * Copyright © 2006 Intel Corporation
- *
- * 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 (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- * Eric Anholt <eric@anholt.net>
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <kdrive-config.h>
-#endif
-
-#include "ephyr.h"
-#include "exa_priv.h"
-#include "fbpict.h"
-
-#define EPHYR_TRACE_DRAW 0
-
-#if EPHYR_TRACE_DRAW
-#define TRACE_DRAW() ErrorF("%s\n", __FUNCTION__);
-#else
-#define TRACE_DRAW() do { } while (0)
-#endif
-
-/* Use some oddball alignments, to expose issues in alignment handling in EXA. */
-#define EPHYR_OFFSET_ALIGN 24
-#define EPHYR_PITCH_ALIGN 24
-
-#define EPHYR_OFFSCREEN_SIZE (16 * 1024 * 1024)
-#define EPHYR_OFFSCREEN_BASE (1 * 1024 * 1024)
-
-/**
- * Forces a real devPrivate.ptr for hidden pixmaps, so that we can call down to
- * fb functions.
- */
-static void
-ephyrPreparePipelinedAccess(PixmapPtr pPix, int index)
-{
- KdScreenPriv(pPix->drawable.pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- EphyrScrPriv *scrpriv = screen->driver;
- EphyrFakexaPriv *fakexa = scrpriv->fakexa;
-
- assert(fakexa->saved_ptrs[index] == NULL);
- fakexa->saved_ptrs[index] = pPix->devPrivate.ptr;
-
- if (pPix->devPrivate.ptr != NULL)
- return;
-
- pPix->devPrivate.ptr = fakexa->exa->memoryBase + exaGetPixmapOffset(pPix);
-}
-
-/**
- * Restores the original devPrivate.ptr of the pixmap from before we messed with
- * it.
- */
-static void
-ephyrFinishPipelinedAccess(PixmapPtr pPix, int index)
-{
- KdScreenPriv(pPix->drawable.pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- EphyrScrPriv *scrpriv = screen->driver;
- EphyrFakexaPriv *fakexa = scrpriv->fakexa;
-
- pPix->devPrivate.ptr = fakexa->saved_ptrs[index];
- fakexa->saved_ptrs[index] = NULL;
-}
-
-/**
- * Sets up a scratch GC for fbFill, and saves other parameters for the
- * ephyrSolid implementation.
- */
-static Bool
-ephyrPrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg)
-{
- ScreenPtr pScreen = pPix->drawable.pScreen;
- KdScreenPriv(pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- EphyrScrPriv *scrpriv = screen->driver;
- EphyrFakexaPriv *fakexa = scrpriv->fakexa;
- CARD32 tmpval[3];
-
- ephyrPreparePipelinedAccess(pPix, EXA_PREPARE_DEST);
-
- fakexa->pDst = pPix;
- fakexa->pGC = GetScratchGC(pPix->drawable.depth, pScreen);
-
- tmpval[0] = alu;
- tmpval[1] = pm;
- tmpval[2] = fg;
- ChangeGC(fakexa->pGC, GCFunction | GCPlaneMask | GCForeground,
- tmpval);
-
- ValidateGC(&pPix->drawable, fakexa->pGC);
-
- TRACE_DRAW();
-
- return TRUE;
-}
-
-/**
- * Does an fbFill of the rectangle to be drawn.
- */
-static void
-ephyrSolid(PixmapPtr pPix, int x1, int y1, int x2, int y2)
-{
- ScreenPtr pScreen = pPix->drawable.pScreen;
- KdScreenPriv(pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- EphyrScrPriv *scrpriv = screen->driver;
- EphyrFakexaPriv *fakexa = scrpriv->fakexa;
-
- fbFill(&fakexa->pDst->drawable, fakexa->pGC, x1, y1, x2 - x1, y2 - y1);
-}
-
-/**
- * Cleans up the scratch GC created in ephyrPrepareSolid.
- */
-static void
-ephyrDoneSolid(PixmapPtr pPix)
-{
- ScreenPtr pScreen = pPix->drawable.pScreen;
- KdScreenPriv(pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- EphyrScrPriv *scrpriv = screen->driver;
- EphyrFakexaPriv *fakexa = scrpriv->fakexa;
-
- FreeScratchGC(fakexa->pGC);
-
- ephyrFinishPipelinedAccess(pPix, EXA_PREPARE_DEST);
-}
-
-/**
- * Sets up a scratch GC for fbCopyArea, and saves other parameters for the
- * ephyrCopy implementation.
- */
-static Bool
-ephyrPrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, int dx, int dy, int alu,
- Pixel pm)
-{
- ScreenPtr pScreen = pDst->drawable.pScreen;
- KdScreenPriv(pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- EphyrScrPriv *scrpriv = screen->driver;
- EphyrFakexaPriv *fakexa = scrpriv->fakexa;
- CARD32 tmpval[2];
-
- ephyrPreparePipelinedAccess(pDst, EXA_PREPARE_DEST);
- ephyrPreparePipelinedAccess(pSrc, EXA_PREPARE_SRC);
-
- fakexa->pSrc = pSrc;
- fakexa->pDst = pDst;
- fakexa->pGC = GetScratchGC(pDst->drawable.depth, pScreen);
-
- tmpval[0] = alu;
- tmpval[1] = pm;
- ChangeGC (fakexa->pGC, GCFunction | GCPlaneMask, tmpval);
-
- ValidateGC(&pDst->drawable, fakexa->pGC);
-
- TRACE_DRAW();
-
- return TRUE;
-}
-
-/**
- * Does an fbCopyArea to take care of the requested copy.
- */
-static void
-ephyrCopy(PixmapPtr pDst, int srcX, int srcY, int dstX, int dstY, int w, int h)
-{
- ScreenPtr pScreen = pDst->drawable.pScreen;
- KdScreenPriv(pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- EphyrScrPriv *scrpriv = screen->driver;
- EphyrFakexaPriv *fakexa = scrpriv->fakexa;
-
- fbCopyArea(&fakexa->pSrc->drawable, &fakexa->pDst->drawable, fakexa->pGC,
- srcX, srcY, w, h, dstX, dstY);
-}
-
-/**
- * Cleans up the scratch GC created in ephyrPrepareCopy.
- */
-static void
-ephyrDoneCopy(PixmapPtr pDst)
-{
- ScreenPtr pScreen = pDst->drawable.pScreen;
- KdScreenPriv(pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- EphyrScrPriv *scrpriv = screen->driver;
- EphyrFakexaPriv *fakexa = scrpriv->fakexa;
-
- FreeScratchGC (fakexa->pGC);
-
- ephyrFinishPipelinedAccess(fakexa->pSrc, EXA_PREPARE_SRC);
- ephyrFinishPipelinedAccess(fakexa->pDst, EXA_PREPARE_DEST);
-}
-
-/**
- * Reports that we can always accelerate the given operation. This may not be
- * desirable from an EXA testing standpoint -- testing the fallback paths would
- * be useful, too.
- */
-static Bool
-ephyrCheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
- PicturePtr pDstPicture)
-{
- /* Exercise the component alpha helper, so fail on this case like a normal
- * driver
- */
- if (pMaskPicture && pMaskPicture->componentAlpha && op == PictOpOver)
- return FALSE;
-
- return TRUE;
-}
-
-/**
- * Saves off the parameters for ephyrComposite.
- */
-static Bool
-ephyrPrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
- PicturePtr pDstPicture, PixmapPtr pSrc, PixmapPtr pMask,
- PixmapPtr pDst)
-{
- KdScreenPriv(pDst->drawable.pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- EphyrScrPriv *scrpriv = screen->driver;
- EphyrFakexaPriv *fakexa = scrpriv->fakexa;
-
- ephyrPreparePipelinedAccess(pDst, EXA_PREPARE_DEST);
- ephyrPreparePipelinedAccess(pSrc, EXA_PREPARE_SRC);
- if (pMask != NULL)
- ephyrPreparePipelinedAccess(pMask, EXA_PREPARE_MASK);
-
- fakexa->op = op;
- fakexa->pSrcPicture = pSrcPicture;
- fakexa->pMaskPicture = pMaskPicture;
- fakexa->pDstPicture = pDstPicture;
- fakexa->pSrc = pSrc;
- fakexa->pMask = pMask;
- fakexa->pDst = pDst;
-
- TRACE_DRAW();
-
- return TRUE;
-}
-
-/**
- * Does an fbComposite to complete the requested drawing operation.
- */
-static void
-ephyrComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
- int dstX, int dstY, int w, int h)
-{
- KdScreenPriv(pDst->drawable.pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- EphyrScrPriv *scrpriv = screen->driver;
- EphyrFakexaPriv *fakexa = scrpriv->fakexa;
-
- fbComposite(fakexa->op, fakexa->pSrcPicture, fakexa->pMaskPicture,
- fakexa->pDstPicture, srcX, srcY, maskX, maskY, dstX, dstY,
- w, h);
-}
-
-static void
-ephyrDoneComposite(PixmapPtr pDst)
-{
- KdScreenPriv(pDst->drawable.pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- EphyrScrPriv *scrpriv = screen->driver;
- EphyrFakexaPriv *fakexa = scrpriv->fakexa;
-
- if (fakexa->pMask != NULL)
- ephyrFinishPipelinedAccess(fakexa->pMask, EXA_PREPARE_MASK);
- ephyrFinishPipelinedAccess(fakexa->pSrc, EXA_PREPARE_SRC);
- ephyrFinishPipelinedAccess(fakexa->pDst, EXA_PREPARE_DEST);
-}
-
-/**
- * Does fake acceleration of DownloadFromScren using memcpy.
- */
-static Bool
-ephyrDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, char *dst,
- int dst_pitch)
-{
- KdScreenPriv(pSrc->drawable.pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- EphyrScrPriv *scrpriv = screen->driver;
- EphyrFakexaPriv *fakexa = scrpriv->fakexa;
- unsigned char *src;
- int src_pitch, cpp;
-
- if (pSrc->drawable.bitsPerPixel < 8)
- return FALSE;
-
- ephyrPreparePipelinedAccess(pSrc, EXA_PREPARE_SRC);
-
- cpp = pSrc->drawable.bitsPerPixel / 8;
- src_pitch = exaGetPixmapPitch(pSrc);
- src = fakexa->exa->memoryBase + exaGetPixmapOffset(pSrc);
- src += y * src_pitch + x * cpp;
-
- for (; h > 0; h--) {
- memcpy(dst, src, w * cpp);
- dst += dst_pitch;
- src += src_pitch;
- }
-
- exaMarkSync(pSrc->drawable.pScreen);
-
- ephyrFinishPipelinedAccess(pSrc, EXA_PREPARE_SRC);
-
- return TRUE;
-}
-
-/**
- * Does fake acceleration of UploadToScreen using memcpy.
- */
-static Bool
-ephyrUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src,
- int src_pitch)
-{
- KdScreenPriv(pDst->drawable.pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- EphyrScrPriv *scrpriv = screen->driver;
- EphyrFakexaPriv *fakexa = scrpriv->fakexa;
- unsigned char *dst;
- int dst_pitch, cpp;
-
- if (pDst->drawable.bitsPerPixel < 8)
- return FALSE;
-
- ephyrPreparePipelinedAccess(pDst, EXA_PREPARE_DEST);
-
- cpp = pDst->drawable.bitsPerPixel / 8;
- dst_pitch = exaGetPixmapPitch(pDst);
- dst = fakexa->exa->memoryBase + exaGetPixmapOffset(pDst);
- dst += y * dst_pitch + x * cpp;
-
- for (; h > 0; h--) {
- memcpy(dst, src, w * cpp);
- dst += dst_pitch;
- src += src_pitch;
- }
-
- exaMarkSync(pDst->drawable.pScreen);
-
- ephyrFinishPipelinedAccess(pDst, EXA_PREPARE_DEST);
-
- return TRUE;
-}
-
-static Bool
-ephyrPrepareAccess(PixmapPtr pPix, int index)
-{
- /* Make sure we don't somehow end up with a pointer that is in framebuffer
- * and hasn't been readied for us.
- */
- assert(pPix->devPrivate.ptr != NULL);
-
- return TRUE;
-}
-
-/**
- * In fakexa, we currently only track whether we have synced to the latest
- * "accelerated" drawing that has happened or not. It's not used for anything
- * yet.
- */
-static int
-ephyrMarkSync(ScreenPtr pScreen)
-{
- KdScreenPriv(pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- EphyrScrPriv *scrpriv = screen->driver;
- EphyrFakexaPriv *fakexa = scrpriv->fakexa;
-
- fakexa->is_synced = FALSE;
-
- return 0;
-}
-
-/**
- * Assumes that we're waiting on the latest marker. When EXA gets smarter and
- * starts using markers in a fine-grained way (for example, waiting on drawing
- * to required pixmaps to complete, rather than waiting for all drawing to
- * complete), we'll want to make the ephyrMarkSync/ephyrWaitMarker
- * implementation fine-grained as well.
- */
-static void
-ephyrWaitMarker(ScreenPtr pScreen, int marker)
-{
- KdScreenPriv(pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- EphyrScrPriv *scrpriv = screen->driver;
- EphyrFakexaPriv *fakexa = scrpriv->fakexa;
-
- fakexa->is_synced = TRUE;
-}
-
-/**
- * This function initializes EXA to use the fake acceleration implementation
- * which just falls through to software. The purpose is to have a reliable,
- * correct driver with which to test changes to the EXA core.
- */
-Bool
-ephyrDrawInit(ScreenPtr pScreen)
-{
- KdScreenPriv(pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- EphyrScrPriv *scrpriv = screen->driver;
- EphyrPriv *priv = screen->card->driver;
- EphyrFakexaPriv *fakexa;
- Bool success;
-
- fakexa = xcalloc(1, sizeof(*fakexa));
- if (fakexa == NULL)
- return FALSE;
-
- fakexa->exa = exaDriverAlloc();
- if (fakexa->exa == NULL) {
- xfree(fakexa);
- return FALSE;
- }
-
- fakexa->exa->memoryBase = (CARD8 *) (priv->base);
- fakexa->exa->memorySize = priv->bytes_per_line * ephyrBufferHeight(screen);
- fakexa->exa->offScreenBase = priv->bytes_per_line * screen->height;
-
- /* Since we statically link against EXA, we shouldn't have to be smart about
- * versioning.
- */
- fakexa->exa->exa_major = 2;
- fakexa->exa->exa_minor = 0;
-
- fakexa->exa->PrepareSolid = ephyrPrepareSolid;
- fakexa->exa->Solid = ephyrSolid;
- fakexa->exa->DoneSolid = ephyrDoneSolid;
-
- fakexa->exa->PrepareCopy = ephyrPrepareCopy;
- fakexa->exa->Copy = ephyrCopy;
- fakexa->exa->DoneCopy = ephyrDoneCopy;
-
- fakexa->exa->CheckComposite = ephyrCheckComposite;
- fakexa->exa->PrepareComposite = ephyrPrepareComposite;
- fakexa->exa->Composite = ephyrComposite;
- fakexa->exa->DoneComposite = ephyrDoneComposite;
-
- fakexa->exa->DownloadFromScreen = ephyrDownloadFromScreen;
- fakexa->exa->UploadToScreen = ephyrUploadToScreen;
-
- fakexa->exa->MarkSync = ephyrMarkSync;
- fakexa->exa->WaitMarker = ephyrWaitMarker;
-
- fakexa->exa->PrepareAccess = ephyrPrepareAccess;
-
- fakexa->exa->pixmapOffsetAlign = EPHYR_OFFSET_ALIGN;
- fakexa->exa->pixmapPitchAlign = EPHYR_PITCH_ALIGN;
-
- fakexa->exa->maxX = 1023;
- fakexa->exa->maxY = 1023;
-
- fakexa->exa->flags = EXA_OFFSCREEN_PIXMAPS;
-
- success = exaDriverInit(pScreen, fakexa->exa);
- if (success) {
- ErrorF("Initialized fake EXA acceleration\n");
- scrpriv->fakexa = fakexa;
- } else {
- ErrorF("Failed to initialize EXA\n");
- xfree(fakexa->exa);
- xfree(fakexa);
- }
-
- return success;
-}
-
-void
-ephyrDrawEnable(ScreenPtr pScreen)
-{
-}
-
-void
-ephyrDrawDisable(ScreenPtr pScreen)
-{
-}
-
-void
-ephyrDrawFini(ScreenPtr pScreen)
-{
-}
-
-/**
- * exaDDXDriverInit is required by the top-level EXA module, and is used by
- * the xorg DDX to hook in its EnableDisableFB wrapper. We don't need it, since
- * we won't be enabling/disabling the FB.
- */
-void
-exaDDXDriverInit(ScreenPtr pScreen)
-{
- ExaScreenPriv(pScreen);
-
- pExaScr->migration = ExaMigrationSmart;
- pExaScr->checkDirtyCorrectness = TRUE;
-}
+/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+
+#include "ephyr.h"
+#include "exa_priv.h"
+#include "fbpict.h"
+
+#define EPHYR_TRACE_DRAW 0
+
+#if EPHYR_TRACE_DRAW
+#define TRACE_DRAW() ErrorF("%s\n", __FUNCTION__);
+#else
+#define TRACE_DRAW() do { } while (0)
+#endif
+
+/* Use some oddball alignments, to expose issues in alignment handling in EXA. */
+#define EPHYR_OFFSET_ALIGN 24
+#define EPHYR_PITCH_ALIGN 24
+
+#define EPHYR_OFFSCREEN_SIZE (16 * 1024 * 1024)
+#define EPHYR_OFFSCREEN_BASE (1 * 1024 * 1024)
+
+/**
+ * Forces a real devPrivate.ptr for hidden pixmaps, so that we can call down to
+ * fb functions.
+ */
+static void
+ephyrPreparePipelinedAccess(PixmapPtr pPix, int index)
+{
+ KdScreenPriv(pPix->drawable.pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+
+ assert(fakexa->saved_ptrs[index] == NULL);
+ fakexa->saved_ptrs[index] = pPix->devPrivate.ptr;
+
+ if (pPix->devPrivate.ptr != NULL)
+ return;
+
+ pPix->devPrivate.ptr = fakexa->exa->memoryBase + exaGetPixmapOffset(pPix);
+}
+
+/**
+ * Restores the original devPrivate.ptr of the pixmap from before we messed with
+ * it.
+ */
+static void
+ephyrFinishPipelinedAccess(PixmapPtr pPix, int index)
+{
+ KdScreenPriv(pPix->drawable.pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+
+ pPix->devPrivate.ptr = fakexa->saved_ptrs[index];
+ fakexa->saved_ptrs[index] = NULL;
+}
+
+/**
+ * Sets up a scratch GC for fbFill, and saves other parameters for the
+ * ephyrSolid implementation.
+ */
+static Bool
+ephyrPrepareSolid(PixmapPtr pPix, int alu, Pixel pm, Pixel fg)
+{
+ ScreenPtr pScreen = pPix->drawable.pScreen;
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+ ChangeGCVal tmpval[3];
+
+ ephyrPreparePipelinedAccess(pPix, EXA_PREPARE_DEST);
+
+ fakexa->pDst = pPix;
+ fakexa->pGC = GetScratchGC(pPix->drawable.depth, pScreen);
+
+ tmpval[0].val = alu;
+ tmpval[1].val = pm;
+ tmpval[2].val = fg;
+ ChangeGC(NullClient, fakexa->pGC, GCFunction | GCPlaneMask | GCForeground, tmpval);
+
+ ValidateGC(&pPix->drawable, fakexa->pGC);
+
+ TRACE_DRAW();
+
+ return TRUE;
+}
+
+/**
+ * Does an fbFill of the rectangle to be drawn.
+ */
+static void
+ephyrSolid(PixmapPtr pPix, int x1, int y1, int x2, int y2)
+{
+ ScreenPtr pScreen = pPix->drawable.pScreen;
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+
+ fbFill(&fakexa->pDst->drawable, fakexa->pGC, x1, y1, x2 - x1, y2 - y1);
+}
+
+/**
+ * Cleans up the scratch GC created in ephyrPrepareSolid.
+ */
+static void
+ephyrDoneSolid(PixmapPtr pPix)
+{
+ ScreenPtr pScreen = pPix->drawable.pScreen;
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+
+ FreeScratchGC(fakexa->pGC);
+
+ ephyrFinishPipelinedAccess(pPix, EXA_PREPARE_DEST);
+}
+
+/**
+ * Sets up a scratch GC for fbCopyArea, and saves other parameters for the
+ * ephyrCopy implementation.
+ */
+static Bool
+ephyrPrepareCopy(PixmapPtr pSrc, PixmapPtr pDst, int dx, int dy, int alu,
+ Pixel pm)
+{
+ ScreenPtr pScreen = pDst->drawable.pScreen;
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+ ChangeGCVal tmpval[2];
+
+ ephyrPreparePipelinedAccess(pDst, EXA_PREPARE_DEST);
+ ephyrPreparePipelinedAccess(pSrc, EXA_PREPARE_SRC);
+
+ fakexa->pSrc = pSrc;
+ fakexa->pDst = pDst;
+ fakexa->pGC = GetScratchGC(pDst->drawable.depth, pScreen);
+
+ tmpval[0].val = alu;
+ tmpval[1].val = pm;
+ ChangeGC (NullClient, fakexa->pGC, GCFunction | GCPlaneMask, tmpval);
+
+ ValidateGC(&pDst->drawable, fakexa->pGC);
+
+ TRACE_DRAW();
+
+ return TRUE;
+}
+
+/**
+ * Does an fbCopyArea to take care of the requested copy.
+ */
+static void
+ephyrCopy(PixmapPtr pDst, int srcX, int srcY, int dstX, int dstY, int w, int h)
+{
+ ScreenPtr pScreen = pDst->drawable.pScreen;
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+
+ fbCopyArea(&fakexa->pSrc->drawable, &fakexa->pDst->drawable, fakexa->pGC,
+ srcX, srcY, w, h, dstX, dstY);
+}
+
+/**
+ * Cleans up the scratch GC created in ephyrPrepareCopy.
+ */
+static void
+ephyrDoneCopy(PixmapPtr pDst)
+{
+ ScreenPtr pScreen = pDst->drawable.pScreen;
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+
+ FreeScratchGC (fakexa->pGC);
+
+ ephyrFinishPipelinedAccess(fakexa->pSrc, EXA_PREPARE_SRC);
+ ephyrFinishPipelinedAccess(fakexa->pDst, EXA_PREPARE_DEST);
+}
+
+/**
+ * Reports that we can always accelerate the given operation. This may not be
+ * desirable from an EXA testing standpoint -- testing the fallback paths would
+ * be useful, too.
+ */
+static Bool
+ephyrCheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
+ PicturePtr pDstPicture)
+{
+ /* Exercise the component alpha helper, so fail on this case like a normal
+ * driver
+ */
+ if (pMaskPicture && pMaskPicture->componentAlpha && op == PictOpOver)
+ return FALSE;
+
+ return TRUE;
+}
+
+/**
+ * Saves off the parameters for ephyrComposite.
+ */
+static Bool
+ephyrPrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
+ PicturePtr pDstPicture, PixmapPtr pSrc, PixmapPtr pMask,
+ PixmapPtr pDst)
+{
+ KdScreenPriv(pDst->drawable.pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+
+ ephyrPreparePipelinedAccess(pDst, EXA_PREPARE_DEST);
+ ephyrPreparePipelinedAccess(pSrc, EXA_PREPARE_SRC);
+ if (pMask != NULL)
+ ephyrPreparePipelinedAccess(pMask, EXA_PREPARE_MASK);
+
+ fakexa->op = op;
+ fakexa->pSrcPicture = pSrcPicture;
+ fakexa->pMaskPicture = pMaskPicture;
+ fakexa->pDstPicture = pDstPicture;
+ fakexa->pSrc = pSrc;
+ fakexa->pMask = pMask;
+ fakexa->pDst = pDst;
+
+ TRACE_DRAW();
+
+ return TRUE;
+}
+
+/**
+ * Does an fbComposite to complete the requested drawing operation.
+ */
+static void
+ephyrComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
+ int dstX, int dstY, int w, int h)
+{
+ KdScreenPriv(pDst->drawable.pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+
+ fbComposite(fakexa->op, fakexa->pSrcPicture, fakexa->pMaskPicture,
+ fakexa->pDstPicture, srcX, srcY, maskX, maskY, dstX, dstY,
+ w, h);
+}
+
+static void
+ephyrDoneComposite(PixmapPtr pDst)
+{
+ KdScreenPriv(pDst->drawable.pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+
+ if (fakexa->pMask != NULL)
+ ephyrFinishPipelinedAccess(fakexa->pMask, EXA_PREPARE_MASK);
+ ephyrFinishPipelinedAccess(fakexa->pSrc, EXA_PREPARE_SRC);
+ ephyrFinishPipelinedAccess(fakexa->pDst, EXA_PREPARE_DEST);
+}
+
+/**
+ * Does fake acceleration of DownloadFromScren using memcpy.
+ */
+static Bool
+ephyrDownloadFromScreen(PixmapPtr pSrc, int x, int y, int w, int h, char *dst,
+ int dst_pitch)
+{
+ KdScreenPriv(pSrc->drawable.pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+ unsigned char *src;
+ int src_pitch, cpp;
+
+ if (pSrc->drawable.bitsPerPixel < 8)
+ return FALSE;
+
+ ephyrPreparePipelinedAccess(pSrc, EXA_PREPARE_SRC);
+
+ cpp = pSrc->drawable.bitsPerPixel / 8;
+ src_pitch = exaGetPixmapPitch(pSrc);
+ src = fakexa->exa->memoryBase + exaGetPixmapOffset(pSrc);
+ src += y * src_pitch + x * cpp;
+
+ for (; h > 0; h--) {
+ memcpy(dst, src, w * cpp);
+ dst += dst_pitch;
+ src += src_pitch;
+ }
+
+ exaMarkSync(pSrc->drawable.pScreen);
+
+ ephyrFinishPipelinedAccess(pSrc, EXA_PREPARE_SRC);
+
+ return TRUE;
+}
+
+/**
+ * Does fake acceleration of UploadToScreen using memcpy.
+ */
+static Bool
+ephyrUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h, char *src,
+ int src_pitch)
+{
+ KdScreenPriv(pDst->drawable.pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+ unsigned char *dst;
+ int dst_pitch, cpp;
+
+ if (pDst->drawable.bitsPerPixel < 8)
+ return FALSE;
+
+ ephyrPreparePipelinedAccess(pDst, EXA_PREPARE_DEST);
+
+ cpp = pDst->drawable.bitsPerPixel / 8;
+ dst_pitch = exaGetPixmapPitch(pDst);
+ dst = fakexa->exa->memoryBase + exaGetPixmapOffset(pDst);
+ dst += y * dst_pitch + x * cpp;
+
+ for (; h > 0; h--) {
+ memcpy(dst, src, w * cpp);
+ dst += dst_pitch;
+ src += src_pitch;
+ }
+
+ exaMarkSync(pDst->drawable.pScreen);
+
+ ephyrFinishPipelinedAccess(pDst, EXA_PREPARE_DEST);
+
+ return TRUE;
+}
+
+static Bool
+ephyrPrepareAccess(PixmapPtr pPix, int index)
+{
+ /* Make sure we don't somehow end up with a pointer that is in framebuffer
+ * and hasn't been readied for us.
+ */
+ assert(pPix->devPrivate.ptr != NULL);
+
+ return TRUE;
+}
+
+/**
+ * In fakexa, we currently only track whether we have synced to the latest
+ * "accelerated" drawing that has happened or not. It's not used for anything
+ * yet.
+ */
+static int
+ephyrMarkSync(ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+
+ fakexa->is_synced = FALSE;
+
+ return 0;
+}
+
+/**
+ * Assumes that we're waiting on the latest marker. When EXA gets smarter and
+ * starts using markers in a fine-grained way (for example, waiting on drawing
+ * to required pixmaps to complete, rather than waiting for all drawing to
+ * complete), we'll want to make the ephyrMarkSync/ephyrWaitMarker
+ * implementation fine-grained as well.
+ */
+static void
+ephyrWaitMarker(ScreenPtr pScreen, int marker)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrFakexaPriv *fakexa = scrpriv->fakexa;
+
+ fakexa->is_synced = TRUE;
+}
+
+/**
+ * This function initializes EXA to use the fake acceleration implementation
+ * which just falls through to software. The purpose is to have a reliable,
+ * correct driver with which to test changes to the EXA core.
+ */
+Bool
+ephyrDrawInit(ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrPriv *priv = screen->card->driver;
+ EphyrFakexaPriv *fakexa;
+ Bool success;
+
+ fakexa = calloc(1, sizeof(*fakexa));
+ if (fakexa == NULL)
+ return FALSE;
+
+ fakexa->exa = exaDriverAlloc();
+ if (fakexa->exa == NULL) {
+ free(fakexa);
+ return FALSE;
+ }
+
+ fakexa->exa->memoryBase = (CARD8 *) (priv->base);
+ fakexa->exa->memorySize = priv->bytes_per_line * ephyrBufferHeight(screen);
+ fakexa->exa->offScreenBase = priv->bytes_per_line * screen->height;
+
+ /* Since we statically link against EXA, we shouldn't have to be smart about
+ * versioning.
+ */
+ fakexa->exa->exa_major = 2;
+ fakexa->exa->exa_minor = 0;
+
+ fakexa->exa->PrepareSolid = ephyrPrepareSolid;
+ fakexa->exa->Solid = ephyrSolid;
+ fakexa->exa->DoneSolid = ephyrDoneSolid;
+
+ fakexa->exa->PrepareCopy = ephyrPrepareCopy;
+ fakexa->exa->Copy = ephyrCopy;
+ fakexa->exa->DoneCopy = ephyrDoneCopy;
+
+ fakexa->exa->CheckComposite = ephyrCheckComposite;
+ fakexa->exa->PrepareComposite = ephyrPrepareComposite;
+ fakexa->exa->Composite = ephyrComposite;
+ fakexa->exa->DoneComposite = ephyrDoneComposite;
+
+ fakexa->exa->DownloadFromScreen = ephyrDownloadFromScreen;
+ fakexa->exa->UploadToScreen = ephyrUploadToScreen;
+
+ fakexa->exa->MarkSync = ephyrMarkSync;
+ fakexa->exa->WaitMarker = ephyrWaitMarker;
+
+ fakexa->exa->PrepareAccess = ephyrPrepareAccess;
+
+ fakexa->exa->pixmapOffsetAlign = EPHYR_OFFSET_ALIGN;
+ fakexa->exa->pixmapPitchAlign = EPHYR_PITCH_ALIGN;
+
+ fakexa->exa->maxX = 1023;
+ fakexa->exa->maxY = 1023;
+
+ fakexa->exa->flags = EXA_OFFSCREEN_PIXMAPS;
+
+ success = exaDriverInit(pScreen, fakexa->exa);
+ if (success) {
+ ErrorF("Initialized fake EXA acceleration\n");
+ scrpriv->fakexa = fakexa;
+ } else {
+ ErrorF("Failed to initialize EXA\n");
+ free(fakexa->exa);
+ free(fakexa);
+ }
+
+ return success;
+}
+
+void
+ephyrDrawEnable(ScreenPtr pScreen)
+{
+}
+
+void
+ephyrDrawDisable(ScreenPtr pScreen)
+{
+}
+
+void
+ephyrDrawFini(ScreenPtr pScreen)
+{
+}
+
+/**
+ * exaDDXDriverInit is required by the top-level EXA module, and is used by
+ * the xorg DDX to hook in its EnableDisableFB wrapper. We don't need it, since
+ * we won't be enabling/disabling the FB.
+ */
+void
+exaDDXDriverInit(ScreenPtr pScreen)
+{
+ ExaScreenPriv(pScreen);
+
+ pExaScr->migration = ExaMigrationSmart;
+ pExaScr->checkDirtyCorrectness = TRUE;
+}
diff --git a/xorg-server/hw/kdrive/ephyr/ephyrdriext.c b/xorg-server/hw/kdrive/ephyr/ephyrdriext.c
index 5f5fd3bff..3d3d18a39 100644
--- a/xorg-server/hw/kdrive/ephyr/ephyrdriext.c
+++ b/xorg-server/hw/kdrive/ephyr/ephyrdriext.c
@@ -1,1429 +1,1429 @@
-/*
- * Xephyr - A kdrive X server thats runs in a host X window.
- * Authored by Matthew Allum <mallum@openedhand.com>
- *
- * Copyright © 2007 OpenedHand Ltd
- *
- * 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 OpenedHand Ltd not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. OpenedHand Ltd makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL OpenedHand Ltd 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.
- *
- * This file is heavily copied from hw/xfree86/dri/xf86dri.c
- *
- * Authors:
- * Dodji Seketeli <dodji@openedhand.com>
- */
-
-#ifdef HAVE_CONFIG_H
-#include <kdrive-config.h>
-#endif
-
-#include <string.h>
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#define _XF86DRI_SERVER_
-#include <X11/dri/xf86dri.h>
-#include <X11/dri/xf86driproto.h>
-#include "misc.h"
-#include "privates.h"
-#include "dixstruct.h"
-#include "extnsionst.h"
-#include "colormapst.h"
-#include "cursorstr.h"
-#include "scrnintstr.h"
-#include "windowstr.h"
-#include "servermd.h"
-#include "swaprep.h"
-#include "ephyrdri.h"
-#include "ephyrdriext.h"
-#include "hostx.h"
-#define _HAVE_XALLOC_DECLS
-#include "ephyrlog.h"
-#include "protocol-versions.h"
-
-typedef struct {
- int foo;
-} EphyrDRIWindowPrivRec;
-typedef EphyrDRIWindowPrivRec* EphyrDRIWindowPrivPtr;
-
-typedef struct {
- CreateWindowProcPtr CreateWindow ;
- DestroyWindowProcPtr DestroyWindow ;
- MoveWindowProcPtr MoveWindow ;
- PositionWindowProcPtr PositionWindow ;
- ClipNotifyProcPtr ClipNotify ;
-} EphyrDRIScreenPrivRec;
-typedef EphyrDRIScreenPrivRec* EphyrDRIScreenPrivPtr;
-
-static int DRIErrorBase;
-
-static DISPATCH_PROC(ProcXF86DRIQueryVersion);
-static DISPATCH_PROC(ProcXF86DRIQueryDirectRenderingCapable);
-static DISPATCH_PROC(ProcXF86DRIOpenConnection);
-static DISPATCH_PROC(ProcXF86DRICloseConnection);
-static DISPATCH_PROC(ProcXF86DRIGetClientDriverName);
-static DISPATCH_PROC(ProcXF86DRICreateContext);
-static DISPATCH_PROC(ProcXF86DRIDestroyContext);
-static DISPATCH_PROC(ProcXF86DRICreateDrawable);
-static DISPATCH_PROC(ProcXF86DRIDestroyDrawable);
-static DISPATCH_PROC(ProcXF86DRIGetDrawableInfo);
-static DISPATCH_PROC(ProcXF86DRIGetDeviceInfo);
-static DISPATCH_PROC(ProcXF86DRIDispatch);
-static DISPATCH_PROC(ProcXF86DRIAuthConnection);
-
-static DISPATCH_PROC(SProcXF86DRIQueryVersion);
-static DISPATCH_PROC(SProcXF86DRIQueryDirectRenderingCapable);
-static DISPATCH_PROC(SProcXF86DRIDispatch);
-
-static Bool ephyrDRIScreenInit (ScreenPtr a_screen) ;
-static Bool ephyrDRICreateWindow (WindowPtr a_win) ;
-static Bool ephyrDRIDestroyWindow (WindowPtr a_win) ;
-static void ephyrDRIMoveWindow (WindowPtr a_win,
- int a_x, int a_y,
- WindowPtr a_siblings,
- VTKind a_kind);
-static Bool ephyrDRIPositionWindow (WindowPtr a_win,
- int x, int y) ;
-static void ephyrDRIClipNotify (WindowPtr a_win,
- int a_x, int a_y) ;
-
-static Bool EphyrMirrorHostVisuals (ScreenPtr a_screen) ;
-static Bool destroyHostPeerWindow (const WindowPtr a_win) ;
-static Bool findWindowPairFromLocal (WindowPtr a_local,
- EphyrWindowPair **a_pair);
-
-static unsigned char DRIReqCode = 0;
-
-static int ephyrDRIWindowKeyIndex;
-static DevPrivateKey ephyrDRIWindowKey = &ephyrDRIWindowKeyIndex;
-static int ephyrDRIScreenKeyIndex;
-static DevPrivateKey ephyrDRIScreenKey = &ephyrDRIScreenKeyIndex;
-
-#define GET_EPHYR_DRI_WINDOW_PRIV(win) ((EphyrDRIWindowPrivPtr) \
- dixLookupPrivate(&(win)->devPrivates, ephyrDRIWindowKey))
-#define GET_EPHYR_DRI_SCREEN_PRIV(screen) ((EphyrDRIScreenPrivPtr) \
- dixLookupPrivate(&(screen)->devPrivates, ephyrDRIScreenKey))
-
-
-Bool
-ephyrDRIExtensionInit (ScreenPtr a_screen)
-{
- Bool is_ok=FALSE ;
- ExtensionEntry* extEntry=NULL;
- EphyrDRIScreenPrivPtr screen_priv=NULL ;
-
- EPHYR_LOG ("enter\n") ;
- if (!hostx_has_dri ()) {
- EPHYR_LOG ("host does not have DRI extension\n") ;
- goto out ;
- }
- EPHYR_LOG ("host X does have DRI extension\n") ;
- if (!hostx_has_xshape ()) {
- EPHYR_LOG ("host does not have XShape extension\n") ;
- goto out ;
- }
- EPHYR_LOG ("host X does have XShape extension\n") ;
-
-#ifdef XF86DRI_EVENTS
- EventType = CreateNewResourceType (XF86DRIFreeEvents, "DRIEvents");
- if (!EventType) {
- EPHYR_LOG_ERROR ("failed to register DRI event resource type\n") ;
- goto out ;
- }
-#endif
-
- if ((extEntry = AddExtension(XF86DRINAME,
- XF86DRINumberEvents,
- XF86DRINumberErrors,
- ProcXF86DRIDispatch,
- SProcXF86DRIDispatch,
- NULL,
- StandardMinorOpcode))) {
- DRIReqCode = (unsigned char)extEntry->base;
- DRIErrorBase = extEntry->errorBase;
- } else {
- EPHYR_LOG_ERROR ("failed to register DRI extension\n") ;
- goto out ;
- }
- screen_priv = xcalloc (1, sizeof (EphyrDRIScreenPrivRec)) ;
- if (!screen_priv) {
- EPHYR_LOG_ERROR ("failed to allocate screen_priv\n") ;
- goto out ;
- }
- dixSetPrivate(&a_screen->devPrivates, ephyrDRIScreenKey, screen_priv);
-
- if (!ephyrDRIScreenInit (a_screen)) {
- EPHYR_LOG_ERROR ("ephyrDRIScreenInit() failed\n") ;
- goto out ;
- }
- EphyrMirrorHostVisuals (a_screen) ;
- is_ok=TRUE ;
-out:
- EPHYR_LOG ("leave\n") ;
- return is_ok ;
-}
-
-static Bool
-ephyrDRIScreenInit (ScreenPtr a_screen)
-{
- Bool is_ok=FALSE ;
- EphyrDRIScreenPrivPtr screen_priv=NULL ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_screen, FALSE) ;
-
- screen_priv=GET_EPHYR_DRI_SCREEN_PRIV (a_screen) ;
- EPHYR_RETURN_VAL_IF_FAIL (screen_priv, FALSE) ;
-
- screen_priv->CreateWindow = a_screen->CreateWindow ;
- screen_priv->DestroyWindow = a_screen->DestroyWindow ;
- screen_priv->MoveWindow = a_screen->MoveWindow ;
- screen_priv->PositionWindow = a_screen->PositionWindow ;
- screen_priv->ClipNotify = a_screen->ClipNotify ;
-
- a_screen->CreateWindow = ephyrDRICreateWindow ;
- a_screen->DestroyWindow = ephyrDRIDestroyWindow ;
- a_screen->MoveWindow = ephyrDRIMoveWindow ;
- a_screen->PositionWindow = ephyrDRIPositionWindow ;
- a_screen->ClipNotify = ephyrDRIClipNotify ;
-
- is_ok = TRUE ;
-
- return is_ok ;
-}
-
-static Bool
-ephyrDRICreateWindow (WindowPtr a_win)
-{
- Bool is_ok=FALSE ;
- ScreenPtr screen=NULL ;
- EphyrDRIScreenPrivPtr screen_priv =NULL;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ;
- screen = a_win->drawable.pScreen ;
- EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ;
- screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
- EPHYR_RETURN_VAL_IF_FAIL (screen_priv
- && screen_priv->CreateWindow,
- FALSE) ;
-
- EPHYR_LOG ("enter. win:%p\n", a_win) ;
-
- screen->CreateWindow = screen_priv->CreateWindow ;
- is_ok = (*screen->CreateWindow) (a_win) ;
- screen->CreateWindow = ephyrDRICreateWindow ;
-
- if (is_ok) {
- dixSetPrivate(&a_win->devPrivates, ephyrDRIWindowKey, NULL);
- }
- return is_ok ;
-}
-
-static Bool
-ephyrDRIDestroyWindow (WindowPtr a_win)
-{
- Bool is_ok=FALSE ;
- ScreenPtr screen=NULL ;
- EphyrDRIScreenPrivPtr screen_priv =NULL;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ;
- screen = a_win->drawable.pScreen ;
- EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ;
- screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
- EPHYR_RETURN_VAL_IF_FAIL (screen_priv
- && screen_priv->DestroyWindow,
- FALSE) ;
-
- screen->DestroyWindow = screen_priv->DestroyWindow ;
- if (screen->DestroyWindow) {
- is_ok = (*screen->DestroyWindow) (a_win) ;
- }
- screen->DestroyWindow = ephyrDRIDestroyWindow ;
-
- if (is_ok) {
- EphyrDRIWindowPrivPtr win_priv=GET_EPHYR_DRI_WINDOW_PRIV (a_win) ;
- if (win_priv) {
- destroyHostPeerWindow (a_win) ;
- xfree (win_priv) ;
- dixSetPrivate(&a_win->devPrivates, ephyrDRIWindowKey, NULL);
- EPHYR_LOG ("destroyed the remote peer window\n") ;
- }
- }
- return is_ok ;
-}
-
-static void
-ephyrDRIMoveWindow (WindowPtr a_win,
- int a_x, int a_y,
- WindowPtr a_siblings,
- VTKind a_kind)
-{
- Bool is_ok=FALSE ;
- ScreenPtr screen=NULL ;
- EphyrDRIScreenPrivPtr screen_priv =NULL;
- EphyrDRIWindowPrivPtr win_priv=NULL ;
- EphyrWindowPair *pair=NULL ;
- EphyrBox geo;
- int x=0,y=0;/*coords relative to parent window*/
-
- EPHYR_RETURN_IF_FAIL (a_win) ;
-
- EPHYR_LOG ("enter\n") ;
- screen = a_win->drawable.pScreen ;
- EPHYR_RETURN_IF_FAIL (screen) ;
- screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
- EPHYR_RETURN_IF_FAIL (screen_priv
- && screen_priv->MoveWindow) ;
-
- screen->MoveWindow = screen_priv->MoveWindow ;
- if (screen->MoveWindow) {
- (*screen->MoveWindow) (a_win, a_x, a_y, a_siblings, a_kind) ;
- }
- screen->MoveWindow = ephyrDRIMoveWindow ;
-
- EPHYR_LOG ("window: %p\n", a_win) ;
- if (!a_win->parent) {
- EPHYR_LOG ("cannot move root window\n") ;
- is_ok = TRUE ;
- goto out ;
- }
- win_priv = GET_EPHYR_DRI_WINDOW_PRIV (a_win) ;
- if (!win_priv) {
- EPHYR_LOG ("not a DRI peered window\n") ;
- is_ok = TRUE ;
- goto out ;
- }
- if (!findWindowPairFromLocal (a_win, &pair) || !pair) {
- EPHYR_LOG_ERROR ("failed to get window pair\n") ;
- goto out ;
- }
- /*compute position relative to parent window*/
- x = a_win->drawable.x - a_win->parent->drawable.x ;
- y = a_win->drawable.y - a_win->parent->drawable.y ;
- /*set the geometry to pass to hostx_set_window_geometry*/
- memset (&geo, 0, sizeof (geo)) ;
- geo.x = x ;
- geo.y = y ;
- geo.width = a_win->drawable.width ;
- geo.height = a_win->drawable.height ;
- hostx_set_window_geometry (pair->remote, &geo) ;
- is_ok = TRUE ;
-
-out:
- EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
- /*do cleanup here*/
-}
-
-static Bool
-ephyrDRIPositionWindow (WindowPtr a_win,
- int a_x, int a_y)
-{
- Bool is_ok=FALSE ;
- ScreenPtr screen=NULL ;
- EphyrDRIScreenPrivPtr screen_priv =NULL;
- EphyrDRIWindowPrivPtr win_priv=NULL ;
- EphyrWindowPair *pair=NULL ;
- EphyrBox geo;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ;
-
- EPHYR_LOG ("enter\n") ;
- screen = a_win->drawable.pScreen ;
- EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ;
- screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
- EPHYR_RETURN_VAL_IF_FAIL (screen_priv
- && screen_priv->PositionWindow,
- FALSE) ;
-
- screen->PositionWindow = screen_priv->PositionWindow ;
- if (screen->PositionWindow) {
- (*screen->PositionWindow) (a_win, a_x, a_y) ;
- }
- screen->PositionWindow = ephyrDRIPositionWindow ;
-
- EPHYR_LOG ("window: %p\n", a_win) ;
- win_priv = GET_EPHYR_DRI_WINDOW_PRIV (a_win) ;
- if (!win_priv) {
- EPHYR_LOG ("not a DRI peered window\n") ;
- is_ok = TRUE ;
- goto out ;
- }
- if (!findWindowPairFromLocal (a_win, &pair) || !pair) {
- EPHYR_LOG_ERROR ("failed to get window pair\n") ;
- goto out ;
- }
- /*set the geometry to pass to hostx_set_window_geometry*/
- memset (&geo, 0, sizeof (geo)) ;
- geo.x = a_x ;
- geo.y = a_y ;
- geo.width = a_win->drawable.width ;
- geo.height = a_win->drawable.height ;
- hostx_set_window_geometry (pair->remote, &geo) ;
- is_ok = TRUE ;
-
-out:
- EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
- /*do cleanup here*/
- return is_ok ;
-}
-
-static void
-ephyrDRIClipNotify (WindowPtr a_win,
- int a_x, int a_y)
-{
- Bool is_ok=FALSE ;
- ScreenPtr screen=NULL ;
- EphyrDRIScreenPrivPtr screen_priv =NULL;
- EphyrDRIWindowPrivPtr win_priv=NULL ;
- EphyrWindowPair *pair=NULL ;
- EphyrRect *rects=NULL;
- int i=0 ;
-
- EPHYR_RETURN_IF_FAIL (a_win) ;
-
- EPHYR_LOG ("enter\n") ;
- screen = a_win->drawable.pScreen ;
- EPHYR_RETURN_IF_FAIL (screen) ;
- screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
- EPHYR_RETURN_IF_FAIL (screen_priv && screen_priv->ClipNotify) ;
-
- screen->ClipNotify = screen_priv->ClipNotify ;
- if (screen->ClipNotify) {
- (*screen->ClipNotify) (a_win, a_x, a_y) ;
- }
- screen->ClipNotify = ephyrDRIClipNotify ;
-
- EPHYR_LOG ("window: %p\n", a_win) ;
- win_priv = GET_EPHYR_DRI_WINDOW_PRIV (a_win) ;
- if (!win_priv) {
- EPHYR_LOG ("not a DRI peered window\n") ;
- is_ok = TRUE ;
- goto out ;
- }
- if (!findWindowPairFromLocal (a_win, &pair) || !pair) {
- EPHYR_LOG_ERROR ("failed to get window pair\n") ;
- goto out ;
- }
- rects = xcalloc (REGION_NUM_RECTS (&a_win->clipList),
- sizeof (EphyrRect)) ;
- for (i=0; i < REGION_NUM_RECTS (&a_win->clipList); i++) {
- memmove (&rects[i],
- &REGION_RECTS (&a_win->clipList)[i],
- sizeof (EphyrRect)) ;
- rects[i].x1 -= a_win->drawable.x;
- rects[i].x2 -= a_win->drawable.x;
- rects[i].y1 -= a_win->drawable.y;
- rects[i].y2 -= a_win->drawable.y;
- }
- /*
- * push the clipping region of this window
- * to the peer window in the host
- */
- is_ok = hostx_set_window_bounding_rectangles
- (pair->remote,
- rects,
- REGION_NUM_RECTS (&a_win->clipList)) ;
- is_ok = TRUE ;
-
-out:
- xfree (rects) ;
- rects = NULL ;
-
- EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
- /*do cleanup here*/
-}
-
-/**
- * Duplicates a visual of a_screen
- * In screen a_screen, for depth a_depth, find a visual which
- * bitsPerRGBValue and colormap size equal
- * a_bits_per_rgb_values and a_colormap_entries.
- * The ID of that duplicated visual is set to a_new_id.
- * That duplicated visual is then added to the list of visuals
- * of the screen.
- */
-static Bool
-EphyrDuplicateVisual (unsigned int a_screen,
- short a_depth,
- short a_class,
- short a_bits_per_rgb_values,
- short a_colormap_entries,
- unsigned int a_red_mask,
- unsigned int a_green_mask,
- unsigned int a_blue_mask,
- unsigned int a_new_id)
-{
- Bool is_ok = FALSE, found_visual=FALSE, found_depth=FALSE ;
- ScreenPtr screen=NULL ;
- VisualRec new_visual, *new_visuals=NULL ;
- int i=0 ;
-
- EPHYR_LOG ("enter\n") ;
- if (a_screen > screenInfo.numScreens) {
- EPHYR_LOG_ERROR ("bad screen number\n") ;
- goto out;
- }
- memset (&new_visual, 0, sizeof (VisualRec)) ;
-
- /*get the screen pointed to by a_screen*/
- screen = screenInfo.screens[a_screen] ;
- EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ;
-
- /*
- * In that screen, first look for an existing visual that has the
- * same characteristics as those passed in parameter
- * to this function and copy it.
- */
- for (i=0; i < screen->numVisuals; i++) {
- if (screen->visuals[i].bitsPerRGBValue == a_bits_per_rgb_values &&
- screen->visuals[i].ColormapEntries == a_colormap_entries ) {
- /*copy the visual found*/
- memcpy (&new_visual, &screen->visuals[i], sizeof (new_visual)) ;
- new_visual.vid = a_new_id ;
- new_visual.class = a_class ;
- new_visual.redMask = a_red_mask ;
- new_visual.greenMask = a_green_mask ;
- new_visual.blueMask = a_blue_mask ;
- found_visual = TRUE ;
- EPHYR_LOG ("found a visual that matches visual id: %d\n",
- a_new_id) ;
- break;
- }
- }
- if (!found_visual) {
- EPHYR_LOG ("did not find any visual matching %d\n", a_new_id) ;
- goto out ;
- }
- /*
- * be prepare to extend screen->visuals to add new_visual to it
- */
- new_visuals = xcalloc (screen->numVisuals+1, sizeof (VisualRec)) ;
- memmove (new_visuals,
- screen->visuals,
- screen->numVisuals*sizeof (VisualRec)) ;
- memmove (&new_visuals[screen->numVisuals],
- &new_visual,
- sizeof (VisualRec)) ;
- /*
- * Now, in that same screen, update the screen->allowedDepths member.
- * In that array, each element represents the visuals applicable to
- * a given depth. So we need to add an entry matching the new visual
- * that we are going to add to screen->visuals
- */
- for (i=0; i<screen->numDepths; i++) {
- VisualID *vids=NULL;
- DepthPtr cur_depth=NULL ;
- /*find the entry matching a_depth*/
- if (screen->allowedDepths[i].depth != a_depth)
- continue ;
- cur_depth = &screen->allowedDepths[i];
- /*
- * extend the list of visual IDs in that entry,
- * so to add a_new_id in there.
- */
- vids = xrealloc (cur_depth->vids,
- (cur_depth->numVids+1)*sizeof (VisualID));
- if (!vids) {
- EPHYR_LOG_ERROR ("failed to realloc numids\n") ;
- goto out ;
- }
- vids[cur_depth->numVids] = a_new_id ;
- /*
- * Okay now commit our change.
- * Do really update screen->allowedDepths[i]
- */
- cur_depth->numVids++ ;
- cur_depth->vids = vids ;
- found_depth=TRUE;
- }
- if (!found_depth) {
- EPHYR_LOG_ERROR ("failed to update screen[%d]->allowedDepth\n",
- a_screen) ;
- goto out ;
- }
- /*
- * Commit our change to screen->visuals
- */
- xfree (screen->visuals) ;
- screen->visuals = new_visuals ;
- screen->numVisuals++ ;
- new_visuals = NULL ;
-
- is_ok = TRUE ;
-out:
- xfree (new_visuals) ;
- new_visuals = NULL ;
-
- EPHYR_LOG ("leave\n") ;
- return is_ok ;
-}
-
-/**
- * Duplicates the visuals of the host X server.
- * This is necessary to have visuals that have the same
- * ID as those of the host X. It is important to have that for
- * GLX.
- */
-static Bool
-EphyrMirrorHostVisuals (ScreenPtr a_screen)
-{
- Bool is_ok=FALSE;
- EphyrHostVisualInfo *visuals=NULL;
- int nb_visuals=0, i=0;
-
- EPHYR_LOG ("enter\n") ;
- if (!hostx_get_visuals_info (&visuals, &nb_visuals)) {
- EPHYR_LOG_ERROR ("failed to get host visuals\n") ;
- goto out ;
- }
- for (i=0; i<nb_visuals; i++) {
- if (!EphyrDuplicateVisual (a_screen->myNum,
- visuals[i].depth,
- visuals[i].class,
- visuals[i].bits_per_rgb,
- visuals[i].colormap_size,
- visuals[i].red_mask,
- visuals[i].green_mask,
- visuals[i].blue_mask,
- visuals[i].visualid)) {
- EPHYR_LOG_ERROR ("failed to duplicate host visual %d\n",
- (int)visuals[i].visualid) ;
- }
- }
-
- is_ok = TRUE ;
-out:
- EPHYR_LOG ("leave\n") ;
- return is_ok;
-}
-
-
-static int
-ProcXF86DRIQueryVersion (register ClientPtr client)
-{
- xXF86DRIQueryVersionReply rep;
- register int n;
- REQUEST_SIZE_MATCH(xXF86DRIQueryVersionReq);
-
- EPHYR_LOG ("enter\n") ;
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.majorVersion = SERVER_XF86DRI_MAJOR_VERSION;
- rep.minorVersion = SERVER_XF86DRI_MINOR_VERSION;
- rep.patchVersion = SERVER_XF86DRI_PATCH_VERSION;
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swaps(&rep.majorVersion, n);
- swaps(&rep.minorVersion, n);
- swapl(&rep.patchVersion, n);
- }
- WriteToClient(client, sizeof(xXF86DRIQueryVersionReply), (char *)&rep);
- EPHYR_LOG ("leave\n") ;
- return (client->noClientException);
-}
-
-static int
-ProcXF86DRIQueryDirectRenderingCapable (register ClientPtr client)
-{
- xXF86DRIQueryDirectRenderingCapableReply rep;
- Bool isCapable;
- register int n;
- REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
- REQUEST_SIZE_MATCH(xXF86DRIQueryDirectRenderingCapableReq);
-
- EPHYR_LOG ("enter\n") ;
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- if (!ephyrDRIQueryDirectRenderingCapable (stuff->screen, &isCapable)) {
- return BadValue;
- }
- rep.isCapable = isCapable;
-
- if (!LocalClient(client) || client->swapped)
- rep.isCapable = 0;
-
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- }
-
- WriteToClient(client, sizeof(xXF86DRIQueryDirectRenderingCapableReply), (char *)&rep);
- EPHYR_LOG ("leave\n") ;
-
- return (client->noClientException);
-}
-
-static int
-ProcXF86DRIOpenConnection (register ClientPtr client)
-{
- xXF86DRIOpenConnectionReply rep;
- drm_handle_t hSAREA;
- char* busIdString;
- REQUEST(xXF86DRIOpenConnectionReq);
- REQUEST_SIZE_MATCH(xXF86DRIOpenConnectionReq);
-
- EPHYR_LOG ("enter\n") ;
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- if (!ephyrDRIOpenConnection(stuff->screen,
- &hSAREA,
- &busIdString)) {
- return BadValue;
- }
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.busIdStringLength = 0;
- if (busIdString)
- rep.busIdStringLength = strlen(busIdString);
- rep.length = bytes_to_int32(SIZEOF(xXF86DRIOpenConnectionReply) - SIZEOF(xGenericReply) +
- pad_to_int32(rep.busIdStringLength));
-
- rep.hSAREALow = (CARD32)(hSAREA & 0xffffffff);
-#if defined(LONG64) && !defined(__linux__)
- rep.hSAREAHigh = (CARD32)(hSAREA >> 32);
-#else
- rep.hSAREAHigh = 0;
-#endif
-
- WriteToClient(client, sizeof(xXF86DRIOpenConnectionReply), (char *)&rep);
- if (rep.busIdStringLength)
- WriteToClient(client, rep.busIdStringLength, busIdString);
- EPHYR_LOG ("leave\n") ;
- return (client->noClientException);
-}
-
-static int
-ProcXF86DRIAuthConnection (register ClientPtr client)
-{
- xXF86DRIAuthConnectionReply rep;
- REQUEST(xXF86DRIAuthConnectionReq);
- REQUEST_SIZE_MATCH(xXF86DRIAuthConnectionReq);
-
- EPHYR_LOG ("enter\n") ;
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.authenticated = 1;
-
- if (!ephyrDRIAuthConnection (stuff->screen, stuff->magic)) {
- ErrorF("Failed to authenticate %lu\n", (unsigned long)stuff->magic);
- rep.authenticated = 0;
- }
- WriteToClient(client, sizeof(xXF86DRIAuthConnectionReply), (char *)&rep);
- EPHYR_LOG ("leave\n") ;
- return (client->noClientException);
-}
-
-static int
-ProcXF86DRICloseConnection (register ClientPtr client)
-{
- REQUEST(xXF86DRICloseConnectionReq);
- REQUEST_SIZE_MATCH(xXF86DRICloseConnectionReq);
- EPHYR_LOG ("enter\n") ;
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- /*
- DRICloseConnection( screenInfo.screens[stuff->screen]);
- */
-
- EPHYR_LOG ("leave\n") ;
- return (client->noClientException);
-}
-
-static int
-ProcXF86DRIGetClientDriverName (register ClientPtr client)
-{
- xXF86DRIGetClientDriverNameReply rep;
- char* clientDriverName;
- REQUEST(xXF86DRIGetClientDriverNameReq);
- REQUEST_SIZE_MATCH(xXF86DRIGetClientDriverNameReq);
-
- EPHYR_LOG ("enter\n") ;
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- ephyrDRIGetClientDriverName (stuff->screen,
- (int *)&rep.ddxDriverMajorVersion,
- (int *)&rep.ddxDriverMinorVersion,
- (int *)&rep.ddxDriverPatchVersion,
- &clientDriverName);
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.clientDriverNameLength = 0;
- if (clientDriverName)
- rep.clientDriverNameLength = strlen(clientDriverName);
- rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetClientDriverNameReply) -
- SIZEOF(xGenericReply) +
- pad_to_int32(rep.clientDriverNameLength));
-
- WriteToClient(client,
- sizeof(xXF86DRIGetClientDriverNameReply), (char *)&rep);
- if (rep.clientDriverNameLength)
- WriteToClient(client,
- rep.clientDriverNameLength,
- clientDriverName);
- EPHYR_LOG ("leave\n") ;
- return (client->noClientException);
-}
-
-static int
-ProcXF86DRICreateContext (register ClientPtr client)
-{
- xXF86DRICreateContextReply rep;
- ScreenPtr pScreen;
- VisualPtr visual;
- int i=0;
- unsigned long context_id=0;
- REQUEST(xXF86DRICreateContextReq);
- REQUEST_SIZE_MATCH(xXF86DRICreateContextReq);
-
- EPHYR_LOG ("enter\n") ;
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- pScreen = screenInfo.screens[stuff->screen];
- visual = pScreen->visuals;
-
- /* Find the requested X visual */
- for (i = 0; i < pScreen->numVisuals; i++, visual++)
- if (visual->vid == stuff->visual)
- break;
- if (i == pScreen->numVisuals) {
- /* No visual found */
- return BadValue;
- }
-
- context_id = stuff->context ;
- if (!ephyrDRICreateContext (stuff->screen,
- stuff->visual,
- &context_id,
- (drm_context_t *)&rep.hHWContext)) {
- return BadValue;
- }
-
- WriteToClient(client, sizeof(xXF86DRICreateContextReply), (char *)&rep);
- EPHYR_LOG ("leave\n") ;
- return (client->noClientException);
-}
-
-static int
-ProcXF86DRIDestroyContext (register ClientPtr client)
-{
- REQUEST(xXF86DRIDestroyContextReq);
- REQUEST_SIZE_MATCH(xXF86DRIDestroyContextReq);
- EPHYR_LOG ("enter\n") ;
-
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- if (!ephyrDRIDestroyContext (stuff->screen, stuff->context)) {
- return BadValue;
- }
-
- EPHYR_LOG ("leave\n") ;
- return (client->noClientException);
-}
-
-static Bool
-getWindowVisual (const WindowPtr a_win,
- VisualPtr *a_visual)
-{
- int i=0, visual_id=0 ;
- EPHYR_RETURN_VAL_IF_FAIL (a_win
- && a_win->drawable.pScreen
- && a_win->drawable.pScreen->visuals,
- FALSE) ;
-
- visual_id = wVisual (a_win) ;
- for (i=0; i < a_win->drawable.pScreen->numVisuals; i++) {
- if (a_win->drawable.pScreen->visuals[i].vid == visual_id) {
- *a_visual = &a_win->drawable.pScreen->visuals[i] ;
- return TRUE ;
- }
- }
- return FALSE ;
-}
-
-
-#define NUM_WINDOW_PAIRS 256
-static EphyrWindowPair window_pairs[NUM_WINDOW_PAIRS] ;
-
-static Bool
-appendWindowPairToList (WindowPtr a_local,
- int a_remote)
-{
- int i=0 ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_local, FALSE) ;
-
- EPHYR_LOG ("(local,remote):(%p, %d)\n", a_local, a_remote) ;
-
- for (i=0; i < NUM_WINDOW_PAIRS; i++) {
- if (window_pairs[i].local == NULL) {
- window_pairs[i].local = a_local ;
- window_pairs[i].remote = a_remote ;
- return TRUE ;
- }
- }
- return FALSE ;
-}
-
-static Bool
-findWindowPairFromLocal (WindowPtr a_local,
- EphyrWindowPair **a_pair)
-{
- int i=0 ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_pair && a_local, FALSE) ;
-
- for (i=0; i < NUM_WINDOW_PAIRS; i++) {
- if (window_pairs[i].local == a_local) {
- *a_pair = &window_pairs[i] ;
- EPHYR_LOG ("found (%p, %d)\n",
- (*a_pair)->local,
- (*a_pair)->remote) ;
- return TRUE ;
- }
- }
- return FALSE ;
-}
-
-Bool
-findWindowPairFromRemote (int a_remote,
- EphyrWindowPair **a_pair)
-{
- int i=0 ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_pair, FALSE) ;
-
- for (i=0; i < NUM_WINDOW_PAIRS; i++) {
- if (window_pairs[i].remote == a_remote) {
- *a_pair = &window_pairs[i] ;
- EPHYR_LOG ("found (%p, %d)\n",
- (*a_pair)->local,
- (*a_pair)->remote) ;
- return TRUE ;
- }
- }
- return FALSE ;
-}
-
-static Bool
-createHostPeerWindow (const WindowPtr a_win,
- int *a_peer_win)
-{
- Bool is_ok=FALSE ;
- VisualPtr visual=NULL;
- EphyrBox geo ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_win && a_peer_win, FALSE) ;
- EPHYR_RETURN_VAL_IF_FAIL (a_win->drawable.pScreen,
- FALSE) ;
-
- EPHYR_LOG ("enter. a_win '%p'\n", a_win) ;
- if (!getWindowVisual (a_win, &visual)) {
- EPHYR_LOG_ERROR ("failed to get window visual\n") ;
- goto out ;
- }
- if (!visual) {
- EPHYR_LOG_ERROR ("failed to create visual\n") ;
- goto out ;
- }
- memset (&geo, 0, sizeof (geo)) ;
- geo.x = a_win->drawable.x ;
- geo.y = a_win->drawable.y ;
- geo.width = a_win->drawable.width ;
- geo.height = a_win->drawable.height ;
- if (!hostx_create_window (a_win->drawable.pScreen->myNum,
- &geo, visual->vid, a_peer_win)) {
- EPHYR_LOG_ERROR ("failed to create host peer window\n") ;
- goto out ;
- }
- if (!appendWindowPairToList (a_win, *a_peer_win)) {
- EPHYR_LOG_ERROR ("failed to append window to pair list\n") ;
- goto out ;
- }
- is_ok = TRUE ;
-out:
- EPHYR_LOG ("leave:remote win%d\n", *a_peer_win) ;
- return is_ok ;
-}
-
-static Bool
-destroyHostPeerWindow (const WindowPtr a_win)
-{
- Bool is_ok = FALSE ;
- EphyrWindowPair *pair=NULL ;
- EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ;
-
- EPHYR_LOG ("enter\n") ;
-
- if (!findWindowPairFromLocal (a_win, &pair) || !pair) {
- EPHYR_LOG_ERROR ("failed to find peer to local window\n") ;
- goto out;
- }
- hostx_destroy_window (pair->remote) ;
- is_ok = TRUE ;
-
-out:
- EPHYR_LOG ("leave\n") ;
- return is_ok;
-}
-
-static int
-ProcXF86DRICreateDrawable (ClientPtr client)
-{
- xXF86DRICreateDrawableReply rep;
- DrawablePtr drawable=NULL;
- WindowPtr window=NULL ;
- EphyrWindowPair *pair=NULL ;
- EphyrDRIWindowPrivPtr win_priv=NULL;
- int rc=0, remote_win=0;
- REQUEST(xXF86DRICreateDrawableReq);
- REQUEST_SIZE_MATCH(xXF86DRICreateDrawableReq);
-
- EPHYR_LOG ("enter\n") ;
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- rc = dixLookupDrawable (&drawable, stuff->drawable, client, 0,
- DixReadAccess);
- if (rc != Success)
- return rc;
- if (drawable->type != DRAWABLE_WINDOW) {
- EPHYR_LOG_ERROR ("non drawable windows are not yet supported\n") ;
- return BadImplementation ;
- }
- EPHYR_LOG ("lookedup drawable %p\n", drawable) ;
- window = (WindowPtr)drawable;
- if (findWindowPairFromLocal (window, &pair) && pair) {
- remote_win = pair->remote ;
- EPHYR_LOG ("found window '%p' paire with remote '%d'\n",
- window, remote_win) ;
- } else if (!createHostPeerWindow (window, &remote_win)) {
- EPHYR_LOG_ERROR ("failed to create host peer window\n") ;
- return BadAlloc ;
- }
-
- if (!ephyrDRICreateDrawable (stuff->screen,
- remote_win,
- (drm_drawable_t *)&rep.hHWDrawable)) {
- EPHYR_LOG_ERROR ("failed to create dri drawable\n") ;
- return BadValue;
- }
-
- win_priv = GET_EPHYR_DRI_WINDOW_PRIV (window) ;
- if (!win_priv) {
- win_priv = xcalloc (1, sizeof (EphyrDRIWindowPrivRec)) ;
- if (!win_priv) {
- EPHYR_LOG_ERROR ("failed to allocate window private\n") ;
- return BadAlloc ;
- }
- dixSetPrivate(&window->devPrivates, ephyrDRIWindowKey, win_priv);
- EPHYR_LOG ("paired window '%p' with remote '%d'\n",
- window, remote_win) ;
- }
-
- WriteToClient(client, sizeof(xXF86DRICreateDrawableReply), (char *)&rep);
- EPHYR_LOG ("leave\n") ;
- return (client->noClientException);
-}
-
-static int
-ProcXF86DRIDestroyDrawable (register ClientPtr client)
-{
- DrawablePtr drawable=NULL;
- WindowPtr window=NULL;
- EphyrWindowPair *pair=NULL;
- int rc=0;
- REQUEST(xXF86DRIDestroyDrawableReq);
- REQUEST_SIZE_MATCH(xXF86DRIDestroyDrawableReq);
-
- EPHYR_LOG ("enter\n") ;
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- rc = dixLookupDrawable(&drawable,
- stuff->drawable,
- client,
- 0,
- DixReadAccess);
- if (rc != Success)
- return rc;
- if (drawable->type != DRAWABLE_WINDOW) {
- EPHYR_LOG_ERROR ("non drawable windows are not yet supported\n") ;
- return BadImplementation ;
- }
- window = (WindowPtr)drawable;
- if (!findWindowPairFromLocal (window, &pair) && pair) {
- EPHYR_LOG_ERROR ("failed to find pair window\n") ;
- return BadImplementation;
- }
- if (!ephyrDRIDestroyDrawable(stuff->screen,
- pair->remote/*drawable in host x*/)) {
- EPHYR_LOG_ERROR ("failed to destroy dri drawable\n") ;
- return BadImplementation;
- }
- pair->local=NULL ;
- pair->remote=0;
-
- EPHYR_LOG ("leave\n") ;
- return (client->noClientException);
-}
-
-static int
-ProcXF86DRIGetDrawableInfo (register ClientPtr client)
-{
- xXF86DRIGetDrawableInfoReply rep;
- DrawablePtr drawable;
- WindowPtr window=NULL;
- EphyrWindowPair *pair=NULL;
- int X=0, Y=0, W=0, H=0, backX=0, backY=0, rc=0, i=0;
- drm_clip_rect_t *clipRects=NULL;
- drm_clip_rect_t *backClipRects=NULL;
- REQUEST(xXF86DRIGetDrawableInfoReq);
- REQUEST_SIZE_MATCH(xXF86DRIGetDrawableInfoReq);
-
- EPHYR_LOG ("enter\n") ;
- memset (&rep, 0, sizeof (rep)) ;
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- rc = dixLookupDrawable(&drawable, stuff->drawable, client, 0,
- DixReadAccess);
- if (rc != Success || !drawable) {
- EPHYR_LOG_ERROR ("could not get drawable\n") ;
- return rc;
- }
-
- if (drawable->type != DRAWABLE_WINDOW) {
- EPHYR_LOG_ERROR ("non windows type drawables are not yes supported\n") ;
- return BadImplementation ;
- }
- window = (WindowPtr)drawable ;
- memset (&pair, 0, sizeof (pair)) ;
- if (!findWindowPairFromLocal (window, &pair) || !pair) {
- EPHYR_LOG_ERROR ("failed to find remote peer drawable\n") ;
- return BadMatch ;
- }
- EPHYR_LOG ("clip list of xephyr gl drawable:\n") ;
- for (i=0; i < REGION_NUM_RECTS (&window->clipList); i++) {
- EPHYR_LOG ("x1:%d, y1:%d, x2:%d, y2:%d\n",
- REGION_RECTS (&window->clipList)[i].x1,
- REGION_RECTS (&window->clipList)[i].y1,
- REGION_RECTS (&window->clipList)[i].x2,
- REGION_RECTS (&window->clipList)[i].y2) ;
- }
-
- if (!ephyrDRIGetDrawableInfo (stuff->screen,
- pair->remote/*the drawable in hostx*/,
- (unsigned int*)&rep.drawableTableIndex,
- (unsigned int*)&rep.drawableTableStamp,
- (int*)&X,
- (int*)&Y,
- (int*)&W,
- (int*)&H,
- (int*)&rep.numClipRects,
- &clipRects,
- &backX,
- &backY,
- (int*)&rep.numBackClipRects,
- &backClipRects)) {
- return BadValue;
- }
- EPHYR_LOG ("num clip rects:%d, num back clip rects:%d\n",
- (int)rep.numClipRects, (int)rep.numBackClipRects) ;
-
- rep.drawableX = X;
- rep.drawableY = Y;
- rep.drawableWidth = W;
- rep.drawableHeight = H;
- rep.length = (SIZEOF(xXF86DRIGetDrawableInfoReply) -
- SIZEOF(xGenericReply));
-
- rep.backX = backX;
- rep.backY = backY;
-
-
- if (rep.numClipRects) {
- if (clipRects) {
- ScreenPtr pScreen = screenInfo.screens[stuff->screen];
- int i=0;
- EPHYR_LOG ("clip list of host gl drawable:\n") ;
- for (i = 0; i < rep.numClipRects; i++) {
- clipRects[i].x1 = max (clipRects[i].x1, 0);
- clipRects[i].y1 = max (clipRects[i].y1, 0);
- clipRects[i].x2 = min (clipRects[i].x2,
- pScreen->width + clipRects[i].x1) ;
- clipRects[i].y2 = min (clipRects[i].y2,
- pScreen->width + clipRects[i].y1) ;
-
- EPHYR_LOG ("x1:%d, y1:%d, x2:%d, y2:%d\n",
- clipRects[i].x1, clipRects[i].y1,
- clipRects[i].x2, clipRects[i].y2) ;
- }
- } else {
- rep.numClipRects = 0;
- }
- } else {
- EPHYR_LOG ("got zero host gl drawable clipping rects\n") ;
- }
- rep.length += sizeof(drm_clip_rect_t) * rep.numClipRects;
- backClipRects = clipRects ;
- rep.numBackClipRects = rep.numClipRects ;
- if (rep.numBackClipRects)
- rep.length += sizeof(drm_clip_rect_t) * rep.numBackClipRects;
- EPHYR_LOG ("num host clip rects:%d\n", (int)rep.numClipRects) ;
- EPHYR_LOG ("num host back clip rects:%d\n", (int)rep.numBackClipRects) ;
-
- rep.length = bytes_to_int32(rep.length);
-
- WriteToClient(client, sizeof(xXF86DRIGetDrawableInfoReply), (char *)&rep);
-
- if (rep.numClipRects) {
- WriteToClient(client,
- sizeof(drm_clip_rect_t) * rep.numClipRects,
- (char *)clipRects);
- }
-
- if (rep.numBackClipRects) {
- WriteToClient(client,
- sizeof(drm_clip_rect_t) * rep.numBackClipRects,
- (char *)backClipRects);
- }
- xfree(clipRects);
- clipRects = NULL ;
-
- EPHYR_LOG ("leave\n") ;
-
- return (client->noClientException);
-}
-
-static int
-ProcXF86DRIGetDeviceInfo (register ClientPtr client)
-{
- xXF86DRIGetDeviceInfoReply rep;
- drm_handle_t hFrameBuffer;
- void *pDevPrivate;
- REQUEST(xXF86DRIGetDeviceInfoReq);
- REQUEST_SIZE_MATCH(xXF86DRIGetDeviceInfoReq);
-
- EPHYR_LOG ("enter\n") ;
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- if (!ephyrDRIGetDeviceInfo (stuff->screen,
- &hFrameBuffer,
- (int*)&rep.framebufferOrigin,
- (int*)&rep.framebufferSize,
- (int*)&rep.framebufferStride,
- (int*)&rep.devPrivateSize,
- &pDevPrivate)) {
- return BadValue;
- }
-
- rep.hFrameBufferLow = (CARD32)(hFrameBuffer & 0xffffffff);
-#if defined(LONG64) && !defined(__linux__)
- rep.hFrameBufferHigh = (CARD32)(hFrameBuffer >> 32);
-#else
- rep.hFrameBufferHigh = 0;
-#endif
-
- rep.length = 0;
- if (rep.devPrivateSize) {
- rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetDeviceInfoReply) -
- SIZEOF(xGenericReply) +
- pad_to_int32(rep.devPrivateSize));
- }
-
- WriteToClient(client, sizeof(xXF86DRIGetDeviceInfoReply), (char *)&rep);
- if (rep.length) {
- WriteToClient(client, rep.devPrivateSize, (char *)pDevPrivate);
- }
- EPHYR_LOG ("leave\n") ;
- return (client->noClientException);
-}
-
-static int
-ProcXF86DRIDispatch (register ClientPtr client)
-{
- REQUEST(xReq);
- EPHYR_LOG ("enter\n") ;
-
- switch (stuff->data)
- {
- case X_XF86DRIQueryVersion: {
- EPHYR_LOG ("leave\n") ;
- return ProcXF86DRIQueryVersion(client);
- }
- case X_XF86DRIQueryDirectRenderingCapable: {
- EPHYR_LOG ("leave\n") ;
- return ProcXF86DRIQueryDirectRenderingCapable(client);
- }
- }
-
- if (!LocalClient(client))
- return DRIErrorBase + XF86DRIClientNotLocal;
-
- switch (stuff->data)
- {
- case X_XF86DRIOpenConnection: {
- EPHYR_LOG ("leave\n") ;
- return ProcXF86DRIOpenConnection(client);
- }
- case X_XF86DRICloseConnection: {
- EPHYR_LOG ("leave\n") ;
- return ProcXF86DRICloseConnection(client);
- }
- case X_XF86DRIGetClientDriverName: {
- EPHYR_LOG ("leave\n") ;
- return ProcXF86DRIGetClientDriverName(client);
- }
- case X_XF86DRICreateContext: {
- EPHYR_LOG ("leave\n") ;
- return ProcXF86DRICreateContext(client);
- }
- case X_XF86DRIDestroyContext: {
- EPHYR_LOG ("leave\n") ;
- return ProcXF86DRIDestroyContext(client);
- }
- case X_XF86DRICreateDrawable: {
- EPHYR_LOG ("leave\n") ;
- return ProcXF86DRICreateDrawable(client);
- }
- case X_XF86DRIDestroyDrawable: {
- EPHYR_LOG ("leave\n") ;
- return ProcXF86DRIDestroyDrawable(client);
- }
- case X_XF86DRIGetDrawableInfo: {
- EPHYR_LOG ("leave\n") ;
- return ProcXF86DRIGetDrawableInfo(client);
- }
- case X_XF86DRIGetDeviceInfo: {
- EPHYR_LOG ("leave\n") ;
- return ProcXF86DRIGetDeviceInfo(client);
- }
- case X_XF86DRIAuthConnection: {
- EPHYR_LOG ("leave\n") ;
- return ProcXF86DRIAuthConnection(client);
- }
- /* {Open,Close}FullScreen are deprecated now */
- default: {
- EPHYR_LOG ("leave\n") ;
- return BadRequest;
- }
- }
-}
-
-static int
-SProcXF86DRIQueryVersion (register ClientPtr client)
-{
- register int n;
- REQUEST(xXF86DRIQueryVersionReq);
- swaps(&stuff->length, n);
- return ProcXF86DRIQueryVersion(client);
-}
-
-static int
-SProcXF86DRIQueryDirectRenderingCapable (register ClientPtr client)
-{
- register int n;
- REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
- swaps(&stuff->length, n);
- swapl(&stuff->screen, n);
- return ProcXF86DRIQueryDirectRenderingCapable(client);
-}
-
-static int
-SProcXF86DRIDispatch (register ClientPtr client)
-{
- REQUEST(xReq);
-
- EPHYR_LOG ("enter\n") ;
- /*
- * Only local clients are allowed DRI access, but remote clients still need
- * these requests to find out cleanly.
- */
- switch (stuff->data)
- {
- case X_XF86DRIQueryVersion: {
- EPHYR_LOG ("leave\n") ;
- return SProcXF86DRIQueryVersion(client);
- }
- case X_XF86DRIQueryDirectRenderingCapable: {
- EPHYR_LOG ("leave\n") ;
- return SProcXF86DRIQueryDirectRenderingCapable(client);
- }
- default: {
- EPHYR_LOG ("leave\n") ;
- return DRIErrorBase + XF86DRIClientNotLocal;
- }
- }
-}
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ * Authored by Matthew Allum <mallum@openedhand.com>
+ *
+ * Copyright © 2007 OpenedHand Ltd
+ *
+ * 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 OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd 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.
+ *
+ * This file is heavily copied from hw/xfree86/dri/xf86dri.c
+ *
+ * Authors:
+ * Dodji Seketeli <dodji@openedhand.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+
+#include <string.h>
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#define _XF86DRI_SERVER_
+#include <X11/dri/xf86dri.h>
+#include <X11/dri/xf86driproto.h>
+#include "misc.h"
+#include "privates.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "servermd.h"
+#include "swaprep.h"
+#include "ephyrdri.h"
+#include "ephyrdriext.h"
+#include "hostx.h"
+#define _HAVE_XALLOC_DECLS
+#include "ephyrlog.h"
+#include "protocol-versions.h"
+
+typedef struct {
+ int foo;
+} EphyrDRIWindowPrivRec;
+typedef EphyrDRIWindowPrivRec* EphyrDRIWindowPrivPtr;
+
+typedef struct {
+ CreateWindowProcPtr CreateWindow ;
+ DestroyWindowProcPtr DestroyWindow ;
+ MoveWindowProcPtr MoveWindow ;
+ PositionWindowProcPtr PositionWindow ;
+ ClipNotifyProcPtr ClipNotify ;
+} EphyrDRIScreenPrivRec;
+typedef EphyrDRIScreenPrivRec* EphyrDRIScreenPrivPtr;
+
+static int DRIErrorBase;
+
+static DISPATCH_PROC(ProcXF86DRIQueryVersion);
+static DISPATCH_PROC(ProcXF86DRIQueryDirectRenderingCapable);
+static DISPATCH_PROC(ProcXF86DRIOpenConnection);
+static DISPATCH_PROC(ProcXF86DRICloseConnection);
+static DISPATCH_PROC(ProcXF86DRIGetClientDriverName);
+static DISPATCH_PROC(ProcXF86DRICreateContext);
+static DISPATCH_PROC(ProcXF86DRIDestroyContext);
+static DISPATCH_PROC(ProcXF86DRICreateDrawable);
+static DISPATCH_PROC(ProcXF86DRIDestroyDrawable);
+static DISPATCH_PROC(ProcXF86DRIGetDrawableInfo);
+static DISPATCH_PROC(ProcXF86DRIGetDeviceInfo);
+static DISPATCH_PROC(ProcXF86DRIDispatch);
+static DISPATCH_PROC(ProcXF86DRIAuthConnection);
+
+static DISPATCH_PROC(SProcXF86DRIQueryVersion);
+static DISPATCH_PROC(SProcXF86DRIQueryDirectRenderingCapable);
+static DISPATCH_PROC(SProcXF86DRIDispatch);
+
+static Bool ephyrDRIScreenInit (ScreenPtr a_screen) ;
+static Bool ephyrDRICreateWindow (WindowPtr a_win) ;
+static Bool ephyrDRIDestroyWindow (WindowPtr a_win) ;
+static void ephyrDRIMoveWindow (WindowPtr a_win,
+ int a_x, int a_y,
+ WindowPtr a_siblings,
+ VTKind a_kind);
+static Bool ephyrDRIPositionWindow (WindowPtr a_win,
+ int x, int y) ;
+static void ephyrDRIClipNotify (WindowPtr a_win,
+ int a_x, int a_y) ;
+
+static Bool EphyrMirrorHostVisuals (ScreenPtr a_screen) ;
+static Bool destroyHostPeerWindow (const WindowPtr a_win) ;
+static Bool findWindowPairFromLocal (WindowPtr a_local,
+ EphyrWindowPair **a_pair);
+
+static unsigned char DRIReqCode = 0;
+
+static int ephyrDRIWindowKeyIndex;
+static DevPrivateKey ephyrDRIWindowKey = &ephyrDRIWindowKeyIndex;
+static int ephyrDRIScreenKeyIndex;
+static DevPrivateKey ephyrDRIScreenKey = &ephyrDRIScreenKeyIndex;
+
+#define GET_EPHYR_DRI_WINDOW_PRIV(win) ((EphyrDRIWindowPrivPtr) \
+ dixLookupPrivate(&(win)->devPrivates, ephyrDRIWindowKey))
+#define GET_EPHYR_DRI_SCREEN_PRIV(screen) ((EphyrDRIScreenPrivPtr) \
+ dixLookupPrivate(&(screen)->devPrivates, ephyrDRIScreenKey))
+
+
+Bool
+ephyrDRIExtensionInit (ScreenPtr a_screen)
+{
+ Bool is_ok=FALSE ;
+ ExtensionEntry* extEntry=NULL;
+ EphyrDRIScreenPrivPtr screen_priv=NULL ;
+
+ EPHYR_LOG ("enter\n") ;
+ if (!hostx_has_dri ()) {
+ EPHYR_LOG ("host does not have DRI extension\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("host X does have DRI extension\n") ;
+ if (!hostx_has_xshape ()) {
+ EPHYR_LOG ("host does not have XShape extension\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("host X does have XShape extension\n") ;
+
+#ifdef XF86DRI_EVENTS
+ EventType = CreateNewResourceType (XF86DRIFreeEvents, "DRIEvents");
+ if (!EventType) {
+ EPHYR_LOG_ERROR ("failed to register DRI event resource type\n") ;
+ goto out ;
+ }
+#endif
+
+ if ((extEntry = AddExtension(XF86DRINAME,
+ XF86DRINumberEvents,
+ XF86DRINumberErrors,
+ ProcXF86DRIDispatch,
+ SProcXF86DRIDispatch,
+ NULL,
+ StandardMinorOpcode))) {
+ DRIReqCode = (unsigned char)extEntry->base;
+ DRIErrorBase = extEntry->errorBase;
+ } else {
+ EPHYR_LOG_ERROR ("failed to register DRI extension\n") ;
+ goto out ;
+ }
+ screen_priv = calloc(1, sizeof (EphyrDRIScreenPrivRec)) ;
+ if (!screen_priv) {
+ EPHYR_LOG_ERROR ("failed to allocate screen_priv\n") ;
+ goto out ;
+ }
+ dixSetPrivate(&a_screen->devPrivates, ephyrDRIScreenKey, screen_priv);
+
+ if (!ephyrDRIScreenInit (a_screen)) {
+ EPHYR_LOG_ERROR ("ephyrDRIScreenInit() failed\n") ;
+ goto out ;
+ }
+ EphyrMirrorHostVisuals (a_screen) ;
+ is_ok=TRUE ;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+static Bool
+ephyrDRIScreenInit (ScreenPtr a_screen)
+{
+ Bool is_ok=FALSE ;
+ EphyrDRIScreenPrivPtr screen_priv=NULL ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_screen, FALSE) ;
+
+ screen_priv=GET_EPHYR_DRI_SCREEN_PRIV (a_screen) ;
+ EPHYR_RETURN_VAL_IF_FAIL (screen_priv, FALSE) ;
+
+ screen_priv->CreateWindow = a_screen->CreateWindow ;
+ screen_priv->DestroyWindow = a_screen->DestroyWindow ;
+ screen_priv->MoveWindow = a_screen->MoveWindow ;
+ screen_priv->PositionWindow = a_screen->PositionWindow ;
+ screen_priv->ClipNotify = a_screen->ClipNotify ;
+
+ a_screen->CreateWindow = ephyrDRICreateWindow ;
+ a_screen->DestroyWindow = ephyrDRIDestroyWindow ;
+ a_screen->MoveWindow = ephyrDRIMoveWindow ;
+ a_screen->PositionWindow = ephyrDRIPositionWindow ;
+ a_screen->ClipNotify = ephyrDRIClipNotify ;
+
+ is_ok = TRUE ;
+
+ return is_ok ;
+}
+
+static Bool
+ephyrDRICreateWindow (WindowPtr a_win)
+{
+ Bool is_ok=FALSE ;
+ ScreenPtr screen=NULL ;
+ EphyrDRIScreenPrivPtr screen_priv =NULL;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ;
+ screen = a_win->drawable.pScreen ;
+ EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ;
+ screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
+ EPHYR_RETURN_VAL_IF_FAIL (screen_priv
+ && screen_priv->CreateWindow,
+ FALSE) ;
+
+ EPHYR_LOG ("enter. win:%p\n", a_win) ;
+
+ screen->CreateWindow = screen_priv->CreateWindow ;
+ is_ok = (*screen->CreateWindow) (a_win) ;
+ screen->CreateWindow = ephyrDRICreateWindow ;
+
+ if (is_ok) {
+ dixSetPrivate(&a_win->devPrivates, ephyrDRIWindowKey, NULL);
+ }
+ return is_ok ;
+}
+
+static Bool
+ephyrDRIDestroyWindow (WindowPtr a_win)
+{
+ Bool is_ok=FALSE ;
+ ScreenPtr screen=NULL ;
+ EphyrDRIScreenPrivPtr screen_priv =NULL;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ;
+ screen = a_win->drawable.pScreen ;
+ EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ;
+ screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
+ EPHYR_RETURN_VAL_IF_FAIL (screen_priv
+ && screen_priv->DestroyWindow,
+ FALSE) ;
+
+ screen->DestroyWindow = screen_priv->DestroyWindow ;
+ if (screen->DestroyWindow) {
+ is_ok = (*screen->DestroyWindow) (a_win) ;
+ }
+ screen->DestroyWindow = ephyrDRIDestroyWindow ;
+
+ if (is_ok) {
+ EphyrDRIWindowPrivPtr win_priv=GET_EPHYR_DRI_WINDOW_PRIV (a_win) ;
+ if (win_priv) {
+ destroyHostPeerWindow (a_win) ;
+ free(win_priv) ;
+ dixSetPrivate(&a_win->devPrivates, ephyrDRIWindowKey, NULL);
+ EPHYR_LOG ("destroyed the remote peer window\n") ;
+ }
+ }
+ return is_ok ;
+}
+
+static void
+ephyrDRIMoveWindow (WindowPtr a_win,
+ int a_x, int a_y,
+ WindowPtr a_siblings,
+ VTKind a_kind)
+{
+ Bool is_ok=FALSE ;
+ ScreenPtr screen=NULL ;
+ EphyrDRIScreenPrivPtr screen_priv =NULL;
+ EphyrDRIWindowPrivPtr win_priv=NULL ;
+ EphyrWindowPair *pair=NULL ;
+ EphyrBox geo;
+ int x=0,y=0;/*coords relative to parent window*/
+
+ EPHYR_RETURN_IF_FAIL (a_win) ;
+
+ EPHYR_LOG ("enter\n") ;
+ screen = a_win->drawable.pScreen ;
+ EPHYR_RETURN_IF_FAIL (screen) ;
+ screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
+ EPHYR_RETURN_IF_FAIL (screen_priv
+ && screen_priv->MoveWindow) ;
+
+ screen->MoveWindow = screen_priv->MoveWindow ;
+ if (screen->MoveWindow) {
+ (*screen->MoveWindow) (a_win, a_x, a_y, a_siblings, a_kind) ;
+ }
+ screen->MoveWindow = ephyrDRIMoveWindow ;
+
+ EPHYR_LOG ("window: %p\n", a_win) ;
+ if (!a_win->parent) {
+ EPHYR_LOG ("cannot move root window\n") ;
+ is_ok = TRUE ;
+ goto out ;
+ }
+ win_priv = GET_EPHYR_DRI_WINDOW_PRIV (a_win) ;
+ if (!win_priv) {
+ EPHYR_LOG ("not a DRI peered window\n") ;
+ is_ok = TRUE ;
+ goto out ;
+ }
+ if (!findWindowPairFromLocal (a_win, &pair) || !pair) {
+ EPHYR_LOG_ERROR ("failed to get window pair\n") ;
+ goto out ;
+ }
+ /*compute position relative to parent window*/
+ x = a_win->drawable.x - a_win->parent->drawable.x ;
+ y = a_win->drawable.y - a_win->parent->drawable.y ;
+ /*set the geometry to pass to hostx_set_window_geometry*/
+ memset (&geo, 0, sizeof (geo)) ;
+ geo.x = x ;
+ geo.y = y ;
+ geo.width = a_win->drawable.width ;
+ geo.height = a_win->drawable.height ;
+ hostx_set_window_geometry (pair->remote, &geo) ;
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
+ /*do cleanup here*/
+}
+
+static Bool
+ephyrDRIPositionWindow (WindowPtr a_win,
+ int a_x, int a_y)
+{
+ Bool is_ok=FALSE ;
+ ScreenPtr screen=NULL ;
+ EphyrDRIScreenPrivPtr screen_priv =NULL;
+ EphyrDRIWindowPrivPtr win_priv=NULL ;
+ EphyrWindowPair *pair=NULL ;
+ EphyrBox geo;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+ screen = a_win->drawable.pScreen ;
+ EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ;
+ screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
+ EPHYR_RETURN_VAL_IF_FAIL (screen_priv
+ && screen_priv->PositionWindow,
+ FALSE) ;
+
+ screen->PositionWindow = screen_priv->PositionWindow ;
+ if (screen->PositionWindow) {
+ (*screen->PositionWindow) (a_win, a_x, a_y) ;
+ }
+ screen->PositionWindow = ephyrDRIPositionWindow ;
+
+ EPHYR_LOG ("window: %p\n", a_win) ;
+ win_priv = GET_EPHYR_DRI_WINDOW_PRIV (a_win) ;
+ if (!win_priv) {
+ EPHYR_LOG ("not a DRI peered window\n") ;
+ is_ok = TRUE ;
+ goto out ;
+ }
+ if (!findWindowPairFromLocal (a_win, &pair) || !pair) {
+ EPHYR_LOG_ERROR ("failed to get window pair\n") ;
+ goto out ;
+ }
+ /*set the geometry to pass to hostx_set_window_geometry*/
+ memset (&geo, 0, sizeof (geo)) ;
+ geo.x = a_x ;
+ geo.y = a_y ;
+ geo.width = a_win->drawable.width ;
+ geo.height = a_win->drawable.height ;
+ hostx_set_window_geometry (pair->remote, &geo) ;
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
+ /*do cleanup here*/
+ return is_ok ;
+}
+
+static void
+ephyrDRIClipNotify (WindowPtr a_win,
+ int a_x, int a_y)
+{
+ Bool is_ok=FALSE ;
+ ScreenPtr screen=NULL ;
+ EphyrDRIScreenPrivPtr screen_priv =NULL;
+ EphyrDRIWindowPrivPtr win_priv=NULL ;
+ EphyrWindowPair *pair=NULL ;
+ EphyrRect *rects=NULL;
+ int i=0 ;
+
+ EPHYR_RETURN_IF_FAIL (a_win) ;
+
+ EPHYR_LOG ("enter\n") ;
+ screen = a_win->drawable.pScreen ;
+ EPHYR_RETURN_IF_FAIL (screen) ;
+ screen_priv = GET_EPHYR_DRI_SCREEN_PRIV (screen) ;
+ EPHYR_RETURN_IF_FAIL (screen_priv && screen_priv->ClipNotify) ;
+
+ screen->ClipNotify = screen_priv->ClipNotify ;
+ if (screen->ClipNotify) {
+ (*screen->ClipNotify) (a_win, a_x, a_y) ;
+ }
+ screen->ClipNotify = ephyrDRIClipNotify ;
+
+ EPHYR_LOG ("window: %p\n", a_win) ;
+ win_priv = GET_EPHYR_DRI_WINDOW_PRIV (a_win) ;
+ if (!win_priv) {
+ EPHYR_LOG ("not a DRI peered window\n") ;
+ is_ok = TRUE ;
+ goto out ;
+ }
+ if (!findWindowPairFromLocal (a_win, &pair) || !pair) {
+ EPHYR_LOG_ERROR ("failed to get window pair\n") ;
+ goto out ;
+ }
+ rects = calloc(REGION_NUM_RECTS (&a_win->clipList),
+ sizeof (EphyrRect)) ;
+ for (i=0; i < REGION_NUM_RECTS (&a_win->clipList); i++) {
+ memmove (&rects[i],
+ &REGION_RECTS (&a_win->clipList)[i],
+ sizeof (EphyrRect)) ;
+ rects[i].x1 -= a_win->drawable.x;
+ rects[i].x2 -= a_win->drawable.x;
+ rects[i].y1 -= a_win->drawable.y;
+ rects[i].y2 -= a_win->drawable.y;
+ }
+ /*
+ * push the clipping region of this window
+ * to the peer window in the host
+ */
+ is_ok = hostx_set_window_bounding_rectangles
+ (pair->remote,
+ rects,
+ REGION_NUM_RECTS (&a_win->clipList)) ;
+ is_ok = TRUE ;
+
+out:
+ free(rects) ;
+ rects = NULL ;
+
+ EPHYR_LOG ("leave. is_ok:%d\n", is_ok) ;
+ /*do cleanup here*/
+}
+
+/**
+ * Duplicates a visual of a_screen
+ * In screen a_screen, for depth a_depth, find a visual which
+ * bitsPerRGBValue and colormap size equal
+ * a_bits_per_rgb_values and a_colormap_entries.
+ * The ID of that duplicated visual is set to a_new_id.
+ * That duplicated visual is then added to the list of visuals
+ * of the screen.
+ */
+static Bool
+EphyrDuplicateVisual (unsigned int a_screen,
+ short a_depth,
+ short a_class,
+ short a_bits_per_rgb_values,
+ short a_colormap_entries,
+ unsigned int a_red_mask,
+ unsigned int a_green_mask,
+ unsigned int a_blue_mask,
+ unsigned int a_new_id)
+{
+ Bool is_ok = FALSE, found_visual=FALSE, found_depth=FALSE ;
+ ScreenPtr screen=NULL ;
+ VisualRec new_visual, *new_visuals=NULL ;
+ int i=0 ;
+
+ EPHYR_LOG ("enter\n") ;
+ if (a_screen > screenInfo.numScreens) {
+ EPHYR_LOG_ERROR ("bad screen number\n") ;
+ goto out;
+ }
+ memset (&new_visual, 0, sizeof (VisualRec)) ;
+
+ /*get the screen pointed to by a_screen*/
+ screen = screenInfo.screens[a_screen] ;
+ EPHYR_RETURN_VAL_IF_FAIL (screen, FALSE) ;
+
+ /*
+ * In that screen, first look for an existing visual that has the
+ * same characteristics as those passed in parameter
+ * to this function and copy it.
+ */
+ for (i=0; i < screen->numVisuals; i++) {
+ if (screen->visuals[i].bitsPerRGBValue == a_bits_per_rgb_values &&
+ screen->visuals[i].ColormapEntries == a_colormap_entries ) {
+ /*copy the visual found*/
+ memcpy (&new_visual, &screen->visuals[i], sizeof (new_visual)) ;
+ new_visual.vid = a_new_id ;
+ new_visual.class = a_class ;
+ new_visual.redMask = a_red_mask ;
+ new_visual.greenMask = a_green_mask ;
+ new_visual.blueMask = a_blue_mask ;
+ found_visual = TRUE ;
+ EPHYR_LOG ("found a visual that matches visual id: %d\n",
+ a_new_id) ;
+ break;
+ }
+ }
+ if (!found_visual) {
+ EPHYR_LOG ("did not find any visual matching %d\n", a_new_id) ;
+ goto out ;
+ }
+ /*
+ * be prepare to extend screen->visuals to add new_visual to it
+ */
+ new_visuals = calloc(screen->numVisuals+1, sizeof (VisualRec)) ;
+ memmove (new_visuals,
+ screen->visuals,
+ screen->numVisuals*sizeof (VisualRec)) ;
+ memmove (&new_visuals[screen->numVisuals],
+ &new_visual,
+ sizeof (VisualRec)) ;
+ /*
+ * Now, in that same screen, update the screen->allowedDepths member.
+ * In that array, each element represents the visuals applicable to
+ * a given depth. So we need to add an entry matching the new visual
+ * that we are going to add to screen->visuals
+ */
+ for (i=0; i<screen->numDepths; i++) {
+ VisualID *vids=NULL;
+ DepthPtr cur_depth=NULL ;
+ /*find the entry matching a_depth*/
+ if (screen->allowedDepths[i].depth != a_depth)
+ continue ;
+ cur_depth = &screen->allowedDepths[i];
+ /*
+ * extend the list of visual IDs in that entry,
+ * so to add a_new_id in there.
+ */
+ vids = realloc(cur_depth->vids,
+ (cur_depth->numVids+1)*sizeof (VisualID));
+ if (!vids) {
+ EPHYR_LOG_ERROR ("failed to realloc numids\n") ;
+ goto out ;
+ }
+ vids[cur_depth->numVids] = a_new_id ;
+ /*
+ * Okay now commit our change.
+ * Do really update screen->allowedDepths[i]
+ */
+ cur_depth->numVids++ ;
+ cur_depth->vids = vids ;
+ found_depth=TRUE;
+ }
+ if (!found_depth) {
+ EPHYR_LOG_ERROR ("failed to update screen[%d]->allowedDepth\n",
+ a_screen) ;
+ goto out ;
+ }
+ /*
+ * Commit our change to screen->visuals
+ */
+ free(screen->visuals) ;
+ screen->visuals = new_visuals ;
+ screen->numVisuals++ ;
+ new_visuals = NULL ;
+
+ is_ok = TRUE ;
+out:
+ free(new_visuals) ;
+ new_visuals = NULL ;
+
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+/**
+ * Duplicates the visuals of the host X server.
+ * This is necessary to have visuals that have the same
+ * ID as those of the host X. It is important to have that for
+ * GLX.
+ */
+static Bool
+EphyrMirrorHostVisuals (ScreenPtr a_screen)
+{
+ Bool is_ok=FALSE;
+ EphyrHostVisualInfo *visuals=NULL;
+ int nb_visuals=0, i=0;
+
+ EPHYR_LOG ("enter\n") ;
+ if (!hostx_get_visuals_info (&visuals, &nb_visuals)) {
+ EPHYR_LOG_ERROR ("failed to get host visuals\n") ;
+ goto out ;
+ }
+ for (i=0; i<nb_visuals; i++) {
+ if (!EphyrDuplicateVisual (a_screen->myNum,
+ visuals[i].depth,
+ visuals[i].class,
+ visuals[i].bits_per_rgb,
+ visuals[i].colormap_size,
+ visuals[i].red_mask,
+ visuals[i].green_mask,
+ visuals[i].blue_mask,
+ visuals[i].visualid)) {
+ EPHYR_LOG_ERROR ("failed to duplicate host visual %d\n",
+ (int)visuals[i].visualid) ;
+ }
+ }
+
+ is_ok = TRUE ;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok;
+}
+
+
+static int
+ProcXF86DRIQueryVersion (register ClientPtr client)
+{
+ xXF86DRIQueryVersionReply rep;
+ register int n;
+ REQUEST_SIZE_MATCH(xXF86DRIQueryVersionReq);
+
+ EPHYR_LOG ("enter\n") ;
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = SERVER_XF86DRI_MAJOR_VERSION;
+ rep.minorVersion = SERVER_XF86DRI_MINOR_VERSION;
+ rep.patchVersion = SERVER_XF86DRI_PATCH_VERSION;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.majorVersion, n);
+ swaps(&rep.minorVersion, n);
+ swapl(&rep.patchVersion, n);
+ }
+ WriteToClient(client, sizeof(xXF86DRIQueryVersionReply), (char *)&rep);
+ EPHYR_LOG ("leave\n") ;
+ return Success;
+}
+
+static int
+ProcXF86DRIQueryDirectRenderingCapable (register ClientPtr client)
+{
+ xXF86DRIQueryDirectRenderingCapableReply rep;
+ Bool isCapable;
+ register int n;
+ REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
+ REQUEST_SIZE_MATCH(xXF86DRIQueryDirectRenderingCapableReq);
+
+ EPHYR_LOG ("enter\n") ;
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ if (!ephyrDRIQueryDirectRenderingCapable (stuff->screen, &isCapable)) {
+ return BadValue;
+ }
+ rep.isCapable = isCapable;
+
+ if (!LocalClient(client) || client->swapped)
+ rep.isCapable = 0;
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ }
+
+ WriteToClient(client, sizeof(xXF86DRIQueryDirectRenderingCapableReply), (char *)&rep);
+ EPHYR_LOG ("leave\n") ;
+
+ return Success;
+}
+
+static int
+ProcXF86DRIOpenConnection (register ClientPtr client)
+{
+ xXF86DRIOpenConnectionReply rep;
+ drm_handle_t hSAREA;
+ char* busIdString;
+ REQUEST(xXF86DRIOpenConnectionReq);
+ REQUEST_SIZE_MATCH(xXF86DRIOpenConnectionReq);
+
+ EPHYR_LOG ("enter\n") ;
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ if (!ephyrDRIOpenConnection(stuff->screen,
+ &hSAREA,
+ &busIdString)) {
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.busIdStringLength = 0;
+ if (busIdString)
+ rep.busIdStringLength = strlen(busIdString);
+ rep.length = bytes_to_int32(SIZEOF(xXF86DRIOpenConnectionReply) - SIZEOF(xGenericReply) +
+ pad_to_int32(rep.busIdStringLength));
+
+ rep.hSAREALow = (CARD32)(hSAREA & 0xffffffff);
+#if defined(LONG64) && !defined(__linux__)
+ rep.hSAREAHigh = (CARD32)(hSAREA >> 32);
+#else
+ rep.hSAREAHigh = 0;
+#endif
+
+ WriteToClient(client, sizeof(xXF86DRIOpenConnectionReply), (char *)&rep);
+ if (rep.busIdStringLength)
+ WriteToClient(client, rep.busIdStringLength, busIdString);
+ EPHYR_LOG ("leave\n") ;
+ return Success;
+}
+
+static int
+ProcXF86DRIAuthConnection (register ClientPtr client)
+{
+ xXF86DRIAuthConnectionReply rep;
+ REQUEST(xXF86DRIAuthConnectionReq);
+ REQUEST_SIZE_MATCH(xXF86DRIAuthConnectionReq);
+
+ EPHYR_LOG ("enter\n") ;
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.authenticated = 1;
+
+ if (!ephyrDRIAuthConnection (stuff->screen, stuff->magic)) {
+ ErrorF("Failed to authenticate %lu\n", (unsigned long)stuff->magic);
+ rep.authenticated = 0;
+ }
+ WriteToClient(client, sizeof(xXF86DRIAuthConnectionReply), (char *)&rep);
+ EPHYR_LOG ("leave\n") ;
+ return Success;
+}
+
+static int
+ProcXF86DRICloseConnection (register ClientPtr client)
+{
+ REQUEST(xXF86DRICloseConnectionReq);
+ REQUEST_SIZE_MATCH(xXF86DRICloseConnectionReq);
+ EPHYR_LOG ("enter\n") ;
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ /*
+ DRICloseConnection( screenInfo.screens[stuff->screen]);
+ */
+
+ EPHYR_LOG ("leave\n") ;
+ return Success;
+}
+
+static int
+ProcXF86DRIGetClientDriverName (register ClientPtr client)
+{
+ xXF86DRIGetClientDriverNameReply rep;
+ char* clientDriverName;
+ REQUEST(xXF86DRIGetClientDriverNameReq);
+ REQUEST_SIZE_MATCH(xXF86DRIGetClientDriverNameReq);
+
+ EPHYR_LOG ("enter\n") ;
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ ephyrDRIGetClientDriverName (stuff->screen,
+ (int *)&rep.ddxDriverMajorVersion,
+ (int *)&rep.ddxDriverMinorVersion,
+ (int *)&rep.ddxDriverPatchVersion,
+ &clientDriverName);
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.clientDriverNameLength = 0;
+ if (clientDriverName)
+ rep.clientDriverNameLength = strlen(clientDriverName);
+ rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetClientDriverNameReply) -
+ SIZEOF(xGenericReply) +
+ pad_to_int32(rep.clientDriverNameLength));
+
+ WriteToClient(client,
+ sizeof(xXF86DRIGetClientDriverNameReply), (char *)&rep);
+ if (rep.clientDriverNameLength)
+ WriteToClient(client,
+ rep.clientDriverNameLength,
+ clientDriverName);
+ EPHYR_LOG ("leave\n") ;
+ return Success;
+}
+
+static int
+ProcXF86DRICreateContext (register ClientPtr client)
+{
+ xXF86DRICreateContextReply rep;
+ ScreenPtr pScreen;
+ VisualPtr visual;
+ int i=0;
+ unsigned long context_id=0;
+ REQUEST(xXF86DRICreateContextReq);
+ REQUEST_SIZE_MATCH(xXF86DRICreateContextReq);
+
+ EPHYR_LOG ("enter\n") ;
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ pScreen = screenInfo.screens[stuff->screen];
+ visual = pScreen->visuals;
+
+ /* Find the requested X visual */
+ for (i = 0; i < pScreen->numVisuals; i++, visual++)
+ if (visual->vid == stuff->visual)
+ break;
+ if (i == pScreen->numVisuals) {
+ /* No visual found */
+ return BadValue;
+ }
+
+ context_id = stuff->context ;
+ if (!ephyrDRICreateContext (stuff->screen,
+ stuff->visual,
+ &context_id,
+ (drm_context_t *)&rep.hHWContext)) {
+ return BadValue;
+ }
+
+ WriteToClient(client, sizeof(xXF86DRICreateContextReply), (char *)&rep);
+ EPHYR_LOG ("leave\n") ;
+ return Success;
+}
+
+static int
+ProcXF86DRIDestroyContext (register ClientPtr client)
+{
+ REQUEST(xXF86DRIDestroyContextReq);
+ REQUEST_SIZE_MATCH(xXF86DRIDestroyContextReq);
+ EPHYR_LOG ("enter\n") ;
+
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ if (!ephyrDRIDestroyContext (stuff->screen, stuff->context)) {
+ return BadValue;
+ }
+
+ EPHYR_LOG ("leave\n") ;
+ return Success;
+}
+
+static Bool
+getWindowVisual (const WindowPtr a_win,
+ VisualPtr *a_visual)
+{
+ int i=0, visual_id=0 ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_win
+ && a_win->drawable.pScreen
+ && a_win->drawable.pScreen->visuals,
+ FALSE) ;
+
+ visual_id = wVisual (a_win) ;
+ for (i=0; i < a_win->drawable.pScreen->numVisuals; i++) {
+ if (a_win->drawable.pScreen->visuals[i].vid == visual_id) {
+ *a_visual = &a_win->drawable.pScreen->visuals[i] ;
+ return TRUE ;
+ }
+ }
+ return FALSE ;
+}
+
+
+#define NUM_WINDOW_PAIRS 256
+static EphyrWindowPair window_pairs[NUM_WINDOW_PAIRS] ;
+
+static Bool
+appendWindowPairToList (WindowPtr a_local,
+ int a_remote)
+{
+ int i=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_local, FALSE) ;
+
+ EPHYR_LOG ("(local,remote):(%p, %d)\n", a_local, a_remote) ;
+
+ for (i=0; i < NUM_WINDOW_PAIRS; i++) {
+ if (window_pairs[i].local == NULL) {
+ window_pairs[i].local = a_local ;
+ window_pairs[i].remote = a_remote ;
+ return TRUE ;
+ }
+ }
+ return FALSE ;
+}
+
+static Bool
+findWindowPairFromLocal (WindowPtr a_local,
+ EphyrWindowPair **a_pair)
+{
+ int i=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_pair && a_local, FALSE) ;
+
+ for (i=0; i < NUM_WINDOW_PAIRS; i++) {
+ if (window_pairs[i].local == a_local) {
+ *a_pair = &window_pairs[i] ;
+ EPHYR_LOG ("found (%p, %d)\n",
+ (*a_pair)->local,
+ (*a_pair)->remote) ;
+ return TRUE ;
+ }
+ }
+ return FALSE ;
+}
+
+Bool
+findWindowPairFromRemote (int a_remote,
+ EphyrWindowPair **a_pair)
+{
+ int i=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_pair, FALSE) ;
+
+ for (i=0; i < NUM_WINDOW_PAIRS; i++) {
+ if (window_pairs[i].remote == a_remote) {
+ *a_pair = &window_pairs[i] ;
+ EPHYR_LOG ("found (%p, %d)\n",
+ (*a_pair)->local,
+ (*a_pair)->remote) ;
+ return TRUE ;
+ }
+ }
+ return FALSE ;
+}
+
+static Bool
+createHostPeerWindow (const WindowPtr a_win,
+ int *a_peer_win)
+{
+ Bool is_ok=FALSE ;
+ VisualPtr visual=NULL;
+ EphyrBox geo ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_win && a_peer_win, FALSE) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_win->drawable.pScreen,
+ FALSE) ;
+
+ EPHYR_LOG ("enter. a_win '%p'\n", a_win) ;
+ if (!getWindowVisual (a_win, &visual)) {
+ EPHYR_LOG_ERROR ("failed to get window visual\n") ;
+ goto out ;
+ }
+ if (!visual) {
+ EPHYR_LOG_ERROR ("failed to create visual\n") ;
+ goto out ;
+ }
+ memset (&geo, 0, sizeof (geo)) ;
+ geo.x = a_win->drawable.x ;
+ geo.y = a_win->drawable.y ;
+ geo.width = a_win->drawable.width ;
+ geo.height = a_win->drawable.height ;
+ if (!hostx_create_window (a_win->drawable.pScreen->myNum,
+ &geo, visual->vid, a_peer_win)) {
+ EPHYR_LOG_ERROR ("failed to create host peer window\n") ;
+ goto out ;
+ }
+ if (!appendWindowPairToList (a_win, *a_peer_win)) {
+ EPHYR_LOG_ERROR ("failed to append window to pair list\n") ;
+ goto out ;
+ }
+ is_ok = TRUE ;
+out:
+ EPHYR_LOG ("leave:remote win%d\n", *a_peer_win) ;
+ return is_ok ;
+}
+
+static Bool
+destroyHostPeerWindow (const WindowPtr a_win)
+{
+ Bool is_ok = FALSE ;
+ EphyrWindowPair *pair=NULL ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_win, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (!findWindowPairFromLocal (a_win, &pair) || !pair) {
+ EPHYR_LOG_ERROR ("failed to find peer to local window\n") ;
+ goto out;
+ }
+ hostx_destroy_window (pair->remote) ;
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok;
+}
+
+static int
+ProcXF86DRICreateDrawable (ClientPtr client)
+{
+ xXF86DRICreateDrawableReply rep;
+ DrawablePtr drawable=NULL;
+ WindowPtr window=NULL ;
+ EphyrWindowPair *pair=NULL ;
+ EphyrDRIWindowPrivPtr win_priv=NULL;
+ int rc=0, remote_win=0;
+ REQUEST(xXF86DRICreateDrawableReq);
+ REQUEST_SIZE_MATCH(xXF86DRICreateDrawableReq);
+
+ EPHYR_LOG ("enter\n") ;
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ rc = dixLookupDrawable (&drawable, stuff->drawable, client, 0,
+ DixReadAccess);
+ if (rc != Success)
+ return rc;
+ if (drawable->type != DRAWABLE_WINDOW) {
+ EPHYR_LOG_ERROR ("non drawable windows are not yet supported\n") ;
+ return BadImplementation ;
+ }
+ EPHYR_LOG ("lookedup drawable %p\n", drawable) ;
+ window = (WindowPtr)drawable;
+ if (findWindowPairFromLocal (window, &pair) && pair) {
+ remote_win = pair->remote ;
+ EPHYR_LOG ("found window '%p' paire with remote '%d'\n",
+ window, remote_win) ;
+ } else if (!createHostPeerWindow (window, &remote_win)) {
+ EPHYR_LOG_ERROR ("failed to create host peer window\n") ;
+ return BadAlloc ;
+ }
+
+ if (!ephyrDRICreateDrawable (stuff->screen,
+ remote_win,
+ (drm_drawable_t *)&rep.hHWDrawable)) {
+ EPHYR_LOG_ERROR ("failed to create dri drawable\n") ;
+ return BadValue;
+ }
+
+ win_priv = GET_EPHYR_DRI_WINDOW_PRIV (window) ;
+ if (!win_priv) {
+ win_priv = calloc(1, sizeof (EphyrDRIWindowPrivRec)) ;
+ if (!win_priv) {
+ EPHYR_LOG_ERROR ("failed to allocate window private\n") ;
+ return BadAlloc ;
+ }
+ dixSetPrivate(&window->devPrivates, ephyrDRIWindowKey, win_priv);
+ EPHYR_LOG ("paired window '%p' with remote '%d'\n",
+ window, remote_win) ;
+ }
+
+ WriteToClient(client, sizeof(xXF86DRICreateDrawableReply), (char *)&rep);
+ EPHYR_LOG ("leave\n") ;
+ return Success;
+}
+
+static int
+ProcXF86DRIDestroyDrawable (register ClientPtr client)
+{
+ DrawablePtr drawable=NULL;
+ WindowPtr window=NULL;
+ EphyrWindowPair *pair=NULL;
+ int rc=0;
+ REQUEST(xXF86DRIDestroyDrawableReq);
+ REQUEST_SIZE_MATCH(xXF86DRIDestroyDrawableReq);
+
+ EPHYR_LOG ("enter\n") ;
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rc = dixLookupDrawable(&drawable,
+ stuff->drawable,
+ client,
+ 0,
+ DixReadAccess);
+ if (rc != Success)
+ return rc;
+ if (drawable->type != DRAWABLE_WINDOW) {
+ EPHYR_LOG_ERROR ("non drawable windows are not yet supported\n") ;
+ return BadImplementation ;
+ }
+ window = (WindowPtr)drawable;
+ if (!findWindowPairFromLocal (window, &pair) && pair) {
+ EPHYR_LOG_ERROR ("failed to find pair window\n") ;
+ return BadImplementation;
+ }
+ if (!ephyrDRIDestroyDrawable(stuff->screen,
+ pair->remote/*drawable in host x*/)) {
+ EPHYR_LOG_ERROR ("failed to destroy dri drawable\n") ;
+ return BadImplementation;
+ }
+ pair->local=NULL ;
+ pair->remote=0;
+
+ EPHYR_LOG ("leave\n") ;
+ return Success;
+}
+
+static int
+ProcXF86DRIGetDrawableInfo (register ClientPtr client)
+{
+ xXF86DRIGetDrawableInfoReply rep;
+ DrawablePtr drawable;
+ WindowPtr window=NULL;
+ EphyrWindowPair *pair=NULL;
+ int X=0, Y=0, W=0, H=0, backX=0, backY=0, rc=0, i=0;
+ drm_clip_rect_t *clipRects=NULL;
+ drm_clip_rect_t *backClipRects=NULL;
+ REQUEST(xXF86DRIGetDrawableInfoReq);
+ REQUEST_SIZE_MATCH(xXF86DRIGetDrawableInfoReq);
+
+ EPHYR_LOG ("enter\n") ;
+ memset (&rep, 0, sizeof (rep)) ;
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ rc = dixLookupDrawable(&drawable, stuff->drawable, client, 0,
+ DixReadAccess);
+ if (rc != Success || !drawable) {
+ EPHYR_LOG_ERROR ("could not get drawable\n") ;
+ return rc;
+ }
+
+ if (drawable->type != DRAWABLE_WINDOW) {
+ EPHYR_LOG_ERROR ("non windows type drawables are not yes supported\n") ;
+ return BadImplementation ;
+ }
+ window = (WindowPtr)drawable ;
+ memset (&pair, 0, sizeof (pair)) ;
+ if (!findWindowPairFromLocal (window, &pair) || !pair) {
+ EPHYR_LOG_ERROR ("failed to find remote peer drawable\n") ;
+ return BadMatch ;
+ }
+ EPHYR_LOG ("clip list of xephyr gl drawable:\n") ;
+ for (i=0; i < REGION_NUM_RECTS (&window->clipList); i++) {
+ EPHYR_LOG ("x1:%d, y1:%d, x2:%d, y2:%d\n",
+ REGION_RECTS (&window->clipList)[i].x1,
+ REGION_RECTS (&window->clipList)[i].y1,
+ REGION_RECTS (&window->clipList)[i].x2,
+ REGION_RECTS (&window->clipList)[i].y2) ;
+ }
+
+ if (!ephyrDRIGetDrawableInfo (stuff->screen,
+ pair->remote/*the drawable in hostx*/,
+ (unsigned int*)&rep.drawableTableIndex,
+ (unsigned int*)&rep.drawableTableStamp,
+ (int*)&X,
+ (int*)&Y,
+ (int*)&W,
+ (int*)&H,
+ (int*)&rep.numClipRects,
+ &clipRects,
+ &backX,
+ &backY,
+ (int*)&rep.numBackClipRects,
+ &backClipRects)) {
+ return BadValue;
+ }
+ EPHYR_LOG ("num clip rects:%d, num back clip rects:%d\n",
+ (int)rep.numClipRects, (int)rep.numBackClipRects) ;
+
+ rep.drawableX = X;
+ rep.drawableY = Y;
+ rep.drawableWidth = W;
+ rep.drawableHeight = H;
+ rep.length = (SIZEOF(xXF86DRIGetDrawableInfoReply) -
+ SIZEOF(xGenericReply));
+
+ rep.backX = backX;
+ rep.backY = backY;
+
+
+ if (rep.numClipRects) {
+ if (clipRects) {
+ ScreenPtr pScreen = screenInfo.screens[stuff->screen];
+ int i=0;
+ EPHYR_LOG ("clip list of host gl drawable:\n") ;
+ for (i = 0; i < rep.numClipRects; i++) {
+ clipRects[i].x1 = max (clipRects[i].x1, 0);
+ clipRects[i].y1 = max (clipRects[i].y1, 0);
+ clipRects[i].x2 = min (clipRects[i].x2,
+ pScreen->width + clipRects[i].x1) ;
+ clipRects[i].y2 = min (clipRects[i].y2,
+ pScreen->width + clipRects[i].y1) ;
+
+ EPHYR_LOG ("x1:%d, y1:%d, x2:%d, y2:%d\n",
+ clipRects[i].x1, clipRects[i].y1,
+ clipRects[i].x2, clipRects[i].y2) ;
+ }
+ } else {
+ rep.numClipRects = 0;
+ }
+ } else {
+ EPHYR_LOG ("got zero host gl drawable clipping rects\n") ;
+ }
+ rep.length += sizeof(drm_clip_rect_t) * rep.numClipRects;
+ backClipRects = clipRects ;
+ rep.numBackClipRects = rep.numClipRects ;
+ if (rep.numBackClipRects)
+ rep.length += sizeof(drm_clip_rect_t) * rep.numBackClipRects;
+ EPHYR_LOG ("num host clip rects:%d\n", (int)rep.numClipRects) ;
+ EPHYR_LOG ("num host back clip rects:%d\n", (int)rep.numBackClipRects) ;
+
+ rep.length = bytes_to_int32(rep.length);
+
+ WriteToClient(client, sizeof(xXF86DRIGetDrawableInfoReply), (char *)&rep);
+
+ if (rep.numClipRects) {
+ WriteToClient(client,
+ sizeof(drm_clip_rect_t) * rep.numClipRects,
+ (char *)clipRects);
+ }
+
+ if (rep.numBackClipRects) {
+ WriteToClient(client,
+ sizeof(drm_clip_rect_t) * rep.numBackClipRects,
+ (char *)backClipRects);
+ }
+ free(clipRects);
+ clipRects = NULL ;
+
+ EPHYR_LOG ("leave\n") ;
+
+ return Success;
+}
+
+static int
+ProcXF86DRIGetDeviceInfo (register ClientPtr client)
+{
+ xXF86DRIGetDeviceInfoReply rep;
+ drm_handle_t hFrameBuffer;
+ void *pDevPrivate;
+ REQUEST(xXF86DRIGetDeviceInfoReq);
+ REQUEST_SIZE_MATCH(xXF86DRIGetDeviceInfoReq);
+
+ EPHYR_LOG ("enter\n") ;
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ if (!ephyrDRIGetDeviceInfo (stuff->screen,
+ &hFrameBuffer,
+ (int*)&rep.framebufferOrigin,
+ (int*)&rep.framebufferSize,
+ (int*)&rep.framebufferStride,
+ (int*)&rep.devPrivateSize,
+ &pDevPrivate)) {
+ return BadValue;
+ }
+
+ rep.hFrameBufferLow = (CARD32)(hFrameBuffer & 0xffffffff);
+#if defined(LONG64) && !defined(__linux__)
+ rep.hFrameBufferHigh = (CARD32)(hFrameBuffer >> 32);
+#else
+ rep.hFrameBufferHigh = 0;
+#endif
+
+ rep.length = 0;
+ if (rep.devPrivateSize) {
+ rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetDeviceInfoReply) -
+ SIZEOF(xGenericReply) +
+ pad_to_int32(rep.devPrivateSize));
+ }
+
+ WriteToClient(client, sizeof(xXF86DRIGetDeviceInfoReply), (char *)&rep);
+ if (rep.length) {
+ WriteToClient(client, rep.devPrivateSize, (char *)pDevPrivate);
+ }
+ EPHYR_LOG ("leave\n") ;
+ return Success;
+}
+
+static int
+ProcXF86DRIDispatch (register ClientPtr client)
+{
+ REQUEST(xReq);
+ EPHYR_LOG ("enter\n") ;
+
+ switch (stuff->data)
+ {
+ case X_XF86DRIQueryVersion: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIQueryVersion(client);
+ }
+ case X_XF86DRIQueryDirectRenderingCapable: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIQueryDirectRenderingCapable(client);
+ }
+ }
+
+ if (!LocalClient(client))
+ return DRIErrorBase + XF86DRIClientNotLocal;
+
+ switch (stuff->data)
+ {
+ case X_XF86DRIOpenConnection: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIOpenConnection(client);
+ }
+ case X_XF86DRICloseConnection: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRICloseConnection(client);
+ }
+ case X_XF86DRIGetClientDriverName: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIGetClientDriverName(client);
+ }
+ case X_XF86DRICreateContext: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRICreateContext(client);
+ }
+ case X_XF86DRIDestroyContext: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIDestroyContext(client);
+ }
+ case X_XF86DRICreateDrawable: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRICreateDrawable(client);
+ }
+ case X_XF86DRIDestroyDrawable: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIDestroyDrawable(client);
+ }
+ case X_XF86DRIGetDrawableInfo: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIGetDrawableInfo(client);
+ }
+ case X_XF86DRIGetDeviceInfo: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIGetDeviceInfo(client);
+ }
+ case X_XF86DRIAuthConnection: {
+ EPHYR_LOG ("leave\n") ;
+ return ProcXF86DRIAuthConnection(client);
+ }
+ /* {Open,Close}FullScreen are deprecated now */
+ default: {
+ EPHYR_LOG ("leave\n") ;
+ return BadRequest;
+ }
+ }
+}
+
+static int
+SProcXF86DRIQueryVersion (register ClientPtr client)
+{
+ register int n;
+ REQUEST(xXF86DRIQueryVersionReq);
+ swaps(&stuff->length, n);
+ return ProcXF86DRIQueryVersion(client);
+}
+
+static int
+SProcXF86DRIQueryDirectRenderingCapable (register ClientPtr client)
+{
+ register int n;
+ REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->screen, n);
+ return ProcXF86DRIQueryDirectRenderingCapable(client);
+}
+
+static int
+SProcXF86DRIDispatch (register ClientPtr client)
+{
+ REQUEST(xReq);
+
+ EPHYR_LOG ("enter\n") ;
+ /*
+ * Only local clients are allowed DRI access, but remote clients still need
+ * these requests to find out cleanly.
+ */
+ switch (stuff->data)
+ {
+ case X_XF86DRIQueryVersion: {
+ EPHYR_LOG ("leave\n") ;
+ return SProcXF86DRIQueryVersion(client);
+ }
+ case X_XF86DRIQueryDirectRenderingCapable: {
+ EPHYR_LOG ("leave\n") ;
+ return SProcXF86DRIQueryDirectRenderingCapable(client);
+ }
+ default: {
+ EPHYR_LOG ("leave\n") ;
+ return DRIErrorBase + XF86DRIClientNotLocal;
+ }
+ }
+}
diff --git a/xorg-server/hw/kdrive/ephyr/ephyrglxext.c b/xorg-server/hw/kdrive/ephyr/ephyrglxext.c
index a0278cc2b..d6b8ca66d 100644
--- a/xorg-server/hw/kdrive/ephyr/ephyrglxext.c
+++ b/xorg-server/hw/kdrive/ephyr/ephyrglxext.c
@@ -1,723 +1,723 @@
-/*
- * Xephyr - A kdrive X server thats runs in a host X window.
- * Authored by Matthew Allum <mallum@openedhand.com>
- *
- * Copyright © 2007 OpenedHand Ltd
- *
- * 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 OpenedHand Ltd not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. OpenedHand Ltd makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- * Authors:
- * Dodji Seketeli <dodji@openedhand.com>
- */
-#ifdef HAVE_CONFIG_H
-#include <kdrive-config.h>
-#endif
-
-#include "extnsionst.h"
-#include "ephyrglxext.h"
-#include "ephyrhostglx.h"
-#define _HAVE_XALLOC_DECLS
-#include "ephyrlog.h"
-#include <GL/glxproto.h>
-#include "glx/glxserver.h"
-#include "glx/indirect_table.h"
-#include "glx/indirect_util.h"
-#include "glx/unpack.h"
-#include "hostx.h"
-
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-
-int ephyrGLXQueryVersion (__GLXclientState *cl, GLbyte *pc) ;
-int ephyrGLXQueryVersionSwap (__GLXclientState *cl, GLbyte *pc) ;
-int ephyrGLXGetVisualConfigs (__GLXclientState *cl, GLbyte *pc) ;
-int ephyrGLXGetVisualConfigsSwap (__GLXclientState *cl, GLbyte *pc) ;
-int ephyrGLXClientInfo(__GLXclientState *cl, GLbyte *pc) ;
-int ephyrGLXClientInfoSwap(__GLXclientState *cl, GLbyte *pc) ;
-int ephyrGLXQueryServerString(__GLXclientState *a_cl, GLbyte *a_pc) ;
-int ephyrGLXQueryServerStringSwap(__GLXclientState *a_cl, GLbyte *a_pc) ;
-int ephyrGLXGetFBConfigsSGIX (__GLXclientState *a_cl, GLbyte *a_pc);
-int ephyrGLXGetFBConfigsSGIXSwap (__GLXclientState *a_cl, GLbyte *a_pc);
-int ephyrGLXCreateContext (__GLXclientState *a_cl, GLbyte *a_pc);
-int ephyrGLXCreateContextSwap (__GLXclientState *a_cl, GLbyte *a_pc);
-int ephyrGLXDestroyContext (__GLXclientState *a_cl, GLbyte *a_pc) ;
-int ephyrGLXDestroyContextSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
-int ephyrGLXMakeCurrent (__GLXclientState *a_cl, GLbyte *a_pc) ;
-int ephyrGLXMakeCurrentSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
-int ephyrGLXGetString (__GLXclientState *a_cl, GLbyte *a_pc) ;
-int ephyrGLXGetStringSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
-int ephyrGLXGetIntegerv (__GLXclientState *a_cl, GLbyte *a_pc) ;
-int ephyrGLXGetIntegervSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
-int ephyrGLXIsDirect (__GLXclientState *a_cl, GLbyte *a_pc) ;
-int ephyrGLXIsDirectSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
-
-Bool
-ephyrHijackGLXExtension (void)
-{
- const void *(*dispatch_functions)[2];
-
- if (!hostx_has_glx ()) {
- EPHYR_LOG ("host X does not have GLX\n") ;
- return FALSE ;
- }
- EPHYR_LOG ("host X does have GLX\n") ;
-
- if (!Single_dispatch_info.dispatch_functions) {
- EPHYR_LOG_ERROR ("could not get dispatch functions table\n") ;
- return FALSE ;
- }
- /*
- * hijack some single entry point dispatch functions
- */
- dispatch_functions = Single_dispatch_info.dispatch_functions ;
- EPHYR_RETURN_VAL_IF_FAIL (dispatch_functions, FALSE) ;
-
- dispatch_functions[X_GLXQueryVersion][0] = ephyrGLXQueryVersion ;
- dispatch_functions[X_GLXQueryVersion][1] = ephyrGLXQueryVersionSwap ;
-
- dispatch_functions[X_GLXGetVisualConfigs][0] = ephyrGLXGetVisualConfigs ;
- dispatch_functions[X_GLXGetVisualConfigs][1] = ephyrGLXGetVisualConfigsSwap ;
- dispatch_functions[X_GLXClientInfo][0] = ephyrGLXClientInfo ;
- dispatch_functions[X_GLXClientInfo][1] = ephyrGLXClientInfoSwap ;
-
- dispatch_functions[X_GLXQueryServerString][0] = ephyrGLXQueryServerString ;
- dispatch_functions[X_GLXQueryServerString][1] =
- ephyrGLXQueryServerStringSwap ;
-
- dispatch_functions[X_GLXCreateContext][0] = ephyrGLXCreateContext ;
- dispatch_functions[X_GLXCreateContext][1] = ephyrGLXCreateContextSwap ;
-
- dispatch_functions[X_GLXDestroyContext][0] = ephyrGLXDestroyContext ;
- dispatch_functions[X_GLXDestroyContext][1] = ephyrGLXDestroyContextSwap ;
-
- dispatch_functions[X_GLXMakeCurrent][0] = ephyrGLXMakeCurrent ;
- dispatch_functions[X_GLXMakeCurrent][1] = ephyrGLXMakeCurrentSwap ;
-
- dispatch_functions[X_GLXIsDirect][0] = ephyrGLXIsDirect ;
- dispatch_functions[X_GLXIsDirect][1] = ephyrGLXIsDirectSwap ;
-
- dispatch_functions[73][0] = ephyrGLXGetString ;
- dispatch_functions[73][1] = ephyrGLXGetStringSwap ;
-
- dispatch_functions[61][0] = ephyrGLXGetIntegerv ;
- dispatch_functions[61][1] = ephyrGLXGetIntegervSwap ;
-
- /*
- * hijack some vendor priv entry point dispatch functions
- */
- dispatch_functions = VendorPriv_dispatch_info.dispatch_functions ;
- dispatch_functions[92][0] = ephyrGLXGetFBConfigsSGIX;
- dispatch_functions[92][1] = ephyrGLXGetFBConfigsSGIXSwap;
- EPHYR_LOG ("hijacked glx entry points to forward requests to host X\n") ;
-
- return TRUE ;
-}
-
-/*********************
- * implementation of
- * hijacked GLX entry
- * points
- ********************/
-
-int
-ephyrGLXQueryVersion(__GLXclientState *a_cl, GLbyte *a_pc)
-{
- ClientPtr client = a_cl->client;
- xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) a_pc;
- xGLXQueryVersionReply reply;
- int major, minor;
- int res = BadImplementation ;
-
- EPHYR_LOG ("enter\n") ;
-
- major = req->majorVersion ;
- minor = req->minorVersion ;
-
- if (!ephyrHostGLXQueryVersion (&major, &minor)) {
- EPHYR_LOG_ERROR ("ephyrHostGLXQueryVersion() failed\n") ;
- goto out ;
- }
- EPHYR_LOG ("major:%d, minor:%d\n",
- major, minor);
- reply.majorVersion = major ;
- reply.minorVersion = minor ;
- reply.length = 0 ;
- reply.type = X_Reply ;
- reply.sequenceNumber = client->sequence ;
-
- if (client->swapped) {
- __glXSwapQueryVersionReply(client, &reply);
- } else {
- WriteToClient(client, sz_xGLXQueryVersionReply, (char *)&reply);
- }
-
- res = Success ;
-out:
- EPHYR_LOG ("leave\n") ;
- return res;
-}
-
-int
-ephyrGLXQueryVersionSwap (__GLXclientState *a_cl, GLbyte *a_pc)
-{
- xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) a_pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT (&req->length);
- __GLX_SWAP_INT (&req->majorVersion);
- __GLX_SWAP_INT (&req->minorVersion);
- return ephyrGLXQueryVersion (a_cl, a_pc) ;
-}
-
-static int
-ephyrGLXGetVisualConfigsReal (__GLXclientState *a_cl,
- GLbyte *a_pc,
- Bool a_do_swap)
-{
- xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) a_pc;
- ClientPtr client = a_cl->client;
- xGLXGetVisualConfigsReply reply;
- int32_t *props_buf=NULL, num_visuals=0,
- num_props=0, res=BadImplementation, i=0,
- props_per_visual_size=0,
- props_buf_size=0;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- EPHYR_LOG ("enter\n") ;
-
- if (!ephyrHostGLXGetVisualConfigs (req->screen,
- &num_visuals,
- &num_props,
- &props_buf_size,
- &props_buf)) {
- EPHYR_LOG_ERROR ("ephyrHostGLXGetVisualConfigs() failed\n") ;
- goto out ;
- }
- EPHYR_LOG ("num_visuals:%d, num_props:%d\n", num_visuals, num_props) ;
-
- reply.numVisuals = num_visuals;
- reply.numProps = num_props;
- reply.length = (num_visuals *__GLX_SIZE_CARD32 * num_props) >> 2;
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
-
- if (a_do_swap) {
- __GLX_SWAP_SHORT(&reply.sequenceNumber);
- __GLX_SWAP_INT(&reply.length);
- __GLX_SWAP_INT(&reply.numVisuals);
- __GLX_SWAP_INT(&reply.numProps);
- __GLX_SWAP_INT_ARRAY (props_buf, num_props) ;
- }
- WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char*)&reply);
- props_per_visual_size = props_buf_size/num_visuals ;
- for (i=0; i < num_visuals; i++) {
- WriteToClient (client,
- props_per_visual_size,
- (char*)props_buf +i*props_per_visual_size);
- }
- res = Success ;
-
-out:
- EPHYR_LOG ("leave\n") ;
- xfree (props_buf) ;
- props_buf = NULL ;
-
- return res ;
-}
-
-static int
-ephyrGLXGetFBConfigsSGIXReal (__GLXclientState *a_cl,
- GLbyte *a_pc,
- Bool a_do_swap)
-{
- xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *)a_pc;
- ClientPtr client = a_cl->client;
- xGLXGetVisualConfigsReply reply;
- int32_t *props_buf=NULL, num_visuals=0,
- num_props=0, res=BadImplementation, i=0,
- props_per_visual_size=0,
- props_buf_size=0;
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
-
- EPHYR_LOG ("enter\n") ;
-
- if (!ephyrHostGLXVendorPrivGetFBConfigsSGIX (req->screen,
- &num_visuals,
- &num_props,
- &props_buf_size,
- &props_buf)) {
- EPHYR_LOG_ERROR ("ephyrHostGLXGetVisualConfigs() failed\n") ;
- goto out ;
- }
- EPHYR_LOG ("num_visuals:%d, num_props:%d\n", num_visuals, num_props) ;
-
- reply.numVisuals = num_visuals;
- reply.numProps = num_props;
- reply.length = props_buf_size >> 2;
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
-
- if (a_do_swap) {
- __GLX_SWAP_SHORT(&reply.sequenceNumber);
- __GLX_SWAP_INT(&reply.length);
- __GLX_SWAP_INT(&reply.numVisuals);
- __GLX_SWAP_INT(&reply.numProps);
- __GLX_SWAP_INT_ARRAY (props_buf, num_props) ;
- }
- WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char*)&reply);
- props_per_visual_size = props_buf_size/num_visuals ;
- for (i=0; i < num_visuals; i++) {
- WriteToClient (client,
- props_per_visual_size,
- &((char*)props_buf)[i*props_per_visual_size]);
- }
- res = Success ;
-
-out:
- EPHYR_LOG ("leave\n") ;
- xfree (props_buf) ;
- props_buf = NULL ;
-
- return res ;
-}
-
-int
-ephyrGLXGetVisualConfigs (__GLXclientState *a_cl, GLbyte *a_pc)
-{
- return ephyrGLXGetVisualConfigsReal (a_cl, a_pc, FALSE) ;
-}
-
-int
-ephyrGLXGetVisualConfigsSwap (__GLXclientState *a_cl, GLbyte *a_pc)
-{
- return ephyrGLXGetVisualConfigsReal (a_cl, a_pc, TRUE) ;
-}
-
-
-int
-ephyrGLXClientInfo(__GLXclientState *a_cl, GLbyte *a_pc)
-{
- int res=BadImplementation ;
- xGLXClientInfoReq *req = (xGLXClientInfoReq *) a_pc;
-
- EPHYR_LOG ("enter\n") ;
- if (!ephyrHostGLXSendClientInfo (req->major, req->minor, (char*)req+1)) {
- EPHYR_LOG_ERROR ("failed to send client info to host\n") ;
- goto out ;
- }
- res = Success ;
-
-out:
- EPHYR_LOG ("leave\n") ;
- return res ;
-}
-
-int
-ephyrGLXClientInfoSwap (__GLXclientState *a_cl, GLbyte *a_pc)
-{
- xGLXClientInfoReq *req = (xGLXClientInfoReq *)a_pc;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- __GLX_SWAP_SHORT (&req->length);
- __GLX_SWAP_INT (&req->major);
- __GLX_SWAP_INT (&req->minor);
- __GLX_SWAP_INT (&req->numbytes);
-
- return ephyrGLXClientInfo (a_cl, a_pc) ;
-}
-
-int
-ephyrGLXQueryServerString(__GLXclientState *a_cl, GLbyte *a_pc)
-{
- int res = BadImplementation ;
- ClientPtr client = a_cl->client;
- xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) a_pc;
- xGLXQueryServerStringReply reply;
- char *server_string=NULL, *buf=NULL;
- int length=0 ;
-
- EPHYR_LOG ("enter\n") ;
- if (!ephyrHostGLXGetStringFromServer (req->screen,
- req->name,
- EPHYR_HOST_GLX_QueryServerString,
- &server_string)) {
- EPHYR_LOG_ERROR ("failed to query string from host\n") ;
- goto out ;
- }
- EPHYR_LOG ("string: %s\n", server_string) ;
- length= strlen (server_string) + 1;
- reply.type = X_Reply ;
- reply.sequenceNumber = client->sequence ;
- reply.length = __GLX_PAD (length) >> 2 ;
- reply.n = length ;
- buf = xcalloc (reply.length << 2, 1);
- if (!buf) {
- EPHYR_LOG_ERROR ("failed to allocate string\n;");
- return BadAlloc;
- }
- memcpy (buf, server_string, length);
-
- WriteToClient(client, sz_xGLXQueryServerStringReply, (char*)&reply);
- WriteToClient(client, (int)(reply.length << 2), server_string);
-
- res = Success ;
-
-out:
- EPHYR_LOG ("leave\n") ;
- xfree (server_string) ;
- server_string = NULL;
-
- xfree (buf);
- buf = NULL;
-
- return res ;
-}
-
-int
-ephyrGLXQueryServerStringSwap(__GLXclientState *a_cl, GLbyte *a_pc)
-{
- EPHYR_LOG_ERROR ("not yet implemented\n") ;
- return BadImplementation ;
-}
-
-
-int
-ephyrGLXGetFBConfigsSGIX (__GLXclientState *a_cl, GLbyte *a_pc)
-{
- return ephyrGLXGetFBConfigsSGIXReal (a_cl, a_pc, FALSE) ;
-}
-
-int
-ephyrGLXGetFBConfigsSGIXSwap (__GLXclientState *a_cl, GLbyte *a_pc)
-{
- return ephyrGLXGetFBConfigsSGIXReal (a_cl, a_pc, TRUE) ;
-}
-
-static int
-ephyrGLXCreateContextReal (xGLXCreateContextReq *a_req, Bool a_do_swap)
-{
- int res=BadImplementation;
- EphyrHostWindowAttributes host_w_attrs ;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_req, BadValue) ;
- EPHYR_LOG ("enter\n") ;
-
- if (a_do_swap) {
- __GLX_SWAP_SHORT(&a_req->length);
- __GLX_SWAP_INT(&a_req->context);
- __GLX_SWAP_INT(&a_req->visual);
- __GLX_SWAP_INT(&a_req->screen);
- __GLX_SWAP_INT(&a_req->shareList);
- }
-
- EPHYR_LOG ("context creation requested. localid:%d, "
- "screen:%d, visual:%d, direct:%d\n",
- (int)a_req->context, (int)a_req->screen,
- (int)a_req->visual, (int)a_req->isDirect) ;
-
- memset (&host_w_attrs, 0, sizeof (host_w_attrs)) ;
- if (!hostx_get_window_attributes (hostx_get_window (a_req->screen),
- &host_w_attrs)) {
- EPHYR_LOG_ERROR ("failed to get host window attrs\n") ;
- goto out ;
- }
-
- EPHYR_LOG ("host window visual id: %d\n", host_w_attrs.visualid) ;
-
- if (!ephyrHostGLXCreateContext (a_req->screen,
- host_w_attrs.visualid,
- a_req->context,
- a_req->shareList,
- a_req->isDirect)) {
- EPHYR_LOG_ERROR ("ephyrHostGLXCreateContext() failed\n") ;
- goto out ;
- }
- res = Success;
-out:
- EPHYR_LOG ("leave\n") ;
- return res ;
-}
-
-int
-ephyrGLXCreateContext (__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
-
- return ephyrGLXCreateContextReal (req, FALSE) ;
-}
-
-int ephyrGLXCreateContextSwap (__GLXclientState *cl, GLbyte *pc)
-{
- xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
- return ephyrGLXCreateContextReal (req, TRUE) ;
-}
-
-static int
-ephyrGLXDestroyContextReal (__GLXclientState *a_cl,
- GLbyte *a_pc,
- Bool a_do_swap)
-{
- int res=BadImplementation;
- ClientPtr client = a_cl->client;
- xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) a_pc;
-
- EPHYR_LOG ("enter. id:%d\n", (int)req->context) ;
- if (!ephyrHostDestroyContext (req->context)) {
- EPHYR_LOG_ERROR ("ephyrHostDestroyContext() failed\n") ;
- client->errorValue = req->context ;
- goto out ;
- }
- res = Success ;
-
-out:
- EPHYR_LOG ("leave\n") ;
- return res ;
-}
-
-int
-ephyrGLXDestroyContext (__GLXclientState *a_cl, GLbyte *a_pc)
-{
- return ephyrGLXDestroyContextReal (a_cl, a_pc, FALSE) ;
-}
-
-int
-ephyrGLXDestroyContextSwap (__GLXclientState *a_cl, GLbyte *a_pc)
-{
- return ephyrGLXDestroyContextReal (a_cl, a_pc, TRUE) ;
-}
-
-static int
-ephyrGLXMakeCurrentReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
-{
- int res=BadImplementation;
- xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) a_pc;
- xGLXMakeCurrentReply reply ;
- DrawablePtr drawable=NULL;
- int rc=0;
-
- EPHYR_LOG ("enter\n") ;
- rc = dixLookupDrawable (&drawable,
- req->drawable,
- a_cl->client,
- 0,
- DixReadAccess);
- EPHYR_RETURN_VAL_IF_FAIL (drawable, BadValue) ;
- EPHYR_RETURN_VAL_IF_FAIL (drawable->pScreen, BadValue) ;
- EPHYR_LOG ("screen nummber requested:%d\n",
- drawable->pScreen->myNum) ;
-
- memset (&reply, 0, sizeof (reply)) ;
- if (!ephyrHostGLXMakeCurrent (hostx_get_window (drawable->pScreen->myNum),
- req->context,
- req->oldContextTag,
- (int*)&reply.contextTag)) {
- EPHYR_LOG_ERROR ("ephyrHostGLXMakeCurrent() failed\n") ;
- goto out;
- }
- reply.length = 0;
- reply.type = X_Reply;
- reply.sequenceNumber = a_cl->client->sequence;
- if (a_do_swap) {
- __GLX_DECLARE_SWAP_VARIABLES;
- __GLX_SWAP_SHORT(&reply.sequenceNumber);
- __GLX_SWAP_INT(&reply.length);
- __GLX_SWAP_INT(&reply.contextTag);
- }
- WriteToClient(a_cl->client, sz_xGLXMakeCurrentReply, (char *)&reply);
-
- res = Success ;
-out:
- EPHYR_LOG ("leave\n") ;
- return res ;
-}
-
-int
-ephyrGLXMakeCurrent (__GLXclientState *a_cl, GLbyte *a_pc)
-{
- return ephyrGLXMakeCurrentReal (a_cl, a_pc, FALSE) ;
-}
-
-int
-ephyrGLXMakeCurrentSwap (__GLXclientState *a_cl, GLbyte *a_pc)
-{
- return ephyrGLXMakeCurrentReal (a_cl, a_pc, TRUE) ;
-}
-
-static int
-ephyrGLXGetStringReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
-{
- ClientPtr client=NULL ;
- int context_tag=0, name=0, res=BadImplementation, length=0 ;
- char *string=NULL;
- __GLX_DECLARE_SWAP_VARIABLES;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_cl && a_pc, BadValue) ;
-
- EPHYR_LOG ("enter\n") ;
-
- client = a_cl->client ;
-
- if (a_do_swap) {
- __GLX_SWAP_INT (a_pc + 4);
- __GLX_SWAP_INT (a_pc + __GLX_SINGLE_HDR_SIZE);
- }
- context_tag = __GLX_GET_SINGLE_CONTEXT_TAG (a_pc) ;
- a_pc += __GLX_SINGLE_HDR_SIZE;
- name = *(GLenum*)(a_pc + 0);
- EPHYR_LOG ("context_tag:%d, name:%d\n", context_tag, name) ;
- if (!ephyrHostGLXGetStringFromServer (context_tag,
- name,
- EPHYR_HOST_GLX_GetString,
- &string)) {
- EPHYR_LOG_ERROR ("failed to get string from server\n") ;
- goto out ;
- }
- if (string) {
- length = strlen (string) + 1;
- EPHYR_LOG ("got string:'%s', size:%d\n", string, length) ;
- } else {
- EPHYR_LOG ("got string: string (null)\n") ;
- }
- __GLX_BEGIN_REPLY (length);
- __GLX_PUT_SIZE (length);
- __GLX_SEND_HEADER ();
- if (a_do_swap) {
- __GLX_SWAP_REPLY_SIZE ();
- __GLX_SWAP_REPLY_HEADER ();
- }
- WriteToClient (client, length, (char *)string);
-
- res = Success ;
-out:
- EPHYR_LOG ("leave\n") ;
- return res ;
-}
-
-int
-ephyrGLXGetString (__GLXclientState *a_cl, GLbyte *a_pc)
-{
- return ephyrGLXGetStringReal (a_cl, a_pc, FALSE) ;
-}
-
-int
-ephyrGLXGetStringSwap (__GLXclientState *a_cl, GLbyte *a_pc)
-{
- return ephyrGLXGetStringReal (a_cl, a_pc, TRUE) ;
-}
-
-static int
-ephyrGLXGetIntegervReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
-{
- int res=BadImplementation;
- xGLXSingleReq * const req = (xGLXSingleReq *) a_pc;
- GLenum int_name ;
- int value=0 ;
- GLint answer_buf_room[200];
- GLint *buf=NULL ;
-
- EPHYR_LOG ("enter\n") ;
-
- a_pc += __GLX_SINGLE_HDR_SIZE;
-
- int_name = *(GLenum*) (a_pc+0) ;
- if (!ephyrHostGetIntegerValue (req->contextTag, int_name, &value)) {
- EPHYR_LOG_ERROR ("ephyrHostGetIntegerValue() failed\n") ;
- goto out ;
- }
- buf = __glXGetAnswerBuffer (a_cl, sizeof (value),
- answer_buf_room,
- sizeof (answer_buf_room),
- 4) ;
-
- if (!buf) {
- EPHYR_LOG_ERROR ("failed to allocate reply buffer\n") ;
- res = BadAlloc ;
- goto out ;
- }
- __glXSendReply (a_cl->client, buf, 1, sizeof (value), GL_FALSE, 0) ;
- res = Success ;
-
-out:
- EPHYR_LOG ("leave\n") ;
- return res ;
-}
-
-int
-ephyrGLXGetIntegerv (__GLXclientState *a_cl, GLbyte *a_pc)
-{
- return ephyrGLXGetIntegervReal (a_cl, a_pc, FALSE) ;
-}
-
-int
-ephyrGLXGetIntegervSwap (__GLXclientState *a_cl, GLbyte *a_pc)
-{
- return ephyrGLXGetIntegervReal (a_cl, a_pc, TRUE) ;
-}
-
-static int
-ephyrGLXIsDirectReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
-{
- int res=BadImplementation;
- ClientPtr client = a_cl->client;
- xGLXIsDirectReq *req = (xGLXIsDirectReq *) a_pc;
- xGLXIsDirectReply reply;
- int is_direct=0 ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_cl && a_pc, FALSE) ;
-
- EPHYR_LOG ("enter\n") ;
-
- memset (&reply, 0, sizeof (reply)) ;
- if (!ephyrHostIsContextDirect (req->context, (int*)&is_direct)) {
- EPHYR_LOG_ERROR ("ephyrHostIsContextDirect() failed\n") ;
- goto out ;
- }
- reply.isDirect = is_direct ;
- reply.length = 0;
- reply.type = X_Reply;
- reply.sequenceNumber = client->sequence;
- WriteToClient(client, sz_xGLXIsDirectReply, (char *)&reply);
- res = Success ;
-
-out:
- EPHYR_LOG ("leave\n") ;
- return res ;
-}
-
-int
-ephyrGLXIsDirect (__GLXclientState *a_cl, GLbyte *a_pc)
-{
- return ephyrGLXIsDirectReal (a_cl, a_pc, FALSE) ;
-}
-
-int
-ephyrGLXIsDirectSwap (__GLXclientState *a_cl, GLbyte *a_pc)
-{
- return ephyrGLXIsDirectReal (a_cl, a_pc, TRUE) ;
-}
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ * Authored by Matthew Allum <mallum@openedhand.com>
+ *
+ * Copyright © 2007 OpenedHand Ltd
+ *
+ * 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 OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:
+ * Dodji Seketeli <dodji@openedhand.com>
+ */
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+
+#include "extnsionst.h"
+#include "ephyrglxext.h"
+#include "ephyrhostglx.h"
+#define _HAVE_XALLOC_DECLS
+#include "ephyrlog.h"
+#include <GL/glxproto.h>
+#include "glx/glxserver.h"
+#include "glx/indirect_table.h"
+#include "glx/indirect_util.h"
+#include "glx/unpack.h"
+#include "hostx.h"
+
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+
+int ephyrGLXQueryVersion (__GLXclientState *cl, GLbyte *pc) ;
+int ephyrGLXQueryVersionSwap (__GLXclientState *cl, GLbyte *pc) ;
+int ephyrGLXGetVisualConfigs (__GLXclientState *cl, GLbyte *pc) ;
+int ephyrGLXGetVisualConfigsSwap (__GLXclientState *cl, GLbyte *pc) ;
+int ephyrGLXClientInfo(__GLXclientState *cl, GLbyte *pc) ;
+int ephyrGLXClientInfoSwap(__GLXclientState *cl, GLbyte *pc) ;
+int ephyrGLXQueryServerString(__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXQueryServerStringSwap(__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXGetFBConfigsSGIX (__GLXclientState *a_cl, GLbyte *a_pc);
+int ephyrGLXGetFBConfigsSGIXSwap (__GLXclientState *a_cl, GLbyte *a_pc);
+int ephyrGLXCreateContext (__GLXclientState *a_cl, GLbyte *a_pc);
+int ephyrGLXCreateContextSwap (__GLXclientState *a_cl, GLbyte *a_pc);
+int ephyrGLXDestroyContext (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXDestroyContextSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXMakeCurrent (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXMakeCurrentSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXGetString (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXGetStringSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXGetIntegerv (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXGetIntegervSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXIsDirect (__GLXclientState *a_cl, GLbyte *a_pc) ;
+int ephyrGLXIsDirectSwap (__GLXclientState *a_cl, GLbyte *a_pc) ;
+
+Bool
+ephyrHijackGLXExtension (void)
+{
+ const void *(*dispatch_functions)[2];
+
+ if (!hostx_has_glx ()) {
+ EPHYR_LOG ("host X does not have GLX\n") ;
+ return FALSE ;
+ }
+ EPHYR_LOG ("host X does have GLX\n") ;
+
+ if (!Single_dispatch_info.dispatch_functions) {
+ EPHYR_LOG_ERROR ("could not get dispatch functions table\n") ;
+ return FALSE ;
+ }
+ /*
+ * hijack some single entry point dispatch functions
+ */
+ dispatch_functions = Single_dispatch_info.dispatch_functions ;
+ EPHYR_RETURN_VAL_IF_FAIL (dispatch_functions, FALSE) ;
+
+ dispatch_functions[X_GLXQueryVersion][0] = ephyrGLXQueryVersion ;
+ dispatch_functions[X_GLXQueryVersion][1] = ephyrGLXQueryVersionSwap ;
+
+ dispatch_functions[X_GLXGetVisualConfigs][0] = ephyrGLXGetVisualConfigs ;
+ dispatch_functions[X_GLXGetVisualConfigs][1] = ephyrGLXGetVisualConfigsSwap ;
+ dispatch_functions[X_GLXClientInfo][0] = ephyrGLXClientInfo ;
+ dispatch_functions[X_GLXClientInfo][1] = ephyrGLXClientInfoSwap ;
+
+ dispatch_functions[X_GLXQueryServerString][0] = ephyrGLXQueryServerString ;
+ dispatch_functions[X_GLXQueryServerString][1] =
+ ephyrGLXQueryServerStringSwap ;
+
+ dispatch_functions[X_GLXCreateContext][0] = ephyrGLXCreateContext ;
+ dispatch_functions[X_GLXCreateContext][1] = ephyrGLXCreateContextSwap ;
+
+ dispatch_functions[X_GLXDestroyContext][0] = ephyrGLXDestroyContext ;
+ dispatch_functions[X_GLXDestroyContext][1] = ephyrGLXDestroyContextSwap ;
+
+ dispatch_functions[X_GLXMakeCurrent][0] = ephyrGLXMakeCurrent ;
+ dispatch_functions[X_GLXMakeCurrent][1] = ephyrGLXMakeCurrentSwap ;
+
+ dispatch_functions[X_GLXIsDirect][0] = ephyrGLXIsDirect ;
+ dispatch_functions[X_GLXIsDirect][1] = ephyrGLXIsDirectSwap ;
+
+ dispatch_functions[73][0] = ephyrGLXGetString ;
+ dispatch_functions[73][1] = ephyrGLXGetStringSwap ;
+
+ dispatch_functions[61][0] = ephyrGLXGetIntegerv ;
+ dispatch_functions[61][1] = ephyrGLXGetIntegervSwap ;
+
+ /*
+ * hijack some vendor priv entry point dispatch functions
+ */
+ dispatch_functions = VendorPriv_dispatch_info.dispatch_functions ;
+ dispatch_functions[92][0] = ephyrGLXGetFBConfigsSGIX;
+ dispatch_functions[92][1] = ephyrGLXGetFBConfigsSGIXSwap;
+ EPHYR_LOG ("hijacked glx entry points to forward requests to host X\n") ;
+
+ return TRUE ;
+}
+
+/*********************
+ * implementation of
+ * hijacked GLX entry
+ * points
+ ********************/
+
+int
+ephyrGLXQueryVersion(__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ ClientPtr client = a_cl->client;
+ xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) a_pc;
+ xGLXQueryVersionReply reply;
+ int major, minor;
+ int res = BadImplementation ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ major = req->majorVersion ;
+ minor = req->minorVersion ;
+
+ if (!ephyrHostGLXQueryVersion (&major, &minor)) {
+ EPHYR_LOG_ERROR ("ephyrHostGLXQueryVersion() failed\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("major:%d, minor:%d\n",
+ major, minor);
+ reply.majorVersion = major ;
+ reply.minorVersion = minor ;
+ reply.length = 0 ;
+ reply.type = X_Reply ;
+ reply.sequenceNumber = client->sequence ;
+
+ if (client->swapped) {
+ __glXSwapQueryVersionReply(client, &reply);
+ } else {
+ WriteToClient(client, sz_xGLXQueryVersionReply, (char *)&reply);
+ }
+
+ res = Success ;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return res;
+}
+
+int
+ephyrGLXQueryVersionSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) a_pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT (&req->length);
+ __GLX_SWAP_INT (&req->majorVersion);
+ __GLX_SWAP_INT (&req->minorVersion);
+ return ephyrGLXQueryVersion (a_cl, a_pc) ;
+}
+
+static int
+ephyrGLXGetVisualConfigsReal (__GLXclientState *a_cl,
+ GLbyte *a_pc,
+ Bool a_do_swap)
+{
+ xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) a_pc;
+ ClientPtr client = a_cl->client;
+ xGLXGetVisualConfigsReply reply;
+ int32_t *props_buf=NULL, num_visuals=0,
+ num_props=0, res=BadImplementation, i=0,
+ props_per_visual_size=0,
+ props_buf_size=0;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (!ephyrHostGLXGetVisualConfigs (req->screen,
+ &num_visuals,
+ &num_props,
+ &props_buf_size,
+ &props_buf)) {
+ EPHYR_LOG_ERROR ("ephyrHostGLXGetVisualConfigs() failed\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("num_visuals:%d, num_props:%d\n", num_visuals, num_props) ;
+
+ reply.numVisuals = num_visuals;
+ reply.numProps = num_props;
+ reply.length = (num_visuals *__GLX_SIZE_CARD32 * num_props) >> 2;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+
+ if (a_do_swap) {
+ __GLX_SWAP_SHORT(&reply.sequenceNumber);
+ __GLX_SWAP_INT(&reply.length);
+ __GLX_SWAP_INT(&reply.numVisuals);
+ __GLX_SWAP_INT(&reply.numProps);
+ __GLX_SWAP_INT_ARRAY (props_buf, num_props) ;
+ }
+ WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char*)&reply);
+ props_per_visual_size = props_buf_size/num_visuals ;
+ for (i=0; i < num_visuals; i++) {
+ WriteToClient (client,
+ props_per_visual_size,
+ (char*)props_buf +i*props_per_visual_size);
+ }
+ res = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ free(props_buf) ;
+ props_buf = NULL ;
+
+ return res ;
+}
+
+static int
+ephyrGLXGetFBConfigsSGIXReal (__GLXclientState *a_cl,
+ GLbyte *a_pc,
+ Bool a_do_swap)
+{
+ xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *)a_pc;
+ ClientPtr client = a_cl->client;
+ xGLXGetVisualConfigsReply reply;
+ int32_t *props_buf=NULL, num_visuals=0,
+ num_props=0, res=BadImplementation, i=0,
+ props_per_visual_size=0,
+ props_buf_size=0;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (!ephyrHostGLXVendorPrivGetFBConfigsSGIX (req->screen,
+ &num_visuals,
+ &num_props,
+ &props_buf_size,
+ &props_buf)) {
+ EPHYR_LOG_ERROR ("ephyrHostGLXGetVisualConfigs() failed\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("num_visuals:%d, num_props:%d\n", num_visuals, num_props) ;
+
+ reply.numVisuals = num_visuals;
+ reply.numProps = num_props;
+ reply.length = props_buf_size >> 2;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+
+ if (a_do_swap) {
+ __GLX_SWAP_SHORT(&reply.sequenceNumber);
+ __GLX_SWAP_INT(&reply.length);
+ __GLX_SWAP_INT(&reply.numVisuals);
+ __GLX_SWAP_INT(&reply.numProps);
+ __GLX_SWAP_INT_ARRAY (props_buf, num_props) ;
+ }
+ WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char*)&reply);
+ props_per_visual_size = props_buf_size/num_visuals ;
+ for (i=0; i < num_visuals; i++) {
+ WriteToClient (client,
+ props_per_visual_size,
+ &((char*)props_buf)[i*props_per_visual_size]);
+ }
+ res = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ free(props_buf) ;
+ props_buf = NULL ;
+
+ return res ;
+}
+
+int
+ephyrGLXGetVisualConfigs (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXGetVisualConfigsReal (a_cl, a_pc, FALSE) ;
+}
+
+int
+ephyrGLXGetVisualConfigsSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXGetVisualConfigsReal (a_cl, a_pc, TRUE) ;
+}
+
+
+int
+ephyrGLXClientInfo(__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ int res=BadImplementation ;
+ xGLXClientInfoReq *req = (xGLXClientInfoReq *) a_pc;
+
+ EPHYR_LOG ("enter\n") ;
+ if (!ephyrHostGLXSendClientInfo (req->major, req->minor, (char*)req+1)) {
+ EPHYR_LOG_ERROR ("failed to send client info to host\n") ;
+ goto out ;
+ }
+ res = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return res ;
+}
+
+int
+ephyrGLXClientInfoSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ xGLXClientInfoReq *req = (xGLXClientInfoReq *)a_pc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ __GLX_SWAP_SHORT (&req->length);
+ __GLX_SWAP_INT (&req->major);
+ __GLX_SWAP_INT (&req->minor);
+ __GLX_SWAP_INT (&req->numbytes);
+
+ return ephyrGLXClientInfo (a_cl, a_pc) ;
+}
+
+int
+ephyrGLXQueryServerString(__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ int res = BadImplementation ;
+ ClientPtr client = a_cl->client;
+ xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) a_pc;
+ xGLXQueryServerStringReply reply;
+ char *server_string=NULL, *buf=NULL;
+ int length=0 ;
+
+ EPHYR_LOG ("enter\n") ;
+ if (!ephyrHostGLXGetStringFromServer (req->screen,
+ req->name,
+ EPHYR_HOST_GLX_QueryServerString,
+ &server_string)) {
+ EPHYR_LOG_ERROR ("failed to query string from host\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("string: %s\n", server_string) ;
+ length= strlen (server_string) + 1;
+ reply.type = X_Reply ;
+ reply.sequenceNumber = client->sequence ;
+ reply.length = __GLX_PAD (length) >> 2 ;
+ reply.n = length ;
+ buf = calloc(reply.length << 2, 1);
+ if (!buf) {
+ EPHYR_LOG_ERROR ("failed to allocate string\n;");
+ return BadAlloc;
+ }
+ memcpy (buf, server_string, length);
+
+ WriteToClient(client, sz_xGLXQueryServerStringReply, (char*)&reply);
+ WriteToClient(client, (int)(reply.length << 2), server_string);
+
+ res = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ free(server_string) ;
+ server_string = NULL;
+
+ free(buf);
+ buf = NULL;
+
+ return res ;
+}
+
+int
+ephyrGLXQueryServerStringSwap(__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ EPHYR_LOG_ERROR ("not yet implemented\n") ;
+ return BadImplementation ;
+}
+
+
+int
+ephyrGLXGetFBConfigsSGIX (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXGetFBConfigsSGIXReal (a_cl, a_pc, FALSE) ;
+}
+
+int
+ephyrGLXGetFBConfigsSGIXSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXGetFBConfigsSGIXReal (a_cl, a_pc, TRUE) ;
+}
+
+static int
+ephyrGLXCreateContextReal (xGLXCreateContextReq *a_req, Bool a_do_swap)
+{
+ int res=BadImplementation;
+ EphyrHostWindowAttributes host_w_attrs ;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_req, BadValue) ;
+ EPHYR_LOG ("enter\n") ;
+
+ if (a_do_swap) {
+ __GLX_SWAP_SHORT(&a_req->length);
+ __GLX_SWAP_INT(&a_req->context);
+ __GLX_SWAP_INT(&a_req->visual);
+ __GLX_SWAP_INT(&a_req->screen);
+ __GLX_SWAP_INT(&a_req->shareList);
+ }
+
+ EPHYR_LOG ("context creation requested. localid:%d, "
+ "screen:%d, visual:%d, direct:%d\n",
+ (int)a_req->context, (int)a_req->screen,
+ (int)a_req->visual, (int)a_req->isDirect) ;
+
+ memset (&host_w_attrs, 0, sizeof (host_w_attrs)) ;
+ if (!hostx_get_window_attributes (hostx_get_window (a_req->screen),
+ &host_w_attrs)) {
+ EPHYR_LOG_ERROR ("failed to get host window attrs\n") ;
+ goto out ;
+ }
+
+ EPHYR_LOG ("host window visual id: %d\n", host_w_attrs.visualid) ;
+
+ if (!ephyrHostGLXCreateContext (a_req->screen,
+ host_w_attrs.visualid,
+ a_req->context,
+ a_req->shareList,
+ a_req->isDirect)) {
+ EPHYR_LOG_ERROR ("ephyrHostGLXCreateContext() failed\n") ;
+ goto out ;
+ }
+ res = Success;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return res ;
+}
+
+int
+ephyrGLXCreateContext (__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
+
+ return ephyrGLXCreateContextReal (req, FALSE) ;
+}
+
+int ephyrGLXCreateContextSwap (__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
+ return ephyrGLXCreateContextReal (req, TRUE) ;
+}
+
+static int
+ephyrGLXDestroyContextReal (__GLXclientState *a_cl,
+ GLbyte *a_pc,
+ Bool a_do_swap)
+{
+ int res=BadImplementation;
+ ClientPtr client = a_cl->client;
+ xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) a_pc;
+
+ EPHYR_LOG ("enter. id:%d\n", (int)req->context) ;
+ if (!ephyrHostDestroyContext (req->context)) {
+ EPHYR_LOG_ERROR ("ephyrHostDestroyContext() failed\n") ;
+ client->errorValue = req->context ;
+ goto out ;
+ }
+ res = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return res ;
+}
+
+int
+ephyrGLXDestroyContext (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXDestroyContextReal (a_cl, a_pc, FALSE) ;
+}
+
+int
+ephyrGLXDestroyContextSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXDestroyContextReal (a_cl, a_pc, TRUE) ;
+}
+
+static int
+ephyrGLXMakeCurrentReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
+{
+ int res=BadImplementation;
+ xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) a_pc;
+ xGLXMakeCurrentReply reply ;
+ DrawablePtr drawable=NULL;
+ int rc=0;
+
+ EPHYR_LOG ("enter\n") ;
+ rc = dixLookupDrawable (&drawable,
+ req->drawable,
+ a_cl->client,
+ 0,
+ DixReadAccess);
+ EPHYR_RETURN_VAL_IF_FAIL (drawable, BadValue) ;
+ EPHYR_RETURN_VAL_IF_FAIL (drawable->pScreen, BadValue) ;
+ EPHYR_LOG ("screen nummber requested:%d\n",
+ drawable->pScreen->myNum) ;
+
+ memset (&reply, 0, sizeof (reply)) ;
+ if (!ephyrHostGLXMakeCurrent (hostx_get_window (drawable->pScreen->myNum),
+ req->context,
+ req->oldContextTag,
+ (int*)&reply.contextTag)) {
+ EPHYR_LOG_ERROR ("ephyrHostGLXMakeCurrent() failed\n") ;
+ goto out;
+ }
+ reply.length = 0;
+ reply.type = X_Reply;
+ reply.sequenceNumber = a_cl->client->sequence;
+ if (a_do_swap) {
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_SWAP_SHORT(&reply.sequenceNumber);
+ __GLX_SWAP_INT(&reply.length);
+ __GLX_SWAP_INT(&reply.contextTag);
+ }
+ WriteToClient(a_cl->client, sz_xGLXMakeCurrentReply, (char *)&reply);
+
+ res = Success ;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return res ;
+}
+
+int
+ephyrGLXMakeCurrent (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXMakeCurrentReal (a_cl, a_pc, FALSE) ;
+}
+
+int
+ephyrGLXMakeCurrentSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXMakeCurrentReal (a_cl, a_pc, TRUE) ;
+}
+
+static int
+ephyrGLXGetStringReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
+{
+ ClientPtr client=NULL ;
+ int context_tag=0, name=0, res=BadImplementation, length=0 ;
+ char *string=NULL;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_cl && a_pc, BadValue) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ client = a_cl->client ;
+
+ if (a_do_swap) {
+ __GLX_SWAP_INT (a_pc + 4);
+ __GLX_SWAP_INT (a_pc + __GLX_SINGLE_HDR_SIZE);
+ }
+ context_tag = __GLX_GET_SINGLE_CONTEXT_TAG (a_pc) ;
+ a_pc += __GLX_SINGLE_HDR_SIZE;
+ name = *(GLenum*)(a_pc + 0);
+ EPHYR_LOG ("context_tag:%d, name:%d\n", context_tag, name) ;
+ if (!ephyrHostGLXGetStringFromServer (context_tag,
+ name,
+ EPHYR_HOST_GLX_GetString,
+ &string)) {
+ EPHYR_LOG_ERROR ("failed to get string from server\n") ;
+ goto out ;
+ }
+ if (string) {
+ length = strlen (string) + 1;
+ EPHYR_LOG ("got string:'%s', size:%d\n", string, length) ;
+ } else {
+ EPHYR_LOG ("got string: string (null)\n") ;
+ }
+ __GLX_BEGIN_REPLY (length);
+ __GLX_PUT_SIZE (length);
+ __GLX_SEND_HEADER ();
+ if (a_do_swap) {
+ __GLX_SWAP_REPLY_SIZE ();
+ __GLX_SWAP_REPLY_HEADER ();
+ }
+ WriteToClient (client, length, (char *)string);
+
+ res = Success ;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return res ;
+}
+
+int
+ephyrGLXGetString (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXGetStringReal (a_cl, a_pc, FALSE) ;
+}
+
+int
+ephyrGLXGetStringSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXGetStringReal (a_cl, a_pc, TRUE) ;
+}
+
+static int
+ephyrGLXGetIntegervReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
+{
+ int res=BadImplementation;
+ xGLXSingleReq * const req = (xGLXSingleReq *) a_pc;
+ GLenum int_name ;
+ int value=0 ;
+ GLint answer_buf_room[200];
+ GLint *buf=NULL ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ a_pc += __GLX_SINGLE_HDR_SIZE;
+
+ int_name = *(GLenum*) (a_pc+0) ;
+ if (!ephyrHostGetIntegerValue (req->contextTag, int_name, &value)) {
+ EPHYR_LOG_ERROR ("ephyrHostGetIntegerValue() failed\n") ;
+ goto out ;
+ }
+ buf = __glXGetAnswerBuffer (a_cl, sizeof (value),
+ answer_buf_room,
+ sizeof (answer_buf_room),
+ 4) ;
+
+ if (!buf) {
+ EPHYR_LOG_ERROR ("failed to allocate reply buffer\n") ;
+ res = BadAlloc ;
+ goto out ;
+ }
+ __glXSendReply (a_cl->client, buf, 1, sizeof (value), GL_FALSE, 0) ;
+ res = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return res ;
+}
+
+int
+ephyrGLXGetIntegerv (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXGetIntegervReal (a_cl, a_pc, FALSE) ;
+}
+
+int
+ephyrGLXGetIntegervSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXGetIntegervReal (a_cl, a_pc, TRUE) ;
+}
+
+static int
+ephyrGLXIsDirectReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
+{
+ int res=BadImplementation;
+ ClientPtr client = a_cl->client;
+ xGLXIsDirectReq *req = (xGLXIsDirectReq *) a_pc;
+ xGLXIsDirectReply reply;
+ int is_direct=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_cl && a_pc, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ memset (&reply, 0, sizeof (reply)) ;
+ if (!ephyrHostIsContextDirect (req->context, (int*)&is_direct)) {
+ EPHYR_LOG_ERROR ("ephyrHostIsContextDirect() failed\n") ;
+ goto out ;
+ }
+ reply.isDirect = is_direct ;
+ reply.length = 0;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ WriteToClient(client, sz_xGLXIsDirectReply, (char *)&reply);
+ res = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return res ;
+}
+
+int
+ephyrGLXIsDirect (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXIsDirectReal (a_cl, a_pc, FALSE) ;
+}
+
+int
+ephyrGLXIsDirectSwap (__GLXclientState *a_cl, GLbyte *a_pc)
+{
+ return ephyrGLXIsDirectReal (a_cl, a_pc, TRUE) ;
+}
diff --git a/xorg-server/hw/kdrive/ephyr/ephyrhostvideo.c b/xorg-server/hw/kdrive/ephyr/ephyrhostvideo.c
index f4a1b9d17..60f200629 100644
--- a/xorg-server/hw/kdrive/ephyr/ephyrhostvideo.c
+++ b/xorg-server/hw/kdrive/ephyr/ephyrhostvideo.c
@@ -1,1012 +1,1012 @@
-/*
- * Xephyr - A kdrive X server thats runs in a host X window.
- * Authored by Matthew Allum <mallum@openedhand.com>
- *
- * Copyright © 2007 OpenedHand Ltd
- *
- * 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 OpenedHand Ltd not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. OpenedHand Ltd makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- * Authors:
- * Dodji Seketeli <dodji@openedhand.com>
- */
-#ifdef HAVE_CONFIG_H
-#include <kdrive-config.h>
-#endif
-/*
- * including some server headers (like kdrive-config.h)
- * might define the macro _XSERVER64
- * on 64 bits machines. That macro must _NOT_ be defined for Xlib
- * client code, otherwise bad things happen.
- * So let's undef that macro if necessary.
- */
-#ifdef _XSERVER64
-#undef _XSERVER64
-#endif
-#include <X11/Xutil.h>
-#include <X11/Xlibint.h>
-#include <X11/extensions/Xvlib.h>
-#include <X11/extensions/Xvproto.h>
-#include <X11/extensions/Xext.h>
-#include <X11/extensions/extutil.h>
-#define _HAVE_XALLOC_DECLS
-
-#include "hostx.h"
-#include "ephyrhostvideo.h"
-#include "ephyrlog.h"
-
-#ifndef TRUE
-#define TRUE 1
-#endif /*TRUE*/
-
-#ifndef FALSE
-#define FALSE 0
-#endif /*FALSE*/
-
-static XExtensionInfo _xv_info_data;
-static XExtensionInfo *xv_info = &_xv_info_data;
-static char *xv_extension_name = XvName;
-static char *xv_error_string(Display *dpy, int code, XExtCodes *codes,
- char * buf, int n);
-static int xv_close_display(Display *dpy, XExtCodes *codes);
-static Bool xv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire);
-
-static XExtensionHooks xv_extension_hooks = {
- NULL, /* create_gc */
- NULL, /* copy_gc */
- NULL, /* flush_gc */
- NULL, /* free_gc */
- NULL, /* create_font */
- NULL, /* free_font */
- xv_close_display, /* close_display */
- xv_wire_to_event, /* wire_to_event */
- NULL, /* event_to_wire */
- NULL, /* error */
- xv_error_string /* error_string */
-};
-
-
-static char *xv_error_list[] =
-{
- "BadPort", /* XvBadPort */
- "BadEncoding", /* XvBadEncoding */
- "BadControl" /* XvBadControl */
-};
-
-
-#define XvCheckExtension(dpy, i, val) \
- XextCheckExtension(dpy, i, xv_extension_name, val)
-#define XvGetReq(name, req) \
- WORD64ALIGN\
- if ((dpy->bufptr + SIZEOF(xv##name##Req)) > dpy->bufmax)\
- _XFlush(dpy);\
- req = (xv##name##Req *)(dpy->last_req = dpy->bufptr);\
- req->reqType = info->codes->major_opcode;\
- req->xvReqType = xv_##name; \
- req->length = (SIZEOF(xv##name##Req))>>2;\
- dpy->bufptr += SIZEOF(xv##name##Req);\
- dpy->request++
-
-static XEXT_GENERATE_CLOSE_DISPLAY (xv_close_display, xv_info)
-
-
-static XEXT_GENERATE_FIND_DISPLAY (xv_find_display, xv_info,
- xv_extension_name,
- &xv_extension_hooks,
- XvNumEvents, NULL)
-
-static XEXT_GENERATE_ERROR_STRING (xv_error_string, xv_extension_name,
- XvNumErrors, xv_error_list)
-
-struct _EphyrHostXVAdaptorArray {
- XvAdaptorInfo *adaptors ;
- unsigned int nb_adaptors ;
-};
-
-/*heavily copied from libx11*/
-#define BUFSIZE 2048
-static void
-ephyrHostXVLogXErrorEvent (Display *a_display,
- XErrorEvent *a_err_event,
- FILE *a_fp)
-{
- char buffer[BUFSIZ];
- char mesg[BUFSIZ];
- char number[32];
- const char *mtype = "XlibMessage";
- register _XExtension *ext = (_XExtension *)NULL;
- _XExtension *bext = (_XExtension *)NULL;
- Display *dpy = a_display ;
-
- XGetErrorText(dpy, a_err_event->error_code, buffer, BUFSIZ);
- XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ);
- (void) fprintf(a_fp, "%s: %s\n ", mesg, buffer);
- XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d",
- mesg, BUFSIZ);
- (void) fprintf(a_fp, mesg, a_err_event->request_code);
- if (a_err_event->request_code < 128) {
- sprintf(number, "%d", a_err_event->request_code);
- XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ);
- } else {
- for (ext = dpy->ext_procs;
- ext && (ext->codes.major_opcode != a_err_event->request_code);
- ext = ext->next)
- ;
- if (ext)
- strcpy(buffer, ext->name);
- else
- buffer[0] = '\0';
- }
- (void) fprintf(a_fp, " (%s)\n", buffer);
- if (a_err_event->request_code >= 128) {
- XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d",
- mesg, BUFSIZ);
- fputs(" ", a_fp);
- (void) fprintf(a_fp, mesg, a_err_event->minor_code);
- if (ext) {
- sprintf(mesg, "%s.%d", ext->name, a_err_event->minor_code);
- XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ);
- (void) fprintf(a_fp, " (%s)", buffer);
- }
- fputs("\n", a_fp);
- }
- if (a_err_event->error_code >= 128) {
- /* kludge, try to find the extension that caused it */
- buffer[0] = '\0';
- for (ext = dpy->ext_procs; ext; ext = ext->next) {
- if (ext->error_string)
- (*ext->error_string)(dpy, a_err_event->error_code, &ext->codes,
- buffer, BUFSIZ);
- if (buffer[0]) {
- bext = ext;
- break;
- }
- if (ext->codes.first_error &&
- ext->codes.first_error < (int)a_err_event->error_code &&
- (!bext || ext->codes.first_error > bext->codes.first_error))
- bext = ext;
- }
- if (bext)
- sprintf(buffer, "%s.%d", bext->name,
- a_err_event->error_code - bext->codes.first_error);
- else
- strcpy(buffer, "Value");
- XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ);
- if (mesg[0]) {
- fputs(" ", a_fp);
- (void) fprintf(a_fp, mesg, a_err_event->resourceid);
- fputs("\n", a_fp);
- }
- /* let extensions try to print the values */
- for (ext = dpy->ext_procs; ext; ext = ext->next) {
- if (ext->error_values)
- (*ext->error_values)(dpy, a_err_event, a_fp);
- }
- } else if ((a_err_event->error_code == BadWindow) ||
- (a_err_event->error_code == BadPixmap) ||
- (a_err_event->error_code == BadCursor) ||
- (a_err_event->error_code == BadFont) ||
- (a_err_event->error_code == BadDrawable) ||
- (a_err_event->error_code == BadColor) ||
- (a_err_event->error_code == BadGC) ||
- (a_err_event->error_code == BadIDChoice) ||
- (a_err_event->error_code == BadValue) ||
- (a_err_event->error_code == BadAtom)) {
- if (a_err_event->error_code == BadValue)
- XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%x",
- mesg, BUFSIZ);
- else if (a_err_event->error_code == BadAtom)
- XGetErrorDatabaseText(dpy, mtype, "AtomID", "AtomID 0x%x",
- mesg, BUFSIZ);
- else
- XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x",
- mesg, BUFSIZ);
- fputs(" ", a_fp);
- (void) fprintf(a_fp, mesg, a_err_event->resourceid);
- fputs("\n", a_fp);
- }
- XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d",
- mesg, BUFSIZ);
- fputs(" ", a_fp);
- (void) fprintf(a_fp, mesg, a_err_event->serial);
- XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d",
- mesg, BUFSIZ);
- fputs("\n ", a_fp);
- (void) fprintf(a_fp, mesg, dpy->request);
- fputs("\n", a_fp);
-}
-
-static int
-ephyrHostXVErrorHandler (Display *a_display,
- XErrorEvent *a_error_event)
-{
- EPHYR_LOG_ERROR ("got an error from the host xserver:\n") ;
- ephyrHostXVLogXErrorEvent (a_display, a_error_event, stderr) ;
- return Success ;
-}
-
-void
-ephyrHostXVInit (void)
-{
- static Bool s_initialized ;
-
- if (s_initialized)
- return ;
- XSetErrorHandler (ephyrHostXVErrorHandler) ;
- s_initialized = TRUE ;
-}
-
-Bool
-ephyrHostXVQueryAdaptors (EphyrHostXVAdaptorArray **a_adaptors)
-{
- EphyrHostXVAdaptorArray *result=NULL ;
- int ret=0 ;
- Bool is_ok=FALSE ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_adaptors, FALSE) ;
-
- EPHYR_LOG ("enter\n") ;
-
- result = Xcalloc (1, sizeof (EphyrHostXVAdaptorArray)) ;
- if (!result)
- goto out ;
-
- ret = XvQueryAdaptors (hostx_get_display (),
- DefaultRootWindow (hostx_get_display ()),
- &result->nb_adaptors,
- &result->adaptors) ;
- if (ret != Success) {
- EPHYR_LOG_ERROR ("failed to query host adaptors: %d\n", ret) ;
- goto out ;
- }
- *a_adaptors = result ;
- is_ok = TRUE ;
-
-out:
- EPHYR_LOG ("leave\n") ;
- return is_ok ;
-}
-
-void
-ephyrHostXVAdaptorArrayDelete (EphyrHostXVAdaptorArray *a_adaptors)
-{
- if (!a_adaptors)
- return ;
- if (a_adaptors->adaptors) {
- XvFreeAdaptorInfo (a_adaptors->adaptors) ;
- a_adaptors->adaptors = NULL ;
- a_adaptors->nb_adaptors = 0 ;
- }
- XFree (a_adaptors) ;
-}
-
-int
-ephyrHostXVAdaptorArrayGetSize (const EphyrHostXVAdaptorArray *a_this)
-{
- EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
- return a_this->nb_adaptors ;
-}
-
-EphyrHostXVAdaptor*
-ephyrHostXVAdaptorArrayAt (const EphyrHostXVAdaptorArray *a_this,
- int a_index)
-{
- EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ;
-
- if (a_index >= a_this->nb_adaptors)
- return NULL ;
- return (EphyrHostXVAdaptor*)&a_this->adaptors[a_index] ;
-}
-
-char
-ephyrHostXVAdaptorGetType (const EphyrHostXVAdaptor *a_this)
-{
- EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
- return ((XvAdaptorInfo*)a_this)->type ;
-}
-
-const char*
-ephyrHostXVAdaptorGetName (const EphyrHostXVAdaptor *a_this)
-{
- EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ;
-
- return ((XvAdaptorInfo*)a_this)->name ;
-}
-
-EphyrHostVideoFormat*
-ephyrHostXVAdaptorGetVideoFormats (const EphyrHostXVAdaptor *a_this,
- int *a_nb_formats)
-{
- EphyrHostVideoFormat *formats=NULL ;
- int nb_formats=0, i=0 ;
- XVisualInfo *visual_info, visual_info_template ;
- int nb_visual_info ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ;
-
- nb_formats = ((XvAdaptorInfo*)a_this)->num_formats ;
- formats = Xcalloc (nb_formats, sizeof (EphyrHostVideoFormat)) ;
- for (i=0; i < nb_formats; i++) {
- memset (&visual_info_template, 0, sizeof (visual_info_template)) ;
- visual_info_template.visualid =
- ((XvAdaptorInfo*)a_this)->formats[i].visual_id;
- visual_info = XGetVisualInfo (hostx_get_display (),
- VisualIDMask,
- &visual_info_template,
- &nb_visual_info) ;
- formats[i].depth = ((XvAdaptorInfo*)a_this)->formats[i].depth ;
- formats[i].visual_class = visual_info->class ;
- XFree (visual_info) ;
- }
- if (a_nb_formats)
- *a_nb_formats = nb_formats ;
- return formats ;
-}
-
-int
-ephyrHostXVAdaptorGetNbPorts (const EphyrHostXVAdaptor *a_this)
-{
- EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
-
- return ((XvAdaptorInfo*)a_this)->num_ports ;
-}
-
-int
-ephyrHostXVAdaptorGetFirstPortID (const EphyrHostXVAdaptor *a_this)
-{
- EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
-
- return ((XvAdaptorInfo*)a_this)->base_id ;
-}
-
-Bool
-ephyrHostXVAdaptorHasPutVideo (const EphyrHostXVAdaptor *a_this,
- Bool *a_result)
-{
- EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
-
- if (((XvAdaptorInfo*)a_this)->type & XvVideoMask & XvInputMask)
- *a_result = TRUE ;
- else
- *a_result = FALSE ;
- return TRUE ;
-}
-
-Bool
-ephyrHostXVAdaptorHasGetVideo (const EphyrHostXVAdaptor *a_this,
- Bool *a_result)
-{
- if (((XvAdaptorInfo*)a_this)->type & XvVideoMask & XvOutputMask)
- *a_result = TRUE ;
- else
- *a_result = FALSE ;
- return TRUE ;
-}
-
-Bool
-ephyrHostXVAdaptorHasPutStill (const EphyrHostXVAdaptor *a_this,
- Bool *a_result)
-{
- EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
-
- if (((XvAdaptorInfo*)a_this)->type & XvStillMask && XvInputMask)
- *a_result = TRUE ;
- else
- *a_result = FALSE ;
- return TRUE ;
-}
-
-Bool
-ephyrHostXVAdaptorHasGetStill (const EphyrHostXVAdaptor *a_this,
- Bool *a_result)
-{
- EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
-
- if (((XvAdaptorInfo*)a_this)->type & XvStillMask && XvOutputMask)
- *a_result = TRUE ;
- else
- *a_result = FALSE ;
- return TRUE ;
-}
-
-Bool
-ephyrHostXVAdaptorHasPutImage (const EphyrHostXVAdaptor *a_this,
- Bool *a_result)
-{
- EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
-
- if (((XvAdaptorInfo*)a_this)->type & XvImageMask && XvInputMask)
- *a_result = TRUE ;
- else
- *a_result = FALSE ;
- return TRUE ;
-}
-
-Bool
-ephyrHostXVQueryEncodings (int a_port_id,
- EphyrHostEncoding **a_encodings,
- unsigned int *a_num_encodings)
-{
- EphyrHostEncoding *encodings=NULL ;
- XvEncodingInfo *encoding_info=NULL ;
- unsigned int num_encodings=0, i;
- int ret=0 ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_encodings && a_num_encodings, FALSE) ;
-
- ret = XvQueryEncodings (hostx_get_display (),
- a_port_id,
- &num_encodings,
- &encoding_info) ;
- if (num_encodings && encoding_info) {
- encodings = Xcalloc (num_encodings, sizeof (EphyrHostEncoding)) ;
- for (i=0; i<num_encodings; i++) {
- encodings[i].id = encoding_info[i].encoding_id ;
- encodings[i].name = strdup (encoding_info[i].name) ;
- encodings[i].width = encoding_info[i].width ;
- encodings[i].height = encoding_info[i].height ;
- encodings[i].rate.numerator = encoding_info[i].rate.numerator ;
- encodings[i].rate.denominator = encoding_info[i].rate.denominator ;
- }
- }
- if (encoding_info) {
- XvFreeEncodingInfo (encoding_info) ;
- encoding_info = NULL ;
- }
- *a_encodings = encodings ;
- *a_num_encodings = num_encodings ;
-
- if (ret != Success)
- return FALSE ;
- return TRUE ;
-}
-
-void
-ephyrHostEncodingsDelete (EphyrHostEncoding *a_encodings,
- int a_num_encodings)
-{
- int i=0 ;
-
- if (!a_encodings)
- return ;
- for (i=0; i < a_num_encodings; i++) {
- xfree (a_encodings[i].name) ;
- a_encodings[i].name = NULL ;
- }
- xfree (a_encodings) ;
-}
-
-void
-ephyrHostAttributesDelete (EphyrHostAttribute *a_attributes)
-{
- if (!a_attributes)
- return ;
- XFree (a_attributes) ;
-}
-
-Bool
-ephyrHostXVQueryPortAttributes (int a_port_id,
- EphyrHostAttribute **a_attributes,
- int *a_num_attributes)
-{
- EPHYR_RETURN_VAL_IF_FAIL (a_attributes && a_num_attributes, FALSE) ;
-
- *a_attributes =
- (EphyrHostAttribute*)XvQueryPortAttributes (hostx_get_display (),
- a_port_id,
- a_num_attributes);
-
- return TRUE ;
-}
-
-Bool
-ephyrHostXVQueryImageFormats (int a_port_id,
- EphyrHostImageFormat **a_formats,
- int *a_num_format)
-{
- XvImageFormatValues *result=NULL ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_formats && a_num_format, FALSE) ;
-
- result = XvListImageFormats (hostx_get_display (),
- a_port_id,
- a_num_format) ;
- *a_formats = (EphyrHostImageFormat*) result ;
- return TRUE ;
-
-}
-
-Bool
-ephyrHostXVSetPortAttribute (int a_port_id,
- int a_atom,
- int a_attr_value)
-{
- int res=Success ;
-
- EPHYR_LOG ("atom,name,value: (%d,%s,%d)\n",
- a_atom,
- XGetAtomName (hostx_get_display (), a_atom),
- a_attr_value) ;
-
- res = XvSetPortAttribute (hostx_get_display (),
- a_port_id,
- a_atom,
- a_attr_value) ;
- if (res != Success) {
- EPHYR_LOG_ERROR ("XvSetPortAttribute() failed: %d\n", res) ;
- return FALSE ;
- }
- XFlush (hostx_get_display ()) ;
- EPHYR_LOG ("leave\n") ;
-
- return TRUE ;
-}
-
-Bool
-ephyrHostXVGetPortAttribute (int a_port_id,
- int a_atom,
- int *a_attr_value)
-{
- int res=Success ;
- Bool ret=FALSE ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_attr_value, FALSE) ;
-
- EPHYR_LOG ("enter, a_port_id: %d, a_atomid: %d, attr_name: %s\n",
- a_port_id, a_atom, XGetAtomName (hostx_get_display (), a_atom)) ;
-
- res = XvGetPortAttribute (hostx_get_display (),
- a_port_id,
- a_atom,
- a_attr_value) ;
- if (res != Success) {
- EPHYR_LOG_ERROR ("XvGetPortAttribute() failed: %d \n", res) ;
- goto out ;
- }
- EPHYR_LOG ("atom,value: (%d, %d)\n", a_atom, *a_attr_value) ;
-
- ret = TRUE ;
-
-out:
- EPHYR_LOG ("leave\n") ;
- return ret ;
-}
-
-Bool
-ephyrHostXVQueryBestSize (int a_port_id,
- Bool a_motion,
- unsigned int a_frame_w,
- unsigned int a_frame_h,
- unsigned int a_drw_w,
- unsigned int a_drw_h,
- unsigned int *a_actual_w,
- unsigned int *a_actual_h)
-{
- int res=0 ;
- Bool is_ok=FALSE ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_actual_w && a_actual_h, FALSE) ;
-
- EPHYR_LOG ("enter: frame (%dx%d), drw (%dx%d)\n",
- a_frame_w, a_frame_h,
- a_drw_w, a_drw_h) ;
-
- res = XvQueryBestSize (hostx_get_display (),
- a_port_id,
- a_motion,
- a_frame_w, a_frame_h,
- a_drw_w, a_drw_h,
- a_actual_w, a_actual_h) ;
- if (res != Success) {
- EPHYR_LOG_ERROR ("XvQueryBestSize() failed: %d\n", res) ;
- goto out ;
- }
- XSync (hostx_get_display (), FALSE) ;
-
- EPHYR_LOG ("actual (%dx%d)\n", *a_actual_w, *a_actual_h) ;
- is_ok = TRUE ;
-
-out:
- EPHYR_LOG ("leave\n") ;
- return is_ok ;
-}
-
-static Bool
-xv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire)
-{
- XExtDisplayInfo *info = xv_find_display (dpy);
- XvEvent *re = (XvEvent *)host;
- xvEvent *event = (xvEvent *)wire;
-
- XvCheckExtension(dpy, info, False);
-
- switch ((event->u.u.type & 0x7F) - info->codes->first_event) {
- case XvVideoNotify:
- re->xvvideo.type = event->u.u.type & 0x7f;
- re->xvvideo.serial =
- _XSetLastRequestRead(dpy, (xGenericReply *)event);
- re->xvvideo.send_event = ((event->u.u.type & 0x80) != 0);
- re->xvvideo.display = dpy;
- re->xvvideo.time = event->u.videoNotify.time;
- re->xvvideo.reason = event->u.videoNotify.reason;
- re->xvvideo.drawable = event->u.videoNotify.drawable;
- re->xvvideo.port_id = event->u.videoNotify.port;
- break;
- case XvPortNotify:
- re->xvport.type = event->u.u.type & 0x7f;
- re->xvport.serial =
- _XSetLastRequestRead(dpy, (xGenericReply *)event);
- re->xvport.send_event = ((event->u.u.type & 0x80) != 0);
- re->xvport.display = dpy;
- re->xvport.time = event->u.portNotify.time;
- re->xvport.port_id = event->u.portNotify.port;
- re->xvport.attribute = event->u.portNotify.attribute;
- re->xvport.value = event->u.portNotify.value;
- break;
- default:
- return False;
- }
-
- return True ;
-}
-
-Bool
-ephyrHostXVQueryImageAttributes (int a_port_id,
- int a_image_id /*image fourcc code*/,
- unsigned short *a_width,
- unsigned short *a_height,
- int *a_image_size,
- int *a_pitches,
- int *a_offsets)
-{
- Display *dpy = hostx_get_display () ;
- Bool ret=FALSE ;
- XExtDisplayInfo *info = xv_find_display (dpy);
- xvQueryImageAttributesReq *req=NULL;
- xvQueryImageAttributesReply rep;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_width, FALSE) ;
- EPHYR_RETURN_VAL_IF_FAIL (a_height, FALSE) ;
- EPHYR_RETURN_VAL_IF_FAIL (a_image_size, FALSE) ;
-
- XvCheckExtension (dpy, info, FALSE);
-
- LockDisplay (dpy);
-
- XvGetReq (QueryImageAttributes, req);
- req->id = a_image_id;
- req->port = a_port_id;
- req->width = *a_width;
- req->height = *a_height;
- /*
- * read the reply
- */
- if (!_XReply (dpy, (xReply *)&rep, 0, xFalse)) {
- EPHYR_LOG_ERROR ("QeryImageAttribute req failed\n") ;
- goto out ;
- }
- if (a_pitches && a_offsets) {
- _XRead (dpy,
- (char*)a_pitches,
- rep.num_planes << 2);
- _XRead (dpy,
- (char*)a_offsets,
- rep.num_planes << 2);
- } else {
- _XEatData(dpy, rep.length << 2);
- }
- *a_width = rep.width ;
- *a_height = rep.height ;
- *a_image_size = rep.data_size ;
-
- ret = TRUE ;
-
-out:
- UnlockDisplay (dpy) ;
- SyncHandle ();
- return ret ;
-}
-
-Bool
-ephyrHostGetAtom (const char* a_name,
- Bool a_create_if_not_exists,
- int *a_atom)
-{
- int atom=None ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_atom, FALSE) ;
-
- atom = XInternAtom (hostx_get_display (), a_name, a_create_if_not_exists);
- if (atom == None) {
- return FALSE ;
- }
- *a_atom = atom ;
- return TRUE ;
-}
-
-char*
-ephyrHostGetAtomName (int a_atom)
-{
- return XGetAtomName (hostx_get_display (), a_atom) ;
-}
-
-void
-ephyrHostFree (void *a_pointer)
-{
- if (a_pointer)
- XFree (a_pointer) ;
-}
-
-Bool
-ephyrHostXVPutImage (int a_screen_num,
- int a_port_id,
- int a_image_id,
- int a_drw_x,
- int a_drw_y,
- int a_drw_w,
- int a_drw_h,
- int a_src_x,
- int a_src_y,
- int a_src_w,
- int a_src_h,
- int a_image_width,
- int a_image_height,
- unsigned char *a_buf,
- EphyrHostBox *a_clip_rects,
- int a_clip_rect_nums )
-{
- Bool is_ok=TRUE ;
- XvImage *xv_image=NULL ;
- GC gc=0 ;
- XGCValues gc_values;
- Display *dpy = hostx_get_display () ;
- XRectangle *rects=NULL ;
- int res = 0 ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_buf, FALSE) ;
-
- EPHYR_LOG ("enter, num_clip_rects: %d\n", a_clip_rect_nums) ;
-
- memset (&gc_values, 0, sizeof (gc_values)) ;
- gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
- if (!gc) {
- EPHYR_LOG_ERROR ("failed to create gc \n") ;
- goto out ;
- }
- xv_image = (XvImage*) XvCreateImage (hostx_get_display (),
- a_port_id, a_image_id,
- NULL, a_image_width, a_image_height) ;
- if (!xv_image) {
- EPHYR_LOG_ERROR ("failed to create image\n") ;
- goto out ;
- }
- xv_image->data = (char*)a_buf ;
- if (a_clip_rect_nums) {
- int i=0 ;
- rects = calloc (a_clip_rect_nums, sizeof (XRectangle)) ;
- for (i=0; i < a_clip_rect_nums; i++) {
- rects[i].x = a_clip_rects[i].x1 ;
- rects[i].y = a_clip_rects[i].y1 ;
- rects[i].width = a_clip_rects[i].x2 - a_clip_rects[i].x1;
- rects[i].height = a_clip_rects[i].y2 - a_clip_rects[i].y1;
- EPHYR_LOG ("(x,y,w,h): (%d,%d,%d,%d)\n",
- rects[i].x, rects[i].y,
- rects[i].width, rects[i].height) ;
- }
- XSetClipRectangles (dpy, gc, 0, 0, rects, a_clip_rect_nums, YXBanded) ;
- /*this always returns 1*/
- }
- res = XvPutImage (dpy, a_port_id,
- hostx_get_window (a_screen_num),
- gc, xv_image,
- a_src_x, a_src_y, a_src_w, a_src_h,
- a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
- if (res != Success) {
- EPHYR_LOG_ERROR ("XvPutImage() failed: %d\n", res) ;
- goto out ;
- }
- is_ok = TRUE ;
-
-out:
- if (xv_image) {
- XFree (xv_image) ;
- xv_image = NULL ;
- }
- if (gc) {
- XFreeGC (dpy, gc) ;
- gc = NULL ;
- }
- if (rects) {
- free (rects) ;
- rects = NULL ;
- }
- EPHYR_LOG ("leave\n") ;
- return is_ok ;
-}
-
-Bool
-ephyrHostXVPutVideo (int a_screen_num, int a_port_id,
- int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
- int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
-{
- Bool is_ok=FALSE ;
- int res=FALSE ;
- GC gc=0 ;
- XGCValues gc_values;
- Display *dpy=hostx_get_display () ;
-
- EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
-
- gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
- if (!gc) {
- EPHYR_LOG_ERROR ("failed to create gc \n") ;
- goto out ;
- }
- res = XvPutVideo (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
- a_vid_x, a_vid_y, a_vid_w, a_vid_h,
- a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
-
- if (res != Success) {
- EPHYR_LOG_ERROR ("XvPutVideo() failed: %d\n", res) ;
- goto out ;
- }
-
- is_ok = TRUE ;
-
-out:
- if (gc) {
- XFreeGC (dpy, gc) ;
- gc = NULL ;
- }
- return is_ok ;
-}
-
-Bool
-ephyrHostXVGetVideo (int a_screen_num, int a_port_id,
- int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
- int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
-{
- Bool is_ok=FALSE ;
- int res=FALSE ;
- GC gc=0 ;
- XGCValues gc_values;
- Display *dpy=hostx_get_display () ;
-
- EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
-
- gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
- if (!gc) {
- EPHYR_LOG_ERROR ("failed to create gc \n") ;
- goto out ;
- }
- res = XvGetVideo (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
- a_vid_x, a_vid_y, a_vid_w, a_vid_h,
- a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
-
- if (res != Success) {
- EPHYR_LOG_ERROR ("XvGetVideo() failed: %d\n", res) ;
- goto out ;
- }
-
- is_ok = TRUE ;
-
-out:
- if (gc) {
- XFreeGC (dpy, gc) ;
- gc = NULL ;
- }
- return is_ok ;
-}
-
-Bool
-ephyrHostXVPutStill (int a_screen_num, int a_port_id,
- int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
- int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
-{
- Bool is_ok=FALSE ;
- int res=FALSE ;
- GC gc=0 ;
- XGCValues gc_values;
- Display *dpy=hostx_get_display () ;
-
- EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
-
- gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
- if (!gc) {
- EPHYR_LOG_ERROR ("failed to create gc \n") ;
- goto out ;
- }
- res = XvPutStill (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
- a_vid_x, a_vid_y, a_vid_w, a_vid_h,
- a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
-
- if (res != Success) {
- EPHYR_LOG_ERROR ("XvPutStill() failed: %d\n", res) ;
- goto out ;
- }
-
- is_ok = TRUE ;
-
-out:
- if (gc) {
- XFreeGC (dpy, gc) ;
- gc = NULL ;
- }
- return is_ok ;
-}
-
-Bool
-ephyrHostXVGetStill (int a_screen_num, int a_port_id,
- int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
- int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
-{
- Bool is_ok=FALSE ;
- int res=FALSE ;
- GC gc=0 ;
- XGCValues gc_values;
- Display *dpy=hostx_get_display () ;
-
- EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
-
- gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
- if (!gc) {
- EPHYR_LOG_ERROR ("failed to create gc \n") ;
- goto out ;
- }
- res = XvGetStill (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
- a_vid_x, a_vid_y, a_vid_w, a_vid_h,
- a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
-
- if (res != Success) {
- EPHYR_LOG_ERROR ("XvGetStill() failed: %d\n", res) ;
- goto out ;
- }
-
- is_ok = TRUE ;
-
-out:
- if (gc) {
- XFreeGC (dpy, gc) ;
- gc = NULL ;
- }
- return is_ok ;
-}
-
-Bool
-ephyrHostXVStopVideo (int a_screen_num, int a_port_id)
-{
- int ret=0 ;
- Bool is_ok=FALSE ;
- Display *dpy = hostx_get_display () ;
-
- EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
-
- EPHYR_LOG ("enter\n") ;
-
- ret = XvStopVideo (dpy, a_port_id, hostx_get_window (a_screen_num)) ;
- if (ret != Success) {
- EPHYR_LOG_ERROR ("XvStopVideo() failed: %d \n", ret) ;
- goto out ;
- }
- is_ok = TRUE ;
-
-out:
- EPHYR_LOG ("leave\n") ;
- return is_ok ;
-}
-
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ * Authored by Matthew Allum <mallum@openedhand.com>
+ *
+ * Copyright © 2007 OpenedHand Ltd
+ *
+ * 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 OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:
+ * Dodji Seketeli <dodji@openedhand.com>
+ */
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+/*
+ * including some server headers (like kdrive-config.h)
+ * might define the macro _XSERVER64
+ * on 64 bits machines. That macro must _NOT_ be defined for Xlib
+ * client code, otherwise bad things happen.
+ * So let's undef that macro if necessary.
+ */
+#ifdef _XSERVER64
+#undef _XSERVER64
+#endif
+#include <X11/Xutil.h>
+#include <X11/Xlibint.h>
+#include <X11/extensions/Xvlib.h>
+#include <X11/extensions/Xvproto.h>
+#include <X11/extensions/Xext.h>
+#include <X11/extensions/extutil.h>
+#define _HAVE_XALLOC_DECLS
+
+#include "hostx.h"
+#include "ephyrhostvideo.h"
+#include "ephyrlog.h"
+
+#ifndef TRUE
+#define TRUE 1
+#endif /*TRUE*/
+
+#ifndef FALSE
+#define FALSE 0
+#endif /*FALSE*/
+
+static XExtensionInfo _xv_info_data;
+static XExtensionInfo *xv_info = &_xv_info_data;
+static char *xv_extension_name = XvName;
+static char *xv_error_string(Display *dpy, int code, XExtCodes *codes,
+ char * buf, int n);
+static int xv_close_display(Display *dpy, XExtCodes *codes);
+static Bool xv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire);
+
+static XExtensionHooks xv_extension_hooks = {
+ NULL, /* create_gc */
+ NULL, /* copy_gc */
+ NULL, /* flush_gc */
+ NULL, /* free_gc */
+ NULL, /* create_font */
+ NULL, /* free_font */
+ xv_close_display, /* close_display */
+ xv_wire_to_event, /* wire_to_event */
+ NULL, /* event_to_wire */
+ NULL, /* error */
+ xv_error_string /* error_string */
+};
+
+
+static char *xv_error_list[] =
+{
+ "BadPort", /* XvBadPort */
+ "BadEncoding", /* XvBadEncoding */
+ "BadControl" /* XvBadControl */
+};
+
+
+#define XvCheckExtension(dpy, i, val) \
+ XextCheckExtension(dpy, i, xv_extension_name, val)
+#define XvGetReq(name, req) \
+ WORD64ALIGN\
+ if ((dpy->bufptr + SIZEOF(xv##name##Req)) > dpy->bufmax)\
+ _XFlush(dpy);\
+ req = (xv##name##Req *)(dpy->last_req = dpy->bufptr);\
+ req->reqType = info->codes->major_opcode;\
+ req->xvReqType = xv_##name; \
+ req->length = (SIZEOF(xv##name##Req))>>2;\
+ dpy->bufptr += SIZEOF(xv##name##Req);\
+ dpy->request++
+
+static XEXT_GENERATE_CLOSE_DISPLAY (xv_close_display, xv_info)
+
+
+static XEXT_GENERATE_FIND_DISPLAY (xv_find_display, xv_info,
+ xv_extension_name,
+ &xv_extension_hooks,
+ XvNumEvents, NULL)
+
+static XEXT_GENERATE_ERROR_STRING (xv_error_string, xv_extension_name,
+ XvNumErrors, xv_error_list)
+
+struct _EphyrHostXVAdaptorArray {
+ XvAdaptorInfo *adaptors ;
+ unsigned int nb_adaptors ;
+};
+
+/*heavily copied from libx11*/
+#define BUFSIZE 2048
+static void
+ephyrHostXVLogXErrorEvent (Display *a_display,
+ XErrorEvent *a_err_event,
+ FILE *a_fp)
+{
+ char buffer[BUFSIZ];
+ char mesg[BUFSIZ];
+ char number[32];
+ const char *mtype = "XlibMessage";
+ register _XExtension *ext = (_XExtension *)NULL;
+ _XExtension *bext = (_XExtension *)NULL;
+ Display *dpy = a_display ;
+
+ XGetErrorText(dpy, a_err_event->error_code, buffer, BUFSIZ);
+ XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ);
+ (void) fprintf(a_fp, "%s: %s\n ", mesg, buffer);
+ XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d",
+ mesg, BUFSIZ);
+ (void) fprintf(a_fp, mesg, a_err_event->request_code);
+ if (a_err_event->request_code < 128) {
+ sprintf(number, "%d", a_err_event->request_code);
+ XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ);
+ } else {
+ for (ext = dpy->ext_procs;
+ ext && (ext->codes.major_opcode != a_err_event->request_code);
+ ext = ext->next)
+ ;
+ if (ext)
+ strcpy(buffer, ext->name);
+ else
+ buffer[0] = '\0';
+ }
+ (void) fprintf(a_fp, " (%s)\n", buffer);
+ if (a_err_event->request_code >= 128) {
+ XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d",
+ mesg, BUFSIZ);
+ fputs(" ", a_fp);
+ (void) fprintf(a_fp, mesg, a_err_event->minor_code);
+ if (ext) {
+ sprintf(mesg, "%s.%d", ext->name, a_err_event->minor_code);
+ XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ);
+ (void) fprintf(a_fp, " (%s)", buffer);
+ }
+ fputs("\n", a_fp);
+ }
+ if (a_err_event->error_code >= 128) {
+ /* kludge, try to find the extension that caused it */
+ buffer[0] = '\0';
+ for (ext = dpy->ext_procs; ext; ext = ext->next) {
+ if (ext->error_string)
+ (*ext->error_string)(dpy, a_err_event->error_code, &ext->codes,
+ buffer, BUFSIZ);
+ if (buffer[0]) {
+ bext = ext;
+ break;
+ }
+ if (ext->codes.first_error &&
+ ext->codes.first_error < (int)a_err_event->error_code &&
+ (!bext || ext->codes.first_error > bext->codes.first_error))
+ bext = ext;
+ }
+ if (bext)
+ sprintf(buffer, "%s.%d", bext->name,
+ a_err_event->error_code - bext->codes.first_error);
+ else
+ strcpy(buffer, "Value");
+ XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ);
+ if (mesg[0]) {
+ fputs(" ", a_fp);
+ (void) fprintf(a_fp, mesg, a_err_event->resourceid);
+ fputs("\n", a_fp);
+ }
+ /* let extensions try to print the values */
+ for (ext = dpy->ext_procs; ext; ext = ext->next) {
+ if (ext->error_values)
+ (*ext->error_values)(dpy, a_err_event, a_fp);
+ }
+ } else if ((a_err_event->error_code == BadWindow) ||
+ (a_err_event->error_code == BadPixmap) ||
+ (a_err_event->error_code == BadCursor) ||
+ (a_err_event->error_code == BadFont) ||
+ (a_err_event->error_code == BadDrawable) ||
+ (a_err_event->error_code == BadColor) ||
+ (a_err_event->error_code == BadGC) ||
+ (a_err_event->error_code == BadIDChoice) ||
+ (a_err_event->error_code == BadValue) ||
+ (a_err_event->error_code == BadAtom)) {
+ if (a_err_event->error_code == BadValue)
+ XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%x",
+ mesg, BUFSIZ);
+ else if (a_err_event->error_code == BadAtom)
+ XGetErrorDatabaseText(dpy, mtype, "AtomID", "AtomID 0x%x",
+ mesg, BUFSIZ);
+ else
+ XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x",
+ mesg, BUFSIZ);
+ fputs(" ", a_fp);
+ (void) fprintf(a_fp, mesg, a_err_event->resourceid);
+ fputs("\n", a_fp);
+ }
+ XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d",
+ mesg, BUFSIZ);
+ fputs(" ", a_fp);
+ (void) fprintf(a_fp, mesg, a_err_event->serial);
+ XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d",
+ mesg, BUFSIZ);
+ fputs("\n ", a_fp);
+ (void) fprintf(a_fp, mesg, dpy->request);
+ fputs("\n", a_fp);
+}
+
+static int
+ephyrHostXVErrorHandler (Display *a_display,
+ XErrorEvent *a_error_event)
+{
+ EPHYR_LOG_ERROR ("got an error from the host xserver:\n") ;
+ ephyrHostXVLogXErrorEvent (a_display, a_error_event, stderr) ;
+ return Success ;
+}
+
+void
+ephyrHostXVInit (void)
+{
+ static Bool s_initialized ;
+
+ if (s_initialized)
+ return ;
+ XSetErrorHandler (ephyrHostXVErrorHandler) ;
+ s_initialized = TRUE ;
+}
+
+Bool
+ephyrHostXVQueryAdaptors (EphyrHostXVAdaptorArray **a_adaptors)
+{
+ EphyrHostXVAdaptorArray *result=NULL ;
+ int ret=0 ;
+ Bool is_ok=FALSE ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_adaptors, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ result = Xcalloc (1, sizeof (EphyrHostXVAdaptorArray)) ;
+ if (!result)
+ goto out ;
+
+ ret = XvQueryAdaptors (hostx_get_display (),
+ DefaultRootWindow (hostx_get_display ()),
+ &result->nb_adaptors,
+ &result->adaptors) ;
+ if (ret != Success) {
+ EPHYR_LOG_ERROR ("failed to query host adaptors: %d\n", ret) ;
+ goto out ;
+ }
+ *a_adaptors = result ;
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+void
+ephyrHostXVAdaptorArrayDelete (EphyrHostXVAdaptorArray *a_adaptors)
+{
+ if (!a_adaptors)
+ return ;
+ if (a_adaptors->adaptors) {
+ XvFreeAdaptorInfo (a_adaptors->adaptors) ;
+ a_adaptors->adaptors = NULL ;
+ a_adaptors->nb_adaptors = 0 ;
+ }
+ XFree (a_adaptors) ;
+}
+
+int
+ephyrHostXVAdaptorArrayGetSize (const EphyrHostXVAdaptorArray *a_this)
+{
+ EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
+ return a_this->nb_adaptors ;
+}
+
+EphyrHostXVAdaptor*
+ephyrHostXVAdaptorArrayAt (const EphyrHostXVAdaptorArray *a_this,
+ int a_index)
+{
+ EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ;
+
+ if (a_index >= a_this->nb_adaptors)
+ return NULL ;
+ return (EphyrHostXVAdaptor*)&a_this->adaptors[a_index] ;
+}
+
+char
+ephyrHostXVAdaptorGetType (const EphyrHostXVAdaptor *a_this)
+{
+ EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
+ return ((XvAdaptorInfo*)a_this)->type ;
+}
+
+const char*
+ephyrHostXVAdaptorGetName (const EphyrHostXVAdaptor *a_this)
+{
+ EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ;
+
+ return ((XvAdaptorInfo*)a_this)->name ;
+}
+
+EphyrHostVideoFormat*
+ephyrHostXVAdaptorGetVideoFormats (const EphyrHostXVAdaptor *a_this,
+ int *a_nb_formats)
+{
+ EphyrHostVideoFormat *formats=NULL ;
+ int nb_formats=0, i=0 ;
+ XVisualInfo *visual_info, visual_info_template ;
+ int nb_visual_info ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ;
+
+ nb_formats = ((XvAdaptorInfo*)a_this)->num_formats ;
+ formats = Xcalloc (nb_formats, sizeof (EphyrHostVideoFormat)) ;
+ for (i=0; i < nb_formats; i++) {
+ memset (&visual_info_template, 0, sizeof (visual_info_template)) ;
+ visual_info_template.visualid =
+ ((XvAdaptorInfo*)a_this)->formats[i].visual_id;
+ visual_info = XGetVisualInfo (hostx_get_display (),
+ VisualIDMask,
+ &visual_info_template,
+ &nb_visual_info) ;
+ formats[i].depth = ((XvAdaptorInfo*)a_this)->formats[i].depth ;
+ formats[i].visual_class = visual_info->class ;
+ XFree (visual_info) ;
+ }
+ if (a_nb_formats)
+ *a_nb_formats = nb_formats ;
+ return formats ;
+}
+
+int
+ephyrHostXVAdaptorGetNbPorts (const EphyrHostXVAdaptor *a_this)
+{
+ EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
+
+ return ((XvAdaptorInfo*)a_this)->num_ports ;
+}
+
+int
+ephyrHostXVAdaptorGetFirstPortID (const EphyrHostXVAdaptor *a_this)
+{
+ EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
+
+ return ((XvAdaptorInfo*)a_this)->base_id ;
+}
+
+Bool
+ephyrHostXVAdaptorHasPutVideo (const EphyrHostXVAdaptor *a_this,
+ Bool *a_result)
+{
+ EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
+
+ if (((XvAdaptorInfo*)a_this)->type & XvVideoMask & XvInputMask)
+ *a_result = TRUE ;
+ else
+ *a_result = FALSE ;
+ return TRUE ;
+}
+
+Bool
+ephyrHostXVAdaptorHasGetVideo (const EphyrHostXVAdaptor *a_this,
+ Bool *a_result)
+{
+ if (((XvAdaptorInfo*)a_this)->type & XvVideoMask & XvOutputMask)
+ *a_result = TRUE ;
+ else
+ *a_result = FALSE ;
+ return TRUE ;
+}
+
+Bool
+ephyrHostXVAdaptorHasPutStill (const EphyrHostXVAdaptor *a_this,
+ Bool *a_result)
+{
+ EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
+
+ if (((XvAdaptorInfo*)a_this)->type & XvStillMask && XvInputMask)
+ *a_result = TRUE ;
+ else
+ *a_result = FALSE ;
+ return TRUE ;
+}
+
+Bool
+ephyrHostXVAdaptorHasGetStill (const EphyrHostXVAdaptor *a_this,
+ Bool *a_result)
+{
+ EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
+
+ if (((XvAdaptorInfo*)a_this)->type & XvStillMask && XvOutputMask)
+ *a_result = TRUE ;
+ else
+ *a_result = FALSE ;
+ return TRUE ;
+}
+
+Bool
+ephyrHostXVAdaptorHasPutImage (const EphyrHostXVAdaptor *a_this,
+ Bool *a_result)
+{
+ EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
+
+ if (((XvAdaptorInfo*)a_this)->type & XvImageMask && XvInputMask)
+ *a_result = TRUE ;
+ else
+ *a_result = FALSE ;
+ return TRUE ;
+}
+
+Bool
+ephyrHostXVQueryEncodings (int a_port_id,
+ EphyrHostEncoding **a_encodings,
+ unsigned int *a_num_encodings)
+{
+ EphyrHostEncoding *encodings=NULL ;
+ XvEncodingInfo *encoding_info=NULL ;
+ unsigned int num_encodings=0, i;
+ int ret=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_encodings && a_num_encodings, FALSE) ;
+
+ ret = XvQueryEncodings (hostx_get_display (),
+ a_port_id,
+ &num_encodings,
+ &encoding_info) ;
+ if (num_encodings && encoding_info) {
+ encodings = Xcalloc (num_encodings, sizeof (EphyrHostEncoding)) ;
+ for (i=0; i<num_encodings; i++) {
+ encodings[i].id = encoding_info[i].encoding_id ;
+ encodings[i].name = strdup (encoding_info[i].name) ;
+ encodings[i].width = encoding_info[i].width ;
+ encodings[i].height = encoding_info[i].height ;
+ encodings[i].rate.numerator = encoding_info[i].rate.numerator ;
+ encodings[i].rate.denominator = encoding_info[i].rate.denominator ;
+ }
+ }
+ if (encoding_info) {
+ XvFreeEncodingInfo (encoding_info) ;
+ encoding_info = NULL ;
+ }
+ *a_encodings = encodings ;
+ *a_num_encodings = num_encodings ;
+
+ if (ret != Success)
+ return FALSE ;
+ return TRUE ;
+}
+
+void
+ephyrHostEncodingsDelete (EphyrHostEncoding *a_encodings,
+ int a_num_encodings)
+{
+ int i=0 ;
+
+ if (!a_encodings)
+ return ;
+ for (i=0; i < a_num_encodings; i++) {
+ free(a_encodings[i].name) ;
+ a_encodings[i].name = NULL ;
+ }
+ free(a_encodings) ;
+}
+
+void
+ephyrHostAttributesDelete (EphyrHostAttribute *a_attributes)
+{
+ if (!a_attributes)
+ return ;
+ XFree (a_attributes) ;
+}
+
+Bool
+ephyrHostXVQueryPortAttributes (int a_port_id,
+ EphyrHostAttribute **a_attributes,
+ int *a_num_attributes)
+{
+ EPHYR_RETURN_VAL_IF_FAIL (a_attributes && a_num_attributes, FALSE) ;
+
+ *a_attributes =
+ (EphyrHostAttribute*)XvQueryPortAttributes (hostx_get_display (),
+ a_port_id,
+ a_num_attributes);
+
+ return TRUE ;
+}
+
+Bool
+ephyrHostXVQueryImageFormats (int a_port_id,
+ EphyrHostImageFormat **a_formats,
+ int *a_num_format)
+{
+ XvImageFormatValues *result=NULL ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_formats && a_num_format, FALSE) ;
+
+ result = XvListImageFormats (hostx_get_display (),
+ a_port_id,
+ a_num_format) ;
+ *a_formats = (EphyrHostImageFormat*) result ;
+ return TRUE ;
+
+}
+
+Bool
+ephyrHostXVSetPortAttribute (int a_port_id,
+ int a_atom,
+ int a_attr_value)
+{
+ int res=Success ;
+
+ EPHYR_LOG ("atom,name,value: (%d,%s,%d)\n",
+ a_atom,
+ XGetAtomName (hostx_get_display (), a_atom),
+ a_attr_value) ;
+
+ res = XvSetPortAttribute (hostx_get_display (),
+ a_port_id,
+ a_atom,
+ a_attr_value) ;
+ if (res != Success) {
+ EPHYR_LOG_ERROR ("XvSetPortAttribute() failed: %d\n", res) ;
+ return FALSE ;
+ }
+ XFlush (hostx_get_display ()) ;
+ EPHYR_LOG ("leave\n") ;
+
+ return TRUE ;
+}
+
+Bool
+ephyrHostXVGetPortAttribute (int a_port_id,
+ int a_atom,
+ int *a_attr_value)
+{
+ int res=Success ;
+ Bool ret=FALSE ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_attr_value, FALSE) ;
+
+ EPHYR_LOG ("enter, a_port_id: %d, a_atomid: %d, attr_name: %s\n",
+ a_port_id, a_atom, XGetAtomName (hostx_get_display (), a_atom)) ;
+
+ res = XvGetPortAttribute (hostx_get_display (),
+ a_port_id,
+ a_atom,
+ a_attr_value) ;
+ if (res != Success) {
+ EPHYR_LOG_ERROR ("XvGetPortAttribute() failed: %d \n", res) ;
+ goto out ;
+ }
+ EPHYR_LOG ("atom,value: (%d, %d)\n", a_atom, *a_attr_value) ;
+
+ ret = TRUE ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return ret ;
+}
+
+Bool
+ephyrHostXVQueryBestSize (int a_port_id,
+ Bool a_motion,
+ unsigned int a_frame_w,
+ unsigned int a_frame_h,
+ unsigned int a_drw_w,
+ unsigned int a_drw_h,
+ unsigned int *a_actual_w,
+ unsigned int *a_actual_h)
+{
+ int res=0 ;
+ Bool is_ok=FALSE ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_actual_w && a_actual_h, FALSE) ;
+
+ EPHYR_LOG ("enter: frame (%dx%d), drw (%dx%d)\n",
+ a_frame_w, a_frame_h,
+ a_drw_w, a_drw_h) ;
+
+ res = XvQueryBestSize (hostx_get_display (),
+ a_port_id,
+ a_motion,
+ a_frame_w, a_frame_h,
+ a_drw_w, a_drw_h,
+ a_actual_w, a_actual_h) ;
+ if (res != Success) {
+ EPHYR_LOG_ERROR ("XvQueryBestSize() failed: %d\n", res) ;
+ goto out ;
+ }
+ XSync (hostx_get_display (), FALSE) ;
+
+ EPHYR_LOG ("actual (%dx%d)\n", *a_actual_w, *a_actual_h) ;
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+static Bool
+xv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire)
+{
+ XExtDisplayInfo *info = xv_find_display (dpy);
+ XvEvent *re = (XvEvent *)host;
+ xvEvent *event = (xvEvent *)wire;
+
+ XvCheckExtension(dpy, info, False);
+
+ switch ((event->u.u.type & 0x7F) - info->codes->first_event) {
+ case XvVideoNotify:
+ re->xvvideo.type = event->u.u.type & 0x7f;
+ re->xvvideo.serial =
+ _XSetLastRequestRead(dpy, (xGenericReply *)event);
+ re->xvvideo.send_event = ((event->u.u.type & 0x80) != 0);
+ re->xvvideo.display = dpy;
+ re->xvvideo.time = event->u.videoNotify.time;
+ re->xvvideo.reason = event->u.videoNotify.reason;
+ re->xvvideo.drawable = event->u.videoNotify.drawable;
+ re->xvvideo.port_id = event->u.videoNotify.port;
+ break;
+ case XvPortNotify:
+ re->xvport.type = event->u.u.type & 0x7f;
+ re->xvport.serial =
+ _XSetLastRequestRead(dpy, (xGenericReply *)event);
+ re->xvport.send_event = ((event->u.u.type & 0x80) != 0);
+ re->xvport.display = dpy;
+ re->xvport.time = event->u.portNotify.time;
+ re->xvport.port_id = event->u.portNotify.port;
+ re->xvport.attribute = event->u.portNotify.attribute;
+ re->xvport.value = event->u.portNotify.value;
+ break;
+ default:
+ return False;
+ }
+
+ return True ;
+}
+
+Bool
+ephyrHostXVQueryImageAttributes (int a_port_id,
+ int a_image_id /*image fourcc code*/,
+ unsigned short *a_width,
+ unsigned short *a_height,
+ int *a_image_size,
+ int *a_pitches,
+ int *a_offsets)
+{
+ Display *dpy = hostx_get_display () ;
+ Bool ret=FALSE ;
+ XExtDisplayInfo *info = xv_find_display (dpy);
+ xvQueryImageAttributesReq *req=NULL;
+ xvQueryImageAttributesReply rep;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_width, FALSE) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_height, FALSE) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_image_size, FALSE) ;
+
+ XvCheckExtension (dpy, info, FALSE);
+
+ LockDisplay (dpy);
+
+ XvGetReq (QueryImageAttributes, req);
+ req->id = a_image_id;
+ req->port = a_port_id;
+ req->width = *a_width;
+ req->height = *a_height;
+ /*
+ * read the reply
+ */
+ if (!_XReply (dpy, (xReply *)&rep, 0, xFalse)) {
+ EPHYR_LOG_ERROR ("QeryImageAttribute req failed\n") ;
+ goto out ;
+ }
+ if (a_pitches && a_offsets) {
+ _XRead (dpy,
+ (char*)a_pitches,
+ rep.num_planes << 2);
+ _XRead (dpy,
+ (char*)a_offsets,
+ rep.num_planes << 2);
+ } else {
+ _XEatData(dpy, rep.length << 2);
+ }
+ *a_width = rep.width ;
+ *a_height = rep.height ;
+ *a_image_size = rep.data_size ;
+
+ ret = TRUE ;
+
+out:
+ UnlockDisplay (dpy) ;
+ SyncHandle ();
+ return ret ;
+}
+
+Bool
+ephyrHostGetAtom (const char* a_name,
+ Bool a_create_if_not_exists,
+ int *a_atom)
+{
+ int atom=None ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_atom, FALSE) ;
+
+ atom = XInternAtom (hostx_get_display (), a_name, a_create_if_not_exists);
+ if (atom == None) {
+ return FALSE ;
+ }
+ *a_atom = atom ;
+ return TRUE ;
+}
+
+char*
+ephyrHostGetAtomName (int a_atom)
+{
+ return XGetAtomName (hostx_get_display (), a_atom) ;
+}
+
+void
+ephyrHostFree (void *a_pointer)
+{
+ if (a_pointer)
+ XFree (a_pointer) ;
+}
+
+Bool
+ephyrHostXVPutImage (int a_screen_num,
+ int a_port_id,
+ int a_image_id,
+ int a_drw_x,
+ int a_drw_y,
+ int a_drw_w,
+ int a_drw_h,
+ int a_src_x,
+ int a_src_y,
+ int a_src_w,
+ int a_src_h,
+ int a_image_width,
+ int a_image_height,
+ unsigned char *a_buf,
+ EphyrHostBox *a_clip_rects,
+ int a_clip_rect_nums )
+{
+ Bool is_ok=TRUE ;
+ XvImage *xv_image=NULL ;
+ GC gc=0 ;
+ XGCValues gc_values;
+ Display *dpy = hostx_get_display () ;
+ XRectangle *rects=NULL ;
+ int res = 0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_buf, FALSE) ;
+
+ EPHYR_LOG ("enter, num_clip_rects: %d\n", a_clip_rect_nums) ;
+
+ memset (&gc_values, 0, sizeof (gc_values)) ;
+ gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
+ if (!gc) {
+ EPHYR_LOG_ERROR ("failed to create gc \n") ;
+ goto out ;
+ }
+ xv_image = (XvImage*) XvCreateImage (hostx_get_display (),
+ a_port_id, a_image_id,
+ NULL, a_image_width, a_image_height) ;
+ if (!xv_image) {
+ EPHYR_LOG_ERROR ("failed to create image\n") ;
+ goto out ;
+ }
+ xv_image->data = (char*)a_buf ;
+ if (a_clip_rect_nums) {
+ int i=0 ;
+ rects = calloc (a_clip_rect_nums, sizeof (XRectangle)) ;
+ for (i=0; i < a_clip_rect_nums; i++) {
+ rects[i].x = a_clip_rects[i].x1 ;
+ rects[i].y = a_clip_rects[i].y1 ;
+ rects[i].width = a_clip_rects[i].x2 - a_clip_rects[i].x1;
+ rects[i].height = a_clip_rects[i].y2 - a_clip_rects[i].y1;
+ EPHYR_LOG ("(x,y,w,h): (%d,%d,%d,%d)\n",
+ rects[i].x, rects[i].y,
+ rects[i].width, rects[i].height) ;
+ }
+ XSetClipRectangles (dpy, gc, 0, 0, rects, a_clip_rect_nums, YXBanded) ;
+ /*this always returns 1*/
+ }
+ res = XvPutImage (dpy, a_port_id,
+ hostx_get_window (a_screen_num),
+ gc, xv_image,
+ a_src_x, a_src_y, a_src_w, a_src_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
+ if (res != Success) {
+ EPHYR_LOG_ERROR ("XvPutImage() failed: %d\n", res) ;
+ goto out ;
+ }
+ is_ok = TRUE ;
+
+out:
+ if (xv_image) {
+ XFree (xv_image) ;
+ xv_image = NULL ;
+ }
+ if (gc) {
+ XFreeGC (dpy, gc) ;
+ gc = NULL ;
+ }
+ if (rects) {
+ free (rects) ;
+ rects = NULL ;
+ }
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+Bool
+ephyrHostXVPutVideo (int a_screen_num, int a_port_id,
+ int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
+ int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
+{
+ Bool is_ok=FALSE ;
+ int res=FALSE ;
+ GC gc=0 ;
+ XGCValues gc_values;
+ Display *dpy=hostx_get_display () ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
+
+ gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
+ if (!gc) {
+ EPHYR_LOG_ERROR ("failed to create gc \n") ;
+ goto out ;
+ }
+ res = XvPutVideo (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
+ a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
+
+ if (res != Success) {
+ EPHYR_LOG_ERROR ("XvPutVideo() failed: %d\n", res) ;
+ goto out ;
+ }
+
+ is_ok = TRUE ;
+
+out:
+ if (gc) {
+ XFreeGC (dpy, gc) ;
+ gc = NULL ;
+ }
+ return is_ok ;
+}
+
+Bool
+ephyrHostXVGetVideo (int a_screen_num, int a_port_id,
+ int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
+ int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
+{
+ Bool is_ok=FALSE ;
+ int res=FALSE ;
+ GC gc=0 ;
+ XGCValues gc_values;
+ Display *dpy=hostx_get_display () ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
+
+ gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
+ if (!gc) {
+ EPHYR_LOG_ERROR ("failed to create gc \n") ;
+ goto out ;
+ }
+ res = XvGetVideo (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
+ a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
+
+ if (res != Success) {
+ EPHYR_LOG_ERROR ("XvGetVideo() failed: %d\n", res) ;
+ goto out ;
+ }
+
+ is_ok = TRUE ;
+
+out:
+ if (gc) {
+ XFreeGC (dpy, gc) ;
+ gc = NULL ;
+ }
+ return is_ok ;
+}
+
+Bool
+ephyrHostXVPutStill (int a_screen_num, int a_port_id,
+ int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
+ int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
+{
+ Bool is_ok=FALSE ;
+ int res=FALSE ;
+ GC gc=0 ;
+ XGCValues gc_values;
+ Display *dpy=hostx_get_display () ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
+
+ gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
+ if (!gc) {
+ EPHYR_LOG_ERROR ("failed to create gc \n") ;
+ goto out ;
+ }
+ res = XvPutStill (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
+ a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
+
+ if (res != Success) {
+ EPHYR_LOG_ERROR ("XvPutStill() failed: %d\n", res) ;
+ goto out ;
+ }
+
+ is_ok = TRUE ;
+
+out:
+ if (gc) {
+ XFreeGC (dpy, gc) ;
+ gc = NULL ;
+ }
+ return is_ok ;
+}
+
+Bool
+ephyrHostXVGetStill (int a_screen_num, int a_port_id,
+ int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
+ int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
+{
+ Bool is_ok=FALSE ;
+ int res=FALSE ;
+ GC gc=0 ;
+ XGCValues gc_values;
+ Display *dpy=hostx_get_display () ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
+
+ gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
+ if (!gc) {
+ EPHYR_LOG_ERROR ("failed to create gc \n") ;
+ goto out ;
+ }
+ res = XvGetStill (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
+ a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
+
+ if (res != Success) {
+ EPHYR_LOG_ERROR ("XvGetStill() failed: %d\n", res) ;
+ goto out ;
+ }
+
+ is_ok = TRUE ;
+
+out:
+ if (gc) {
+ XFreeGC (dpy, gc) ;
+ gc = NULL ;
+ }
+ return is_ok ;
+}
+
+Bool
+ephyrHostXVStopVideo (int a_screen_num, int a_port_id)
+{
+ int ret=0 ;
+ Bool is_ok=FALSE ;
+ Display *dpy = hostx_get_display () ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ ret = XvStopVideo (dpy, a_port_id, hostx_get_window (a_screen_num)) ;
+ if (ret != Success) {
+ EPHYR_LOG_ERROR ("XvStopVideo() failed: %d \n", ret) ;
+ goto out ;
+ }
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
diff --git a/xorg-server/hw/kdrive/ephyr/ephyrvideo.c b/xorg-server/hw/kdrive/ephyr/ephyrvideo.c
index 6624ab98a..14213c966 100644
--- a/xorg-server/hw/kdrive/ephyr/ephyrvideo.c
+++ b/xorg-server/hw/kdrive/ephyr/ephyrvideo.c
@@ -1,1273 +1,1273 @@
-/*
- * Xephyr - A kdrive X server thats runs in a host X window.
- * Authored by Matthew Allum <mallum@openedhand.com>
- *
- * Copyright © 2007 OpenedHand Ltd
- *
- * 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 OpenedHand Ltd not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. OpenedHand Ltd makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- * Authors:
- * Dodji Seketeli <dodji@openedhand.com>
- */
-
-#ifdef HAVE_CONFIG_H
-#include <kdrive-config.h>
-#endif
-#include <string.h>
-#include <X11/extensions/Xv.h>
-#include "ephyrlog.h"
-#include "kdrive.h"
-#include "kxv.h"
-#include "ephyr.h"
-#include "hostx.h"
-#include "ephyrhostvideo.h"
-
-struct _EphyrXVPriv {
- EphyrHostXVAdaptorArray *host_adaptors ;
- KdVideoAdaptorPtr adaptors ;
- int num_adaptors ;
-};
-typedef struct _EphyrXVPriv EphyrXVPriv ;
-
-struct _EphyrPortPriv {
- int port_number ;
- KdVideoAdaptorPtr current_adaptor ;
- EphyrXVPriv *xv_priv;
- unsigned char *image_buf ;
- int image_buf_size ;
- int image_id ;
- int drw_x, drw_y, drw_w, drw_h ;
- int src_x, src_y, src_w, src_h ;
- int image_width, image_height ;
-};
-typedef struct _EphyrPortPriv EphyrPortPriv ;
-
-static Bool DoSimpleClip (BoxPtr a_dst_drw,
- BoxPtr a_clipper,
- BoxPtr a_result) ;
-
-static Bool ephyrLocalAtomToHost (int a_local_atom, int *a_host_atom) ;
-
-/*
-static Bool ephyrHostAtomToLocal (int a_host_atom, int *a_local_atom) ;
-*/
-
-static EphyrXVPriv* ephyrXVPrivNew (void) ;
-static void ephyrXVPrivDelete (EphyrXVPriv *a_this) ;
-static Bool ephyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this) ;
-static Bool ephyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this) ;
-static Bool ephyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this,
- ScreenPtr a_screen) ;
-
-static Bool ephyrXVPrivIsAttrValueValid (KdAttributePtr a_attrs,
- int a_attrs_len,
- const char *a_attr_name,
- int a_attr_value,
- Bool *a_is_valid) ;
-
-static Bool ephyrXVPrivGetImageBufSize (int a_port_id,
- int a_image_id,
- unsigned short a_width,
- unsigned short a_height,
- int *a_size) ;
-
-static Bool ephyrXVPrivSaveImageToPortPriv (EphyrPortPriv *a_port_priv,
- const unsigned char *a_image,
- int a_image_len) ;
-
-static void ephyrStopVideo (KdScreenInfo *a_info,
- pointer a_xv_priv,
- Bool a_exit);
-
-static int ephyrSetPortAttribute (KdScreenInfo *a_info,
- Atom a_attr_name,
- int a_attr_value,
- pointer a_port_priv);
-
-static int ephyrGetPortAttribute (KdScreenInfo *a_screen_info,
- Atom a_attr_name,
- int *a_attr_value,
- pointer a_port_priv);
-
-static void ephyrQueryBestSize (KdScreenInfo *a_info,
- Bool a_motion,
- short a_src_w,
- short a_src_h,
- short a_drw_w,
- short a_drw_h,
- unsigned int *a_prefered_w,
- unsigned int *a_prefered_h,
- pointer a_port_priv);
-
-static int ephyrPutImage (KdScreenInfo *a_info,
- DrawablePtr a_drawable,
- short a_src_x,
- short a_src_y,
- short a_drw_x,
- short a_drw_y,
- short a_src_w,
- short a_src_h,
- short a_drw_w,
- short a_drw_h,
- int a_id,
- unsigned char *a_buf,
- short a_width,
- short a_height,
- Bool a_sync,
- RegionPtr a_clipping_region,
- pointer a_port_priv);
-
-static int ephyrReputImage (KdScreenInfo *a_info,
- DrawablePtr a_drawable,
- short a_drw_x,
- short a_drw_y,
- RegionPtr a_clipping_region,
- pointer a_port_priv) ;
-
-static int ephyrPutVideo (KdScreenInfo *a_info,
- DrawablePtr a_drawable,
- short a_vid_x, short a_vid_y,
- short a_drw_x, short a_drw_y,
- short a_vid_w, short a_vid_h,
- short a_drw_w, short a_drw_h,
- RegionPtr a_clip_region,
- pointer a_port_priv) ;
-
-static int ephyrGetVideo (KdScreenInfo *a_info,
- DrawablePtr a_drawable,
- short a_vid_x, short a_vid_y,
- short a_drw_x, short a_drw_y,
- short a_vid_w, short a_vid_h,
- short a_drw_w, short a_drw_h,
- RegionPtr a_clip_region,
- pointer a_port_priv) ;
-
-static int ephyrPutStill (KdScreenInfo *a_info,
- DrawablePtr a_drawable,
- short a_vid_x, short a_vid_y,
- short a_drw_x, short a_drw_y,
- short a_vid_w, short a_vid_h,
- short a_drw_w, short a_drw_h,
- RegionPtr a_clip_region,
- pointer a_port_priv) ;
-
-static int ephyrGetStill (KdScreenInfo *a_info,
- DrawablePtr a_drawable,
- short a_vid_x, short a_vid_y,
- short a_drw_x, short a_drw_y,
- short a_vid_w, short a_vid_h,
- short a_drw_w, short a_drw_h,
- RegionPtr a_clip_region,
- pointer a_port_priv) ;
-
-static int ephyrQueryImageAttributes (KdScreenInfo *a_info,
- int a_id,
- unsigned short *a_w,
- unsigned short *a_h,
- int *a_pitches,
- int *a_offsets);
-static int s_base_port_id ;
-
-/**************
- * <helpers>
- * ************/
-
-static Bool
-DoSimpleClip (BoxPtr a_dst_box,
- BoxPtr a_clipper,
- BoxPtr a_result)
-{
- BoxRec dstClippedBox ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_dst_box && a_clipper && a_result, FALSE) ;
-
- /*
- * setup the clipbox inside the destination.
- */
- dstClippedBox.x1 = a_dst_box->x1 ;
- dstClippedBox.x2 = a_dst_box->x2 ;
- dstClippedBox.y1 = a_dst_box->y1 ;
- dstClippedBox.y2 = a_dst_box->y2 ;
-
- /*
- * if the cliper leftmost edge is inside
- * the destination area then the leftmost edge of the resulting
- * clipped box is the leftmost edge of the cliper.
- */
- if (a_clipper->x1 > dstClippedBox.x1)
- dstClippedBox.x1 = a_clipper->x1 ;
-
- /*
- * if the cliper top edge is inside the destination area
- * then the bottom horizontal edge of the resulting clipped box
- * is the bottom edge of the cliper
- */
- if (a_clipper->y1 > dstClippedBox.y1)
- dstClippedBox.y1 = a_clipper->y1 ;
-
- /*ditto for right edge*/
- if (a_clipper->x2 < dstClippedBox.x2)
- dstClippedBox.x2 = a_clipper->x2 ;
-
- /*ditto for bottom edge*/
- if (a_clipper->y2 < dstClippedBox.y2)
- dstClippedBox.y2 = a_clipper->y2 ;
-
- memcpy (a_result, &dstClippedBox, sizeof (dstClippedBox)) ;
- return TRUE ;
-}
-
-static Bool
-ephyrLocalAtomToHost (int a_local_atom, int *a_host_atom)
-{
- const char *atom_name=NULL;
- int host_atom=None ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_host_atom, FALSE) ;
-
- if (!ValidAtom (a_local_atom))
- return FALSE ;
-
- atom_name = NameForAtom (a_local_atom) ;
-
- if (!atom_name)
- return FALSE ;
-
- if (!ephyrHostGetAtom (atom_name, FALSE, &host_atom) || host_atom == None) {
- EPHYR_LOG_ERROR ("no atom for string %s defined in host X\n",
- atom_name) ;
- return FALSE ;
- }
- *a_host_atom = host_atom ;
- return TRUE ;
-}
-
-/*
- Not used yed.
-static Bool
-ephyrHostAtomToLocal (int a_host_atom, int *a_local_atom)
-{
- Bool is_ok=FALSE ;
- char *atom_name=NULL ;
- int atom=None ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_local_atom, FALSE) ;
-
- atom_name = ephyrHostGetAtomName (a_host_atom) ;
- if (!atom_name)
- goto out ;
-
- atom = MakeAtom (atom_name, strlen (atom_name), TRUE) ;
- if (atom == None)
- goto out ;
-
- *a_local_atom = atom ;
- is_ok = TRUE ;
-
-out:
- if (atom_name) {
- ephyrHostFree (atom_name) ;
- }
- return is_ok ;
-}
-*/
-
-/**************
- *</helpers>
- * ************/
-
-Bool
-ephyrInitVideo (ScreenPtr pScreen)
-{
- Bool is_ok = FALSE ;
- KdScreenPriv(pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- static EphyrXVPriv *xv_priv;
-
- EPHYR_LOG ("enter\n") ;
-
- if (screen->fb.bitsPerPixel == 8) {
- EPHYR_LOG_ERROR ("8 bits depth not supported\n") ;
- return FALSE ;
- }
-
- if (!xv_priv) {
- xv_priv = ephyrXVPrivNew () ;
- }
- if (!xv_priv) {
- EPHYR_LOG_ERROR ("failed to create xv_priv\n") ;
- goto out ;
- }
-
- if (!ephyrXVPrivRegisterAdaptors (xv_priv, pScreen)) {
- EPHYR_LOG_ERROR ("failed to register adaptors\n") ;
- goto out ;
- }
- is_ok = TRUE ;
-
-out:
- return is_ok ;
-}
-
-static EphyrXVPriv*
-ephyrXVPrivNew (void)
-{
- EphyrXVPriv *xv_priv=NULL ;
-
- EPHYR_LOG ("enter\n") ;
-
- xv_priv = xcalloc (1, sizeof (EphyrXVPriv)) ;
- if (!xv_priv) {
- EPHYR_LOG_ERROR ("failed to create EphyrXVPriv\n") ;
- goto error ;
- }
-
- ephyrHostXVInit () ;
-
- if (!ephyrXVPrivQueryHostAdaptors (xv_priv)) {
- EPHYR_LOG_ERROR ("failed to query the host x for xv properties\n") ;
- goto error ;
- }
- if (!ephyrXVPrivSetAdaptorsHooks (xv_priv)) {
- EPHYR_LOG_ERROR ("failed to set xv_priv hooks\n") ;
- goto error ;
- }
-
- EPHYR_LOG ("leave\n") ;
- return xv_priv ;
-
-error:
- if (xv_priv) {
- ephyrXVPrivDelete (xv_priv) ;
- xv_priv = NULL ;
- }
- return NULL ;
-}
-
-static void
-ephyrXVPrivDelete (EphyrXVPriv *a_this)
-{
- EPHYR_LOG ("enter\n") ;
-
- if (!a_this)
- return ;
- if (a_this->host_adaptors) {
- ephyrHostXVAdaptorArrayDelete (a_this->host_adaptors) ;
- a_this->host_adaptors = NULL ;
- }
- xfree (a_this->adaptors) ;
- a_this->adaptors = NULL ;
- xfree (a_this) ;
- EPHYR_LOG ("leave\n") ;
-}
-
-static KdVideoEncodingPtr
-videoEncodingDup (EphyrHostEncoding *a_encodings,
- int a_num_encodings)
-{
- KdVideoEncodingPtr result = NULL ;
- int i=0 ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_encodings && a_num_encodings, NULL) ;
-
- result = xcalloc (a_num_encodings, sizeof (KdVideoEncodingRec)) ;
- for (i=0 ; i < a_num_encodings; i++) {
- result[i].id = a_encodings[i].id ;
- result[i].name = strdup (a_encodings[i].name) ;
- result[i].width = a_encodings[i].width ;
- result[i].height = a_encodings[i].height ;
- result[i].rate.numerator = a_encodings[i].rate.numerator ;
- result[i].rate.denominator = a_encodings[i].rate.denominator ;
- }
- return result ;
-}
-
-static KdAttributePtr
-portAttributesDup (EphyrHostAttribute *a_encodings,
- int a_num_encodings)
-{
- int i=0 ;
- KdAttributePtr result=NULL ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_encodings && a_num_encodings, NULL) ;
-
- result = xcalloc (a_num_encodings, sizeof (KdAttributeRec)) ;
- if (!result) {
- EPHYR_LOG_ERROR ("failed to allocate attributes\n") ;
- return NULL ;
- }
- for (i=0; i < a_num_encodings; i++) {
- result[i].flags = a_encodings[i].flags ;
- result[i].min_value = a_encodings[i].min_value ;
- result[i].max_value = a_encodings[i].max_value ;
- result[i].name = strdup (a_encodings[i].name) ;
- }
- return result ;
-}
-
-static Bool
-ephyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
-{
- EphyrHostXVAdaptor *cur_host_adaptor=NULL ;
- EphyrHostVideoFormat *video_formats=NULL ;
- EphyrHostEncoding *encodings=NULL ;
- EphyrHostAttribute *attributes=NULL ;
- EphyrHostImageFormat *image_formats=NULL ;
- int num_video_formats=0, base_port_id=0,
- num_attributes=0, num_formats=0, i=0,
- port_priv_offset=0;
- unsigned num_encodings=0 ;
- Bool is_ok = FALSE ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_this, FALSE) ;
-
- EPHYR_LOG ("enter\n") ;
-
- if (!ephyrHostXVQueryAdaptors (&a_this->host_adaptors)) {
- EPHYR_LOG_ERROR ("failed to query host adaptors\n") ;
- goto out ;
- }
- if (a_this->host_adaptors)
- a_this->num_adaptors =
- ephyrHostXVAdaptorArrayGetSize (a_this->host_adaptors) ;
- if (a_this->num_adaptors < 0) {
- EPHYR_LOG_ERROR ("failed to get number of host adaptors\n") ;
- goto out ;
- }
- EPHYR_LOG ("host has %d adaptors\n", a_this->num_adaptors) ;
- /*
- * copy what we can from adaptors into a_this->adaptors
- */
- if (a_this->num_adaptors) {
- a_this->adaptors = xcalloc (a_this->num_adaptors,
- sizeof (KdVideoAdaptorRec)) ;
- if (!a_this->adaptors) {
- EPHYR_LOG_ERROR ("failed to create internal adaptors\n") ;
- goto out ;
- }
- }
- for (i=0; i < a_this->num_adaptors; i++) {
- int j=0 ;
- cur_host_adaptor =
- ephyrHostXVAdaptorArrayAt (a_this->host_adaptors, i) ;
- if (!cur_host_adaptor)
- continue ;
- a_this->adaptors[i].nPorts =
- ephyrHostXVAdaptorGetNbPorts (cur_host_adaptor) ;
- if (a_this->adaptors[i].nPorts <=0) {
- EPHYR_LOG_ERROR ("Could not find any port of adaptor %d\n", i) ;
- continue ;
- }
- a_this->adaptors[i].type =
- ephyrHostXVAdaptorGetType (cur_host_adaptor) ;
- a_this->adaptors[i].type |= XvWindowMask ;
- a_this->adaptors[i].flags =
- VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
- if (ephyrHostXVAdaptorGetName (cur_host_adaptor))
- a_this->adaptors[i].name =
- strdup (ephyrHostXVAdaptorGetName (cur_host_adaptor)) ;
- else
- a_this->adaptors[i].name = strdup ("Xephyr Video Overlay");
- base_port_id = ephyrHostXVAdaptorGetFirstPortID (cur_host_adaptor) ;
- if (base_port_id < 0) {
- EPHYR_LOG_ERROR ("failed to get port id for adaptor %d\n", i) ;
- continue ;
- }
- if (!s_base_port_id)
- s_base_port_id = base_port_id ;
-
- if (!ephyrHostXVQueryEncodings (base_port_id,
- &encodings,
- &num_encodings)) {
- EPHYR_LOG_ERROR ("failed to get encodings for port port id %d,"
- " adaptors %d\n",
- base_port_id, i) ;
- continue ;
- }
- a_this->adaptors[i].nEncodings = num_encodings ;
- a_this->adaptors[i].pEncodings =
- videoEncodingDup (encodings, num_encodings) ;
- video_formats = (EphyrHostVideoFormat*)
- ephyrHostXVAdaptorGetVideoFormats (cur_host_adaptor,
- &num_video_formats);
- a_this->adaptors[i].pFormats = (KdVideoFormatPtr) video_formats ;
- a_this->adaptors[i].nFormats = num_video_formats ;
- /* got a_this->adaptors[i].nPorts already
- a_this->adaptors[i].nPorts =
- ephyrHostXVAdaptorGetNbPorts (cur_host_adaptor) ;
- */
- a_this->adaptors[i].pPortPrivates =
- xcalloc (a_this->adaptors[i].nPorts,
- sizeof (DevUnion) + sizeof (EphyrPortPriv)) ;
- port_priv_offset = a_this->adaptors[i].nPorts;
- for (j=0; j < a_this->adaptors[i].nPorts; j++) {
- EphyrPortPriv *port_privs_base =
- (EphyrPortPriv*)&a_this->adaptors[i].pPortPrivates[port_priv_offset];
- EphyrPortPriv *port_priv = &port_privs_base[j] ;
- port_priv->port_number = base_port_id + j;
- port_priv->current_adaptor = &a_this->adaptors[i] ;
- port_priv->xv_priv = a_this ;
- a_this->adaptors[i].pPortPrivates[j].ptr = port_priv;
- }
- if (!ephyrHostXVQueryPortAttributes (base_port_id,
- &attributes,
- &num_attributes)) {
- EPHYR_LOG_ERROR ("failed to get port attribute "
- "for adaptor %d\n", i) ;
- continue ;
- }
- a_this->adaptors[i].pAttributes =
- portAttributesDup (attributes, num_attributes);
- a_this->adaptors[i].nAttributes = num_attributes ;
- /*make sure atoms of attrs names are created in xephyr*/
- for (j=0; j < a_this->adaptors[i].nAttributes; j++) {
- if (a_this->adaptors[i].pAttributes[j].name)
- MakeAtom (a_this->adaptors[i].pAttributes[j].name,
- strlen (a_this->adaptors[i].pAttributes[j].name),
- TRUE) ;
- }
- if (!ephyrHostXVQueryImageFormats (base_port_id,
- &image_formats,
- &num_formats)) {
- EPHYR_LOG_ERROR ("failed to get image formats "
- "for adaptor %d\n", i) ;
- continue ;
- }
- a_this->adaptors[i].pImages = (KdImagePtr) image_formats ;
- a_this->adaptors[i].nImages = num_formats ;
- }
- is_ok = TRUE ;
-
-out:
- if (encodings) {
- ephyrHostEncodingsDelete (encodings, num_encodings) ;
- encodings = NULL ;
- }
- if (attributes) {
- ephyrHostAttributesDelete (attributes) ;
- attributes = NULL ;
- }
- EPHYR_LOG ("leave\n") ;
- return is_ok ;
-}
-
-static Bool
-ephyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this)
-{
- int i=0 ;
- Bool has_it=FALSE ;
- EphyrHostXVAdaptor *cur_host_adaptor=NULL ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_this, FALSE) ;
-
- EPHYR_LOG ("enter\n") ;
-
- for (i=0; i < a_this->num_adaptors; i++) {
- a_this->adaptors[i].ReputImage = ephyrReputImage ;
- a_this->adaptors[i].StopVideo = ephyrStopVideo ;
- a_this->adaptors[i].SetPortAttribute = ephyrSetPortAttribute ;
- a_this->adaptors[i].GetPortAttribute = ephyrGetPortAttribute ;
- a_this->adaptors[i].QueryBestSize = ephyrQueryBestSize ;
- a_this->adaptors[i].QueryImageAttributes = ephyrQueryImageAttributes ;
-
- cur_host_adaptor =
- ephyrHostXVAdaptorArrayAt (a_this->host_adaptors, i) ;
- if (!cur_host_adaptor) {
- EPHYR_LOG_ERROR ("failed to get host adaptor at index %d\n", i) ;
- continue ;
- }
- has_it = FALSE ;
- if (!ephyrHostXVAdaptorHasPutImage (cur_host_adaptor, &has_it)) {
- EPHYR_LOG_ERROR ("error\n") ;
- }
- if (has_it) {
- a_this->adaptors[i].PutImage = ephyrPutImage;
- }
-
- has_it = FALSE ;
- if (!ephyrHostXVAdaptorHasPutVideo (cur_host_adaptor, &has_it)) {
- EPHYR_LOG_ERROR ("error\n") ;
- }
- if (has_it) {
- a_this->adaptors[i].PutVideo = ephyrPutVideo;
- }
-
- has_it = FALSE ;
- if (!ephyrHostXVAdaptorHasGetVideo (cur_host_adaptor, &has_it)) {
- EPHYR_LOG_ERROR ("error\n") ;
- }
- if (has_it) {
- a_this->adaptors[i].GetVideo = ephyrGetVideo;
- }
-
- has_it = FALSE ;
- if (!ephyrHostXVAdaptorHasPutStill (cur_host_adaptor, &has_it)) {
- EPHYR_LOG_ERROR ("error\n") ;
- }
- if (has_it) {
- a_this->adaptors[i].PutStill = ephyrPutStill;
- }
-
- has_it = FALSE ;
- if (!ephyrHostXVAdaptorHasGetStill (cur_host_adaptor, &has_it)) {
- EPHYR_LOG_ERROR ("error\n") ;
- }
- if (has_it) {
- a_this->adaptors[i].GetStill = ephyrGetStill;
- }
- }
- EPHYR_LOG ("leave\n") ;
- return TRUE ;
-}
-
-static Bool
-ephyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this,
- ScreenPtr a_screen)
-{
- KdScreenPriv(a_screen);
- KdScreenInfo *screen = pScreenPriv->screen;
- Bool is_ok = FALSE ;
- KdVideoAdaptorPtr *adaptors=NULL, *registered_adaptors=NULL ;
- int num_registered_adaptors=0, i=0, num_adaptors=0 ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_this && a_screen, FALSE) ;
-
- EPHYR_LOG ("enter\n") ;
-
- if (!a_this->num_adaptors)
- goto out ;
- num_registered_adaptors =
- KdXVListGenericAdaptors (screen, &registered_adaptors);
-
- num_adaptors = num_registered_adaptors + a_this->num_adaptors ;
- adaptors = xcalloc (num_adaptors, sizeof (KdVideoAdaptorPtr)) ;
- if (!adaptors) {
- EPHYR_LOG_ERROR ("failed to allocate adaptors tab\n") ;
- goto out ;
- }
- memmove (adaptors, registered_adaptors, num_registered_adaptors) ;
- for (i=0 ; i < a_this->num_adaptors; i++) {
- *(adaptors + num_registered_adaptors + i) = &a_this->adaptors[i] ;
- }
- if (!KdXVScreenInit (a_screen, adaptors, num_adaptors)) {
- EPHYR_LOG_ERROR ("failed to register adaptors\n");
- goto out ;
- }
- EPHYR_LOG ("there are %d registered adaptors\n", num_adaptors) ;
- is_ok = TRUE ;
-
-out:
- xfree (registered_adaptors) ;
- registered_adaptors = NULL ;
- xfree (adaptors) ;
- adaptors = NULL ;
-
- EPHYR_LOG ("leave\n") ;
- return is_ok ;
-}
-
-static Bool
-ephyrXVPrivIsAttrValueValid (KdAttributePtr a_attrs,
- int a_attrs_len,
- const char *a_attr_name,
- int a_attr_value,
- Bool *a_is_valid)
-{
- int i=0 ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_attrs && a_attr_name && a_is_valid,
- FALSE) ;
-
- for (i=0; i < a_attrs_len; i++) {
- if (a_attrs[i].name && strcmp (a_attrs[i].name, a_attr_name))
- continue ;
- if (a_attrs[i].min_value > a_attr_value ||
- a_attrs[i].max_value < a_attr_value) {
- *a_is_valid = FALSE ;
- EPHYR_LOG_ERROR ("attribute was not valid\n"
- "value:%d. min:%d. max:%d\n",
- a_attr_value,
- a_attrs[i].min_value,
- a_attrs[i].max_value) ;
- } else {
- *a_is_valid = TRUE ;
- }
- return TRUE ;
- }
- return FALSE ;
-}
-
-static Bool
-ephyrXVPrivGetImageBufSize (int a_port_id,
- int a_image_id,
- unsigned short a_width,
- unsigned short a_height,
- int *a_size)
-{
- Bool is_ok=FALSE ;
- unsigned short width=a_width, height=a_height ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_size, FALSE) ;
-
- EPHYR_LOG ("enter\n") ;
-
- if (!ephyrHostXVQueryImageAttributes (a_port_id, a_image_id,
- &width, &height, a_size, NULL, NULL)) {
- EPHYR_LOG_ERROR ("failed to get image attributes\n") ;
- goto out ;
- }
- is_ok = TRUE ;
-
-out:
- EPHYR_LOG ("leave\n") ;
- return is_ok ;
-}
-
-static Bool
-ephyrXVPrivSaveImageToPortPriv (EphyrPortPriv *a_port_priv,
- const unsigned char *a_image_buf,
- int a_image_len)
-{
- Bool is_ok=FALSE ;
-
- EPHYR_LOG ("enter\n") ;
-
- if (a_port_priv->image_buf_size < a_image_len) {
- unsigned char *buf=NULL ;
- buf = realloc (a_port_priv->image_buf, a_image_len) ;
- if (!buf) {
- EPHYR_LOG_ERROR ("failed to realloc image buffer\n") ;
- goto out ;
- }
- a_port_priv->image_buf = buf ;
- a_port_priv->image_buf_size = a_image_len;
- }
- memmove (a_port_priv->image_buf, a_image_buf, a_image_len) ;
- is_ok = TRUE ;
-
-out:
- return is_ok ;
- EPHYR_LOG ("leave\n") ;
-}
-
-static void
-ephyrStopVideo (KdScreenInfo *a_info, pointer a_port_priv, Bool a_exit)
-{
- EphyrPortPriv *port_priv = a_port_priv ;
-
- EPHYR_RETURN_IF_FAIL (a_info && a_info->pScreen) ;
- EPHYR_RETURN_IF_FAIL (port_priv) ;
-
- EPHYR_LOG ("enter\n") ;
- if (!ephyrHostXVStopVideo (a_info->pScreen->myNum,
- port_priv->port_number)) {
- EPHYR_LOG_ERROR ("XvStopVideo() failed\n") ;
- }
- EPHYR_LOG ("leave\n") ;
-}
-
-static int
-ephyrSetPortAttribute (KdScreenInfo *a_info,
- Atom a_attr_name,
- int a_attr_value,
- pointer a_port_priv)
-{
- int res=Success, host_atom=0 ;
- EphyrPortPriv *port_priv = a_port_priv ;
- Bool is_attr_valid=FALSE ;
-
- EPHYR_RETURN_VAL_IF_FAIL (port_priv, BadMatch) ;
- EPHYR_RETURN_VAL_IF_FAIL (port_priv->current_adaptor, BadMatch) ;
- EPHYR_RETURN_VAL_IF_FAIL (port_priv->current_adaptor->pAttributes,
- BadMatch) ;
- EPHYR_RETURN_VAL_IF_FAIL (port_priv->current_adaptor->nAttributes,
- BadMatch) ;
- EPHYR_RETURN_VAL_IF_FAIL (ValidAtom (a_attr_name), BadMatch) ;
-
- EPHYR_LOG ("enter, portnum:%d, atomid:%d, attr_name:%s, attr_val:%d\n",
- port_priv->port_number,
- (int)a_attr_name,
- NameForAtom (a_attr_name),
- a_attr_value) ;
-
- if (!ephyrLocalAtomToHost (a_attr_name, &host_atom)) {
- EPHYR_LOG_ERROR ("failed to convert local atom to host atom\n") ;
- res = BadMatch ;
- goto out ;
- }
-
- if (!ephyrXVPrivIsAttrValueValid (port_priv->current_adaptor->pAttributes,
- port_priv->current_adaptor->nAttributes,
- NameForAtom (a_attr_name),
- a_attr_value,
- &is_attr_valid)) {
- EPHYR_LOG_ERROR ("failed to validate attribute %s\n",
- NameForAtom (a_attr_name)) ;
- /*
- res = BadMatch ;
- goto out ;
- */
- }
- if (!is_attr_valid) {
- EPHYR_LOG_ERROR ("attribute %s is not valid\n",
- NameForAtom (a_attr_name)) ;
- /*
- res = BadMatch ;
- goto out ;
- */
- }
-
- if (!ephyrHostXVSetPortAttribute (port_priv->port_number,
- host_atom,
- a_attr_value)) {
- EPHYR_LOG_ERROR ("failed to set port attribute\n") ;
- res = BadMatch ;
- goto out ;
- }
-
- res = Success ;
-out:
- EPHYR_LOG ("leave\n") ;
- return res ;
-}
-
-static int
-ephyrGetPortAttribute (KdScreenInfo *a_screen_info,
- Atom a_attr_name,
- int *a_attr_value,
- pointer a_port_priv)
-{
- int res=Success, host_atom=0 ;
- EphyrPortPriv *port_priv = a_port_priv ;
-
- EPHYR_RETURN_VAL_IF_FAIL (port_priv, BadMatch) ;
- EPHYR_RETURN_VAL_IF_FAIL (ValidAtom (a_attr_name), BadMatch) ;
-
- EPHYR_LOG ("enter, portnum:%d, atomid:%d, attr_name:%s\n",
- port_priv->port_number,
- (int)a_attr_name,
- NameForAtom (a_attr_name)) ;
-
- if (!ephyrLocalAtomToHost (a_attr_name, &host_atom)) {
- EPHYR_LOG_ERROR ("failed to convert local atom to host atom\n") ;
- res = BadMatch ;
- goto out ;
- }
-
- if (!ephyrHostXVGetPortAttribute (port_priv->port_number,
- host_atom,
- a_attr_value)) {
- EPHYR_LOG_ERROR ("failed to get port attribute\n") ;
- res = BadMatch ;
- goto out ;
- }
-
- res = Success ;
-out:
- EPHYR_LOG ("leave\n") ;
- return res ;
-}
-
-static void
-ephyrQueryBestSize (KdScreenInfo *a_info,
- Bool a_motion,
- short a_src_w,
- short a_src_h,
- short a_drw_w,
- short a_drw_h,
- unsigned int *a_prefered_w,
- unsigned int *a_prefered_h,
- pointer a_port_priv)
-{
- int res=0 ;
- EphyrPortPriv *port_priv = a_port_priv ;
-
- EPHYR_RETURN_IF_FAIL (port_priv) ;
-
- EPHYR_LOG ("enter\n") ;
- res = ephyrHostXVQueryBestSize (port_priv->port_number,
- a_motion,
- a_src_w, a_src_h,
- a_drw_w, a_drw_h,
- a_prefered_w, a_prefered_h) ;
- if (!res) {
- EPHYR_LOG_ERROR ("Failed to query best size\n") ;
- }
- EPHYR_LOG ("leave\n") ;
-}
-
-static int
-ephyrPutImage (KdScreenInfo *a_info,
- DrawablePtr a_drawable,
- short a_src_x,
- short a_src_y,
- short a_drw_x,
- short a_drw_y,
- short a_src_w,
- short a_src_h,
- short a_drw_w,
- short a_drw_h,
- int a_id,
- unsigned char *a_buf,
- short a_width,
- short a_height,
- Bool a_sync,
- RegionPtr a_clipping_region,
- pointer a_port_priv)
-{
- EphyrPortPriv *port_priv = a_port_priv ;
- Bool is_ok=FALSE ;
- int result=BadImplementation, image_size=0 ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ;
- EPHYR_RETURN_VAL_IF_FAIL (a_drawable, BadValue) ;
-
- EPHYR_LOG ("enter\n") ;
-
- if (!ephyrHostXVPutImage (a_info->pScreen->myNum,
- port_priv->port_number,
- a_id,
- a_drw_x, a_drw_y, a_drw_w, a_drw_h,
- a_src_x, a_src_y, a_src_w, a_src_h,
- a_width, a_height, a_buf,
- (EphyrHostBox*)REGION_RECTS (a_clipping_region),
- REGION_NUM_RECTS (a_clipping_region))) {
- EPHYR_LOG_ERROR ("EphyrHostXVPutImage() failed\n") ;
- goto out ;
- }
-
- /*
- * Now save the image so that we can resend it to host it
- * later, in ReputImage.
- */
- if (!ephyrXVPrivGetImageBufSize (port_priv->port_number,
- a_id, a_width, a_height, &image_size)) {
- EPHYR_LOG_ERROR ("failed to get image size\n") ;
- /*this is a minor error so we won't get bail out abruptly*/
- is_ok = FALSE ;
- } else {
- is_ok = TRUE ;
- }
- if (is_ok) {
- if (!ephyrXVPrivSaveImageToPortPriv (port_priv, a_buf, image_size)) {
- is_ok=FALSE ;
- } else {
- port_priv->image_id = a_id;
- port_priv->drw_x = a_drw_x;
- port_priv->drw_y = a_drw_y;
- port_priv->drw_w = a_drw_w ;
- port_priv->drw_h = a_drw_h ;
- port_priv->src_x = a_src_x;
- port_priv->src_y = a_src_y ;
- port_priv->src_w = a_src_w ;
- port_priv->src_h = a_src_h ;
- port_priv->image_width = a_width ;
- port_priv->image_height = a_height ;
- }
- }
- if (!is_ok) {
- if (port_priv->image_buf) {
- free (port_priv->image_buf) ;
- port_priv->image_buf = NULL ;
- port_priv->image_buf_size = 0 ;
- }
- }
-
- result = Success ;
-
-out:
- EPHYR_LOG ("leave\n") ;
- return result ;
-}
-
-static int
-ephyrReputImage (KdScreenInfo *a_info,
- DrawablePtr a_drawable,
- short a_drw_x,
- short a_drw_y,
- RegionPtr a_clipping_region,
- pointer a_port_priv)
-{
- EphyrPortPriv *port_priv = a_port_priv ;
- int result=BadImplementation ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_info->pScreen, FALSE) ;
- EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
-
- EPHYR_LOG ("enter\n") ;
-
- if (!port_priv->image_buf_size || !port_priv->image_buf) {
- EPHYR_LOG_ERROR ("has null image buf in cache\n") ;
- goto out ;
- }
- if (!ephyrHostXVPutImage (a_info->pScreen->myNum,
- port_priv->port_number,
- port_priv->image_id,
- a_drw_x, a_drw_y,
- port_priv->drw_w, port_priv->drw_h,
- port_priv->src_x, port_priv->src_y,
- port_priv->src_w, port_priv->src_h,
- port_priv->image_width, port_priv->image_height,
- port_priv->image_buf,
- (EphyrHostBox*)REGION_RECTS (a_clipping_region),
- REGION_NUM_RECTS (a_clipping_region))) {
- EPHYR_LOG_ERROR ("ephyrHostXVPutImage() failed\n") ;
- goto out ;
- }
-
- result = Success ;
-
-out:
- EPHYR_LOG ("leave\n") ;
- return result ;
-}
-
-static int
-ephyrPutVideo (KdScreenInfo *a_info,
- DrawablePtr a_drawable,
- short a_vid_x, short a_vid_y,
- short a_drw_x, short a_drw_y,
- short a_vid_w, short a_vid_h,
- short a_drw_w, short a_drw_h,
- RegionPtr a_clipping_region,
- pointer a_port_priv)
-{
- EphyrPortPriv *port_priv = a_port_priv ;
- BoxRec clipped_area, dst_box ;
- int result=BadImplementation ;
- int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_info->pScreen, BadValue) ;
- EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
-
- EPHYR_LOG ("enter\n") ;
-
- dst_box.x1 = a_drw_x ;
- dst_box.x2 = a_drw_x + a_drw_w;
- dst_box.y1 = a_drw_y ;
- dst_box.y2 = a_drw_y + a_drw_h;
-
- if (!DoSimpleClip (&dst_box,
- REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
- &clipped_area)) {
- EPHYR_LOG_ERROR ("failed to simple clip\n") ;
- goto out ;
- }
-
- drw_x = clipped_area.x1 ;
- drw_y = clipped_area.y1 ;
- drw_w = clipped_area.x2 - clipped_area.x1 ;
- drw_h = clipped_area.y2 - clipped_area.y1 ;
-
- if (!ephyrHostXVPutVideo (a_info->pScreen->myNum,
- port_priv->port_number,
- a_vid_x, a_vid_y, a_vid_w, a_vid_h,
- a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
- EPHYR_LOG_ERROR ("ephyrHostXVPutVideo() failed\n") ;
- goto out ;
- }
- result = Success ;
-
-out:
- EPHYR_LOG ("leave\n") ;
- return result ;
-}
-
-static int
-ephyrGetVideo (KdScreenInfo *a_info,
- DrawablePtr a_drawable,
- short a_vid_x, short a_vid_y,
- short a_drw_x, short a_drw_y,
- short a_vid_w, short a_vid_h,
- short a_drw_w, short a_drw_h,
- RegionPtr a_clipping_region,
- pointer a_port_priv)
-{
- EphyrPortPriv *port_priv = a_port_priv ;
- BoxRec clipped_area, dst_box ;
- int result=BadImplementation ;
- int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ;
- EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
-
- EPHYR_LOG ("enter\n") ;
-
- dst_box.x1 = a_drw_x ;
- dst_box.x2 = a_drw_x + a_drw_w;
- dst_box.y1 = a_drw_y ;
- dst_box.y2 = a_drw_y + a_drw_h;
-
- if (!DoSimpleClip (&dst_box,
- REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
- &clipped_area)) {
- EPHYR_LOG_ERROR ("failed to simple clip\n") ;
- goto out ;
- }
-
- drw_x = clipped_area.x1 ;
- drw_y = clipped_area.y1 ;
- drw_w = clipped_area.x2 - clipped_area.x1 ;
- drw_h = clipped_area.y2 - clipped_area.y1 ;
-
- if (!ephyrHostXVGetVideo (a_info->pScreen->myNum,
- port_priv->port_number,
- a_vid_x, a_vid_y, a_vid_w, a_vid_h,
- a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
- EPHYR_LOG_ERROR ("ephyrHostXVGetVideo() failed\n") ;
- goto out ;
- }
- result = Success ;
-
-out:
- EPHYR_LOG ("leave\n") ;
- return result ;
-}
-
-static int
-ephyrPutStill (KdScreenInfo *a_info,
- DrawablePtr a_drawable,
- short a_vid_x, short a_vid_y,
- short a_drw_x, short a_drw_y,
- short a_vid_w, short a_vid_h,
- short a_drw_w, short a_drw_h,
- RegionPtr a_clipping_region,
- pointer a_port_priv)
-{
- EphyrPortPriv *port_priv = a_port_priv ;
- BoxRec clipped_area, dst_box ;
- int result=BadImplementation ;
- int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ;
- EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
-
- EPHYR_LOG ("enter\n") ;
-
- dst_box.x1 = a_drw_x ;
- dst_box.x2 = a_drw_x + a_drw_w;
- dst_box.y1 = a_drw_y ;
- dst_box.y2 = a_drw_y + a_drw_h;
-
- if (!DoSimpleClip (&dst_box,
- REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
- &clipped_area)) {
- EPHYR_LOG_ERROR ("failed to simple clip\n") ;
- goto out ;
- }
-
- drw_x = clipped_area.x1 ;
- drw_y = clipped_area.y1 ;
- drw_w = clipped_area.x2 - clipped_area.x1 ;
- drw_h = clipped_area.y2 - clipped_area.y1 ;
-
- if (!ephyrHostXVPutStill (a_info->pScreen->myNum,
- port_priv->port_number,
- a_vid_x, a_vid_y, a_vid_w, a_vid_h,
- a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
- EPHYR_LOG_ERROR ("ephyrHostXVPutStill() failed\n") ;
- goto out ;
- }
- result = Success ;
-
-out:
- EPHYR_LOG ("leave\n") ;
- return result ;
-}
-
-static int
-ephyrGetStill (KdScreenInfo *a_info,
- DrawablePtr a_drawable,
- short a_vid_x, short a_vid_y,
- short a_drw_x, short a_drw_y,
- short a_vid_w, short a_vid_h,
- short a_drw_w, short a_drw_h,
- RegionPtr a_clipping_region,
- pointer a_port_priv)
-{
- EphyrPortPriv *port_priv = a_port_priv ;
- BoxRec clipped_area, dst_box ;
- int result=BadImplementation ;
- int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ;
- EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
-
- EPHYR_LOG ("enter\n") ;
-
- dst_box.x1 = a_drw_x ;
- dst_box.x2 = a_drw_x + a_drw_w;
- dst_box.y1 = a_drw_y ;
- dst_box.y2 = a_drw_y + a_drw_h;
-
- if (!DoSimpleClip (&dst_box,
- REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
- &clipped_area)) {
- EPHYR_LOG_ERROR ("failed to simple clip\n") ;
- goto out ;
- }
-
- drw_x = clipped_area.x1 ;
- drw_y = clipped_area.y1 ;
- drw_w = clipped_area.x2 - clipped_area.x1 ;
- drw_h = clipped_area.y2 - clipped_area.y1 ;
-
- if (!ephyrHostXVGetStill (a_info->pScreen->myNum,
- port_priv->port_number,
- a_vid_x, a_vid_y, a_vid_w, a_vid_h,
- a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
- EPHYR_LOG_ERROR ("ephyrHostXVGetStill() failed\n") ;
- goto out ;
- }
- result = Success ;
-
-out:
- EPHYR_LOG ("leave\n") ;
- return result ;
-}
-
-static int
-ephyrQueryImageAttributes (KdScreenInfo *a_info,
- int a_id,
- unsigned short *a_w,
- unsigned short *a_h,
- int *a_pitches,
- int *a_offsets)
-{
- int image_size=0 ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_w && a_h, FALSE) ;
-
- EPHYR_LOG ("enter: dim (%dx%d), pitches: %p, offsets: %p\n",
- *a_w, *a_h, a_pitches, a_offsets) ;
-
- if (!ephyrHostXVQueryImageAttributes (s_base_port_id,
- a_id,
- a_w, a_h,
- &image_size,
- a_pitches, a_offsets)) {
- EPHYR_LOG_ERROR ("EphyrHostXVQueryImageAttributes() failed\n") ;
- goto out ;
- }
- EPHYR_LOG ("image size: %d, dim (%dx%d)\n", image_size, *a_w, *a_h) ;
-
-out:
- EPHYR_LOG ("leave\n") ;
- return image_size ;
-}
+/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ * Authored by Matthew Allum <mallum@openedhand.com>
+ *
+ * Copyright © 2007 OpenedHand Ltd
+ *
+ * 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 OpenedHand Ltd not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. OpenedHand Ltd makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors:
+ * Dodji Seketeli <dodji@openedhand.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+#include <string.h>
+#include <X11/extensions/Xv.h>
+#include "ephyrlog.h"
+#include "kdrive.h"
+#include "kxv.h"
+#include "ephyr.h"
+#include "hostx.h"
+#include "ephyrhostvideo.h"
+
+struct _EphyrXVPriv {
+ EphyrHostXVAdaptorArray *host_adaptors ;
+ KdVideoAdaptorPtr adaptors ;
+ int num_adaptors ;
+};
+typedef struct _EphyrXVPriv EphyrXVPriv ;
+
+struct _EphyrPortPriv {
+ int port_number ;
+ KdVideoAdaptorPtr current_adaptor ;
+ EphyrXVPriv *xv_priv;
+ unsigned char *image_buf ;
+ int image_buf_size ;
+ int image_id ;
+ int drw_x, drw_y, drw_w, drw_h ;
+ int src_x, src_y, src_w, src_h ;
+ int image_width, image_height ;
+};
+typedef struct _EphyrPortPriv EphyrPortPriv ;
+
+static Bool DoSimpleClip (BoxPtr a_dst_drw,
+ BoxPtr a_clipper,
+ BoxPtr a_result) ;
+
+static Bool ephyrLocalAtomToHost (int a_local_atom, int *a_host_atom) ;
+
+/*
+static Bool ephyrHostAtomToLocal (int a_host_atom, int *a_local_atom) ;
+*/
+
+static EphyrXVPriv* ephyrXVPrivNew (void) ;
+static void ephyrXVPrivDelete (EphyrXVPriv *a_this) ;
+static Bool ephyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this) ;
+static Bool ephyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this) ;
+static Bool ephyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this,
+ ScreenPtr a_screen) ;
+
+static Bool ephyrXVPrivIsAttrValueValid (KdAttributePtr a_attrs,
+ int a_attrs_len,
+ const char *a_attr_name,
+ int a_attr_value,
+ Bool *a_is_valid) ;
+
+static Bool ephyrXVPrivGetImageBufSize (int a_port_id,
+ int a_image_id,
+ unsigned short a_width,
+ unsigned short a_height,
+ int *a_size) ;
+
+static Bool ephyrXVPrivSaveImageToPortPriv (EphyrPortPriv *a_port_priv,
+ const unsigned char *a_image,
+ int a_image_len) ;
+
+static void ephyrStopVideo (KdScreenInfo *a_info,
+ pointer a_xv_priv,
+ Bool a_exit);
+
+static int ephyrSetPortAttribute (KdScreenInfo *a_info,
+ Atom a_attr_name,
+ int a_attr_value,
+ pointer a_port_priv);
+
+static int ephyrGetPortAttribute (KdScreenInfo *a_screen_info,
+ Atom a_attr_name,
+ int *a_attr_value,
+ pointer a_port_priv);
+
+static void ephyrQueryBestSize (KdScreenInfo *a_info,
+ Bool a_motion,
+ short a_src_w,
+ short a_src_h,
+ short a_drw_w,
+ short a_drw_h,
+ unsigned int *a_prefered_w,
+ unsigned int *a_prefered_h,
+ pointer a_port_priv);
+
+static int ephyrPutImage (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_src_x,
+ short a_src_y,
+ short a_drw_x,
+ short a_drw_y,
+ short a_src_w,
+ short a_src_h,
+ short a_drw_w,
+ short a_drw_h,
+ int a_id,
+ unsigned char *a_buf,
+ short a_width,
+ short a_height,
+ Bool a_sync,
+ RegionPtr a_clipping_region,
+ pointer a_port_priv);
+
+static int ephyrReputImage (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_drw_x,
+ short a_drw_y,
+ RegionPtr a_clipping_region,
+ pointer a_port_priv) ;
+
+static int ephyrPutVideo (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_vid_x, short a_vid_y,
+ short a_drw_x, short a_drw_y,
+ short a_vid_w, short a_vid_h,
+ short a_drw_w, short a_drw_h,
+ RegionPtr a_clip_region,
+ pointer a_port_priv) ;
+
+static int ephyrGetVideo (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_vid_x, short a_vid_y,
+ short a_drw_x, short a_drw_y,
+ short a_vid_w, short a_vid_h,
+ short a_drw_w, short a_drw_h,
+ RegionPtr a_clip_region,
+ pointer a_port_priv) ;
+
+static int ephyrPutStill (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_vid_x, short a_vid_y,
+ short a_drw_x, short a_drw_y,
+ short a_vid_w, short a_vid_h,
+ short a_drw_w, short a_drw_h,
+ RegionPtr a_clip_region,
+ pointer a_port_priv) ;
+
+static int ephyrGetStill (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_vid_x, short a_vid_y,
+ short a_drw_x, short a_drw_y,
+ short a_vid_w, short a_vid_h,
+ short a_drw_w, short a_drw_h,
+ RegionPtr a_clip_region,
+ pointer a_port_priv) ;
+
+static int ephyrQueryImageAttributes (KdScreenInfo *a_info,
+ int a_id,
+ unsigned short *a_w,
+ unsigned short *a_h,
+ int *a_pitches,
+ int *a_offsets);
+static int s_base_port_id ;
+
+/**************
+ * <helpers>
+ * ************/
+
+static Bool
+DoSimpleClip (BoxPtr a_dst_box,
+ BoxPtr a_clipper,
+ BoxPtr a_result)
+{
+ BoxRec dstClippedBox ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_dst_box && a_clipper && a_result, FALSE) ;
+
+ /*
+ * setup the clipbox inside the destination.
+ */
+ dstClippedBox.x1 = a_dst_box->x1 ;
+ dstClippedBox.x2 = a_dst_box->x2 ;
+ dstClippedBox.y1 = a_dst_box->y1 ;
+ dstClippedBox.y2 = a_dst_box->y2 ;
+
+ /*
+ * if the cliper leftmost edge is inside
+ * the destination area then the leftmost edge of the resulting
+ * clipped box is the leftmost edge of the cliper.
+ */
+ if (a_clipper->x1 > dstClippedBox.x1)
+ dstClippedBox.x1 = a_clipper->x1 ;
+
+ /*
+ * if the cliper top edge is inside the destination area
+ * then the bottom horizontal edge of the resulting clipped box
+ * is the bottom edge of the cliper
+ */
+ if (a_clipper->y1 > dstClippedBox.y1)
+ dstClippedBox.y1 = a_clipper->y1 ;
+
+ /*ditto for right edge*/
+ if (a_clipper->x2 < dstClippedBox.x2)
+ dstClippedBox.x2 = a_clipper->x2 ;
+
+ /*ditto for bottom edge*/
+ if (a_clipper->y2 < dstClippedBox.y2)
+ dstClippedBox.y2 = a_clipper->y2 ;
+
+ memcpy (a_result, &dstClippedBox, sizeof (dstClippedBox)) ;
+ return TRUE ;
+}
+
+static Bool
+ephyrLocalAtomToHost (int a_local_atom, int *a_host_atom)
+{
+ const char *atom_name=NULL;
+ int host_atom=None ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_host_atom, FALSE) ;
+
+ if (!ValidAtom (a_local_atom))
+ return FALSE ;
+
+ atom_name = NameForAtom (a_local_atom) ;
+
+ if (!atom_name)
+ return FALSE ;
+
+ if (!ephyrHostGetAtom (atom_name, FALSE, &host_atom) || host_atom == None) {
+ EPHYR_LOG_ERROR ("no atom for string %s defined in host X\n",
+ atom_name) ;
+ return FALSE ;
+ }
+ *a_host_atom = host_atom ;
+ return TRUE ;
+}
+
+/*
+ Not used yed.
+static Bool
+ephyrHostAtomToLocal (int a_host_atom, int *a_local_atom)
+{
+ Bool is_ok=FALSE ;
+ char *atom_name=NULL ;
+ int atom=None ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_local_atom, FALSE) ;
+
+ atom_name = ephyrHostGetAtomName (a_host_atom) ;
+ if (!atom_name)
+ goto out ;
+
+ atom = MakeAtom (atom_name, strlen (atom_name), TRUE) ;
+ if (atom == None)
+ goto out ;
+
+ *a_local_atom = atom ;
+ is_ok = TRUE ;
+
+out:
+ if (atom_name) {
+ ephyrHostFree (atom_name) ;
+ }
+ return is_ok ;
+}
+*/
+
+/**************
+ *</helpers>
+ * ************/
+
+Bool
+ephyrInitVideo (ScreenPtr pScreen)
+{
+ Bool is_ok = FALSE ;
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ static EphyrXVPriv *xv_priv;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (screen->fb.bitsPerPixel == 8) {
+ EPHYR_LOG_ERROR ("8 bits depth not supported\n") ;
+ return FALSE ;
+ }
+
+ if (!xv_priv) {
+ xv_priv = ephyrXVPrivNew () ;
+ }
+ if (!xv_priv) {
+ EPHYR_LOG_ERROR ("failed to create xv_priv\n") ;
+ goto out ;
+ }
+
+ if (!ephyrXVPrivRegisterAdaptors (xv_priv, pScreen)) {
+ EPHYR_LOG_ERROR ("failed to register adaptors\n") ;
+ goto out ;
+ }
+ is_ok = TRUE ;
+
+out:
+ return is_ok ;
+}
+
+static EphyrXVPriv*
+ephyrXVPrivNew (void)
+{
+ EphyrXVPriv *xv_priv=NULL ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ xv_priv = calloc(1, sizeof (EphyrXVPriv)) ;
+ if (!xv_priv) {
+ EPHYR_LOG_ERROR ("failed to create EphyrXVPriv\n") ;
+ goto error ;
+ }
+
+ ephyrHostXVInit () ;
+
+ if (!ephyrXVPrivQueryHostAdaptors (xv_priv)) {
+ EPHYR_LOG_ERROR ("failed to query the host x for xv properties\n") ;
+ goto error ;
+ }
+ if (!ephyrXVPrivSetAdaptorsHooks (xv_priv)) {
+ EPHYR_LOG_ERROR ("failed to set xv_priv hooks\n") ;
+ goto error ;
+ }
+
+ EPHYR_LOG ("leave\n") ;
+ return xv_priv ;
+
+error:
+ if (xv_priv) {
+ ephyrXVPrivDelete (xv_priv) ;
+ xv_priv = NULL ;
+ }
+ return NULL ;
+}
+
+static void
+ephyrXVPrivDelete (EphyrXVPriv *a_this)
+{
+ EPHYR_LOG ("enter\n") ;
+
+ if (!a_this)
+ return ;
+ if (a_this->host_adaptors) {
+ ephyrHostXVAdaptorArrayDelete (a_this->host_adaptors) ;
+ a_this->host_adaptors = NULL ;
+ }
+ free(a_this->adaptors) ;
+ a_this->adaptors = NULL ;
+ free(a_this) ;
+ EPHYR_LOG ("leave\n") ;
+}
+
+static KdVideoEncodingPtr
+videoEncodingDup (EphyrHostEncoding *a_encodings,
+ int a_num_encodings)
+{
+ KdVideoEncodingPtr result = NULL ;
+ int i=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_encodings && a_num_encodings, NULL) ;
+
+ result = calloc(a_num_encodings, sizeof (KdVideoEncodingRec)) ;
+ for (i=0 ; i < a_num_encodings; i++) {
+ result[i].id = a_encodings[i].id ;
+ result[i].name = strdup (a_encodings[i].name) ;
+ result[i].width = a_encodings[i].width ;
+ result[i].height = a_encodings[i].height ;
+ result[i].rate.numerator = a_encodings[i].rate.numerator ;
+ result[i].rate.denominator = a_encodings[i].rate.denominator ;
+ }
+ return result ;
+}
+
+static KdAttributePtr
+portAttributesDup (EphyrHostAttribute *a_encodings,
+ int a_num_encodings)
+{
+ int i=0 ;
+ KdAttributePtr result=NULL ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_encodings && a_num_encodings, NULL) ;
+
+ result = calloc(a_num_encodings, sizeof (KdAttributeRec)) ;
+ if (!result) {
+ EPHYR_LOG_ERROR ("failed to allocate attributes\n") ;
+ return NULL ;
+ }
+ for (i=0; i < a_num_encodings; i++) {
+ result[i].flags = a_encodings[i].flags ;
+ result[i].min_value = a_encodings[i].min_value ;
+ result[i].max_value = a_encodings[i].max_value ;
+ result[i].name = strdup (a_encodings[i].name) ;
+ }
+ return result ;
+}
+
+static Bool
+ephyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
+{
+ EphyrHostXVAdaptor *cur_host_adaptor=NULL ;
+ EphyrHostVideoFormat *video_formats=NULL ;
+ EphyrHostEncoding *encodings=NULL ;
+ EphyrHostAttribute *attributes=NULL ;
+ EphyrHostImageFormat *image_formats=NULL ;
+ int num_video_formats=0, base_port_id=0,
+ num_attributes=0, num_formats=0, i=0,
+ port_priv_offset=0;
+ unsigned num_encodings=0 ;
+ Bool is_ok = FALSE ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_this, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (!ephyrHostXVQueryAdaptors (&a_this->host_adaptors)) {
+ EPHYR_LOG_ERROR ("failed to query host adaptors\n") ;
+ goto out ;
+ }
+ if (a_this->host_adaptors)
+ a_this->num_adaptors =
+ ephyrHostXVAdaptorArrayGetSize (a_this->host_adaptors) ;
+ if (a_this->num_adaptors < 0) {
+ EPHYR_LOG_ERROR ("failed to get number of host adaptors\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("host has %d adaptors\n", a_this->num_adaptors) ;
+ /*
+ * copy what we can from adaptors into a_this->adaptors
+ */
+ if (a_this->num_adaptors) {
+ a_this->adaptors = calloc(a_this->num_adaptors,
+ sizeof (KdVideoAdaptorRec)) ;
+ if (!a_this->adaptors) {
+ EPHYR_LOG_ERROR ("failed to create internal adaptors\n") ;
+ goto out ;
+ }
+ }
+ for (i=0; i < a_this->num_adaptors; i++) {
+ int j=0 ;
+ cur_host_adaptor =
+ ephyrHostXVAdaptorArrayAt (a_this->host_adaptors, i) ;
+ if (!cur_host_adaptor)
+ continue ;
+ a_this->adaptors[i].nPorts =
+ ephyrHostXVAdaptorGetNbPorts (cur_host_adaptor) ;
+ if (a_this->adaptors[i].nPorts <=0) {
+ EPHYR_LOG_ERROR ("Could not find any port of adaptor %d\n", i) ;
+ continue ;
+ }
+ a_this->adaptors[i].type =
+ ephyrHostXVAdaptorGetType (cur_host_adaptor) ;
+ a_this->adaptors[i].type |= XvWindowMask ;
+ a_this->adaptors[i].flags =
+ VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
+ if (ephyrHostXVAdaptorGetName (cur_host_adaptor))
+ a_this->adaptors[i].name =
+ strdup (ephyrHostXVAdaptorGetName (cur_host_adaptor)) ;
+ else
+ a_this->adaptors[i].name = strdup ("Xephyr Video Overlay");
+ base_port_id = ephyrHostXVAdaptorGetFirstPortID (cur_host_adaptor) ;
+ if (base_port_id < 0) {
+ EPHYR_LOG_ERROR ("failed to get port id for adaptor %d\n", i) ;
+ continue ;
+ }
+ if (!s_base_port_id)
+ s_base_port_id = base_port_id ;
+
+ if (!ephyrHostXVQueryEncodings (base_port_id,
+ &encodings,
+ &num_encodings)) {
+ EPHYR_LOG_ERROR ("failed to get encodings for port port id %d,"
+ " adaptors %d\n",
+ base_port_id, i) ;
+ continue ;
+ }
+ a_this->adaptors[i].nEncodings = num_encodings ;
+ a_this->adaptors[i].pEncodings =
+ videoEncodingDup (encodings, num_encodings) ;
+ video_formats = (EphyrHostVideoFormat*)
+ ephyrHostXVAdaptorGetVideoFormats (cur_host_adaptor,
+ &num_video_formats);
+ a_this->adaptors[i].pFormats = (KdVideoFormatPtr) video_formats ;
+ a_this->adaptors[i].nFormats = num_video_formats ;
+ /* got a_this->adaptors[i].nPorts already
+ a_this->adaptors[i].nPorts =
+ ephyrHostXVAdaptorGetNbPorts (cur_host_adaptor) ;
+ */
+ a_this->adaptors[i].pPortPrivates =
+ calloc(a_this->adaptors[i].nPorts,
+ sizeof (DevUnion) + sizeof (EphyrPortPriv)) ;
+ port_priv_offset = a_this->adaptors[i].nPorts;
+ for (j=0; j < a_this->adaptors[i].nPorts; j++) {
+ EphyrPortPriv *port_privs_base =
+ (EphyrPortPriv*)&a_this->adaptors[i].pPortPrivates[port_priv_offset];
+ EphyrPortPriv *port_priv = &port_privs_base[j] ;
+ port_priv->port_number = base_port_id + j;
+ port_priv->current_adaptor = &a_this->adaptors[i] ;
+ port_priv->xv_priv = a_this ;
+ a_this->adaptors[i].pPortPrivates[j].ptr = port_priv;
+ }
+ if (!ephyrHostXVQueryPortAttributes (base_port_id,
+ &attributes,
+ &num_attributes)) {
+ EPHYR_LOG_ERROR ("failed to get port attribute "
+ "for adaptor %d\n", i) ;
+ continue ;
+ }
+ a_this->adaptors[i].pAttributes =
+ portAttributesDup (attributes, num_attributes);
+ a_this->adaptors[i].nAttributes = num_attributes ;
+ /*make sure atoms of attrs names are created in xephyr*/
+ for (j=0; j < a_this->adaptors[i].nAttributes; j++) {
+ if (a_this->adaptors[i].pAttributes[j].name)
+ MakeAtom (a_this->adaptors[i].pAttributes[j].name,
+ strlen (a_this->adaptors[i].pAttributes[j].name),
+ TRUE) ;
+ }
+ if (!ephyrHostXVQueryImageFormats (base_port_id,
+ &image_formats,
+ &num_formats)) {
+ EPHYR_LOG_ERROR ("failed to get image formats "
+ "for adaptor %d\n", i) ;
+ continue ;
+ }
+ a_this->adaptors[i].pImages = (KdImagePtr) image_formats ;
+ a_this->adaptors[i].nImages = num_formats ;
+ }
+ is_ok = TRUE ;
+
+out:
+ if (encodings) {
+ ephyrHostEncodingsDelete (encodings, num_encodings) ;
+ encodings = NULL ;
+ }
+ if (attributes) {
+ ephyrHostAttributesDelete (attributes) ;
+ attributes = NULL ;
+ }
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+static Bool
+ephyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this)
+{
+ int i=0 ;
+ Bool has_it=FALSE ;
+ EphyrHostXVAdaptor *cur_host_adaptor=NULL ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_this, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ for (i=0; i < a_this->num_adaptors; i++) {
+ a_this->adaptors[i].ReputImage = ephyrReputImage ;
+ a_this->adaptors[i].StopVideo = ephyrStopVideo ;
+ a_this->adaptors[i].SetPortAttribute = ephyrSetPortAttribute ;
+ a_this->adaptors[i].GetPortAttribute = ephyrGetPortAttribute ;
+ a_this->adaptors[i].QueryBestSize = ephyrQueryBestSize ;
+ a_this->adaptors[i].QueryImageAttributes = ephyrQueryImageAttributes ;
+
+ cur_host_adaptor =
+ ephyrHostXVAdaptorArrayAt (a_this->host_adaptors, i) ;
+ if (!cur_host_adaptor) {
+ EPHYR_LOG_ERROR ("failed to get host adaptor at index %d\n", i) ;
+ continue ;
+ }
+ has_it = FALSE ;
+ if (!ephyrHostXVAdaptorHasPutImage (cur_host_adaptor, &has_it)) {
+ EPHYR_LOG_ERROR ("error\n") ;
+ }
+ if (has_it) {
+ a_this->adaptors[i].PutImage = ephyrPutImage;
+ }
+
+ has_it = FALSE ;
+ if (!ephyrHostXVAdaptorHasPutVideo (cur_host_adaptor, &has_it)) {
+ EPHYR_LOG_ERROR ("error\n") ;
+ }
+ if (has_it) {
+ a_this->adaptors[i].PutVideo = ephyrPutVideo;
+ }
+
+ has_it = FALSE ;
+ if (!ephyrHostXVAdaptorHasGetVideo (cur_host_adaptor, &has_it)) {
+ EPHYR_LOG_ERROR ("error\n") ;
+ }
+ if (has_it) {
+ a_this->adaptors[i].GetVideo = ephyrGetVideo;
+ }
+
+ has_it = FALSE ;
+ if (!ephyrHostXVAdaptorHasPutStill (cur_host_adaptor, &has_it)) {
+ EPHYR_LOG_ERROR ("error\n") ;
+ }
+ if (has_it) {
+ a_this->adaptors[i].PutStill = ephyrPutStill;
+ }
+
+ has_it = FALSE ;
+ if (!ephyrHostXVAdaptorHasGetStill (cur_host_adaptor, &has_it)) {
+ EPHYR_LOG_ERROR ("error\n") ;
+ }
+ if (has_it) {
+ a_this->adaptors[i].GetStill = ephyrGetStill;
+ }
+ }
+ EPHYR_LOG ("leave\n") ;
+ return TRUE ;
+}
+
+static Bool
+ephyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this,
+ ScreenPtr a_screen)
+{
+ KdScreenPriv(a_screen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ Bool is_ok = FALSE ;
+ KdVideoAdaptorPtr *adaptors=NULL, *registered_adaptors=NULL ;
+ int num_registered_adaptors=0, i=0, num_adaptors=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_this && a_screen, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (!a_this->num_adaptors)
+ goto out ;
+ num_registered_adaptors =
+ KdXVListGenericAdaptors (screen, &registered_adaptors);
+
+ num_adaptors = num_registered_adaptors + a_this->num_adaptors ;
+ adaptors = calloc(num_adaptors, sizeof (KdVideoAdaptorPtr)) ;
+ if (!adaptors) {
+ EPHYR_LOG_ERROR ("failed to allocate adaptors tab\n") ;
+ goto out ;
+ }
+ memmove (adaptors, registered_adaptors, num_registered_adaptors) ;
+ for (i=0 ; i < a_this->num_adaptors; i++) {
+ *(adaptors + num_registered_adaptors + i) = &a_this->adaptors[i] ;
+ }
+ if (!KdXVScreenInit (a_screen, adaptors, num_adaptors)) {
+ EPHYR_LOG_ERROR ("failed to register adaptors\n");
+ goto out ;
+ }
+ EPHYR_LOG ("there are %d registered adaptors\n", num_adaptors) ;
+ is_ok = TRUE ;
+
+out:
+ free(registered_adaptors) ;
+ registered_adaptors = NULL ;
+ free(adaptors) ;
+ adaptors = NULL ;
+
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+static Bool
+ephyrXVPrivIsAttrValueValid (KdAttributePtr a_attrs,
+ int a_attrs_len,
+ const char *a_attr_name,
+ int a_attr_value,
+ Bool *a_is_valid)
+{
+ int i=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_attrs && a_attr_name && a_is_valid,
+ FALSE) ;
+
+ for (i=0; i < a_attrs_len; i++) {
+ if (a_attrs[i].name && strcmp (a_attrs[i].name, a_attr_name))
+ continue ;
+ if (a_attrs[i].min_value > a_attr_value ||
+ a_attrs[i].max_value < a_attr_value) {
+ *a_is_valid = FALSE ;
+ EPHYR_LOG_ERROR ("attribute was not valid\n"
+ "value:%d. min:%d. max:%d\n",
+ a_attr_value,
+ a_attrs[i].min_value,
+ a_attrs[i].max_value) ;
+ } else {
+ *a_is_valid = TRUE ;
+ }
+ return TRUE ;
+ }
+ return FALSE ;
+}
+
+static Bool
+ephyrXVPrivGetImageBufSize (int a_port_id,
+ int a_image_id,
+ unsigned short a_width,
+ unsigned short a_height,
+ int *a_size)
+{
+ Bool is_ok=FALSE ;
+ unsigned short width=a_width, height=a_height ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_size, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (!ephyrHostXVQueryImageAttributes (a_port_id, a_image_id,
+ &width, &height, a_size, NULL, NULL)) {
+ EPHYR_LOG_ERROR ("failed to get image attributes\n") ;
+ goto out ;
+ }
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+static Bool
+ephyrXVPrivSaveImageToPortPriv (EphyrPortPriv *a_port_priv,
+ const unsigned char *a_image_buf,
+ int a_image_len)
+{
+ Bool is_ok=FALSE ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (a_port_priv->image_buf_size < a_image_len) {
+ unsigned char *buf=NULL ;
+ buf = realloc (a_port_priv->image_buf, a_image_len) ;
+ if (!buf) {
+ EPHYR_LOG_ERROR ("failed to realloc image buffer\n") ;
+ goto out ;
+ }
+ a_port_priv->image_buf = buf ;
+ a_port_priv->image_buf_size = a_image_len;
+ }
+ memmove (a_port_priv->image_buf, a_image_buf, a_image_len) ;
+ is_ok = TRUE ;
+
+out:
+ return is_ok ;
+ EPHYR_LOG ("leave\n") ;
+}
+
+static void
+ephyrStopVideo (KdScreenInfo *a_info, pointer a_port_priv, Bool a_exit)
+{
+ EphyrPortPriv *port_priv = a_port_priv ;
+
+ EPHYR_RETURN_IF_FAIL (a_info && a_info->pScreen) ;
+ EPHYR_RETURN_IF_FAIL (port_priv) ;
+
+ EPHYR_LOG ("enter\n") ;
+ if (!ephyrHostXVStopVideo (a_info->pScreen->myNum,
+ port_priv->port_number)) {
+ EPHYR_LOG_ERROR ("XvStopVideo() failed\n") ;
+ }
+ EPHYR_LOG ("leave\n") ;
+}
+
+static int
+ephyrSetPortAttribute (KdScreenInfo *a_info,
+ Atom a_attr_name,
+ int a_attr_value,
+ pointer a_port_priv)
+{
+ int res=Success, host_atom=0 ;
+ EphyrPortPriv *port_priv = a_port_priv ;
+ Bool is_attr_valid=FALSE ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (port_priv, BadMatch) ;
+ EPHYR_RETURN_VAL_IF_FAIL (port_priv->current_adaptor, BadMatch) ;
+ EPHYR_RETURN_VAL_IF_FAIL (port_priv->current_adaptor->pAttributes,
+ BadMatch) ;
+ EPHYR_RETURN_VAL_IF_FAIL (port_priv->current_adaptor->nAttributes,
+ BadMatch) ;
+ EPHYR_RETURN_VAL_IF_FAIL (ValidAtom (a_attr_name), BadMatch) ;
+
+ EPHYR_LOG ("enter, portnum:%d, atomid:%d, attr_name:%s, attr_val:%d\n",
+ port_priv->port_number,
+ (int)a_attr_name,
+ NameForAtom (a_attr_name),
+ a_attr_value) ;
+
+ if (!ephyrLocalAtomToHost (a_attr_name, &host_atom)) {
+ EPHYR_LOG_ERROR ("failed to convert local atom to host atom\n") ;
+ res = BadMatch ;
+ goto out ;
+ }
+
+ if (!ephyrXVPrivIsAttrValueValid (port_priv->current_adaptor->pAttributes,
+ port_priv->current_adaptor->nAttributes,
+ NameForAtom (a_attr_name),
+ a_attr_value,
+ &is_attr_valid)) {
+ EPHYR_LOG_ERROR ("failed to validate attribute %s\n",
+ NameForAtom (a_attr_name)) ;
+ /*
+ res = BadMatch ;
+ goto out ;
+ */
+ }
+ if (!is_attr_valid) {
+ EPHYR_LOG_ERROR ("attribute %s is not valid\n",
+ NameForAtom (a_attr_name)) ;
+ /*
+ res = BadMatch ;
+ goto out ;
+ */
+ }
+
+ if (!ephyrHostXVSetPortAttribute (port_priv->port_number,
+ host_atom,
+ a_attr_value)) {
+ EPHYR_LOG_ERROR ("failed to set port attribute\n") ;
+ res = BadMatch ;
+ goto out ;
+ }
+
+ res = Success ;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return res ;
+}
+
+static int
+ephyrGetPortAttribute (KdScreenInfo *a_screen_info,
+ Atom a_attr_name,
+ int *a_attr_value,
+ pointer a_port_priv)
+{
+ int res=Success, host_atom=0 ;
+ EphyrPortPriv *port_priv = a_port_priv ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (port_priv, BadMatch) ;
+ EPHYR_RETURN_VAL_IF_FAIL (ValidAtom (a_attr_name), BadMatch) ;
+
+ EPHYR_LOG ("enter, portnum:%d, atomid:%d, attr_name:%s\n",
+ port_priv->port_number,
+ (int)a_attr_name,
+ NameForAtom (a_attr_name)) ;
+
+ if (!ephyrLocalAtomToHost (a_attr_name, &host_atom)) {
+ EPHYR_LOG_ERROR ("failed to convert local atom to host atom\n") ;
+ res = BadMatch ;
+ goto out ;
+ }
+
+ if (!ephyrHostXVGetPortAttribute (port_priv->port_number,
+ host_atom,
+ a_attr_value)) {
+ EPHYR_LOG_ERROR ("failed to get port attribute\n") ;
+ res = BadMatch ;
+ goto out ;
+ }
+
+ res = Success ;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return res ;
+}
+
+static void
+ephyrQueryBestSize (KdScreenInfo *a_info,
+ Bool a_motion,
+ short a_src_w,
+ short a_src_h,
+ short a_drw_w,
+ short a_drw_h,
+ unsigned int *a_prefered_w,
+ unsigned int *a_prefered_h,
+ pointer a_port_priv)
+{
+ int res=0 ;
+ EphyrPortPriv *port_priv = a_port_priv ;
+
+ EPHYR_RETURN_IF_FAIL (port_priv) ;
+
+ EPHYR_LOG ("enter\n") ;
+ res = ephyrHostXVQueryBestSize (port_priv->port_number,
+ a_motion,
+ a_src_w, a_src_h,
+ a_drw_w, a_drw_h,
+ a_prefered_w, a_prefered_h) ;
+ if (!res) {
+ EPHYR_LOG_ERROR ("Failed to query best size\n") ;
+ }
+ EPHYR_LOG ("leave\n") ;
+}
+
+static int
+ephyrPutImage (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_src_x,
+ short a_src_y,
+ short a_drw_x,
+ short a_drw_y,
+ short a_src_w,
+ short a_src_h,
+ short a_drw_w,
+ short a_drw_h,
+ int a_id,
+ unsigned char *a_buf,
+ short a_width,
+ short a_height,
+ Bool a_sync,
+ RegionPtr a_clipping_region,
+ pointer a_port_priv)
+{
+ EphyrPortPriv *port_priv = a_port_priv ;
+ Bool is_ok=FALSE ;
+ int result=BadImplementation, image_size=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_drawable, BadValue) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (!ephyrHostXVPutImage (a_info->pScreen->myNum,
+ port_priv->port_number,
+ a_id,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h,
+ a_src_x, a_src_y, a_src_w, a_src_h,
+ a_width, a_height, a_buf,
+ (EphyrHostBox*)REGION_RECTS (a_clipping_region),
+ REGION_NUM_RECTS (a_clipping_region))) {
+ EPHYR_LOG_ERROR ("EphyrHostXVPutImage() failed\n") ;
+ goto out ;
+ }
+
+ /*
+ * Now save the image so that we can resend it to host it
+ * later, in ReputImage.
+ */
+ if (!ephyrXVPrivGetImageBufSize (port_priv->port_number,
+ a_id, a_width, a_height, &image_size)) {
+ EPHYR_LOG_ERROR ("failed to get image size\n") ;
+ /*this is a minor error so we won't get bail out abruptly*/
+ is_ok = FALSE ;
+ } else {
+ is_ok = TRUE ;
+ }
+ if (is_ok) {
+ if (!ephyrXVPrivSaveImageToPortPriv (port_priv, a_buf, image_size)) {
+ is_ok=FALSE ;
+ } else {
+ port_priv->image_id = a_id;
+ port_priv->drw_x = a_drw_x;
+ port_priv->drw_y = a_drw_y;
+ port_priv->drw_w = a_drw_w ;
+ port_priv->drw_h = a_drw_h ;
+ port_priv->src_x = a_src_x;
+ port_priv->src_y = a_src_y ;
+ port_priv->src_w = a_src_w ;
+ port_priv->src_h = a_src_h ;
+ port_priv->image_width = a_width ;
+ port_priv->image_height = a_height ;
+ }
+ }
+ if (!is_ok) {
+ if (port_priv->image_buf) {
+ free (port_priv->image_buf) ;
+ port_priv->image_buf = NULL ;
+ port_priv->image_buf_size = 0 ;
+ }
+ }
+
+ result = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return result ;
+}
+
+static int
+ephyrReputImage (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_drw_x,
+ short a_drw_y,
+ RegionPtr a_clipping_region,
+ pointer a_port_priv)
+{
+ EphyrPortPriv *port_priv = a_port_priv ;
+ int result=BadImplementation ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_info->pScreen, FALSE) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (!port_priv->image_buf_size || !port_priv->image_buf) {
+ EPHYR_LOG_ERROR ("has null image buf in cache\n") ;
+ goto out ;
+ }
+ if (!ephyrHostXVPutImage (a_info->pScreen->myNum,
+ port_priv->port_number,
+ port_priv->image_id,
+ a_drw_x, a_drw_y,
+ port_priv->drw_w, port_priv->drw_h,
+ port_priv->src_x, port_priv->src_y,
+ port_priv->src_w, port_priv->src_h,
+ port_priv->image_width, port_priv->image_height,
+ port_priv->image_buf,
+ (EphyrHostBox*)REGION_RECTS (a_clipping_region),
+ REGION_NUM_RECTS (a_clipping_region))) {
+ EPHYR_LOG_ERROR ("ephyrHostXVPutImage() failed\n") ;
+ goto out ;
+ }
+
+ result = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return result ;
+}
+
+static int
+ephyrPutVideo (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_vid_x, short a_vid_y,
+ short a_drw_x, short a_drw_y,
+ short a_vid_w, short a_vid_h,
+ short a_drw_w, short a_drw_h,
+ RegionPtr a_clipping_region,
+ pointer a_port_priv)
+{
+ EphyrPortPriv *port_priv = a_port_priv ;
+ BoxRec clipped_area, dst_box ;
+ int result=BadImplementation ;
+ int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_info->pScreen, BadValue) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ dst_box.x1 = a_drw_x ;
+ dst_box.x2 = a_drw_x + a_drw_w;
+ dst_box.y1 = a_drw_y ;
+ dst_box.y2 = a_drw_y + a_drw_h;
+
+ if (!DoSimpleClip (&dst_box,
+ REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
+ &clipped_area)) {
+ EPHYR_LOG_ERROR ("failed to simple clip\n") ;
+ goto out ;
+ }
+
+ drw_x = clipped_area.x1 ;
+ drw_y = clipped_area.y1 ;
+ drw_w = clipped_area.x2 - clipped_area.x1 ;
+ drw_h = clipped_area.y2 - clipped_area.y1 ;
+
+ if (!ephyrHostXVPutVideo (a_info->pScreen->myNum,
+ port_priv->port_number,
+ a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
+ EPHYR_LOG_ERROR ("ephyrHostXVPutVideo() failed\n") ;
+ goto out ;
+ }
+ result = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return result ;
+}
+
+static int
+ephyrGetVideo (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_vid_x, short a_vid_y,
+ short a_drw_x, short a_drw_y,
+ short a_vid_w, short a_vid_h,
+ short a_drw_w, short a_drw_h,
+ RegionPtr a_clipping_region,
+ pointer a_port_priv)
+{
+ EphyrPortPriv *port_priv = a_port_priv ;
+ BoxRec clipped_area, dst_box ;
+ int result=BadImplementation ;
+ int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ dst_box.x1 = a_drw_x ;
+ dst_box.x2 = a_drw_x + a_drw_w;
+ dst_box.y1 = a_drw_y ;
+ dst_box.y2 = a_drw_y + a_drw_h;
+
+ if (!DoSimpleClip (&dst_box,
+ REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
+ &clipped_area)) {
+ EPHYR_LOG_ERROR ("failed to simple clip\n") ;
+ goto out ;
+ }
+
+ drw_x = clipped_area.x1 ;
+ drw_y = clipped_area.y1 ;
+ drw_w = clipped_area.x2 - clipped_area.x1 ;
+ drw_h = clipped_area.y2 - clipped_area.y1 ;
+
+ if (!ephyrHostXVGetVideo (a_info->pScreen->myNum,
+ port_priv->port_number,
+ a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
+ EPHYR_LOG_ERROR ("ephyrHostXVGetVideo() failed\n") ;
+ goto out ;
+ }
+ result = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return result ;
+}
+
+static int
+ephyrPutStill (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_vid_x, short a_vid_y,
+ short a_drw_x, short a_drw_y,
+ short a_vid_w, short a_vid_h,
+ short a_drw_w, short a_drw_h,
+ RegionPtr a_clipping_region,
+ pointer a_port_priv)
+{
+ EphyrPortPriv *port_priv = a_port_priv ;
+ BoxRec clipped_area, dst_box ;
+ int result=BadImplementation ;
+ int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ dst_box.x1 = a_drw_x ;
+ dst_box.x2 = a_drw_x + a_drw_w;
+ dst_box.y1 = a_drw_y ;
+ dst_box.y2 = a_drw_y + a_drw_h;
+
+ if (!DoSimpleClip (&dst_box,
+ REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
+ &clipped_area)) {
+ EPHYR_LOG_ERROR ("failed to simple clip\n") ;
+ goto out ;
+ }
+
+ drw_x = clipped_area.x1 ;
+ drw_y = clipped_area.y1 ;
+ drw_w = clipped_area.x2 - clipped_area.x1 ;
+ drw_h = clipped_area.y2 - clipped_area.y1 ;
+
+ if (!ephyrHostXVPutStill (a_info->pScreen->myNum,
+ port_priv->port_number,
+ a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
+ EPHYR_LOG_ERROR ("ephyrHostXVPutStill() failed\n") ;
+ goto out ;
+ }
+ result = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return result ;
+}
+
+static int
+ephyrGetStill (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_vid_x, short a_vid_y,
+ short a_drw_x, short a_drw_y,
+ short a_vid_w, short a_vid_h,
+ short a_drw_w, short a_drw_h,
+ RegionPtr a_clipping_region,
+ pointer a_port_priv)
+{
+ EphyrPortPriv *port_priv = a_port_priv ;
+ BoxRec clipped_area, dst_box ;
+ int result=BadImplementation ;
+ int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ dst_box.x1 = a_drw_x ;
+ dst_box.x2 = a_drw_x + a_drw_w;
+ dst_box.y1 = a_drw_y ;
+ dst_box.y2 = a_drw_y + a_drw_h;
+
+ if (!DoSimpleClip (&dst_box,
+ REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
+ &clipped_area)) {
+ EPHYR_LOG_ERROR ("failed to simple clip\n") ;
+ goto out ;
+ }
+
+ drw_x = clipped_area.x1 ;
+ drw_y = clipped_area.y1 ;
+ drw_w = clipped_area.x2 - clipped_area.x1 ;
+ drw_h = clipped_area.y2 - clipped_area.y1 ;
+
+ if (!ephyrHostXVGetStill (a_info->pScreen->myNum,
+ port_priv->port_number,
+ a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
+ EPHYR_LOG_ERROR ("ephyrHostXVGetStill() failed\n") ;
+ goto out ;
+ }
+ result = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return result ;
+}
+
+static int
+ephyrQueryImageAttributes (KdScreenInfo *a_info,
+ int a_id,
+ unsigned short *a_w,
+ unsigned short *a_h,
+ int *a_pitches,
+ int *a_offsets)
+{
+ int image_size=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_w && a_h, FALSE) ;
+
+ EPHYR_LOG ("enter: dim (%dx%d), pitches: %p, offsets: %p\n",
+ *a_w, *a_h, a_pitches, a_offsets) ;
+
+ if (!ephyrHostXVQueryImageAttributes (s_base_port_id,
+ a_id,
+ a_w, a_h,
+ &image_size,
+ a_pitches, a_offsets)) {
+ EPHYR_LOG_ERROR ("EphyrHostXVQueryImageAttributes() failed\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("image size: %d, dim (%dx%d)\n", image_size, *a_w, *a_h) ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return image_size ;
+}
diff --git a/xorg-server/hw/kdrive/fake/fake.c b/xorg-server/hw/kdrive/fake/fake.c
index 809e309a6..9f2327d94 100644
--- a/xorg-server/hw/kdrive/fake/fake.c
+++ b/xorg-server/hw/kdrive/fake/fake.c
@@ -1,476 +1,476 @@
-/*
- * Copyright © 2004 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <kdrive-config.h>
-#endif
-#include "fake.h"
-
-extern int KdTsPhyScreen;
-
-Bool
-fakeInitialize (KdCardInfo *card, FakePriv *priv)
-{
- priv->base = 0;
- priv->bytes_per_line = 0;
- return TRUE;
-}
-
-Bool
-fakeCardInit (KdCardInfo *card)
-{
- FakePriv *priv;
-
- priv = (FakePriv *) xalloc (sizeof (FakePriv));
- if (!priv)
- return FALSE;
-
- if (!fakeInitialize (card, priv))
- {
- xfree (priv);
- return FALSE;
- }
- card->driver = priv;
-
- return TRUE;
-}
-
-Bool
-fakeScreenInitialize (KdScreenInfo *screen, FakeScrPriv *scrpriv)
-{
- if (!screen->width || !screen->height)
- {
- screen->width = 1024;
- screen->height = 768;
- screen->rate = 72;
- }
-
- if (screen->width <= 0)
- screen->width = 1;
- if (screen->height <= 0)
- screen->height = 1;
-
- if (!screen->fb.depth)
- screen->fb.depth = 16;
-
- if (screen->fb.depth <= 8)
- {
- screen->fb.visuals = ((1 << StaticGray) |
- (1 << GrayScale) |
- (1 << StaticColor) |
- (1 << PseudoColor) |
- (1 << TrueColor) |
- (1 << DirectColor));
- }
- else
- {
- screen->fb.visuals = (1 << TrueColor);
-#define Mask(o,l) (((1 << l) - 1) << o)
- if (screen->fb.depth <= 15)
- {
- screen->fb.depth = 15;
- screen->fb.bitsPerPixel = 16;
- screen->fb.redMask = Mask (10, 5);
- screen->fb.greenMask = Mask (5, 5);
- screen->fb.blueMask = Mask (0, 5);
- }
- else if (screen->fb.depth <= 16)
- {
- screen->fb.depth = 16;
- screen->fb.bitsPerPixel = 16;
- screen->fb.redMask = Mask (11, 5);
- screen->fb.greenMask = Mask (5, 6);
- screen->fb.blueMask = Mask (0, 5);
- }
- else
- {
- screen->fb.depth = 24;
- screen->fb.bitsPerPixel = 32;
- screen->fb.redMask = Mask (16, 8);
- screen->fb.greenMask = Mask (8, 8);
- screen->fb.blueMask = Mask (0, 8);
- }
- }
-
- scrpriv->randr = screen->randr;
-
- return fakeMapFramebuffer (screen);
-}
-
-Bool
-fakeScreenInit (KdScreenInfo *screen)
-{
- FakeScrPriv *scrpriv;
-
- scrpriv = xcalloc (1, sizeof (FakeScrPriv));
- if (!scrpriv)
- return FALSE;
- screen->driver = scrpriv;
- if (!fakeScreenInitialize (screen, scrpriv))
- {
- screen->driver = 0;
- xfree (scrpriv);
- return FALSE;
- }
- return TRUE;
-}
-
-void *
-fakeWindowLinear (ScreenPtr pScreen,
- CARD32 row,
- CARD32 offset,
- int mode,
- CARD32 *size,
- void *closure)
-{
- KdScreenPriv(pScreen);
- FakePriv *priv = pScreenPriv->card->driver;
-
- if (!pScreenPriv->enabled)
- return 0;
- *size = priv->bytes_per_line;
- return priv->base + row * priv->bytes_per_line;
-}
-
-Bool
-fakeMapFramebuffer (KdScreenInfo *screen)
-{
- FakeScrPriv *scrpriv = screen->driver;
- KdPointerMatrix m;
- FakePriv *priv = screen->card->driver;
-
- if (scrpriv->randr != RR_Rotate_0)
- scrpriv->shadow = TRUE;
- else
- scrpriv->shadow = FALSE;
-
- KdComputePointerMatrix (&m, scrpriv->randr, screen->width, screen->height);
-
- KdSetPointerMatrix (&m);
-
- priv->bytes_per_line = ((screen->width * screen->fb.bitsPerPixel + 31) >> 5) << 2;
- if (priv->base)
- free (priv->base);
- priv->base = malloc (priv->bytes_per_line * screen->height);
-
- if (scrpriv->shadow)
- {
- if (!KdShadowFbAlloc (screen, scrpriv->randr & (RR_Rotate_90|RR_Rotate_270)))
- return FALSE;
- }
- else
- {
- screen->fb.byteStride = priv->bytes_per_line;
- screen->fb.pixelStride = (priv->bytes_per_line * 8/
- screen->fb.bitsPerPixel);
- screen->fb.frameBuffer = (CARD8 *) (priv->base);
- }
-
- return TRUE;
-}
-
-void
-fakeSetScreenSizes (ScreenPtr pScreen)
-{
- KdScreenPriv(pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- FakeScrPriv *scrpriv = screen->driver;
-
- if (scrpriv->randr & (RR_Rotate_0|RR_Rotate_180))
- {
- pScreen->width = screen->width;
- pScreen->height = screen->height;
- pScreen->mmWidth = screen->width_mm;
- pScreen->mmHeight = screen->height_mm;
- }
- else
- {
- pScreen->width = screen->width;
- pScreen->height = screen->height;
- pScreen->mmWidth = screen->height_mm;
- pScreen->mmHeight = screen->width_mm;
- }
-}
-
-Bool
-fakeUnmapFramebuffer (KdScreenInfo *screen)
-{
- FakePriv *priv = screen->card->driver;
- KdShadowFbFree (screen);
- if (priv->base)
- {
- free (priv->base);
- priv->base = 0;
- }
- return TRUE;
-}
-
-Bool
-fakeSetShadow (ScreenPtr pScreen)
-{
- KdScreenPriv(pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- FakeScrPriv *scrpriv = screen->driver;
- ShadowUpdateProc update;
- ShadowWindowProc window;
-
- window = fakeWindowLinear;
- update = 0;
- if (scrpriv->randr)
- update = shadowUpdateRotatePacked;
- else
- update = shadowUpdatePacked;
- return KdShadowSet (pScreen, scrpriv->randr, update, window);
-}
-
-
-#ifdef RANDR
-Bool
-fakeRandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
-{
- KdScreenPriv(pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- FakeScrPriv *scrpriv = screen->driver;
- RRScreenSizePtr pSize;
- Rotation randr;
- int n;
-
- *rotations = RR_Rotate_All|RR_Reflect_All;
-
- for (n = 0; n < pScreen->numDepths; n++)
- if (pScreen->allowedDepths[n].numVids)
- break;
- if (n == pScreen->numDepths)
- return FALSE;
-
- pSize = RRRegisterSize (pScreen,
- screen->width,
- screen->height,
- screen->width_mm,
- screen->height_mm);
-
- randr = KdSubRotation (scrpriv->randr, screen->randr);
-
- RRSetCurrentConfig (pScreen, randr, 0, pSize);
-
- return TRUE;
-}
-
-Bool
-fakeRandRSetConfig (ScreenPtr pScreen,
- Rotation randr,
- int rate,
- RRScreenSizePtr pSize)
-{
- KdScreenPriv(pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- FakeScrPriv *scrpriv = screen->driver;
- Bool wasEnabled = pScreenPriv->enabled;
- FakeScrPriv oldscr;
- int oldwidth;
- int oldheight;
- int oldmmwidth;
- int oldmmheight;
- int newwidth, newheight;
-
- if (screen->randr & (RR_Rotate_0|RR_Rotate_180))
- {
- newwidth = pSize->width;
- newheight = pSize->height;
- }
- else
- {
- newwidth = pSize->height;
- newheight = pSize->width;
- }
-
- if (wasEnabled)
- KdDisableScreen (pScreen);
-
- oldscr = *scrpriv;
-
- oldwidth = screen->width;
- oldheight = screen->height;
- oldmmwidth = pScreen->mmWidth;
- oldmmheight = pScreen->mmHeight;
-
- /*
- * Set new configuration
- */
-
- scrpriv->randr = KdAddRotation (screen->randr, randr);
-
- fakeUnmapFramebuffer (screen);
-
- if (!fakeMapFramebuffer (screen))
- goto bail4;
-
- KdShadowUnset (screen->pScreen);
-
- if (!fakeSetShadow (screen->pScreen))
- goto bail4;
-
- fakeSetScreenSizes (screen->pScreen);
-
- /*
- * Set frame buffer mapping
- */
- (*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen),
- pScreen->width,
- pScreen->height,
- screen->fb.depth,
- screen->fb.bitsPerPixel,
- screen->fb.byteStride,
- screen->fb.frameBuffer);
-
- /* set the subpixel order */
-
- KdSetSubpixelOrder (pScreen, scrpriv->randr);
- if (wasEnabled)
- KdEnableScreen (pScreen);
-
- return TRUE;
-
-bail4:
- fakeUnmapFramebuffer (screen);
- *scrpriv = oldscr;
- (void) fakeMapFramebuffer (screen);
- pScreen->width = oldwidth;
- pScreen->height = oldheight;
- pScreen->mmWidth = oldmmwidth;
- pScreen->mmHeight = oldmmheight;
-
- if (wasEnabled)
- KdEnableScreen (pScreen);
- return FALSE;
-}
-
-Bool
-fakeRandRInit (ScreenPtr pScreen)
-{
- rrScrPrivPtr pScrPriv;
-
- if (!RRScreenInit (pScreen))
- return FALSE;
-
- pScrPriv = rrGetScrPriv(pScreen);
- pScrPriv->rrGetInfo = fakeRandRGetInfo;
- pScrPriv->rrSetConfig = fakeRandRSetConfig;
- return TRUE;
-}
-#endif
-
-Bool
-fakeCreateColormap (ColormapPtr pmap)
-{
- return fbInitializeColormap (pmap);
-}
-
-Bool
-fakeInitScreen (ScreenPtr pScreen)
-{
-#ifdef TOUCHSCREEN
- KdTsPhyScreen = pScreen->myNum;
-#endif
-
- pScreen->CreateColormap = fakeCreateColormap;
- return TRUE;
-}
-
-Bool
-fakeFinishInitScreen (ScreenPtr pScreen)
-{
- if (!shadowSetup (pScreen))
- return FALSE;
-
-#ifdef RANDR
- if (!fakeRandRInit (pScreen))
- return FALSE;
-#endif
-
- return TRUE;
-}
-
-
-Bool
-fakeCreateResources (ScreenPtr pScreen)
-{
- return fakeSetShadow (pScreen);
-}
-
-void
-fakePreserve (KdCardInfo *card)
-{
-}
-
-Bool
-fakeEnable (ScreenPtr pScreen)
-{
- return TRUE;
-}
-
-Bool
-fakeDPMS (ScreenPtr pScreen, int mode)
-{
- return TRUE;
-}
-
-void
-fakeDisable (ScreenPtr pScreen)
-{
-}
-
-void
-fakeRestore (KdCardInfo *card)
-{
-}
-
-void
-fakeScreenFini (KdScreenInfo *screen)
-{
-}
-
-void
-fakeCardFini (KdCardInfo *card)
-{
- FakePriv *priv = card->driver;
-
- free (priv->base);
- xfree (priv);
-}
-
-void
-fakeGetColors (ScreenPtr pScreen, int n, xColorItem *pdefs)
-{
- while (n--)
- {
- pdefs->red = 0;
- pdefs->green = 0;
- pdefs->blue = 0;
- pdefs++;
- }
-}
-
-void
-fakePutColors (ScreenPtr pScreen, int n, xColorItem *pdefs)
-{
-}
+/*
+ * Copyright © 2004 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+#include "fake.h"
+
+extern int KdTsPhyScreen;
+
+Bool
+fakeInitialize (KdCardInfo *card, FakePriv *priv)
+{
+ priv->base = 0;
+ priv->bytes_per_line = 0;
+ return TRUE;
+}
+
+Bool
+fakeCardInit (KdCardInfo *card)
+{
+ FakePriv *priv;
+
+ priv = (FakePriv *) malloc(sizeof (FakePriv));
+ if (!priv)
+ return FALSE;
+
+ if (!fakeInitialize (card, priv))
+ {
+ free(priv);
+ return FALSE;
+ }
+ card->driver = priv;
+
+ return TRUE;
+}
+
+Bool
+fakeScreenInitialize (KdScreenInfo *screen, FakeScrPriv *scrpriv)
+{
+ if (!screen->width || !screen->height)
+ {
+ screen->width = 1024;
+ screen->height = 768;
+ screen->rate = 72;
+ }
+
+ if (screen->width <= 0)
+ screen->width = 1;
+ if (screen->height <= 0)
+ screen->height = 1;
+
+ if (!screen->fb.depth)
+ screen->fb.depth = 16;
+
+ if (screen->fb.depth <= 8)
+ {
+ screen->fb.visuals = ((1 << StaticGray) |
+ (1 << GrayScale) |
+ (1 << StaticColor) |
+ (1 << PseudoColor) |
+ (1 << TrueColor) |
+ (1 << DirectColor));
+ }
+ else
+ {
+ screen->fb.visuals = (1 << TrueColor);
+#define Mask(o,l) (((1 << l) - 1) << o)
+ if (screen->fb.depth <= 15)
+ {
+ screen->fb.depth = 15;
+ screen->fb.bitsPerPixel = 16;
+ screen->fb.redMask = Mask (10, 5);
+ screen->fb.greenMask = Mask (5, 5);
+ screen->fb.blueMask = Mask (0, 5);
+ }
+ else if (screen->fb.depth <= 16)
+ {
+ screen->fb.depth = 16;
+ screen->fb.bitsPerPixel = 16;
+ screen->fb.redMask = Mask (11, 5);
+ screen->fb.greenMask = Mask (5, 6);
+ screen->fb.blueMask = Mask (0, 5);
+ }
+ else
+ {
+ screen->fb.depth = 24;
+ screen->fb.bitsPerPixel = 32;
+ screen->fb.redMask = Mask (16, 8);
+ screen->fb.greenMask = Mask (8, 8);
+ screen->fb.blueMask = Mask (0, 8);
+ }
+ }
+
+ scrpriv->randr = screen->randr;
+
+ return fakeMapFramebuffer (screen);
+}
+
+Bool
+fakeScreenInit (KdScreenInfo *screen)
+{
+ FakeScrPriv *scrpriv;
+
+ scrpriv = calloc(1, sizeof (FakeScrPriv));
+ if (!scrpriv)
+ return FALSE;
+ screen->driver = scrpriv;
+ if (!fakeScreenInitialize (screen, scrpriv))
+ {
+ screen->driver = 0;
+ free(scrpriv);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void *
+fakeWindowLinear (ScreenPtr pScreen,
+ CARD32 row,
+ CARD32 offset,
+ int mode,
+ CARD32 *size,
+ void *closure)
+{
+ KdScreenPriv(pScreen);
+ FakePriv *priv = pScreenPriv->card->driver;
+
+ if (!pScreenPriv->enabled)
+ return 0;
+ *size = priv->bytes_per_line;
+ return priv->base + row * priv->bytes_per_line;
+}
+
+Bool
+fakeMapFramebuffer (KdScreenInfo *screen)
+{
+ FakeScrPriv *scrpriv = screen->driver;
+ KdPointerMatrix m;
+ FakePriv *priv = screen->card->driver;
+
+ if (scrpriv->randr != RR_Rotate_0)
+ scrpriv->shadow = TRUE;
+ else
+ scrpriv->shadow = FALSE;
+
+ KdComputePointerMatrix (&m, scrpriv->randr, screen->width, screen->height);
+
+ KdSetPointerMatrix (&m);
+
+ priv->bytes_per_line = ((screen->width * screen->fb.bitsPerPixel + 31) >> 5) << 2;
+ if (priv->base)
+ free (priv->base);
+ priv->base = malloc (priv->bytes_per_line * screen->height);
+
+ if (scrpriv->shadow)
+ {
+ if (!KdShadowFbAlloc (screen, scrpriv->randr & (RR_Rotate_90|RR_Rotate_270)))
+ return FALSE;
+ }
+ else
+ {
+ screen->fb.byteStride = priv->bytes_per_line;
+ screen->fb.pixelStride = (priv->bytes_per_line * 8/
+ screen->fb.bitsPerPixel);
+ screen->fb.frameBuffer = (CARD8 *) (priv->base);
+ }
+
+ return TRUE;
+}
+
+void
+fakeSetScreenSizes (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ FakeScrPriv *scrpriv = screen->driver;
+
+ if (scrpriv->randr & (RR_Rotate_0|RR_Rotate_180))
+ {
+ pScreen->width = screen->width;
+ pScreen->height = screen->height;
+ pScreen->mmWidth = screen->width_mm;
+ pScreen->mmHeight = screen->height_mm;
+ }
+ else
+ {
+ pScreen->width = screen->width;
+ pScreen->height = screen->height;
+ pScreen->mmWidth = screen->height_mm;
+ pScreen->mmHeight = screen->width_mm;
+ }
+}
+
+Bool
+fakeUnmapFramebuffer (KdScreenInfo *screen)
+{
+ FakePriv *priv = screen->card->driver;
+ KdShadowFbFree (screen);
+ if (priv->base)
+ {
+ free (priv->base);
+ priv->base = 0;
+ }
+ return TRUE;
+}
+
+Bool
+fakeSetShadow (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ FakeScrPriv *scrpriv = screen->driver;
+ ShadowUpdateProc update;
+ ShadowWindowProc window;
+
+ window = fakeWindowLinear;
+ update = 0;
+ if (scrpriv->randr)
+ update = shadowUpdateRotatePacked;
+ else
+ update = shadowUpdatePacked;
+ return KdShadowSet (pScreen, scrpriv->randr, update, window);
+}
+
+
+#ifdef RANDR
+Bool
+fakeRandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ FakeScrPriv *scrpriv = screen->driver;
+ RRScreenSizePtr pSize;
+ Rotation randr;
+ int n;
+
+ *rotations = RR_Rotate_All|RR_Reflect_All;
+
+ for (n = 0; n < pScreen->numDepths; n++)
+ if (pScreen->allowedDepths[n].numVids)
+ break;
+ if (n == pScreen->numDepths)
+ return FALSE;
+
+ pSize = RRRegisterSize (pScreen,
+ screen->width,
+ screen->height,
+ screen->width_mm,
+ screen->height_mm);
+
+ randr = KdSubRotation (scrpriv->randr, screen->randr);
+
+ RRSetCurrentConfig (pScreen, randr, 0, pSize);
+
+ return TRUE;
+}
+
+Bool
+fakeRandRSetConfig (ScreenPtr pScreen,
+ Rotation randr,
+ int rate,
+ RRScreenSizePtr pSize)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ FakeScrPriv *scrpriv = screen->driver;
+ Bool wasEnabled = pScreenPriv->enabled;
+ FakeScrPriv oldscr;
+ int oldwidth;
+ int oldheight;
+ int oldmmwidth;
+ int oldmmheight;
+ int newwidth, newheight;
+
+ if (screen->randr & (RR_Rotate_0|RR_Rotate_180))
+ {
+ newwidth = pSize->width;
+ newheight = pSize->height;
+ }
+ else
+ {
+ newwidth = pSize->height;
+ newheight = pSize->width;
+ }
+
+ if (wasEnabled)
+ KdDisableScreen (pScreen);
+
+ oldscr = *scrpriv;
+
+ oldwidth = screen->width;
+ oldheight = screen->height;
+ oldmmwidth = pScreen->mmWidth;
+ oldmmheight = pScreen->mmHeight;
+
+ /*
+ * Set new configuration
+ */
+
+ scrpriv->randr = KdAddRotation (screen->randr, randr);
+
+ fakeUnmapFramebuffer (screen);
+
+ if (!fakeMapFramebuffer (screen))
+ goto bail4;
+
+ KdShadowUnset (screen->pScreen);
+
+ if (!fakeSetShadow (screen->pScreen))
+ goto bail4;
+
+ fakeSetScreenSizes (screen->pScreen);
+
+ /*
+ * Set frame buffer mapping
+ */
+ (*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen),
+ pScreen->width,
+ pScreen->height,
+ screen->fb.depth,
+ screen->fb.bitsPerPixel,
+ screen->fb.byteStride,
+ screen->fb.frameBuffer);
+
+ /* set the subpixel order */
+
+ KdSetSubpixelOrder (pScreen, scrpriv->randr);
+ if (wasEnabled)
+ KdEnableScreen (pScreen);
+
+ return TRUE;
+
+bail4:
+ fakeUnmapFramebuffer (screen);
+ *scrpriv = oldscr;
+ (void) fakeMapFramebuffer (screen);
+ pScreen->width = oldwidth;
+ pScreen->height = oldheight;
+ pScreen->mmWidth = oldmmwidth;
+ pScreen->mmHeight = oldmmheight;
+
+ if (wasEnabled)
+ KdEnableScreen (pScreen);
+ return FALSE;
+}
+
+Bool
+fakeRandRInit (ScreenPtr pScreen)
+{
+ rrScrPrivPtr pScrPriv;
+
+ if (!RRScreenInit (pScreen))
+ return FALSE;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+ pScrPriv->rrGetInfo = fakeRandRGetInfo;
+ pScrPriv->rrSetConfig = fakeRandRSetConfig;
+ return TRUE;
+}
+#endif
+
+Bool
+fakeCreateColormap (ColormapPtr pmap)
+{
+ return fbInitializeColormap (pmap);
+}
+
+Bool
+fakeInitScreen (ScreenPtr pScreen)
+{
+#ifdef TOUCHSCREEN
+ KdTsPhyScreen = pScreen->myNum;
+#endif
+
+ pScreen->CreateColormap = fakeCreateColormap;
+ return TRUE;
+}
+
+Bool
+fakeFinishInitScreen (ScreenPtr pScreen)
+{
+ if (!shadowSetup (pScreen))
+ return FALSE;
+
+#ifdef RANDR
+ if (!fakeRandRInit (pScreen))
+ return FALSE;
+#endif
+
+ return TRUE;
+}
+
+
+Bool
+fakeCreateResources (ScreenPtr pScreen)
+{
+ return fakeSetShadow (pScreen);
+}
+
+void
+fakePreserve (KdCardInfo *card)
+{
+}
+
+Bool
+fakeEnable (ScreenPtr pScreen)
+{
+ return TRUE;
+}
+
+Bool
+fakeDPMS (ScreenPtr pScreen, int mode)
+{
+ return TRUE;
+}
+
+void
+fakeDisable (ScreenPtr pScreen)
+{
+}
+
+void
+fakeRestore (KdCardInfo *card)
+{
+}
+
+void
+fakeScreenFini (KdScreenInfo *screen)
+{
+}
+
+void
+fakeCardFini (KdCardInfo *card)
+{
+ FakePriv *priv = card->driver;
+
+ free (priv->base);
+ free(priv);
+}
+
+void
+fakeGetColors (ScreenPtr pScreen, int n, xColorItem *pdefs)
+{
+ while (n--)
+ {
+ pdefs->red = 0;
+ pdefs->green = 0;
+ pdefs->blue = 0;
+ pdefs++;
+ }
+}
+
+void
+fakePutColors (ScreenPtr pScreen, int n, xColorItem *pdefs)
+{
+}
diff --git a/xorg-server/hw/kdrive/fbdev/fbdev.c b/xorg-server/hw/kdrive/fbdev/fbdev.c
index d4604ad29..b127ab89b 100644
--- a/xorg-server/hw/kdrive/fbdev/fbdev.c
+++ b/xorg-server/hw/kdrive/fbdev/fbdev.c
@@ -1,826 +1,826 @@
-/*
- * Copyright © 1999 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <kdrive-config.h>
-#endif
-#include "fbdev.h"
-#include <sys/ioctl.h>
-
-#include <errno.h>
-
-extern int KdTsPhyScreen;
-
-char *fbdevDevicePath = NULL;
-
-static Bool
-fbdevInitialize (KdCardInfo *card, FbdevPriv *priv)
-{
- unsigned long off;
-
- if (fbdevDevicePath == NULL)
- fbdevDevicePath = "/dev/fb0";
-
- if ((priv->fd = open(fbdevDevicePath, O_RDWR)) < 0)
- {
- ErrorF("Error opening framebuffer %s: %s\n",
- fbdevDevicePath, strerror(errno));
- return FALSE;
- }
-
- /* quiet valgrind */
- memset (&priv->fix, '\0', sizeof (priv->fix));
- if (ioctl(priv->fd, FBIOGET_FSCREENINFO, &priv->fix) < 0) {
- perror("Error with /dev/fb ioctl FIOGET_FSCREENINFO");
- close (priv->fd);
- return FALSE;
- }
- /* quiet valgrind */
- memset (&priv->var, '\0', sizeof (priv->var));
- if (ioctl(priv->fd, FBIOGET_VSCREENINFO, &priv->var) < 0) {
- perror("Error with /dev/fb ioctl FIOGET_VSCREENINFO");
- close (priv->fd);
- return FALSE;
- }
-
- priv->fb_base = (char *) mmap ((caddr_t) NULL,
- priv->fix.smem_len,
- PROT_READ|PROT_WRITE,
- MAP_SHARED,
- priv->fd, 0);
-
- if (priv->fb_base == (char *)-1)
- {
- perror("ERROR: mmap framebuffer fails!");
- close (priv->fd);
- return FALSE;
- }
- off = (unsigned long) priv->fix.smem_start % (unsigned long) getpagesize();
- priv->fb = priv->fb_base + off;
- return TRUE;
-}
-
-Bool
-fbdevCardInit (KdCardInfo *card)
-{
- FbdevPriv *priv;
-
- priv = (FbdevPriv *) xalloc (sizeof (FbdevPriv));
- if (!priv)
- return FALSE;
-
- if (!fbdevInitialize (card, priv))
- {
- xfree (priv);
- return FALSE;
- }
- card->driver = priv;
-
- return TRUE;
-}
-
-static Pixel
-fbdevMakeContig (Pixel orig, Pixel others)
-{
- Pixel low;
-
- low = lowbit (orig) >> 1;
- while (low && (others & low) == 0)
- {
- orig |= low;
- low >>= 1;
- }
- return orig;
-}
-
-static Bool
-fbdevModeSupported (KdScreenInfo *screen,
- const KdMonitorTiming *t)
-{
- return TRUE;
-}
-
-static void
-fbdevConvertMonitorTiming (const KdMonitorTiming *t, struct fb_var_screeninfo *var)
-{
- memset (var, 0, sizeof (struct fb_var_screeninfo));
-
- var->xres = t->horizontal;
- var->yres = t->vertical;
- var->xres_virtual = t->horizontal;
- var->yres_virtual = t->vertical;
- var->xoffset = 0;
- var->yoffset = 0;
- var->pixclock = t->clock ? 1000000000 / t->clock : 0;
- var->left_margin = t->hbp;
- var->right_margin = t->hfp;
- var->upper_margin = t->vbp;
- var->lower_margin = t->vfp;
- var->hsync_len = t->hblank - t->hfp - t->hbp;
- var->vsync_len = t->vblank - t->vfp - t->vbp;
-
- var->sync = 0;
- var->vmode = 0;
-
- if (t->hpol == KdSyncPositive)
- var->sync |= FB_SYNC_HOR_HIGH_ACT;
- if (t->vpol == KdSyncPositive)
- var->sync |= FB_SYNC_VERT_HIGH_ACT;
-}
-
-static Bool
-fbdevScreenInitialize (KdScreenInfo *screen, FbdevScrPriv *scrpriv)
-{
- FbdevPriv *priv = screen->card->driver;
- Pixel allbits;
- int depth;
- Bool gray;
- struct fb_var_screeninfo var;
- const KdMonitorTiming *t;
- int k;
-
- k = ioctl (priv->fd, FBIOGET_VSCREENINFO, &var);
-
- if (!screen->width || !screen->height)
- {
- if (k >= 0)
- {
- screen->width = var.xres;
- screen->height = var.yres;
- }
- else
- {
- screen->width = 1024;
- screen->height = 768;
- }
- screen->rate = 103; /* FIXME: should get proper value from fb driver */
- }
- if (!screen->fb.depth)
- {
- if (k >= 0)
- screen->fb.depth = var.bits_per_pixel;
- else
- screen->fb.depth = 16;
- }
-
- if ((screen->width != var.xres) || (screen->height != var.yres))
- {
- t = KdFindMode (screen, fbdevModeSupported);
- screen->rate = t->rate;
- screen->width = t->horizontal;
- screen->height = t->vertical;
-
- /* Now try setting the mode */
- if (k < 0 || (t->horizontal != var.xres || t->vertical != var.yres))
- fbdevConvertMonitorTiming (t, &var);
- }
-
- var.activate = FB_ACTIVATE_NOW;
- var.bits_per_pixel = screen->fb.depth;
- var.nonstd = 0;
- var.grayscale = 0;
-
- k = ioctl (priv->fd, FBIOPUT_VSCREENINFO, &var);
-
- if (k < 0)
- {
- fprintf (stderr, "error: %s\n", strerror (errno));
- return FALSE;
- }
-
- /* Re-get the "fixed" parameters since they might have changed */
- k = ioctl (priv->fd, FBIOGET_FSCREENINFO, &priv->fix);
- if (k < 0)
- perror ("FBIOGET_FSCREENINFO");
-
- /* Now get the new screeninfo */
- ioctl (priv->fd, FBIOGET_VSCREENINFO, &priv->var);
- depth = priv->var.bits_per_pixel;
- gray = priv->var.grayscale;
-
- switch (priv->fix.visual) {
- case FB_VISUAL_PSEUDOCOLOR:
- if (gray)
- {
- screen->fb.visuals = (1 << StaticGray);
- /* could also support GrayScale, but what's the point? */
- }
- else
- {
- screen->fb.visuals = ((1 << StaticGray) |
- (1 << GrayScale) |
- (1 << StaticColor) |
- (1 << PseudoColor) |
- (1 << TrueColor) |
- (1 << DirectColor));
- }
- screen->fb.blueMask = 0x00;
- screen->fb.greenMask = 0x00;
- screen->fb.redMask = 0x00;
- break;
- case FB_VISUAL_STATIC_PSEUDOCOLOR:
- if (gray)
- {
- screen->fb.visuals = (1 << StaticGray);
- }
- else
- {
- screen->fb.visuals = (1 << StaticColor);
- }
- screen->fb.blueMask = 0x00;
- screen->fb.greenMask = 0x00;
- screen->fb.redMask = 0x00;
- break;
- case FB_VISUAL_TRUECOLOR:
- case FB_VISUAL_DIRECTCOLOR:
- screen->fb.visuals = (1 << TrueColor);
-#define Mask(o,l) (((1 << l) - 1) << o)
- screen->fb.redMask = Mask (priv->var.red.offset, priv->var.red.length);
- screen->fb.greenMask = Mask (priv->var.green.offset, priv->var.green.length);
- screen->fb.blueMask = Mask (priv->var.blue.offset, priv->var.blue.length);
-
- /*
- * This is a kludge so that Render will work -- fill in the gaps
- * in the pixel
- */
- screen->fb.redMask = fbdevMakeContig (screen->fb.redMask,
- screen->fb.greenMask|
- screen->fb.blueMask);
-
- screen->fb.greenMask = fbdevMakeContig (screen->fb.greenMask,
- screen->fb.redMask|
- screen->fb.blueMask);
-
- screen->fb.blueMask = fbdevMakeContig (screen->fb.blueMask,
- screen->fb.redMask|
- screen->fb.greenMask);
-
- allbits = screen->fb.redMask | screen->fb.greenMask | screen->fb.blueMask;
- depth = 32;
- while (depth && !(allbits & (1 << (depth - 1))))
- depth--;
- break;
- default:
- return FALSE;
- break;
- }
- screen->fb.depth = depth;
- screen->fb.bitsPerPixel = priv->var.bits_per_pixel;
-
- scrpriv->randr = screen->randr;
-
- return fbdevMapFramebuffer (screen);
-}
-
-Bool
-fbdevScreenInit (KdScreenInfo *screen)
-{
- FbdevScrPriv *scrpriv;
-
- scrpriv = xcalloc (1, sizeof (FbdevScrPriv));
- if (!scrpriv)
- return FALSE;
- screen->driver = scrpriv;
- if (!fbdevScreenInitialize (screen, scrpriv))
- {
- screen->driver = 0;
- xfree (scrpriv);
- return FALSE;
- }
- return TRUE;
-}
-
-static void *
-fbdevWindowLinear (ScreenPtr pScreen,
- CARD32 row,
- CARD32 offset,
- int mode,
- CARD32 *size,
- void *closure)
-{
- KdScreenPriv(pScreen);
- FbdevPriv *priv = pScreenPriv->card->driver;
-
- if (!pScreenPriv->enabled)
- return 0;
- *size = priv->fix.line_length;
- return (CARD8 *) priv->fb + row * priv->fix.line_length + offset;
-}
-
-Bool
-fbdevMapFramebuffer (KdScreenInfo *screen)
-{
- FbdevScrPriv *scrpriv = screen->driver;
- KdPointerMatrix m;
- FbdevPriv *priv = screen->card->driver;
-
- if (scrpriv->randr != RR_Rotate_0)
- scrpriv->shadow = TRUE;
- else
- scrpriv->shadow = FALSE;
-
- KdComputePointerMatrix (&m, scrpriv->randr, screen->width, screen->height);
-
- KdSetPointerMatrix (&m);
-
- screen->width = priv->var.xres;
- screen->height = priv->var.yres;
-
- if (scrpriv->shadow)
- {
- if (!KdShadowFbAlloc (screen,
- scrpriv->randr & (RR_Rotate_90|RR_Rotate_270)))
- return FALSE;
- }
- else
- {
- screen->fb.byteStride = priv->fix.line_length;
- screen->fb.pixelStride = (priv->fix.line_length * 8 /
- priv->var.bits_per_pixel);
- screen->fb.frameBuffer = (CARD8 *) (priv->fb);
- }
-
- return TRUE;
-}
-
-static void
-fbdevSetScreenSizes (ScreenPtr pScreen)
-{
- KdScreenPriv(pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- FbdevScrPriv *scrpriv = screen->driver;
- FbdevPriv *priv = screen->card->driver;
-
- if (scrpriv->randr & (RR_Rotate_0|RR_Rotate_180))
- {
- pScreen->width = priv->var.xres;
- pScreen->height = priv->var.yres;
- pScreen->mmWidth = screen->width_mm;
- pScreen->mmHeight = screen->height_mm;
- }
- else
- {
- pScreen->width = priv->var.yres;
- pScreen->height = priv->var.xres;
- pScreen->mmWidth = screen->height_mm;
- pScreen->mmHeight = screen->width_mm;
- }
-}
-
-static Bool
-fbdevUnmapFramebuffer (KdScreenInfo *screen)
-{
- KdShadowFbFree (screen);
- return TRUE;
-}
-
-static Bool
-fbdevSetShadow (ScreenPtr pScreen)
-{
- KdScreenPriv(pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- FbdevScrPriv *scrpriv = screen->driver;
- FbdevPriv *priv = screen->card->driver;
- ShadowUpdateProc update;
- ShadowWindowProc window;
- int useYX = 0;
-
-#ifdef __arm__
- /* Use variant copy routines that always read left to right in the
- shadow framebuffer. Reading vertical strips is exceptionally
- slow on XScale due to cache effects. */
- useYX = 1;
-#endif
-
- window = fbdevWindowLinear;
- update = 0;
- if (scrpriv->randr)
- if (priv->var.bits_per_pixel == 16) {
- switch (scrpriv->randr) {
- case RR_Rotate_90:
- if (useYX)
- update = shadowUpdateRotate16_90YX;
- else
- update = shadowUpdateRotate16_90;
- break;
- case RR_Rotate_180:
- update = shadowUpdateRotate16_180;
- break;
- case RR_Rotate_270:
- if (useYX)
- update = shadowUpdateRotate16_270YX;
- else
- update = shadowUpdateRotate16_270;
- break;
- default:
- update = shadowUpdateRotate16;
- break;
- }
- } else
- update = shadowUpdateRotatePacked;
- else
- update = shadowUpdatePacked;
- return KdShadowSet (pScreen, scrpriv->randr, update, window);
-}
-
-
-#ifdef RANDR
-static Bool
-fbdevRandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
-{
- KdScreenPriv(pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- FbdevScrPriv *scrpriv = screen->driver;
- RRScreenSizePtr pSize;
- Rotation randr;
- int n;
-
- *rotations = RR_Rotate_All|RR_Reflect_All;
-
- for (n = 0; n < pScreen->numDepths; n++)
- if (pScreen->allowedDepths[n].numVids)
- break;
- if (n == pScreen->numDepths)
- return FALSE;
-
- pSize = RRRegisterSize (pScreen,
- screen->width,
- screen->height,
- screen->width_mm,
- screen->height_mm);
-
- randr = KdSubRotation (scrpriv->randr, screen->randr);
-
- RRSetCurrentConfig (pScreen, randr, 0, pSize);
-
- return TRUE;
-}
-
-static Bool
-fbdevRandRSetConfig (ScreenPtr pScreen,
- Rotation randr,
- int rate,
- RRScreenSizePtr pSize)
-{
- KdScreenPriv(pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- FbdevScrPriv *scrpriv = screen->driver;
- Bool wasEnabled = pScreenPriv->enabled;
- FbdevScrPriv oldscr;
- int oldwidth;
- int oldheight;
- int oldmmwidth;
- int oldmmheight;
- int newwidth, newheight;
-
- if (screen->randr & (RR_Rotate_0|RR_Rotate_180))
- {
- newwidth = pSize->width;
- newheight = pSize->height;
- }
- else
- {
- newwidth = pSize->height;
- newheight = pSize->width;
- }
-
- if (wasEnabled)
- KdDisableScreen (pScreen);
-
- oldscr = *scrpriv;
-
- oldwidth = screen->width;
- oldheight = screen->height;
- oldmmwidth = pScreen->mmWidth;
- oldmmheight = pScreen->mmHeight;
-
- /*
- * Set new configuration
- */
-
- scrpriv->randr = KdAddRotation (screen->randr, randr);
-
- fbdevUnmapFramebuffer (screen);
-
- if (!fbdevMapFramebuffer (screen))
- goto bail4;
-
- KdShadowUnset (screen->pScreen);
-
- if (!fbdevSetShadow (screen->pScreen))
- goto bail4;
-
- fbdevSetScreenSizes (screen->pScreen);
-
- /*
- * Set frame buffer mapping
- */
- (*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen),
- pScreen->width,
- pScreen->height,
- screen->fb.depth,
- screen->fb.bitsPerPixel,
- screen->fb.byteStride,
- screen->fb.frameBuffer);
-
- /* set the subpixel order */
-
- KdSetSubpixelOrder (pScreen, scrpriv->randr);
- if (wasEnabled)
- KdEnableScreen (pScreen);
-
- return TRUE;
-
-bail4:
- fbdevUnmapFramebuffer (screen);
- *scrpriv = oldscr;
- (void) fbdevMapFramebuffer (screen);
- pScreen->width = oldwidth;
- pScreen->height = oldheight;
- pScreen->mmWidth = oldmmwidth;
- pScreen->mmHeight = oldmmheight;
-
- if (wasEnabled)
- KdEnableScreen (pScreen);
- return FALSE;
-}
-
-static Bool
-fbdevRandRInit (ScreenPtr pScreen)
-{
- rrScrPrivPtr pScrPriv;
-
- if (!RRScreenInit (pScreen))
- return FALSE;
-
- pScrPriv = rrGetScrPriv(pScreen);
- pScrPriv->rrGetInfo = fbdevRandRGetInfo;
- pScrPriv->rrSetConfig = fbdevRandRSetConfig;
- return TRUE;
-}
-#endif
-
-static Bool
-fbdevCreateColormap (ColormapPtr pmap)
-{
- ScreenPtr pScreen = pmap->pScreen;
- KdScreenPriv(pScreen);
- FbdevPriv *priv = pScreenPriv->card->driver;
- VisualPtr pVisual;
- int i;
- int nent;
- xColorItem *pdefs;
-
- switch (priv->fix.visual) {
- case FB_VISUAL_STATIC_PSEUDOCOLOR:
- pVisual = pmap->pVisual;
- nent = pVisual->ColormapEntries;
- pdefs = xalloc (nent * sizeof (xColorItem));
- if (!pdefs)
- return FALSE;
- for (i = 0; i < nent; i++)
- pdefs[i].pixel = i;
- fbdevGetColors (pScreen, nent, pdefs);
- for (i = 0; i < nent; i++)
- {
- pmap->red[i].co.local.red = pdefs[i].red;
- pmap->red[i].co.local.green = pdefs[i].green;
- pmap->red[i].co.local.blue = pdefs[i].blue;
- }
- xfree (pdefs);
- return TRUE;
- default:
- return fbInitializeColormap (pmap);
- }
-}
-
-Bool
-fbdevInitScreen (ScreenPtr pScreen)
-{
-#ifdef TOUCHSCREEN
- KdTsPhyScreen = pScreen->myNum;
-#endif
-
- pScreen->CreateColormap = fbdevCreateColormap;
- return TRUE;
-}
-
-Bool
-fbdevFinishInitScreen (ScreenPtr pScreen)
-{
- if (!shadowSetup (pScreen))
- return FALSE;
-
-#ifdef RANDR
- if (!fbdevRandRInit (pScreen))
- return FALSE;
-#endif
-
- return TRUE;
-}
-
-
-Bool
-fbdevCreateResources (ScreenPtr pScreen)
-{
- return fbdevSetShadow (pScreen);
-}
-
-void
-fbdevPreserve (KdCardInfo *card)
-{
-}
-
-static int
-fbdevUpdateFbColormap(FbdevPriv *priv, int minidx, int maxidx)
-{
- struct fb_cmap cmap;
-
- cmap.start = minidx;
- cmap.len = maxidx - minidx + 1;
- cmap.red = &priv->red[minidx];
- cmap.green = &priv->green[minidx];
- cmap.blue = &priv->blue[minidx];
- cmap.transp = 0;
-
- return ioctl(priv->fd, FBIOPUTCMAP, &cmap);
-}
-
-Bool
-fbdevEnable (ScreenPtr pScreen)
-{
- KdScreenPriv(pScreen);
- FbdevPriv *priv = pScreenPriv->card->driver;
- int k;
-
- priv->var.activate = FB_ACTIVATE_NOW|FB_CHANGE_CMAP_VBL;
-
- /* display it on the LCD */
- k = ioctl (priv->fd, FBIOPUT_VSCREENINFO, &priv->var);
- if (k < 0)
- {
- perror ("FBIOPUT_VSCREENINFO");
- return FALSE;
- }
-
- if (priv->fix.visual == FB_VISUAL_DIRECTCOLOR)
- {
- int i;
-
- for (i = 0;
- i < (1 << priv->var.red.length) ||
- i < (1 << priv->var.green.length) ||
- i < (1 << priv->var.blue.length); i++)
- {
- priv->red[i] = i * 65535 / ((1 << priv->var.red.length) - 1);
- priv->green[i] = i * 65535 / ((1 << priv->var.green.length) - 1);
- priv->blue[i] = i * 65535 / ((1 << priv->var.blue.length) - 1);
- }
-
- fbdevUpdateFbColormap(priv, 0, i);
- }
- return TRUE;
-}
-
-Bool
-fbdevDPMS (ScreenPtr pScreen, int mode)
-{
- KdScreenPriv(pScreen);
- FbdevPriv *priv = pScreenPriv->card->driver;
- static int oldmode = -1;
-
- if (mode == oldmode)
- return TRUE;
-#ifdef FBIOPUT_POWERMODE
- if (ioctl (priv->fd, FBIOPUT_POWERMODE, &mode) >= 0)
- {
- oldmode = mode;
- return TRUE;
- }
-#endif
-#ifdef FBIOBLANK
- if (ioctl (priv->fd, FBIOBLANK, mode ? mode + 1 : 0) >= 0)
- {
- oldmode = mode;
- return TRUE;
- }
-#endif
- return FALSE;
-}
-
-void
-fbdevDisable (ScreenPtr pScreen)
-{
-}
-
-void
-fbdevRestore (KdCardInfo *card)
-{
-}
-
-void
-fbdevScreenFini (KdScreenInfo *screen)
-{
-}
-
-void
-fbdevCardFini (KdCardInfo *card)
-{
- FbdevPriv *priv = card->driver;
-
- munmap (priv->fb_base, priv->fix.smem_len);
- close (priv->fd);
- xfree (priv);
-}
-
-/*
- * Retrieve actual colormap and return selected n entries in pdefs.
- */
-void
-fbdevGetColors (ScreenPtr pScreen, int n, xColorItem *pdefs)
-{
- KdScreenPriv(pScreen);
- FbdevPriv *priv = pScreenPriv->card->driver;
- struct fb_cmap cmap;
- int p;
- int k;
- int min, max;
-
- min = 256;
- max = 0;
- for (k = 0; k < n; k++)
- {
- if (pdefs[k].pixel < min)
- min = pdefs[k].pixel;
- if (pdefs[k].pixel > max)
- max = pdefs[k].pixel;
- }
- cmap.start = min;
- cmap.len = max - min + 1;
- cmap.red = &priv->red[min];
- cmap.green = &priv->green[min];
- cmap.blue = &priv->blue[min];
- cmap.transp = 0;
- k = ioctl (priv->fd, FBIOGETCMAP, &cmap);
- if (k < 0)
- {
- perror ("can't get colormap");
- return;
- }
- while (n--)
- {
- p = pdefs->pixel;
- pdefs->red = priv->red[p];
- pdefs->green = priv->green[p];
- pdefs->blue = priv->blue[p];
- pdefs++;
- }
-}
-
-/*
- * Change colormap by updating n entries described in pdefs.
- */
-void
-fbdevPutColors (ScreenPtr pScreen, int n, xColorItem *pdefs)
-{
- KdScreenPriv(pScreen);
- FbdevPriv *priv = pScreenPriv->card->driver;
- int p;
- int min, max;
-
- min = 256;
- max = 0;
- while (n--)
- {
- p = pdefs->pixel;
- priv->red[p] = pdefs->red;
- priv->green[p] = pdefs->green;
- priv->blue[p] = pdefs->blue;
- if (p < min)
- min = p;
- if (p > max)
- max = p;
- pdefs++;
- }
-
- fbdevUpdateFbColormap(priv, min, max);
-}
+/*
+ * Copyright © 1999 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+#include "fbdev.h"
+#include <sys/ioctl.h>
+
+#include <errno.h>
+
+extern int KdTsPhyScreen;
+
+char *fbdevDevicePath = NULL;
+
+static Bool
+fbdevInitialize (KdCardInfo *card, FbdevPriv *priv)
+{
+ unsigned long off;
+
+ if (fbdevDevicePath == NULL)
+ fbdevDevicePath = "/dev/fb0";
+
+ if ((priv->fd = open(fbdevDevicePath, O_RDWR)) < 0)
+ {
+ ErrorF("Error opening framebuffer %s: %s\n",
+ fbdevDevicePath, strerror(errno));
+ return FALSE;
+ }
+
+ /* quiet valgrind */
+ memset (&priv->fix, '\0', sizeof (priv->fix));
+ if (ioctl(priv->fd, FBIOGET_FSCREENINFO, &priv->fix) < 0) {
+ perror("Error with /dev/fb ioctl FIOGET_FSCREENINFO");
+ close (priv->fd);
+ return FALSE;
+ }
+ /* quiet valgrind */
+ memset (&priv->var, '\0', sizeof (priv->var));
+ if (ioctl(priv->fd, FBIOGET_VSCREENINFO, &priv->var) < 0) {
+ perror("Error with /dev/fb ioctl FIOGET_VSCREENINFO");
+ close (priv->fd);
+ return FALSE;
+ }
+
+ priv->fb_base = (char *) mmap ((caddr_t) NULL,
+ priv->fix.smem_len,
+ PROT_READ|PROT_WRITE,
+ MAP_SHARED,
+ priv->fd, 0);
+
+ if (priv->fb_base == (char *)-1)
+ {
+ perror("ERROR: mmap framebuffer fails!");
+ close (priv->fd);
+ return FALSE;
+ }
+ off = (unsigned long) priv->fix.smem_start % (unsigned long) getpagesize();
+ priv->fb = priv->fb_base + off;
+ return TRUE;
+}
+
+Bool
+fbdevCardInit (KdCardInfo *card)
+{
+ FbdevPriv *priv;
+
+ priv = (FbdevPriv *) malloc(sizeof (FbdevPriv));
+ if (!priv)
+ return FALSE;
+
+ if (!fbdevInitialize (card, priv))
+ {
+ free(priv);
+ return FALSE;
+ }
+ card->driver = priv;
+
+ return TRUE;
+}
+
+static Pixel
+fbdevMakeContig (Pixel orig, Pixel others)
+{
+ Pixel low;
+
+ low = lowbit (orig) >> 1;
+ while (low && (others & low) == 0)
+ {
+ orig |= low;
+ low >>= 1;
+ }
+ return orig;
+}
+
+static Bool
+fbdevModeSupported (KdScreenInfo *screen,
+ const KdMonitorTiming *t)
+{
+ return TRUE;
+}
+
+static void
+fbdevConvertMonitorTiming (const KdMonitorTiming *t, struct fb_var_screeninfo *var)
+{
+ memset (var, 0, sizeof (struct fb_var_screeninfo));
+
+ var->xres = t->horizontal;
+ var->yres = t->vertical;
+ var->xres_virtual = t->horizontal;
+ var->yres_virtual = t->vertical;
+ var->xoffset = 0;
+ var->yoffset = 0;
+ var->pixclock = t->clock ? 1000000000 / t->clock : 0;
+ var->left_margin = t->hbp;
+ var->right_margin = t->hfp;
+ var->upper_margin = t->vbp;
+ var->lower_margin = t->vfp;
+ var->hsync_len = t->hblank - t->hfp - t->hbp;
+ var->vsync_len = t->vblank - t->vfp - t->vbp;
+
+ var->sync = 0;
+ var->vmode = 0;
+
+ if (t->hpol == KdSyncPositive)
+ var->sync |= FB_SYNC_HOR_HIGH_ACT;
+ if (t->vpol == KdSyncPositive)
+ var->sync |= FB_SYNC_VERT_HIGH_ACT;
+}
+
+static Bool
+fbdevScreenInitialize (KdScreenInfo *screen, FbdevScrPriv *scrpriv)
+{
+ FbdevPriv *priv = screen->card->driver;
+ Pixel allbits;
+ int depth;
+ Bool gray;
+ struct fb_var_screeninfo var;
+ const KdMonitorTiming *t;
+ int k;
+
+ k = ioctl (priv->fd, FBIOGET_VSCREENINFO, &var);
+
+ if (!screen->width || !screen->height)
+ {
+ if (k >= 0)
+ {
+ screen->width = var.xres;
+ screen->height = var.yres;
+ }
+ else
+ {
+ screen->width = 1024;
+ screen->height = 768;
+ }
+ screen->rate = 103; /* FIXME: should get proper value from fb driver */
+ }
+ if (!screen->fb.depth)
+ {
+ if (k >= 0)
+ screen->fb.depth = var.bits_per_pixel;
+ else
+ screen->fb.depth = 16;
+ }
+
+ if ((screen->width != var.xres) || (screen->height != var.yres))
+ {
+ t = KdFindMode (screen, fbdevModeSupported);
+ screen->rate = t->rate;
+ screen->width = t->horizontal;
+ screen->height = t->vertical;
+
+ /* Now try setting the mode */
+ if (k < 0 || (t->horizontal != var.xres || t->vertical != var.yres))
+ fbdevConvertMonitorTiming (t, &var);
+ }
+
+ var.activate = FB_ACTIVATE_NOW;
+ var.bits_per_pixel = screen->fb.depth;
+ var.nonstd = 0;
+ var.grayscale = 0;
+
+ k = ioctl (priv->fd, FBIOPUT_VSCREENINFO, &var);
+
+ if (k < 0)
+ {
+ fprintf (stderr, "error: %s\n", strerror (errno));
+ return FALSE;
+ }
+
+ /* Re-get the "fixed" parameters since they might have changed */
+ k = ioctl (priv->fd, FBIOGET_FSCREENINFO, &priv->fix);
+ if (k < 0)
+ perror ("FBIOGET_FSCREENINFO");
+
+ /* Now get the new screeninfo */
+ ioctl (priv->fd, FBIOGET_VSCREENINFO, &priv->var);
+ depth = priv->var.bits_per_pixel;
+ gray = priv->var.grayscale;
+
+ switch (priv->fix.visual) {
+ case FB_VISUAL_PSEUDOCOLOR:
+ if (gray)
+ {
+ screen->fb.visuals = (1 << StaticGray);
+ /* could also support GrayScale, but what's the point? */
+ }
+ else
+ {
+ screen->fb.visuals = ((1 << StaticGray) |
+ (1 << GrayScale) |
+ (1 << StaticColor) |
+ (1 << PseudoColor) |
+ (1 << TrueColor) |
+ (1 << DirectColor));
+ }
+ screen->fb.blueMask = 0x00;
+ screen->fb.greenMask = 0x00;
+ screen->fb.redMask = 0x00;
+ break;
+ case FB_VISUAL_STATIC_PSEUDOCOLOR:
+ if (gray)
+ {
+ screen->fb.visuals = (1 << StaticGray);
+ }
+ else
+ {
+ screen->fb.visuals = (1 << StaticColor);
+ }
+ screen->fb.blueMask = 0x00;
+ screen->fb.greenMask = 0x00;
+ screen->fb.redMask = 0x00;
+ break;
+ case FB_VISUAL_TRUECOLOR:
+ case FB_VISUAL_DIRECTCOLOR:
+ screen->fb.visuals = (1 << TrueColor);
+#define Mask(o,l) (((1 << l) - 1) << o)
+ screen->fb.redMask = Mask (priv->var.red.offset, priv->var.red.length);
+ screen->fb.greenMask = Mask (priv->var.green.offset, priv->var.green.length);
+ screen->fb.blueMask = Mask (priv->var.blue.offset, priv->var.blue.length);
+
+ /*
+ * This is a kludge so that Render will work -- fill in the gaps
+ * in the pixel
+ */
+ screen->fb.redMask = fbdevMakeContig (screen->fb.redMask,
+ screen->fb.greenMask|
+ screen->fb.blueMask);
+
+ screen->fb.greenMask = fbdevMakeContig (screen->fb.greenMask,
+ screen->fb.redMask|
+ screen->fb.blueMask);
+
+ screen->fb.blueMask = fbdevMakeContig (screen->fb.blueMask,
+ screen->fb.redMask|
+ screen->fb.greenMask);
+
+ allbits = screen->fb.redMask | screen->fb.greenMask | screen->fb.blueMask;
+ depth = 32;
+ while (depth && !(allbits & (1 << (depth - 1))))
+ depth--;
+ break;
+ default:
+ return FALSE;
+ break;
+ }
+ screen->fb.depth = depth;
+ screen->fb.bitsPerPixel = priv->var.bits_per_pixel;
+
+ scrpriv->randr = screen->randr;
+
+ return fbdevMapFramebuffer (screen);
+}
+
+Bool
+fbdevScreenInit (KdScreenInfo *screen)
+{
+ FbdevScrPriv *scrpriv;
+
+ scrpriv = calloc(1, sizeof (FbdevScrPriv));
+ if (!scrpriv)
+ return FALSE;
+ screen->driver = scrpriv;
+ if (!fbdevScreenInitialize (screen, scrpriv))
+ {
+ screen->driver = 0;
+ free(scrpriv);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static void *
+fbdevWindowLinear (ScreenPtr pScreen,
+ CARD32 row,
+ CARD32 offset,
+ int mode,
+ CARD32 *size,
+ void *closure)
+{
+ KdScreenPriv(pScreen);
+ FbdevPriv *priv = pScreenPriv->card->driver;
+
+ if (!pScreenPriv->enabled)
+ return 0;
+ *size = priv->fix.line_length;
+ return (CARD8 *) priv->fb + row * priv->fix.line_length + offset;
+}
+
+Bool
+fbdevMapFramebuffer (KdScreenInfo *screen)
+{
+ FbdevScrPriv *scrpriv = screen->driver;
+ KdPointerMatrix m;
+ FbdevPriv *priv = screen->card->driver;
+
+ if (scrpriv->randr != RR_Rotate_0)
+ scrpriv->shadow = TRUE;
+ else
+ scrpriv->shadow = FALSE;
+
+ KdComputePointerMatrix (&m, scrpriv->randr, screen->width, screen->height);
+
+ KdSetPointerMatrix (&m);
+
+ screen->width = priv->var.xres;
+ screen->height = priv->var.yres;
+
+ if (scrpriv->shadow)
+ {
+ if (!KdShadowFbAlloc (screen,
+ scrpriv->randr & (RR_Rotate_90|RR_Rotate_270)))
+ return FALSE;
+ }
+ else
+ {
+ screen->fb.byteStride = priv->fix.line_length;
+ screen->fb.pixelStride = (priv->fix.line_length * 8 /
+ priv->var.bits_per_pixel);
+ screen->fb.frameBuffer = (CARD8 *) (priv->fb);
+ }
+
+ return TRUE;
+}
+
+static void
+fbdevSetScreenSizes (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ FbdevScrPriv *scrpriv = screen->driver;
+ FbdevPriv *priv = screen->card->driver;
+
+ if (scrpriv->randr & (RR_Rotate_0|RR_Rotate_180))
+ {
+ pScreen->width = priv->var.xres;
+ pScreen->height = priv->var.yres;
+ pScreen->mmWidth = screen->width_mm;
+ pScreen->mmHeight = screen->height_mm;
+ }
+ else
+ {
+ pScreen->width = priv->var.yres;
+ pScreen->height = priv->var.xres;
+ pScreen->mmWidth = screen->height_mm;
+ pScreen->mmHeight = screen->width_mm;
+ }
+}
+
+static Bool
+fbdevUnmapFramebuffer (KdScreenInfo *screen)
+{
+ KdShadowFbFree (screen);
+ return TRUE;
+}
+
+static Bool
+fbdevSetShadow (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ FbdevScrPriv *scrpriv = screen->driver;
+ FbdevPriv *priv = screen->card->driver;
+ ShadowUpdateProc update;
+ ShadowWindowProc window;
+ int useYX = 0;
+
+#ifdef __arm__
+ /* Use variant copy routines that always read left to right in the
+ shadow framebuffer. Reading vertical strips is exceptionally
+ slow on XScale due to cache effects. */
+ useYX = 1;
+#endif
+
+ window = fbdevWindowLinear;
+ update = 0;
+ if (scrpriv->randr)
+ if (priv->var.bits_per_pixel == 16) {
+ switch (scrpriv->randr) {
+ case RR_Rotate_90:
+ if (useYX)
+ update = shadowUpdateRotate16_90YX;
+ else
+ update = shadowUpdateRotate16_90;
+ break;
+ case RR_Rotate_180:
+ update = shadowUpdateRotate16_180;
+ break;
+ case RR_Rotate_270:
+ if (useYX)
+ update = shadowUpdateRotate16_270YX;
+ else
+ update = shadowUpdateRotate16_270;
+ break;
+ default:
+ update = shadowUpdateRotate16;
+ break;
+ }
+ } else
+ update = shadowUpdateRotatePacked;
+ else
+ update = shadowUpdatePacked;
+ return KdShadowSet (pScreen, scrpriv->randr, update, window);
+}
+
+
+#ifdef RANDR
+static Bool
+fbdevRandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ FbdevScrPriv *scrpriv = screen->driver;
+ RRScreenSizePtr pSize;
+ Rotation randr;
+ int n;
+
+ *rotations = RR_Rotate_All|RR_Reflect_All;
+
+ for (n = 0; n < pScreen->numDepths; n++)
+ if (pScreen->allowedDepths[n].numVids)
+ break;
+ if (n == pScreen->numDepths)
+ return FALSE;
+
+ pSize = RRRegisterSize (pScreen,
+ screen->width,
+ screen->height,
+ screen->width_mm,
+ screen->height_mm);
+
+ randr = KdSubRotation (scrpriv->randr, screen->randr);
+
+ RRSetCurrentConfig (pScreen, randr, 0, pSize);
+
+ return TRUE;
+}
+
+static Bool
+fbdevRandRSetConfig (ScreenPtr pScreen,
+ Rotation randr,
+ int rate,
+ RRScreenSizePtr pSize)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ FbdevScrPriv *scrpriv = screen->driver;
+ Bool wasEnabled = pScreenPriv->enabled;
+ FbdevScrPriv oldscr;
+ int oldwidth;
+ int oldheight;
+ int oldmmwidth;
+ int oldmmheight;
+ int newwidth, newheight;
+
+ if (screen->randr & (RR_Rotate_0|RR_Rotate_180))
+ {
+ newwidth = pSize->width;
+ newheight = pSize->height;
+ }
+ else
+ {
+ newwidth = pSize->height;
+ newheight = pSize->width;
+ }
+
+ if (wasEnabled)
+ KdDisableScreen (pScreen);
+
+ oldscr = *scrpriv;
+
+ oldwidth = screen->width;
+ oldheight = screen->height;
+ oldmmwidth = pScreen->mmWidth;
+ oldmmheight = pScreen->mmHeight;
+
+ /*
+ * Set new configuration
+ */
+
+ scrpriv->randr = KdAddRotation (screen->randr, randr);
+
+ fbdevUnmapFramebuffer (screen);
+
+ if (!fbdevMapFramebuffer (screen))
+ goto bail4;
+
+ KdShadowUnset (screen->pScreen);
+
+ if (!fbdevSetShadow (screen->pScreen))
+ goto bail4;
+
+ fbdevSetScreenSizes (screen->pScreen);
+
+ /*
+ * Set frame buffer mapping
+ */
+ (*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen),
+ pScreen->width,
+ pScreen->height,
+ screen->fb.depth,
+ screen->fb.bitsPerPixel,
+ screen->fb.byteStride,
+ screen->fb.frameBuffer);
+
+ /* set the subpixel order */
+
+ KdSetSubpixelOrder (pScreen, scrpriv->randr);
+ if (wasEnabled)
+ KdEnableScreen (pScreen);
+
+ return TRUE;
+
+bail4:
+ fbdevUnmapFramebuffer (screen);
+ *scrpriv = oldscr;
+ (void) fbdevMapFramebuffer (screen);
+ pScreen->width = oldwidth;
+ pScreen->height = oldheight;
+ pScreen->mmWidth = oldmmwidth;
+ pScreen->mmHeight = oldmmheight;
+
+ if (wasEnabled)
+ KdEnableScreen (pScreen);
+ return FALSE;
+}
+
+static Bool
+fbdevRandRInit (ScreenPtr pScreen)
+{
+ rrScrPrivPtr pScrPriv;
+
+ if (!RRScreenInit (pScreen))
+ return FALSE;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+ pScrPriv->rrGetInfo = fbdevRandRGetInfo;
+ pScrPriv->rrSetConfig = fbdevRandRSetConfig;
+ return TRUE;
+}
+#endif
+
+static Bool
+fbdevCreateColormap (ColormapPtr pmap)
+{
+ ScreenPtr pScreen = pmap->pScreen;
+ KdScreenPriv(pScreen);
+ FbdevPriv *priv = pScreenPriv->card->driver;
+ VisualPtr pVisual;
+ int i;
+ int nent;
+ xColorItem *pdefs;
+
+ switch (priv->fix.visual) {
+ case FB_VISUAL_STATIC_PSEUDOCOLOR:
+ pVisual = pmap->pVisual;
+ nent = pVisual->ColormapEntries;
+ pdefs = malloc(nent * sizeof (xColorItem));
+ if (!pdefs)
+ return FALSE;
+ for (i = 0; i < nent; i++)
+ pdefs[i].pixel = i;
+ fbdevGetColors (pScreen, nent, pdefs);
+ for (i = 0; i < nent; i++)
+ {
+ pmap->red[i].co.local.red = pdefs[i].red;
+ pmap->red[i].co.local.green = pdefs[i].green;
+ pmap->red[i].co.local.blue = pdefs[i].blue;
+ }
+ free(pdefs);
+ return TRUE;
+ default:
+ return fbInitializeColormap (pmap);
+ }
+}
+
+Bool
+fbdevInitScreen (ScreenPtr pScreen)
+{
+#ifdef TOUCHSCREEN
+ KdTsPhyScreen = pScreen->myNum;
+#endif
+
+ pScreen->CreateColormap = fbdevCreateColormap;
+ return TRUE;
+}
+
+Bool
+fbdevFinishInitScreen (ScreenPtr pScreen)
+{
+ if (!shadowSetup (pScreen))
+ return FALSE;
+
+#ifdef RANDR
+ if (!fbdevRandRInit (pScreen))
+ return FALSE;
+#endif
+
+ return TRUE;
+}
+
+
+Bool
+fbdevCreateResources (ScreenPtr pScreen)
+{
+ return fbdevSetShadow (pScreen);
+}
+
+void
+fbdevPreserve (KdCardInfo *card)
+{
+}
+
+static int
+fbdevUpdateFbColormap(FbdevPriv *priv, int minidx, int maxidx)
+{
+ struct fb_cmap cmap;
+
+ cmap.start = minidx;
+ cmap.len = maxidx - minidx + 1;
+ cmap.red = &priv->red[minidx];
+ cmap.green = &priv->green[minidx];
+ cmap.blue = &priv->blue[minidx];
+ cmap.transp = 0;
+
+ return ioctl(priv->fd, FBIOPUTCMAP, &cmap);
+}
+
+Bool
+fbdevEnable (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ FbdevPriv *priv = pScreenPriv->card->driver;
+ int k;
+
+ priv->var.activate = FB_ACTIVATE_NOW|FB_CHANGE_CMAP_VBL;
+
+ /* display it on the LCD */
+ k = ioctl (priv->fd, FBIOPUT_VSCREENINFO, &priv->var);
+ if (k < 0)
+ {
+ perror ("FBIOPUT_VSCREENINFO");
+ return FALSE;
+ }
+
+ if (priv->fix.visual == FB_VISUAL_DIRECTCOLOR)
+ {
+ int i;
+
+ for (i = 0;
+ i < (1 << priv->var.red.length) ||
+ i < (1 << priv->var.green.length) ||
+ i < (1 << priv->var.blue.length); i++)
+ {
+ priv->red[i] = i * 65535 / ((1 << priv->var.red.length) - 1);
+ priv->green[i] = i * 65535 / ((1 << priv->var.green.length) - 1);
+ priv->blue[i] = i * 65535 / ((1 << priv->var.blue.length) - 1);
+ }
+
+ fbdevUpdateFbColormap(priv, 0, i);
+ }
+ return TRUE;
+}
+
+Bool
+fbdevDPMS (ScreenPtr pScreen, int mode)
+{
+ KdScreenPriv(pScreen);
+ FbdevPriv *priv = pScreenPriv->card->driver;
+ static int oldmode = -1;
+
+ if (mode == oldmode)
+ return TRUE;
+#ifdef FBIOPUT_POWERMODE
+ if (ioctl (priv->fd, FBIOPUT_POWERMODE, &mode) >= 0)
+ {
+ oldmode = mode;
+ return TRUE;
+ }
+#endif
+#ifdef FBIOBLANK
+ if (ioctl (priv->fd, FBIOBLANK, mode ? mode + 1 : 0) >= 0)
+ {
+ oldmode = mode;
+ return TRUE;
+ }
+#endif
+ return FALSE;
+}
+
+void
+fbdevDisable (ScreenPtr pScreen)
+{
+}
+
+void
+fbdevRestore (KdCardInfo *card)
+{
+}
+
+void
+fbdevScreenFini (KdScreenInfo *screen)
+{
+}
+
+void
+fbdevCardFini (KdCardInfo *card)
+{
+ FbdevPriv *priv = card->driver;
+
+ munmap (priv->fb_base, priv->fix.smem_len);
+ close (priv->fd);
+ free(priv);
+}
+
+/*
+ * Retrieve actual colormap and return selected n entries in pdefs.
+ */
+void
+fbdevGetColors (ScreenPtr pScreen, int n, xColorItem *pdefs)
+{
+ KdScreenPriv(pScreen);
+ FbdevPriv *priv = pScreenPriv->card->driver;
+ struct fb_cmap cmap;
+ int p;
+ int k;
+ int min, max;
+
+ min = 256;
+ max = 0;
+ for (k = 0; k < n; k++)
+ {
+ if (pdefs[k].pixel < min)
+ min = pdefs[k].pixel;
+ if (pdefs[k].pixel > max)
+ max = pdefs[k].pixel;
+ }
+ cmap.start = min;
+ cmap.len = max - min + 1;
+ cmap.red = &priv->red[min];
+ cmap.green = &priv->green[min];
+ cmap.blue = &priv->blue[min];
+ cmap.transp = 0;
+ k = ioctl (priv->fd, FBIOGETCMAP, &cmap);
+ if (k < 0)
+ {
+ perror ("can't get colormap");
+ return;
+ }
+ while (n--)
+ {
+ p = pdefs->pixel;
+ pdefs->red = priv->red[p];
+ pdefs->green = priv->green[p];
+ pdefs->blue = priv->blue[p];
+ pdefs++;
+ }
+}
+
+/*
+ * Change colormap by updating n entries described in pdefs.
+ */
+void
+fbdevPutColors (ScreenPtr pScreen, int n, xColorItem *pdefs)
+{
+ KdScreenPriv(pScreen);
+ FbdevPriv *priv = pScreenPriv->card->driver;
+ int p;
+ int min, max;
+
+ min = 256;
+ max = 0;
+ while (n--)
+ {
+ p = pdefs->pixel;
+ priv->red[p] = pdefs->red;
+ priv->green[p] = pdefs->green;
+ priv->blue[p] = pdefs->blue;
+ if (p < min)
+ min = p;
+ if (p > max)
+ max = p;
+ pdefs++;
+ }
+
+ fbdevUpdateFbColormap(priv, min, max);
+}
diff --git a/xorg-server/hw/kdrive/linux/evdev.c b/xorg-server/hw/kdrive/linux/evdev.c
index 0e4c9f735..20df77b99 100644
--- a/xorg-server/hw/kdrive/linux/evdev.c
+++ b/xorg-server/hw/kdrive/linux/evdev.c
@@ -1,539 +1,539 @@
-/*
- * Copyright © 2004 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <kdrive-config.h>
-#endif
-#include <errno.h>
-#include <linux/input.h>
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include <X11/Xpoll.h>
-#include "inputstr.h"
-#include "scrnintstr.h"
-#include "kdrive.h"
-
-#define NUM_EVENTS 128
-#define ABS_UNSET -65535
-
-#define BITS_PER_LONG (sizeof(long) * 8)
-#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
-#define ISBITSET(x,y) ((x)[LONG(y)] & BIT(y))
-#define OFF(x) ((x)%BITS_PER_LONG)
-#define LONG(x) ((x)/BITS_PER_LONG)
-#define BIT(x) (1 << OFF(x))
-
-typedef struct _kevdev {
- /* current device state */
- int rel[REL_MAX + 1];
- int abs[ABS_MAX + 1];
- int prevabs[ABS_MAX + 1];
- long key[NBITS(KEY_MAX + 1)];
-
- /* supported device info */
- long relbits[NBITS(REL_MAX + 1)];
- long absbits[NBITS(ABS_MAX + 1)];
- long keybits[NBITS(KEY_MAX + 1)];
- struct input_absinfo absinfo[ABS_MAX + 1];
- int max_rel;
- int max_abs;
-
- int fd;
-} Kevdev;
-
-static void
-EvdevPtrBtn (KdPointerInfo *pi, struct input_event *ev)
-{
- int flags = KD_MOUSE_DELTA | pi->buttonState;
-
- if (ev->code >= BTN_MOUSE && ev->code < BTN_JOYSTICK) {
- switch (ev->code) {
- case BTN_LEFT:
- if (ev->value == 1)
- flags |= KD_BUTTON_1;
- else
- flags &= ~KD_BUTTON_1;
- break;
- case BTN_MIDDLE:
- if (ev->value == 1)
- flags |= KD_BUTTON_2;
- else
- flags &= ~KD_BUTTON_2;
- break;
- case BTN_RIGHT:
- if (ev->value == 1)
- flags |= KD_BUTTON_3;
- else
- flags &= ~KD_BUTTON_3;
- break;
- default:
- /* Unknow button */
- break;
- }
-
- KdEnqueuePointerEvent (pi, flags, 0, 0, 0);
- }
-}
-static void
-EvdevPtrMotion (KdPointerInfo *pi, struct input_event *ev)
-{
- Kevdev *ke = pi->driverPrivate;
- int i;
- int flags = KD_MOUSE_DELTA | pi->buttonState;
-
- for (i = 0; i <= ke->max_rel; i++)
- if (ke->rel[i])
- {
- int a;
- for (a = 0; a <= ke->max_rel; a++)
- {
- if (ISBITSET (ke->relbits, a))
- {
- if (a == 0)
- KdEnqueuePointerEvent(pi, flags, ke->rel[a], 0, 0);
- else if (a == 1)
- KdEnqueuePointerEvent(pi, flags, 0, ke->rel[a], 0);
- }
- ke->rel[a] = 0;
- }
- break;
- }
- for (i = 0; i < ke->max_abs; i++)
- if (ke->abs[i] != ke->prevabs[i])
- {
- int a;
- ErrorF ("abs");
- for (a = 0; a <= ke->max_abs; a++)
- {
- if (ISBITSET (ke->absbits, a))
- ErrorF (" %d=%d", a, ke->abs[a]);
- ke->prevabs[a] = ke->abs[a];
- }
- ErrorF ("\n");
- break;
- }
-
- if (ev->code == REL_WHEEL) {
- for (i = 0; i < abs (ev->value); i++)
- {
- if (ev->value > 0)
- flags |= KD_BUTTON_4;
- else
- flags |= KD_BUTTON_5;
-
- KdEnqueuePointerEvent (pi, flags, 0, 0, 0);
-
- if (ev->value > 0)
- flags &= ~KD_BUTTON_4;
- else
- flags &= ~KD_BUTTON_5;
-
- KdEnqueuePointerEvent (pi, flags, 0, 0, 0);
- }
- }
-
-}
-
-static void
-EvdevPtrRead (int evdevPort, void *closure)
-{
- KdPointerInfo *pi = closure;
- Kevdev *ke = pi->driverPrivate;
- int i;
- struct input_event events[NUM_EVENTS];
- int n;
-
- n = read (evdevPort, &events, NUM_EVENTS * sizeof (struct input_event));
- if (n <= 0) {
- if (errno == ENODEV)
- DeleteInputDeviceRequest(pi->dixdev);
- return;
- }
-
- n /= sizeof (struct input_event);
- for (i = 0; i < n; i++)
- {
- switch (events[i].type) {
- case EV_SYN:
- break;
- case EV_KEY:
- EvdevPtrBtn (pi, &events[i]);
- break;
- case EV_REL:
- ke->rel[events[i].code] += events[i].value;
- EvdevPtrMotion (pi, &events[i]);
- break;
- case EV_ABS:
- ke->abs[events[i].code] = events[i].value;
- EvdevPtrMotion (pi, &events[i]);
- break;
- }
- }
-}
-
-char *kdefaultEvdev[] = {
- "/dev/input/event0",
- "/dev/input/event1",
- "/dev/input/event2",
- "/dev/input/event3",
-};
-
-#define NUM_DEFAULT_EVDEV (sizeof (kdefaultEvdev) / sizeof (kdefaultEvdev[0]))
-
-static Status
-EvdevPtrInit (KdPointerInfo *pi)
-{
- int i;
- int fd;
-
- if (!pi->path) {
- for (i = 0; i < NUM_DEFAULT_EVDEV; i++) {
- fd = open (kdefaultEvdev[i], 2);
- if (fd >= 0) {
- pi->path = strdup (kdefaultEvdev[i]);
- break;
- }
- }
- }
- else {
- fd = open (pi->path, O_RDWR);
- if (fd < 0) {
- ErrorF("Failed to open evdev device %s\n", pi->path);
- return BadMatch;
- }
- }
-
- close(fd);
-
- pi->name = strdup("Evdev mouse");
-
- return Success;
-}
-
-static Status
-EvdevPtrEnable (KdPointerInfo *pi)
-{
- int fd;
- unsigned long ev[NBITS(EV_MAX)];
- Kevdev *ke;
-
- if (!pi || !pi->path)
- return BadImplementation;
-
- fd = open(pi->path, 2);
- if (fd < 0)
- return BadMatch;
-
- if (ioctl (fd, EVIOCGRAB, 1) < 0)
- perror ("Grabbing evdev mouse device failed");
-
- if (ioctl (fd, EVIOCGBIT(0 /*EV*/, sizeof (ev)), ev) < 0)
- {
- perror ("EVIOCGBIT 0");
- close (fd);
- return BadMatch;
- }
- ke = xcalloc (1, sizeof (Kevdev));
- if (!ke)
- {
- close (fd);
- return BadAlloc;
- }
- if (ISBITSET (ev, EV_KEY))
- {
- if (ioctl (fd, EVIOCGBIT (EV_KEY, sizeof (ke->keybits)),
- ke->keybits) < 0)
- {
- perror ("EVIOCGBIT EV_KEY");
- xfree (ke);
- close (fd);
- return BadMatch;
- }
- }
- if (ISBITSET (ev, EV_REL))
- {
- if (ioctl (fd, EVIOCGBIT (EV_REL, sizeof (ke->relbits)),
- ke->relbits) < 0)
- {
- perror ("EVIOCGBIT EV_REL");
- xfree (ke);
- close (fd);
- return BadMatch;
- }
- for (ke->max_rel = REL_MAX; ke->max_rel >= 0; ke->max_rel--)
- if (ISBITSET(ke->relbits, ke->max_rel))
- break;
- }
- if (ISBITSET (ev, EV_ABS))
- {
- int i;
-
- if (ioctl (fd, EVIOCGBIT (EV_ABS, sizeof (ke->absbits)),
- ke->absbits) < 0)
- {
- perror ("EVIOCGBIT EV_ABS");
- xfree (ke);
- close (fd);
- return BadMatch;
- }
- for (ke->max_abs = ABS_MAX; ke->max_abs >= 0; ke->max_abs--)
- if (ISBITSET(ke->absbits, ke->max_abs))
- break;
- for (i = 0; i <= ke->max_abs; i++)
- {
- if (ISBITSET (ke->absbits, i))
- if (ioctl (fd, EVIOCGABS(i), &ke->absinfo[i]) < 0)
- {
- perror ("EVIOCGABS");
- break;
- }
- ke->prevabs[i] = ABS_UNSET;
- }
- if (i <= ke->max_abs)
- {
- xfree (ke);
- close (fd);
- return BadValue;
- }
- }
- if (!KdRegisterFd (fd, EvdevPtrRead, pi)) {
- xfree (ke);
- close (fd);
- return BadAlloc;
- }
- pi->driverPrivate = ke;
- ke->fd = fd;
-
- return Success;
-}
-
-static void
-EvdevPtrDisable (KdPointerInfo *pi)
-{
- Kevdev *ke;
-
- ke = pi->driverPrivate;
-
- if (!pi || !pi->driverPrivate)
- return;
-
- KdUnregisterFd (pi, ke->fd, TRUE);
-
- if (ioctl (ke->fd, EVIOCGRAB, 0) < 0)
- perror ("Ungrabbing evdev mouse device failed");
-
- xfree (ke);
- pi->driverPrivate = 0;
-}
-
-static void
-EvdevPtrFini (KdPointerInfo *pi)
-{
-}
-
-
-/*
- * Evdev keyboard functions
- */
-
-static void
-readMapping (KdKeyboardInfo *ki)
-{
- if (!ki)
- return;
-
- ki->minScanCode = 0;
- ki->maxScanCode = 247;
-}
-
-static void
-EvdevKbdRead (int evdevPort, void *closure)
-{
- KdKeyboardInfo *ki = closure;
- struct input_event events[NUM_EVENTS];
- int i, n;
-
- n = read (evdevPort, &events, NUM_EVENTS * sizeof (struct input_event));
- if (n <= 0) {
- if (errno == ENODEV)
- DeleteInputDeviceRequest(ki->dixdev);
- return;
- }
-
- n /= sizeof (struct input_event);
- for (i = 0; i < n; i++)
- {
- if (events[i].type == EV_KEY)
- KdEnqueueKeyboardEvent (ki, events[i].code, !events[i].value);
-/* FIXME: must implement other types of events
- else
- ErrorF("Event type (%d) not delivered\n", events[i].type);
-*/
- }
-}
-
-static Status
-EvdevKbdInit (KdKeyboardInfo *ki)
-{
- int fd;
-
- if (!ki->path) {
- ErrorF("Couldn't find evdev device path\n");
- return BadValue;
- }
- else {
- fd = open (ki->path, O_RDWR);
- if (fd < 0) {
- ErrorF("Failed to open evdev device %s\n", ki->path);
- return BadMatch;
- }
- }
-
- close (fd);
-
- ki->name = strdup("Evdev keyboard");
-
- readMapping(ki);
-
- return Success;
-}
-
-static Status
-EvdevKbdEnable (KdKeyboardInfo *ki)
-{
- unsigned long ev[NBITS(EV_MAX)];
- Kevdev *ke;
- int fd;
-
- if (!ki || !ki->path)
- return BadImplementation;
-
- fd = open(ki->path, O_RDWR);
- if (fd < 0)
- return BadMatch;
-
- if (ioctl (fd, EVIOCGRAB, 1) < 0)
- perror ("Grabbing evdev keyboard device failed");
-
- if (ioctl (fd, EVIOCGBIT(0 /*EV*/, sizeof (ev)), ev) < 0) {
- perror ("EVIOCGBIT 0");
- close (fd);
- return BadMatch;
- }
-
- ke = xcalloc (1, sizeof (Kevdev));
- if (!ke) {
- close (fd);
- return BadAlloc;
- }
-
- if (!KdRegisterFd (fd, EvdevKbdRead, ki)) {
- xfree (ke);
- close (fd);
- return BadAlloc;
- }
- ki->driverPrivate = ke;
- ke->fd = fd;
-
- return Success;
-}
-
-static void
-EvdevKbdLeds (KdKeyboardInfo *ki, int leds)
-{
-/* struct input_event event;
- Kevdev *ke;
-
- ki->driverPrivate = ke;
-
- memset(&event, 0, sizeof(event));
-
- event.type = EV_LED;
- event.code = LED_CAPSL;
- event.value = leds & (1 << 0) ? 1 : 0;
- write(ke->fd, (char *) &event, sizeof(event));
-
- event.type = EV_LED;
- event.code = LED_NUML;
- event.value = leds & (1 << 1) ? 1 : 0;
- write(ke->fd, (char *) &event, sizeof(event));
-
- event.type = EV_LED;
- event.code = LED_SCROLLL;
- event.value = leds & (1 << 2) ? 1 : 0;
- write(ke->fd, (char *) &event, sizeof(event));
-
- event.type = EV_LED;
- event.code = LED_COMPOSE;
- event.value = leds & (1 << 3) ? 1 : 0;
- write(ke->fd, (char *) &event, sizeof(event));
-*/
-}
-
-static void
-EvdevKbdBell (KdKeyboardInfo *ki, int volume, int frequency, int duration)
-{
-}
-
-static void
-EvdevKbdDisable (KdKeyboardInfo *ki)
-{
- Kevdev *ke;
-
- ke = ki->driverPrivate;
-
- if (!ki || !ki->driverPrivate)
- return;
-
- KdUnregisterFd (ki, ke->fd, TRUE);
-
- if (ioctl (ke->fd, EVIOCGRAB, 0) < 0)
- perror ("Ungrabbing evdev keyboard device failed");
-
- xfree (ke);
- ki->driverPrivate = 0;
-}
-
-static void
-EvdevKbdFini (KdKeyboardInfo *ki)
-{
-}
-
-KdPointerDriver LinuxEvdevMouseDriver = {
- "evdev",
- EvdevPtrInit,
- EvdevPtrEnable,
- EvdevPtrDisable,
- EvdevPtrFini,
- NULL,
-};
-
-KdKeyboardDriver LinuxEvdevKeyboardDriver = {
- "evdev",
- EvdevKbdInit,
- EvdevKbdEnable,
- EvdevKbdLeds,
- EvdevKbdBell,
- EvdevKbdDisable,
- EvdevKbdFini,
- NULL,
-};
+/*
+ * Copyright © 2004 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+#include <errno.h>
+#include <linux/input.h>
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/Xpoll.h>
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "kdrive.h"
+
+#define NUM_EVENTS 128
+#define ABS_UNSET -65535
+
+#define BITS_PER_LONG (sizeof(long) * 8)
+#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1)
+#define ISBITSET(x,y) ((x)[LONG(y)] & BIT(y))
+#define OFF(x) ((x)%BITS_PER_LONG)
+#define LONG(x) ((x)/BITS_PER_LONG)
+#define BIT(x) (1 << OFF(x))
+
+typedef struct _kevdev {
+ /* current device state */
+ int rel[REL_MAX + 1];
+ int abs[ABS_MAX + 1];
+ int prevabs[ABS_MAX + 1];
+ long key[NBITS(KEY_MAX + 1)];
+
+ /* supported device info */
+ long relbits[NBITS(REL_MAX + 1)];
+ long absbits[NBITS(ABS_MAX + 1)];
+ long keybits[NBITS(KEY_MAX + 1)];
+ struct input_absinfo absinfo[ABS_MAX + 1];
+ int max_rel;
+ int max_abs;
+
+ int fd;
+} Kevdev;
+
+static void
+EvdevPtrBtn (KdPointerInfo *pi, struct input_event *ev)
+{
+ int flags = KD_MOUSE_DELTA | pi->buttonState;
+
+ if (ev->code >= BTN_MOUSE && ev->code < BTN_JOYSTICK) {
+ switch (ev->code) {
+ case BTN_LEFT:
+ if (ev->value == 1)
+ flags |= KD_BUTTON_1;
+ else
+ flags &= ~KD_BUTTON_1;
+ break;
+ case BTN_MIDDLE:
+ if (ev->value == 1)
+ flags |= KD_BUTTON_2;
+ else
+ flags &= ~KD_BUTTON_2;
+ break;
+ case BTN_RIGHT:
+ if (ev->value == 1)
+ flags |= KD_BUTTON_3;
+ else
+ flags &= ~KD_BUTTON_3;
+ break;
+ default:
+ /* Unknow button */
+ break;
+ }
+
+ KdEnqueuePointerEvent (pi, flags, 0, 0, 0);
+ }
+}
+static void
+EvdevPtrMotion (KdPointerInfo *pi, struct input_event *ev)
+{
+ Kevdev *ke = pi->driverPrivate;
+ int i;
+ int flags = KD_MOUSE_DELTA | pi->buttonState;
+
+ for (i = 0; i <= ke->max_rel; i++)
+ if (ke->rel[i])
+ {
+ int a;
+ for (a = 0; a <= ke->max_rel; a++)
+ {
+ if (ISBITSET (ke->relbits, a))
+ {
+ if (a == 0)
+ KdEnqueuePointerEvent(pi, flags, ke->rel[a], 0, 0);
+ else if (a == 1)
+ KdEnqueuePointerEvent(pi, flags, 0, ke->rel[a], 0);
+ }
+ ke->rel[a] = 0;
+ }
+ break;
+ }
+ for (i = 0; i < ke->max_abs; i++)
+ if (ke->abs[i] != ke->prevabs[i])
+ {
+ int a;
+ ErrorF ("abs");
+ for (a = 0; a <= ke->max_abs; a++)
+ {
+ if (ISBITSET (ke->absbits, a))
+ ErrorF (" %d=%d", a, ke->abs[a]);
+ ke->prevabs[a] = ke->abs[a];
+ }
+ ErrorF ("\n");
+ break;
+ }
+
+ if (ev->code == REL_WHEEL) {
+ for (i = 0; i < abs (ev->value); i++)
+ {
+ if (ev->value > 0)
+ flags |= KD_BUTTON_4;
+ else
+ flags |= KD_BUTTON_5;
+
+ KdEnqueuePointerEvent (pi, flags, 0, 0, 0);
+
+ if (ev->value > 0)
+ flags &= ~KD_BUTTON_4;
+ else
+ flags &= ~KD_BUTTON_5;
+
+ KdEnqueuePointerEvent (pi, flags, 0, 0, 0);
+ }
+ }
+
+}
+
+static void
+EvdevPtrRead (int evdevPort, void *closure)
+{
+ KdPointerInfo *pi = closure;
+ Kevdev *ke = pi->driverPrivate;
+ int i;
+ struct input_event events[NUM_EVENTS];
+ int n;
+
+ n = read (evdevPort, &events, NUM_EVENTS * sizeof (struct input_event));
+ if (n <= 0) {
+ if (errno == ENODEV)
+ DeleteInputDeviceRequest(pi->dixdev);
+ return;
+ }
+
+ n /= sizeof (struct input_event);
+ for (i = 0; i < n; i++)
+ {
+ switch (events[i].type) {
+ case EV_SYN:
+ break;
+ case EV_KEY:
+ EvdevPtrBtn (pi, &events[i]);
+ break;
+ case EV_REL:
+ ke->rel[events[i].code] += events[i].value;
+ EvdevPtrMotion (pi, &events[i]);
+ break;
+ case EV_ABS:
+ ke->abs[events[i].code] = events[i].value;
+ EvdevPtrMotion (pi, &events[i]);
+ break;
+ }
+ }
+}
+
+char *kdefaultEvdev[] = {
+ "/dev/input/event0",
+ "/dev/input/event1",
+ "/dev/input/event2",
+ "/dev/input/event3",
+};
+
+#define NUM_DEFAULT_EVDEV (sizeof (kdefaultEvdev) / sizeof (kdefaultEvdev[0]))
+
+static Status
+EvdevPtrInit (KdPointerInfo *pi)
+{
+ int i;
+ int fd;
+
+ if (!pi->path) {
+ for (i = 0; i < NUM_DEFAULT_EVDEV; i++) {
+ fd = open (kdefaultEvdev[i], 2);
+ if (fd >= 0) {
+ pi->path = strdup (kdefaultEvdev[i]);
+ break;
+ }
+ }
+ }
+ else {
+ fd = open (pi->path, O_RDWR);
+ if (fd < 0) {
+ ErrorF("Failed to open evdev device %s\n", pi->path);
+ return BadMatch;
+ }
+ }
+
+ close(fd);
+
+ pi->name = strdup("Evdev mouse");
+
+ return Success;
+}
+
+static Status
+EvdevPtrEnable (KdPointerInfo *pi)
+{
+ int fd;
+ unsigned long ev[NBITS(EV_MAX)];
+ Kevdev *ke;
+
+ if (!pi || !pi->path)
+ return BadImplementation;
+
+ fd = open(pi->path, 2);
+ if (fd < 0)
+ return BadMatch;
+
+ if (ioctl (fd, EVIOCGRAB, 1) < 0)
+ perror ("Grabbing evdev mouse device failed");
+
+ if (ioctl (fd, EVIOCGBIT(0 /*EV*/, sizeof (ev)), ev) < 0)
+ {
+ perror ("EVIOCGBIT 0");
+ close (fd);
+ return BadMatch;
+ }
+ ke = calloc(1, sizeof (Kevdev));
+ if (!ke)
+ {
+ close (fd);
+ return BadAlloc;
+ }
+ if (ISBITSET (ev, EV_KEY))
+ {
+ if (ioctl (fd, EVIOCGBIT (EV_KEY, sizeof (ke->keybits)),
+ ke->keybits) < 0)
+ {
+ perror ("EVIOCGBIT EV_KEY");
+ free(ke);
+ close (fd);
+ return BadMatch;
+ }
+ }
+ if (ISBITSET (ev, EV_REL))
+ {
+ if (ioctl (fd, EVIOCGBIT (EV_REL, sizeof (ke->relbits)),
+ ke->relbits) < 0)
+ {
+ perror ("EVIOCGBIT EV_REL");
+ free(ke);
+ close (fd);
+ return BadMatch;
+ }
+ for (ke->max_rel = REL_MAX; ke->max_rel >= 0; ke->max_rel--)
+ if (ISBITSET(ke->relbits, ke->max_rel))
+ break;
+ }
+ if (ISBITSET (ev, EV_ABS))
+ {
+ int i;
+
+ if (ioctl (fd, EVIOCGBIT (EV_ABS, sizeof (ke->absbits)),
+ ke->absbits) < 0)
+ {
+ perror ("EVIOCGBIT EV_ABS");
+ free(ke);
+ close (fd);
+ return BadMatch;
+ }
+ for (ke->max_abs = ABS_MAX; ke->max_abs >= 0; ke->max_abs--)
+ if (ISBITSET(ke->absbits, ke->max_abs))
+ break;
+ for (i = 0; i <= ke->max_abs; i++)
+ {
+ if (ISBITSET (ke->absbits, i))
+ if (ioctl (fd, EVIOCGABS(i), &ke->absinfo[i]) < 0)
+ {
+ perror ("EVIOCGABS");
+ break;
+ }
+ ke->prevabs[i] = ABS_UNSET;
+ }
+ if (i <= ke->max_abs)
+ {
+ free(ke);
+ close (fd);
+ return BadValue;
+ }
+ }
+ if (!KdRegisterFd (fd, EvdevPtrRead, pi)) {
+ free(ke);
+ close (fd);
+ return BadAlloc;
+ }
+ pi->driverPrivate = ke;
+ ke->fd = fd;
+
+ return Success;
+}
+
+static void
+EvdevPtrDisable (KdPointerInfo *pi)
+{
+ Kevdev *ke;
+
+ ke = pi->driverPrivate;
+
+ if (!pi || !pi->driverPrivate)
+ return;
+
+ KdUnregisterFd (pi, ke->fd, TRUE);
+
+ if (ioctl (ke->fd, EVIOCGRAB, 0) < 0)
+ perror ("Ungrabbing evdev mouse device failed");
+
+ free(ke);
+ pi->driverPrivate = 0;
+}
+
+static void
+EvdevPtrFini (KdPointerInfo *pi)
+{
+}
+
+
+/*
+ * Evdev keyboard functions
+ */
+
+static void
+readMapping (KdKeyboardInfo *ki)
+{
+ if (!ki)
+ return;
+
+ ki->minScanCode = 0;
+ ki->maxScanCode = 247;
+}
+
+static void
+EvdevKbdRead (int evdevPort, void *closure)
+{
+ KdKeyboardInfo *ki = closure;
+ struct input_event events[NUM_EVENTS];
+ int i, n;
+
+ n = read (evdevPort, &events, NUM_EVENTS * sizeof (struct input_event));
+ if (n <= 0) {
+ if (errno == ENODEV)
+ DeleteInputDeviceRequest(ki->dixdev);
+ return;
+ }
+
+ n /= sizeof (struct input_event);
+ for (i = 0; i < n; i++)
+ {
+ if (events[i].type == EV_KEY)
+ KdEnqueueKeyboardEvent (ki, events[i].code, !events[i].value);
+/* FIXME: must implement other types of events
+ else
+ ErrorF("Event type (%d) not delivered\n", events[i].type);
+*/
+ }
+}
+
+static Status
+EvdevKbdInit (KdKeyboardInfo *ki)
+{
+ int fd;
+
+ if (!ki->path) {
+ ErrorF("Couldn't find evdev device path\n");
+ return BadValue;
+ }
+ else {
+ fd = open (ki->path, O_RDWR);
+ if (fd < 0) {
+ ErrorF("Failed to open evdev device %s\n", ki->path);
+ return BadMatch;
+ }
+ }
+
+ close (fd);
+
+ ki->name = strdup("Evdev keyboard");
+
+ readMapping(ki);
+
+ return Success;
+}
+
+static Status
+EvdevKbdEnable (KdKeyboardInfo *ki)
+{
+ unsigned long ev[NBITS(EV_MAX)];
+ Kevdev *ke;
+ int fd;
+
+ if (!ki || !ki->path)
+ return BadImplementation;
+
+ fd = open(ki->path, O_RDWR);
+ if (fd < 0)
+ return BadMatch;
+
+ if (ioctl (fd, EVIOCGRAB, 1) < 0)
+ perror ("Grabbing evdev keyboard device failed");
+
+ if (ioctl (fd, EVIOCGBIT(0 /*EV*/, sizeof (ev)), ev) < 0) {
+ perror ("EVIOCGBIT 0");
+ close (fd);
+ return BadMatch;
+ }
+
+ ke = calloc(1, sizeof (Kevdev));
+ if (!ke) {
+ close (fd);
+ return BadAlloc;
+ }
+
+ if (!KdRegisterFd (fd, EvdevKbdRead, ki)) {
+ free(ke);
+ close (fd);
+ return BadAlloc;
+ }
+ ki->driverPrivate = ke;
+ ke->fd = fd;
+
+ return Success;
+}
+
+static void
+EvdevKbdLeds (KdKeyboardInfo *ki, int leds)
+{
+/* struct input_event event;
+ Kevdev *ke;
+
+ ki->driverPrivate = ke;
+
+ memset(&event, 0, sizeof(event));
+
+ event.type = EV_LED;
+ event.code = LED_CAPSL;
+ event.value = leds & (1 << 0) ? 1 : 0;
+ write(ke->fd, (char *) &event, sizeof(event));
+
+ event.type = EV_LED;
+ event.code = LED_NUML;
+ event.value = leds & (1 << 1) ? 1 : 0;
+ write(ke->fd, (char *) &event, sizeof(event));
+
+ event.type = EV_LED;
+ event.code = LED_SCROLLL;
+ event.value = leds & (1 << 2) ? 1 : 0;
+ write(ke->fd, (char *) &event, sizeof(event));
+
+ event.type = EV_LED;
+ event.code = LED_COMPOSE;
+ event.value = leds & (1 << 3) ? 1 : 0;
+ write(ke->fd, (char *) &event, sizeof(event));
+*/
+}
+
+static void
+EvdevKbdBell (KdKeyboardInfo *ki, int volume, int frequency, int duration)
+{
+}
+
+static void
+EvdevKbdDisable (KdKeyboardInfo *ki)
+{
+ Kevdev *ke;
+
+ ke = ki->driverPrivate;
+
+ if (!ki || !ki->driverPrivate)
+ return;
+
+ KdUnregisterFd (ki, ke->fd, TRUE);
+
+ if (ioctl (ke->fd, EVIOCGRAB, 0) < 0)
+ perror ("Ungrabbing evdev keyboard device failed");
+
+ free(ke);
+ ki->driverPrivate = 0;
+}
+
+static void
+EvdevKbdFini (KdKeyboardInfo *ki)
+{
+}
+
+KdPointerDriver LinuxEvdevMouseDriver = {
+ "evdev",
+ EvdevPtrInit,
+ EvdevPtrEnable,
+ EvdevPtrDisable,
+ EvdevPtrFini,
+ NULL,
+};
+
+KdKeyboardDriver LinuxEvdevKeyboardDriver = {
+ "evdev",
+ EvdevKbdInit,
+ EvdevKbdEnable,
+ EvdevKbdLeds,
+ EvdevKbdBell,
+ EvdevKbdDisable,
+ EvdevKbdFini,
+ NULL,
+};
diff --git a/xorg-server/hw/kdrive/linux/keyboard.c b/xorg-server/hw/kdrive/linux/keyboard.c
index 6eed7aed3..c888d14dc 100644
--- a/xorg-server/hw/kdrive/linux/keyboard.c
+++ b/xorg-server/hw/kdrive/linux/keyboard.c
@@ -1,765 +1,765 @@
-/*
- * Copyright © 1999 Keith Packard
- * XKB integration © 2006 Nokia Corporation, author: Tomas Frydrych <tf@o-hand.com>
- *
- * LinuxKeyboardRead() XKB code based on xf86KbdLnx.c:
- * Copyright © 1990,91 by Thomas Roell, Dinkelscherben, Germany.
- * Copyright © 1994-2001 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-#ifdef HAVE_CONFIG_H
-#include <kdrive-config.h>
-#endif
-#include "kdrive.h"
-#include <linux/keyboard.h>
-#include <linux/kd.h>
-#define XK_PUBLISHING
-#include <X11/keysym.h>
-#include <termios.h>
-#include <sys/ioctl.h>
-
-extern int LinuxConsoleFd;
-
-static const KeySym linux_to_x[256] = {
- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- XK_BackSpace, XK_Tab, XK_Linefeed, NoSymbol,
- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- NoSymbol, NoSymbol, NoSymbol, XK_Escape,
- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- XK_space, XK_exclam, XK_quotedbl, XK_numbersign,
- XK_dollar, XK_percent, XK_ampersand, XK_apostrophe,
- XK_parenleft, XK_parenright, XK_asterisk, XK_plus,
- XK_comma, XK_minus, XK_period, XK_slash,
- XK_0, XK_1, XK_2, XK_3,
- XK_4, XK_5, XK_6, XK_7,
- XK_8, XK_9, XK_colon, XK_semicolon,
- XK_less, XK_equal, XK_greater, XK_question,
- XK_at, XK_A, XK_B, XK_C,
- XK_D, XK_E, XK_F, XK_G,
- XK_H, XK_I, XK_J, XK_K,
- XK_L, XK_M, XK_N, XK_O,
- XK_P, XK_Q, XK_R, XK_S,
- XK_T, XK_U, XK_V, XK_W,
- XK_X, XK_Y, XK_Z, XK_bracketleft,
- XK_backslash, XK_bracketright,XK_asciicircum, XK_underscore,
- XK_grave, XK_a, XK_b, XK_c,
- XK_d, XK_e, XK_f, XK_g,
- XK_h, XK_i, XK_j, XK_k,
- XK_l, XK_m, XK_n, XK_o,
- XK_p, XK_q, XK_r, XK_s,
- XK_t, XK_u, XK_v, XK_w,
- XK_x, XK_y, XK_z, XK_braceleft,
- XK_bar, XK_braceright, XK_asciitilde, XK_BackSpace,
- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- NoSymbol, NoSymbol, NoSymbol, NoSymbol,
- XK_nobreakspace,XK_exclamdown, XK_cent, XK_sterling,
- XK_currency, XK_yen, XK_brokenbar, XK_section,
- XK_diaeresis, XK_copyright, XK_ordfeminine, XK_guillemotleft,
- XK_notsign, XK_hyphen, XK_registered, XK_macron,
- XK_degree, XK_plusminus, XK_twosuperior, XK_threesuperior,
- XK_acute, XK_mu, XK_paragraph, XK_periodcentered,
- XK_cedilla, XK_onesuperior, XK_masculine, XK_guillemotright,
- XK_onequarter, XK_onehalf, XK_threequarters,XK_questiondown,
- XK_Agrave, XK_Aacute, XK_Acircumflex, XK_Atilde,
- XK_Adiaeresis, XK_Aring, XK_AE, XK_Ccedilla,
- XK_Egrave, XK_Eacute, XK_Ecircumflex, XK_Ediaeresis,
- XK_Igrave, XK_Iacute, XK_Icircumflex, XK_Idiaeresis,
- XK_ETH, XK_Ntilde, XK_Ograve, XK_Oacute,
- XK_Ocircumflex, XK_Otilde, XK_Odiaeresis, XK_multiply,
- XK_Ooblique, XK_Ugrave, XK_Uacute, XK_Ucircumflex,
- XK_Udiaeresis, XK_Yacute, XK_THORN, XK_ssharp,
- XK_agrave, XK_aacute, XK_acircumflex, XK_atilde,
- XK_adiaeresis, XK_aring, XK_ae, XK_ccedilla,
- XK_egrave, XK_eacute, XK_ecircumflex, XK_ediaeresis,
- XK_igrave, XK_iacute, XK_icircumflex, XK_idiaeresis,
- XK_eth, XK_ntilde, XK_ograve, XK_oacute,
- XK_ocircumflex, XK_otilde, XK_odiaeresis, XK_division,
- XK_oslash, XK_ugrave, XK_uacute, XK_ucircumflex,
- XK_udiaeresis, XK_yacute, XK_thorn, XK_ydiaeresis
-};
-
-/*
- * Getting a keycode from scancode
- *
- * With XKB
- * --------
- *
- * We have to enqueue keyboard events using standard X keycodes which correspond
- * to AT scancode + 8; this means that we need to translate the Linux scancode
- * provided by the kernel to an AT scancode -- this translation is not linear
- * and requires that we use a LUT.
- *
- *
- * Without XKB
- * -----------
- *
- * We can use custom keycodes, which makes things simpler; we define our custom
- * keycodes as Linux scancodes + KD_KEY_OFFSET
-*/
-
-/*
- This LUT translates AT scancodes into Linux ones -- the keymap we create
- for the core X keyboard protocol has to be AT-scancode based so that it
- corresponds to the Xkb keymap.
-*/
-#if 0
-static unsigned char at2lnx[] =
-{
- 0x0, /* no valid scancode */
- 0x01, /* KEY_Escape */ 0x02, /* KEY_1 */
- 0x03, /* KEY_2 */ 0x04, /* KEY_3 */
- 0x05, /* KEY_4 */ 0x06, /* KEY_5 */
- 0x07, /* KEY_6 */ 0x08, /* KEY_7 */
- 0x09, /* KEY_8 */ 0x0a, /* KEY_9 */
- 0x0b, /* KEY_0 */ 0x0c, /* KEY_Minus */
- 0x0d, /* KEY_Equal */ 0x0e, /* KEY_BackSpace */
- 0x0f, /* KEY_Tab */ 0x10, /* KEY_Q */
- 0x11, /* KEY_W */ 0x12, /* KEY_E */
- 0x13, /* KEY_R */ 0x14, /* KEY_T */
- 0x15, /* KEY_Y */ 0x16, /* KEY_U */
- 0x17, /* KEY_I */ 0x18, /* KEY_O */
- 0x19, /* KEY_P */ 0x1a, /* KEY_LBrace */
- 0x1b, /* KEY_RBrace */ 0x1c, /* KEY_Enter */
- 0x1d, /* KEY_LCtrl */ 0x1e, /* KEY_A */
- 0x1f, /* KEY_S */ 0x20, /* KEY_D */
- 0x21, /* KEY_F */ 0x22, /* KEY_G */
- 0x23, /* KEY_H */ 0x24, /* KEY_J */
- 0x25, /* KEY_K */ 0x26, /* KEY_L */
- 0x27, /* KEY_SemiColon */ 0x28, /* KEY_Quote */
- 0x29, /* KEY_Tilde */ 0x2a, /* KEY_ShiftL */
- 0x2b, /* KEY_BSlash */ 0x2c, /* KEY_Z */
- 0x2d, /* KEY_X */ 0x2e, /* KEY_C */
- 0x2f, /* KEY_V */ 0x30, /* KEY_B */
- 0x31, /* KEY_N */ 0x32, /* KEY_M */
- 0x33, /* KEY_Comma */ 0x34, /* KEY_Period */
- 0x35, /* KEY_Slash */ 0x36, /* KEY_ShiftR */
- 0x37, /* KEY_KP_Multiply */ 0x38, /* KEY_Alt */
- 0x39, /* KEY_Space */ 0x3a, /* KEY_CapsLock */
- 0x3b, /* KEY_F1 */ 0x3c, /* KEY_F2 */
- 0x3d, /* KEY_F3 */ 0x3e, /* KEY_F4 */
- 0x3f, /* KEY_F5 */ 0x40, /* KEY_F6 */
- 0x41, /* KEY_F7 */ 0x42, /* KEY_F8 */
- 0x43, /* KEY_F9 */ 0x44, /* KEY_F10 */
- 0x45, /* KEY_NumLock */ 0x46, /* KEY_ScrollLock */
- 0x47, /* KEY_KP_7 */ 0x48, /* KEY_KP_8 */
- 0x49, /* KEY_KP_9 */ 0x4a, /* KEY_KP_Minus */
- 0x4b, /* KEY_KP_4 */ 0x4c, /* KEY_KP_5 */
- 0x4d, /* KEY_KP_6 */ 0x4e, /* KEY_KP_Plus */
- 0x4f, /* KEY_KP_1 */ 0x50, /* KEY_KP_2 */
- 0x51, /* KEY_KP_3 */ 0x52, /* KEY_KP_0 */
- 0x53, /* KEY_KP_Decimal */ 0x54, /* KEY_SysReqest */
- 0x00, /* 0x55 */ 0x56, /* KEY_Less */
- 0x57, /* KEY_F11 */ 0x58, /* KEY_F12 */
- 0x66, /* KEY_Home */ 0x67, /* KEY_Up */
- 0x68, /* KEY_PgUp */ 0x69, /* KEY_Left */
- 0x5d, /* KEY_Begin */ 0x6a, /* KEY_Right */
- 0x6b, /* KEY_End */ 0x6c, /* KEY_Down */
- 0x6d, /* KEY_PgDown */ 0x6e, /* KEY_Insert */
- 0x6f, /* KEY_Delete */ 0x60, /* KEY_KP_Enter */
- 0x61, /* KEY_RCtrl */ 0x77, /* KEY_Pause */
- 0x63, /* KEY_Print */ 0x62, /* KEY_KP_Divide */
- 0x64, /* KEY_AltLang */ 0x65, /* KEY_Break */
- 0x00, /* KEY_LMeta */ 0x00, /* KEY_RMeta */
- 0x7A, /* KEY_Menu/FOCUS_PF11*/0x00, /* 0x6e */
- 0x7B, /* FOCUS_PF12 */ 0x00, /* 0x70 */
- 0x00, /* 0x71 */ 0x00, /* 0x72 */
- 0x59, /* FOCUS_PF2 */ 0x78, /* FOCUS_PF9 */
- 0x00, /* 0x75 */ 0x00, /* 0x76 */
- 0x5A, /* FOCUS_PF3 */ 0x5B, /* FOCUS_PF4 */
- 0x5C, /* FOCUS_PF5 */ 0x5D, /* FOCUS_PF6 */
- 0x5E, /* FOCUS_PF7 */ 0x5F, /* FOCUS_PF8 */
- 0x7C, /* JAP_86 */ 0x79, /* FOCUS_PF10 */
- 0x00, /* 0x7f */
-};
-
-#define NUM_AT_KEYS (sizeof(at2lnx)/sizeof(at2lnx[0]))
-#define LNX_KEY_INDEX(n) n < NUM_AT_KEYS ? at2lnx[n] : 0
-
-static unsigned char tbl[KD_MAX_WIDTH] =
-{
- 0,
- 1 << KG_SHIFT,
- (1 << KG_ALTGR),
- (1 << KG_ALTGR) | (1 << KG_SHIFT)
-};
-#endif
-
-static void
-readKernelMapping(KdKeyboardInfo *ki)
-{
-#if 0
- KeySym *k;
- int i, j;
- struct kbentry kbe;
- int minKeyCode, maxKeyCode;
- int row;
- int fd;
-
- if (!ki)
- return;
-
- fd = LinuxConsoleFd;
-
- minKeyCode = NR_KEYS;
- maxKeyCode = 0;
- row = 0;
- ki->keySyms.mapWidth = KD_MAX_WIDTH;
- for (i = 0; i < NR_KEYS && row < KD_MAX_LENGTH; ++i)
- {
- kbe.kb_index = LNX_KEY_INDEX(i);
-
- k = ki->keySyms.map + row * ki->keySyms.mapWidth;
-
- for (j = 0; j < ki->keySyms.mapWidth; ++j)
- {
- unsigned short kval;
-
- k[j] = NoSymbol;
-
- kbe.kb_table = tbl[j];
- kbe.kb_value = 0;
- if (ioctl(fd, KDGKBENT, &kbe))
- continue;
-
- kval = KVAL(kbe.kb_value);
- switch (KTYP(kbe.kb_value))
- {
- case KT_LATIN:
- case KT_LETTER:
- k[j] = linux_to_x[kval];
- break;
-
- case KT_FN:
- if (kval <= 19)
- k[j] = XK_F1 + kval;
- else switch (kbe.kb_value)
- {
- case K_FIND:
- k[j] = XK_Home; /* or XK_Find */
- break;
- case K_INSERT:
- k[j] = XK_Insert;
- break;
- case K_REMOVE:
- k[j] = XK_Delete;
- break;
- case K_SELECT:
- k[j] = XK_End; /* or XK_Select */
- break;
- case K_PGUP:
- k[j] = XK_Prior;
- break;
- case K_PGDN:
- k[j] = XK_Next;
- break;
- case K_HELP:
- k[j] = XK_Help;
- break;
- case K_DO:
- k[j] = XK_Execute;
- break;
- case K_PAUSE:
- k[j] = XK_Pause;
- break;
- case K_MACRO:
- k[j] = XK_Menu;
- break;
- default:
- break;
- }
- break;
-
- case KT_SPEC:
- switch (kbe.kb_value)
- {
- case K_ENTER:
- k[j] = XK_Return;
- break;
- case K_BREAK:
- k[j] = XK_Break;
- break;
- case K_CAPS:
- k[j] = XK_Caps_Lock;
- break;
- case K_NUM:
- k[j] = XK_Num_Lock;
- break;
- case K_HOLD:
- k[j] = XK_Scroll_Lock;
- break;
- case K_COMPOSE:
- k[j] = XK_Multi_key;
- break;
- default:
- break;
- }
- break;
-
- case KT_PAD:
- switch (kbe.kb_value)
- {
- case K_PPLUS:
- k[j] = XK_KP_Add;
- break;
- case K_PMINUS:
- k[j] = XK_KP_Subtract;
- break;
- case K_PSTAR:
- k[j] = XK_KP_Multiply;
- break;
- case K_PSLASH:
- k[j] = XK_KP_Divide;
- break;
- case K_PENTER:
- k[j] = XK_KP_Enter;
- break;
- case K_PCOMMA:
- k[j] = XK_KP_Separator;
- break;
- case K_PDOT:
- k[j] = XK_KP_Decimal;
- break;
- case K_PPLUSMINUS:
- k[j] = XK_KP_Subtract;
- break;
- default:
- if (kval <= 9)
- k[j] = XK_KP_0 + kval;
- break;
- }
- break;
-
- /*
- * KT_DEAD keys are for accelerated diacritical creation.
- */
- case KT_DEAD:
- switch (kbe.kb_value)
- {
- case K_DGRAVE:
- k[j] = XK_dead_grave;
- break;
- case K_DACUTE:
- k[j] = XK_dead_acute;
- break;
- case K_DCIRCM:
- k[j] = XK_dead_circumflex;
- break;
- case K_DTILDE:
- k[j] = XK_dead_tilde;
- break;
- case K_DDIERE:
- k[j] = XK_dead_diaeresis;
- break;
- }
- break;
-
- case KT_CUR:
- switch (kbe.kb_value)
- {
- case K_DOWN:
- k[j] = XK_Down;
- break;
- case K_LEFT:
- k[j] = XK_Left;
- break;
- case K_RIGHT:
- k[j] = XK_Right;
- break;
- case K_UP:
- k[j] = XK_Up;
- break;
- }
- break;
-
- case KT_SHIFT:
- switch (kbe.kb_value)
- {
- case K_ALTGR:
- k[j] = XK_Mode_switch;
- break;
- case K_ALT:
- k[j] = (kbe.kb_index == 0x64 ?
- XK_Alt_R : XK_Alt_L);
- break;
- case K_CTRL:
- k[j] = (kbe.kb_index == 0x61 ?
- XK_Control_R : XK_Control_L);
- break;
- case K_CTRLL:
- k[j] = XK_Control_L;
- break;
- case K_CTRLR:
- k[j] = XK_Control_R;
- break;
- case K_SHIFT:
- k[j] = (kbe.kb_index == 0x36 ?
- XK_Shift_R : XK_Shift_L);
- break;
- case K_SHIFTL:
- k[j] = XK_Shift_L;
- break;
- case K_SHIFTR:
- k[j] = XK_Shift_R;
- break;
- default:
- break;
- }
- break;
-
- /*
- * KT_ASCII keys accumulate a 3 digit decimal number that gets
- * emitted when the shift state changes. We can't emulate that.
- */
- case KT_ASCII:
- break;
-
- case KT_LOCK:
- if (kbe.kb_value == K_SHIFTLOCK)
- k[j] = XK_Shift_Lock;
- break;
-
-#ifdef KT_X
- case KT_X:
- /* depends on new keyboard symbols in file linux/keyboard.h */
- if(kbe.kb_value == K_XMENU) k[j] = XK_Menu;
- if(kbe.kb_value == K_XTELEPHONE) k[j] = XK_telephone;
- break;
-#endif
-#ifdef KT_XF
- case KT_XF:
- /* special linux keysyms which map directly to XF86 keysyms */
- k[j] = (kbe.kb_value & 0xFF) + 0x1008FF00;
- break;
-#endif
-
- default:
- break;
- }
- if (i < minKeyCode)
- minKeyCode = i;
- if (i > maxKeyCode)
- maxKeyCode = i;
- }
-
- if (minKeyCode == NR_KEYS)
- continue;
-
- if (k[3] == k[2]) k[3] = NoSymbol;
- if (k[2] == k[1]) k[2] = NoSymbol;
- if (k[1] == k[0]) k[1] = NoSymbol;
- if (k[0] == k[2] && k[1] == k[3]) k[2] = k[3] = NoSymbol;
- if (k[3] == k[0] && k[2] == k[1] && k[2] == NoSymbol) k[3] =NoSymbol;
- row++;
- }
- ki->minScanCode = minKeyCode;
- ki->maxScanCode = maxKeyCode;
-#endif
-}
-
-/*
- * We need these to handle extended scancodes correctly (I could just use the
- * numbers below, but this makes the code more readable
- */
-
-/* The prefix codes */
-#define KEY_Prefix0 /* special 0x60 */ 96
-#define KEY_Prefix1 /* special 0x61 */ 97
-
-/* The raw scancodes */
-#define KEY_Enter /* Enter 0x1c */ 28
-#define KEY_LCtrl /* Ctrl(left) 0x1d */ 29
-#define KEY_Slash /* / (Slash) ? 0x35 */ 53
-#define KEY_KP_Multiply /* * 0x37 */ 55
-#define KEY_Alt /* Alt(left) 0x38 */ 56
-#define KEY_F3 /* F3 0x3d */ 61
-#define KEY_F4 /* F4 0x3e */ 62
-#define KEY_F5 /* F5 0x3f */ 63
-#define KEY_F6 /* F6 0x40 */ 64
-#define KEY_F7 /* F7 0x41 */ 65
-#define KEY_ScrollLock /* ScrollLock 0x46 */ 70
-#define KEY_KP_7 /* 7 Home 0x47 */ 71
-#define KEY_KP_8 /* 8 Up 0x48 */ 72
-#define KEY_KP_9 /* 9 PgUp 0x49 */ 73
-#define KEY_KP_Minus /* - (Minus) 0x4a */ 74
-#define KEY_KP_4 /* 4 Left 0x4b */ 75
-#define KEY_KP_5 /* 5 0x4c */ 76
-#define KEY_KP_6 /* 6 Right 0x4d */ 77
-#define KEY_KP_Plus /* + (Plus) 0x4e */ 78
-#define KEY_KP_1 /* 1 End 0x4f */ 79
-#define KEY_KP_2 /* 2 Down 0x50 */ 80
-#define KEY_KP_3 /* 3 PgDown 0x51 */ 81
-#define KEY_KP_0 /* 0 Insert 0x52 */ 82
-#define KEY_KP_Decimal /* . (Decimal) Delete 0x53 */ 83
-#define KEY_Home /* Home 0x59 */ 89
-#define KEY_Up /* Up 0x5a */ 90
-#define KEY_PgUp /* PgUp 0x5b */ 91
-#define KEY_Left /* Left 0x5c */ 92
-#define KEY_Begin /* Begin 0x5d */ 93
-#define KEY_Right /* Right 0x5e */ 94
-#define KEY_End /* End 0x5f */ 95
-#define KEY_Down /* Down 0x60 */ 96
-#define KEY_PgDown /* PgDown 0x61 */ 97
-#define KEY_Insert /* Insert 0x62 */ 98
-#define KEY_Delete /* Delete 0x63 */ 99
-#define KEY_KP_Enter /* Enter 0x64 */ 100
-#define KEY_RCtrl /* Ctrl(right) 0x65 */ 101
-#define KEY_Pause /* Pause 0x66 */ 102
-#define KEY_Print /* Print 0x67 */ 103
-#define KEY_KP_Divide /* Divide 0x68 */ 104
-#define KEY_AltLang /* AtlLang(right) 0x69 */ 105
-#define KEY_Break /* Break 0x6a */ 106
-#define KEY_LMeta /* Left Meta 0x6b */ 107
-#define KEY_RMeta /* Right Meta 0x6c */ 108
-#define KEY_Menu /* Menu 0x6d */ 109
-#define KEY_F13 /* F13 0x6e */ 110
-#define KEY_F14 /* F14 0x6f */ 111
-#define KEY_F15 /* F15 0x70 */ 112
-#define KEY_F16 /* F16 0x71 */ 113
-#define KEY_F17 /* F17 0x72 */ 114
-#define KEY_KP_DEC /* KP_DEC 0x73 */ 115
-
-static void
-LinuxKeyboardRead (int fd, void *closure)
-{
- unsigned char buf[256], *b;
- int n;
- unsigned char prefix = 0, scancode = 0;
-
- while ((n = read (fd, buf, sizeof (buf))) > 0) {
- b = buf;
- while (n--) {
- /*
- * With xkb we use RAW mode for reading the console, which allows us
- * process extended scancodes.
- *
- * See if this is a prefix extending the following keycode
- */
- if (!prefix && ((b[0] & 0x7f) == KEY_Prefix0))
- {
- prefix = KEY_Prefix0;
- /* swallow this up */
- b++;
- continue;
- }
- else if (!prefix && ((b[0] & 0x7f) == KEY_Prefix1))
- {
- prefix = KEY_Prefix1;
- /* swallow this up */
- b++;
- continue;
- }
- scancode = b[0] & 0x7f;
-
- switch (prefix) {
- /* from xf86Events.c */
- case KEY_Prefix0:
- {
- switch (scancode) {
- case KEY_KP_7:
- scancode = KEY_Home; break; /* curs home */
- case KEY_KP_8:
- scancode = KEY_Up; break; /* curs up */
- case KEY_KP_9:
- scancode = KEY_PgUp; break; /* curs pgup */
- case KEY_KP_4:
- scancode = KEY_Left; break; /* curs left */
- case KEY_KP_5:
- scancode = KEY_Begin; break; /* curs begin */
- case KEY_KP_6:
- scancode = KEY_Right; break; /* curs right */
- case KEY_KP_1:
- scancode = KEY_End; break; /* curs end */
- case KEY_KP_2:
- scancode = KEY_Down; break; /* curs down */
- case KEY_KP_3:
- scancode = KEY_PgDown; break; /* curs pgdown */
- case KEY_KP_0:
- scancode = KEY_Insert; break; /* curs insert */
- case KEY_KP_Decimal:
- scancode = KEY_Delete; break; /* curs delete */
- case KEY_Enter:
- scancode = KEY_KP_Enter; break; /* keypad enter */
- case KEY_LCtrl:
- scancode = KEY_RCtrl; break; /* right ctrl */
- case KEY_KP_Multiply:
- scancode = KEY_Print; break; /* print */
- case KEY_Slash:
- scancode = KEY_KP_Divide; break; /* keyp divide */
- case KEY_Alt:
- scancode = KEY_AltLang; break; /* right alt */
- case KEY_ScrollLock:
- scancode = KEY_Break; break; /* curs break */
- case 0x5b:
- scancode = KEY_LMeta; break;
- case 0x5c:
- scancode = KEY_RMeta; break;
- case 0x5d:
- scancode = KEY_Menu; break;
- case KEY_F3:
- scancode = KEY_F13; break;
- case KEY_F4:
- scancode = KEY_F14; break;
- case KEY_F5:
- scancode = KEY_F15; break;
- case KEY_F6:
- scancode = KEY_F16; break;
- case KEY_F7:
- scancode = KEY_F17; break;
- case KEY_KP_Plus:
- scancode = KEY_KP_DEC; break;
- /* Ignore virtual shifts (E0 2A, E0 AA, E0 36, E0 B6) */
- case 0x2A:
- case 0x36:
- b++;
- prefix = 0;
- continue;
- default:
- /*
- * "Internet" keyboards are generating lots of new
- * codes. Let them pass. There is little consistency
- * between them, so don't bother with symbolic names at
- * this level.
- */
- scancode += 0x78;
- }
- break;
- }
-
- case KEY_Prefix1:
- {
- /* we do no handle these */
- b++;
- prefix = 0;
- continue;
- }
-
- default: /* should not happen*/
- case 0: /* do nothing */
- ;
- }
-
- prefix = 0;
- KdEnqueueKeyboardEvent (closure, scancode, b[0] & 0x80);
- b++;
- }
- }
-}
-
-static int LinuxKbdTrans;
-static struct termios LinuxTermios;
-
-static Status
-LinuxKeyboardEnable (KdKeyboardInfo *ki)
-{
- struct termios nTty;
- unsigned char buf[256];
- int n;
- int fd;
-
- if (!ki)
- return !Success;
-
- fd = LinuxConsoleFd;
- ki->driverPrivate = (void *) fd;
-
- ioctl (fd, KDGKBMODE, &LinuxKbdTrans);
- tcgetattr (fd, &LinuxTermios);
- ioctl(fd, KDSKBMODE, K_RAW);
- nTty = LinuxTermios;
- nTty.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP);
- nTty.c_oflag = 0;
- nTty.c_cflag = CREAD | CS8;
- nTty.c_lflag = 0;
- nTty.c_cc[VTIME]=0;
- nTty.c_cc[VMIN]=1;
- cfsetispeed(&nTty, 9600);
- cfsetospeed(&nTty, 9600);
- tcsetattr(fd, TCSANOW, &nTty);
- /*
- * Flush any pending keystrokes
- */
- while ((n = read (fd, buf, sizeof (buf))) > 0)
- ;
- KdRegisterFd (fd, LinuxKeyboardRead, ki);
- return Success;
-}
-
-static void
-LinuxKeyboardDisable (KdKeyboardInfo *ki)
-{
- int fd;
-
- if (!ki)
- return;
-
- fd = (int) ki->driverPrivate;
-
- KdUnregisterFd(ki, fd, FALSE);
- ioctl(fd, KDSKBMODE, LinuxKbdTrans);
- tcsetattr(fd, TCSANOW, &LinuxTermios);
-}
-
-static Status
-LinuxKeyboardInit (KdKeyboardInfo *ki)
-{
- if (!ki)
- return !Success;
-
- xfree(ki->path);
- ki->path = strdup("console");
- xfree(ki->name);
- ki->name = strdup("Linux console keyboard");
-
- readKernelMapping (ki);
-
- return Success;
-}
-
-static void
-LinuxKeyboardLeds (KdKeyboardInfo *ki, int leds)
-{
- if (!ki)
- return;
-
- ioctl ((int)ki->driverPrivate, KDSETLED, leds & 7);
-}
-
-KdKeyboardDriver LinuxKeyboardDriver = {
- "keyboard",
- .Init = LinuxKeyboardInit,
- .Enable = LinuxKeyboardEnable,
- .Leds = LinuxKeyboardLeds,
- .Disable = LinuxKeyboardDisable,
-};
+/*
+ * Copyright © 1999 Keith Packard
+ * XKB integration © 2006 Nokia Corporation, author: Tomas Frydrych <tf@o-hand.com>
+ *
+ * LinuxKeyboardRead() XKB code based on xf86KbdLnx.c:
+ * Copyright © 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+ * Copyright © 1994-2001 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+#include "kdrive.h"
+#include <linux/keyboard.h>
+#include <linux/kd.h>
+#define XK_PUBLISHING
+#include <X11/keysym.h>
+#include <termios.h>
+#include <sys/ioctl.h>
+
+extern int LinuxConsoleFd;
+
+static const KeySym linux_to_x[256] = {
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ XK_BackSpace, XK_Tab, XK_Linefeed, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, XK_Escape,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ XK_space, XK_exclam, XK_quotedbl, XK_numbersign,
+ XK_dollar, XK_percent, XK_ampersand, XK_apostrophe,
+ XK_parenleft, XK_parenright, XK_asterisk, XK_plus,
+ XK_comma, XK_minus, XK_period, XK_slash,
+ XK_0, XK_1, XK_2, XK_3,
+ XK_4, XK_5, XK_6, XK_7,
+ XK_8, XK_9, XK_colon, XK_semicolon,
+ XK_less, XK_equal, XK_greater, XK_question,
+ XK_at, XK_A, XK_B, XK_C,
+ XK_D, XK_E, XK_F, XK_G,
+ XK_H, XK_I, XK_J, XK_K,
+ XK_L, XK_M, XK_N, XK_O,
+ XK_P, XK_Q, XK_R, XK_S,
+ XK_T, XK_U, XK_V, XK_W,
+ XK_X, XK_Y, XK_Z, XK_bracketleft,
+ XK_backslash, XK_bracketright,XK_asciicircum, XK_underscore,
+ XK_grave, XK_a, XK_b, XK_c,
+ XK_d, XK_e, XK_f, XK_g,
+ XK_h, XK_i, XK_j, XK_k,
+ XK_l, XK_m, XK_n, XK_o,
+ XK_p, XK_q, XK_r, XK_s,
+ XK_t, XK_u, XK_v, XK_w,
+ XK_x, XK_y, XK_z, XK_braceleft,
+ XK_bar, XK_braceright, XK_asciitilde, XK_BackSpace,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ NoSymbol, NoSymbol, NoSymbol, NoSymbol,
+ XK_nobreakspace,XK_exclamdown, XK_cent, XK_sterling,
+ XK_currency, XK_yen, XK_brokenbar, XK_section,
+ XK_diaeresis, XK_copyright, XK_ordfeminine, XK_guillemotleft,
+ XK_notsign, XK_hyphen, XK_registered, XK_macron,
+ XK_degree, XK_plusminus, XK_twosuperior, XK_threesuperior,
+ XK_acute, XK_mu, XK_paragraph, XK_periodcentered,
+ XK_cedilla, XK_onesuperior, XK_masculine, XK_guillemotright,
+ XK_onequarter, XK_onehalf, XK_threequarters,XK_questiondown,
+ XK_Agrave, XK_Aacute, XK_Acircumflex, XK_Atilde,
+ XK_Adiaeresis, XK_Aring, XK_AE, XK_Ccedilla,
+ XK_Egrave, XK_Eacute, XK_Ecircumflex, XK_Ediaeresis,
+ XK_Igrave, XK_Iacute, XK_Icircumflex, XK_Idiaeresis,
+ XK_ETH, XK_Ntilde, XK_Ograve, XK_Oacute,
+ XK_Ocircumflex, XK_Otilde, XK_Odiaeresis, XK_multiply,
+ XK_Ooblique, XK_Ugrave, XK_Uacute, XK_Ucircumflex,
+ XK_Udiaeresis, XK_Yacute, XK_THORN, XK_ssharp,
+ XK_agrave, XK_aacute, XK_acircumflex, XK_atilde,
+ XK_adiaeresis, XK_aring, XK_ae, XK_ccedilla,
+ XK_egrave, XK_eacute, XK_ecircumflex, XK_ediaeresis,
+ XK_igrave, XK_iacute, XK_icircumflex, XK_idiaeresis,
+ XK_eth, XK_ntilde, XK_ograve, XK_oacute,
+ XK_ocircumflex, XK_otilde, XK_odiaeresis, XK_division,
+ XK_oslash, XK_ugrave, XK_uacute, XK_ucircumflex,
+ XK_udiaeresis, XK_yacute, XK_thorn, XK_ydiaeresis
+};
+
+/*
+ * Getting a keycode from scancode
+ *
+ * With XKB
+ * --------
+ *
+ * We have to enqueue keyboard events using standard X keycodes which correspond
+ * to AT scancode + 8; this means that we need to translate the Linux scancode
+ * provided by the kernel to an AT scancode -- this translation is not linear
+ * and requires that we use a LUT.
+ *
+ *
+ * Without XKB
+ * -----------
+ *
+ * We can use custom keycodes, which makes things simpler; we define our custom
+ * keycodes as Linux scancodes + KD_KEY_OFFSET
+*/
+
+/*
+ This LUT translates AT scancodes into Linux ones -- the keymap we create
+ for the core X keyboard protocol has to be AT-scancode based so that it
+ corresponds to the Xkb keymap.
+*/
+#if 0
+static unsigned char at2lnx[] =
+{
+ 0x0, /* no valid scancode */
+ 0x01, /* KEY_Escape */ 0x02, /* KEY_1 */
+ 0x03, /* KEY_2 */ 0x04, /* KEY_3 */
+ 0x05, /* KEY_4 */ 0x06, /* KEY_5 */
+ 0x07, /* KEY_6 */ 0x08, /* KEY_7 */
+ 0x09, /* KEY_8 */ 0x0a, /* KEY_9 */
+ 0x0b, /* KEY_0 */ 0x0c, /* KEY_Minus */
+ 0x0d, /* KEY_Equal */ 0x0e, /* KEY_BackSpace */
+ 0x0f, /* KEY_Tab */ 0x10, /* KEY_Q */
+ 0x11, /* KEY_W */ 0x12, /* KEY_E */
+ 0x13, /* KEY_R */ 0x14, /* KEY_T */
+ 0x15, /* KEY_Y */ 0x16, /* KEY_U */
+ 0x17, /* KEY_I */ 0x18, /* KEY_O */
+ 0x19, /* KEY_P */ 0x1a, /* KEY_LBrace */
+ 0x1b, /* KEY_RBrace */ 0x1c, /* KEY_Enter */
+ 0x1d, /* KEY_LCtrl */ 0x1e, /* KEY_A */
+ 0x1f, /* KEY_S */ 0x20, /* KEY_D */
+ 0x21, /* KEY_F */ 0x22, /* KEY_G */
+ 0x23, /* KEY_H */ 0x24, /* KEY_J */
+ 0x25, /* KEY_K */ 0x26, /* KEY_L */
+ 0x27, /* KEY_SemiColon */ 0x28, /* KEY_Quote */
+ 0x29, /* KEY_Tilde */ 0x2a, /* KEY_ShiftL */
+ 0x2b, /* KEY_BSlash */ 0x2c, /* KEY_Z */
+ 0x2d, /* KEY_X */ 0x2e, /* KEY_C */
+ 0x2f, /* KEY_V */ 0x30, /* KEY_B */
+ 0x31, /* KEY_N */ 0x32, /* KEY_M */
+ 0x33, /* KEY_Comma */ 0x34, /* KEY_Period */
+ 0x35, /* KEY_Slash */ 0x36, /* KEY_ShiftR */
+ 0x37, /* KEY_KP_Multiply */ 0x38, /* KEY_Alt */
+ 0x39, /* KEY_Space */ 0x3a, /* KEY_CapsLock */
+ 0x3b, /* KEY_F1 */ 0x3c, /* KEY_F2 */
+ 0x3d, /* KEY_F3 */ 0x3e, /* KEY_F4 */
+ 0x3f, /* KEY_F5 */ 0x40, /* KEY_F6 */
+ 0x41, /* KEY_F7 */ 0x42, /* KEY_F8 */
+ 0x43, /* KEY_F9 */ 0x44, /* KEY_F10 */
+ 0x45, /* KEY_NumLock */ 0x46, /* KEY_ScrollLock */
+ 0x47, /* KEY_KP_7 */ 0x48, /* KEY_KP_8 */
+ 0x49, /* KEY_KP_9 */ 0x4a, /* KEY_KP_Minus */
+ 0x4b, /* KEY_KP_4 */ 0x4c, /* KEY_KP_5 */
+ 0x4d, /* KEY_KP_6 */ 0x4e, /* KEY_KP_Plus */
+ 0x4f, /* KEY_KP_1 */ 0x50, /* KEY_KP_2 */
+ 0x51, /* KEY_KP_3 */ 0x52, /* KEY_KP_0 */
+ 0x53, /* KEY_KP_Decimal */ 0x54, /* KEY_SysReqest */
+ 0x00, /* 0x55 */ 0x56, /* KEY_Less */
+ 0x57, /* KEY_F11 */ 0x58, /* KEY_F12 */
+ 0x66, /* KEY_Home */ 0x67, /* KEY_Up */
+ 0x68, /* KEY_PgUp */ 0x69, /* KEY_Left */
+ 0x5d, /* KEY_Begin */ 0x6a, /* KEY_Right */
+ 0x6b, /* KEY_End */ 0x6c, /* KEY_Down */
+ 0x6d, /* KEY_PgDown */ 0x6e, /* KEY_Insert */
+ 0x6f, /* KEY_Delete */ 0x60, /* KEY_KP_Enter */
+ 0x61, /* KEY_RCtrl */ 0x77, /* KEY_Pause */
+ 0x63, /* KEY_Print */ 0x62, /* KEY_KP_Divide */
+ 0x64, /* KEY_AltLang */ 0x65, /* KEY_Break */
+ 0x00, /* KEY_LMeta */ 0x00, /* KEY_RMeta */
+ 0x7A, /* KEY_Menu/FOCUS_PF11*/0x00, /* 0x6e */
+ 0x7B, /* FOCUS_PF12 */ 0x00, /* 0x70 */
+ 0x00, /* 0x71 */ 0x00, /* 0x72 */
+ 0x59, /* FOCUS_PF2 */ 0x78, /* FOCUS_PF9 */
+ 0x00, /* 0x75 */ 0x00, /* 0x76 */
+ 0x5A, /* FOCUS_PF3 */ 0x5B, /* FOCUS_PF4 */
+ 0x5C, /* FOCUS_PF5 */ 0x5D, /* FOCUS_PF6 */
+ 0x5E, /* FOCUS_PF7 */ 0x5F, /* FOCUS_PF8 */
+ 0x7C, /* JAP_86 */ 0x79, /* FOCUS_PF10 */
+ 0x00, /* 0x7f */
+};
+
+#define NUM_AT_KEYS (sizeof(at2lnx)/sizeof(at2lnx[0]))
+#define LNX_KEY_INDEX(n) n < NUM_AT_KEYS ? at2lnx[n] : 0
+
+static unsigned char tbl[KD_MAX_WIDTH] =
+{
+ 0,
+ 1 << KG_SHIFT,
+ (1 << KG_ALTGR),
+ (1 << KG_ALTGR) | (1 << KG_SHIFT)
+};
+#endif
+
+static void
+readKernelMapping(KdKeyboardInfo *ki)
+{
+#if 0
+ KeySym *k;
+ int i, j;
+ struct kbentry kbe;
+ int minKeyCode, maxKeyCode;
+ int row;
+ int fd;
+
+ if (!ki)
+ return;
+
+ fd = LinuxConsoleFd;
+
+ minKeyCode = NR_KEYS;
+ maxKeyCode = 0;
+ row = 0;
+ ki->keySyms.mapWidth = KD_MAX_WIDTH;
+ for (i = 0; i < NR_KEYS && row < KD_MAX_LENGTH; ++i)
+ {
+ kbe.kb_index = LNX_KEY_INDEX(i);
+
+ k = ki->keySyms.map + row * ki->keySyms.mapWidth;
+
+ for (j = 0; j < ki->keySyms.mapWidth; ++j)
+ {
+ unsigned short kval;
+
+ k[j] = NoSymbol;
+
+ kbe.kb_table = tbl[j];
+ kbe.kb_value = 0;
+ if (ioctl(fd, KDGKBENT, &kbe))
+ continue;
+
+ kval = KVAL(kbe.kb_value);
+ switch (KTYP(kbe.kb_value))
+ {
+ case KT_LATIN:
+ case KT_LETTER:
+ k[j] = linux_to_x[kval];
+ break;
+
+ case KT_FN:
+ if (kval <= 19)
+ k[j] = XK_F1 + kval;
+ else switch (kbe.kb_value)
+ {
+ case K_FIND:
+ k[j] = XK_Home; /* or XK_Find */
+ break;
+ case K_INSERT:
+ k[j] = XK_Insert;
+ break;
+ case K_REMOVE:
+ k[j] = XK_Delete;
+ break;
+ case K_SELECT:
+ k[j] = XK_End; /* or XK_Select */
+ break;
+ case K_PGUP:
+ k[j] = XK_Prior;
+ break;
+ case K_PGDN:
+ k[j] = XK_Next;
+ break;
+ case K_HELP:
+ k[j] = XK_Help;
+ break;
+ case K_DO:
+ k[j] = XK_Execute;
+ break;
+ case K_PAUSE:
+ k[j] = XK_Pause;
+ break;
+ case K_MACRO:
+ k[j] = XK_Menu;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case KT_SPEC:
+ switch (kbe.kb_value)
+ {
+ case K_ENTER:
+ k[j] = XK_Return;
+ break;
+ case K_BREAK:
+ k[j] = XK_Break;
+ break;
+ case K_CAPS:
+ k[j] = XK_Caps_Lock;
+ break;
+ case K_NUM:
+ k[j] = XK_Num_Lock;
+ break;
+ case K_HOLD:
+ k[j] = XK_Scroll_Lock;
+ break;
+ case K_COMPOSE:
+ k[j] = XK_Multi_key;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case KT_PAD:
+ switch (kbe.kb_value)
+ {
+ case K_PPLUS:
+ k[j] = XK_KP_Add;
+ break;
+ case K_PMINUS:
+ k[j] = XK_KP_Subtract;
+ break;
+ case K_PSTAR:
+ k[j] = XK_KP_Multiply;
+ break;
+ case K_PSLASH:
+ k[j] = XK_KP_Divide;
+ break;
+ case K_PENTER:
+ k[j] = XK_KP_Enter;
+ break;
+ case K_PCOMMA:
+ k[j] = XK_KP_Separator;
+ break;
+ case K_PDOT:
+ k[j] = XK_KP_Decimal;
+ break;
+ case K_PPLUSMINUS:
+ k[j] = XK_KP_Subtract;
+ break;
+ default:
+ if (kval <= 9)
+ k[j] = XK_KP_0 + kval;
+ break;
+ }
+ break;
+
+ /*
+ * KT_DEAD keys are for accelerated diacritical creation.
+ */
+ case KT_DEAD:
+ switch (kbe.kb_value)
+ {
+ case K_DGRAVE:
+ k[j] = XK_dead_grave;
+ break;
+ case K_DACUTE:
+ k[j] = XK_dead_acute;
+ break;
+ case K_DCIRCM:
+ k[j] = XK_dead_circumflex;
+ break;
+ case K_DTILDE:
+ k[j] = XK_dead_tilde;
+ break;
+ case K_DDIERE:
+ k[j] = XK_dead_diaeresis;
+ break;
+ }
+ break;
+
+ case KT_CUR:
+ switch (kbe.kb_value)
+ {
+ case K_DOWN:
+ k[j] = XK_Down;
+ break;
+ case K_LEFT:
+ k[j] = XK_Left;
+ break;
+ case K_RIGHT:
+ k[j] = XK_Right;
+ break;
+ case K_UP:
+ k[j] = XK_Up;
+ break;
+ }
+ break;
+
+ case KT_SHIFT:
+ switch (kbe.kb_value)
+ {
+ case K_ALTGR:
+ k[j] = XK_Mode_switch;
+ break;
+ case K_ALT:
+ k[j] = (kbe.kb_index == 0x64 ?
+ XK_Alt_R : XK_Alt_L);
+ break;
+ case K_CTRL:
+ k[j] = (kbe.kb_index == 0x61 ?
+ XK_Control_R : XK_Control_L);
+ break;
+ case K_CTRLL:
+ k[j] = XK_Control_L;
+ break;
+ case K_CTRLR:
+ k[j] = XK_Control_R;
+ break;
+ case K_SHIFT:
+ k[j] = (kbe.kb_index == 0x36 ?
+ XK_Shift_R : XK_Shift_L);
+ break;
+ case K_SHIFTL:
+ k[j] = XK_Shift_L;
+ break;
+ case K_SHIFTR:
+ k[j] = XK_Shift_R;
+ break;
+ default:
+ break;
+ }
+ break;
+
+ /*
+ * KT_ASCII keys accumulate a 3 digit decimal number that gets
+ * emitted when the shift state changes. We can't emulate that.
+ */
+ case KT_ASCII:
+ break;
+
+ case KT_LOCK:
+ if (kbe.kb_value == K_SHIFTLOCK)
+ k[j] = XK_Shift_Lock;
+ break;
+
+#ifdef KT_X
+ case KT_X:
+ /* depends on new keyboard symbols in file linux/keyboard.h */
+ if(kbe.kb_value == K_XMENU) k[j] = XK_Menu;
+ if(kbe.kb_value == K_XTELEPHONE) k[j] = XK_telephone;
+ break;
+#endif
+#ifdef KT_XF
+ case KT_XF:
+ /* special linux keysyms which map directly to XF86 keysyms */
+ k[j] = (kbe.kb_value & 0xFF) + 0x1008FF00;
+ break;
+#endif
+
+ default:
+ break;
+ }
+ if (i < minKeyCode)
+ minKeyCode = i;
+ if (i > maxKeyCode)
+ maxKeyCode = i;
+ }
+
+ if (minKeyCode == NR_KEYS)
+ continue;
+
+ if (k[3] == k[2]) k[3] = NoSymbol;
+ if (k[2] == k[1]) k[2] = NoSymbol;
+ if (k[1] == k[0]) k[1] = NoSymbol;
+ if (k[0] == k[2] && k[1] == k[3]) k[2] = k[3] = NoSymbol;
+ if (k[3] == k[0] && k[2] == k[1] && k[2] == NoSymbol) k[3] =NoSymbol;
+ row++;
+ }
+ ki->minScanCode = minKeyCode;
+ ki->maxScanCode = maxKeyCode;
+#endif
+}
+
+/*
+ * We need these to handle extended scancodes correctly (I could just use the
+ * numbers below, but this makes the code more readable
+ */
+
+/* The prefix codes */
+#define KEY_Prefix0 /* special 0x60 */ 96
+#define KEY_Prefix1 /* special 0x61 */ 97
+
+/* The raw scancodes */
+#define KEY_Enter /* Enter 0x1c */ 28
+#define KEY_LCtrl /* Ctrl(left) 0x1d */ 29
+#define KEY_Slash /* / (Slash) ? 0x35 */ 53
+#define KEY_KP_Multiply /* * 0x37 */ 55
+#define KEY_Alt /* Alt(left) 0x38 */ 56
+#define KEY_F3 /* F3 0x3d */ 61
+#define KEY_F4 /* F4 0x3e */ 62
+#define KEY_F5 /* F5 0x3f */ 63
+#define KEY_F6 /* F6 0x40 */ 64
+#define KEY_F7 /* F7 0x41 */ 65
+#define KEY_ScrollLock /* ScrollLock 0x46 */ 70
+#define KEY_KP_7 /* 7 Home 0x47 */ 71
+#define KEY_KP_8 /* 8 Up 0x48 */ 72
+#define KEY_KP_9 /* 9 PgUp 0x49 */ 73
+#define KEY_KP_Minus /* - (Minus) 0x4a */ 74
+#define KEY_KP_4 /* 4 Left 0x4b */ 75
+#define KEY_KP_5 /* 5 0x4c */ 76
+#define KEY_KP_6 /* 6 Right 0x4d */ 77
+#define KEY_KP_Plus /* + (Plus) 0x4e */ 78
+#define KEY_KP_1 /* 1 End 0x4f */ 79
+#define KEY_KP_2 /* 2 Down 0x50 */ 80
+#define KEY_KP_3 /* 3 PgDown 0x51 */ 81
+#define KEY_KP_0 /* 0 Insert 0x52 */ 82
+#define KEY_KP_Decimal /* . (Decimal) Delete 0x53 */ 83
+#define KEY_Home /* Home 0x59 */ 89
+#define KEY_Up /* Up 0x5a */ 90
+#define KEY_PgUp /* PgUp 0x5b */ 91
+#define KEY_Left /* Left 0x5c */ 92
+#define KEY_Begin /* Begin 0x5d */ 93
+#define KEY_Right /* Right 0x5e */ 94
+#define KEY_End /* End 0x5f */ 95
+#define KEY_Down /* Down 0x60 */ 96
+#define KEY_PgDown /* PgDown 0x61 */ 97
+#define KEY_Insert /* Insert 0x62 */ 98
+#define KEY_Delete /* Delete 0x63 */ 99
+#define KEY_KP_Enter /* Enter 0x64 */ 100
+#define KEY_RCtrl /* Ctrl(right) 0x65 */ 101
+#define KEY_Pause /* Pause 0x66 */ 102
+#define KEY_Print /* Print 0x67 */ 103
+#define KEY_KP_Divide /* Divide 0x68 */ 104
+#define KEY_AltLang /* AtlLang(right) 0x69 */ 105
+#define KEY_Break /* Break 0x6a */ 106
+#define KEY_LMeta /* Left Meta 0x6b */ 107
+#define KEY_RMeta /* Right Meta 0x6c */ 108
+#define KEY_Menu /* Menu 0x6d */ 109
+#define KEY_F13 /* F13 0x6e */ 110
+#define KEY_F14 /* F14 0x6f */ 111
+#define KEY_F15 /* F15 0x70 */ 112
+#define KEY_F16 /* F16 0x71 */ 113
+#define KEY_F17 /* F17 0x72 */ 114
+#define KEY_KP_DEC /* KP_DEC 0x73 */ 115
+
+static void
+LinuxKeyboardRead (int fd, void *closure)
+{
+ unsigned char buf[256], *b;
+ int n;
+ unsigned char prefix = 0, scancode = 0;
+
+ while ((n = read (fd, buf, sizeof (buf))) > 0) {
+ b = buf;
+ while (n--) {
+ /*
+ * With xkb we use RAW mode for reading the console, which allows us
+ * process extended scancodes.
+ *
+ * See if this is a prefix extending the following keycode
+ */
+ if (!prefix && ((b[0] & 0x7f) == KEY_Prefix0))
+ {
+ prefix = KEY_Prefix0;
+ /* swallow this up */
+ b++;
+ continue;
+ }
+ else if (!prefix && ((b[0] & 0x7f) == KEY_Prefix1))
+ {
+ prefix = KEY_Prefix1;
+ /* swallow this up */
+ b++;
+ continue;
+ }
+ scancode = b[0] & 0x7f;
+
+ switch (prefix) {
+ /* from xf86Events.c */
+ case KEY_Prefix0:
+ {
+ switch (scancode) {
+ case KEY_KP_7:
+ scancode = KEY_Home; break; /* curs home */
+ case KEY_KP_8:
+ scancode = KEY_Up; break; /* curs up */
+ case KEY_KP_9:
+ scancode = KEY_PgUp; break; /* curs pgup */
+ case KEY_KP_4:
+ scancode = KEY_Left; break; /* curs left */
+ case KEY_KP_5:
+ scancode = KEY_Begin; break; /* curs begin */
+ case KEY_KP_6:
+ scancode = KEY_Right; break; /* curs right */
+ case KEY_KP_1:
+ scancode = KEY_End; break; /* curs end */
+ case KEY_KP_2:
+ scancode = KEY_Down; break; /* curs down */
+ case KEY_KP_3:
+ scancode = KEY_PgDown; break; /* curs pgdown */
+ case KEY_KP_0:
+ scancode = KEY_Insert; break; /* curs insert */
+ case KEY_KP_Decimal:
+ scancode = KEY_Delete; break; /* curs delete */
+ case KEY_Enter:
+ scancode = KEY_KP_Enter; break; /* keypad enter */
+ case KEY_LCtrl:
+ scancode = KEY_RCtrl; break; /* right ctrl */
+ case KEY_KP_Multiply:
+ scancode = KEY_Print; break; /* print */
+ case KEY_Slash:
+ scancode = KEY_KP_Divide; break; /* keyp divide */
+ case KEY_Alt:
+ scancode = KEY_AltLang; break; /* right alt */
+ case KEY_ScrollLock:
+ scancode = KEY_Break; break; /* curs break */
+ case 0x5b:
+ scancode = KEY_LMeta; break;
+ case 0x5c:
+ scancode = KEY_RMeta; break;
+ case 0x5d:
+ scancode = KEY_Menu; break;
+ case KEY_F3:
+ scancode = KEY_F13; break;
+ case KEY_F4:
+ scancode = KEY_F14; break;
+ case KEY_F5:
+ scancode = KEY_F15; break;
+ case KEY_F6:
+ scancode = KEY_F16; break;
+ case KEY_F7:
+ scancode = KEY_F17; break;
+ case KEY_KP_Plus:
+ scancode = KEY_KP_DEC; break;
+ /* Ignore virtual shifts (E0 2A, E0 AA, E0 36, E0 B6) */
+ case 0x2A:
+ case 0x36:
+ b++;
+ prefix = 0;
+ continue;
+ default:
+ /*
+ * "Internet" keyboards are generating lots of new
+ * codes. Let them pass. There is little consistency
+ * between them, so don't bother with symbolic names at
+ * this level.
+ */
+ scancode += 0x78;
+ }
+ break;
+ }
+
+ case KEY_Prefix1:
+ {
+ /* we do no handle these */
+ b++;
+ prefix = 0;
+ continue;
+ }
+
+ default: /* should not happen*/
+ case 0: /* do nothing */
+ ;
+ }
+
+ prefix = 0;
+ KdEnqueueKeyboardEvent (closure, scancode, b[0] & 0x80);
+ b++;
+ }
+ }
+}
+
+static int LinuxKbdTrans;
+static struct termios LinuxTermios;
+
+static Status
+LinuxKeyboardEnable (KdKeyboardInfo *ki)
+{
+ struct termios nTty;
+ unsigned char buf[256];
+ int n;
+ int fd;
+
+ if (!ki)
+ return !Success;
+
+ fd = LinuxConsoleFd;
+ ki->driverPrivate = (void *) fd;
+
+ ioctl (fd, KDGKBMODE, &LinuxKbdTrans);
+ tcgetattr (fd, &LinuxTermios);
+ ioctl(fd, KDSKBMODE, K_RAW);
+ nTty = LinuxTermios;
+ nTty.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP);
+ nTty.c_oflag = 0;
+ nTty.c_cflag = CREAD | CS8;
+ nTty.c_lflag = 0;
+ nTty.c_cc[VTIME]=0;
+ nTty.c_cc[VMIN]=1;
+ cfsetispeed(&nTty, 9600);
+ cfsetospeed(&nTty, 9600);
+ tcsetattr(fd, TCSANOW, &nTty);
+ /*
+ * Flush any pending keystrokes
+ */
+ while ((n = read (fd, buf, sizeof (buf))) > 0)
+ ;
+ KdRegisterFd (fd, LinuxKeyboardRead, ki);
+ return Success;
+}
+
+static void
+LinuxKeyboardDisable (KdKeyboardInfo *ki)
+{
+ int fd;
+
+ if (!ki)
+ return;
+
+ fd = (int) ki->driverPrivate;
+
+ KdUnregisterFd(ki, fd, FALSE);
+ ioctl(fd, KDSKBMODE, LinuxKbdTrans);
+ tcsetattr(fd, TCSANOW, &LinuxTermios);
+}
+
+static Status
+LinuxKeyboardInit (KdKeyboardInfo *ki)
+{
+ if (!ki)
+ return !Success;
+
+ free(ki->path);
+ ki->path = strdup("console");
+ free(ki->name);
+ ki->name = strdup("Linux console keyboard");
+
+ readKernelMapping (ki);
+
+ return Success;
+}
+
+static void
+LinuxKeyboardLeds (KdKeyboardInfo *ki, int leds)
+{
+ if (!ki)
+ return;
+
+ ioctl ((int)ki->driverPrivate, KDSETLED, leds & 7);
+}
+
+KdKeyboardDriver LinuxKeyboardDriver = {
+ "keyboard",
+ .Init = LinuxKeyboardInit,
+ .Enable = LinuxKeyboardEnable,
+ .Leds = LinuxKeyboardLeds,
+ .Disable = LinuxKeyboardDisable,
+};
diff --git a/xorg-server/hw/kdrive/linux/mouse.c b/xorg-server/hw/kdrive/linux/mouse.c
index 007263e4b..2e39d240e 100644
--- a/xorg-server/hw/kdrive/linux/mouse.c
+++ b/xorg-server/hw/kdrive/linux/mouse.c
@@ -1,1030 +1,1030 @@
-/*
- * Copyright © 2001 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <kdrive-config.h>
-#endif
-#include <errno.h>
-#include <termios.h>
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include <X11/Xpoll.h>
-#include "inputstr.h"
-#include "scrnintstr.h"
-#include "kdrive.h"
-
-#undef DEBUG
-#undef DEBUG_BYTES
-#define KBUFIO_SIZE 256
-#define MOUSE_TIMEOUT 100
-
-typedef struct _kbufio {
- int fd;
- unsigned char buf[KBUFIO_SIZE];
- int avail;
- int used;
-} Kbufio;
-
-static Bool
-MouseWaitForReadable (int fd, int timeout)
-{
- fd_set set;
- struct timeval tv, *tp;
- int n;
- CARD32 done;
-
- done = GetTimeInMillis () + timeout;
- for (;;)
- {
- FD_ZERO (&set);
- FD_SET (fd, &set);
- if (timeout == -1)
- tp = 0;
- else
- {
- tv.tv_sec = timeout / 1000;
- tv.tv_usec = (timeout % 1000) * 1000;
- tp = &tv;
- }
- n = select (fd + 1, &set, 0, 0, tp);
- if (n > 0)
- return TRUE;
- if (n < 0 && (errno == EAGAIN || errno == EINTR))
- {
- timeout = (int) (done - GetTimeInMillis ());
- if (timeout > 0)
- continue;
- }
- break;
- }
- return FALSE;
-}
-
-static int
-MouseReadByte (Kbufio *b, int timeout)
-{
- int n;
- if (b->avail <= b->used)
- {
- if (timeout && !MouseWaitForReadable (b->fd, timeout))
- {
-#ifdef DEBUG_BYTES
- ErrorF ("\tTimeout %d\n", timeout);
-#endif
- return -1;
- }
- n = read (b->fd, b->buf, KBUFIO_SIZE);
- if (n <= 0)
- return -1;
- b->avail = n;
- b->used = 0;
- }
-#ifdef DEBUG_BYTES
- ErrorF ("\tget %02x\n", b->buf[b->used]);
-#endif
- return b->buf[b->used++];
-}
-
-#if NOTUSED
-static int
-MouseFlush (Kbufio *b, char *buf, int size)
-{
- CARD32 now = GetTimeInMillis ();
- CARD32 done = now + 100;
- int c;
- int n = 0;
-
- while ((c = MouseReadByte (b, done - now)) != -1)
- {
- if (buf)
- {
- if (n == size)
- {
- memmove (buf, buf + 1, size - 1);
- n--;
- }
- buf[n++] = c;
- }
- now = GetTimeInMillis ();
- if ((INT32) (now - done) >= 0)
- break;
- }
- return n;
-}
-
-static int
-MousePeekByte (Kbufio *b, int timeout)
-{
- int c;
-
- c = MouseReadByte (b, timeout);
- if (c != -1)
- --b->used;
- return c;
-}
-#endif /* NOTUSED */
-
-static Bool
-MouseWaitForWritable (int fd, int timeout)
-{
- fd_set set;
- struct timeval tv, *tp;
- int n;
-
- FD_ZERO (&set);
- FD_SET (fd, &set);
- if (timeout == -1)
- tp = 0;
- else
- {
- tv.tv_sec = timeout / 1000;
- tv.tv_usec = (timeout % 1000) * 1000;
- tp = &tv;
- }
- n = select (fd + 1, 0, &set, 0, tp);
- if (n > 0)
- return TRUE;
- return FALSE;
-}
-
-static Bool
-MouseWriteByte (int fd, unsigned char c, int timeout)
-{
- int ret;
-
-#ifdef DEBUG_BYTES
- ErrorF ("\tput %02x\n", c);
-#endif
- for (;;)
- {
- ret = write (fd, &c, 1);
- if (ret == 1)
- return TRUE;
- if (ret == 0)
- return FALSE;
- if (errno != EWOULDBLOCK)
- return FALSE;
- if (!MouseWaitForWritable (fd, timeout))
- return FALSE;
- }
-}
-
-static Bool
-MouseWriteBytes (int fd, unsigned char *c, int n, int timeout)
-{
- while (n--)
- if (!MouseWriteByte (fd, *c++, timeout))
- return FALSE;
- return TRUE;
-}
-
-#define MAX_MOUSE 10 /* maximum length of mouse protocol */
-#define MAX_SKIP 16 /* number of error bytes before switching */
-#define MAX_VALID 4 /* number of valid packets before accepting */
-
-typedef struct _kmouseProt {
- char *name;
- Bool (*Complete) (KdPointerInfo *pi, unsigned char *ev, int ne);
- int (*Valid) (KdPointerInfo *pi, unsigned char *ev, int ne);
- Bool (*Parse) (KdPointerInfo *pi, unsigned char *ev, int ne);
- Bool (*Init) (KdPointerInfo *pi);
- unsigned char headerMask, headerValid;
- unsigned char dataMask, dataValid;
- Bool tty;
- unsigned int c_iflag;
- unsigned int c_oflag;
- unsigned int c_lflag;
- unsigned int c_cflag;
- unsigned int speed;
- unsigned char *init;
- unsigned long state;
-} KmouseProt;
-
-typedef enum _kmouseStage {
- MouseBroken, MouseTesting, MouseWorking
-} KmouseStage;
-
-typedef struct _kmouse {
- Kbufio iob;
- const KmouseProt *prot;
- int i_prot;
- KmouseStage stage; /* protocol verification stage */
- Bool tty; /* mouse device is a tty */
- int valid; /* sequential valid events */
- int tested; /* bytes scanned during Testing phase */
- int invalid;/* total invalid bytes for this protocol */
- unsigned long state; /* private per protocol, init to prot->state */
-} Kmouse;
-
-static int mouseValid (KdPointerInfo *pi, unsigned char *ev, int ne)
-{
- Kmouse *km = pi->driverPrivate;
- const KmouseProt *prot = km->prot;
- int i;
-
- for (i = 0; i < ne; i++)
- if ((ev[i] & prot->headerMask) == prot->headerValid)
- break;
- if (i != 0)
- return i;
- for (i = 1; i < ne; i++)
- if ((ev[i] & prot->dataMask) != prot->dataValid)
- return -1;
- return 0;
-}
-
-static Bool threeComplete (KdPointerInfo *pi, unsigned char *ev, int ne)
-{
- return ne == 3;
-}
-
-static Bool fourComplete (KdPointerInfo *pi, unsigned char *ev, int ne)
-{
- return ne == 4;
-}
-
-static Bool fiveComplete (KdPointerInfo *pi, unsigned char *ev, int ne)
-{
- return ne == 5;
-}
-
-static Bool MouseReasonable (KdPointerInfo *pi, unsigned long flags, int dx, int dy)
-{
- Kmouse *km = pi->driverPrivate;
-
- if (km->stage == MouseWorking)
- return TRUE;
- if (dx < -50 || dx > 50)
- {
-#ifdef DEBUG
- ErrorF ("Large X %d\n", dx);
-#endif
- return FALSE;
- }
- if (dy < -50 || dy > 50)
- {
-#ifdef DEBUG
- ErrorF ("Large Y %d\n", dy);
-#endif
- return FALSE;
- }
- return TRUE;
-}
-
-/*
- * Standard PS/2 mouse protocol
- */
-static Bool ps2Parse (KdPointerInfo *pi, unsigned char *ev, int ne)
-{
- Kmouse *km = pi->driverPrivate;
- int dx, dy, dz;
- unsigned long flags;
- unsigned long flagsrelease = 0;
-
- flags = KD_MOUSE_DELTA;
- if (ev[0] & 4)
- flags |= KD_BUTTON_2;
- if (ev[0] & 2)
- flags |= KD_BUTTON_3;
- if (ev[0] & 1)
- flags |= KD_BUTTON_1;
-
- if (ne > 3)
- {
- dz = (int) (signed char) ev[3];
- if (dz < 0)
- {
- flags |= KD_BUTTON_4;
- flagsrelease = KD_BUTTON_4;
- }
- else if (dz > 0)
- {
- flags |= KD_BUTTON_5;
- flagsrelease = KD_BUTTON_5;
- }
- }
-
- dx = ev[1];
- if (ev[0] & 0x10)
- dx -= 256;
- dy = ev[2];
- if (ev[0] & 0x20)
- dy -= 256;
- dy = -dy;
- if (!MouseReasonable (pi, flags, dx, dy))
- return FALSE;
- if (km->stage == MouseWorking)
- {
- KdEnqueuePointerEvent (pi, flags, dx, dy, 0);
- if (flagsrelease)
- {
- flags &= ~flagsrelease;
- KdEnqueuePointerEvent (pi, flags, dx, dy, 0);
- }
- }
- return TRUE;
-}
-
-static Bool ps2Init (KdPointerInfo *pi);
-
-static const KmouseProt ps2Prot = {
- "ps/2",
- threeComplete, mouseValid, ps2Parse, ps2Init,
- 0x08, 0x08, 0x00, 0x00,
- FALSE
-};
-
-static const KmouseProt imps2Prot = {
- "imps/2",
- fourComplete, mouseValid, ps2Parse, ps2Init,
- 0x08, 0x08, 0x00, 0x00,
- FALSE
-};
-
-static const KmouseProt exps2Prot = {
- "exps/2",
- fourComplete, mouseValid, ps2Parse, ps2Init,
- 0x08, 0x08, 0x00, 0x00,
- FALSE
-};
-
-/*
- * Once the mouse is known to speak ps/2 protocol, go and find out
- * what advanced capabilities it has and turn them on
- */
-
-/* these extracted from FreeBSD 4.3 sys/dev/kbd/atkbdcreg.h */
-
-/* aux device commands (sent to KBD_DATA_PORT) */
-#define PSMC_SET_SCALING11 0x00e6
-#define PSMC_SET_SCALING21 0x00e7
-#define PSMC_SET_RESOLUTION 0x00e8
-#define PSMC_SEND_DEV_STATUS 0x00e9
-#define PSMC_SET_STREAM_MODE 0x00ea
-#define PSMC_SEND_DEV_DATA 0x00eb
-#define PSMC_SET_REMOTE_MODE 0x00f0
-#define PSMC_SEND_DEV_ID 0x00f2
-#define PSMC_SET_SAMPLING_RATE 0x00f3
-#define PSMC_ENABLE_DEV 0x00f4
-#define PSMC_DISABLE_DEV 0x00f5
-#define PSMC_SET_DEFAULTS 0x00f6
-#define PSMC_RESET_DEV 0x00ff
-
-/* PSMC_SET_RESOLUTION argument */
-#define PSMD_RES_LOW 0 /* typically 25ppi */
-#define PSMD_RES_MEDIUM_LOW 1 /* typically 50ppi */
-#define PSMD_RES_MEDIUM_HIGH 2 /* typically 100ppi (default) */
-#define PSMD_RES_HIGH 3 /* typically 200ppi */
-#define PSMD_MAX_RESOLUTION PSMD_RES_HIGH
-
-/* PSMC_SET_SAMPLING_RATE */
-#define PSMD_MAX_RATE 255 /* FIXME: not sure if it's possible */
-
-/* aux device ID */
-#define PSM_MOUSE_ID 0
-#define PSM_BALLPOINT_ID 2
-#define PSM_INTELLI_ID 3
-#define PSM_EXPLORER_ID 4
-#define PSM_4DMOUSE_ID 6
-#define PSM_4DPLUS_ID 8
-
-static unsigned char ps2_init[] = {
- PSMC_ENABLE_DEV,
- 0,
-};
-
-#define NINIT_PS2 1
-
-static unsigned char wheel_3button_init[] = {
- PSMC_SET_SAMPLING_RATE, 200,
- PSMC_SET_SAMPLING_RATE, 100,
- PSMC_SET_SAMPLING_RATE, 80,
- PSMC_SEND_DEV_ID,
- 0,
-};
-
-#define NINIT_IMPS2 4
-
-static unsigned char wheel_5button_init[] = {
- PSMC_SET_SAMPLING_RATE, 200,
- PSMC_SET_SAMPLING_RATE, 100,
- PSMC_SET_SAMPLING_RATE, 80,
- PSMC_SET_SAMPLING_RATE, 200,
- PSMC_SET_SAMPLING_RATE, 200,
- PSMC_SET_SAMPLING_RATE, 80,
- PSMC_SEND_DEV_ID,
- 0
-};
-
-#define NINIT_EXPS2 7
-
-static unsigned char intelli_init[] = {
- PSMC_SET_SAMPLING_RATE, 200,
- PSMC_SET_SAMPLING_RATE, 100,
- PSMC_SET_SAMPLING_RATE, 80,
- 0
-};
-
-#define NINIT_INTELLI 3
-
-static int
-ps2SkipInit (KdPointerInfo *pi, int ninit, Bool ret_next)
-{
- Kmouse *km = pi->driverPrivate;
- int c = -1;
- int skipping;
- Bool waiting;
-
- skipping = 0;
- waiting = FALSE;
- while (ninit || ret_next)
- {
- c = MouseReadByte (&km->iob, MOUSE_TIMEOUT);
- if (c == -1)
- break;
- /* look for ACK */
- if (c == 0xfa)
- {
- ninit--;
- if (ret_next)
- waiting = TRUE;
- }
- /* look for packet start -- not the response */
- else if ((c & 0x08) == 0x08)
- waiting = FALSE;
- else if (waiting)
- break;
- }
- return c;
-}
-
-static Bool
-ps2Init (KdPointerInfo *pi)
-{
- Kmouse *km = pi->driverPrivate;
- int skipping;
- Bool waiting;
- int id;
- unsigned char *init;
- int ninit;
-
- /* Send Intellimouse initialization sequence */
- MouseWriteBytes (km->iob.fd, intelli_init, strlen ((char *) intelli_init), 100);
- /*
- * Send ID command
- */
- if (!MouseWriteByte (km->iob.fd, PSMC_SEND_DEV_ID, 100))
- return FALSE;
- skipping = 0;
- waiting = FALSE;
- id = ps2SkipInit (pi, 0, TRUE);
- switch (id) {
- case 3:
- init = wheel_3button_init;
- ninit = NINIT_IMPS2;
- km->prot = &imps2Prot;
- break;
- case 4:
- init = wheel_5button_init;
- ninit = NINIT_EXPS2;
- km->prot = &exps2Prot;
- break;
- default:
- init = ps2_init;
- ninit = NINIT_PS2;
- km->prot = &ps2Prot;
- break;
- }
- if (init)
- MouseWriteBytes (km->iob.fd, init, strlen ((char *) init), 100);
- /*
- * Flush out the available data to eliminate responses to the
- * initialization string. Make sure any partial event is
- * skipped
- */
- (void) ps2SkipInit (pi, ninit, FALSE);
- return TRUE;
-}
-
-static Bool busParse (KdPointerInfo *pi, unsigned char *ev, int ne)
-{
- Kmouse *km = pi->driverPrivate;
- int dx, dy;
- unsigned long flags;
-
- flags = KD_MOUSE_DELTA;
- dx = (signed char) ev[1];
- dy = -(signed char) ev[2];
- if ((ev[0] & 4) == 0)
- flags |= KD_BUTTON_1;
- if ((ev[0] & 2) == 0)
- flags |= KD_BUTTON_2;
- if ((ev[0] & 1) == 0)
- flags |= KD_BUTTON_3;
- if (!MouseReasonable (pi, flags, dx, dy))
- return FALSE;
- if (km->stage == MouseWorking)
- KdEnqueuePointerEvent (pi, flags, dx, dy, 0);
- return TRUE;
-}
-
-static const KmouseProt busProt = {
- "bus",
- threeComplete, mouseValid, busParse, 0,
- 0xf8, 0x00, 0x00, 0x00,
- FALSE
-};
-
-/*
- * Standard MS serial protocol, three bytes
- */
-
-static Bool msParse (KdPointerInfo *pi, unsigned char *ev, int ne)
-{
- Kmouse *km = pi->driverPrivate;
- int dx, dy;
- unsigned long flags;
-
- flags = KD_MOUSE_DELTA;
-
- if (ev[0] & 0x20)
- flags |= KD_BUTTON_1;
- if (ev[0] & 0x10)
- flags |= KD_BUTTON_3;
-
- dx = (signed char)(((ev[0] & 0x03) << 6) | (ev[1] & 0x3F));
- dy = (signed char)(((ev[0] & 0x0C) << 4) | (ev[2] & 0x3F));
- if (!MouseReasonable (pi, flags, dx, dy))
- return FALSE;
- if (km->stage == MouseWorking)
- KdEnqueuePointerEvent (pi, flags, dx, dy, 0);
- return TRUE;
-}
-
-static const KmouseProt msProt = {
- "ms",
- threeComplete, mouseValid, msParse, 0,
- 0xc0, 0x40, 0xc0, 0x00,
- TRUE,
- IGNPAR,
- 0,
- 0,
- CS7 | CSTOPB | CREAD | CLOCAL,
- B1200,
-};
-
-/*
- * Logitech mice send 3 or 4 bytes, the only way to tell is to look at the
- * first byte of a synchronized protocol stream and see if it's got
- * any bits turned on that can't occur in that fourth byte
- */
-static Bool logiComplete (KdPointerInfo *pi, unsigned char *ev, int ne)
-{
- Kmouse *km = pi->driverPrivate;
-
- if ((ev[0] & 0x40) == 0x40)
- return ne == 3;
- if (km->stage != MouseBroken && (ev[0] & ~0x23) == 0)
- return ne == 1;
- return FALSE;
-}
-
-static int logiValid (KdPointerInfo *pi, unsigned char *ev, int ne)
-{
- Kmouse *km = pi->driverPrivate;
- const KmouseProt *prot = km->prot;
- int i;
-
- for (i = 0; i < ne; i++)
- {
- if ((ev[i] & 0x40) == 0x40)
- break;
- if (km->stage != MouseBroken && (ev[i] & ~0x23) == 0)
- break;
- }
- if (i != 0)
- return i;
- for (i = 1; i < ne; i++)
- if ((ev[i] & prot->dataMask) != prot->dataValid)
- return -1;
- return 0;
-}
-
-static Bool logiParse (KdPointerInfo *pi, unsigned char *ev, int ne)
-{
- Kmouse *km = pi->driverPrivate;
- int dx, dy;
- unsigned long flags;
-
- flags = KD_MOUSE_DELTA;
-
- if (ne == 3)
- {
- if (ev[0] & 0x20)
- flags |= KD_BUTTON_1;
- if (ev[0] & 0x10)
- flags |= KD_BUTTON_3;
-
- dx = (signed char)(((ev[0] & 0x03) << 6) | (ev[1] & 0x3F));
- dy = (signed char)(((ev[0] & 0x0C) << 4) | (ev[2] & 0x3F));
- flags |= km->state & KD_BUTTON_2;
- }
- else
- {
- if (ev[0] & 0x20)
- flags |= KD_BUTTON_2;
- dx = 0;
- dy = 0;
- flags |= km->state & (KD_BUTTON_1|KD_BUTTON_3);
- }
-
- if (!MouseReasonable (pi, flags, dx, dy))
- return FALSE;
- if (km->stage == MouseWorking)
- KdEnqueuePointerEvent (pi, flags, dx, dy, 0);
- return TRUE;
-}
-
-static const KmouseProt logiProt = {
- "logitech",
- logiComplete, logiValid, logiParse, 0,
- 0xc0, 0x40, 0xc0, 0x00,
- TRUE,
- IGNPAR,
- 0,
- 0,
- CS7 | CSTOPB | CREAD | CLOCAL,
- B1200,
-};
-
-/*
- * Mouse systems protocol, 5 bytes
- */
-static Bool mscParse (KdPointerInfo *pi, unsigned char *ev, int ne)
-{
- Kmouse *km = pi->driverPrivate;
- int dx, dy;
- unsigned long flags;
-
- flags = KD_MOUSE_DELTA;
-
- if (!(ev[0] & 0x4))
- flags |= KD_BUTTON_1;
- if (!(ev[0] & 0x2))
- flags |= KD_BUTTON_2;
- if (!(ev[0] & 0x1))
- flags |= KD_BUTTON_3;
- dx = (signed char)(ev[1]) + (signed char)(ev[3]);
- dy = - ((signed char)(ev[2]) + (signed char)(ev[4]));
-
- if (!MouseReasonable (pi, flags, dx, dy))
- return FALSE;
- if (km->stage == MouseWorking)
- KdEnqueuePointerEvent (pi, flags, dx, dy, 0);
- return TRUE;
-}
-
-static const KmouseProt mscProt = {
- "msc",
- fiveComplete, mouseValid, mscParse, 0,
- 0xf8, 0x80, 0x00, 0x00,
- TRUE,
- IGNPAR,
- 0,
- 0,
- CS8 | CSTOPB | CREAD | CLOCAL,
- B1200,
-};
-
-/*
- * Use logitech before ms -- they're the same except that
- * logitech sometimes has a fourth byte
- */
-static const KmouseProt *kmouseProts[] = {
- &ps2Prot, &imps2Prot, &exps2Prot, &busProt, &logiProt, &msProt, &mscProt,
-};
-
-#define NUM_PROT (sizeof (kmouseProts) / sizeof (kmouseProts[0]))
-
-static void
-MouseInitProtocol (Kmouse *km)
-{
- int ret;
- struct termios t;
-
- if (km->prot->tty)
- {
- ret = tcgetattr (km->iob.fd, &t);
-
- if (ret >= 0)
- {
- t.c_iflag = km->prot->c_iflag;
- t.c_oflag = km->prot->c_oflag;
- t.c_lflag = km->prot->c_lflag;
- t.c_cflag = km->prot->c_cflag;
- cfsetispeed (&t, km->prot->speed);
- cfsetospeed (&t, km->prot->speed);
- ret = tcsetattr (km->iob.fd, TCSANOW, &t);
- }
- }
- km->stage = MouseBroken;
- km->valid = 0;
- km->tested = 0;
- km->invalid = 0;
- km->state = km->prot->state;
-}
-
-static void
-MouseFirstProtocol (Kmouse *km, char *prot)
-{
- if (prot)
- {
- for (km->i_prot = 0; km->i_prot < NUM_PROT; km->i_prot++)
- if (!strcmp (prot, kmouseProts[km->i_prot]->name))
- break;
- if (km->i_prot == NUM_PROT)
- {
- int i;
- ErrorF ("Unknown mouse protocol \"%s\". Pick one of:", prot);
- for (i = 0; i < NUM_PROT; i++)
- ErrorF (" %s", kmouseProts[i]->name);
- ErrorF ("\n");
- }
- else
- {
- km->prot = kmouseProts[km->i_prot];
- if (km->tty && !km->prot->tty)
- ErrorF ("Mouse device is serial port, protocol %s is not serial protocol\n",
- prot);
- else if (!km->tty && km->prot->tty)
- ErrorF ("Mouse device is not serial port, protocol %s is serial protocol\n",
- prot);
- }
- }
- if (!km->prot)
- {
- for (km->i_prot = 0; kmouseProts[km->i_prot]->tty != km->tty; km->i_prot++)
- ;
- km->prot = kmouseProts[km->i_prot];
- }
- MouseInitProtocol (km);
-}
-
-static void
-MouseNextProtocol (Kmouse *km)
-{
- do
- {
- if (!km->prot)
- km->i_prot = 0;
- else
- if (++km->i_prot == NUM_PROT) km->i_prot = 0;
- km->prot = kmouseProts[km->i_prot];
- } while (km->prot->tty != km->tty);
- MouseInitProtocol (km);
- ErrorF ("Switching to mouse protocol \"%s\"\n", km->prot->name);
-}
-
-static void
-MouseRead (int mousePort, void *closure)
-{
- KdPointerInfo *pi = closure;
- Kmouse *km = pi->driverPrivate;
- unsigned char event[MAX_MOUSE];
- int ne;
- int c;
- int i;
- int timeout;
-
- timeout = 0;
- ne = 0;
- for(;;)
- {
- c = MouseReadByte (&km->iob, timeout);
- if (c == -1)
- {
- if (ne)
- {
- km->invalid += ne + km->tested;
- km->valid = 0;
- km->tested = 0;
- km->stage = MouseBroken;
- }
- break;
- }
- event[ne++] = c;
- i = (*km->prot->Valid) (pi, event, ne);
- if (i != 0)
- {
-#ifdef DEBUG
- ErrorF ("Mouse protocol %s broken %d of %d bytes bad\n",
- km->prot->name, i > 0 ? i : ne, ne);
-#endif
- if (i > 0 && i < ne)
- {
- ne -= i;
- memmove (event, event + i, ne);
- }
- else
- {
- i = ne;
- ne = 0;
- }
- km->invalid += i + km->tested;
- km->valid = 0;
- km->tested = 0;
- if (km->stage == MouseWorking)
- km->i_prot--;
- km->stage = MouseBroken;
- if (km->invalid > MAX_SKIP)
- {
- MouseNextProtocol (km);
- ne = 0;
- }
- timeout = 0;
- }
- else
- {
- if ((*km->prot->Complete) (pi, event, ne))
- {
- if ((*km->prot->Parse) (pi, event, ne))
- {
- switch (km->stage)
- {
- case MouseBroken:
-#ifdef DEBUG
- ErrorF ("Mouse protocol %s seems OK\n",
- km->prot->name);
-#endif
- /* do not zero invalid to accumulate invalid bytes */
- km->valid = 0;
- km->tested = 0;
- km->stage = MouseTesting;
- /* fall through ... */
- case MouseTesting:
- km->valid++;
- km->tested += ne;
- if (km->valid > MAX_VALID)
- {
-#ifdef DEBUG
- ErrorF ("Mouse protocol %s working\n",
- km->prot->name);
-#endif
- km->stage = MouseWorking;
- km->invalid = 0;
- km->tested = 0;
- km->valid = 0;
- if (km->prot->Init && !(*km->prot->Init) (pi))
- km->stage = MouseBroken;
- }
- break;
- case MouseWorking:
- break;
- }
- }
- else
- {
- km->invalid += ne + km->tested;
- km->valid = 0;
- km->tested = 0;
- km->stage = MouseBroken;
- }
- ne = 0;
- timeout = 0;
- }
- else
- timeout = MOUSE_TIMEOUT;
- }
- }
-}
-
-int MouseInputType;
-
-char *kdefaultMouse[] = {
- "/dev/input/mice",
- "/dev/mouse",
- "/dev/psaux",
- "/dev/adbmouse",
- "/dev/ttyS0",
- "/dev/ttyS1",
-};
-
-#define NUM_DEFAULT_MOUSE (sizeof (kdefaultMouse) / sizeof (kdefaultMouse[0]))
-
-static Status
-MouseInit (KdPointerInfo *pi)
-{
- int i;
- int fd;
- Kmouse *km;
-
- if (!pi)
- return BadImplementation;
-
- if (!pi->path || strcmp(pi->path, "auto") == 0) {
- for (i = 0; i < NUM_DEFAULT_MOUSE; i++) {
- fd = open (kdefaultMouse[i], 2);
- if (fd >= 0) {
- pi->path = strdup (kdefaultMouse[i]);
- break;
- }
- }
- }
- else {
- fd = open (pi->path, 2);
- }
-
- if (fd < 0)
- return BadMatch;
-
- close(fd);
-
- km = (Kmouse *) xalloc (sizeof (Kmouse));
- if (km) {
- km->iob.avail = km->iob.used = 0;
- MouseFirstProtocol(km, pi->protocol ? pi->protocol : "exps/2");
- /* MouseFirstProtocol sets state to MouseBroken for later protocol
- * checks. Skip these checks if a protocol was supplied */
- if (pi->protocol)
- km->state = MouseWorking;
- km->i_prot = 0;
- km->tty = isatty (fd);
- km->iob.fd = -1;
- pi->driverPrivate = km;
- }
- else {
- close (fd);
- return BadAlloc;
- }
-
- return Success;
-}
-
-static Status
-MouseEnable (KdPointerInfo *pi)
-{
- Kmouse *km;
-
- if (!pi || !pi->driverPrivate || !pi->path)
- return BadImplementation;
-
- km = pi->driverPrivate;
-
- km->iob.fd = open(pi->path, 2);
- if (km->iob.fd < 0)
- return BadMatch;
-
- if (!KdRegisterFd (km->iob.fd, MouseRead, pi))
- {
- close(km->iob.fd);
- return BadAlloc;
- }
-
- return Success;
-}
-
-static void
-MouseDisable (KdPointerInfo *pi)
-{
- Kmouse *km;
- if (!pi || !pi->driverPrivate)
- return;
-
- km = pi->driverPrivate;
- KdUnregisterFd (pi, km->iob.fd, TRUE);
-}
-
-static void
-MouseFini (KdPointerInfo *pi)
-{
- xfree (pi->driverPrivate);
- pi->driverPrivate = NULL;
-}
-
-KdPointerDriver LinuxMouseDriver = {
- "mouse",
- MouseInit,
- MouseEnable,
- MouseDisable,
- MouseFini,
- NULL,
-};
+/*
+ * Copyright © 2001 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+#include <errno.h>
+#include <termios.h>
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/Xpoll.h>
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "kdrive.h"
+
+#undef DEBUG
+#undef DEBUG_BYTES
+#define KBUFIO_SIZE 256
+#define MOUSE_TIMEOUT 100
+
+typedef struct _kbufio {
+ int fd;
+ unsigned char buf[KBUFIO_SIZE];
+ int avail;
+ int used;
+} Kbufio;
+
+static Bool
+MouseWaitForReadable (int fd, int timeout)
+{
+ fd_set set;
+ struct timeval tv, *tp;
+ int n;
+ CARD32 done;
+
+ done = GetTimeInMillis () + timeout;
+ for (;;)
+ {
+ FD_ZERO (&set);
+ FD_SET (fd, &set);
+ if (timeout == -1)
+ tp = 0;
+ else
+ {
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout % 1000) * 1000;
+ tp = &tv;
+ }
+ n = select (fd + 1, &set, 0, 0, tp);
+ if (n > 0)
+ return TRUE;
+ if (n < 0 && (errno == EAGAIN || errno == EINTR))
+ {
+ timeout = (int) (done - GetTimeInMillis ());
+ if (timeout > 0)
+ continue;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+static int
+MouseReadByte (Kbufio *b, int timeout)
+{
+ int n;
+ if (b->avail <= b->used)
+ {
+ if (timeout && !MouseWaitForReadable (b->fd, timeout))
+ {
+#ifdef DEBUG_BYTES
+ ErrorF ("\tTimeout %d\n", timeout);
+#endif
+ return -1;
+ }
+ n = read (b->fd, b->buf, KBUFIO_SIZE);
+ if (n <= 0)
+ return -1;
+ b->avail = n;
+ b->used = 0;
+ }
+#ifdef DEBUG_BYTES
+ ErrorF ("\tget %02x\n", b->buf[b->used]);
+#endif
+ return b->buf[b->used++];
+}
+
+#if NOTUSED
+static int
+MouseFlush (Kbufio *b, char *buf, int size)
+{
+ CARD32 now = GetTimeInMillis ();
+ CARD32 done = now + 100;
+ int c;
+ int n = 0;
+
+ while ((c = MouseReadByte (b, done - now)) != -1)
+ {
+ if (buf)
+ {
+ if (n == size)
+ {
+ memmove (buf, buf + 1, size - 1);
+ n--;
+ }
+ buf[n++] = c;
+ }
+ now = GetTimeInMillis ();
+ if ((INT32) (now - done) >= 0)
+ break;
+ }
+ return n;
+}
+
+static int
+MousePeekByte (Kbufio *b, int timeout)
+{
+ int c;
+
+ c = MouseReadByte (b, timeout);
+ if (c != -1)
+ --b->used;
+ return c;
+}
+#endif /* NOTUSED */
+
+static Bool
+MouseWaitForWritable (int fd, int timeout)
+{
+ fd_set set;
+ struct timeval tv, *tp;
+ int n;
+
+ FD_ZERO (&set);
+ FD_SET (fd, &set);
+ if (timeout == -1)
+ tp = 0;
+ else
+ {
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout % 1000) * 1000;
+ tp = &tv;
+ }
+ n = select (fd + 1, 0, &set, 0, tp);
+ if (n > 0)
+ return TRUE;
+ return FALSE;
+}
+
+static Bool
+MouseWriteByte (int fd, unsigned char c, int timeout)
+{
+ int ret;
+
+#ifdef DEBUG_BYTES
+ ErrorF ("\tput %02x\n", c);
+#endif
+ for (;;)
+ {
+ ret = write (fd, &c, 1);
+ if (ret == 1)
+ return TRUE;
+ if (ret == 0)
+ return FALSE;
+ if (errno != EWOULDBLOCK)
+ return FALSE;
+ if (!MouseWaitForWritable (fd, timeout))
+ return FALSE;
+ }
+}
+
+static Bool
+MouseWriteBytes (int fd, unsigned char *c, int n, int timeout)
+{
+ while (n--)
+ if (!MouseWriteByte (fd, *c++, timeout))
+ return FALSE;
+ return TRUE;
+}
+
+#define MAX_MOUSE 10 /* maximum length of mouse protocol */
+#define MAX_SKIP 16 /* number of error bytes before switching */
+#define MAX_VALID 4 /* number of valid packets before accepting */
+
+typedef struct _kmouseProt {
+ char *name;
+ Bool (*Complete) (KdPointerInfo *pi, unsigned char *ev, int ne);
+ int (*Valid) (KdPointerInfo *pi, unsigned char *ev, int ne);
+ Bool (*Parse) (KdPointerInfo *pi, unsigned char *ev, int ne);
+ Bool (*Init) (KdPointerInfo *pi);
+ unsigned char headerMask, headerValid;
+ unsigned char dataMask, dataValid;
+ Bool tty;
+ unsigned int c_iflag;
+ unsigned int c_oflag;
+ unsigned int c_lflag;
+ unsigned int c_cflag;
+ unsigned int speed;
+ unsigned char *init;
+ unsigned long state;
+} KmouseProt;
+
+typedef enum _kmouseStage {
+ MouseBroken, MouseTesting, MouseWorking
+} KmouseStage;
+
+typedef struct _kmouse {
+ Kbufio iob;
+ const KmouseProt *prot;
+ int i_prot;
+ KmouseStage stage; /* protocol verification stage */
+ Bool tty; /* mouse device is a tty */
+ int valid; /* sequential valid events */
+ int tested; /* bytes scanned during Testing phase */
+ int invalid;/* total invalid bytes for this protocol */
+ unsigned long state; /* private per protocol, init to prot->state */
+} Kmouse;
+
+static int mouseValid (KdPointerInfo *pi, unsigned char *ev, int ne)
+{
+ Kmouse *km = pi->driverPrivate;
+ const KmouseProt *prot = km->prot;
+ int i;
+
+ for (i = 0; i < ne; i++)
+ if ((ev[i] & prot->headerMask) == prot->headerValid)
+ break;
+ if (i != 0)
+ return i;
+ for (i = 1; i < ne; i++)
+ if ((ev[i] & prot->dataMask) != prot->dataValid)
+ return -1;
+ return 0;
+}
+
+static Bool threeComplete (KdPointerInfo *pi, unsigned char *ev, int ne)
+{
+ return ne == 3;
+}
+
+static Bool fourComplete (KdPointerInfo *pi, unsigned char *ev, int ne)
+{
+ return ne == 4;
+}
+
+static Bool fiveComplete (KdPointerInfo *pi, unsigned char *ev, int ne)
+{
+ return ne == 5;
+}
+
+static Bool MouseReasonable (KdPointerInfo *pi, unsigned long flags, int dx, int dy)
+{
+ Kmouse *km = pi->driverPrivate;
+
+ if (km->stage == MouseWorking)
+ return TRUE;
+ if (dx < -50 || dx > 50)
+ {
+#ifdef DEBUG
+ ErrorF ("Large X %d\n", dx);
+#endif
+ return FALSE;
+ }
+ if (dy < -50 || dy > 50)
+ {
+#ifdef DEBUG
+ ErrorF ("Large Y %d\n", dy);
+#endif
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*
+ * Standard PS/2 mouse protocol
+ */
+static Bool ps2Parse (KdPointerInfo *pi, unsigned char *ev, int ne)
+{
+ Kmouse *km = pi->driverPrivate;
+ int dx, dy, dz;
+ unsigned long flags;
+ unsigned long flagsrelease = 0;
+
+ flags = KD_MOUSE_DELTA;
+ if (ev[0] & 4)
+ flags |= KD_BUTTON_2;
+ if (ev[0] & 2)
+ flags |= KD_BUTTON_3;
+ if (ev[0] & 1)
+ flags |= KD_BUTTON_1;
+
+ if (ne > 3)
+ {
+ dz = (int) (signed char) ev[3];
+ if (dz < 0)
+ {
+ flags |= KD_BUTTON_4;
+ flagsrelease = KD_BUTTON_4;
+ }
+ else if (dz > 0)
+ {
+ flags |= KD_BUTTON_5;
+ flagsrelease = KD_BUTTON_5;
+ }
+ }
+
+ dx = ev[1];
+ if (ev[0] & 0x10)
+ dx -= 256;
+ dy = ev[2];
+ if (ev[0] & 0x20)
+ dy -= 256;
+ dy = -dy;
+ if (!MouseReasonable (pi, flags, dx, dy))
+ return FALSE;
+ if (km->stage == MouseWorking)
+ {
+ KdEnqueuePointerEvent (pi, flags, dx, dy, 0);
+ if (flagsrelease)
+ {
+ flags &= ~flagsrelease;
+ KdEnqueuePointerEvent (pi, flags, dx, dy, 0);
+ }
+ }
+ return TRUE;
+}
+
+static Bool ps2Init (KdPointerInfo *pi);
+
+static const KmouseProt ps2Prot = {
+ "ps/2",
+ threeComplete, mouseValid, ps2Parse, ps2Init,
+ 0x08, 0x08, 0x00, 0x00,
+ FALSE
+};
+
+static const KmouseProt imps2Prot = {
+ "imps/2",
+ fourComplete, mouseValid, ps2Parse, ps2Init,
+ 0x08, 0x08, 0x00, 0x00,
+ FALSE
+};
+
+static const KmouseProt exps2Prot = {
+ "exps/2",
+ fourComplete, mouseValid, ps2Parse, ps2Init,
+ 0x08, 0x08, 0x00, 0x00,
+ FALSE
+};
+
+/*
+ * Once the mouse is known to speak ps/2 protocol, go and find out
+ * what advanced capabilities it has and turn them on
+ */
+
+/* these extracted from FreeBSD 4.3 sys/dev/kbd/atkbdcreg.h */
+
+/* aux device commands (sent to KBD_DATA_PORT) */
+#define PSMC_SET_SCALING11 0x00e6
+#define PSMC_SET_SCALING21 0x00e7
+#define PSMC_SET_RESOLUTION 0x00e8
+#define PSMC_SEND_DEV_STATUS 0x00e9
+#define PSMC_SET_STREAM_MODE 0x00ea
+#define PSMC_SEND_DEV_DATA 0x00eb
+#define PSMC_SET_REMOTE_MODE 0x00f0
+#define PSMC_SEND_DEV_ID 0x00f2
+#define PSMC_SET_SAMPLING_RATE 0x00f3
+#define PSMC_ENABLE_DEV 0x00f4
+#define PSMC_DISABLE_DEV 0x00f5
+#define PSMC_SET_DEFAULTS 0x00f6
+#define PSMC_RESET_DEV 0x00ff
+
+/* PSMC_SET_RESOLUTION argument */
+#define PSMD_RES_LOW 0 /* typically 25ppi */
+#define PSMD_RES_MEDIUM_LOW 1 /* typically 50ppi */
+#define PSMD_RES_MEDIUM_HIGH 2 /* typically 100ppi (default) */
+#define PSMD_RES_HIGH 3 /* typically 200ppi */
+#define PSMD_MAX_RESOLUTION PSMD_RES_HIGH
+
+/* PSMC_SET_SAMPLING_RATE */
+#define PSMD_MAX_RATE 255 /* FIXME: not sure if it's possible */
+
+/* aux device ID */
+#define PSM_MOUSE_ID 0
+#define PSM_BALLPOINT_ID 2
+#define PSM_INTELLI_ID 3
+#define PSM_EXPLORER_ID 4
+#define PSM_4DMOUSE_ID 6
+#define PSM_4DPLUS_ID 8
+
+static unsigned char ps2_init[] = {
+ PSMC_ENABLE_DEV,
+ 0,
+};
+
+#define NINIT_PS2 1
+
+static unsigned char wheel_3button_init[] = {
+ PSMC_SET_SAMPLING_RATE, 200,
+ PSMC_SET_SAMPLING_RATE, 100,
+ PSMC_SET_SAMPLING_RATE, 80,
+ PSMC_SEND_DEV_ID,
+ 0,
+};
+
+#define NINIT_IMPS2 4
+
+static unsigned char wheel_5button_init[] = {
+ PSMC_SET_SAMPLING_RATE, 200,
+ PSMC_SET_SAMPLING_RATE, 100,
+ PSMC_SET_SAMPLING_RATE, 80,
+ PSMC_SET_SAMPLING_RATE, 200,
+ PSMC_SET_SAMPLING_RATE, 200,
+ PSMC_SET_SAMPLING_RATE, 80,
+ PSMC_SEND_DEV_ID,
+ 0
+};
+
+#define NINIT_EXPS2 7
+
+static unsigned char intelli_init[] = {
+ PSMC_SET_SAMPLING_RATE, 200,
+ PSMC_SET_SAMPLING_RATE, 100,
+ PSMC_SET_SAMPLING_RATE, 80,
+ 0
+};
+
+#define NINIT_INTELLI 3
+
+static int
+ps2SkipInit (KdPointerInfo *pi, int ninit, Bool ret_next)
+{
+ Kmouse *km = pi->driverPrivate;
+ int c = -1;
+ int skipping;
+ Bool waiting;
+
+ skipping = 0;
+ waiting = FALSE;
+ while (ninit || ret_next)
+ {
+ c = MouseReadByte (&km->iob, MOUSE_TIMEOUT);
+ if (c == -1)
+ break;
+ /* look for ACK */
+ if (c == 0xfa)
+ {
+ ninit--;
+ if (ret_next)
+ waiting = TRUE;
+ }
+ /* look for packet start -- not the response */
+ else if ((c & 0x08) == 0x08)
+ waiting = FALSE;
+ else if (waiting)
+ break;
+ }
+ return c;
+}
+
+static Bool
+ps2Init (KdPointerInfo *pi)
+{
+ Kmouse *km = pi->driverPrivate;
+ int skipping;
+ Bool waiting;
+ int id;
+ unsigned char *init;
+ int ninit;
+
+ /* Send Intellimouse initialization sequence */
+ MouseWriteBytes (km->iob.fd, intelli_init, strlen ((char *) intelli_init), 100);
+ /*
+ * Send ID command
+ */
+ if (!MouseWriteByte (km->iob.fd, PSMC_SEND_DEV_ID, 100))
+ return FALSE;
+ skipping = 0;
+ waiting = FALSE;
+ id = ps2SkipInit (pi, 0, TRUE);
+ switch (id) {
+ case 3:
+ init = wheel_3button_init;
+ ninit = NINIT_IMPS2;
+ km->prot = &imps2Prot;
+ break;
+ case 4:
+ init = wheel_5button_init;
+ ninit = NINIT_EXPS2;
+ km->prot = &exps2Prot;
+ break;
+ default:
+ init = ps2_init;
+ ninit = NINIT_PS2;
+ km->prot = &ps2Prot;
+ break;
+ }
+ if (init)
+ MouseWriteBytes (km->iob.fd, init, strlen ((char *) init), 100);
+ /*
+ * Flush out the available data to eliminate responses to the
+ * initialization string. Make sure any partial event is
+ * skipped
+ */
+ (void) ps2SkipInit (pi, ninit, FALSE);
+ return TRUE;
+}
+
+static Bool busParse (KdPointerInfo *pi, unsigned char *ev, int ne)
+{
+ Kmouse *km = pi->driverPrivate;
+ int dx, dy;
+ unsigned long flags;
+
+ flags = KD_MOUSE_DELTA;
+ dx = (signed char) ev[1];
+ dy = -(signed char) ev[2];
+ if ((ev[0] & 4) == 0)
+ flags |= KD_BUTTON_1;
+ if ((ev[0] & 2) == 0)
+ flags |= KD_BUTTON_2;
+ if ((ev[0] & 1) == 0)
+ flags |= KD_BUTTON_3;
+ if (!MouseReasonable (pi, flags, dx, dy))
+ return FALSE;
+ if (km->stage == MouseWorking)
+ KdEnqueuePointerEvent (pi, flags, dx, dy, 0);
+ return TRUE;
+}
+
+static const KmouseProt busProt = {
+ "bus",
+ threeComplete, mouseValid, busParse, 0,
+ 0xf8, 0x00, 0x00, 0x00,
+ FALSE
+};
+
+/*
+ * Standard MS serial protocol, three bytes
+ */
+
+static Bool msParse (KdPointerInfo *pi, unsigned char *ev, int ne)
+{
+ Kmouse *km = pi->driverPrivate;
+ int dx, dy;
+ unsigned long flags;
+
+ flags = KD_MOUSE_DELTA;
+
+ if (ev[0] & 0x20)
+ flags |= KD_BUTTON_1;
+ if (ev[0] & 0x10)
+ flags |= KD_BUTTON_3;
+
+ dx = (signed char)(((ev[0] & 0x03) << 6) | (ev[1] & 0x3F));
+ dy = (signed char)(((ev[0] & 0x0C) << 4) | (ev[2] & 0x3F));
+ if (!MouseReasonable (pi, flags, dx, dy))
+ return FALSE;
+ if (km->stage == MouseWorking)
+ KdEnqueuePointerEvent (pi, flags, dx, dy, 0);
+ return TRUE;
+}
+
+static const KmouseProt msProt = {
+ "ms",
+ threeComplete, mouseValid, msParse, 0,
+ 0xc0, 0x40, 0xc0, 0x00,
+ TRUE,
+ IGNPAR,
+ 0,
+ 0,
+ CS7 | CSTOPB | CREAD | CLOCAL,
+ B1200,
+};
+
+/*
+ * Logitech mice send 3 or 4 bytes, the only way to tell is to look at the
+ * first byte of a synchronized protocol stream and see if it's got
+ * any bits turned on that can't occur in that fourth byte
+ */
+static Bool logiComplete (KdPointerInfo *pi, unsigned char *ev, int ne)
+{
+ Kmouse *km = pi->driverPrivate;
+
+ if ((ev[0] & 0x40) == 0x40)
+ return ne == 3;
+ if (km->stage != MouseBroken && (ev[0] & ~0x23) == 0)
+ return ne == 1;
+ return FALSE;
+}
+
+static int logiValid (KdPointerInfo *pi, unsigned char *ev, int ne)
+{
+ Kmouse *km = pi->driverPrivate;
+ const KmouseProt *prot = km->prot;
+ int i;
+
+ for (i = 0; i < ne; i++)
+ {
+ if ((ev[i] & 0x40) == 0x40)
+ break;
+ if (km->stage != MouseBroken && (ev[i] & ~0x23) == 0)
+ break;
+ }
+ if (i != 0)
+ return i;
+ for (i = 1; i < ne; i++)
+ if ((ev[i] & prot->dataMask) != prot->dataValid)
+ return -1;
+ return 0;
+}
+
+static Bool logiParse (KdPointerInfo *pi, unsigned char *ev, int ne)
+{
+ Kmouse *km = pi->driverPrivate;
+ int dx, dy;
+ unsigned long flags;
+
+ flags = KD_MOUSE_DELTA;
+
+ if (ne == 3)
+ {
+ if (ev[0] & 0x20)
+ flags |= KD_BUTTON_1;
+ if (ev[0] & 0x10)
+ flags |= KD_BUTTON_3;
+
+ dx = (signed char)(((ev[0] & 0x03) << 6) | (ev[1] & 0x3F));
+ dy = (signed char)(((ev[0] & 0x0C) << 4) | (ev[2] & 0x3F));
+ flags |= km->state & KD_BUTTON_2;
+ }
+ else
+ {
+ if (ev[0] & 0x20)
+ flags |= KD_BUTTON_2;
+ dx = 0;
+ dy = 0;
+ flags |= km->state & (KD_BUTTON_1|KD_BUTTON_3);
+ }
+
+ if (!MouseReasonable (pi, flags, dx, dy))
+ return FALSE;
+ if (km->stage == MouseWorking)
+ KdEnqueuePointerEvent (pi, flags, dx, dy, 0);
+ return TRUE;
+}
+
+static const KmouseProt logiProt = {
+ "logitech",
+ logiComplete, logiValid, logiParse, 0,
+ 0xc0, 0x40, 0xc0, 0x00,
+ TRUE,
+ IGNPAR,
+ 0,
+ 0,
+ CS7 | CSTOPB | CREAD | CLOCAL,
+ B1200,
+};
+
+/*
+ * Mouse systems protocol, 5 bytes
+ */
+static Bool mscParse (KdPointerInfo *pi, unsigned char *ev, int ne)
+{
+ Kmouse *km = pi->driverPrivate;
+ int dx, dy;
+ unsigned long flags;
+
+ flags = KD_MOUSE_DELTA;
+
+ if (!(ev[0] & 0x4))
+ flags |= KD_BUTTON_1;
+ if (!(ev[0] & 0x2))
+ flags |= KD_BUTTON_2;
+ if (!(ev[0] & 0x1))
+ flags |= KD_BUTTON_3;
+ dx = (signed char)(ev[1]) + (signed char)(ev[3]);
+ dy = - ((signed char)(ev[2]) + (signed char)(ev[4]));
+
+ if (!MouseReasonable (pi, flags, dx, dy))
+ return FALSE;
+ if (km->stage == MouseWorking)
+ KdEnqueuePointerEvent (pi, flags, dx, dy, 0);
+ return TRUE;
+}
+
+static const KmouseProt mscProt = {
+ "msc",
+ fiveComplete, mouseValid, mscParse, 0,
+ 0xf8, 0x80, 0x00, 0x00,
+ TRUE,
+ IGNPAR,
+ 0,
+ 0,
+ CS8 | CSTOPB | CREAD | CLOCAL,
+ B1200,
+};
+
+/*
+ * Use logitech before ms -- they're the same except that
+ * logitech sometimes has a fourth byte
+ */
+static const KmouseProt *kmouseProts[] = {
+ &ps2Prot, &imps2Prot, &exps2Prot, &busProt, &logiProt, &msProt, &mscProt,
+};
+
+#define NUM_PROT (sizeof (kmouseProts) / sizeof (kmouseProts[0]))
+
+static void
+MouseInitProtocol (Kmouse *km)
+{
+ int ret;
+ struct termios t;
+
+ if (km->prot->tty)
+ {
+ ret = tcgetattr (km->iob.fd, &t);
+
+ if (ret >= 0)
+ {
+ t.c_iflag = km->prot->c_iflag;
+ t.c_oflag = km->prot->c_oflag;
+ t.c_lflag = km->prot->c_lflag;
+ t.c_cflag = km->prot->c_cflag;
+ cfsetispeed (&t, km->prot->speed);
+ cfsetospeed (&t, km->prot->speed);
+ ret = tcsetattr (km->iob.fd, TCSANOW, &t);
+ }
+ }
+ km->stage = MouseBroken;
+ km->valid = 0;
+ km->tested = 0;
+ km->invalid = 0;
+ km->state = km->prot->state;
+}
+
+static void
+MouseFirstProtocol (Kmouse *km, char *prot)
+{
+ if (prot)
+ {
+ for (km->i_prot = 0; km->i_prot < NUM_PROT; km->i_prot++)
+ if (!strcmp (prot, kmouseProts[km->i_prot]->name))
+ break;
+ if (km->i_prot == NUM_PROT)
+ {
+ int i;
+ ErrorF ("Unknown mouse protocol \"%s\". Pick one of:", prot);
+ for (i = 0; i < NUM_PROT; i++)
+ ErrorF (" %s", kmouseProts[i]->name);
+ ErrorF ("\n");
+ }
+ else
+ {
+ km->prot = kmouseProts[km->i_prot];
+ if (km->tty && !km->prot->tty)
+ ErrorF ("Mouse device is serial port, protocol %s is not serial protocol\n",
+ prot);
+ else if (!km->tty && km->prot->tty)
+ ErrorF ("Mouse device is not serial port, protocol %s is serial protocol\n",
+ prot);
+ }
+ }
+ if (!km->prot)
+ {
+ for (km->i_prot = 0; kmouseProts[km->i_prot]->tty != km->tty; km->i_prot++)
+ ;
+ km->prot = kmouseProts[km->i_prot];
+ }
+ MouseInitProtocol (km);
+}
+
+static void
+MouseNextProtocol (Kmouse *km)
+{
+ do
+ {
+ if (!km->prot)
+ km->i_prot = 0;
+ else
+ if (++km->i_prot == NUM_PROT) km->i_prot = 0;
+ km->prot = kmouseProts[km->i_prot];
+ } while (km->prot->tty != km->tty);
+ MouseInitProtocol (km);
+ ErrorF ("Switching to mouse protocol \"%s\"\n", km->prot->name);
+}
+
+static void
+MouseRead (int mousePort, void *closure)
+{
+ KdPointerInfo *pi = closure;
+ Kmouse *km = pi->driverPrivate;
+ unsigned char event[MAX_MOUSE];
+ int ne;
+ int c;
+ int i;
+ int timeout;
+
+ timeout = 0;
+ ne = 0;
+ for(;;)
+ {
+ c = MouseReadByte (&km->iob, timeout);
+ if (c == -1)
+ {
+ if (ne)
+ {
+ km->invalid += ne + km->tested;
+ km->valid = 0;
+ km->tested = 0;
+ km->stage = MouseBroken;
+ }
+ break;
+ }
+ event[ne++] = c;
+ i = (*km->prot->Valid) (pi, event, ne);
+ if (i != 0)
+ {
+#ifdef DEBUG
+ ErrorF ("Mouse protocol %s broken %d of %d bytes bad\n",
+ km->prot->name, i > 0 ? i : ne, ne);
+#endif
+ if (i > 0 && i < ne)
+ {
+ ne -= i;
+ memmove (event, event + i, ne);
+ }
+ else
+ {
+ i = ne;
+ ne = 0;
+ }
+ km->invalid += i + km->tested;
+ km->valid = 0;
+ km->tested = 0;
+ if (km->stage == MouseWorking)
+ km->i_prot--;
+ km->stage = MouseBroken;
+ if (km->invalid > MAX_SKIP)
+ {
+ MouseNextProtocol (km);
+ ne = 0;
+ }
+ timeout = 0;
+ }
+ else
+ {
+ if ((*km->prot->Complete) (pi, event, ne))
+ {
+ if ((*km->prot->Parse) (pi, event, ne))
+ {
+ switch (km->stage)
+ {
+ case MouseBroken:
+#ifdef DEBUG
+ ErrorF ("Mouse protocol %s seems OK\n",
+ km->prot->name);
+#endif
+ /* do not zero invalid to accumulate invalid bytes */
+ km->valid = 0;
+ km->tested = 0;
+ km->stage = MouseTesting;
+ /* fall through ... */
+ case MouseTesting:
+ km->valid++;
+ km->tested += ne;
+ if (km->valid > MAX_VALID)
+ {
+#ifdef DEBUG
+ ErrorF ("Mouse protocol %s working\n",
+ km->prot->name);
+#endif
+ km->stage = MouseWorking;
+ km->invalid = 0;
+ km->tested = 0;
+ km->valid = 0;
+ if (km->prot->Init && !(*km->prot->Init) (pi))
+ km->stage = MouseBroken;
+ }
+ break;
+ case MouseWorking:
+ break;
+ }
+ }
+ else
+ {
+ km->invalid += ne + km->tested;
+ km->valid = 0;
+ km->tested = 0;
+ km->stage = MouseBroken;
+ }
+ ne = 0;
+ timeout = 0;
+ }
+ else
+ timeout = MOUSE_TIMEOUT;
+ }
+ }
+}
+
+int MouseInputType;
+
+char *kdefaultMouse[] = {
+ "/dev/input/mice",
+ "/dev/mouse",
+ "/dev/psaux",
+ "/dev/adbmouse",
+ "/dev/ttyS0",
+ "/dev/ttyS1",
+};
+
+#define NUM_DEFAULT_MOUSE (sizeof (kdefaultMouse) / sizeof (kdefaultMouse[0]))
+
+static Status
+MouseInit (KdPointerInfo *pi)
+{
+ int i;
+ int fd;
+ Kmouse *km;
+
+ if (!pi)
+ return BadImplementation;
+
+ if (!pi->path || strcmp(pi->path, "auto") == 0) {
+ for (i = 0; i < NUM_DEFAULT_MOUSE; i++) {
+ fd = open (kdefaultMouse[i], 2);
+ if (fd >= 0) {
+ pi->path = strdup (kdefaultMouse[i]);
+ break;
+ }
+ }
+ }
+ else {
+ fd = open (pi->path, 2);
+ }
+
+ if (fd < 0)
+ return BadMatch;
+
+ close(fd);
+
+ km = (Kmouse *) malloc(sizeof (Kmouse));
+ if (km) {
+ km->iob.avail = km->iob.used = 0;
+ MouseFirstProtocol(km, pi->protocol ? pi->protocol : "exps/2");
+ /* MouseFirstProtocol sets state to MouseBroken for later protocol
+ * checks. Skip these checks if a protocol was supplied */
+ if (pi->protocol)
+ km->state = MouseWorking;
+ km->i_prot = 0;
+ km->tty = isatty (fd);
+ km->iob.fd = -1;
+ pi->driverPrivate = km;
+ }
+ else {
+ close (fd);
+ return BadAlloc;
+ }
+
+ return Success;
+}
+
+static Status
+MouseEnable (KdPointerInfo *pi)
+{
+ Kmouse *km;
+
+ if (!pi || !pi->driverPrivate || !pi->path)
+ return BadImplementation;
+
+ km = pi->driverPrivate;
+
+ km->iob.fd = open(pi->path, 2);
+ if (km->iob.fd < 0)
+ return BadMatch;
+
+ if (!KdRegisterFd (km->iob.fd, MouseRead, pi))
+ {
+ close(km->iob.fd);
+ return BadAlloc;
+ }
+
+ return Success;
+}
+
+static void
+MouseDisable (KdPointerInfo *pi)
+{
+ Kmouse *km;
+ if (!pi || !pi->driverPrivate)
+ return;
+
+ km = pi->driverPrivate;
+ KdUnregisterFd (pi, km->iob.fd, TRUE);
+}
+
+static void
+MouseFini (KdPointerInfo *pi)
+{
+ free(pi->driverPrivate);
+ pi->driverPrivate = NULL;
+}
+
+KdPointerDriver LinuxMouseDriver = {
+ "mouse",
+ MouseInit,
+ MouseEnable,
+ MouseDisable,
+ MouseFini,
+ NULL,
+};
diff --git a/xorg-server/hw/kdrive/linux/tslib.c b/xorg-server/hw/kdrive/linux/tslib.c
index 322ccc7d5..ee0f779f3 100644
--- a/xorg-server/hw/kdrive/linux/tslib.c
+++ b/xorg-server/hw/kdrive/linux/tslib.c
@@ -1,190 +1,190 @@
-/*
- * TSLIB based touchscreen driver for KDrive
- * Porting to new input API and event queueing by Daniel Stone.
- * Derived from ts.c by Keith Packard
- * Derived from ps2.c by Jim Gettys
- *
- * Copyright © 1999 Keith Packard
- * Copyright © 2000 Compaq Computer Corporation
- * Copyright © 2002 MontaVista Software Inc.
- * Copyright © 2005 OpenedHand Ltd.
- * Copyright © 2006 Nokia Corporation
- *
- * 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 the authors and/or copyright holders
- * not be used in advertising or publicity pertaining to distribution of the
- * software without specific, written prior permission. The authors and/or
- * copyright holders make no representations about the suitability of this
- * software for any purpose. It is provided "as is" without express or
- * implied warranty.
- *
- * THE AUTHORS AND/OR COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD
- * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS, IN NO EVENT SHALL THE AUTHORS AND/OR COPYRIGHT HOLDERS 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_KDRIVE_CONFIG_H
-#include <kdrive-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include <X11/Xpoll.h>
-#include "inputstr.h"
-#include "scrnintstr.h"
-#include "kdrive.h"
-#include <sys/ioctl.h>
-#include <tslib.h>
-#include <dirent.h>
-#include <linux/input.h>
-
-struct TslibPrivate {
- int fd;
- int lastx, lasty;
- struct tsdev *tsDev;
- void (*raw_event_hook)(int x, int y, int pressure, void *closure);
- void *raw_event_closure;
- int phys_screen;
-};
-
-
-static void
-TsRead (int fd, void *closure)
-{
- KdPointerInfo *pi = closure;
- struct TslibPrivate *private = pi->driverPrivate;
- struct ts_sample event;
- long x = 0, y = 0;
- unsigned long flags;
-
- if (private->raw_event_hook) {
- while (ts_read_raw(private->tsDev, &event, 1) == 1)
- private->raw_event_hook (event.x, event.y, event.pressure,
- private->raw_event_closure);
- return;
- }
-
- while (ts_read(private->tsDev, &event, 1) == 1) {
- if (event.pressure) {
- flags = KD_BUTTON_1;
-
- /*
- * Here we test for the touch screen driver actually being on the
- * touch screen, if it is we send absolute coordinates. If not,
- * then we send delta's so that we can track the entire vga screen.
- */
- if (KdCurScreen == private->phys_screen) {
- x = event.x;
- y = event.y;
- } else {
- flags |= KD_MOUSE_DELTA;
- if ((private->lastx == 0) || (private->lasty == 0)) {
- x = event.x;
- y = event.y;
- } else {
- x = event.x - private->lastx;
- y = event.y - private->lasty;
- }
- }
- private->lastx = event.x;
- private->lasty = event.y;
- } else {
- flags = 0;
- x = private->lastx;
- y = private->lasty;
- }
-
- KdEnqueuePointerEvent (pi, flags, x, y, event.pressure);
- }
-}
-
-static Status
-TslibEnable (KdPointerInfo *pi)
-{
- struct TslibPrivate *private = pi->driverPrivate;
-
- private->raw_event_hook = NULL;
- private->raw_event_closure = NULL;
- if (!pi->path) {
- pi->path = strdup("/dev/input/touchscreen0");
- ErrorF("[tslib/TslibEnable] no device path given, trying %s\n", pi->path);
- }
- private->tsDev = ts_open(pi->path, 0);
- private->fd = ts_fd(private->tsDev);
- if (!private->tsDev || ts_config(private->tsDev) || private->fd < 0) {
- ErrorF("[tslib/TslibEnable] failed to open %s\n", pi->path);
- if (private->fd >= 0)
- close(private->fd);
- return BadAlloc;
- }
-
- KdRegisterFd(private->fd, TsRead, pi);
-
- return Success;
-}
-
-
-static void
-TslibDisable (KdPointerInfo *pi)
-{
- struct TslibPrivate *private = pi->driverPrivate;
-
- if (private->fd)
- KdUnregisterFd(pi, private->fd, TRUE);
-
- if (private->tsDev)
- ts_close(private->tsDev);
-
- private->fd = 0;
- private->tsDev = NULL;
-}
-
-
-static Status
-TslibInit (KdPointerInfo *pi)
-{
- struct TslibPrivate *private = NULL;
-
- if (!pi || !pi->dixdev)
- return !Success;
-
- pi->driverPrivate = (struct TslibPrivate *)
- xcalloc(sizeof(struct TslibPrivate), 1);
- if (!pi->driverPrivate)
- return !Success;
-
- private = pi->driverPrivate;
- /* hacktastic */
- private->phys_screen = 0;
- pi->nAxes = 3;
- pi->name = strdup("Touchscreen");
- pi->inputClass = KD_TOUCHSCREEN;
-
- return Success;
-}
-
-
-static void
-TslibFini (KdPointerInfo *pi)
-{
- xfree(pi->driverPrivate);
- pi->driverPrivate = NULL;
-}
-
-
-KdPointerDriver TsDriver = {
- "tslib",
- TslibInit,
- TslibEnable,
- TslibDisable,
- TslibFini,
- NULL,
-};
+/*
+ * TSLIB based touchscreen driver for KDrive
+ * Porting to new input API and event queueing by Daniel Stone.
+ * Derived from ts.c by Keith Packard
+ * Derived from ps2.c by Jim Gettys
+ *
+ * Copyright © 1999 Keith Packard
+ * Copyright © 2000 Compaq Computer Corporation
+ * Copyright © 2002 MontaVista Software Inc.
+ * Copyright © 2005 OpenedHand Ltd.
+ * Copyright © 2006 Nokia Corporation
+ *
+ * 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 the authors and/or copyright holders
+ * not be used in advertising or publicity pertaining to distribution of the
+ * software without specific, written prior permission. The authors and/or
+ * copyright holders make no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express or
+ * implied warranty.
+ *
+ * THE AUTHORS AND/OR COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD
+ * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL THE AUTHORS AND/OR COPYRIGHT HOLDERS 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_KDRIVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/Xpoll.h>
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "kdrive.h"
+#include <sys/ioctl.h>
+#include <tslib.h>
+#include <dirent.h>
+#include <linux/input.h>
+
+struct TslibPrivate {
+ int fd;
+ int lastx, lasty;
+ struct tsdev *tsDev;
+ void (*raw_event_hook)(int x, int y, int pressure, void *closure);
+ void *raw_event_closure;
+ int phys_screen;
+};
+
+
+static void
+TsRead (int fd, void *closure)
+{
+ KdPointerInfo *pi = closure;
+ struct TslibPrivate *private = pi->driverPrivate;
+ struct ts_sample event;
+ long x = 0, y = 0;
+ unsigned long flags;
+
+ if (private->raw_event_hook) {
+ while (ts_read_raw(private->tsDev, &event, 1) == 1)
+ private->raw_event_hook (event.x, event.y, event.pressure,
+ private->raw_event_closure);
+ return;
+ }
+
+ while (ts_read(private->tsDev, &event, 1) == 1) {
+ if (event.pressure) {
+ flags = KD_BUTTON_1;
+
+ /*
+ * Here we test for the touch screen driver actually being on the
+ * touch screen, if it is we send absolute coordinates. If not,
+ * then we send delta's so that we can track the entire vga screen.
+ */
+ if (KdCurScreen == private->phys_screen) {
+ x = event.x;
+ y = event.y;
+ } else {
+ flags |= KD_MOUSE_DELTA;
+ if ((private->lastx == 0) || (private->lasty == 0)) {
+ x = event.x;
+ y = event.y;
+ } else {
+ x = event.x - private->lastx;
+ y = event.y - private->lasty;
+ }
+ }
+ private->lastx = event.x;
+ private->lasty = event.y;
+ } else {
+ flags = 0;
+ x = private->lastx;
+ y = private->lasty;
+ }
+
+ KdEnqueuePointerEvent (pi, flags, x, y, event.pressure);
+ }
+}
+
+static Status
+TslibEnable (KdPointerInfo *pi)
+{
+ struct TslibPrivate *private = pi->driverPrivate;
+
+ private->raw_event_hook = NULL;
+ private->raw_event_closure = NULL;
+ if (!pi->path) {
+ pi->path = strdup("/dev/input/touchscreen0");
+ ErrorF("[tslib/TslibEnable] no device path given, trying %s\n", pi->path);
+ }
+ private->tsDev = ts_open(pi->path, 0);
+ private->fd = ts_fd(private->tsDev);
+ if (!private->tsDev || ts_config(private->tsDev) || private->fd < 0) {
+ ErrorF("[tslib/TslibEnable] failed to open %s\n", pi->path);
+ if (private->fd >= 0)
+ close(private->fd);
+ return BadAlloc;
+ }
+
+ KdRegisterFd(private->fd, TsRead, pi);
+
+ return Success;
+}
+
+
+static void
+TslibDisable (KdPointerInfo *pi)
+{
+ struct TslibPrivate *private = pi->driverPrivate;
+
+ if (private->fd)
+ KdUnregisterFd(pi, private->fd, TRUE);
+
+ if (private->tsDev)
+ ts_close(private->tsDev);
+
+ private->fd = 0;
+ private->tsDev = NULL;
+}
+
+
+static Status
+TslibInit (KdPointerInfo *pi)
+{
+ struct TslibPrivate *private = NULL;
+
+ if (!pi || !pi->dixdev)
+ return !Success;
+
+ pi->driverPrivate = (struct TslibPrivate *)
+ calloc(sizeof(struct TslibPrivate), 1);
+ if (!pi->driverPrivate)
+ return !Success;
+
+ private = pi->driverPrivate;
+ /* hacktastic */
+ private->phys_screen = 0;
+ pi->nAxes = 3;
+ pi->name = strdup("Touchscreen");
+ pi->inputClass = KD_TOUCHSCREEN;
+
+ return Success;
+}
+
+
+static void
+TslibFini (KdPointerInfo *pi)
+{
+ free(pi->driverPrivate);
+ pi->driverPrivate = NULL;
+}
+
+
+KdPointerDriver TsDriver = {
+ "tslib",
+ TslibInit,
+ TslibEnable,
+ TslibDisable,
+ TslibFini,
+ NULL,
+};
diff --git a/xorg-server/hw/kdrive/src/kcmap.c b/xorg-server/hw/kdrive/src/kcmap.c
index 40697e091..127c7a078 100644
--- a/xorg-server/hw/kdrive/src/kcmap.c
+++ b/xorg-server/hw/kdrive/src/kcmap.c
@@ -1,246 +1,246 @@
-/*
- * Copyright © 1999 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <kdrive-config.h>
-#endif
-#include "kdrive.h"
-
-/*
- * Put the entire colormap into the DAC
- */
-
-void
-KdSetColormap (ScreenPtr pScreen)
-{
- KdScreenPriv(pScreen);
- ColormapPtr pCmap = pScreenPriv->pInstalledmap;
- Pixel pixels[KD_MAX_PSEUDO_SIZE];
- xrgb colors[KD_MAX_PSEUDO_SIZE];
- xColorItem defs[KD_MAX_PSEUDO_SIZE];
- int i;
-
- if (!pScreenPriv->card->cfuncs->putColors)
- return;
- if (pScreenPriv->screen->fb.depth > KD_MAX_PSEUDO_DEPTH)
- return;
-
- if (!pScreenPriv->enabled)
- return;
-
- if (!pCmap)
- return;
-
- /*
- * Make DIX convert pixels into RGB values -- this handles
- * true/direct as well as pseudo/static visuals
- */
-
- for (i = 0; i < (1 << pScreenPriv->screen->fb.depth); i++)
- pixels[i] = i;
-
- QueryColors (pCmap, (1 << pScreenPriv->screen->fb.depth), pixels, colors);
-
- for (i = 0; i < (1 << pScreenPriv->screen->fb.depth); i++)
- {
- defs[i].pixel = i;
- defs[i].red = colors[i].red;
- defs[i].green = colors[i].green;
- defs[i].blue = colors[i].blue;
- defs[i].flags = DoRed|DoGreen|DoBlue;
- }
-
- (*pScreenPriv->card->cfuncs->putColors) (pCmap->pScreen,
- (1 << pScreenPriv->screen->fb.depth),
- defs);
-
- /* recolor hardware cursor */
- if (pScreenPriv->card->cfuncs->recolorCursor)
- (*pScreenPriv->card->cfuncs->recolorCursor) (pCmap->pScreen, 0, 0);
-}
-
-/*
- * When the hardware is enabled, save the hardware colors and store
- * the current colormap
- */
-void
-KdEnableColormap (ScreenPtr pScreen)
-{
- KdScreenPriv(pScreen);
- int i;
-
- if (!pScreenPriv->card->cfuncs->putColors)
- return;
-
- if (pScreenPriv->screen->fb.depth <= KD_MAX_PSEUDO_DEPTH)
- {
- for (i = 0; i < (1 << pScreenPriv->screen->fb.depth); i++)
- pScreenPriv->systemPalette[i].pixel = i;
- (*pScreenPriv->card->cfuncs->getColors) (pScreen,
- (1 << pScreenPriv->screen->fb.depth),
- pScreenPriv->systemPalette);
- }
- KdSetColormap (pScreen);
-}
-
-void
-KdDisableColormap (ScreenPtr pScreen)
-{
- KdScreenPriv(pScreen);
-
- if (!pScreenPriv->card->cfuncs->putColors)
- return;
-
- if (pScreenPriv->screen->fb.depth <= KD_MAX_PSEUDO_DEPTH)
- {
- (*pScreenPriv->card->cfuncs->putColors) (pScreen,
- (1 << pScreenPriv->screen->fb.depth),
- pScreenPriv->systemPalette);
- }
-}
-
-/*
- * KdInstallColormap
- *
- * This function is called when the server receives a request to install a
- * colormap or when the server needs to install one on its own, like when
- * there's no window manager running and the user has moved the pointer over
- * an X client window. It needs to build an identity Windows palette for the
- * colormap and realize it into the Windows system palette.
- */
-void
-KdInstallColormap (ColormapPtr pCmap)
-{
- KdScreenPriv(pCmap->pScreen);
-
- if (pCmap == pScreenPriv->pInstalledmap)
- return;
-
- /* Tell X clients that the installed colormap is going away. */
- if (pScreenPriv->pInstalledmap)
- WalkTree(pScreenPriv->pInstalledmap->pScreen, TellLostMap,
- (pointer) &(pScreenPriv->pInstalledmap->mid));
-
- /* Take note of the new installed colorscreen-> */
- pScreenPriv->pInstalledmap = pCmap;
-
- KdSetColormap (pCmap->pScreen);
-
- /* Tell X clients of the new colormap */
- WalkTree(pCmap->pScreen, TellGainedMap, (pointer) &(pCmap->mid));
-}
-
-/*
- * KdUninstallColormap
- *
- * This function uninstalls a colormap by either installing
- * the default X colormap or erasing the installed colormap pointer.
- * The default X colormap itself cannot be uninstalled.
- */
-void
-KdUninstallColormap (ColormapPtr pCmap)
-{
- KdScreenPriv(pCmap->pScreen);
- Colormap defMapID;
- ColormapPtr defMap;
-
- /* ignore if not installed */
- if (pCmap != pScreenPriv->pInstalledmap)
- return;
-
- /* ignore attempts to uninstall default colormap */
- defMapID = pCmap->pScreen->defColormap;
- if ((Colormap) pCmap->mid == defMapID)
- return;
-
- /* install default */
- dixLookupResourceByType((pointer *)&defMap, defMapID, RT_COLORMAP,
- serverClient, DixInstallAccess);
- if (defMap)
- (*pCmap->pScreen->InstallColormap)(defMap);
- else
- {
- /* uninstall and clear colormap pointer */
- WalkTree(pCmap->pScreen, TellLostMap,
- (pointer) &(pCmap->mid));
- pScreenPriv->pInstalledmap = 0;
- }
-}
-
-int
-KdListInstalledColormaps (ScreenPtr pScreen, Colormap *pCmaps)
-{
- KdScreenPriv(pScreen);
- int n = 0;
-
- if (pScreenPriv->pInstalledmap)
- {
- *pCmaps++ = pScreenPriv->pInstalledmap->mid;
- n++;
- }
- return n;
-}
-
-/*
- * KdStoreColors
- *
- * This function is called whenever the server receives a request to store
- * color values into one or more entries in the currently installed X
- * colormap; it can be either the default colormap or a private colorscreen->
- */
-void
-KdStoreColors (ColormapPtr pCmap, int ndef, xColorItem *pdefs)
-{
- KdScreenPriv(pCmap->pScreen);
- VisualPtr pVisual;
- xColorItem expanddefs[KD_MAX_PSEUDO_SIZE];
-
- if (pCmap != pScreenPriv->pInstalledmap)
- return;
-
- if (!pScreenPriv->card->cfuncs->putColors)
- return;
-
- if (pScreenPriv->screen->fb.depth > KD_MAX_PSEUDO_DEPTH)
- return;
-
- if (!pScreenPriv->enabled)
- return;
-
- /* Check for DirectColor or TrueColor being simulated on a PseudoColor device. */
- pVisual = pCmap->pVisual;
- if ((pVisual->class | DynamicClass) == DirectColor)
- {
- /*
- * Expand DirectColor or TrueColor color values into a PseudoColor
- * format. Defer to the Color Framebuffer (CFB) code to do that.
- */
- ndef = fbExpandDirectColors(pCmap, ndef, pdefs, expanddefs);
- pdefs = expanddefs;
- }
-
- (*pScreenPriv->card->cfuncs->putColors) (pCmap->pScreen, ndef, pdefs);
-
- /* recolor hardware cursor */
- if (pScreenPriv->card->cfuncs->recolorCursor)
- (*pScreenPriv->card->cfuncs->recolorCursor) (pCmap->pScreen, ndef, pdefs);
-}
+/*
+ * Copyright © 1999 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+#include "kdrive.h"
+
+/*
+ * Put the entire colormap into the DAC
+ */
+
+void
+KdSetColormap (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ ColormapPtr pCmap = pScreenPriv->pInstalledmap;
+ Pixel pixels[KD_MAX_PSEUDO_SIZE];
+ xrgb colors[KD_MAX_PSEUDO_SIZE];
+ xColorItem defs[KD_MAX_PSEUDO_SIZE];
+ int i;
+
+ if (!pScreenPriv->card->cfuncs->putColors)
+ return;
+ if (pScreenPriv->screen->fb.depth > KD_MAX_PSEUDO_DEPTH)
+ return;
+
+ if (!pScreenPriv->enabled)
+ return;
+
+ if (!pCmap)
+ return;
+
+ /*
+ * Make DIX convert pixels into RGB values -- this handles
+ * true/direct as well as pseudo/static visuals
+ */
+
+ for (i = 0; i < (1 << pScreenPriv->screen->fb.depth); i++)
+ pixels[i] = i;
+
+ QueryColors (pCmap, (1 << pScreenPriv->screen->fb.depth), pixels, colors, serverClient);
+
+ for (i = 0; i < (1 << pScreenPriv->screen->fb.depth); i++)
+ {
+ defs[i].pixel = i;
+ defs[i].red = colors[i].red;
+ defs[i].green = colors[i].green;
+ defs[i].blue = colors[i].blue;
+ defs[i].flags = DoRed|DoGreen|DoBlue;
+ }
+
+ (*pScreenPriv->card->cfuncs->putColors) (pCmap->pScreen,
+ (1 << pScreenPriv->screen->fb.depth),
+ defs);
+
+ /* recolor hardware cursor */
+ if (pScreenPriv->card->cfuncs->recolorCursor)
+ (*pScreenPriv->card->cfuncs->recolorCursor) (pCmap->pScreen, 0, 0);
+}
+
+/*
+ * When the hardware is enabled, save the hardware colors and store
+ * the current colormap
+ */
+void
+KdEnableColormap (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ int i;
+
+ if (!pScreenPriv->card->cfuncs->putColors)
+ return;
+
+ if (pScreenPriv->screen->fb.depth <= KD_MAX_PSEUDO_DEPTH)
+ {
+ for (i = 0; i < (1 << pScreenPriv->screen->fb.depth); i++)
+ pScreenPriv->systemPalette[i].pixel = i;
+ (*pScreenPriv->card->cfuncs->getColors) (pScreen,
+ (1 << pScreenPriv->screen->fb.depth),
+ pScreenPriv->systemPalette);
+ }
+ KdSetColormap (pScreen);
+}
+
+void
+KdDisableColormap (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+
+ if (!pScreenPriv->card->cfuncs->putColors)
+ return;
+
+ if (pScreenPriv->screen->fb.depth <= KD_MAX_PSEUDO_DEPTH)
+ {
+ (*pScreenPriv->card->cfuncs->putColors) (pScreen,
+ (1 << pScreenPriv->screen->fb.depth),
+ pScreenPriv->systemPalette);
+ }
+}
+
+/*
+ * KdInstallColormap
+ *
+ * This function is called when the server receives a request to install a
+ * colormap or when the server needs to install one on its own, like when
+ * there's no window manager running and the user has moved the pointer over
+ * an X client window. It needs to build an identity Windows palette for the
+ * colormap and realize it into the Windows system palette.
+ */
+void
+KdInstallColormap (ColormapPtr pCmap)
+{
+ KdScreenPriv(pCmap->pScreen);
+
+ if (pCmap == pScreenPriv->pInstalledmap)
+ return;
+
+ /* Tell X clients that the installed colormap is going away. */
+ if (pScreenPriv->pInstalledmap)
+ WalkTree(pScreenPriv->pInstalledmap->pScreen, TellLostMap,
+ (pointer) &(pScreenPriv->pInstalledmap->mid));
+
+ /* Take note of the new installed colorscreen-> */
+ pScreenPriv->pInstalledmap = pCmap;
+
+ KdSetColormap (pCmap->pScreen);
+
+ /* Tell X clients of the new colormap */
+ WalkTree(pCmap->pScreen, TellGainedMap, (pointer) &(pCmap->mid));
+}
+
+/*
+ * KdUninstallColormap
+ *
+ * This function uninstalls a colormap by either installing
+ * the default X colormap or erasing the installed colormap pointer.
+ * The default X colormap itself cannot be uninstalled.
+ */
+void
+KdUninstallColormap (ColormapPtr pCmap)
+{
+ KdScreenPriv(pCmap->pScreen);
+ Colormap defMapID;
+ ColormapPtr defMap;
+
+ /* ignore if not installed */
+ if (pCmap != pScreenPriv->pInstalledmap)
+ return;
+
+ /* ignore attempts to uninstall default colormap */
+ defMapID = pCmap->pScreen->defColormap;
+ if ((Colormap) pCmap->mid == defMapID)
+ return;
+
+ /* install default */
+ dixLookupResourceByType((pointer *)&defMap, defMapID, RT_COLORMAP,
+ serverClient, DixInstallAccess);
+ if (defMap)
+ (*pCmap->pScreen->InstallColormap)(defMap);
+ else
+ {
+ /* uninstall and clear colormap pointer */
+ WalkTree(pCmap->pScreen, TellLostMap,
+ (pointer) &(pCmap->mid));
+ pScreenPriv->pInstalledmap = 0;
+ }
+}
+
+int
+KdListInstalledColormaps (ScreenPtr pScreen, Colormap *pCmaps)
+{
+ KdScreenPriv(pScreen);
+ int n = 0;
+
+ if (pScreenPriv->pInstalledmap)
+ {
+ *pCmaps++ = pScreenPriv->pInstalledmap->mid;
+ n++;
+ }
+ return n;
+}
+
+/*
+ * KdStoreColors
+ *
+ * This function is called whenever the server receives a request to store
+ * color values into one or more entries in the currently installed X
+ * colormap; it can be either the default colormap or a private colorscreen->
+ */
+void
+KdStoreColors (ColormapPtr pCmap, int ndef, xColorItem *pdefs)
+{
+ KdScreenPriv(pCmap->pScreen);
+ VisualPtr pVisual;
+ xColorItem expanddefs[KD_MAX_PSEUDO_SIZE];
+
+ if (pCmap != pScreenPriv->pInstalledmap)
+ return;
+
+ if (!pScreenPriv->card->cfuncs->putColors)
+ return;
+
+ if (pScreenPriv->screen->fb.depth > KD_MAX_PSEUDO_DEPTH)
+ return;
+
+ if (!pScreenPriv->enabled)
+ return;
+
+ /* Check for DirectColor or TrueColor being simulated on a PseudoColor device. */
+ pVisual = pCmap->pVisual;
+ if ((pVisual->class | DynamicClass) == DirectColor)
+ {
+ /*
+ * Expand DirectColor or TrueColor color values into a PseudoColor
+ * format. Defer to the Color Framebuffer (CFB) code to do that.
+ */
+ ndef = fbExpandDirectColors(pCmap, ndef, pdefs, expanddefs);
+ pdefs = expanddefs;
+ }
+
+ (*pScreenPriv->card->cfuncs->putColors) (pCmap->pScreen, ndef, pdefs);
+
+ /* recolor hardware cursor */
+ if (pScreenPriv->card->cfuncs->recolorCursor)
+ (*pScreenPriv->card->cfuncs->recolorCursor) (pCmap->pScreen, ndef, pdefs);
+}
diff --git a/xorg-server/hw/kdrive/src/kdrive.c b/xorg-server/hw/kdrive/src/kdrive.c
index a8eb3996b..a7db41379 100644
--- a/xorg-server/hw/kdrive/src/kdrive.c
+++ b/xorg-server/hw/kdrive/src/kdrive.c
@@ -207,7 +207,7 @@ KdDoSwitchCmd (char *reason)
{
if (kdSwitchCmd)
{
- char *command = xalloc (strlen (kdSwitchCmd) +
+ char *command = malloc(strlen (kdSwitchCmd) +
1 +
strlen (reason) +
1);
@@ -217,7 +217,7 @@ KdDoSwitchCmd (char *reason)
strcat (command, " ");
strcat (command, reason);
system (command);
- xfree (command);
+ free(command);
}
}
@@ -701,7 +701,7 @@ KdAllocatePrivates (ScreenPtr pScreen)
if (kdGeneration != serverGeneration)
kdGeneration = serverGeneration;
- pScreenPriv = xcalloc(1, sizeof (*pScreenPriv));
+ pScreenPriv = calloc(1, sizeof (*pScreenPriv));
if (!pScreenPriv)
return FALSE;
KdSetScreenPriv (pScreen, pScreenPriv);
@@ -790,7 +790,7 @@ KdCloseScreen (int index, ScreenPtr pScreen)
pScreenPriv->screen->pScreen = 0;
- xfree ((pointer) pScreenPriv);
+ free((pointer) pScreenPriv);
return ret;
}
diff --git a/xorg-server/hw/kdrive/src/kinfo.c b/xorg-server/hw/kdrive/src/kinfo.c
index 0825ee24f..90fe37ae9 100644
--- a/xorg-server/hw/kdrive/src/kinfo.c
+++ b/xorg-server/hw/kdrive/src/kinfo.c
@@ -1,163 +1,163 @@
-/*
- * Copyright © 1999 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <kdrive-config.h>
-#endif
-#include "kdrive.h"
-
-KdCardInfo *kdCardInfo;
-
-KdCardInfo *
-KdCardInfoAdd (KdCardFuncs *funcs,
- void *closure)
-{
- KdCardInfo *ci, **prev;
-
- ci = xcalloc (1, sizeof (KdCardInfo));
- if (!ci)
- return 0;
- for (prev = &kdCardInfo; *prev; prev = &(*prev)->next);
- *prev = ci;
- ci->cfuncs = funcs;
- ci->closure = closure;
- ci->screenList = 0;
- ci->selected = 0;
- ci->next = 0;
- return ci;
-}
-
-KdCardInfo *
-KdCardInfoLast (void)
-{
- KdCardInfo *ci;
-
- if (!kdCardInfo)
- return 0;
- for (ci = kdCardInfo; ci->next; ci = ci->next);
- return ci;
-}
-
-void
-KdCardInfoDispose (KdCardInfo *ci)
-{
- KdCardInfo **prev;
-
- for (prev = &kdCardInfo; *prev; prev = &(*prev)->next)
- if (*prev == ci)
- {
- *prev = ci->next;
- xfree (ci);
- break;
- }
-}
-
-KdScreenInfo *
-KdScreenInfoAdd (KdCardInfo *ci)
-{
- KdScreenInfo *si, **prev;
- int n;
-
- si = xcalloc (1, sizeof (KdScreenInfo));
- if (!si)
- return 0;
- for (prev = &ci->screenList, n = 0; *prev; prev = &(*prev)->next, n++);
- *prev = si;
- si->next = 0;
- si->card = ci;
- si->mynum = n;
- return si;
-}
-
-void
-KdScreenInfoDispose (KdScreenInfo *si)
-{
- KdCardInfo *ci = si->card;
- KdScreenInfo **prev;
-
- for (prev = &ci->screenList; *prev; prev = &(*prev)->next) {
- if (*prev == si)
- {
- *prev = si->next;
- xfree (si);
- if (!ci->screenList)
- KdCardInfoDispose (ci);
- break;
- }
- }
-}
-
-KdPointerInfo *
-KdNewPointer (void)
-{
- KdPointerInfo *pi;
- int i;
-
- pi = (KdPointerInfo *)xcalloc(1, sizeof(KdPointerInfo));
- if (!pi)
- return NULL;
-
- pi->name = strdup("Generic Pointer");
- pi->path = NULL;
- pi->inputClass = KD_MOUSE;
- pi->driver = NULL;
- pi->driverPrivate = NULL;
- pi->next = NULL;
- pi->options = NULL;
- pi->nAxes = 3;
- pi->nButtons = KD_MAX_BUTTON;
- for (i = 1; i < KD_MAX_BUTTON; i++)
- pi->map[i] = i;
-
- return pi;
-}
-
-void
-KdFreePointer(KdPointerInfo *pi)
-{
- InputOption *option, *prev = NULL;
-
- xfree(pi->name);
- xfree(pi->path);
-
- for (option = pi->options; option; option = option->next) {
- xfree(prev);
- xfree(option->key);
- xfree(option->value);
- prev = option;
- }
-
- xfree(prev);
- xfree(pi);
-}
-
-void
-KdFreeKeyboard(KdKeyboardInfo *ki)
-{
- xfree(ki->name);
- xfree(ki->path);
- xfree(ki->xkbRules);
- xfree(ki->xkbModel);
- xfree(ki->xkbLayout);
- ki->next = NULL;
- xfree(ki);
-}
+/*
+ * Copyright © 1999 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+#include "kdrive.h"
+
+KdCardInfo *kdCardInfo;
+
+KdCardInfo *
+KdCardInfoAdd (KdCardFuncs *funcs,
+ void *closure)
+{
+ KdCardInfo *ci, **prev;
+
+ ci = calloc(1, sizeof (KdCardInfo));
+ if (!ci)
+ return 0;
+ for (prev = &kdCardInfo; *prev; prev = &(*prev)->next);
+ *prev = ci;
+ ci->cfuncs = funcs;
+ ci->closure = closure;
+ ci->screenList = 0;
+ ci->selected = 0;
+ ci->next = 0;
+ return ci;
+}
+
+KdCardInfo *
+KdCardInfoLast (void)
+{
+ KdCardInfo *ci;
+
+ if (!kdCardInfo)
+ return 0;
+ for (ci = kdCardInfo; ci->next; ci = ci->next);
+ return ci;
+}
+
+void
+KdCardInfoDispose (KdCardInfo *ci)
+{
+ KdCardInfo **prev;
+
+ for (prev = &kdCardInfo; *prev; prev = &(*prev)->next)
+ if (*prev == ci)
+ {
+ *prev = ci->next;
+ free(ci);
+ break;
+ }
+}
+
+KdScreenInfo *
+KdScreenInfoAdd (KdCardInfo *ci)
+{
+ KdScreenInfo *si, **prev;
+ int n;
+
+ si = calloc(1, sizeof (KdScreenInfo));
+ if (!si)
+ return 0;
+ for (prev = &ci->screenList, n = 0; *prev; prev = &(*prev)->next, n++);
+ *prev = si;
+ si->next = 0;
+ si->card = ci;
+ si->mynum = n;
+ return si;
+}
+
+void
+KdScreenInfoDispose (KdScreenInfo *si)
+{
+ KdCardInfo *ci = si->card;
+ KdScreenInfo **prev;
+
+ for (prev = &ci->screenList; *prev; prev = &(*prev)->next) {
+ if (*prev == si)
+ {
+ *prev = si->next;
+ free(si);
+ if (!ci->screenList)
+ KdCardInfoDispose (ci);
+ break;
+ }
+ }
+}
+
+KdPointerInfo *
+KdNewPointer (void)
+{
+ KdPointerInfo *pi;
+ int i;
+
+ pi = (KdPointerInfo *)calloc(1, sizeof(KdPointerInfo));
+ if (!pi)
+ return NULL;
+
+ pi->name = strdup("Generic Pointer");
+ pi->path = NULL;
+ pi->inputClass = KD_MOUSE;
+ pi->driver = NULL;
+ pi->driverPrivate = NULL;
+ pi->next = NULL;
+ pi->options = NULL;
+ pi->nAxes = 3;
+ pi->nButtons = KD_MAX_BUTTON;
+ for (i = 1; i < KD_MAX_BUTTON; i++)
+ pi->map[i] = i;
+
+ return pi;
+}
+
+void
+KdFreePointer(KdPointerInfo *pi)
+{
+ InputOption *option, *prev = NULL;
+
+ free(pi->name);
+ free(pi->path);
+
+ for (option = pi->options; option; option = option->next) {
+ free(prev);
+ free(option->key);
+ free(option->value);
+ prev = option;
+ }
+
+ free(prev);
+ free(pi);
+}
+
+void
+KdFreeKeyboard(KdKeyboardInfo *ki)
+{
+ free(ki->name);
+ free(ki->path);
+ free(ki->xkbRules);
+ free(ki->xkbModel);
+ free(ki->xkbLayout);
+ ki->next = NULL;
+ free(ki);
+}
diff --git a/xorg-server/hw/kdrive/src/kinput.c b/xorg-server/hw/kdrive/src/kinput.c
index 9ba90e63f..d1b12b890 100644
--- a/xorg-server/hw/kdrive/src/kinput.c
+++ b/xorg-server/hw/kdrive/src/kinput.c
@@ -440,7 +440,7 @@ KdPointerProc(DeviceIntPtr pDevice, int onoff)
"(unnamed)");
return !Success;
}
- xfree(pi->driverPrivate);
+ free(pi->driverPrivate);
pi->driverPrivate = NULL;
}
@@ -453,12 +453,12 @@ KdPointerProc(DeviceIntPtr pDevice, int onoff)
return !Success;
}
- btn_labels = xcalloc(pi->nButtons, sizeof(Atom));
+ btn_labels = calloc(pi->nButtons, sizeof(Atom));
if (!btn_labels)
return BadAlloc;
- axes_labels = xcalloc(pi->nAxes, sizeof(Atom));
+ axes_labels = calloc(pi->nAxes, sizeof(Atom));
if (!axes_labels) {
- xfree(btn_labels);
+ free(btn_labels);
return BadAlloc;
}
@@ -492,8 +492,8 @@ KdPointerProc(DeviceIntPtr pDevice, int onoff)
(PtrCtrlProcPtr)NoopDDA,
GetMotionHistorySize(), pi->nAxes, axes_labels);
- xfree(btn_labels);
- xfree(axes_labels);
+ free(btn_labels);
+ free(axes_labels);
if (pi->inputClass == KD_TOUCHSCREEN) {
InitAbsoluteClassDeviceStruct(pDevice);
@@ -759,7 +759,7 @@ KdKeyboardProc(DeviceIntPtr pDevice, int onoff)
"(unnamed)");
return !Success;
}
- xfree(ki->driverPrivate);
+ free(ki->driverPrivate);
ki->driverPrivate = NULL;
}
@@ -910,7 +910,7 @@ KdRemoveKeyboardDriver (KdKeyboardDriver *driver)
KdKeyboardInfo *
KdNewKeyboard (void)
{
- KdKeyboardInfo *ki = xcalloc(sizeof(KdKeyboardInfo), 1);
+ KdKeyboardInfo *ki = calloc(sizeof(KdKeyboardInfo), 1);
if (!ki)
return NULL;
@@ -938,7 +938,7 @@ KdAddConfigKeyboard (char *keyboard)
if (!keyboard)
return Success;
- new = (struct KdConfigDevice *) xcalloc(sizeof(struct KdConfigDevice), 1);
+ new = (struct KdConfigDevice *) calloc(sizeof(struct KdConfigDevice), 1);
if (!new)
return BadAlloc;
@@ -1006,7 +1006,7 @@ KdAddConfigPointer (char *pointer)
if (!pointer)
return Success;
- new = (struct KdConfigDevice *) xcalloc(sizeof(struct KdConfigDevice), 1);
+ new = (struct KdConfigDevice *) calloc(sizeof(struct KdConfigDevice), 1);
if (!new)
return BadAlloc;
@@ -1076,7 +1076,7 @@ KdGetOptions (InputOption **options, char *string)
InputOption *newopt = NULL, **tmpo = NULL;
int tam_key = 0;
- newopt = xcalloc(1, sizeof (InputOption));
+ newopt = calloc(1, sizeof (InputOption));
if (!newopt)
return FALSE;
@@ -1087,7 +1087,7 @@ KdGetOptions (InputOption **options, char *string)
if (strchr(string, '='))
{
tam_key = (strchr(string, '=') - string);
- newopt->key = (char *)xalloc(tam_key);
+ newopt->key = (char *)malloc(tam_key);
strncpy(newopt->key, string, tam_key);
newopt->key[tam_key] = '\0';
newopt->value = xstrdup(strchr(string, '=') + 1);
diff --git a/xorg-server/hw/kdrive/src/kshadow.c b/xorg-server/hw/kdrive/src/kshadow.c
index cf3391dba..4454020f0 100644
--- a/xorg-server/hw/kdrive/src/kshadow.c
+++ b/xorg-server/hw/kdrive/src/kshadow.c
@@ -1,81 +1,81 @@
-/*
- * Copyright © 1999 Keith Packard
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <kdrive-config.h>
-#endif
-#include "kdrive.h"
-
-Bool
-KdShadowFbAlloc (KdScreenInfo *screen, Bool rotate)
-{
- int paddedWidth;
- void *buf;
- int width = rotate ? screen->height : screen->width;
- int height = rotate ? screen->width : screen->height;
- int bpp = screen->fb.bitsPerPixel;
-
- /* use fb computation for width */
- paddedWidth = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof (FbBits);
- buf = xalloc (paddedWidth * height);
- if (!buf)
- return FALSE;
- if (screen->fb.shadow)
- xfree (screen->fb.frameBuffer);
- screen->fb.shadow = TRUE;
- screen->fb.frameBuffer = buf;
- screen->fb.byteStride = paddedWidth;
- screen->fb.pixelStride = paddedWidth * 8 / bpp;
- return TRUE;
-}
-
-void
-KdShadowFbFree (KdScreenInfo *screen)
-{
- if (screen->fb.shadow)
- {
- xfree (screen->fb.frameBuffer);
- screen->fb.frameBuffer = 0;
- screen->fb.shadow = FALSE;
- }
-}
-
-Bool
-KdShadowSet (ScreenPtr pScreen, int randr, ShadowUpdateProc update, ShadowWindowProc window)
-{
- KdScreenPriv(pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
-
- shadowRemove (pScreen, pScreen->GetScreenPixmap(pScreen));
- if(screen->fb.shadow)
- {
- return shadowAdd (pScreen, pScreen->GetScreenPixmap(pScreen),
- update, window, randr, 0);
- }
- return TRUE;
-}
-
-void
-KdShadowUnset (ScreenPtr pScreen)
-{
- shadowRemove(pScreen, pScreen->GetScreenPixmap(pScreen));
-}
+/*
+ * Copyright © 1999 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+#include "kdrive.h"
+
+Bool
+KdShadowFbAlloc (KdScreenInfo *screen, Bool rotate)
+{
+ int paddedWidth;
+ void *buf;
+ int width = rotate ? screen->height : screen->width;
+ int height = rotate ? screen->width : screen->height;
+ int bpp = screen->fb.bitsPerPixel;
+
+ /* use fb computation for width */
+ paddedWidth = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof (FbBits);
+ buf = malloc(paddedWidth * height);
+ if (!buf)
+ return FALSE;
+ if (screen->fb.shadow)
+ free(screen->fb.frameBuffer);
+ screen->fb.shadow = TRUE;
+ screen->fb.frameBuffer = buf;
+ screen->fb.byteStride = paddedWidth;
+ screen->fb.pixelStride = paddedWidth * 8 / bpp;
+ return TRUE;
+}
+
+void
+KdShadowFbFree (KdScreenInfo *screen)
+{
+ if (screen->fb.shadow)
+ {
+ free(screen->fb.frameBuffer);
+ screen->fb.frameBuffer = 0;
+ screen->fb.shadow = FALSE;
+ }
+}
+
+Bool
+KdShadowSet (ScreenPtr pScreen, int randr, ShadowUpdateProc update, ShadowWindowProc window)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+
+ shadowRemove (pScreen, pScreen->GetScreenPixmap(pScreen));
+ if(screen->fb.shadow)
+ {
+ return shadowAdd (pScreen, pScreen->GetScreenPixmap(pScreen),
+ update, window, randr, 0);
+ }
+ return TRUE;
+}
+
+void
+KdShadowUnset (ScreenPtr pScreen)
+{
+ shadowRemove(pScreen, pScreen->GetScreenPixmap(pScreen));
+}
diff --git a/xorg-server/hw/kdrive/src/kxv.c b/xorg-server/hw/kdrive/src/kxv.c
index 27ecc5d6c..9fef34d1f 100644
--- a/xorg-server/hw/kdrive/src/kxv.c
+++ b/xorg-server/hw/kdrive/src/kxv.c
@@ -1,1907 +1,1907 @@
-/*
-
- XFree86 Xv DDX written by Mark Vojkovich (markv@valinux.com)
- Adapted for KDrive by Pontus Lidman <pontus.lidman@nokia.com>
-
- Copyright (C) 2000, 2001 - Nokia Home Communications
- Copyright (C) 1998, 1999 - 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, and/or sell copies of the Software, and to permit persons
-to whom the Software is furnished to do so, provided that the above
-copyright notice(s) and this permission notice appear in all copies of
-the Software and that both the above copyright notice(s) and this
-permission notice appear in supporting documentation.
-
-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
-OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
-HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR 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.
-
-Except as contained in this notice, the name of a copyright holder
-shall not be used in advertising or otherwise to promote the sale, use
-or other dealings in this Software without prior written authorization
-of the copyright holder.
-
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <kdrive-config.h>
-#endif
-#include "kdrive.h"
-
-#include "scrnintstr.h"
-#include "regionstr.h"
-#include "windowstr.h"
-#include "pixmapstr.h"
-#include "mivalidate.h"
-#include "validate.h"
-#include "resource.h"
-#include "gcstruct.h"
-#include "dixstruct.h"
-
-#include <X11/extensions/Xv.h>
-#include <X11/extensions/Xvproto.h>
-
-#include "kxv.h"
-#include "fourcc.h"
-
-
-/* XvScreenRec fields */
-
-static Bool KdXVCloseScreen(int, ScreenPtr);
-static int KdXVQueryAdaptors(ScreenPtr, XvAdaptorPtr *, int *);
-
-/* XvAdaptorRec fields */
-
-static int KdXVAllocatePort(unsigned long, XvPortPtr, XvPortPtr*);
-static int KdXVFreePort(XvPortPtr);
-static int KdXVPutVideo(ClientPtr, DrawablePtr,XvPortPtr, GCPtr,
- INT16, INT16, CARD16, CARD16,
- INT16, INT16, CARD16, CARD16);
-static int KdXVPutStill(ClientPtr, DrawablePtr,XvPortPtr, GCPtr,
- INT16, INT16, CARD16, CARD16,
- INT16, INT16, CARD16, CARD16);
-static int KdXVGetVideo(ClientPtr, DrawablePtr,XvPortPtr, GCPtr,
- INT16, INT16, CARD16, CARD16,
- INT16, INT16, CARD16, CARD16);
-static int KdXVGetStill(ClientPtr, DrawablePtr,XvPortPtr, GCPtr,
- INT16, INT16, CARD16, CARD16,
- INT16, INT16, CARD16, CARD16);
-static int KdXVStopVideo(ClientPtr, XvPortPtr, DrawablePtr);
-static int KdXVSetPortAttribute(ClientPtr, XvPortPtr, Atom, INT32);
-static int KdXVGetPortAttribute(ClientPtr, XvPortPtr, Atom, INT32 *);
-static int KdXVQueryBestSize(ClientPtr, XvPortPtr, CARD8,
- CARD16, CARD16,CARD16, CARD16,
- unsigned int*, unsigned int*);
-static int KdXVPutImage(ClientPtr, DrawablePtr, XvPortPtr, GCPtr,
- INT16, INT16, CARD16, CARD16,
- INT16, INT16, CARD16, CARD16,
- XvImagePtr, unsigned char*, Bool,
- CARD16, CARD16);
-static int KdXVQueryImageAttributes(ClientPtr, XvPortPtr, XvImagePtr,
- CARD16*, CARD16*, int*, int*);
-
-
-/* ScreenRec fields */
-
-static Bool KdXVCreateWindow(WindowPtr pWin);
-static Bool KdXVDestroyWindow(WindowPtr pWin);
-static void KdXVWindowExposures(WindowPtr pWin, RegionPtr r1, RegionPtr r2);
-static void KdXVClipNotify(WindowPtr pWin, int dx, int dy);
-
-/* misc */
-static Bool KdXVInitAdaptors(ScreenPtr, KdVideoAdaptorPtr*, int);
-
-static int KdXVWindowKeyIndex;
-DevPrivateKey KdXVWindowKey = &KdXVWindowKeyIndex;
-static int KdXvScreenKeyIndex;
-DevPrivateKey KdXvScreenKey = &KdXvScreenKeyIndex;
-static unsigned long KdXVGeneration = 0;
-static unsigned long PortResource = 0;
-
-DevPrivateKey (*XvGetScreenKeyProc)(void) = XvGetScreenKey;
-unsigned long (*XvGetRTPortProc)(void) = XvGetRTPort;
-int (*XvScreenInitProc)(ScreenPtr) = XvScreenInit;
-
-#define GET_XV_SCREEN(pScreen) ((XvScreenPtr) \
- dixLookupPrivate(&(pScreen)->devPrivates, KdXvScreenKey))
-
-#define GET_KDXV_SCREEN(pScreen) \
- ((KdXVScreenPtr)(GET_XV_SCREEN(pScreen)->devPriv.ptr))
-
-#define GET_KDXV_WINDOW(pWin) ((KdXVWindowPtr) \
- dixLookupPrivate(&(pWin)->devPrivates, KdXVWindowKey))
-
-static KdXVInitGenericAdaptorPtr *GenDrivers = NULL;
-static int NumGenDrivers = 0;
-
-int
-KdXVRegisterGenericAdaptorDriver(
- KdXVInitGenericAdaptorPtr InitFunc
-){
- KdXVInitGenericAdaptorPtr *newdrivers;
-
-/* fprintf(stderr,"KdXVRegisterGenericAdaptorDriver\n"); */
-
- newdrivers = xrealloc(GenDrivers, sizeof(KdXVInitGenericAdaptorPtr) *
- (1 + NumGenDrivers));
- if (!newdrivers)
- return 0;
- GenDrivers = newdrivers;
-
- GenDrivers[NumGenDrivers++] = InitFunc;
-
- return 1;
-}
-
-int
-KdXVListGenericAdaptors(
- KdScreenInfo * screen,
- KdVideoAdaptorPtr **adaptors
-){
- int i,j,n,num;
- KdVideoAdaptorPtr *DrivAdap,*new;
-
- num = 0;
- *adaptors = NULL;
- for (i = 0; i < NumGenDrivers; i++) {
- n = GenDrivers[i](screen,&DrivAdap);
- if (0 == n)
- continue;
- new = xrealloc(*adaptors, sizeof(KdVideoAdaptorPtr) * (num+n));
- if (NULL == new)
- continue;
- *adaptors = new;
- for (j = 0; j < n; j++, num++)
- (*adaptors)[num] = DrivAdap[j];
- }
- return num;
-}
-
-KdVideoAdaptorPtr
-KdXVAllocateVideoAdaptorRec(KdScreenInfo * screen)
-{
- return xcalloc(1, sizeof(KdVideoAdaptorRec));
-}
-
-void
-KdXVFreeVideoAdaptorRec(KdVideoAdaptorPtr ptr)
-{
- xfree(ptr);
-}
-
-
-Bool
-KdXVScreenInit(
- ScreenPtr pScreen,
- KdVideoAdaptorPtr *adaptors,
- int num
-){
- KdXVScreenPtr ScreenPriv;
- XvScreenPtr pxvs;
-
-/* fprintf(stderr,"KdXVScreenInit initializing %d adaptors\n",num); */
-
- if (KdXVGeneration != serverGeneration)
- KdXVGeneration = serverGeneration;
-
- if(!XvGetScreenKeyProc || !XvGetRTPortProc || !XvScreenInitProc)
- return FALSE;
-
- if(Success != (*XvScreenInitProc)(pScreen)) return FALSE;
-
- KdXvScreenKey = (*XvGetScreenKeyProc)();
- PortResource = (*XvGetRTPortProc)();
-
- pxvs = GET_XV_SCREEN(pScreen);
-
-
- /* Anyone initializing the Xv layer must provide these two.
- The Xv di layer calls them without even checking if they exist! */
-
- pxvs->ddCloseScreen = KdXVCloseScreen;
- pxvs->ddQueryAdaptors = KdXVQueryAdaptors;
-
- /* The Xv di layer provides us with a private hook so that we don't
- have to allocate our own screen private. They also provide
- a CloseScreen hook so that we don't have to wrap it. I'm not
- sure that I appreciate that. */
-
- ScreenPriv = xalloc(sizeof(KdXVScreenRec));
- pxvs->devPriv.ptr = (pointer)ScreenPriv;
-
- if(!ScreenPriv) return FALSE;
-
-
- ScreenPriv->CreateWindow = pScreen->CreateWindow;
- ScreenPriv->DestroyWindow = pScreen->DestroyWindow;
- ScreenPriv->WindowExposures = pScreen->WindowExposures;
- ScreenPriv->ClipNotify = pScreen->ClipNotify;
-
-/* fprintf(stderr,"XV: Wrapping screen funcs\n"); */
-
- pScreen->CreateWindow = KdXVCreateWindow;
- pScreen->DestroyWindow = KdXVDestroyWindow;
- pScreen->WindowExposures = KdXVWindowExposures;
- pScreen->ClipNotify = KdXVClipNotify;
-
- if(!KdXVInitAdaptors(pScreen, adaptors, num))
- return FALSE;
-
- return TRUE;
-}
-
-static void
-KdXVFreeAdaptor(XvAdaptorPtr pAdaptor)
-{
- int i;
-
- xfree(pAdaptor->name);
-
- if(pAdaptor->pEncodings) {
- XvEncodingPtr pEncode = pAdaptor->pEncodings;
-
- for(i = 0; i < pAdaptor->nEncodings; i++, pEncode++) {
- xfree(pEncode->name);
- }
- xfree(pAdaptor->pEncodings);
- }
-
- xfree(pAdaptor->pFormats);
-
- if(pAdaptor->pPorts) {
- XvPortPtr pPort = pAdaptor->pPorts;
- XvPortRecPrivatePtr pPriv;
-
- for(i = 0; i < pAdaptor->nPorts; i++, pPort++) {
- pPriv = (XvPortRecPrivatePtr)pPort->devPriv.ptr;
- if(pPriv) {
- if(pPriv->clientClip)
- REGION_DESTROY(pAdaptor->pScreen, pPriv->clientClip);
- if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
- REGION_DESTROY(pAdaptor->pScreen, pPriv->pCompositeClip);
- xfree(pPriv);
- }
- }
- xfree(pAdaptor->pPorts);
- }
-
- if(pAdaptor->nAttributes) {
- XvAttributePtr pAttribute = pAdaptor->pAttributes;
-
- for(i = 0; i < pAdaptor->nAttributes; i++, pAttribute++) {
- xfree(pAttribute->name);
- }
-
- xfree(pAdaptor->pAttributes);
- }
-
- xfree(pAdaptor->pImages);
-
- xfree(pAdaptor->devPriv.ptr);
-}
-
-static Bool
-KdXVInitAdaptors(
- ScreenPtr pScreen,
- KdVideoAdaptorPtr *infoPtr,
- int number
-) {
- KdScreenPriv(pScreen);
- KdScreenInfo * screen = pScreenPriv->screen;
-
- XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
- KdVideoAdaptorPtr adaptorPtr;
- XvAdaptorPtr pAdaptor, pa;
- XvAdaptorRecPrivatePtr adaptorPriv;
- int na, numAdaptor;
- XvPortRecPrivatePtr portPriv;
- XvPortPtr pPort, pp;
- int numPort;
- KdAttributePtr attributePtr;
- XvAttributePtr pAttribute, pat;
- KdVideoFormatPtr formatPtr;
- XvFormatPtr pFormat, pf;
- int numFormat, totFormat;
- KdVideoEncodingPtr encodingPtr;
- XvEncodingPtr pEncode, pe;
- KdImagePtr imagePtr;
- XvImagePtr pImage, pi;
- int numVisuals;
- VisualPtr pVisual;
- int i;
-
- pxvs->nAdaptors = 0;
- pxvs->pAdaptors = NULL;
-
- if(!(pAdaptor = xcalloc(number, sizeof(XvAdaptorRec))))
- return FALSE;
-
- for(pa = pAdaptor, na = 0, numAdaptor = 0; na < number; na++, adaptorPtr++) {
- adaptorPtr = infoPtr[na];
-
- if(!adaptorPtr->StopVideo || !adaptorPtr->SetPortAttribute ||
- !adaptorPtr->GetPortAttribute || !adaptorPtr->QueryBestSize)
- continue;
-
- /* client libs expect at least one encoding */
- if(!adaptorPtr->nEncodings || !adaptorPtr->pEncodings)
- continue;
-
- pa->type = adaptorPtr->type;
-
- if(!adaptorPtr->PutVideo && !adaptorPtr->GetVideo)
- pa->type &= ~XvVideoMask;
-
- if(!adaptorPtr->PutStill && !adaptorPtr->GetStill)
- pa->type &= ~XvStillMask;
-
- if(!adaptorPtr->PutImage || !adaptorPtr->QueryImageAttributes)
- pa->type &= ~XvImageMask;
-
- if(!adaptorPtr->PutVideo && !adaptorPtr->PutImage &&
- !adaptorPtr->PutStill)
- pa->type &= ~XvInputMask;
-
- if(!adaptorPtr->GetVideo && !adaptorPtr->GetStill)
- pa->type &= ~XvOutputMask;
-
- if(!(adaptorPtr->type & (XvPixmapMask | XvWindowMask)))
- continue;
- if(!(adaptorPtr->type & (XvImageMask | XvVideoMask | XvStillMask)))
- continue;
-
- pa->pScreen = pScreen;
- pa->ddAllocatePort = KdXVAllocatePort;
- pa->ddFreePort = KdXVFreePort;
- pa->ddPutVideo = KdXVPutVideo;
- pa->ddPutStill = KdXVPutStill;
- pa->ddGetVideo = KdXVGetVideo;
- pa->ddGetStill = KdXVGetStill;
- pa->ddStopVideo = KdXVStopVideo;
- pa->ddPutImage = KdXVPutImage;
- pa->ddSetPortAttribute = KdXVSetPortAttribute;
- pa->ddGetPortAttribute = KdXVGetPortAttribute;
- pa->ddQueryBestSize = KdXVQueryBestSize;
- pa->ddQueryImageAttributes = KdXVQueryImageAttributes;
- if((pa->name = xalloc(strlen(adaptorPtr->name) + 1)))
- strcpy(pa->name, adaptorPtr->name);
-
- if(adaptorPtr->nEncodings &&
- (pEncode = xcalloc(adaptorPtr->nEncodings, sizeof(XvEncodingRec)))) {
-
- for(pe = pEncode, encodingPtr = adaptorPtr->pEncodings, i = 0;
- i < adaptorPtr->nEncodings; pe++, i++, encodingPtr++)
- {
- pe->id = encodingPtr->id;
- pe->pScreen = pScreen;
- if((pe->name = xalloc(strlen(encodingPtr->name) + 1)))
- strcpy(pe->name, encodingPtr->name);
- pe->width = encodingPtr->width;
- pe->height = encodingPtr->height;
- pe->rate.numerator = encodingPtr->rate.numerator;
- pe->rate.denominator = encodingPtr->rate.denominator;
- }
- pa->nEncodings = adaptorPtr->nEncodings;
- pa->pEncodings = pEncode;
- }
-
- if(adaptorPtr->nImages &&
- (pImage = xcalloc(adaptorPtr->nImages, sizeof(XvImageRec)))) {
-
- for(i = 0, pi = pImage, imagePtr = adaptorPtr->pImages;
- i < adaptorPtr->nImages; i++, pi++, imagePtr++)
- {
- pi->id = imagePtr->id;
- pi->type = imagePtr->type;
- pi->byte_order = imagePtr->byte_order;
- memcpy(pi->guid, imagePtr->guid, 16);
- pi->bits_per_pixel = imagePtr->bits_per_pixel;
- pi->format = imagePtr->format;
- pi->num_planes = imagePtr->num_planes;
- pi->depth = imagePtr->depth;
- pi->red_mask = imagePtr->red_mask;
- pi->green_mask = imagePtr->green_mask;
- pi->blue_mask = imagePtr->blue_mask;
- pi->y_sample_bits = imagePtr->y_sample_bits;
- pi->u_sample_bits = imagePtr->u_sample_bits;
- pi->v_sample_bits = imagePtr->v_sample_bits;
- pi->horz_y_period = imagePtr->horz_y_period;
- pi->horz_u_period = imagePtr->horz_u_period;
- pi->horz_v_period = imagePtr->horz_v_period;
- pi->vert_y_period = imagePtr->vert_y_period;
- pi->vert_u_period = imagePtr->vert_u_period;
- pi->vert_v_period = imagePtr->vert_v_period;
- memcpy(pi->component_order, imagePtr->component_order, 32);
- pi->scanline_order = imagePtr->scanline_order;
- }
- pa->nImages = adaptorPtr->nImages;
- pa->pImages = pImage;
- }
-
- if(adaptorPtr->nAttributes &&
- (pAttribute = xcalloc(adaptorPtr->nAttributes, sizeof(XvAttributeRec))))
- {
- for(pat = pAttribute, attributePtr = adaptorPtr->pAttributes, i = 0;
- i < adaptorPtr->nAttributes; pat++, i++, attributePtr++)
- {
- pat->flags = attributePtr->flags;
- pat->min_value = attributePtr->min_value;
- pat->max_value = attributePtr->max_value;
- if((pat->name = xalloc(strlen(attributePtr->name) + 1)))
- strcpy(pat->name, attributePtr->name);
- }
- pa->nAttributes = adaptorPtr->nAttributes;
- pa->pAttributes = pAttribute;
- }
-
-
- totFormat = adaptorPtr->nFormats;
-
- if(!(pFormat = xcalloc(totFormat, sizeof(XvFormatRec)))) {
- KdXVFreeAdaptor(pa);
- continue;
- }
- for(pf = pFormat, i = 0, numFormat = 0, formatPtr = adaptorPtr->pFormats;
- i < adaptorPtr->nFormats; i++, formatPtr++)
- {
- numVisuals = pScreen->numVisuals;
- pVisual = pScreen->visuals;
-
- while(numVisuals--) {
- if((pVisual->class == formatPtr->class) &&
- (pVisual->nplanes == formatPtr->depth)) {
-
- if(numFormat >= totFormat) {
- void *moreSpace;
- totFormat *= 2;
- moreSpace = xrealloc(pFormat,
- totFormat * sizeof(XvFormatRec));
- if(!moreSpace) break;
- pFormat = moreSpace;
- pf = pFormat + numFormat;
- }
-
- pf->visual = pVisual->vid;
- pf->depth = formatPtr->depth;
-
- pf++;
- numFormat++;
- }
- pVisual++;
- }
- }
- pa->nFormats = numFormat;
- pa->pFormats = pFormat;
- if(!numFormat) {
- KdXVFreeAdaptor(pa);
- continue;
- }
-
- if(!(adaptorPriv = xcalloc(1, sizeof(XvAdaptorRecPrivate)))) {
- KdXVFreeAdaptor(pa);
- continue;
- }
-
- adaptorPriv->flags = adaptorPtr->flags;
- adaptorPriv->PutVideo = adaptorPtr->PutVideo;
- adaptorPriv->PutStill = adaptorPtr->PutStill;
- adaptorPriv->GetVideo = adaptorPtr->GetVideo;
- adaptorPriv->GetStill = adaptorPtr->GetStill;
- adaptorPriv->StopVideo = adaptorPtr->StopVideo;
- adaptorPriv->SetPortAttribute = adaptorPtr->SetPortAttribute;
- adaptorPriv->GetPortAttribute = adaptorPtr->GetPortAttribute;
- adaptorPriv->QueryBestSize = adaptorPtr->QueryBestSize;
- adaptorPriv->QueryImageAttributes = adaptorPtr->QueryImageAttributes;
- adaptorPriv->PutImage = adaptorPtr->PutImage;
- adaptorPriv->ReputImage = adaptorPtr->ReputImage;
-
- pa->devPriv.ptr = (pointer)adaptorPriv;
-
- if(!(pPort = xcalloc(adaptorPtr->nPorts, sizeof(XvPortRec)))) {
- KdXVFreeAdaptor(pa);
- continue;
- }
- for(pp = pPort, i = 0, numPort = 0;
- i < adaptorPtr->nPorts; i++) {
-
- if(!(pp->id = FakeClientID(0)))
- continue;
-
- if(!(portPriv = xcalloc(1, sizeof(XvPortRecPrivate))))
- continue;
-
- if(!AddResource(pp->id, PortResource, pp)) {
- xfree(portPriv);
- continue;
- }
-
- pp->pAdaptor = pa;
- pp->pNotify = (XvPortNotifyPtr)NULL;
- pp->pDraw = (DrawablePtr)NULL;
- pp->client = (ClientPtr)NULL;
- pp->grab.client = (ClientPtr)NULL;
- pp->time = currentTime;
- pp->devPriv.ptr = portPriv;
-
- portPriv->screen = screen;
- portPriv->AdaptorRec = adaptorPriv;
- portPriv->DevPriv.ptr = adaptorPtr->pPortPrivates[i].ptr;
-
- pp++;
- numPort++;
- }
- pa->nPorts = numPort;
- pa->pPorts = pPort;
- if(!numPort) {
- KdXVFreeAdaptor(pa);
- continue;
- }
-
- pa->base_id = pPort->id;
-
- pa++;
- numAdaptor++;
- }
-
- if(numAdaptor) {
- pxvs->nAdaptors = numAdaptor;
- pxvs->pAdaptors = pAdaptor;
- } else {
- xfree(pAdaptor);
- return FALSE;
- }
-
- return TRUE;
-}
-
-/* Video should be clipped to the intersection of the window cliplist
- and the client cliplist specified in the GC for which the video was
- initialized. When we need to reclip a window, the GC that started
- the video may not even be around anymore. That's why we save the
- client clip from the GC when the video is initialized. We then
- use KdXVUpdateCompositeClip to calculate the new composite clip
- when we need it. This is different from what DEC did. They saved
- the GC and used it's clip list when they needed to reclip the window,
- even if the client clip was different from the one the video was
- initialized with. If the original GC was destroyed, they had to stop
- the video. I like the new method better (MArk).
-
- This function only works for windows. Will need to rewrite when
- (if) we support pixmap rendering.
-*/
-
-static void
-KdXVUpdateCompositeClip(XvPortRecPrivatePtr portPriv)
-{
- RegionPtr pregWin, pCompositeClip;
- WindowPtr pWin;
- Bool freeCompClip = FALSE;
-
- if(portPriv->pCompositeClip)
- return;
-
- pWin = (WindowPtr)portPriv->pDraw;
-
- /* get window clip list */
- if(portPriv->subWindowMode == IncludeInferiors) {
- pregWin = NotClippedByChildren(pWin);
- freeCompClip = TRUE;
- } else
- pregWin = &pWin->clipList;
-
- if(!portPriv->clientClip) {
- portPriv->pCompositeClip = pregWin;
- portPriv->FreeCompositeClip = freeCompClip;
- return;
- }
-
- pCompositeClip = REGION_CREATE(pWin->pScreen, NullBox, 1);
- REGION_COPY(pWin->pScreen, pCompositeClip, portPriv->clientClip);
- REGION_TRANSLATE(pWin->pScreen, pCompositeClip,
- portPriv->pDraw->x + portPriv->clipOrg.x,
- portPriv->pDraw->y + portPriv->clipOrg.y);
- REGION_INTERSECT(pWin->pScreen, pCompositeClip, pregWin, pCompositeClip);
-
- portPriv->pCompositeClip = pCompositeClip;
- portPriv->FreeCompositeClip = TRUE;
-
- if(freeCompClip) {
- REGION_DESTROY(pWin->pScreen, pregWin);
- }
-}
-
-/* Save the current clientClip and update the CompositeClip whenever
- we have a fresh GC */
-
-static void
-KdXVCopyClip(
- XvPortRecPrivatePtr portPriv,
- GCPtr pGC
-){
- /* copy the new clip if it exists */
- if((pGC->clientClipType == CT_REGION) && pGC->clientClip) {
- if(!portPriv->clientClip)
- portPriv->clientClip = REGION_CREATE(pGC->pScreen, NullBox, 1);
- /* Note: this is in window coordinates */
- REGION_COPY(pGC->pScreen, portPriv->clientClip, pGC->clientClip);
- } else if(portPriv->clientClip) { /* free the old clientClip */
- REGION_DESTROY(pGC->pScreen, portPriv->clientClip);
- portPriv->clientClip = NULL;
- }
-
- /* get rid of the old clip list */
- if(portPriv->pCompositeClip && portPriv->FreeCompositeClip) {
- REGION_DESTROY(pWin->pScreen, portPriv->pCompositeClip);
- }
-
- portPriv->clipOrg = pGC->clipOrg;
- portPriv->pCompositeClip = pGC->pCompositeClip;
- portPriv->FreeCompositeClip = FALSE;
- portPriv->subWindowMode = pGC->subWindowMode;
-}
-
-static int
-KdXVRegetVideo(XvPortRecPrivatePtr portPriv)
-{
- RegionRec WinRegion;
- RegionRec ClipRegion;
- BoxRec WinBox;
- int ret = Success;
- Bool clippedAway = FALSE;
-
- KdXVUpdateCompositeClip(portPriv);
-
- /* translate the video region to the screen */
- WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
- WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
- WinBox.x2 = WinBox.x1 + portPriv->drw_w;
- WinBox.y2 = WinBox.y1 + portPriv->drw_h;
-
- /* clip to the window composite clip */
- REGION_INIT(portPriv->pDraw->pScreen, &WinRegion, &WinBox, 1);
- REGION_INIT(portPriv->pDraw->pScreen, &ClipRegion, NullBox, 1);
- REGION_INTERSECT(portPriv->pDraw->pScreen, &ClipRegion, &WinRegion, portPriv->pCompositeClip);
-
- /* that's all if it's totally obscured */
- if(!REGION_NOTEMPTY(portPriv->pDraw->pScreen, &ClipRegion)) {
- clippedAway = TRUE;
- goto CLIP_VIDEO_BAILOUT;
- }
-
- if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
- REGION_SUBTRACT(portPriv->pDraw->pScreen, &ClipRegion, &WinRegion, &ClipRegion);
- }
-
- ret = (*portPriv->AdaptorRec->GetVideo)(portPriv->screen, portPriv->pDraw,
- portPriv->vid_x, portPriv->vid_y,
- WinBox.x1, WinBox.y1,
- portPriv->vid_w, portPriv->vid_h,
- portPriv->drw_w, portPriv->drw_h,
- &ClipRegion, portPriv->DevPriv.ptr);
-
- if(ret == Success)
- portPriv->isOn = XV_ON;
-
-CLIP_VIDEO_BAILOUT:
-
- if((clippedAway || (ret != Success)) && portPriv->isOn == XV_ON) {
- (*portPriv->AdaptorRec->StopVideo)(
- portPriv->screen, portPriv->DevPriv.ptr, FALSE);
- portPriv->isOn = XV_PENDING;
- }
-
- /* This clip was copied and only good for one shot */
- if(!portPriv->FreeCompositeClip)
- portPriv->pCompositeClip = NULL;
-
- REGION_UNINIT(portPriv->pDraw->pScreen, &WinRegion);
- REGION_UNINIT(portPriv->pDraw->pScreen, &ClipRegion);
-
- return ret;
-}
-
-
-static int
-KdXVReputVideo(XvPortRecPrivatePtr portPriv)
-{
- RegionRec WinRegion;
- RegionRec ClipRegion;
- BoxRec WinBox;
- ScreenPtr pScreen = portPriv->pDraw->pScreen;
- KdScreenPriv(pScreen);
- KdScreenInfo *screen=pScreenPriv->screen;
- int ret = Success;
- Bool clippedAway = FALSE;
-
- KdXVUpdateCompositeClip(portPriv);
-
- /* translate the video region to the screen */
- WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
- WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
- WinBox.x2 = WinBox.x1 + portPriv->drw_w;
- WinBox.y2 = WinBox.y1 + portPriv->drw_h;
-
- /* clip to the window composite clip */
- REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
- REGION_INIT(pScreen, &ClipRegion, NullBox, 1);
- REGION_INTERSECT(Screen, &ClipRegion, &WinRegion, portPriv->pCompositeClip);
-
- /* clip and translate to the viewport */
- if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
- RegionRec VPReg;
- BoxRec VPBox;
-
- VPBox.x1 = 0;
- VPBox.y1 = 0;
- VPBox.x2 = screen->width;
- VPBox.y2 = screen->height;
-
- REGION_INIT(pScreen, &VPReg, &VPBox, 1);
- REGION_INTERSECT(Screen, &ClipRegion, &ClipRegion, &VPReg);
- REGION_UNINIT(pScreen, &VPReg);
- }
-
- /* that's all if it's totally obscured */
- if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
- clippedAway = TRUE;
- goto CLIP_VIDEO_BAILOUT;
- }
-
- /* bailout if we have to clip but the hardware doesn't support it */
- if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) {
- BoxPtr clipBox = REGION_RECTS(&ClipRegion);
- if( (REGION_NUM_RECTS(&ClipRegion) != 1) ||
- (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) ||
- (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2))
- {
- clippedAway = TRUE;
- goto CLIP_VIDEO_BAILOUT;
- }
- }
-
- if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
- REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
- }
-
- ret = (*portPriv->AdaptorRec->PutVideo)(portPriv->screen, portPriv->pDraw,
- portPriv->vid_x, portPriv->vid_y,
- WinBox.x1, WinBox.y1,
- portPriv->vid_w, portPriv->vid_h,
- portPriv->drw_w, portPriv->drw_h,
- &ClipRegion, portPriv->DevPriv.ptr);
-
- if(ret == Success) portPriv->isOn = XV_ON;
-
-CLIP_VIDEO_BAILOUT:
-
- if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
- (*portPriv->AdaptorRec->StopVideo)(
- portPriv->screen, portPriv->DevPriv.ptr, FALSE);
- portPriv->isOn = XV_PENDING;
- }
-
- /* This clip was copied and only good for one shot */
- if(!portPriv->FreeCompositeClip)
- portPriv->pCompositeClip = NULL;
-
- REGION_UNINIT(pScreen, &WinRegion);
- REGION_UNINIT(pScreen, &ClipRegion);
-
- return ret;
-}
-
-static int
-KdXVReputImage(XvPortRecPrivatePtr portPriv)
-{
- RegionRec WinRegion;
- RegionRec ClipRegion;
- BoxRec WinBox;
- ScreenPtr pScreen = portPriv->pDraw->pScreen;
- KdScreenPriv(pScreen);
- KdScreenInfo *screen=pScreenPriv->screen;
- int ret = Success;
- Bool clippedAway = FALSE;
-
- KdXVUpdateCompositeClip(portPriv);
-
- /* translate the video region to the screen */
- WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
- WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
- WinBox.x2 = WinBox.x1 + portPriv->drw_w;
- WinBox.y2 = WinBox.y1 + portPriv->drw_h;
-
- /* clip to the window composite clip */
- REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
- REGION_INIT(pScreen, &ClipRegion, NullBox, 1);
- REGION_INTERSECT(Screen, &ClipRegion, &WinRegion, portPriv->pCompositeClip);
-
- /* clip and translate to the viewport */
- if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
- RegionRec VPReg;
- BoxRec VPBox;
-
- VPBox.x1 = 0;
- VPBox.y1 = 0;
- VPBox.x2 = screen->width;
- VPBox.y2 = screen->height;
-
- REGION_INIT(pScreen, &VPReg, &VPBox, 1);
- REGION_INTERSECT(Screen, &ClipRegion, &ClipRegion, &VPReg);
- REGION_UNINIT(pScreen, &VPReg);
- }
-
- /* that's all if it's totally obscured */
- if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
- clippedAway = TRUE;
- goto CLIP_VIDEO_BAILOUT;
- }
-
- /* bailout if we have to clip but the hardware doesn't support it */
- if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) {
- BoxPtr clipBox = REGION_RECTS(&ClipRegion);
- if( (REGION_NUM_RECTS(&ClipRegion) != 1) ||
- (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) ||
- (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2))
- {
- clippedAway = TRUE;
- goto CLIP_VIDEO_BAILOUT;
- }
- }
-
- if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
- REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
- }
-
- ret = (*portPriv->AdaptorRec->ReputImage)(portPriv->screen, portPriv->pDraw,
- WinBox.x1, WinBox.y1,
- &ClipRegion, portPriv->DevPriv.ptr);
-
- portPriv->isOn = (ret == Success) ? XV_ON : XV_OFF;
-
-CLIP_VIDEO_BAILOUT:
-
- if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
- (*portPriv->AdaptorRec->StopVideo)(
- portPriv->screen, portPriv->DevPriv.ptr, FALSE);
- portPriv->isOn = XV_PENDING;
- }
-
- /* This clip was copied and only good for one shot */
- if(!portPriv->FreeCompositeClip)
- portPriv->pCompositeClip = NULL;
-
- REGION_UNINIT(pScreen, &WinRegion);
- REGION_UNINIT(pScreen, &ClipRegion);
-
- return ret;
-}
-
-
-static int
-KdXVReputAllVideo(WindowPtr pWin, pointer data)
-{
- KdXVWindowPtr WinPriv;
-
- if (pWin->drawable.type != DRAWABLE_WINDOW)
- return WT_DONTWALKCHILDREN;
-
- WinPriv = GET_KDXV_WINDOW(pWin);
-
- while(WinPriv) {
- if(WinPriv->PortRec->type == XvInputMask)
- KdXVReputVideo(WinPriv->PortRec);
- else
- KdXVRegetVideo(WinPriv->PortRec);
- WinPriv = WinPriv->next;
- }
-
- return WT_WALKCHILDREN;
-}
-
-static int
-KdXVEnlistPortInWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv)
-{
- KdXVWindowPtr winPriv, PrivRoot;
-
- winPriv = PrivRoot = GET_KDXV_WINDOW(pWin);
-
- /* Enlist our port in the window private */
- while(winPriv) {
- if(winPriv->PortRec == portPriv) /* we're already listed */
- break;
- winPriv = winPriv->next;
- }
-
- if(!winPriv) {
- winPriv = xalloc(sizeof(KdXVWindowRec));
- if(!winPriv) return BadAlloc;
- winPriv->PortRec = portPriv;
- winPriv->next = PrivRoot;
- dixSetPrivate(&pWin->devPrivates, KdXVWindowKey, winPriv);
- }
- return Success;
-}
-
-
-static void
-KdXVRemovePortFromWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv)
-{
- KdXVWindowPtr winPriv, prevPriv = NULL;
-
- winPriv = GET_KDXV_WINDOW(pWin);
-
- while(winPriv) {
- if(winPriv->PortRec == portPriv) {
- if(prevPriv)
- prevPriv->next = winPriv->next;
- else
- dixSetPrivate(&pWin->devPrivates, KdXVWindowKey, winPriv->next);
- xfree(winPriv);
- break;
- }
- prevPriv = winPriv;
- winPriv = winPriv->next;
- }
- portPriv->pDraw = NULL;
-}
-
-/**** ScreenRec fields ****/
-
-
-static Bool
-KdXVCreateWindow(WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- KdXVScreenPtr ScreenPriv = GET_KDXV_SCREEN(pScreen);
- int ret;
-
- pScreen->CreateWindow = ScreenPriv->CreateWindow;
- ret = (*pScreen->CreateWindow)(pWin);
- pScreen->CreateWindow = KdXVCreateWindow;
-
- if (ret)
- dixSetPrivate(&pWin->devPrivates, KdXVWindowKey, NULL);
-
- return ret;
-}
-
-
-static Bool
-KdXVDestroyWindow(WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- KdXVScreenPtr ScreenPriv = GET_KDXV_SCREEN(pScreen);
- KdXVWindowPtr tmp, WinPriv = GET_KDXV_WINDOW(pWin);
- int ret;
-
- while(WinPriv) {
- XvPortRecPrivatePtr pPriv = WinPriv->PortRec;
-
- if(pPriv->isOn > XV_OFF) {
- (*pPriv->AdaptorRec->StopVideo)(
- pPriv->screen, pPriv->DevPriv.ptr, TRUE);
- pPriv->isOn = XV_OFF;
- }
-
- pPriv->pDraw = NULL;
- tmp = WinPriv;
- WinPriv = WinPriv->next;
- xfree(tmp);
- }
-
- dixSetPrivate(&pWin->devPrivates, KdXVWindowKey, NULL);
-
- pScreen->DestroyWindow = ScreenPriv->DestroyWindow;
- ret = (*pScreen->DestroyWindow)(pWin);
- pScreen->DestroyWindow = KdXVDestroyWindow;
-
- return ret;
-}
-
-
-static void
-KdXVWindowExposures(WindowPtr pWin, RegionPtr reg1, RegionPtr reg2)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- KdXVScreenPtr ScreenPriv = GET_KDXV_SCREEN(pScreen);
- KdXVWindowPtr WinPriv = GET_KDXV_WINDOW(pWin);
- KdXVWindowPtr pPrev;
- XvPortRecPrivatePtr pPriv;
- Bool AreasExposed;
-
- AreasExposed = (WinPriv && reg1 && REGION_NOTEMPTY(pScreen, reg1));
-
- pScreen->WindowExposures = ScreenPriv->WindowExposures;
- (*pScreen->WindowExposures)(pWin, reg1, reg2);
- pScreen->WindowExposures = KdXVWindowExposures;
-
- /* filter out XClearWindow/Area */
- if (!pWin->valdata) return;
-
- pPrev = NULL;
-
- while(WinPriv) {
- pPriv = WinPriv->PortRec;
-
- /* Reput anyone with a reput function */
-
- switch(pPriv->type) {
- case XvInputMask:
- KdXVReputVideo(pPriv);
- break;
- case XvOutputMask:
- KdXVRegetVideo(pPriv);
- break;
- default: /* overlaid still/image*/
- if (pPriv->AdaptorRec->ReputImage)
- KdXVReputImage(pPriv);
- else if(AreasExposed) {
- KdXVWindowPtr tmp;
-
- if (pPriv->isOn == XV_ON) {
- (*pPriv->AdaptorRec->StopVideo)(
- pPriv->screen, pPriv->DevPriv.ptr, FALSE);
- pPriv->isOn = XV_PENDING;
- }
- pPriv->pDraw = NULL;
-
- if(!pPrev)
- dixSetPrivate(&pWin->devPrivates, KdXVWindowKey, WinPriv->next);
- else
- pPrev->next = WinPriv->next;
- tmp = WinPriv;
- WinPriv = WinPriv->next;
- xfree(tmp);
- continue;
- }
- break;
- }
- pPrev = WinPriv;
- WinPriv = WinPriv->next;
- }
-}
-
-
-static void
-KdXVClipNotify(WindowPtr pWin, int dx, int dy)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- KdXVScreenPtr ScreenPriv = GET_KDXV_SCREEN(pScreen);
- KdXVWindowPtr WinPriv = GET_KDXV_WINDOW(pWin);
- KdXVWindowPtr tmp, pPrev = NULL;
- XvPortRecPrivatePtr pPriv;
- Bool visible = (pWin->visibility == VisibilityUnobscured) ||
- (pWin->visibility == VisibilityPartiallyObscured);
-
- while(WinPriv) {
- pPriv = WinPriv->PortRec;
-
- if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
- REGION_DESTROY(pScreen, pPriv->pCompositeClip);
-
- pPriv->pCompositeClip = NULL;
-
- /* Stop everything except images, but stop them too if the
- window isn't visible. But we only remove the images. */
-
- if(pPriv->type || !visible) {
- if(pPriv->isOn == XV_ON) {
- (*pPriv->AdaptorRec->StopVideo)(
- pPriv->screen, pPriv->DevPriv.ptr, FALSE);
- pPriv->isOn = XV_PENDING;
- }
-
- if(!pPriv->type) { /* overlaid still/image */
- pPriv->pDraw = NULL;
-
- if(!pPrev)
- dixSetPrivate(&pWin->devPrivates, KdXVWindowKey, WinPriv->next);
- else
- pPrev->next = WinPriv->next;
- tmp = WinPriv;
- WinPriv = WinPriv->next;
- xfree(tmp);
- continue;
- }
- }
-
- pPrev = WinPriv;
- WinPriv = WinPriv->next;
- }
-
- if(ScreenPriv->ClipNotify) {
- pScreen->ClipNotify = ScreenPriv->ClipNotify;
- (*pScreen->ClipNotify)(pWin, dx, dy);
- pScreen->ClipNotify = KdXVClipNotify;
- }
-}
-
-
-
-/**** Required XvScreenRec fields ****/
-
-static Bool
-KdXVCloseScreen(int i, ScreenPtr pScreen)
-{
- XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
- KdXVScreenPtr ScreenPriv = GET_KDXV_SCREEN(pScreen);
- XvAdaptorPtr pa;
- int c;
-
- if(!ScreenPriv) return TRUE;
-
- pScreen->CreateWindow = ScreenPriv->CreateWindow;
- pScreen->DestroyWindow = ScreenPriv->DestroyWindow;
- pScreen->WindowExposures = ScreenPriv->WindowExposures;
- pScreen->ClipNotify = ScreenPriv->ClipNotify;
-
-/* fprintf(stderr,"XV: Unwrapping screen funcs\n"); */
-
- for(c = 0, pa = pxvs->pAdaptors; c < pxvs->nAdaptors; c++, pa++) {
- KdXVFreeAdaptor(pa);
- }
-
- xfree(pxvs->pAdaptors);
- xfree(ScreenPriv);
-
- return TRUE;
-}
-
-
-static int
-KdXVQueryAdaptors(
- ScreenPtr pScreen,
- XvAdaptorPtr *p_pAdaptors,
- int *p_nAdaptors
-){
- XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
-
- *p_nAdaptors = pxvs->nAdaptors;
- *p_pAdaptors = pxvs->pAdaptors;
-
- return (Success);
-}
-
-static Bool
-KdXVRunning (ScreenPtr pScreen)
-{
- return (KdXVGeneration == serverGeneration &&
- GET_XV_SCREEN(pScreen) != 0);
-}
-
-Bool
-KdXVEnable(ScreenPtr pScreen)
-{
- if (!KdXVRunning (pScreen))
- return TRUE;
-
- WalkTree(pScreen, KdXVReputAllVideo, 0);
-
- return TRUE;
-}
-
-void
-KdXVDisable(ScreenPtr pScreen)
-{
- XvScreenPtr pxvs;
- KdXVScreenPtr ScreenPriv;
- XvAdaptorPtr pAdaptor;
- XvPortPtr pPort;
- XvPortRecPrivatePtr pPriv;
- int i, j;
-
- if (!KdXVRunning (pScreen))
- return;
-
- pxvs = GET_XV_SCREEN(pScreen);
- ScreenPriv = GET_KDXV_SCREEN(pScreen);
-
- for(i = 0; i < pxvs->nAdaptors; i++) {
- pAdaptor = &pxvs->pAdaptors[i];
- for(j = 0; j < pAdaptor->nPorts; j++) {
- pPort = &pAdaptor->pPorts[j];
- pPriv = (XvPortRecPrivatePtr)pPort->devPriv.ptr;
- if(pPriv->isOn > XV_OFF) {
-
- (*pPriv->AdaptorRec->StopVideo)(
- pPriv->screen, pPriv->DevPriv.ptr, TRUE);
- pPriv->isOn = XV_OFF;
-
- if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
- REGION_DESTROY(pScreen, pPriv->pCompositeClip);
-
- pPriv->pCompositeClip = NULL;
-
- if(!pPriv->type && pPriv->pDraw) { /* still */
- KdXVRemovePortFromWindow((WindowPtr)pPriv->pDraw, pPriv);
- }
- }
- }
- }
-}
-
-/**** XvAdaptorRec fields ****/
-
-static int
-KdXVAllocatePort(
- unsigned long port,
- XvPortPtr pPort,
- XvPortPtr *ppPort
-){
- *ppPort = pPort;
- return Success;
-}
-
-static int
-KdXVFreePort(XvPortPtr pPort)
-{
- return Success;
-}
-
-static int
-KdXVPutVideo(
- ClientPtr client,
- DrawablePtr pDraw,
- XvPortPtr pPort,
- GCPtr pGC,
- INT16 vid_x, INT16 vid_y,
- CARD16 vid_w, CARD16 vid_h,
- INT16 drw_x, INT16 drw_y,
- CARD16 drw_w, CARD16 drw_h
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
- KdScreenPriv(portPriv->screen->pScreen);
- int result;
-
- /* No dumping video to pixmaps... For now anyhow */
- if(pDraw->type != DRAWABLE_WINDOW) {
- pPort->pDraw = (DrawablePtr)NULL;
- return BadAlloc;
- }
-
- /* If we are changing windows, unregister our port in the old window */
- if(portPriv->pDraw && (portPriv->pDraw != pDraw))
- KdXVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
-
- /* Register our port with the new window */
- result = KdXVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
- if(result != Success) return result;
-
- portPriv->pDraw = pDraw;
- portPriv->type = XvInputMask;
-
- /* save a copy of these parameters */
- portPriv->vid_x = vid_x; portPriv->vid_y = vid_y;
- portPriv->vid_w = vid_w; portPriv->vid_h = vid_h;
- portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
- portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
-
- /* make sure we have the most recent copy of the clientClip */
- KdXVCopyClip(portPriv, pGC);
-
- /* To indicate to the DI layer that we were successful */
- pPort->pDraw = pDraw;
-
- if (!pScreenPriv->enabled) return Success;
-
- return(KdXVReputVideo(portPriv));
-}
-
-static int
-KdXVPutStill(
- ClientPtr client,
- DrawablePtr pDraw,
- XvPortPtr pPort,
- GCPtr pGC,
- INT16 vid_x, INT16 vid_y,
- CARD16 vid_w, CARD16 vid_h,
- INT16 drw_x, INT16 drw_y,
- CARD16 drw_w, CARD16 drw_h
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
- ScreenPtr pScreen = pDraw->pScreen;
- KdScreenPriv(pScreen);
- KdScreenInfo *screen=pScreenPriv->screen;
- RegionRec WinRegion;
- RegionRec ClipRegion;
- BoxRec WinBox;
- int ret = Success;
- Bool clippedAway = FALSE;
-
- if (pDraw->type != DRAWABLE_WINDOW)
- return BadAlloc;
-
- if (!pScreenPriv->enabled) return Success;
-
- WinBox.x1 = pDraw->x + drw_x;
- WinBox.y1 = pDraw->y + drw_y;
- WinBox.x2 = WinBox.x1 + drw_w;
- WinBox.y2 = WinBox.y1 + drw_h;
-
- REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
- REGION_INIT(pScreen, &ClipRegion, NullBox, 1);
- REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, pGC->pCompositeClip);
-
- if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
- RegionRec VPReg;
- BoxRec VPBox;
-
- VPBox.x1 = 0;
- VPBox.y1 = 0;
- VPBox.x2 = screen->width;
- VPBox.y2 = screen->height;
-
- REGION_INIT(pScreen, &VPReg, &VPBox, 1);
- REGION_INTERSECT(Screen, &ClipRegion, &ClipRegion, &VPReg);
- REGION_UNINIT(pScreen, &VPReg);
- }
-
- if(portPriv->pDraw) {
- KdXVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
- }
-
- if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
- clippedAway = TRUE;
- goto PUT_STILL_BAILOUT;
- }
-
- if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) {
- BoxPtr clipBox = REGION_RECTS(&ClipRegion);
- if( (REGION_NUM_RECTS(&ClipRegion) != 1) ||
- (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) ||
- (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2))
- {
- clippedAway = TRUE;
- goto PUT_STILL_BAILOUT;
- }
- }
-
- if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
- REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
- }
-
- ret = (*portPriv->AdaptorRec->PutStill)(portPriv->screen, pDraw,
- vid_x, vid_y, WinBox.x1, WinBox.y1,
- vid_w, vid_h, drw_w, drw_h,
- &ClipRegion, portPriv->DevPriv.ptr);
-
- if((ret == Success) &&
- (portPriv->AdaptorRec->flags & VIDEO_OVERLAID_STILLS)) {
-
- KdXVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
- portPriv->isOn = XV_ON;
- portPriv->pDraw = pDraw;
- portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
- portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
- portPriv->type = 0; /* no mask means it's transient and should
- not be reput once it's removed */
- pPort->pDraw = pDraw; /* make sure we can get stop requests */
- }
-
-PUT_STILL_BAILOUT:
-
- if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
- (*portPriv->AdaptorRec->StopVideo)(
- portPriv->screen, portPriv->DevPriv.ptr, FALSE);
- portPriv->isOn = XV_PENDING;
- }
-
- REGION_UNINIT(pScreen, &WinRegion);
- REGION_UNINIT(pScreen, &ClipRegion);
-
- return ret;
-}
-
-static int
-KdXVGetVideo(
- ClientPtr client,
- DrawablePtr pDraw,
- XvPortPtr pPort,
- GCPtr pGC,
- INT16 vid_x, INT16 vid_y,
- CARD16 vid_w, CARD16 vid_h,
- INT16 drw_x, INT16 drw_y,
- CARD16 drw_w, CARD16 drw_h
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
- int result;
- KdScreenPriv(portPriv->screen->pScreen);
-
- /* No pixmaps... For now anyhow */
- if(pDraw->type != DRAWABLE_WINDOW) {
- pPort->pDraw = (DrawablePtr)NULL;
- return BadAlloc;
- }
-
- /* If we are changing windows, unregister our port in the old window */
- if(portPriv->pDraw && (portPriv->pDraw != pDraw))
- KdXVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
-
- /* Register our port with the new window */
- result = KdXVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
- if(result != Success) return result;
-
- portPriv->pDraw = pDraw;
- portPriv->type = XvOutputMask;
-
- /* save a copy of these parameters */
- portPriv->vid_x = vid_x; portPriv->vid_y = vid_y;
- portPriv->vid_w = vid_w; portPriv->vid_h = vid_h;
- portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
- portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
-
- /* make sure we have the most recent copy of the clientClip */
- KdXVCopyClip(portPriv, pGC);
-
- /* To indicate to the DI layer that we were successful */
- pPort->pDraw = pDraw;
-
- if(!pScreenPriv->enabled) return Success;
-
- return(KdXVRegetVideo(portPriv));
-}
-
-static int
-KdXVGetStill(
- ClientPtr client,
- DrawablePtr pDraw,
- XvPortPtr pPort,
- GCPtr pGC,
- INT16 vid_x, INT16 vid_y,
- CARD16 vid_w, CARD16 vid_h,
- INT16 drw_x, INT16 drw_y,
- CARD16 drw_w, CARD16 drw_h
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
- ScreenPtr pScreen = pDraw->pScreen;
- KdScreenPriv(pScreen);
- RegionRec WinRegion;
- RegionRec ClipRegion;
- BoxRec WinBox;
- int ret = Success;
- Bool clippedAway = FALSE;
-
- if (pDraw->type != DRAWABLE_WINDOW)
- return BadAlloc;
-
- if(!pScreenPriv->enabled) return Success;
-
- WinBox.x1 = pDraw->x + drw_x;
- WinBox.y1 = pDraw->y + drw_y;
- WinBox.x2 = WinBox.x1 + drw_w;
- WinBox.y2 = WinBox.y1 + drw_h;
-
- REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
- REGION_INIT(pScreen, &ClipRegion, NullBox, 1);
- REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, pGC->pCompositeClip);
-
- if(portPriv->pDraw) {
- KdXVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
- }
-
- if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
- clippedAway = TRUE;
- goto GET_STILL_BAILOUT;
- }
-
- if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
- REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
- }
-
- ret = (*portPriv->AdaptorRec->GetStill)(portPriv->screen, pDraw,
- vid_x, vid_y, WinBox.x1, WinBox.y1,
- vid_w, vid_h, drw_w, drw_h,
- &ClipRegion, portPriv->DevPriv.ptr);
-
-GET_STILL_BAILOUT:
-
- if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
- (*portPriv->AdaptorRec->StopVideo)(
- portPriv->screen, portPriv->DevPriv.ptr, FALSE);
- portPriv->isOn = XV_PENDING;
- }
-
- REGION_UNINIT(pScreen, &WinRegion);
- REGION_UNINIT(pScreen, &ClipRegion);
-
- return ret;
-}
-
-
-
-static int
-KdXVStopVideo(
- ClientPtr client,
- XvPortPtr pPort,
- DrawablePtr pDraw
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
- KdScreenPriv(portPriv->screen->pScreen);
-
- if(pDraw->type != DRAWABLE_WINDOW)
- return BadAlloc;
-
- KdXVRemovePortFromWindow((WindowPtr)pDraw, portPriv);
-
- if(!pScreenPriv->enabled) return Success;
-
- /* Must free resources. */
-
- if(portPriv->isOn > XV_OFF) {
- (*portPriv->AdaptorRec->StopVideo)(
- portPriv->screen, portPriv->DevPriv.ptr, TRUE);
- portPriv->isOn = XV_OFF;
- }
-
- return Success;
-}
-
-static int
-KdXVSetPortAttribute(
- ClientPtr client,
- XvPortPtr pPort,
- Atom attribute,
- INT32 value
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
-
- return((*portPriv->AdaptorRec->SetPortAttribute)(portPriv->screen,
- attribute, value, portPriv->DevPriv.ptr));
-}
-
-
-static int
-KdXVGetPortAttribute(
- ClientPtr client,
- XvPortPtr pPort,
- Atom attribute,
- INT32 *p_value
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
-
- return((*portPriv->AdaptorRec->GetPortAttribute)(portPriv->screen,
- attribute, (int *) p_value, portPriv->DevPriv.ptr));
-}
-
-
-
-static int
-KdXVQueryBestSize(
- ClientPtr client,
- XvPortPtr pPort,
- CARD8 motion,
- CARD16 vid_w, CARD16 vid_h,
- CARD16 drw_w, CARD16 drw_h,
- unsigned int *p_w, unsigned int *p_h
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
-
- (*portPriv->AdaptorRec->QueryBestSize)(portPriv->screen,
- (Bool)motion, vid_w, vid_h, drw_w, drw_h,
- p_w, p_h, portPriv->DevPriv.ptr);
-
- return Success;
-}
-
-
-static int
-KdXVPutImage(
- ClientPtr client,
- DrawablePtr pDraw,
- XvPortPtr pPort,
- GCPtr pGC,
- INT16 src_x, INT16 src_y,
- CARD16 src_w, CARD16 src_h,
- INT16 drw_x, INT16 drw_y,
- CARD16 drw_w, CARD16 drw_h,
- XvImagePtr format,
- unsigned char* data,
- Bool sync,
- CARD16 width, CARD16 height
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
- ScreenPtr pScreen = pDraw->pScreen;
- KdScreenPriv(pScreen);
- RegionRec WinRegion;
- RegionRec ClipRegion;
- BoxRec WinBox;
- int ret = Success;
- Bool clippedAway = FALSE;
-
- if (pDraw->type != DRAWABLE_WINDOW)
- return BadAlloc;
-
- if(!pScreenPriv->enabled) return Success;
-
- WinBox.x1 = pDraw->x + drw_x;
- WinBox.y1 = pDraw->y + drw_y;
- WinBox.x2 = WinBox.x1 + drw_w;
- WinBox.y2 = WinBox.y1 + drw_h;
-
- REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
- REGION_INIT(pScreen, &ClipRegion, NullBox, 1);
- REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, pGC->pCompositeClip);
-
- if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
- RegionRec VPReg;
- BoxRec VPBox;
-
- VPBox.x1 = 0;
- VPBox.y1 = 0;
- VPBox.x2 = pScreen->width;
- VPBox.y2 = pScreen->height;
-
- REGION_INIT(pScreen, &VPReg, &VPBox, 1);
- REGION_INTERSECT(Screen, &ClipRegion, &ClipRegion, &VPReg);
- REGION_UNINIT(pScreen, &VPReg);
- }
-
- if(portPriv->pDraw) {
- KdXVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
- }
-
- if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
- clippedAway = TRUE;
- goto PUT_IMAGE_BAILOUT;
- }
-
- if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) {
- BoxPtr clipBox = REGION_RECTS(&ClipRegion);
- if( (REGION_NUM_RECTS(&ClipRegion) != 1) ||
- (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) ||
- (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2))
- {
- clippedAway = TRUE;
- goto PUT_IMAGE_BAILOUT;
- }
- }
-
- if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
- REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
- }
-
- ret = (*portPriv->AdaptorRec->PutImage)(portPriv->screen, pDraw,
- src_x, src_y, WinBox.x1, WinBox.y1,
- src_w, src_h, drw_w, drw_h, format->id, data, width, height,
- sync, &ClipRegion, portPriv->DevPriv.ptr);
-
- if((ret == Success) &&
- (portPriv->AdaptorRec->flags & VIDEO_OVERLAID_IMAGES)) {
-
- KdXVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
- portPriv->isOn = XV_ON;
- portPriv->pDraw = pDraw;
- portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
- portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
- portPriv->type = 0; /* no mask means it's transient and should
- not be reput once it's removed */
- pPort->pDraw = pDraw; /* make sure we can get stop requests */
- }
-
-PUT_IMAGE_BAILOUT:
-
- if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
- (*portPriv->AdaptorRec->StopVideo)(
- portPriv->screen, portPriv->DevPriv.ptr, FALSE);
- portPriv->isOn = XV_PENDING;
- }
-
- REGION_UNINIT(pScreen, &WinRegion);
- REGION_UNINIT(pScreen, &ClipRegion);
-
- return ret;
-}
-
-
-static int
-KdXVQueryImageAttributes(
- ClientPtr client,
- XvPortPtr pPort,
- XvImagePtr format,
- CARD16 *width,
- CARD16 *height,
- int *pitches,
- int *offsets
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
-
- return (*portPriv->AdaptorRec->QueryImageAttributes)(portPriv->screen,
- format->id, width, height, pitches, offsets);
-}
-
-
-/**************** Common video manipulation functions *******************/
-
-void
-KdXVCopyPackedData(KdScreenInfo *screen, CARD8 *src, CARD8 *dst, int randr,
- int srcPitch, int dstPitch, int srcW, int srcH, int top, int left,
- int h, int w)
-{
- int srcDown = srcPitch, srcRight = 2, srcNext;
- int p;
-
- switch (randr & RR_Rotate_All) {
- case RR_Rotate_0:
- srcDown = srcPitch;
- srcRight = 2;
- break;
- case RR_Rotate_90:
- src += (srcH - 1) * 2;
- srcDown = -2;
- srcRight = srcPitch;
- break;
- case RR_Rotate_180:
- src += srcPitch * (srcH - 1) + (srcW - 1) * 2;
- srcDown = -srcPitch;
- srcRight = -2;
- break;
- case RR_Rotate_270:
- src += srcPitch * (srcW - 1);
- srcDown = 2;
- srcRight = -srcPitch;
- break;
- }
-
- src = src + top * srcDown + left * srcRight;
-
- w >>= 1;
- /* srcRight >>= 1; */
- srcNext = srcRight >> 1;
- while (h--) {
- CARD16 *s = (CARD16 *)src;
- CARD32 *d = (CARD32 *)dst;
- p = w;
- while (p--) {
- *d++ = s[0] | (s[srcNext] << 16);
- s += srcRight;
- }
- src += srcPitch;
- dst += dstPitch;
- }
-}
-
-void
-KdXVCopyPlanarData(KdScreenInfo *screen, CARD8 *src, CARD8 *dst, int randr,
- int srcPitch, int srcPitch2, int dstPitch, int srcW, int srcH, int height,
- int top, int left, int h, int w, int id)
-{
- int i, j;
- CARD8 *src1, *src2, *src3, *dst1;
- int srcDown = srcPitch, srcDown2 = srcPitch2;
- int srcRight = 2, srcRight2 = 1, srcNext = 1;
-
- /* compute source data pointers */
- src1 = src;
- src2 = src1 + height * srcPitch;
- src3 = src2 + (height >> 1) * srcPitch2;
- switch (randr & RR_Rotate_All) {
- case RR_Rotate_0:
- srcDown = srcPitch;
- srcDown2 = srcPitch2;
- srcRight = 2;
- srcRight2 = 1;
- srcNext = 1;
- break;
- case RR_Rotate_90:
- src1 = src1 + srcH - 1;
- src2 = src2 + (srcH >> 1) - 1;
- src3 = src3 + (srcH >> 1) - 1;
- srcDown = -1;
- srcDown2 = -1;
- srcRight = srcPitch * 2;
- srcRight2 = srcPitch2;
- srcNext = srcPitch;
- break;
- case RR_Rotate_180:
- src1 = src1 + srcPitch * (srcH - 1) + (srcW - 1);
- src2 = src2 + srcPitch2 * ((srcH >> 1) - 1) + ((srcW >> 1) - 1);
- src3 = src3 + srcPitch2 * ((srcH >> 1) - 1) + ((srcW >> 1) - 1);
- srcDown = -srcPitch;
- srcDown2 = -srcPitch2;
- srcRight = -2;
- srcRight2 = -1;
- srcNext = -1;
- break;
- case RR_Rotate_270:
- src1 = src1 + srcPitch * (srcW - 1);
- src2 = src2 + srcPitch2 * ((srcW >> 1) - 1);
- src3 = src3 + srcPitch2 * ((srcW >> 1) - 1);
- srcDown = 1;
- srcDown2 = 1;
- srcRight = -srcPitch * 2;
- srcRight2 = -srcPitch2;
- srcNext = -srcPitch;
- break;
- }
-
- /* adjust for origin */
- src1 += top * srcDown + left * srcNext;
- src2 += (top >> 1) * srcDown2 + (left >> 1) * srcRight2;
- src3 += (top >> 1) * srcDown2 + (left >> 1) * srcRight2;
-
- if (id == FOURCC_I420) {
- CARD8 *srct = src2;
- src2 = src3;
- src3 = srct;
- }
-
- dst1 = dst;
-
- w >>= 1;
- for (j = 0; j < h; j++) {
- CARD32 *dst = (CARD32 *)dst1;
- CARD8 *s1l = src1;
- CARD8 *s1r = src1 + srcNext;
- CARD8 *s2 = src2;
- CARD8 *s3 = src3;
-
- for (i = 0; i < w; i++) {
- *dst++ = *s1l | (*s1r << 16) | (*s3 << 8) | (*s2 << 24);
- s1l += srcRight;
- s1r += srcRight;
- s2 += srcRight2;
- s3 += srcRight2;
- }
- src1 += srcDown;
- dst1 += dstPitch;
- if (j & 1) {
- src2 += srcDown2;
- src3 += srcDown2;
- }
- }
-}
-
-void
-KXVPaintRegion (DrawablePtr pDraw, RegionPtr pRgn, Pixel fg)
-{
- GCPtr pGC;
- CARD32 val[2];
- xRectangle *rects, *r;
- BoxPtr pBox = REGION_RECTS (pRgn);
- int nBox = REGION_NUM_RECTS (pRgn);
-
- rects = xalloc (nBox * sizeof (xRectangle));
- if (!rects)
- goto bail0;
- r = rects;
- while (nBox--)
- {
- r->x = pBox->x1 - pDraw->x;
- r->y = pBox->y1 - pDraw->y;
- r->width = pBox->x2 - pBox->x1;
- r->height = pBox->y2 - pBox->y1;
- r++;
- pBox++;
- }
-
- pGC = GetScratchGC (pDraw->depth, pDraw->pScreen);
- if (!pGC)
- goto bail1;
-
- val[0] = fg;
- val[1] = IncludeInferiors;
- ChangeGC (pGC, GCForeground|GCSubwindowMode, val);
-
- ValidateGC (pDraw, pGC);
-
- (*pGC->ops->PolyFillRect) (pDraw, pGC,
- REGION_NUM_RECTS (pRgn), rects);
-
- FreeScratchGC (pGC);
-bail1:
- xfree (rects);
-bail0:
- ;
-}
+/*
+
+ XFree86 Xv DDX written by Mark Vojkovich (markv@valinux.com)
+ Adapted for KDrive by Pontus Lidman <pontus.lidman@nokia.com>
+
+ Copyright (C) 2000, 2001 - Nokia Home Communications
+ Copyright (C) 1998, 1999 - 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, and/or sell copies of the Software, and to permit persons
+to whom the Software is furnished to do so, provided that the above
+copyright notice(s) and this permission notice appear in all copies of
+the Software and that both the above copyright notice(s) and this
+permission notice appear in supporting documentation.
+
+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
+OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
+HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR 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.
+
+Except as contained in this notice, the name of a copyright holder
+shall not be used in advertising or otherwise to promote the sale, use
+or other dealings in this Software without prior written authorization
+of the copyright holder.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <kdrive-config.h>
+#endif
+#include "kdrive.h"
+
+#include "scrnintstr.h"
+#include "regionstr.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "mivalidate.h"
+#include "validate.h"
+#include "resource.h"
+#include "gcstruct.h"
+#include "dixstruct.h"
+
+#include <X11/extensions/Xv.h>
+#include <X11/extensions/Xvproto.h>
+
+#include "kxv.h"
+#include "fourcc.h"
+
+
+/* XvScreenRec fields */
+
+static Bool KdXVCloseScreen(int, ScreenPtr);
+static int KdXVQueryAdaptors(ScreenPtr, XvAdaptorPtr *, int *);
+
+/* XvAdaptorRec fields */
+
+static int KdXVAllocatePort(unsigned long, XvPortPtr, XvPortPtr*);
+static int KdXVFreePort(XvPortPtr);
+static int KdXVPutVideo(ClientPtr, DrawablePtr,XvPortPtr, GCPtr,
+ INT16, INT16, CARD16, CARD16,
+ INT16, INT16, CARD16, CARD16);
+static int KdXVPutStill(ClientPtr, DrawablePtr,XvPortPtr, GCPtr,
+ INT16, INT16, CARD16, CARD16,
+ INT16, INT16, CARD16, CARD16);
+static int KdXVGetVideo(ClientPtr, DrawablePtr,XvPortPtr, GCPtr,
+ INT16, INT16, CARD16, CARD16,
+ INT16, INT16, CARD16, CARD16);
+static int KdXVGetStill(ClientPtr, DrawablePtr,XvPortPtr, GCPtr,
+ INT16, INT16, CARD16, CARD16,
+ INT16, INT16, CARD16, CARD16);
+static int KdXVStopVideo(ClientPtr, XvPortPtr, DrawablePtr);
+static int KdXVSetPortAttribute(ClientPtr, XvPortPtr, Atom, INT32);
+static int KdXVGetPortAttribute(ClientPtr, XvPortPtr, Atom, INT32 *);
+static int KdXVQueryBestSize(ClientPtr, XvPortPtr, CARD8,
+ CARD16, CARD16,CARD16, CARD16,
+ unsigned int*, unsigned int*);
+static int KdXVPutImage(ClientPtr, DrawablePtr, XvPortPtr, GCPtr,
+ INT16, INT16, CARD16, CARD16,
+ INT16, INT16, CARD16, CARD16,
+ XvImagePtr, unsigned char*, Bool,
+ CARD16, CARD16);
+static int KdXVQueryImageAttributes(ClientPtr, XvPortPtr, XvImagePtr,
+ CARD16*, CARD16*, int*, int*);
+
+
+/* ScreenRec fields */
+
+static Bool KdXVCreateWindow(WindowPtr pWin);
+static Bool KdXVDestroyWindow(WindowPtr pWin);
+static void KdXVWindowExposures(WindowPtr pWin, RegionPtr r1, RegionPtr r2);
+static void KdXVClipNotify(WindowPtr pWin, int dx, int dy);
+
+/* misc */
+static Bool KdXVInitAdaptors(ScreenPtr, KdVideoAdaptorPtr*, int);
+
+static int KdXVWindowKeyIndex;
+DevPrivateKey KdXVWindowKey = &KdXVWindowKeyIndex;
+static int KdXvScreenKeyIndex;
+DevPrivateKey KdXvScreenKey = &KdXvScreenKeyIndex;
+static unsigned long KdXVGeneration = 0;
+static unsigned long PortResource = 0;
+
+DevPrivateKey (*XvGetScreenKeyProc)(void) = XvGetScreenKey;
+unsigned long (*XvGetRTPortProc)(void) = XvGetRTPort;
+int (*XvScreenInitProc)(ScreenPtr) = XvScreenInit;
+
+#define GET_XV_SCREEN(pScreen) ((XvScreenPtr) \
+ dixLookupPrivate(&(pScreen)->devPrivates, KdXvScreenKey))
+
+#define GET_KDXV_SCREEN(pScreen) \
+ ((KdXVScreenPtr)(GET_XV_SCREEN(pScreen)->devPriv.ptr))
+
+#define GET_KDXV_WINDOW(pWin) ((KdXVWindowPtr) \
+ dixLookupPrivate(&(pWin)->devPrivates, KdXVWindowKey))
+
+static KdXVInitGenericAdaptorPtr *GenDrivers = NULL;
+static int NumGenDrivers = 0;
+
+int
+KdXVRegisterGenericAdaptorDriver(
+ KdXVInitGenericAdaptorPtr InitFunc
+){
+ KdXVInitGenericAdaptorPtr *newdrivers;
+
+/* fprintf(stderr,"KdXVRegisterGenericAdaptorDriver\n"); */
+
+ newdrivers = realloc(GenDrivers, sizeof(KdXVInitGenericAdaptorPtr) *
+ (1 + NumGenDrivers));
+ if (!newdrivers)
+ return 0;
+ GenDrivers = newdrivers;
+
+ GenDrivers[NumGenDrivers++] = InitFunc;
+
+ return 1;
+}
+
+int
+KdXVListGenericAdaptors(
+ KdScreenInfo * screen,
+ KdVideoAdaptorPtr **adaptors
+){
+ int i,j,n,num;
+ KdVideoAdaptorPtr *DrivAdap,*new;
+
+ num = 0;
+ *adaptors = NULL;
+ for (i = 0; i < NumGenDrivers; i++) {
+ n = GenDrivers[i](screen,&DrivAdap);
+ if (0 == n)
+ continue;
+ new = realloc(*adaptors, sizeof(KdVideoAdaptorPtr) * (num+n));
+ if (NULL == new)
+ continue;
+ *adaptors = new;
+ for (j = 0; j < n; j++, num++)
+ (*adaptors)[num] = DrivAdap[j];
+ }
+ return num;
+}
+
+KdVideoAdaptorPtr
+KdXVAllocateVideoAdaptorRec(KdScreenInfo * screen)
+{
+ return calloc(1, sizeof(KdVideoAdaptorRec));
+}
+
+void
+KdXVFreeVideoAdaptorRec(KdVideoAdaptorPtr ptr)
+{
+ free(ptr);
+}
+
+
+Bool
+KdXVScreenInit(
+ ScreenPtr pScreen,
+ KdVideoAdaptorPtr *adaptors,
+ int num
+){
+ KdXVScreenPtr ScreenPriv;
+ XvScreenPtr pxvs;
+
+/* fprintf(stderr,"KdXVScreenInit initializing %d adaptors\n",num); */
+
+ if (KdXVGeneration != serverGeneration)
+ KdXVGeneration = serverGeneration;
+
+ if(!XvGetScreenKeyProc || !XvGetRTPortProc || !XvScreenInitProc)
+ return FALSE;
+
+ if(Success != (*XvScreenInitProc)(pScreen)) return FALSE;
+
+ KdXvScreenKey = (*XvGetScreenKeyProc)();
+ PortResource = (*XvGetRTPortProc)();
+
+ pxvs = GET_XV_SCREEN(pScreen);
+
+
+ /* Anyone initializing the Xv layer must provide these two.
+ The Xv di layer calls them without even checking if they exist! */
+
+ pxvs->ddCloseScreen = KdXVCloseScreen;
+ pxvs->ddQueryAdaptors = KdXVQueryAdaptors;
+
+ /* The Xv di layer provides us with a private hook so that we don't
+ have to allocate our own screen private. They also provide
+ a CloseScreen hook so that we don't have to wrap it. I'm not
+ sure that I appreciate that. */
+
+ ScreenPriv = malloc(sizeof(KdXVScreenRec));
+ pxvs->devPriv.ptr = (pointer)ScreenPriv;
+
+ if(!ScreenPriv) return FALSE;
+
+
+ ScreenPriv->CreateWindow = pScreen->CreateWindow;
+ ScreenPriv->DestroyWindow = pScreen->DestroyWindow;
+ ScreenPriv->WindowExposures = pScreen->WindowExposures;
+ ScreenPriv->ClipNotify = pScreen->ClipNotify;
+
+/* fprintf(stderr,"XV: Wrapping screen funcs\n"); */
+
+ pScreen->CreateWindow = KdXVCreateWindow;
+ pScreen->DestroyWindow = KdXVDestroyWindow;
+ pScreen->WindowExposures = KdXVWindowExposures;
+ pScreen->ClipNotify = KdXVClipNotify;
+
+ if(!KdXVInitAdaptors(pScreen, adaptors, num))
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+KdXVFreeAdaptor(XvAdaptorPtr pAdaptor)
+{
+ int i;
+
+ free(pAdaptor->name);
+
+ if(pAdaptor->pEncodings) {
+ XvEncodingPtr pEncode = pAdaptor->pEncodings;
+
+ for(i = 0; i < pAdaptor->nEncodings; i++, pEncode++) {
+ free(pEncode->name);
+ }
+ free(pAdaptor->pEncodings);
+ }
+
+ free(pAdaptor->pFormats);
+
+ if(pAdaptor->pPorts) {
+ XvPortPtr pPort = pAdaptor->pPorts;
+ XvPortRecPrivatePtr pPriv;
+
+ for(i = 0; i < pAdaptor->nPorts; i++, pPort++) {
+ pPriv = (XvPortRecPrivatePtr)pPort->devPriv.ptr;
+ if(pPriv) {
+ if(pPriv->clientClip)
+ REGION_DESTROY(pAdaptor->pScreen, pPriv->clientClip);
+ if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
+ REGION_DESTROY(pAdaptor->pScreen, pPriv->pCompositeClip);
+ free(pPriv);
+ }
+ }
+ free(pAdaptor->pPorts);
+ }
+
+ if(pAdaptor->nAttributes) {
+ XvAttributePtr pAttribute = pAdaptor->pAttributes;
+
+ for(i = 0; i < pAdaptor->nAttributes; i++, pAttribute++) {
+ free(pAttribute->name);
+ }
+
+ free(pAdaptor->pAttributes);
+ }
+
+ free(pAdaptor->pImages);
+
+ free(pAdaptor->devPriv.ptr);
+}
+
+static Bool
+KdXVInitAdaptors(
+ ScreenPtr pScreen,
+ KdVideoAdaptorPtr *infoPtr,
+ int number
+) {
+ KdScreenPriv(pScreen);
+ KdScreenInfo * screen = pScreenPriv->screen;
+
+ XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
+ KdVideoAdaptorPtr adaptorPtr;
+ XvAdaptorPtr pAdaptor, pa;
+ XvAdaptorRecPrivatePtr adaptorPriv;
+ int na, numAdaptor;
+ XvPortRecPrivatePtr portPriv;
+ XvPortPtr pPort, pp;
+ int numPort;
+ KdAttributePtr attributePtr;
+ XvAttributePtr pAttribute, pat;
+ KdVideoFormatPtr formatPtr;
+ XvFormatPtr pFormat, pf;
+ int numFormat, totFormat;
+ KdVideoEncodingPtr encodingPtr;
+ XvEncodingPtr pEncode, pe;
+ KdImagePtr imagePtr;
+ XvImagePtr pImage, pi;
+ int numVisuals;
+ VisualPtr pVisual;
+ int i;
+
+ pxvs->nAdaptors = 0;
+ pxvs->pAdaptors = NULL;
+
+ if(!(pAdaptor = calloc(number, sizeof(XvAdaptorRec))))
+ return FALSE;
+
+ for(pa = pAdaptor, na = 0, numAdaptor = 0; na < number; na++, adaptorPtr++) {
+ adaptorPtr = infoPtr[na];
+
+ if(!adaptorPtr->StopVideo || !adaptorPtr->SetPortAttribute ||
+ !adaptorPtr->GetPortAttribute || !adaptorPtr->QueryBestSize)
+ continue;
+
+ /* client libs expect at least one encoding */
+ if(!adaptorPtr->nEncodings || !adaptorPtr->pEncodings)
+ continue;
+
+ pa->type = adaptorPtr->type;
+
+ if(!adaptorPtr->PutVideo && !adaptorPtr->GetVideo)
+ pa->type &= ~XvVideoMask;
+
+ if(!adaptorPtr->PutStill && !adaptorPtr->GetStill)
+ pa->type &= ~XvStillMask;
+
+ if(!adaptorPtr->PutImage || !adaptorPtr->QueryImageAttributes)
+ pa->type &= ~XvImageMask;
+
+ if(!adaptorPtr->PutVideo && !adaptorPtr->PutImage &&
+ !adaptorPtr->PutStill)
+ pa->type &= ~XvInputMask;
+
+ if(!adaptorPtr->GetVideo && !adaptorPtr->GetStill)
+ pa->type &= ~XvOutputMask;
+
+ if(!(adaptorPtr->type & (XvPixmapMask | XvWindowMask)))
+ continue;
+ if(!(adaptorPtr->type & (XvImageMask | XvVideoMask | XvStillMask)))
+ continue;
+
+ pa->pScreen = pScreen;
+ pa->ddAllocatePort = KdXVAllocatePort;
+ pa->ddFreePort = KdXVFreePort;
+ pa->ddPutVideo = KdXVPutVideo;
+ pa->ddPutStill = KdXVPutStill;
+ pa->ddGetVideo = KdXVGetVideo;
+ pa->ddGetStill = KdXVGetStill;
+ pa->ddStopVideo = KdXVStopVideo;
+ pa->ddPutImage = KdXVPutImage;
+ pa->ddSetPortAttribute = KdXVSetPortAttribute;
+ pa->ddGetPortAttribute = KdXVGetPortAttribute;
+ pa->ddQueryBestSize = KdXVQueryBestSize;
+ pa->ddQueryImageAttributes = KdXVQueryImageAttributes;
+ if((pa->name = malloc(strlen(adaptorPtr->name) + 1)))
+ strcpy(pa->name, adaptorPtr->name);
+
+ if(adaptorPtr->nEncodings &&
+ (pEncode = calloc(adaptorPtr->nEncodings, sizeof(XvEncodingRec)))) {
+
+ for(pe = pEncode, encodingPtr = adaptorPtr->pEncodings, i = 0;
+ i < adaptorPtr->nEncodings; pe++, i++, encodingPtr++)
+ {
+ pe->id = encodingPtr->id;
+ pe->pScreen = pScreen;
+ if((pe->name = malloc(strlen(encodingPtr->name) + 1)))
+ strcpy(pe->name, encodingPtr->name);
+ pe->width = encodingPtr->width;
+ pe->height = encodingPtr->height;
+ pe->rate.numerator = encodingPtr->rate.numerator;
+ pe->rate.denominator = encodingPtr->rate.denominator;
+ }
+ pa->nEncodings = adaptorPtr->nEncodings;
+ pa->pEncodings = pEncode;
+ }
+
+ if(adaptorPtr->nImages &&
+ (pImage = calloc(adaptorPtr->nImages, sizeof(XvImageRec)))) {
+
+ for(i = 0, pi = pImage, imagePtr = adaptorPtr->pImages;
+ i < adaptorPtr->nImages; i++, pi++, imagePtr++)
+ {
+ pi->id = imagePtr->id;
+ pi->type = imagePtr->type;
+ pi->byte_order = imagePtr->byte_order;
+ memcpy(pi->guid, imagePtr->guid, 16);
+ pi->bits_per_pixel = imagePtr->bits_per_pixel;
+ pi->format = imagePtr->format;
+ pi->num_planes = imagePtr->num_planes;
+ pi->depth = imagePtr->depth;
+ pi->red_mask = imagePtr->red_mask;
+ pi->green_mask = imagePtr->green_mask;
+ pi->blue_mask = imagePtr->blue_mask;
+ pi->y_sample_bits = imagePtr->y_sample_bits;
+ pi->u_sample_bits = imagePtr->u_sample_bits;
+ pi->v_sample_bits = imagePtr->v_sample_bits;
+ pi->horz_y_period = imagePtr->horz_y_period;
+ pi->horz_u_period = imagePtr->horz_u_period;
+ pi->horz_v_period = imagePtr->horz_v_period;
+ pi->vert_y_period = imagePtr->vert_y_period;
+ pi->vert_u_period = imagePtr->vert_u_period;
+ pi->vert_v_period = imagePtr->vert_v_period;
+ memcpy(pi->component_order, imagePtr->component_order, 32);
+ pi->scanline_order = imagePtr->scanline_order;
+ }
+ pa->nImages = adaptorPtr->nImages;
+ pa->pImages = pImage;
+ }
+
+ if(adaptorPtr->nAttributes &&
+ (pAttribute = calloc(adaptorPtr->nAttributes, sizeof(XvAttributeRec))))
+ {
+ for(pat = pAttribute, attributePtr = adaptorPtr->pAttributes, i = 0;
+ i < adaptorPtr->nAttributes; pat++, i++, attributePtr++)
+ {
+ pat->flags = attributePtr->flags;
+ pat->min_value = attributePtr->min_value;
+ pat->max_value = attributePtr->max_value;
+ if((pat->name = malloc(strlen(attributePtr->name) + 1)))
+ strcpy(pat->name, attributePtr->name);
+ }
+ pa->nAttributes = adaptorPtr->nAttributes;
+ pa->pAttributes = pAttribute;
+ }
+
+
+ totFormat = adaptorPtr->nFormats;
+
+ if(!(pFormat = calloc(totFormat, sizeof(XvFormatRec)))) {
+ KdXVFreeAdaptor(pa);
+ continue;
+ }
+ for(pf = pFormat, i = 0, numFormat = 0, formatPtr = adaptorPtr->pFormats;
+ i < adaptorPtr->nFormats; i++, formatPtr++)
+ {
+ numVisuals = pScreen->numVisuals;
+ pVisual = pScreen->visuals;
+
+ while(numVisuals--) {
+ if((pVisual->class == formatPtr->class) &&
+ (pVisual->nplanes == formatPtr->depth)) {
+
+ if(numFormat >= totFormat) {
+ void *moreSpace;
+ totFormat *= 2;
+ moreSpace = realloc(pFormat,
+ totFormat * sizeof(XvFormatRec));
+ if(!moreSpace) break;
+ pFormat = moreSpace;
+ pf = pFormat + numFormat;
+ }
+
+ pf->visual = pVisual->vid;
+ pf->depth = formatPtr->depth;
+
+ pf++;
+ numFormat++;
+ }
+ pVisual++;
+ }
+ }
+ pa->nFormats = numFormat;
+ pa->pFormats = pFormat;
+ if(!numFormat) {
+ KdXVFreeAdaptor(pa);
+ continue;
+ }
+
+ if(!(adaptorPriv = calloc(1, sizeof(XvAdaptorRecPrivate)))) {
+ KdXVFreeAdaptor(pa);
+ continue;
+ }
+
+ adaptorPriv->flags = adaptorPtr->flags;
+ adaptorPriv->PutVideo = adaptorPtr->PutVideo;
+ adaptorPriv->PutStill = adaptorPtr->PutStill;
+ adaptorPriv->GetVideo = adaptorPtr->GetVideo;
+ adaptorPriv->GetStill = adaptorPtr->GetStill;
+ adaptorPriv->StopVideo = adaptorPtr->StopVideo;
+ adaptorPriv->SetPortAttribute = adaptorPtr->SetPortAttribute;
+ adaptorPriv->GetPortAttribute = adaptorPtr->GetPortAttribute;
+ adaptorPriv->QueryBestSize = adaptorPtr->QueryBestSize;
+ adaptorPriv->QueryImageAttributes = adaptorPtr->QueryImageAttributes;
+ adaptorPriv->PutImage = adaptorPtr->PutImage;
+ adaptorPriv->ReputImage = adaptorPtr->ReputImage;
+
+ pa->devPriv.ptr = (pointer)adaptorPriv;
+
+ if(!(pPort = calloc(adaptorPtr->nPorts, sizeof(XvPortRec)))) {
+ KdXVFreeAdaptor(pa);
+ continue;
+ }
+ for(pp = pPort, i = 0, numPort = 0;
+ i < adaptorPtr->nPorts; i++) {
+
+ if(!(pp->id = FakeClientID(0)))
+ continue;
+
+ if(!(portPriv = calloc(1, sizeof(XvPortRecPrivate))))
+ continue;
+
+ if(!AddResource(pp->id, PortResource, pp)) {
+ free(portPriv);
+ continue;
+ }
+
+ pp->pAdaptor = pa;
+ pp->pNotify = (XvPortNotifyPtr)NULL;
+ pp->pDraw = (DrawablePtr)NULL;
+ pp->client = (ClientPtr)NULL;
+ pp->grab.client = (ClientPtr)NULL;
+ pp->time = currentTime;
+ pp->devPriv.ptr = portPriv;
+
+ portPriv->screen = screen;
+ portPriv->AdaptorRec = adaptorPriv;
+ portPriv->DevPriv.ptr = adaptorPtr->pPortPrivates[i].ptr;
+
+ pp++;
+ numPort++;
+ }
+ pa->nPorts = numPort;
+ pa->pPorts = pPort;
+ if(!numPort) {
+ KdXVFreeAdaptor(pa);
+ continue;
+ }
+
+ pa->base_id = pPort->id;
+
+ pa++;
+ numAdaptor++;
+ }
+
+ if(numAdaptor) {
+ pxvs->nAdaptors = numAdaptor;
+ pxvs->pAdaptors = pAdaptor;
+ } else {
+ free(pAdaptor);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Video should be clipped to the intersection of the window cliplist
+ and the client cliplist specified in the GC for which the video was
+ initialized. When we need to reclip a window, the GC that started
+ the video may not even be around anymore. That's why we save the
+ client clip from the GC when the video is initialized. We then
+ use KdXVUpdateCompositeClip to calculate the new composite clip
+ when we need it. This is different from what DEC did. They saved
+ the GC and used it's clip list when they needed to reclip the window,
+ even if the client clip was different from the one the video was
+ initialized with. If the original GC was destroyed, they had to stop
+ the video. I like the new method better (MArk).
+
+ This function only works for windows. Will need to rewrite when
+ (if) we support pixmap rendering.
+*/
+
+static void
+KdXVUpdateCompositeClip(XvPortRecPrivatePtr portPriv)
+{
+ RegionPtr pregWin, pCompositeClip;
+ WindowPtr pWin;
+ Bool freeCompClip = FALSE;
+
+ if(portPriv->pCompositeClip)
+ return;
+
+ pWin = (WindowPtr)portPriv->pDraw;
+
+ /* get window clip list */
+ if(portPriv->subWindowMode == IncludeInferiors) {
+ pregWin = NotClippedByChildren(pWin);
+ freeCompClip = TRUE;
+ } else
+ pregWin = &pWin->clipList;
+
+ if(!portPriv->clientClip) {
+ portPriv->pCompositeClip = pregWin;
+ portPriv->FreeCompositeClip = freeCompClip;
+ return;
+ }
+
+ pCompositeClip = REGION_CREATE(pWin->pScreen, NullBox, 1);
+ REGION_COPY(pWin->pScreen, pCompositeClip, portPriv->clientClip);
+ REGION_TRANSLATE(pWin->pScreen, pCompositeClip,
+ portPriv->pDraw->x + portPriv->clipOrg.x,
+ portPriv->pDraw->y + portPriv->clipOrg.y);
+ REGION_INTERSECT(pWin->pScreen, pCompositeClip, pregWin, pCompositeClip);
+
+ portPriv->pCompositeClip = pCompositeClip;
+ portPriv->FreeCompositeClip = TRUE;
+
+ if(freeCompClip) {
+ REGION_DESTROY(pWin->pScreen, pregWin);
+ }
+}
+
+/* Save the current clientClip and update the CompositeClip whenever
+ we have a fresh GC */
+
+static void
+KdXVCopyClip(
+ XvPortRecPrivatePtr portPriv,
+ GCPtr pGC
+){
+ /* copy the new clip if it exists */
+ if((pGC->clientClipType == CT_REGION) && pGC->clientClip) {
+ if(!portPriv->clientClip)
+ portPriv->clientClip = REGION_CREATE(pGC->pScreen, NullBox, 1);
+ /* Note: this is in window coordinates */
+ REGION_COPY(pGC->pScreen, portPriv->clientClip, pGC->clientClip);
+ } else if(portPriv->clientClip) { /* free the old clientClip */
+ REGION_DESTROY(pGC->pScreen, portPriv->clientClip);
+ portPriv->clientClip = NULL;
+ }
+
+ /* get rid of the old clip list */
+ if(portPriv->pCompositeClip && portPriv->FreeCompositeClip) {
+ REGION_DESTROY(pWin->pScreen, portPriv->pCompositeClip);
+ }
+
+ portPriv->clipOrg = pGC->clipOrg;
+ portPriv->pCompositeClip = pGC->pCompositeClip;
+ portPriv->FreeCompositeClip = FALSE;
+ portPriv->subWindowMode = pGC->subWindowMode;
+}
+
+static int
+KdXVRegetVideo(XvPortRecPrivatePtr portPriv)
+{
+ RegionRec WinRegion;
+ RegionRec ClipRegion;
+ BoxRec WinBox;
+ int ret = Success;
+ Bool clippedAway = FALSE;
+
+ KdXVUpdateCompositeClip(portPriv);
+
+ /* translate the video region to the screen */
+ WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
+ WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
+ WinBox.x2 = WinBox.x1 + portPriv->drw_w;
+ WinBox.y2 = WinBox.y1 + portPriv->drw_h;
+
+ /* clip to the window composite clip */
+ REGION_INIT(portPriv->pDraw->pScreen, &WinRegion, &WinBox, 1);
+ REGION_INIT(portPriv->pDraw->pScreen, &ClipRegion, NullBox, 1);
+ REGION_INTERSECT(portPriv->pDraw->pScreen, &ClipRegion, &WinRegion, portPriv->pCompositeClip);
+
+ /* that's all if it's totally obscured */
+ if(!REGION_NOTEMPTY(portPriv->pDraw->pScreen, &ClipRegion)) {
+ clippedAway = TRUE;
+ goto CLIP_VIDEO_BAILOUT;
+ }
+
+ if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
+ REGION_SUBTRACT(portPriv->pDraw->pScreen, &ClipRegion, &WinRegion, &ClipRegion);
+ }
+
+ ret = (*portPriv->AdaptorRec->GetVideo)(portPriv->screen, portPriv->pDraw,
+ portPriv->vid_x, portPriv->vid_y,
+ WinBox.x1, WinBox.y1,
+ portPriv->vid_w, portPriv->vid_h,
+ portPriv->drw_w, portPriv->drw_h,
+ &ClipRegion, portPriv->DevPriv.ptr);
+
+ if(ret == Success)
+ portPriv->isOn = XV_ON;
+
+CLIP_VIDEO_BAILOUT:
+
+ if((clippedAway || (ret != Success)) && portPriv->isOn == XV_ON) {
+ (*portPriv->AdaptorRec->StopVideo)(
+ portPriv->screen, portPriv->DevPriv.ptr, FALSE);
+ portPriv->isOn = XV_PENDING;
+ }
+
+ /* This clip was copied and only good for one shot */
+ if(!portPriv->FreeCompositeClip)
+ portPriv->pCompositeClip = NULL;
+
+ REGION_UNINIT(portPriv->pDraw->pScreen, &WinRegion);
+ REGION_UNINIT(portPriv->pDraw->pScreen, &ClipRegion);
+
+ return ret;
+}
+
+
+static int
+KdXVReputVideo(XvPortRecPrivatePtr portPriv)
+{
+ RegionRec WinRegion;
+ RegionRec ClipRegion;
+ BoxRec WinBox;
+ ScreenPtr pScreen = portPriv->pDraw->pScreen;
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen=pScreenPriv->screen;
+ int ret = Success;
+ Bool clippedAway = FALSE;
+
+ KdXVUpdateCompositeClip(portPriv);
+
+ /* translate the video region to the screen */
+ WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
+ WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
+ WinBox.x2 = WinBox.x1 + portPriv->drw_w;
+ WinBox.y2 = WinBox.y1 + portPriv->drw_h;
+
+ /* clip to the window composite clip */
+ REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
+ REGION_INIT(pScreen, &ClipRegion, NullBox, 1);
+ REGION_INTERSECT(Screen, &ClipRegion, &WinRegion, portPriv->pCompositeClip);
+
+ /* clip and translate to the viewport */
+ if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
+ RegionRec VPReg;
+ BoxRec VPBox;
+
+ VPBox.x1 = 0;
+ VPBox.y1 = 0;
+ VPBox.x2 = screen->width;
+ VPBox.y2 = screen->height;
+
+ REGION_INIT(pScreen, &VPReg, &VPBox, 1);
+ REGION_INTERSECT(Screen, &ClipRegion, &ClipRegion, &VPReg);
+ REGION_UNINIT(pScreen, &VPReg);
+ }
+
+ /* that's all if it's totally obscured */
+ if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
+ clippedAway = TRUE;
+ goto CLIP_VIDEO_BAILOUT;
+ }
+
+ /* bailout if we have to clip but the hardware doesn't support it */
+ if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) {
+ BoxPtr clipBox = REGION_RECTS(&ClipRegion);
+ if( (REGION_NUM_RECTS(&ClipRegion) != 1) ||
+ (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) ||
+ (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2))
+ {
+ clippedAway = TRUE;
+ goto CLIP_VIDEO_BAILOUT;
+ }
+ }
+
+ if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
+ REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
+ }
+
+ ret = (*portPriv->AdaptorRec->PutVideo)(portPriv->screen, portPriv->pDraw,
+ portPriv->vid_x, portPriv->vid_y,
+ WinBox.x1, WinBox.y1,
+ portPriv->vid_w, portPriv->vid_h,
+ portPriv->drw_w, portPriv->drw_h,
+ &ClipRegion, portPriv->DevPriv.ptr);
+
+ if(ret == Success) portPriv->isOn = XV_ON;
+
+CLIP_VIDEO_BAILOUT:
+
+ if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
+ (*portPriv->AdaptorRec->StopVideo)(
+ portPriv->screen, portPriv->DevPriv.ptr, FALSE);
+ portPriv->isOn = XV_PENDING;
+ }
+
+ /* This clip was copied and only good for one shot */
+ if(!portPriv->FreeCompositeClip)
+ portPriv->pCompositeClip = NULL;
+
+ REGION_UNINIT(pScreen, &WinRegion);
+ REGION_UNINIT(pScreen, &ClipRegion);
+
+ return ret;
+}
+
+static int
+KdXVReputImage(XvPortRecPrivatePtr portPriv)
+{
+ RegionRec WinRegion;
+ RegionRec ClipRegion;
+ BoxRec WinBox;
+ ScreenPtr pScreen = portPriv->pDraw->pScreen;
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen=pScreenPriv->screen;
+ int ret = Success;
+ Bool clippedAway = FALSE;
+
+ KdXVUpdateCompositeClip(portPriv);
+
+ /* translate the video region to the screen */
+ WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
+ WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
+ WinBox.x2 = WinBox.x1 + portPriv->drw_w;
+ WinBox.y2 = WinBox.y1 + portPriv->drw_h;
+
+ /* clip to the window composite clip */
+ REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
+ REGION_INIT(pScreen, &ClipRegion, NullBox, 1);
+ REGION_INTERSECT(Screen, &ClipRegion, &WinRegion, portPriv->pCompositeClip);
+
+ /* clip and translate to the viewport */
+ if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
+ RegionRec VPReg;
+ BoxRec VPBox;
+
+ VPBox.x1 = 0;
+ VPBox.y1 = 0;
+ VPBox.x2 = screen->width;
+ VPBox.y2 = screen->height;
+
+ REGION_INIT(pScreen, &VPReg, &VPBox, 1);
+ REGION_INTERSECT(Screen, &ClipRegion, &ClipRegion, &VPReg);
+ REGION_UNINIT(pScreen, &VPReg);
+ }
+
+ /* that's all if it's totally obscured */
+ if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
+ clippedAway = TRUE;
+ goto CLIP_VIDEO_BAILOUT;
+ }
+
+ /* bailout if we have to clip but the hardware doesn't support it */
+ if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) {
+ BoxPtr clipBox = REGION_RECTS(&ClipRegion);
+ if( (REGION_NUM_RECTS(&ClipRegion) != 1) ||
+ (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) ||
+ (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2))
+ {
+ clippedAway = TRUE;
+ goto CLIP_VIDEO_BAILOUT;
+ }
+ }
+
+ if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
+ REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
+ }
+
+ ret = (*portPriv->AdaptorRec->ReputImage)(portPriv->screen, portPriv->pDraw,
+ WinBox.x1, WinBox.y1,
+ &ClipRegion, portPriv->DevPriv.ptr);
+
+ portPriv->isOn = (ret == Success) ? XV_ON : XV_OFF;
+
+CLIP_VIDEO_BAILOUT:
+
+ if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
+ (*portPriv->AdaptorRec->StopVideo)(
+ portPriv->screen, portPriv->DevPriv.ptr, FALSE);
+ portPriv->isOn = XV_PENDING;
+ }
+
+ /* This clip was copied and only good for one shot */
+ if(!portPriv->FreeCompositeClip)
+ portPriv->pCompositeClip = NULL;
+
+ REGION_UNINIT(pScreen, &WinRegion);
+ REGION_UNINIT(pScreen, &ClipRegion);
+
+ return ret;
+}
+
+
+static int
+KdXVReputAllVideo(WindowPtr pWin, pointer data)
+{
+ KdXVWindowPtr WinPriv;
+
+ if (pWin->drawable.type != DRAWABLE_WINDOW)
+ return WT_DONTWALKCHILDREN;
+
+ WinPriv = GET_KDXV_WINDOW(pWin);
+
+ while(WinPriv) {
+ if(WinPriv->PortRec->type == XvInputMask)
+ KdXVReputVideo(WinPriv->PortRec);
+ else
+ KdXVRegetVideo(WinPriv->PortRec);
+ WinPriv = WinPriv->next;
+ }
+
+ return WT_WALKCHILDREN;
+}
+
+static int
+KdXVEnlistPortInWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv)
+{
+ KdXVWindowPtr winPriv, PrivRoot;
+
+ winPriv = PrivRoot = GET_KDXV_WINDOW(pWin);
+
+ /* Enlist our port in the window private */
+ while(winPriv) {
+ if(winPriv->PortRec == portPriv) /* we're already listed */
+ break;
+ winPriv = winPriv->next;
+ }
+
+ if(!winPriv) {
+ winPriv = malloc(sizeof(KdXVWindowRec));
+ if(!winPriv) return BadAlloc;
+ winPriv->PortRec = portPriv;
+ winPriv->next = PrivRoot;
+ dixSetPrivate(&pWin->devPrivates, KdXVWindowKey, winPriv);
+ }
+ return Success;
+}
+
+
+static void
+KdXVRemovePortFromWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv)
+{
+ KdXVWindowPtr winPriv, prevPriv = NULL;
+
+ winPriv = GET_KDXV_WINDOW(pWin);
+
+ while(winPriv) {
+ if(winPriv->PortRec == portPriv) {
+ if(prevPriv)
+ prevPriv->next = winPriv->next;
+ else
+ dixSetPrivate(&pWin->devPrivates, KdXVWindowKey, winPriv->next);
+ free(winPriv);
+ break;
+ }
+ prevPriv = winPriv;
+ winPriv = winPriv->next;
+ }
+ portPriv->pDraw = NULL;
+}
+
+/**** ScreenRec fields ****/
+
+
+static Bool
+KdXVCreateWindow(WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ KdXVScreenPtr ScreenPriv = GET_KDXV_SCREEN(pScreen);
+ int ret;
+
+ pScreen->CreateWindow = ScreenPriv->CreateWindow;
+ ret = (*pScreen->CreateWindow)(pWin);
+ pScreen->CreateWindow = KdXVCreateWindow;
+
+ if (ret)
+ dixSetPrivate(&pWin->devPrivates, KdXVWindowKey, NULL);
+
+ return ret;
+}
+
+
+static Bool
+KdXVDestroyWindow(WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ KdXVScreenPtr ScreenPriv = GET_KDXV_SCREEN(pScreen);
+ KdXVWindowPtr tmp, WinPriv = GET_KDXV_WINDOW(pWin);
+ int ret;
+
+ while(WinPriv) {
+ XvPortRecPrivatePtr pPriv = WinPriv->PortRec;
+
+ if(pPriv->isOn > XV_OFF) {
+ (*pPriv->AdaptorRec->StopVideo)(
+ pPriv->screen, pPriv->DevPriv.ptr, TRUE);
+ pPriv->isOn = XV_OFF;
+ }
+
+ pPriv->pDraw = NULL;
+ tmp = WinPriv;
+ WinPriv = WinPriv->next;
+ free(tmp);
+ }
+
+ dixSetPrivate(&pWin->devPrivates, KdXVWindowKey, NULL);
+
+ pScreen->DestroyWindow = ScreenPriv->DestroyWindow;
+ ret = (*pScreen->DestroyWindow)(pWin);
+ pScreen->DestroyWindow = KdXVDestroyWindow;
+
+ return ret;
+}
+
+
+static void
+KdXVWindowExposures(WindowPtr pWin, RegionPtr reg1, RegionPtr reg2)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ KdXVScreenPtr ScreenPriv = GET_KDXV_SCREEN(pScreen);
+ KdXVWindowPtr WinPriv = GET_KDXV_WINDOW(pWin);
+ KdXVWindowPtr pPrev;
+ XvPortRecPrivatePtr pPriv;
+ Bool AreasExposed;
+
+ AreasExposed = (WinPriv && reg1 && REGION_NOTEMPTY(pScreen, reg1));
+
+ pScreen->WindowExposures = ScreenPriv->WindowExposures;
+ (*pScreen->WindowExposures)(pWin, reg1, reg2);
+ pScreen->WindowExposures = KdXVWindowExposures;
+
+ /* filter out XClearWindow/Area */
+ if (!pWin->valdata) return;
+
+ pPrev = NULL;
+
+ while(WinPriv) {
+ pPriv = WinPriv->PortRec;
+
+ /* Reput anyone with a reput function */
+
+ switch(pPriv->type) {
+ case XvInputMask:
+ KdXVReputVideo(pPriv);
+ break;
+ case XvOutputMask:
+ KdXVRegetVideo(pPriv);
+ break;
+ default: /* overlaid still/image*/
+ if (pPriv->AdaptorRec->ReputImage)
+ KdXVReputImage(pPriv);
+ else if(AreasExposed) {
+ KdXVWindowPtr tmp;
+
+ if (pPriv->isOn == XV_ON) {
+ (*pPriv->AdaptorRec->StopVideo)(
+ pPriv->screen, pPriv->DevPriv.ptr, FALSE);
+ pPriv->isOn = XV_PENDING;
+ }
+ pPriv->pDraw = NULL;
+
+ if(!pPrev)
+ dixSetPrivate(&pWin->devPrivates, KdXVWindowKey, WinPriv->next);
+ else
+ pPrev->next = WinPriv->next;
+ tmp = WinPriv;
+ WinPriv = WinPriv->next;
+ free(tmp);
+ continue;
+ }
+ break;
+ }
+ pPrev = WinPriv;
+ WinPriv = WinPriv->next;
+ }
+}
+
+
+static void
+KdXVClipNotify(WindowPtr pWin, int dx, int dy)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ KdXVScreenPtr ScreenPriv = GET_KDXV_SCREEN(pScreen);
+ KdXVWindowPtr WinPriv = GET_KDXV_WINDOW(pWin);
+ KdXVWindowPtr tmp, pPrev = NULL;
+ XvPortRecPrivatePtr pPriv;
+ Bool visible = (pWin->visibility == VisibilityUnobscured) ||
+ (pWin->visibility == VisibilityPartiallyObscured);
+
+ while(WinPriv) {
+ pPriv = WinPriv->PortRec;
+
+ if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
+ REGION_DESTROY(pScreen, pPriv->pCompositeClip);
+
+ pPriv->pCompositeClip = NULL;
+
+ /* Stop everything except images, but stop them too if the
+ window isn't visible. But we only remove the images. */
+
+ if(pPriv->type || !visible) {
+ if(pPriv->isOn == XV_ON) {
+ (*pPriv->AdaptorRec->StopVideo)(
+ pPriv->screen, pPriv->DevPriv.ptr, FALSE);
+ pPriv->isOn = XV_PENDING;
+ }
+
+ if(!pPriv->type) { /* overlaid still/image */
+ pPriv->pDraw = NULL;
+
+ if(!pPrev)
+ dixSetPrivate(&pWin->devPrivates, KdXVWindowKey, WinPriv->next);
+ else
+ pPrev->next = WinPriv->next;
+ tmp = WinPriv;
+ WinPriv = WinPriv->next;
+ free(tmp);
+ continue;
+ }
+ }
+
+ pPrev = WinPriv;
+ WinPriv = WinPriv->next;
+ }
+
+ if(ScreenPriv->ClipNotify) {
+ pScreen->ClipNotify = ScreenPriv->ClipNotify;
+ (*pScreen->ClipNotify)(pWin, dx, dy);
+ pScreen->ClipNotify = KdXVClipNotify;
+ }
+}
+
+
+
+/**** Required XvScreenRec fields ****/
+
+static Bool
+KdXVCloseScreen(int i, ScreenPtr pScreen)
+{
+ XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
+ KdXVScreenPtr ScreenPriv = GET_KDXV_SCREEN(pScreen);
+ XvAdaptorPtr pa;
+ int c;
+
+ if(!ScreenPriv) return TRUE;
+
+ pScreen->CreateWindow = ScreenPriv->CreateWindow;
+ pScreen->DestroyWindow = ScreenPriv->DestroyWindow;
+ pScreen->WindowExposures = ScreenPriv->WindowExposures;
+ pScreen->ClipNotify = ScreenPriv->ClipNotify;
+
+/* fprintf(stderr,"XV: Unwrapping screen funcs\n"); */
+
+ for(c = 0, pa = pxvs->pAdaptors; c < pxvs->nAdaptors; c++, pa++) {
+ KdXVFreeAdaptor(pa);
+ }
+
+ free(pxvs->pAdaptors);
+ free(ScreenPriv);
+
+ return TRUE;
+}
+
+
+static int
+KdXVQueryAdaptors(
+ ScreenPtr pScreen,
+ XvAdaptorPtr *p_pAdaptors,
+ int *p_nAdaptors
+){
+ XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
+
+ *p_nAdaptors = pxvs->nAdaptors;
+ *p_pAdaptors = pxvs->pAdaptors;
+
+ return (Success);
+}
+
+static Bool
+KdXVRunning (ScreenPtr pScreen)
+{
+ return (KdXVGeneration == serverGeneration &&
+ GET_XV_SCREEN(pScreen) != 0);
+}
+
+Bool
+KdXVEnable(ScreenPtr pScreen)
+{
+ if (!KdXVRunning (pScreen))
+ return TRUE;
+
+ WalkTree(pScreen, KdXVReputAllVideo, 0);
+
+ return TRUE;
+}
+
+void
+KdXVDisable(ScreenPtr pScreen)
+{
+ XvScreenPtr pxvs;
+ KdXVScreenPtr ScreenPriv;
+ XvAdaptorPtr pAdaptor;
+ XvPortPtr pPort;
+ XvPortRecPrivatePtr pPriv;
+ int i, j;
+
+ if (!KdXVRunning (pScreen))
+ return;
+
+ pxvs = GET_XV_SCREEN(pScreen);
+ ScreenPriv = GET_KDXV_SCREEN(pScreen);
+
+ for(i = 0; i < pxvs->nAdaptors; i++) {
+ pAdaptor = &pxvs->pAdaptors[i];
+ for(j = 0; j < pAdaptor->nPorts; j++) {
+ pPort = &pAdaptor->pPorts[j];
+ pPriv = (XvPortRecPrivatePtr)pPort->devPriv.ptr;
+ if(pPriv->isOn > XV_OFF) {
+
+ (*pPriv->AdaptorRec->StopVideo)(
+ pPriv->screen, pPriv->DevPriv.ptr, TRUE);
+ pPriv->isOn = XV_OFF;
+
+ if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
+ REGION_DESTROY(pScreen, pPriv->pCompositeClip);
+
+ pPriv->pCompositeClip = NULL;
+
+ if(!pPriv->type && pPriv->pDraw) { /* still */
+ KdXVRemovePortFromWindow((WindowPtr)pPriv->pDraw, pPriv);
+ }
+ }
+ }
+ }
+}
+
+/**** XvAdaptorRec fields ****/
+
+static int
+KdXVAllocatePort(
+ unsigned long port,
+ XvPortPtr pPort,
+ XvPortPtr *ppPort
+){
+ *ppPort = pPort;
+ return Success;
+}
+
+static int
+KdXVFreePort(XvPortPtr pPort)
+{
+ return Success;
+}
+
+static int
+KdXVPutVideo(
+ ClientPtr client,
+ DrawablePtr pDraw,
+ XvPortPtr pPort,
+ GCPtr pGC,
+ INT16 vid_x, INT16 vid_y,
+ CARD16 vid_w, CARD16 vid_h,
+ INT16 drw_x, INT16 drw_y,
+ CARD16 drw_w, CARD16 drw_h
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+ KdScreenPriv(portPriv->screen->pScreen);
+ int result;
+
+ /* No dumping video to pixmaps... For now anyhow */
+ if(pDraw->type != DRAWABLE_WINDOW) {
+ pPort->pDraw = (DrawablePtr)NULL;
+ return BadAlloc;
+ }
+
+ /* If we are changing windows, unregister our port in the old window */
+ if(portPriv->pDraw && (portPriv->pDraw != pDraw))
+ KdXVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
+
+ /* Register our port with the new window */
+ result = KdXVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
+ if(result != Success) return result;
+
+ portPriv->pDraw = pDraw;
+ portPriv->type = XvInputMask;
+
+ /* save a copy of these parameters */
+ portPriv->vid_x = vid_x; portPriv->vid_y = vid_y;
+ portPriv->vid_w = vid_w; portPriv->vid_h = vid_h;
+ portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
+ portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
+
+ /* make sure we have the most recent copy of the clientClip */
+ KdXVCopyClip(portPriv, pGC);
+
+ /* To indicate to the DI layer that we were successful */
+ pPort->pDraw = pDraw;
+
+ if (!pScreenPriv->enabled) return Success;
+
+ return(KdXVReputVideo(portPriv));
+}
+
+static int
+KdXVPutStill(
+ ClientPtr client,
+ DrawablePtr pDraw,
+ XvPortPtr pPort,
+ GCPtr pGC,
+ INT16 vid_x, INT16 vid_y,
+ CARD16 vid_w, CARD16 vid_h,
+ INT16 drw_x, INT16 drw_y,
+ CARD16 drw_w, CARD16 drw_h
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+ ScreenPtr pScreen = pDraw->pScreen;
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen=pScreenPriv->screen;
+ RegionRec WinRegion;
+ RegionRec ClipRegion;
+ BoxRec WinBox;
+ int ret = Success;
+ Bool clippedAway = FALSE;
+
+ if (pDraw->type != DRAWABLE_WINDOW)
+ return BadAlloc;
+
+ if (!pScreenPriv->enabled) return Success;
+
+ WinBox.x1 = pDraw->x + drw_x;
+ WinBox.y1 = pDraw->y + drw_y;
+ WinBox.x2 = WinBox.x1 + drw_w;
+ WinBox.y2 = WinBox.y1 + drw_h;
+
+ REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
+ REGION_INIT(pScreen, &ClipRegion, NullBox, 1);
+ REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, pGC->pCompositeClip);
+
+ if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
+ RegionRec VPReg;
+ BoxRec VPBox;
+
+ VPBox.x1 = 0;
+ VPBox.y1 = 0;
+ VPBox.x2 = screen->width;
+ VPBox.y2 = screen->height;
+
+ REGION_INIT(pScreen, &VPReg, &VPBox, 1);
+ REGION_INTERSECT(Screen, &ClipRegion, &ClipRegion, &VPReg);
+ REGION_UNINIT(pScreen, &VPReg);
+ }
+
+ if(portPriv->pDraw) {
+ KdXVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
+ }
+
+ if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
+ clippedAway = TRUE;
+ goto PUT_STILL_BAILOUT;
+ }
+
+ if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) {
+ BoxPtr clipBox = REGION_RECTS(&ClipRegion);
+ if( (REGION_NUM_RECTS(&ClipRegion) != 1) ||
+ (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) ||
+ (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2))
+ {
+ clippedAway = TRUE;
+ goto PUT_STILL_BAILOUT;
+ }
+ }
+
+ if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
+ REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
+ }
+
+ ret = (*portPriv->AdaptorRec->PutStill)(portPriv->screen, pDraw,
+ vid_x, vid_y, WinBox.x1, WinBox.y1,
+ vid_w, vid_h, drw_w, drw_h,
+ &ClipRegion, portPriv->DevPriv.ptr);
+
+ if((ret == Success) &&
+ (portPriv->AdaptorRec->flags & VIDEO_OVERLAID_STILLS)) {
+
+ KdXVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
+ portPriv->isOn = XV_ON;
+ portPriv->pDraw = pDraw;
+ portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
+ portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
+ portPriv->type = 0; /* no mask means it's transient and should
+ not be reput once it's removed */
+ pPort->pDraw = pDraw; /* make sure we can get stop requests */
+ }
+
+PUT_STILL_BAILOUT:
+
+ if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
+ (*portPriv->AdaptorRec->StopVideo)(
+ portPriv->screen, portPriv->DevPriv.ptr, FALSE);
+ portPriv->isOn = XV_PENDING;
+ }
+
+ REGION_UNINIT(pScreen, &WinRegion);
+ REGION_UNINIT(pScreen, &ClipRegion);
+
+ return ret;
+}
+
+static int
+KdXVGetVideo(
+ ClientPtr client,
+ DrawablePtr pDraw,
+ XvPortPtr pPort,
+ GCPtr pGC,
+ INT16 vid_x, INT16 vid_y,
+ CARD16 vid_w, CARD16 vid_h,
+ INT16 drw_x, INT16 drw_y,
+ CARD16 drw_w, CARD16 drw_h
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+ int result;
+ KdScreenPriv(portPriv->screen->pScreen);
+
+ /* No pixmaps... For now anyhow */
+ if(pDraw->type != DRAWABLE_WINDOW) {
+ pPort->pDraw = (DrawablePtr)NULL;
+ return BadAlloc;
+ }
+
+ /* If we are changing windows, unregister our port in the old window */
+ if(portPriv->pDraw && (portPriv->pDraw != pDraw))
+ KdXVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
+
+ /* Register our port with the new window */
+ result = KdXVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
+ if(result != Success) return result;
+
+ portPriv->pDraw = pDraw;
+ portPriv->type = XvOutputMask;
+
+ /* save a copy of these parameters */
+ portPriv->vid_x = vid_x; portPriv->vid_y = vid_y;
+ portPriv->vid_w = vid_w; portPriv->vid_h = vid_h;
+ portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
+ portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
+
+ /* make sure we have the most recent copy of the clientClip */
+ KdXVCopyClip(portPriv, pGC);
+
+ /* To indicate to the DI layer that we were successful */
+ pPort->pDraw = pDraw;
+
+ if(!pScreenPriv->enabled) return Success;
+
+ return(KdXVRegetVideo(portPriv));
+}
+
+static int
+KdXVGetStill(
+ ClientPtr client,
+ DrawablePtr pDraw,
+ XvPortPtr pPort,
+ GCPtr pGC,
+ INT16 vid_x, INT16 vid_y,
+ CARD16 vid_w, CARD16 vid_h,
+ INT16 drw_x, INT16 drw_y,
+ CARD16 drw_w, CARD16 drw_h
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+ ScreenPtr pScreen = pDraw->pScreen;
+ KdScreenPriv(pScreen);
+ RegionRec WinRegion;
+ RegionRec ClipRegion;
+ BoxRec WinBox;
+ int ret = Success;
+ Bool clippedAway = FALSE;
+
+ if (pDraw->type != DRAWABLE_WINDOW)
+ return BadAlloc;
+
+ if(!pScreenPriv->enabled) return Success;
+
+ WinBox.x1 = pDraw->x + drw_x;
+ WinBox.y1 = pDraw->y + drw_y;
+ WinBox.x2 = WinBox.x1 + drw_w;
+ WinBox.y2 = WinBox.y1 + drw_h;
+
+ REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
+ REGION_INIT(pScreen, &ClipRegion, NullBox, 1);
+ REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, pGC->pCompositeClip);
+
+ if(portPriv->pDraw) {
+ KdXVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
+ }
+
+ if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
+ clippedAway = TRUE;
+ goto GET_STILL_BAILOUT;
+ }
+
+ if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
+ REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
+ }
+
+ ret = (*portPriv->AdaptorRec->GetStill)(portPriv->screen, pDraw,
+ vid_x, vid_y, WinBox.x1, WinBox.y1,
+ vid_w, vid_h, drw_w, drw_h,
+ &ClipRegion, portPriv->DevPriv.ptr);
+
+GET_STILL_BAILOUT:
+
+ if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
+ (*portPriv->AdaptorRec->StopVideo)(
+ portPriv->screen, portPriv->DevPriv.ptr, FALSE);
+ portPriv->isOn = XV_PENDING;
+ }
+
+ REGION_UNINIT(pScreen, &WinRegion);
+ REGION_UNINIT(pScreen, &ClipRegion);
+
+ return ret;
+}
+
+
+
+static int
+KdXVStopVideo(
+ ClientPtr client,
+ XvPortPtr pPort,
+ DrawablePtr pDraw
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+ KdScreenPriv(portPriv->screen->pScreen);
+
+ if(pDraw->type != DRAWABLE_WINDOW)
+ return BadAlloc;
+
+ KdXVRemovePortFromWindow((WindowPtr)pDraw, portPriv);
+
+ if(!pScreenPriv->enabled) return Success;
+
+ /* Must free resources. */
+
+ if(portPriv->isOn > XV_OFF) {
+ (*portPriv->AdaptorRec->StopVideo)(
+ portPriv->screen, portPriv->DevPriv.ptr, TRUE);
+ portPriv->isOn = XV_OFF;
+ }
+
+ return Success;
+}
+
+static int
+KdXVSetPortAttribute(
+ ClientPtr client,
+ XvPortPtr pPort,
+ Atom attribute,
+ INT32 value
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+
+ return((*portPriv->AdaptorRec->SetPortAttribute)(portPriv->screen,
+ attribute, value, portPriv->DevPriv.ptr));
+}
+
+
+static int
+KdXVGetPortAttribute(
+ ClientPtr client,
+ XvPortPtr pPort,
+ Atom attribute,
+ INT32 *p_value
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+
+ return((*portPriv->AdaptorRec->GetPortAttribute)(portPriv->screen,
+ attribute, (int *) p_value, portPriv->DevPriv.ptr));
+}
+
+
+
+static int
+KdXVQueryBestSize(
+ ClientPtr client,
+ XvPortPtr pPort,
+ CARD8 motion,
+ CARD16 vid_w, CARD16 vid_h,
+ CARD16 drw_w, CARD16 drw_h,
+ unsigned int *p_w, unsigned int *p_h
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+
+ (*portPriv->AdaptorRec->QueryBestSize)(portPriv->screen,
+ (Bool)motion, vid_w, vid_h, drw_w, drw_h,
+ p_w, p_h, portPriv->DevPriv.ptr);
+
+ return Success;
+}
+
+
+static int
+KdXVPutImage(
+ ClientPtr client,
+ DrawablePtr pDraw,
+ XvPortPtr pPort,
+ GCPtr pGC,
+ INT16 src_x, INT16 src_y,
+ CARD16 src_w, CARD16 src_h,
+ INT16 drw_x, INT16 drw_y,
+ CARD16 drw_w, CARD16 drw_h,
+ XvImagePtr format,
+ unsigned char* data,
+ Bool sync,
+ CARD16 width, CARD16 height
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+ ScreenPtr pScreen = pDraw->pScreen;
+ KdScreenPriv(pScreen);
+ RegionRec WinRegion;
+ RegionRec ClipRegion;
+ BoxRec WinBox;
+ int ret = Success;
+ Bool clippedAway = FALSE;
+
+ if (pDraw->type != DRAWABLE_WINDOW)
+ return BadAlloc;
+
+ if(!pScreenPriv->enabled) return Success;
+
+ WinBox.x1 = pDraw->x + drw_x;
+ WinBox.y1 = pDraw->y + drw_y;
+ WinBox.x2 = WinBox.x1 + drw_w;
+ WinBox.y2 = WinBox.y1 + drw_h;
+
+ REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
+ REGION_INIT(pScreen, &ClipRegion, NullBox, 1);
+ REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, pGC->pCompositeClip);
+
+ if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
+ RegionRec VPReg;
+ BoxRec VPBox;
+
+ VPBox.x1 = 0;
+ VPBox.y1 = 0;
+ VPBox.x2 = pScreen->width;
+ VPBox.y2 = pScreen->height;
+
+ REGION_INIT(pScreen, &VPReg, &VPBox, 1);
+ REGION_INTERSECT(Screen, &ClipRegion, &ClipRegion, &VPReg);
+ REGION_UNINIT(pScreen, &VPReg);
+ }
+
+ if(portPriv->pDraw) {
+ KdXVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
+ }
+
+ if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
+ clippedAway = TRUE;
+ goto PUT_IMAGE_BAILOUT;
+ }
+
+ if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) {
+ BoxPtr clipBox = REGION_RECTS(&ClipRegion);
+ if( (REGION_NUM_RECTS(&ClipRegion) != 1) ||
+ (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) ||
+ (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2))
+ {
+ clippedAway = TRUE;
+ goto PUT_IMAGE_BAILOUT;
+ }
+ }
+
+ if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
+ REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
+ }
+
+ ret = (*portPriv->AdaptorRec->PutImage)(portPriv->screen, pDraw,
+ src_x, src_y, WinBox.x1, WinBox.y1,
+ src_w, src_h, drw_w, drw_h, format->id, data, width, height,
+ sync, &ClipRegion, portPriv->DevPriv.ptr);
+
+ if((ret == Success) &&
+ (portPriv->AdaptorRec->flags & VIDEO_OVERLAID_IMAGES)) {
+
+ KdXVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
+ portPriv->isOn = XV_ON;
+ portPriv->pDraw = pDraw;
+ portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
+ portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
+ portPriv->type = 0; /* no mask means it's transient and should
+ not be reput once it's removed */
+ pPort->pDraw = pDraw; /* make sure we can get stop requests */
+ }
+
+PUT_IMAGE_BAILOUT:
+
+ if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
+ (*portPriv->AdaptorRec->StopVideo)(
+ portPriv->screen, portPriv->DevPriv.ptr, FALSE);
+ portPriv->isOn = XV_PENDING;
+ }
+
+ REGION_UNINIT(pScreen, &WinRegion);
+ REGION_UNINIT(pScreen, &ClipRegion);
+
+ return ret;
+}
+
+
+static int
+KdXVQueryImageAttributes(
+ ClientPtr client,
+ XvPortPtr pPort,
+ XvImagePtr format,
+ CARD16 *width,
+ CARD16 *height,
+ int *pitches,
+ int *offsets
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+
+ return (*portPriv->AdaptorRec->QueryImageAttributes)(portPriv->screen,
+ format->id, width, height, pitches, offsets);
+}
+
+
+/**************** Common video manipulation functions *******************/
+
+void
+KdXVCopyPackedData(KdScreenInfo *screen, CARD8 *src, CARD8 *dst, int randr,
+ int srcPitch, int dstPitch, int srcW, int srcH, int top, int left,
+ int h, int w)
+{
+ int srcDown = srcPitch, srcRight = 2, srcNext;
+ int p;
+
+ switch (randr & RR_Rotate_All) {
+ case RR_Rotate_0:
+ srcDown = srcPitch;
+ srcRight = 2;
+ break;
+ case RR_Rotate_90:
+ src += (srcH - 1) * 2;
+ srcDown = -2;
+ srcRight = srcPitch;
+ break;
+ case RR_Rotate_180:
+ src += srcPitch * (srcH - 1) + (srcW - 1) * 2;
+ srcDown = -srcPitch;
+ srcRight = -2;
+ break;
+ case RR_Rotate_270:
+ src += srcPitch * (srcW - 1);
+ srcDown = 2;
+ srcRight = -srcPitch;
+ break;
+ }
+
+ src = src + top * srcDown + left * srcRight;
+
+ w >>= 1;
+ /* srcRight >>= 1; */
+ srcNext = srcRight >> 1;
+ while (h--) {
+ CARD16 *s = (CARD16 *)src;
+ CARD32 *d = (CARD32 *)dst;
+ p = w;
+ while (p--) {
+ *d++ = s[0] | (s[srcNext] << 16);
+ s += srcRight;
+ }
+ src += srcPitch;
+ dst += dstPitch;
+ }
+}
+
+void
+KdXVCopyPlanarData(KdScreenInfo *screen, CARD8 *src, CARD8 *dst, int randr,
+ int srcPitch, int srcPitch2, int dstPitch, int srcW, int srcH, int height,
+ int top, int left, int h, int w, int id)
+{
+ int i, j;
+ CARD8 *src1, *src2, *src3, *dst1;
+ int srcDown = srcPitch, srcDown2 = srcPitch2;
+ int srcRight = 2, srcRight2 = 1, srcNext = 1;
+
+ /* compute source data pointers */
+ src1 = src;
+ src2 = src1 + height * srcPitch;
+ src3 = src2 + (height >> 1) * srcPitch2;
+ switch (randr & RR_Rotate_All) {
+ case RR_Rotate_0:
+ srcDown = srcPitch;
+ srcDown2 = srcPitch2;
+ srcRight = 2;
+ srcRight2 = 1;
+ srcNext = 1;
+ break;
+ case RR_Rotate_90:
+ src1 = src1 + srcH - 1;
+ src2 = src2 + (srcH >> 1) - 1;
+ src3 = src3 + (srcH >> 1) - 1;
+ srcDown = -1;
+ srcDown2 = -1;
+ srcRight = srcPitch * 2;
+ srcRight2 = srcPitch2;
+ srcNext = srcPitch;
+ break;
+ case RR_Rotate_180:
+ src1 = src1 + srcPitch * (srcH - 1) + (srcW - 1);
+ src2 = src2 + srcPitch2 * ((srcH >> 1) - 1) + ((srcW >> 1) - 1);
+ src3 = src3 + srcPitch2 * ((srcH >> 1) - 1) + ((srcW >> 1) - 1);
+ srcDown = -srcPitch;
+ srcDown2 = -srcPitch2;
+ srcRight = -2;
+ srcRight2 = -1;
+ srcNext = -1;
+ break;
+ case RR_Rotate_270:
+ src1 = src1 + srcPitch * (srcW - 1);
+ src2 = src2 + srcPitch2 * ((srcW >> 1) - 1);
+ src3 = src3 + srcPitch2 * ((srcW >> 1) - 1);
+ srcDown = 1;
+ srcDown2 = 1;
+ srcRight = -srcPitch * 2;
+ srcRight2 = -srcPitch2;
+ srcNext = -srcPitch;
+ break;
+ }
+
+ /* adjust for origin */
+ src1 += top * srcDown + left * srcNext;
+ src2 += (top >> 1) * srcDown2 + (left >> 1) * srcRight2;
+ src3 += (top >> 1) * srcDown2 + (left >> 1) * srcRight2;
+
+ if (id == FOURCC_I420) {
+ CARD8 *srct = src2;
+ src2 = src3;
+ src3 = srct;
+ }
+
+ dst1 = dst;
+
+ w >>= 1;
+ for (j = 0; j < h; j++) {
+ CARD32 *dst = (CARD32 *)dst1;
+ CARD8 *s1l = src1;
+ CARD8 *s1r = src1 + srcNext;
+ CARD8 *s2 = src2;
+ CARD8 *s3 = src3;
+
+ for (i = 0; i < w; i++) {
+ *dst++ = *s1l | (*s1r << 16) | (*s3 << 8) | (*s2 << 24);
+ s1l += srcRight;
+ s1r += srcRight;
+ s2 += srcRight2;
+ s3 += srcRight2;
+ }
+ src1 += srcDown;
+ dst1 += dstPitch;
+ if (j & 1) {
+ src2 += srcDown2;
+ src3 += srcDown2;
+ }
+ }
+}
+
+void
+KXVPaintRegion (DrawablePtr pDraw, RegionPtr pRgn, Pixel fg)
+{
+ GCPtr pGC;
+ ChangeGCVal val[2];
+ xRectangle *rects, *r;
+ BoxPtr pBox = REGION_RECTS (pRgn);
+ int nBox = REGION_NUM_RECTS (pRgn);
+
+ rects = malloc(nBox * sizeof (xRectangle));
+ if (!rects)
+ goto bail0;
+ r = rects;
+ while (nBox--)
+ {
+ r->x = pBox->x1 - pDraw->x;
+ r->y = pBox->y1 - pDraw->y;
+ r->width = pBox->x2 - pBox->x1;
+ r->height = pBox->y2 - pBox->y1;
+ r++;
+ pBox++;
+ }
+
+ pGC = GetScratchGC (pDraw->depth, pDraw->pScreen);
+ if (!pGC)
+ goto bail1;
+
+ val[0].val = fg;
+ val[1].val = IncludeInferiors;
+ ChangeGC (NullClient, pGC, GCForeground|GCSubwindowMode, val);
+
+ ValidateGC (pDraw, pGC);
+
+ (*pGC->ops->PolyFillRect) (pDraw, pGC,
+ REGION_NUM_RECTS (pRgn), rects);
+
+ FreeScratchGC (pGC);
+bail1:
+ free(rects);
+bail0:
+ ;
+}
diff --git a/xorg-server/hw/vfb/InitOutput.c b/xorg-server/hw/vfb/InitOutput.c
index 29857877e..30e68e5d3 100644
--- a/xorg-server/hw/vfb/InitOutput.c
+++ b/xorg-server/hw/vfb/InitOutput.c
@@ -1,973 +1,973 @@
-/*
-
-Copyright 1993, 1998 The Open Group
-
-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.
-
-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 OPEN GROUP 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 Open Group 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 Open Group.
-
-*/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#if defined(WIN32)
-#include <X11/Xwinsock.h>
-#endif
-#include <stdio.h>
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include <X11/Xos.h>
-#include "scrnintstr.h"
-#include "servermd.h"
-#define PSZ 8
-#include "fb.h"
-#include "mibstore.h"
-#include "colormapst.h"
-#include "gcstruct.h"
-#include "input.h"
-#include "mipointer.h"
-#include "micmap.h"
-#include <sys/types.h>
-#ifdef HAS_MMAP
-#include <sys/mman.h>
-#ifndef MAP_FILE
-#define MAP_FILE 0
-#endif
-#endif /* HAS_MMAP */
-#include <sys/stat.h>
-#include <errno.h>
-#ifndef WIN32
-#include <sys/param.h>
-#endif
-#include <X11/XWDFile.h>
-#ifdef HAS_SHM
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#endif /* HAS_SHM */
-#include "dix.h"
-#include "miline.h"
-
-#define VFB_DEFAULT_WIDTH 1280
-#define VFB_DEFAULT_HEIGHT 1024
-#define VFB_DEFAULT_DEPTH 8
-#define VFB_DEFAULT_WHITEPIXEL 1
-#define VFB_DEFAULT_BLACKPIXEL 0
-#define VFB_DEFAULT_LINEBIAS 0
-#define XWD_WINDOW_NAME_LEN 60
-
-typedef struct
-{
- int width;
- int paddedBytesWidth;
- int paddedWidth;
- int height;
- int depth;
- int bitsPerPixel;
- int sizeInBytes;
- int ncolors;
- char *pfbMemory;
- XWDColor *pXWDCmap;
- XWDFileHeader *pXWDHeader;
- Pixel blackPixel;
- Pixel whitePixel;
- unsigned int lineBias;
- CloseScreenProcPtr closeScreen;
-
-#ifdef HAS_MMAP
- int mmap_fd;
- char mmap_file[MAXPATHLEN];
-#endif
-
-#ifdef HAS_SHM
- int shmid;
-#endif
-} vfbScreenInfo, *vfbScreenInfoPtr;
-
-static int vfbNumScreens;
-static vfbScreenInfo *vfbScreens;
-static vfbScreenInfo defaultScreenInfo = {
- .width = VFB_DEFAULT_WIDTH,
- .height = VFB_DEFAULT_HEIGHT,
- .depth = VFB_DEFAULT_DEPTH,
- .blackPixel = VFB_DEFAULT_BLACKPIXEL,
- .whitePixel = VFB_DEFAULT_WHITEPIXEL,
- .lineBias = VFB_DEFAULT_LINEBIAS,
-};
-static Bool vfbPixmapDepths[33];
-#ifdef HAS_MMAP
-static char *pfbdir = NULL;
-#endif
-typedef enum { NORMAL_MEMORY_FB, SHARED_MEMORY_FB, MMAPPED_FILE_FB } fbMemType;
-static fbMemType fbmemtype = NORMAL_MEMORY_FB;
-static char needswap = 0;
-static Bool Render = TRUE;
-
-#define swapcopy16(_dst, _src) \
- if (needswap) { CARD16 _s = _src; cpswaps(_s, _dst); } \
- else _dst = _src;
-
-#define swapcopy32(_dst, _src) \
- if (needswap) { CARD32 _s = _src; cpswapl(_s, _dst); } \
- else _dst = _src;
-
-
-static void
-vfbInitializePixmapDepths(void)
-{
- int i;
- vfbPixmapDepths[1] = TRUE; /* always need bitmaps */
- for (i = 2; i <= 32; i++)
- vfbPixmapDepths[i] = FALSE;
-}
-
-static int
-vfbBitsPerPixel(int depth)
-{
- if (depth == 1) return 1;
- else if (depth <= 8) return 8;
- else if (depth <= 16) return 16;
- else return 32;
-}
-
-void
-ddxGiveUp(void)
-{
- int i;
-
- /* clean up the framebuffers */
-
- switch (fbmemtype)
- {
-#ifdef HAS_MMAP
- case MMAPPED_FILE_FB:
- for (i = 0; i < vfbNumScreens; i++)
- {
- if (-1 == unlink(vfbScreens[i].mmap_file))
- {
- perror("unlink");
- ErrorF("unlink %s failed, %s",
- vfbScreens[i].mmap_file, strerror(errno));
- }
- }
- break;
-#else /* HAS_MMAP */
- case MMAPPED_FILE_FB:
- break;
-#endif /* HAS_MMAP */
-
-#ifdef HAS_SHM
- case SHARED_MEMORY_FB:
- for (i = 0; i < vfbNumScreens; i++)
- {
- if (-1 == shmdt((char *)vfbScreens[i].pXWDHeader))
- {
- perror("shmdt");
- ErrorF("shmdt failed, %s", strerror(errno));
- }
- }
- break;
-#else /* HAS_SHM */
- case SHARED_MEMORY_FB:
- break;
-#endif /* HAS_SHM */
-
- case NORMAL_MEMORY_FB:
- for (i = 0; i < vfbNumScreens; i++)
- {
- Xfree(vfbScreens[i].pXWDHeader);
- }
- break;
- }
-}
-
-void
-AbortDDX(void)
-{
- ddxGiveUp();
-}
-
-#ifdef __APPLE__
-void
-DarwinHandleGUI(int argc, char *argv[])
-{
-}
-#endif
-
-void
-OsVendorInit(void)
-{
-}
-
-void
-OsVendorFatalError(void)
-{
-}
-
-#if defined(DDXBEFORERESET)
-void ddxBeforeReset(void)
-{
- return;
-}
-#endif
-
-void
-ddxUseMsg(void)
-{
- ErrorF("-screen scrn WxHxD set screen's width, height, depth\n");
- ErrorF("-pixdepths list-of-int support given pixmap depths\n");
- ErrorF("+/-render turn on/off RENDER extension support"
- "(default on)\n");
- ErrorF("-linebias n adjust thin line pixelization\n");
- ErrorF("-blackpixel n pixel value for black\n");
- ErrorF("-whitepixel n pixel value for white\n");
-
-#ifdef HAS_MMAP
- ErrorF("-fbdir directory put framebuffers in mmap'ed files in directory\n");
-#endif
-
-#ifdef HAS_SHM
- ErrorF("-shmem put framebuffers in shared memory\n");
-#endif
-}
-
-int
-ddxProcessArgument(int argc, char *argv[], int i)
-{
- static Bool firstTime = TRUE;
- static int lastScreen = -1;
- vfbScreenInfo *currentScreen;
-
- if (firstTime)
- {
- vfbInitializePixmapDepths();
- firstTime = FALSE;
- }
-
- if (lastScreen == -1)
- currentScreen = &defaultScreenInfo;
- else
- currentScreen = &vfbScreens[lastScreen];
-
-#define CHECK_FOR_REQUIRED_ARGUMENTS(num) \
- if (((i + num) >= argc) || (!argv[i + num])) { \
- ErrorF("Required argument to %s not specified\n", argv[i]); \
- UseMsg(); \
- FatalError("Required argument to %s not specified\n", argv[i]); \
- }
-
- if (strcmp (argv[i], "-screen") == 0) /* -screen n WxHxD */
- {
- int screenNum;
- CHECK_FOR_REQUIRED_ARGUMENTS(2);
- screenNum = atoi(argv[i+1]);
- if (screenNum < 0)
- {
- ErrorF("Invalid screen number %d\n", screenNum);
- UseMsg();
- FatalError("Invalid screen number %d passed to -screen\n",
- screenNum);
- }
-
- if (vfbNumScreens <= screenNum)
- {
- vfbScreens = xrealloc(vfbScreens, sizeof(*vfbScreens) * (screenNum + 1));
- if (!vfbScreens)
- FatalError("Not enough memory for screen %d\n", screenNum);
- for (; vfbNumScreens <= screenNum; ++vfbNumScreens)
- vfbScreens[vfbNumScreens] = defaultScreenInfo;
- }
-
- if (3 != sscanf(argv[i+2], "%dx%dx%d",
- &vfbScreens[screenNum].width,
- &vfbScreens[screenNum].height,
- &vfbScreens[screenNum].depth))
- {
- ErrorF("Invalid screen configuration %s\n", argv[i+2]);
- UseMsg();
- FatalError("Invalid screen configuration %s for -screen %d\n",
- argv[i+2], screenNum);
- }
-
- lastScreen = screenNum;
- return 3;
- }
-
- if (strcmp (argv[i], "-pixdepths") == 0) /* -pixdepths list-of-depth */
- {
- int depth, ret = 1;
-
- CHECK_FOR_REQUIRED_ARGUMENTS(1);
- while ((++i < argc) && (depth = atoi(argv[i])) != 0)
- {
- if (depth < 0 || depth > 32)
- {
- ErrorF("Invalid pixmap depth %d\n", depth);
- UseMsg();
- FatalError("Invalid pixmap depth %d passed to -pixdepths\n",
- depth);
- }
- vfbPixmapDepths[depth] = TRUE;
- ret++;
- }
- return ret;
- }
-
- if (strcmp (argv[i], "+render") == 0) /* +render */
- {
- Render = TRUE;
- return 1;
- }
-
- if (strcmp (argv[i], "-render") == 0) /* -render */
- {
- Render = FALSE;
-#ifdef COMPOSITE
- noCompositeExtension = TRUE;
-#endif
- return 1;
- }
-
- if (strcmp (argv[i], "-blackpixel") == 0) /* -blackpixel n */
- {
- CHECK_FOR_REQUIRED_ARGUMENTS(1);
- currentScreen->blackPixel = atoi(argv[++i]);
- return 2;
- }
-
- if (strcmp (argv[i], "-whitepixel") == 0) /* -whitepixel n */
- {
- CHECK_FOR_REQUIRED_ARGUMENTS(1);
- currentScreen->whitePixel = atoi(argv[++i]);
- return 2;
- }
-
- if (strcmp (argv[i], "-linebias") == 0) /* -linebias n */
- {
- CHECK_FOR_REQUIRED_ARGUMENTS(1);
- currentScreen->lineBias = atoi(argv[++i]);
- return 2;
- }
-
-#ifdef HAS_MMAP
- if (strcmp (argv[i], "-fbdir") == 0) /* -fbdir directory */
- {
- CHECK_FOR_REQUIRED_ARGUMENTS(1);
- pfbdir = argv[++i];
- fbmemtype = MMAPPED_FILE_FB;
- return 2;
- }
-#endif /* HAS_MMAP */
-
-#ifdef HAS_SHM
- if (strcmp (argv[i], "-shmem") == 0) /* -shmem */
- {
- fbmemtype = SHARED_MEMORY_FB;
- return 1;
- }
-#endif
-
- return 0;
-}
-
-static int cmapScrPrivateKeyIndex;
-static DevPrivateKey cmapScrPrivateKey = &cmapScrPrivateKeyIndex;
-
-#define GetInstalledColormap(s) ((ColormapPtr) dixLookupPrivate(&(s)->devPrivates, cmapScrPrivateKey))
-#define SetInstalledColormap(s,c) (dixSetPrivate(&(s)->devPrivates, cmapScrPrivateKey, c))
-
-static int
-vfbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
-{
- /* By the time we are processing requests, we can guarantee that there
- * is always a colormap installed */
- *pmaps = GetInstalledColormap(pScreen)->mid;
- return (1);
-}
-
-
-static void
-vfbInstallColormap(ColormapPtr pmap)
-{
- ColormapPtr oldpmap = GetInstalledColormap(pmap->pScreen);
-
- if (pmap != oldpmap)
- {
- int entries;
- XWDFileHeader *pXWDHeader;
- XWDColor *pXWDCmap;
- VisualPtr pVisual;
- Pixel * ppix;
- xrgb * prgb;
- xColorItem *defs;
- int i;
-
- if(oldpmap != (ColormapPtr)None)
- WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid);
- /* Install pmap */
- SetInstalledColormap(pmap->pScreen, pmap);
- WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid);
-
- entries = pmap->pVisual->ColormapEntries;
- pXWDHeader = vfbScreens[pmap->pScreen->myNum].pXWDHeader;
- pXWDCmap = vfbScreens[pmap->pScreen->myNum].pXWDCmap;
- pVisual = pmap->pVisual;
-
- swapcopy32(pXWDHeader->visual_class, pVisual->class);
- swapcopy32(pXWDHeader->red_mask, pVisual->redMask);
- swapcopy32(pXWDHeader->green_mask, pVisual->greenMask);
- swapcopy32(pXWDHeader->blue_mask, pVisual->blueMask);
- swapcopy32(pXWDHeader->bits_per_rgb, pVisual->bitsPerRGBValue);
- swapcopy32(pXWDHeader->colormap_entries, pVisual->ColormapEntries);
-
- ppix = (Pixel *)xalloc(entries * sizeof(Pixel));
- prgb = (xrgb *)xalloc(entries * sizeof(xrgb));
- defs = (xColorItem *)xalloc(entries * sizeof(xColorItem));
-
- for (i = 0; i < entries; i++) ppix[i] = i;
- /* XXX truecolor */
- QueryColors(pmap, entries, ppix, prgb);
-
- for (i = 0; i < entries; i++) { /* convert xrgbs to xColorItems */
- defs[i].pixel = ppix[i] & 0xff; /* change pixel to index */
- defs[i].red = prgb[i].red;
- defs[i].green = prgb[i].green;
- defs[i].blue = prgb[i].blue;
- defs[i].flags = DoRed|DoGreen|DoBlue;
- }
- (*pmap->pScreen->StoreColors)(pmap, entries, defs);
-
- xfree(ppix);
- xfree(prgb);
- xfree(defs);
- }
-}
-
-static void
-vfbUninstallColormap(ColormapPtr pmap)
-{
- ColormapPtr curpmap = GetInstalledColormap(pmap->pScreen);
-
- if(pmap == curpmap)
- {
- if (pmap->mid != pmap->pScreen->defColormap)
- {
- dixLookupResourceByType((pointer *)&curpmap,
- pmap->pScreen->defColormap,
- RT_COLORMAP, serverClient,
- DixInstallAccess);
- (*pmap->pScreen->InstallColormap)(curpmap);
- }
- }
-}
-
-static void
-vfbStoreColors(ColormapPtr pmap, int ndef, xColorItem *pdefs)
-{
- XWDColor *pXWDCmap;
- int i;
-
- if (pmap != GetInstalledColormap(pmap->pScreen))
- {
- return;
- }
-
- pXWDCmap = vfbScreens[pmap->pScreen->myNum].pXWDCmap;
-
- if ((pmap->pVisual->class | DynamicClass) == DirectColor)
- {
- return;
- }
-
- for (i = 0; i < ndef; i++)
- {
- if (pdefs[i].flags & DoRed)
- {
- swapcopy16(pXWDCmap[pdefs[i].pixel].red, pdefs[i].red);
- }
- if (pdefs[i].flags & DoGreen)
- {
- swapcopy16(pXWDCmap[pdefs[i].pixel].green, pdefs[i].green);
- }
- if (pdefs[i].flags & DoBlue)
- {
- swapcopy16(pXWDCmap[pdefs[i].pixel].blue, pdefs[i].blue);
- }
- }
-}
-
-static Bool
-vfbSaveScreen(ScreenPtr pScreen, int on)
-{
- return TRUE;
-}
-
-#ifdef HAS_MMAP
-
-/* this flushes any changes to the screens out to the mmapped file */
-static void
-vfbBlockHandler(pointer blockData, OSTimePtr pTimeout, pointer pReadmask)
-{
- int i;
-
- for (i = 0; i < vfbNumScreens; i++)
- {
-#ifdef MS_ASYNC
- if (-1 == msync((caddr_t)vfbScreens[i].pXWDHeader,
- (size_t)vfbScreens[i].sizeInBytes, MS_ASYNC))
-#else
- /* silly NetBSD and who else? */
- if (-1 == msync((caddr_t)vfbScreens[i].pXWDHeader,
- (size_t)vfbScreens[i].sizeInBytes))
-#endif
- {
- perror("msync");
- ErrorF("msync failed, %s", strerror(errno));
- }
- }
-}
-
-
-static void
-vfbWakeupHandler(pointer blockData, int result, pointer pReadmask)
-{
-}
-
-
-static void
-vfbAllocateMmappedFramebuffer(vfbScreenInfoPtr pvfb)
-{
-#define DUMMY_BUFFER_SIZE 65536
- char dummyBuffer[DUMMY_BUFFER_SIZE];
- int currentFileSize, writeThisTime;
-
- sprintf(pvfb->mmap_file, "%s/Xvfb_screen%d", pfbdir, (int) (pvfb - vfbScreens));
- if (-1 == (pvfb->mmap_fd = open(pvfb->mmap_file, O_CREAT|O_RDWR, 0666)))
- {
- perror("open");
- ErrorF("open %s failed, %s", pvfb->mmap_file, strerror(errno));
- return;
- }
-
- /* Extend the file to be the proper size */
-
- bzero(dummyBuffer, DUMMY_BUFFER_SIZE);
- for (currentFileSize = 0;
- currentFileSize < pvfb->sizeInBytes;
- currentFileSize += writeThisTime)
- {
- writeThisTime = min(DUMMY_BUFFER_SIZE,
- pvfb->sizeInBytes - currentFileSize);
- if (-1 == write(pvfb->mmap_fd, dummyBuffer, writeThisTime))
- {
- perror("write");
- ErrorF("write %s failed, %s", pvfb->mmap_file, strerror(errno));
- return;
- }
- }
-
- /* try to mmap the file */
-
- pvfb->pXWDHeader = (XWDFileHeader *)mmap((caddr_t)NULL, pvfb->sizeInBytes,
- PROT_READ|PROT_WRITE,
- MAP_FILE|MAP_SHARED,
- pvfb->mmap_fd, 0);
- if (-1 == (long)pvfb->pXWDHeader)
- {
- perror("mmap");
- ErrorF("mmap %s failed, %s", pvfb->mmap_file, strerror(errno));
- pvfb->pXWDHeader = NULL;
- return;
- }
-
- if (!RegisterBlockAndWakeupHandlers(vfbBlockHandler, vfbWakeupHandler,
- NULL))
- {
- pvfb->pXWDHeader = NULL;
- }
-}
-#endif /* HAS_MMAP */
-
-
-#ifdef HAS_SHM
-static void
-vfbAllocateSharedMemoryFramebuffer(vfbScreenInfoPtr pvfb)
-{
- /* create the shared memory segment */
-
- pvfb->shmid = shmget(IPC_PRIVATE, pvfb->sizeInBytes, IPC_CREAT|0777);
- if (pvfb->shmid < 0)
- {
- perror("shmget");
- ErrorF("shmget %d bytes failed, %s", pvfb->sizeInBytes, strerror(errno));
- return;
- }
-
- /* try to attach it */
-
- pvfb->pXWDHeader = (XWDFileHeader *)shmat(pvfb->shmid, 0, 0);
- if (-1 == (long)pvfb->pXWDHeader)
- {
- perror("shmat");
- ErrorF("shmat failed, %s", strerror(errno));
- pvfb->pXWDHeader = NULL;
- return;
- }
-
- ErrorF("screen %d shmid %d\n", (int) (pvfb - vfbScreens), pvfb->shmid);
-}
-#endif /* HAS_SHM */
-
-static char *
-vfbAllocateFramebufferMemory(vfbScreenInfoPtr pvfb)
-{
- if (pvfb->pfbMemory) return pvfb->pfbMemory; /* already done */
-
- pvfb->sizeInBytes = pvfb->paddedBytesWidth * pvfb->height;
-
- /* Calculate how many entries in colormap. This is rather bogus, because
- * the visuals haven't even been set up yet, but we need to know because we
- * have to allocate space in the file for the colormap. The number 10
- * below comes from the MAX_PSEUDO_DEPTH define in cfbcmap.c.
- */
-
- if (pvfb->depth <= 10)
- { /* single index colormaps */
- pvfb->ncolors = 1 << pvfb->depth;
- }
- else
- { /* decomposed colormaps */
- int nplanes_per_color_component = pvfb->depth / 3;
- if (pvfb->depth % 3) nplanes_per_color_component++;
- pvfb->ncolors = 1 << nplanes_per_color_component;
- }
-
- /* add extra bytes for XWDFileHeader, window name, and colormap */
-
- pvfb->sizeInBytes += SIZEOF(XWDheader) + XWD_WINDOW_NAME_LEN +
- pvfb->ncolors * SIZEOF(XWDColor);
-
- pvfb->pXWDHeader = NULL;
- switch (fbmemtype)
- {
-#ifdef HAS_MMAP
- case MMAPPED_FILE_FB: vfbAllocateMmappedFramebuffer(pvfb); break;
-#else
- case MMAPPED_FILE_FB: break;
-#endif
-
-#ifdef HAS_SHM
- case SHARED_MEMORY_FB: vfbAllocateSharedMemoryFramebuffer(pvfb); break;
-#else
- case SHARED_MEMORY_FB: break;
-#endif
-
- case NORMAL_MEMORY_FB:
- pvfb->pXWDHeader = (XWDFileHeader *)Xalloc(pvfb->sizeInBytes);
- break;
- }
-
- if (pvfb->pXWDHeader)
- {
- pvfb->pXWDCmap = (XWDColor *)((char *)pvfb->pXWDHeader
- + SIZEOF(XWDheader) + XWD_WINDOW_NAME_LEN);
- pvfb->pfbMemory = (char *)(pvfb->pXWDCmap + pvfb->ncolors);
-
- return pvfb->pfbMemory;
- }
- else
- return NULL;
-}
-
-
-static void
-vfbWriteXWDFileHeader(ScreenPtr pScreen)
-{
- vfbScreenInfoPtr pvfb = &vfbScreens[pScreen->myNum];
- XWDFileHeader *pXWDHeader = pvfb->pXWDHeader;
- char hostname[XWD_WINDOW_NAME_LEN];
- unsigned long swaptest = 1;
- int i;
-
- needswap = *(char *) &swaptest;
-
- pXWDHeader->header_size = (char *)pvfb->pXWDCmap - (char *)pvfb->pXWDHeader;
- pXWDHeader->file_version = XWD_FILE_VERSION;
-
- pXWDHeader->pixmap_format = ZPixmap;
- pXWDHeader->pixmap_depth = pvfb->depth;
- pXWDHeader->pixmap_height = pXWDHeader->window_height = pvfb->height;
- pXWDHeader->xoffset = 0;
- pXWDHeader->byte_order = IMAGE_BYTE_ORDER;
- pXWDHeader->bitmap_bit_order = BITMAP_BIT_ORDER;
-#ifndef INTERNAL_VS_EXTERNAL_PADDING
- pXWDHeader->pixmap_width = pXWDHeader->window_width = pvfb->width;
- pXWDHeader->bitmap_unit = BITMAP_SCANLINE_UNIT;
- pXWDHeader->bitmap_pad = BITMAP_SCANLINE_PAD;
-#else
- pXWDHeader->pixmap_width = pXWDHeader->window_width = pvfb->paddedWidth;
- pXWDHeader->bitmap_unit = BITMAP_SCANLINE_UNIT_PROTO;
- pXWDHeader->bitmap_pad = BITMAP_SCANLINE_PAD_PROTO;
-#endif
- pXWDHeader->bits_per_pixel = pvfb->bitsPerPixel;
- pXWDHeader->bytes_per_line = pvfb->paddedBytesWidth;
- pXWDHeader->ncolors = pvfb->ncolors;
-
- /* visual related fields are written when colormap is installed */
-
- pXWDHeader->window_x = pXWDHeader->window_y = 0;
- pXWDHeader->window_bdrwidth = 0;
-
- /* write xwd "window" name: Xvfb hostname:server.screen */
-
- if (-1 == gethostname(hostname, sizeof(hostname)))
- hostname[0] = 0;
- else
- hostname[XWD_WINDOW_NAME_LEN-1] = 0;
- sprintf((char *)(pXWDHeader+1), "Xvfb %s:%s.%d", hostname, display,
- pScreen->myNum);
-
- /* write colormap pixel slot values */
-
- for (i = 0; i < pvfb->ncolors; i++)
- {
- pvfb->pXWDCmap[i].pixel = i;
- }
-
- /* byte swap to most significant byte first */
-
- if (needswap)
- {
- SwapLongs((CARD32 *)pXWDHeader, SIZEOF(XWDheader)/4);
- for (i = 0; i < pvfb->ncolors; i++)
- {
- register char n;
- swapl(&pvfb->pXWDCmap[i].pixel, n);
- }
- }
-}
-
-
-static Bool
-vfbCursorOffScreen (ScreenPtr *ppScreen, int *x, int *y)
-{
- return FALSE;
-}
-
-static void
-vfbCrossScreen (ScreenPtr pScreen, Bool entering)
-{
-}
-
-static miPointerScreenFuncRec vfbPointerCursorFuncs =
-{
- vfbCursorOffScreen,
- vfbCrossScreen,
- miPointerWarpCursor
-};
-
-static Bool
-vfbCloseScreen(int index, ScreenPtr pScreen)
-{
- vfbScreenInfoPtr pvfb = &vfbScreens[index];
- int i;
-
- pScreen->CloseScreen = pvfb->closeScreen;
-
- /*
- * XXX probably lots of stuff to clean. For now,
- * clear installed colormaps so that server reset works correctly.
- */
- for (i = 0; i < screenInfo.numScreens; i++)
- SetInstalledColormap(screenInfo.screens[i], NULL);
-
- return pScreen->CloseScreen(index, pScreen);
-}
-
-static Bool
-vfbScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
-{
- vfbScreenInfoPtr pvfb = &vfbScreens[index];
- int dpix = monitorResolution, dpiy = monitorResolution;
- int ret;
- char *pbits;
-
- if (dpix == 0)
- dpix = 100;
-
- if (dpiy == 0)
- dpiy = 100;
-
- pvfb->paddedBytesWidth = PixmapBytePad(pvfb->width, pvfb->depth);
- pvfb->bitsPerPixel = vfbBitsPerPixel(pvfb->depth);
- if (pvfb->bitsPerPixel >= 8 )
- pvfb->paddedWidth = pvfb->paddedBytesWidth / (pvfb->bitsPerPixel / 8);
- else
- pvfb->paddedWidth = pvfb->paddedBytesWidth * 8;
- pbits = vfbAllocateFramebufferMemory(pvfb);
- if (!pbits) return FALSE;
-
- switch (pvfb->depth) {
- case 8:
- miSetVisualTypesAndMasks (8,
- ((1 << StaticGray) |
- (1 << GrayScale) |
- (1 << StaticColor) |
- (1 << PseudoColor) |
- (1 << TrueColor) |
- (1 << DirectColor)),
- 8, PseudoColor, 0, 0, 0);
- break;
- case 15:
- miSetVisualTypesAndMasks (15,
- ((1 << TrueColor) |
- (1 << DirectColor)),
- 8, TrueColor, 0x7c00, 0x03e0, 0x001f);
- break;
- case 16:
- miSetVisualTypesAndMasks (16,
- ((1 << TrueColor) |
- (1 << DirectColor)),
- 8, TrueColor, 0xf800, 0x07e0, 0x001f);
- break;
- case 24:
- miSetVisualTypesAndMasks (24,
- ((1 << TrueColor) |
- (1 << DirectColor)),
- 8, TrueColor, 0xff0000, 0x00ff00, 0x0000ff);
- break;
- case 30:
- miSetVisualTypesAndMasks (30,
- ((1 << TrueColor) |
- (1 << DirectColor)),
- 10, TrueColor, 0x3ff00000, 0x000ffc00, 0x000003ff);
- break;
- }
-
- miSetPixmapDepths ();
-
- ret = fbScreenInit(pScreen, pbits, pvfb->width, pvfb->height,
- dpix, dpiy, pvfb->paddedWidth,pvfb->bitsPerPixel);
- if (ret && Render)
- fbPictureInit (pScreen, 0, 0);
-
- if (!ret) return FALSE;
-
- miInitializeBackingStore(pScreen);
-
- /*
- * Circumvent the backing store that was just initialised. This amounts
- * to a truely bizarre way of initialising SaveDoomedAreas and friends.
- */
-
- pScreen->InstallColormap = vfbInstallColormap;
- pScreen->UninstallColormap = vfbUninstallColormap;
- pScreen->ListInstalledColormaps = vfbListInstalledColormaps;
-
- pScreen->SaveScreen = vfbSaveScreen;
- pScreen->StoreColors = vfbStoreColors;
-
- miDCInitialize(pScreen, &vfbPointerCursorFuncs);
-
- vfbWriteXWDFileHeader(pScreen);
-
- pScreen->blackPixel = pvfb->blackPixel;
- pScreen->whitePixel = pvfb->whitePixel;
-
- ret = fbCreateDefColormap(pScreen);
-
- miSetZeroLineBias(pScreen, pvfb->lineBias);
-
- pvfb->closeScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = vfbCloseScreen;
-
- return ret;
-
-} /* end vfbScreenInit */
-
-
-void
-InitOutput(ScreenInfo *screenInfo, int argc, char **argv)
-{
- int i;
- int NumFormats = 0;
-
- /* initialize pixmap formats */
-
- /* must have a pixmap depth to match every screen depth */
- for (i = 0; i < vfbNumScreens; i++)
- {
- vfbPixmapDepths[vfbScreens[i].depth] = TRUE;
- }
-
- /* RENDER needs a good set of pixmaps. */
- if (Render) {
- vfbPixmapDepths[1] = TRUE;
- vfbPixmapDepths[4] = TRUE;
- vfbPixmapDepths[8] = TRUE;
-#if 0
- vfbPixmapDepths[12] = TRUE;
-#endif
-/* vfbPixmapDepths[15] = TRUE; */
- vfbPixmapDepths[16] = TRUE;
- vfbPixmapDepths[24] = TRUE;
-#if 0
- vfbPixmapDepths[30] = TRUE;
-#endif
- vfbPixmapDepths[32] = TRUE;
- }
-
- for (i = 1; i <= 32; i++)
- {
- if (vfbPixmapDepths[i])
- {
- if (NumFormats >= MAXFORMATS)
- FatalError ("MAXFORMATS is too small for this server\n");
- screenInfo->formats[NumFormats].depth = i;
- screenInfo->formats[NumFormats].bitsPerPixel = vfbBitsPerPixel(i);
- screenInfo->formats[NumFormats].scanlinePad = BITMAP_SCANLINE_PAD;
- NumFormats++;
- }
- }
-
- screenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
- screenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
- screenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
- screenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
- screenInfo->numPixmapFormats = NumFormats;
-
- /* initialize screens */
-
- if (vfbNumScreens < 1)
- {
- vfbScreens = &defaultScreenInfo;
- vfbNumScreens = 1;
- }
- for (i = 0; i < vfbNumScreens; i++)
- {
- if (-1 == AddScreen(vfbScreenInit, argc, argv))
- {
- FatalError("Couldn't add screen %d", i);
- }
- }
-
-} /* end InitOutput */
+/*
+
+Copyright 1993, 1998 The Open Group
+
+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.
+
+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 OPEN GROUP 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 Open Group 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 Open Group.
+
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#if defined(WIN32)
+#include <X11/Xwinsock.h>
+#endif
+#include <stdio.h>
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/Xos.h>
+#include "scrnintstr.h"
+#include "servermd.h"
+#define PSZ 8
+#include "fb.h"
+#include "mibstore.h"
+#include "colormapst.h"
+#include "gcstruct.h"
+#include "input.h"
+#include "mipointer.h"
+#include "micmap.h"
+#include <sys/types.h>
+#ifdef HAS_MMAP
+#include <sys/mman.h>
+#ifndef MAP_FILE
+#define MAP_FILE 0
+#endif
+#endif /* HAS_MMAP */
+#include <sys/stat.h>
+#include <errno.h>
+#ifndef WIN32
+#include <sys/param.h>
+#endif
+#include <X11/XWDFile.h>
+#ifdef HAS_SHM
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#endif /* HAS_SHM */
+#include "dix.h"
+#include "miline.h"
+
+#define VFB_DEFAULT_WIDTH 1280
+#define VFB_DEFAULT_HEIGHT 1024
+#define VFB_DEFAULT_DEPTH 8
+#define VFB_DEFAULT_WHITEPIXEL 1
+#define VFB_DEFAULT_BLACKPIXEL 0
+#define VFB_DEFAULT_LINEBIAS 0
+#define XWD_WINDOW_NAME_LEN 60
+
+typedef struct
+{
+ int width;
+ int paddedBytesWidth;
+ int paddedWidth;
+ int height;
+ int depth;
+ int bitsPerPixel;
+ int sizeInBytes;
+ int ncolors;
+ char *pfbMemory;
+ XWDColor *pXWDCmap;
+ XWDFileHeader *pXWDHeader;
+ Pixel blackPixel;
+ Pixel whitePixel;
+ unsigned int lineBias;
+ CloseScreenProcPtr closeScreen;
+
+#ifdef HAS_MMAP
+ int mmap_fd;
+ char mmap_file[MAXPATHLEN];
+#endif
+
+#ifdef HAS_SHM
+ int shmid;
+#endif
+} vfbScreenInfo, *vfbScreenInfoPtr;
+
+static int vfbNumScreens;
+static vfbScreenInfo *vfbScreens;
+static vfbScreenInfo defaultScreenInfo = {
+ .width = VFB_DEFAULT_WIDTH,
+ .height = VFB_DEFAULT_HEIGHT,
+ .depth = VFB_DEFAULT_DEPTH,
+ .blackPixel = VFB_DEFAULT_BLACKPIXEL,
+ .whitePixel = VFB_DEFAULT_WHITEPIXEL,
+ .lineBias = VFB_DEFAULT_LINEBIAS,
+};
+static Bool vfbPixmapDepths[33];
+#ifdef HAS_MMAP
+static char *pfbdir = NULL;
+#endif
+typedef enum { NORMAL_MEMORY_FB, SHARED_MEMORY_FB, MMAPPED_FILE_FB } fbMemType;
+static fbMemType fbmemtype = NORMAL_MEMORY_FB;
+static char needswap = 0;
+static Bool Render = TRUE;
+
+#define swapcopy16(_dst, _src) \
+ if (needswap) { CARD16 _s = _src; cpswaps(_s, _dst); } \
+ else _dst = _src;
+
+#define swapcopy32(_dst, _src) \
+ if (needswap) { CARD32 _s = _src; cpswapl(_s, _dst); } \
+ else _dst = _src;
+
+
+static void
+vfbInitializePixmapDepths(void)
+{
+ int i;
+ vfbPixmapDepths[1] = TRUE; /* always need bitmaps */
+ for (i = 2; i <= 32; i++)
+ vfbPixmapDepths[i] = FALSE;
+}
+
+static int
+vfbBitsPerPixel(int depth)
+{
+ if (depth == 1) return 1;
+ else if (depth <= 8) return 8;
+ else if (depth <= 16) return 16;
+ else return 32;
+}
+
+void
+ddxGiveUp(void)
+{
+ int i;
+
+ /* clean up the framebuffers */
+
+ switch (fbmemtype)
+ {
+#ifdef HAS_MMAP
+ case MMAPPED_FILE_FB:
+ for (i = 0; i < vfbNumScreens; i++)
+ {
+ if (-1 == unlink(vfbScreens[i].mmap_file))
+ {
+ perror("unlink");
+ ErrorF("unlink %s failed, %s",
+ vfbScreens[i].mmap_file, strerror(errno));
+ }
+ }
+ break;
+#else /* HAS_MMAP */
+ case MMAPPED_FILE_FB:
+ break;
+#endif /* HAS_MMAP */
+
+#ifdef HAS_SHM
+ case SHARED_MEMORY_FB:
+ for (i = 0; i < vfbNumScreens; i++)
+ {
+ if (-1 == shmdt((char *)vfbScreens[i].pXWDHeader))
+ {
+ perror("shmdt");
+ ErrorF("shmdt failed, %s", strerror(errno));
+ }
+ }
+ break;
+#else /* HAS_SHM */
+ case SHARED_MEMORY_FB:
+ break;
+#endif /* HAS_SHM */
+
+ case NORMAL_MEMORY_FB:
+ for (i = 0; i < vfbNumScreens; i++)
+ {
+ free(vfbScreens[i].pXWDHeader);
+ }
+ break;
+ }
+}
+
+void
+AbortDDX(void)
+{
+ ddxGiveUp();
+}
+
+#ifdef __APPLE__
+void
+DarwinHandleGUI(int argc, char *argv[])
+{
+}
+#endif
+
+void
+OsVendorInit(void)
+{
+}
+
+void
+OsVendorFatalError(void)
+{
+}
+
+#if defined(DDXBEFORERESET)
+void ddxBeforeReset(void)
+{
+ return;
+}
+#endif
+
+void
+ddxUseMsg(void)
+{
+ ErrorF("-screen scrn WxHxD set screen's width, height, depth\n");
+ ErrorF("-pixdepths list-of-int support given pixmap depths\n");
+ ErrorF("+/-render turn on/off RENDER extension support"
+ "(default on)\n");
+ ErrorF("-linebias n adjust thin line pixelization\n");
+ ErrorF("-blackpixel n pixel value for black\n");
+ ErrorF("-whitepixel n pixel value for white\n");
+
+#ifdef HAS_MMAP
+ ErrorF("-fbdir directory put framebuffers in mmap'ed files in directory\n");
+#endif
+
+#ifdef HAS_SHM
+ ErrorF("-shmem put framebuffers in shared memory\n");
+#endif
+}
+
+int
+ddxProcessArgument(int argc, char *argv[], int i)
+{
+ static Bool firstTime = TRUE;
+ static int lastScreen = -1;
+ vfbScreenInfo *currentScreen;
+
+ if (firstTime)
+ {
+ vfbInitializePixmapDepths();
+ firstTime = FALSE;
+ }
+
+ if (lastScreen == -1)
+ currentScreen = &defaultScreenInfo;
+ else
+ currentScreen = &vfbScreens[lastScreen];
+
+#define CHECK_FOR_REQUIRED_ARGUMENTS(num) \
+ if (((i + num) >= argc) || (!argv[i + num])) { \
+ ErrorF("Required argument to %s not specified\n", argv[i]); \
+ UseMsg(); \
+ FatalError("Required argument to %s not specified\n", argv[i]); \
+ }
+
+ if (strcmp (argv[i], "-screen") == 0) /* -screen n WxHxD */
+ {
+ int screenNum;
+ CHECK_FOR_REQUIRED_ARGUMENTS(2);
+ screenNum = atoi(argv[i+1]);
+ if (screenNum < 0)
+ {
+ ErrorF("Invalid screen number %d\n", screenNum);
+ UseMsg();
+ FatalError("Invalid screen number %d passed to -screen\n",
+ screenNum);
+ }
+
+ if (vfbNumScreens <= screenNum)
+ {
+ vfbScreens = realloc(vfbScreens, sizeof(*vfbScreens) * (screenNum + 1));
+ if (!vfbScreens)
+ FatalError("Not enough memory for screen %d\n", screenNum);
+ for (; vfbNumScreens <= screenNum; ++vfbNumScreens)
+ vfbScreens[vfbNumScreens] = defaultScreenInfo;
+ }
+
+ if (3 != sscanf(argv[i+2], "%dx%dx%d",
+ &vfbScreens[screenNum].width,
+ &vfbScreens[screenNum].height,
+ &vfbScreens[screenNum].depth))
+ {
+ ErrorF("Invalid screen configuration %s\n", argv[i+2]);
+ UseMsg();
+ FatalError("Invalid screen configuration %s for -screen %d\n",
+ argv[i+2], screenNum);
+ }
+
+ lastScreen = screenNum;
+ return 3;
+ }
+
+ if (strcmp (argv[i], "-pixdepths") == 0) /* -pixdepths list-of-depth */
+ {
+ int depth, ret = 1;
+
+ CHECK_FOR_REQUIRED_ARGUMENTS(1);
+ while ((++i < argc) && (depth = atoi(argv[i])) != 0)
+ {
+ if (depth < 0 || depth > 32)
+ {
+ ErrorF("Invalid pixmap depth %d\n", depth);
+ UseMsg();
+ FatalError("Invalid pixmap depth %d passed to -pixdepths\n",
+ depth);
+ }
+ vfbPixmapDepths[depth] = TRUE;
+ ret++;
+ }
+ return ret;
+ }
+
+ if (strcmp (argv[i], "+render") == 0) /* +render */
+ {
+ Render = TRUE;
+ return 1;
+ }
+
+ if (strcmp (argv[i], "-render") == 0) /* -render */
+ {
+ Render = FALSE;
+#ifdef COMPOSITE
+ noCompositeExtension = TRUE;
+#endif
+ return 1;
+ }
+
+ if (strcmp (argv[i], "-blackpixel") == 0) /* -blackpixel n */
+ {
+ CHECK_FOR_REQUIRED_ARGUMENTS(1);
+ currentScreen->blackPixel = atoi(argv[++i]);
+ return 2;
+ }
+
+ if (strcmp (argv[i], "-whitepixel") == 0) /* -whitepixel n */
+ {
+ CHECK_FOR_REQUIRED_ARGUMENTS(1);
+ currentScreen->whitePixel = atoi(argv[++i]);
+ return 2;
+ }
+
+ if (strcmp (argv[i], "-linebias") == 0) /* -linebias n */
+ {
+ CHECK_FOR_REQUIRED_ARGUMENTS(1);
+ currentScreen->lineBias = atoi(argv[++i]);
+ return 2;
+ }
+
+#ifdef HAS_MMAP
+ if (strcmp (argv[i], "-fbdir") == 0) /* -fbdir directory */
+ {
+ CHECK_FOR_REQUIRED_ARGUMENTS(1);
+ pfbdir = argv[++i];
+ fbmemtype = MMAPPED_FILE_FB;
+ return 2;
+ }
+#endif /* HAS_MMAP */
+
+#ifdef HAS_SHM
+ if (strcmp (argv[i], "-shmem") == 0) /* -shmem */
+ {
+ fbmemtype = SHARED_MEMORY_FB;
+ return 1;
+ }
+#endif
+
+ return 0;
+}
+
+static int cmapScrPrivateKeyIndex;
+static DevPrivateKey cmapScrPrivateKey = &cmapScrPrivateKeyIndex;
+
+#define GetInstalledColormap(s) ((ColormapPtr) dixLookupPrivate(&(s)->devPrivates, cmapScrPrivateKey))
+#define SetInstalledColormap(s,c) (dixSetPrivate(&(s)->devPrivates, cmapScrPrivateKey, c))
+
+static int
+vfbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
+{
+ /* By the time we are processing requests, we can guarantee that there
+ * is always a colormap installed */
+ *pmaps = GetInstalledColormap(pScreen)->mid;
+ return (1);
+}
+
+
+static void
+vfbInstallColormap(ColormapPtr pmap)
+{
+ ColormapPtr oldpmap = GetInstalledColormap(pmap->pScreen);
+
+ if (pmap != oldpmap)
+ {
+ int entries;
+ XWDFileHeader *pXWDHeader;
+ XWDColor *pXWDCmap;
+ VisualPtr pVisual;
+ Pixel * ppix;
+ xrgb * prgb;
+ xColorItem *defs;
+ int i;
+
+ if(oldpmap != (ColormapPtr)None)
+ WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid);
+ /* Install pmap */
+ SetInstalledColormap(pmap->pScreen, pmap);
+ WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid);
+
+ entries = pmap->pVisual->ColormapEntries;
+ pXWDHeader = vfbScreens[pmap->pScreen->myNum].pXWDHeader;
+ pXWDCmap = vfbScreens[pmap->pScreen->myNum].pXWDCmap;
+ pVisual = pmap->pVisual;
+
+ swapcopy32(pXWDHeader->visual_class, pVisual->class);
+ swapcopy32(pXWDHeader->red_mask, pVisual->redMask);
+ swapcopy32(pXWDHeader->green_mask, pVisual->greenMask);
+ swapcopy32(pXWDHeader->blue_mask, pVisual->blueMask);
+ swapcopy32(pXWDHeader->bits_per_rgb, pVisual->bitsPerRGBValue);
+ swapcopy32(pXWDHeader->colormap_entries, pVisual->ColormapEntries);
+
+ ppix = (Pixel *)malloc(entries * sizeof(Pixel));
+ prgb = (xrgb *)malloc(entries * sizeof(xrgb));
+ defs = (xColorItem *)malloc(entries * sizeof(xColorItem));
+
+ for (i = 0; i < entries; i++) ppix[i] = i;
+ /* XXX truecolor */
+ QueryColors(pmap, entries, ppix, prgb, serverClient);
+
+ for (i = 0; i < entries; i++) { /* convert xrgbs to xColorItems */
+ defs[i].pixel = ppix[i] & 0xff; /* change pixel to index */
+ defs[i].red = prgb[i].red;
+ defs[i].green = prgb[i].green;
+ defs[i].blue = prgb[i].blue;
+ defs[i].flags = DoRed|DoGreen|DoBlue;
+ }
+ (*pmap->pScreen->StoreColors)(pmap, entries, defs);
+
+ free(ppix);
+ free(prgb);
+ free(defs);
+ }
+}
+
+static void
+vfbUninstallColormap(ColormapPtr pmap)
+{
+ ColormapPtr curpmap = GetInstalledColormap(pmap->pScreen);
+
+ if(pmap == curpmap)
+ {
+ if (pmap->mid != pmap->pScreen->defColormap)
+ {
+ dixLookupResourceByType((pointer *)&curpmap,
+ pmap->pScreen->defColormap,
+ RT_COLORMAP, serverClient,
+ DixInstallAccess);
+ (*pmap->pScreen->InstallColormap)(curpmap);
+ }
+ }
+}
+
+static void
+vfbStoreColors(ColormapPtr pmap, int ndef, xColorItem *pdefs)
+{
+ XWDColor *pXWDCmap;
+ int i;
+
+ if (pmap != GetInstalledColormap(pmap->pScreen))
+ {
+ return;
+ }
+
+ pXWDCmap = vfbScreens[pmap->pScreen->myNum].pXWDCmap;
+
+ if ((pmap->pVisual->class | DynamicClass) == DirectColor)
+ {
+ return;
+ }
+
+ for (i = 0; i < ndef; i++)
+ {
+ if (pdefs[i].flags & DoRed)
+ {
+ swapcopy16(pXWDCmap[pdefs[i].pixel].red, pdefs[i].red);
+ }
+ if (pdefs[i].flags & DoGreen)
+ {
+ swapcopy16(pXWDCmap[pdefs[i].pixel].green, pdefs[i].green);
+ }
+ if (pdefs[i].flags & DoBlue)
+ {
+ swapcopy16(pXWDCmap[pdefs[i].pixel].blue, pdefs[i].blue);
+ }
+ }
+}
+
+static Bool
+vfbSaveScreen(ScreenPtr pScreen, int on)
+{
+ return TRUE;
+}
+
+#ifdef HAS_MMAP
+
+/* this flushes any changes to the screens out to the mmapped file */
+static void
+vfbBlockHandler(pointer blockData, OSTimePtr pTimeout, pointer pReadmask)
+{
+ int i;
+
+ for (i = 0; i < vfbNumScreens; i++)
+ {
+#ifdef MS_ASYNC
+ if (-1 == msync((caddr_t)vfbScreens[i].pXWDHeader,
+ (size_t)vfbScreens[i].sizeInBytes, MS_ASYNC))
+#else
+ /* silly NetBSD and who else? */
+ if (-1 == msync((caddr_t)vfbScreens[i].pXWDHeader,
+ (size_t)vfbScreens[i].sizeInBytes))
+#endif
+ {
+ perror("msync");
+ ErrorF("msync failed, %s", strerror(errno));
+ }
+ }
+}
+
+
+static void
+vfbWakeupHandler(pointer blockData, int result, pointer pReadmask)
+{
+}
+
+
+static void
+vfbAllocateMmappedFramebuffer(vfbScreenInfoPtr pvfb)
+{
+#define DUMMY_BUFFER_SIZE 65536
+ char dummyBuffer[DUMMY_BUFFER_SIZE];
+ int currentFileSize, writeThisTime;
+
+ sprintf(pvfb->mmap_file, "%s/Xvfb_screen%d", pfbdir, (int) (pvfb - vfbScreens));
+ if (-1 == (pvfb->mmap_fd = open(pvfb->mmap_file, O_CREAT|O_RDWR, 0666)))
+ {
+ perror("open");
+ ErrorF("open %s failed, %s", pvfb->mmap_file, strerror(errno));
+ return;
+ }
+
+ /* Extend the file to be the proper size */
+
+ bzero(dummyBuffer, DUMMY_BUFFER_SIZE);
+ for (currentFileSize = 0;
+ currentFileSize < pvfb->sizeInBytes;
+ currentFileSize += writeThisTime)
+ {
+ writeThisTime = min(DUMMY_BUFFER_SIZE,
+ pvfb->sizeInBytes - currentFileSize);
+ if (-1 == write(pvfb->mmap_fd, dummyBuffer, writeThisTime))
+ {
+ perror("write");
+ ErrorF("write %s failed, %s", pvfb->mmap_file, strerror(errno));
+ return;
+ }
+ }
+
+ /* try to mmap the file */
+
+ pvfb->pXWDHeader = (XWDFileHeader *)mmap((caddr_t)NULL, pvfb->sizeInBytes,
+ PROT_READ|PROT_WRITE,
+ MAP_FILE|MAP_SHARED,
+ pvfb->mmap_fd, 0);
+ if (-1 == (long)pvfb->pXWDHeader)
+ {
+ perror("mmap");
+ ErrorF("mmap %s failed, %s", pvfb->mmap_file, strerror(errno));
+ pvfb->pXWDHeader = NULL;
+ return;
+ }
+
+ if (!RegisterBlockAndWakeupHandlers(vfbBlockHandler, vfbWakeupHandler,
+ NULL))
+ {
+ pvfb->pXWDHeader = NULL;
+ }
+}
+#endif /* HAS_MMAP */
+
+
+#ifdef HAS_SHM
+static void
+vfbAllocateSharedMemoryFramebuffer(vfbScreenInfoPtr pvfb)
+{
+ /* create the shared memory segment */
+
+ pvfb->shmid = shmget(IPC_PRIVATE, pvfb->sizeInBytes, IPC_CREAT|0777);
+ if (pvfb->shmid < 0)
+ {
+ perror("shmget");
+ ErrorF("shmget %d bytes failed, %s", pvfb->sizeInBytes, strerror(errno));
+ return;
+ }
+
+ /* try to attach it */
+
+ pvfb->pXWDHeader = (XWDFileHeader *)shmat(pvfb->shmid, 0, 0);
+ if (-1 == (long)pvfb->pXWDHeader)
+ {
+ perror("shmat");
+ ErrorF("shmat failed, %s", strerror(errno));
+ pvfb->pXWDHeader = NULL;
+ return;
+ }
+
+ ErrorF("screen %d shmid %d\n", (int) (pvfb - vfbScreens), pvfb->shmid);
+}
+#endif /* HAS_SHM */
+
+static char *
+vfbAllocateFramebufferMemory(vfbScreenInfoPtr pvfb)
+{
+ if (pvfb->pfbMemory) return pvfb->pfbMemory; /* already done */
+
+ pvfb->sizeInBytes = pvfb->paddedBytesWidth * pvfb->height;
+
+ /* Calculate how many entries in colormap. This is rather bogus, because
+ * the visuals haven't even been set up yet, but we need to know because we
+ * have to allocate space in the file for the colormap. The number 10
+ * below comes from the MAX_PSEUDO_DEPTH define in cfbcmap.c.
+ */
+
+ if (pvfb->depth <= 10)
+ { /* single index colormaps */
+ pvfb->ncolors = 1 << pvfb->depth;
+ }
+ else
+ { /* decomposed colormaps */
+ int nplanes_per_color_component = pvfb->depth / 3;
+ if (pvfb->depth % 3) nplanes_per_color_component++;
+ pvfb->ncolors = 1 << nplanes_per_color_component;
+ }
+
+ /* add extra bytes for XWDFileHeader, window name, and colormap */
+
+ pvfb->sizeInBytes += SIZEOF(XWDheader) + XWD_WINDOW_NAME_LEN +
+ pvfb->ncolors * SIZEOF(XWDColor);
+
+ pvfb->pXWDHeader = NULL;
+ switch (fbmemtype)
+ {
+#ifdef HAS_MMAP
+ case MMAPPED_FILE_FB: vfbAllocateMmappedFramebuffer(pvfb); break;
+#else
+ case MMAPPED_FILE_FB: break;
+#endif
+
+#ifdef HAS_SHM
+ case SHARED_MEMORY_FB: vfbAllocateSharedMemoryFramebuffer(pvfb); break;
+#else
+ case SHARED_MEMORY_FB: break;
+#endif
+
+ case NORMAL_MEMORY_FB:
+ pvfb->pXWDHeader = (XWDFileHeader *)malloc(pvfb->sizeInBytes);
+ break;
+ }
+
+ if (pvfb->pXWDHeader)
+ {
+ pvfb->pXWDCmap = (XWDColor *)((char *)pvfb->pXWDHeader
+ + SIZEOF(XWDheader) + XWD_WINDOW_NAME_LEN);
+ pvfb->pfbMemory = (char *)(pvfb->pXWDCmap + pvfb->ncolors);
+
+ return pvfb->pfbMemory;
+ }
+ else
+ return NULL;
+}
+
+
+static void
+vfbWriteXWDFileHeader(ScreenPtr pScreen)
+{
+ vfbScreenInfoPtr pvfb = &vfbScreens[pScreen->myNum];
+ XWDFileHeader *pXWDHeader = pvfb->pXWDHeader;
+ char hostname[XWD_WINDOW_NAME_LEN];
+ unsigned long swaptest = 1;
+ int i;
+
+ needswap = *(char *) &swaptest;
+
+ pXWDHeader->header_size = (char *)pvfb->pXWDCmap - (char *)pvfb->pXWDHeader;
+ pXWDHeader->file_version = XWD_FILE_VERSION;
+
+ pXWDHeader->pixmap_format = ZPixmap;
+ pXWDHeader->pixmap_depth = pvfb->depth;
+ pXWDHeader->pixmap_height = pXWDHeader->window_height = pvfb->height;
+ pXWDHeader->xoffset = 0;
+ pXWDHeader->byte_order = IMAGE_BYTE_ORDER;
+ pXWDHeader->bitmap_bit_order = BITMAP_BIT_ORDER;
+#ifndef INTERNAL_VS_EXTERNAL_PADDING
+ pXWDHeader->pixmap_width = pXWDHeader->window_width = pvfb->width;
+ pXWDHeader->bitmap_unit = BITMAP_SCANLINE_UNIT;
+ pXWDHeader->bitmap_pad = BITMAP_SCANLINE_PAD;
+#else
+ pXWDHeader->pixmap_width = pXWDHeader->window_width = pvfb->paddedWidth;
+ pXWDHeader->bitmap_unit = BITMAP_SCANLINE_UNIT_PROTO;
+ pXWDHeader->bitmap_pad = BITMAP_SCANLINE_PAD_PROTO;
+#endif
+ pXWDHeader->bits_per_pixel = pvfb->bitsPerPixel;
+ pXWDHeader->bytes_per_line = pvfb->paddedBytesWidth;
+ pXWDHeader->ncolors = pvfb->ncolors;
+
+ /* visual related fields are written when colormap is installed */
+
+ pXWDHeader->window_x = pXWDHeader->window_y = 0;
+ pXWDHeader->window_bdrwidth = 0;
+
+ /* write xwd "window" name: Xvfb hostname:server.screen */
+
+ if (-1 == gethostname(hostname, sizeof(hostname)))
+ hostname[0] = 0;
+ else
+ hostname[XWD_WINDOW_NAME_LEN-1] = 0;
+ sprintf((char *)(pXWDHeader+1), "Xvfb %s:%s.%d", hostname, display,
+ pScreen->myNum);
+
+ /* write colormap pixel slot values */
+
+ for (i = 0; i < pvfb->ncolors; i++)
+ {
+ pvfb->pXWDCmap[i].pixel = i;
+ }
+
+ /* byte swap to most significant byte first */
+
+ if (needswap)
+ {
+ SwapLongs((CARD32 *)pXWDHeader, SIZEOF(XWDheader)/4);
+ for (i = 0; i < pvfb->ncolors; i++)
+ {
+ register char n;
+ swapl(&pvfb->pXWDCmap[i].pixel, n);
+ }
+ }
+}
+
+
+static Bool
+vfbCursorOffScreen (ScreenPtr *ppScreen, int *x, int *y)
+{
+ return FALSE;
+}
+
+static void
+vfbCrossScreen (ScreenPtr pScreen, Bool entering)
+{
+}
+
+static miPointerScreenFuncRec vfbPointerCursorFuncs =
+{
+ vfbCursorOffScreen,
+ vfbCrossScreen,
+ miPointerWarpCursor
+};
+
+static Bool
+vfbCloseScreen(int index, ScreenPtr pScreen)
+{
+ vfbScreenInfoPtr pvfb = &vfbScreens[index];
+ int i;
+
+ pScreen->CloseScreen = pvfb->closeScreen;
+
+ /*
+ * XXX probably lots of stuff to clean. For now,
+ * clear installed colormaps so that server reset works correctly.
+ */
+ for (i = 0; i < screenInfo.numScreens; i++)
+ SetInstalledColormap(screenInfo.screens[i], NULL);
+
+ return pScreen->CloseScreen(index, pScreen);
+}
+
+static Bool
+vfbScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
+{
+ vfbScreenInfoPtr pvfb = &vfbScreens[index];
+ int dpix = monitorResolution, dpiy = monitorResolution;
+ int ret;
+ char *pbits;
+
+ if (dpix == 0)
+ dpix = 100;
+
+ if (dpiy == 0)
+ dpiy = 100;
+
+ pvfb->paddedBytesWidth = PixmapBytePad(pvfb->width, pvfb->depth);
+ pvfb->bitsPerPixel = vfbBitsPerPixel(pvfb->depth);
+ if (pvfb->bitsPerPixel >= 8 )
+ pvfb->paddedWidth = pvfb->paddedBytesWidth / (pvfb->bitsPerPixel / 8);
+ else
+ pvfb->paddedWidth = pvfb->paddedBytesWidth * 8;
+ pbits = vfbAllocateFramebufferMemory(pvfb);
+ if (!pbits) return FALSE;
+
+ switch (pvfb->depth) {
+ case 8:
+ miSetVisualTypesAndMasks (8,
+ ((1 << StaticGray) |
+ (1 << GrayScale) |
+ (1 << StaticColor) |
+ (1 << PseudoColor) |
+ (1 << TrueColor) |
+ (1 << DirectColor)),
+ 8, PseudoColor, 0, 0, 0);
+ break;
+ case 15:
+ miSetVisualTypesAndMasks (15,
+ ((1 << TrueColor) |
+ (1 << DirectColor)),
+ 8, TrueColor, 0x7c00, 0x03e0, 0x001f);
+ break;
+ case 16:
+ miSetVisualTypesAndMasks (16,
+ ((1 << TrueColor) |
+ (1 << DirectColor)),
+ 8, TrueColor, 0xf800, 0x07e0, 0x001f);
+ break;
+ case 24:
+ miSetVisualTypesAndMasks (24,
+ ((1 << TrueColor) |
+ (1 << DirectColor)),
+ 8, TrueColor, 0xff0000, 0x00ff00, 0x0000ff);
+ break;
+ case 30:
+ miSetVisualTypesAndMasks (30,
+ ((1 << TrueColor) |
+ (1 << DirectColor)),
+ 10, TrueColor, 0x3ff00000, 0x000ffc00, 0x000003ff);
+ break;
+ }
+
+ miSetPixmapDepths ();
+
+ ret = fbScreenInit(pScreen, pbits, pvfb->width, pvfb->height,
+ dpix, dpiy, pvfb->paddedWidth,pvfb->bitsPerPixel);
+ if (ret && Render)
+ fbPictureInit (pScreen, 0, 0);
+
+ if (!ret) return FALSE;
+
+ miInitializeBackingStore(pScreen);
+
+ /*
+ * Circumvent the backing store that was just initialised. This amounts
+ * to a truely bizarre way of initialising SaveDoomedAreas and friends.
+ */
+
+ pScreen->InstallColormap = vfbInstallColormap;
+ pScreen->UninstallColormap = vfbUninstallColormap;
+ pScreen->ListInstalledColormaps = vfbListInstalledColormaps;
+
+ pScreen->SaveScreen = vfbSaveScreen;
+ pScreen->StoreColors = vfbStoreColors;
+
+ miDCInitialize(pScreen, &vfbPointerCursorFuncs);
+
+ vfbWriteXWDFileHeader(pScreen);
+
+ pScreen->blackPixel = pvfb->blackPixel;
+ pScreen->whitePixel = pvfb->whitePixel;
+
+ ret = fbCreateDefColormap(pScreen);
+
+ miSetZeroLineBias(pScreen, pvfb->lineBias);
+
+ pvfb->closeScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = vfbCloseScreen;
+
+ return ret;
+
+} /* end vfbScreenInit */
+
+
+void
+InitOutput(ScreenInfo *screenInfo, int argc, char **argv)
+{
+ int i;
+ int NumFormats = 0;
+
+ /* initialize pixmap formats */
+
+ /* must have a pixmap depth to match every screen depth */
+ for (i = 0; i < vfbNumScreens; i++)
+ {
+ vfbPixmapDepths[vfbScreens[i].depth] = TRUE;
+ }
+
+ /* RENDER needs a good set of pixmaps. */
+ if (Render) {
+ vfbPixmapDepths[1] = TRUE;
+ vfbPixmapDepths[4] = TRUE;
+ vfbPixmapDepths[8] = TRUE;
+#if 0
+ vfbPixmapDepths[12] = TRUE;
+#endif
+/* vfbPixmapDepths[15] = TRUE; */
+ vfbPixmapDepths[16] = TRUE;
+ vfbPixmapDepths[24] = TRUE;
+#if 0
+ vfbPixmapDepths[30] = TRUE;
+#endif
+ vfbPixmapDepths[32] = TRUE;
+ }
+
+ for (i = 1; i <= 32; i++)
+ {
+ if (vfbPixmapDepths[i])
+ {
+ if (NumFormats >= MAXFORMATS)
+ FatalError ("MAXFORMATS is too small for this server\n");
+ screenInfo->formats[NumFormats].depth = i;
+ screenInfo->formats[NumFormats].bitsPerPixel = vfbBitsPerPixel(i);
+ screenInfo->formats[NumFormats].scanlinePad = BITMAP_SCANLINE_PAD;
+ NumFormats++;
+ }
+ }
+
+ screenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
+ screenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
+ screenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
+ screenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
+ screenInfo->numPixmapFormats = NumFormats;
+
+ /* initialize screens */
+
+ if (vfbNumScreens < 1)
+ {
+ vfbScreens = &defaultScreenInfo;
+ vfbNumScreens = 1;
+ }
+ for (i = 0; i < vfbNumScreens; i++)
+ {
+ if (-1 == AddScreen(vfbScreenInit, argc, argv))
+ {
+ FatalError("Couldn't add screen %d", i);
+ }
+ }
+
+} /* end InitOutput */
diff --git a/xorg-server/hw/xfree86/common/xf86.h b/xorg-server/hw/xfree86/common/xf86.h
index e9266abd4..cddca37a3 100644
--- a/xorg-server/hw/xfree86/common/xf86.h
+++ b/xorg-server/hw/xfree86/common/xf86.h
@@ -1,354 +1,354 @@
-/*
- * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-/*
- * This file contains declarations for public XFree86 functions and variables,
- * and definitions of public macros.
- *
- * "public" means available to video drivers.
- */
-
-#ifndef _XF86_H
-#define _XF86_H
-
-#if HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#elif HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <pciaccess.h>
-
-#include "xf86str.h"
-#include "xf86Opt.h"
-#include <X11/Xfuncproto.h>
-#include <stdarg.h>
-#ifdef RANDR
-#include <X11/extensions/randr.h>
-#endif
-
-#include "propertyst.h"
-
-/* General parameters */
-extern _X_EXPORT int xf86DoConfigure;
-extern _X_EXPORT int xf86DoShowOptions;
-extern _X_EXPORT Bool xf86DoConfigurePass1;
-extern _X_EXPORT DevPrivateKey xf86ScreenKey;
-extern _X_EXPORT DevPrivateKey xf86CreateRootWindowKey;
-extern _X_EXPORT DevPrivateKey xf86PixmapKey;
-extern _X_EXPORT ScrnInfoPtr *xf86Screens; /* List of pointers to ScrnInfoRecs */
-extern _X_EXPORT const unsigned char byte_reversed[256];
-extern _X_EXPORT Bool pciSlotClaimed;
-extern _X_EXPORT Bool fbSlotClaimed;
-#if defined(__sparc__) || defined(__sparc)
-extern _X_EXPORT Bool sbusSlotClaimed;
-#endif
-extern _X_EXPORT confDRIRec xf86ConfigDRI;
-extern _X_EXPORT Bool xf86inSuspend;
-extern _X_EXPORT Bool xf86DRI2Enabled(void);
-
-extern _X_EXPORT Bool VTSwitchEnabled; /* kbd driver */
-
-#define XF86SCRNINFO(p) ((ScrnInfoPtr)dixLookupPrivate(&(p)->devPrivates, \
- xf86ScreenKey))
-#define XF86FLIP_PIXELS() \
- do { \
- if (xf86GetFlipPixels()) { \
- pScreen->whitePixel = (pScreen->whitePixel) ? 0 : 1; \
- pScreen->blackPixel = (pScreen->blackPixel) ? 0 : 1; \
- } \
- while (0)
-
-#define BOOLTOSTRING(b) ((b) ? "TRUE" : "FALSE")
-
-#define PIX24TOBPP(p) (((p) == Pix24Use24) ? 24 : \
- (((p) == Pix24Use32) ? 32 : 0))
-
-/* Function Prototypes */
-#ifndef _NO_XF86_PROTOTYPES
-
-/* xf86Bus.c */
-
-extern _X_EXPORT Bool xf86CheckPciSlot( const struct pci_device * );
-extern _X_EXPORT int xf86ClaimPciSlot( struct pci_device *, DriverPtr drvp,
- int chipset, GDevPtr dev, Bool active);
-extern _X_EXPORT void xf86UnclaimPciSlot(struct pci_device *);
-extern _X_EXPORT Bool xf86ParsePciBusString(const char *busID, int *bus, int *device,
- int *func);
-extern _X_EXPORT Bool xf86ComparePciBusString(const char *busID, int bus, int device, int func);
-extern _X_EXPORT void xf86FormatPciBusNumber(int busnum, char *buffer);
-extern _X_EXPORT int xf86GetFbInfoForScreen(int scrnIndex);
-extern _X_EXPORT int xf86ClaimFbSlot(DriverPtr drvp, int chipset, GDevPtr dev, Bool active);
-extern _X_EXPORT int xf86ClaimNoSlot(DriverPtr drvp, int chipset, GDevPtr dev, Bool active);
-extern _X_EXPORT void xf86EnableAccess(ScrnInfoPtr pScrn);
-extern _X_EXPORT Bool xf86IsPrimaryPci(struct pci_device * pPci);
-/* new RAC */
-extern _X_EXPORT Bool xf86DriverHasEntities(DriverPtr drvp);
-extern _X_EXPORT void xf86AddEntityToScreen(ScrnInfoPtr pScrn, int entityIndex);
-extern _X_EXPORT void xf86SetEntityInstanceForScreen(ScrnInfoPtr pScrn, int entityIndex,
- int instance);
-extern _X_EXPORT int xf86GetNumEntityInstances(int entityIndex);
-extern _X_EXPORT GDevPtr xf86GetDevFromEntity(int entityIndex, int instance);
-extern _X_EXPORT void xf86RemoveEntityFromScreen(ScrnInfoPtr pScrn, int entityIndex);
-extern _X_EXPORT EntityInfoPtr xf86GetEntityInfo(int entityIndex);
-extern _X_EXPORT struct pci_device * xf86GetPciInfoForEntity(int entityIndex);
-extern _X_EXPORT Bool xf86SetEntityFuncs(int entityIndex, EntityProc init,
- EntityProc enter, EntityProc leave, pointer);
-extern _X_EXPORT Bool xf86CheckPciMemBase(struct pci_device * pPci, memType base);
-extern _X_EXPORT Bool xf86IsEntityPrimary(int entityIndex);
-extern _X_EXPORT void xf86EnterServerState(xf86State state);
-extern _X_EXPORT ScrnInfoPtr xf86FindScreenForEntity(int entityIndex);
-
-extern _X_EXPORT int xf86GetLastScrnFlag(int entityIndex);
-extern _X_EXPORT void xf86SetLastScrnFlag(int entityIndex, int scrnIndex);
-extern _X_EXPORT Bool xf86IsEntityShared(int entityIndex);
-extern _X_EXPORT void xf86SetEntityShared(int entityIndex);
-extern _X_EXPORT Bool xf86IsEntitySharable(int entityIndex);
-extern _X_EXPORT void xf86SetEntitySharable(int entityIndex);
-extern _X_EXPORT Bool xf86IsPrimInitDone(int entityIndex);
-extern _X_EXPORT void xf86SetPrimInitDone(int entityIndex);
-extern _X_EXPORT void xf86ClearPrimInitDone(int entityIndex);
-extern _X_EXPORT int xf86AllocateEntityPrivateIndex(void);
-extern _X_EXPORT DevUnion *xf86GetEntityPrivate(int entityIndex, int privIndex);
-
-/* xf86Configure.c */
-extern _X_EXPORT GDevPtr xf86AddBusDeviceToConfigure(const char *driver, BusType bus,
- void *busData, int chipset);
-
-/* xf86Cursor.c */
-
-extern _X_EXPORT void xf86LockZoom(ScreenPtr pScreen, int lock);
-extern _X_EXPORT void xf86InitViewport(ScrnInfoPtr pScr);
-extern _X_EXPORT void xf86SetViewport(ScreenPtr pScreen, int x, int y);
-extern _X_EXPORT void xf86ZoomViewport(ScreenPtr pScreen, int zoom);
-extern _X_EXPORT Bool xf86SwitchMode(ScreenPtr pScreen, DisplayModePtr mode);
-extern _X_EXPORT void *xf86GetPointerScreenFuncs(void);
-extern _X_EXPORT void xf86InitOrigins(void);
-extern _X_EXPORT void xf86ReconfigureLayout(void);
-
-/* xf86cvt.c */
-extern _X_EXPORT DisplayModePtr xf86CVTMode(int HDisplay, int VDisplay, float VRefresh,
- Bool Reduced, Bool Interlaced);
-
-/* xf86DPMS.c */
-
-extern _X_EXPORT Bool xf86DPMSInit(ScreenPtr pScreen, DPMSSetProcPtr set, int flags);
-
-#ifdef DPMSExtension
-extern _X_EXPORT int DPMSSet(ClientPtr client, int level);
-extern _X_EXPORT Bool DPMSSupported(void);
-#endif
-
-
-/* xf86DGA.c */
-
-#ifdef XFreeXDGA
-extern _X_EXPORT Bool DGAInit(ScreenPtr pScreen, DGAFunctionPtr funcs, DGAModePtr modes,
- int num);
-extern _X_EXPORT Bool DGAReInitModes(ScreenPtr pScreen, DGAModePtr modes, int num);
-extern _X_EXPORT xf86SetDGAModeProc xf86SetDGAMode;
-#endif
-
-/* xf86Events.c */
-
-extern _X_EXPORT void SetTimeSinceLastInputEvent(void);
-extern _X_EXPORT pointer xf86AddInputHandler(int fd, InputHandlerProc proc, pointer data);
-extern _X_EXPORT int xf86RemoveInputHandler(pointer handler);
-extern _X_EXPORT void xf86DisableInputHandler(pointer handler);
-extern _X_EXPORT void xf86EnableInputHandler(pointer handler);
-extern _X_EXPORT pointer xf86AddGeneralHandler(int fd, InputHandlerProc proc, pointer data);
-extern _X_EXPORT int xf86RemoveGeneralHandler(pointer handler);
-extern _X_EXPORT void xf86DisableGeneralHandler(pointer handler);
-extern _X_EXPORT void xf86EnableGeneralHandler(pointer handler);
-extern _X_EXPORT void xf86InterceptSignals(int *signo);
-extern _X_EXPORT void xf86InterceptSigIll(void (*sigillhandler)(void));
-extern _X_EXPORT Bool xf86EnableVTSwitch(Bool new);
-extern _X_EXPORT void xf86ProcessActionEvent(ActionEvent action, void *arg);
-extern _X_EXPORT void xf86PrintBacktrace(void);
-
-/* xf86Helper.c */
-
-extern _X_EXPORT void xf86AddDriver(DriverPtr driver, pointer module, int flags);
-extern _X_EXPORT void xf86DeleteDriver(int drvIndex);
-extern _X_EXPORT ScrnInfoPtr xf86AllocateScreen(DriverPtr drv, int flags);
-extern _X_EXPORT void xf86DeleteScreen(int scrnIndex, int flags);
-extern _X_EXPORT int xf86AllocateScrnInfoPrivateIndex(void);
-extern _X_EXPORT Bool xf86AddPixFormat(ScrnInfoPtr pScrn, int depth, int bpp, int pad);
-extern _X_EXPORT Bool xf86SetDepthBpp(ScrnInfoPtr scrp, int depth, int bpp, int fbbpp,
- int depth24flags);
-extern _X_EXPORT void xf86PrintDepthBpp(ScrnInfoPtr scrp);
-extern _X_EXPORT Bool xf86SetWeight(ScrnInfoPtr scrp, rgb weight, rgb mask);
-extern _X_EXPORT Bool xf86SetDefaultVisual(ScrnInfoPtr scrp, int visual);
-extern _X_EXPORT Bool xf86SetGamma(ScrnInfoPtr scrp, Gamma newGamma);
-extern _X_EXPORT void xf86SetDpi(ScrnInfoPtr pScrn, int x, int y);
-extern _X_EXPORT void xf86SetBlackWhitePixels(ScreenPtr pScreen);
-extern _X_EXPORT void xf86EnableDisableFBAccess(int scrnIndex, Bool enable);
-extern _X_EXPORT void xf86VDrvMsgVerb(int scrnIndex, MessageType type, int verb,
- const char *format, va_list args);
-extern _X_EXPORT void xf86DrvMsgVerb(int scrnIndex, MessageType type, int verb,
- const char *format, ...) _printf_attribute(4,5);
-extern _X_EXPORT void xf86DrvMsg(int scrnIndex, MessageType type, const char *format, ...)
- _printf_attribute(3,4);
-extern _X_EXPORT void xf86MsgVerb(MessageType type, int verb, const char *format, ...)
- _printf_attribute(3,4);
-extern _X_EXPORT void xf86Msg(MessageType type, const char *format, ...) _printf_attribute(2,3);
-extern _X_EXPORT void xf86ErrorFVerb(int verb, const char *format, ...) _printf_attribute(2,3);
-extern _X_EXPORT void xf86ErrorF(const char *format, ...) _printf_attribute(1,2);
-extern _X_EXPORT const char *xf86TokenToString(SymTabPtr table, int token);
-extern _X_EXPORT int xf86StringToToken(SymTabPtr table, const char *string);
-extern _X_EXPORT void xf86ShowClocks(ScrnInfoPtr scrp, MessageType from);
-extern _X_EXPORT void xf86PrintChipsets(const char *drvname, const char *drvmsg,
- SymTabPtr chips);
-extern _X_EXPORT int xf86MatchDevice(const char *drivername, GDevPtr **driversectlist);
-extern _X_EXPORT int xf86MatchPciInstances(const char *driverName, int vendorID,
- SymTabPtr chipsets, PciChipsets *PCIchipsets,
- GDevPtr *devList, int numDevs, DriverPtr drvp,
- int **foundEntities);
-extern _X_EXPORT void xf86GetClocks(ScrnInfoPtr pScrn, int num,
- Bool (*ClockFunc)(ScrnInfoPtr, int),
- void (*ProtectRegs)(ScrnInfoPtr, Bool),
- void (*BlankScreen)(ScrnInfoPtr, Bool),
- IOADDRESS vertsyncreg, int maskval,
- int knownclkindex, int knownclkvalue);
-extern _X_EXPORT const char *xf86GetVisualName(int visual);
-extern _X_EXPORT int xf86GetVerbosity(void);
-extern _X_EXPORT Pix24Flags xf86GetPix24(void);
-extern _X_EXPORT int xf86GetDepth(void);
-extern _X_EXPORT rgb xf86GetWeight(void);
-extern _X_EXPORT Gamma xf86GetGamma(void);
-extern _X_EXPORT Bool xf86GetFlipPixels(void);
-extern _X_EXPORT const char *xf86GetServerName(void);
-extern _X_EXPORT Bool xf86ServerIsExiting(void);
-extern _X_EXPORT Bool xf86ServerIsResetting(void);
-extern _X_EXPORT Bool xf86ServerIsInitialising(void);
-extern _X_EXPORT Bool xf86ServerIsOnlyDetecting(void);
-extern _X_EXPORT Bool xf86CaughtSignal(void);
-extern _X_EXPORT Bool xf86GetVidModeAllowNonLocal(void);
-extern _X_EXPORT Bool xf86GetVidModeEnabled(void);
-extern _X_EXPORT Bool xf86GetModInDevAllowNonLocal(void);
-extern _X_EXPORT Bool xf86GetModInDevEnabled(void);
-extern _X_EXPORT Bool xf86GetAllowMouseOpenFail(void);
-extern _X_EXPORT Bool xf86IsPc98(void);
-extern _X_EXPORT void xf86DisableRandR(void);
-extern _X_EXPORT CARD32 xorgGetVersion(void);
-extern _X_EXPORT CARD32 xf86GetModuleVersion(pointer module);
-extern _X_EXPORT pointer xf86LoadDrvSubModule(DriverPtr drv, const char *name);
-extern _X_EXPORT pointer xf86LoadSubModule(ScrnInfoPtr pScrn, const char *name);
-extern _X_EXPORT pointer xf86LoadOneModule(char *name, pointer optlist);
-extern _X_EXPORT void xf86UnloadSubModule(pointer mod);
-extern _X_EXPORT Bool xf86LoaderCheckSymbol(const char *name);
-extern _X_EXPORT void xf86SetBackingStore(ScreenPtr pScreen);
-extern _X_EXPORT void xf86SetSilkenMouse(ScreenPtr pScreen);
-extern _X_EXPORT pointer xf86FindXvOptions(int scrnIndex, int adapt_index, char *port_name,
- char **adaptor_name, pointer *adaptor_options);
-extern _X_EXPORT void xf86GetOS(const char **name, int *major, int *minor, int *teeny);
-extern _X_EXPORT ScrnInfoPtr xf86ConfigPciEntity(ScrnInfoPtr pScrn, int scrnFlag,
- int entityIndex,PciChipsets *p_chip,
- void *dummy, EntityProc init,
- EntityProc enter, EntityProc leave,
- pointer private);
-extern _X_EXPORT ScrnInfoPtr xf86ConfigFbEntity(ScrnInfoPtr pScrn, int scrnFlag,
- int entityIndex, EntityProc init,
- EntityProc enter, EntityProc leave,
- pointer private);
-
-/* Obsolete! don't use */
-extern _X_EXPORT Bool xf86ConfigActivePciEntity(ScrnInfoPtr pScrn,
- int entityIndex,PciChipsets *p_chip,
- void *dummy, EntityProc init,
- EntityProc enter, EntityProc leave,
- pointer private);
-
-extern _X_EXPORT Bool xf86IsScreenPrimary(int scrnIndex);
-extern _X_EXPORT int xf86RegisterRootWindowProperty(int ScrnIndex, Atom property, Atom type,
- int format, unsigned long len,
- pointer value);
-extern _X_EXPORT Bool xf86IsUnblank(int mode);
-
-/* xf86Init.c */
-
-extern _X_EXPORT PixmapFormatPtr xf86GetPixFormat(ScrnInfoPtr pScrn, int depth);
-extern _X_EXPORT int xf86GetBppFromDepth(ScrnInfoPtr pScrn, int depth);
-
-/* xf86Mode.c */
-
-extern _X_EXPORT int xf86GetNearestClock(ScrnInfoPtr scrp, int freq, Bool allowDiv2,
- int DivFactor, int MulFactor, int *divider);
-extern _X_EXPORT const char *xf86ModeStatusToString(ModeStatus status);
-extern _X_EXPORT ModeStatus xf86LookupMode(ScrnInfoPtr scrp, DisplayModePtr modep,
- ClockRangePtr clockRanges, LookupModeFlags strategy);
-extern _X_EXPORT ModeStatus xf86CheckModeForMonitor(DisplayModePtr mode, MonPtr monitor);
-extern _X_EXPORT ModeStatus xf86InitialCheckModeForDriver(ScrnInfoPtr scrp, DisplayModePtr mode,
- ClockRangePtr clockRanges,
- LookupModeFlags strategy,
- int maxPitch, int virtualX,
- int virtualY);
-extern _X_EXPORT ModeStatus xf86CheckModeForDriver(ScrnInfoPtr scrp, DisplayModePtr mode,
- int flags);
-extern _X_EXPORT int xf86ValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes,
- char **modeNames, ClockRangePtr clockRanges,
- int *linePitches, int minPitch, int maxPitch,
- int minHeight, int maxHeight, int pitchInc,
- int virtualX, int virtualY, int apertureSize,
- LookupModeFlags strategy);
-extern _X_EXPORT void xf86DeleteMode(DisplayModePtr *modeList, DisplayModePtr mode);
-extern _X_EXPORT void xf86PruneDriverModes(ScrnInfoPtr scrp);
-extern _X_EXPORT void xf86SetCrtcForModes(ScrnInfoPtr scrp, int adjustFlags);
-extern _X_EXPORT void xf86PrintModes(ScrnInfoPtr scrp);
-extern _X_EXPORT void xf86ShowClockRanges(ScrnInfoPtr scrp, ClockRangePtr clockRanges);
-extern _X_EXPORT double xf86ModeHSync(const DisplayModeRec *mode);
-extern _X_EXPORT double xf86ModeVRefresh(const DisplayModeRec *mode);
-extern _X_EXPORT void xf86SetModeDefaultName(DisplayModePtr mode);
-extern _X_EXPORT void xf86SetModeCrtc(DisplayModePtr p, int adjustFlags);
-extern _X_EXPORT DisplayModePtr xf86DuplicateMode(const DisplayModeRec *pMode);
-extern _X_EXPORT DisplayModePtr xf86DuplicateModes(ScrnInfoPtr pScrn, DisplayModePtr modeList);
-extern _X_EXPORT Bool xf86ModesEqual(const DisplayModeRec *pMode1,
- const DisplayModeRec *pMode2);
-extern _X_EXPORT void xf86PrintModeline(int scrnIndex,DisplayModePtr mode);
-extern _X_EXPORT DisplayModePtr xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new);
-
-/* xf86Option.c */
-
-extern _X_EXPORT void xf86CollectOptions(ScrnInfoPtr pScrn, pointer extraOpts);
-
-
-/* xf86RandR.c */
-#ifdef RANDR
-extern _X_EXPORT Bool xf86RandRInit (ScreenPtr pScreen);
-extern _X_EXPORT Rotation xf86GetRotation(ScreenPtr pScreen);
-extern _X_EXPORT Bool xf86RandRSetNewVirtualAndDimensions(ScreenPtr pScreen,
- int newvirtX, int newvirtY,
- int newmmWidth, int newmmHeight, Bool resetMode);
-#endif
-
-/* xf86VidModeExtentionInit.c */
-
-extern _X_EXPORT Bool VidModeExtensionInit(ScreenPtr pScreen);
-
-#endif /* _NO_XF86_PROTOTYPES */
-
-#endif /* _XF86_H */
+/*
+ * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ * This file contains declarations for public XFree86 functions and variables,
+ * and definitions of public macros.
+ *
+ * "public" means available to video drivers.
+ */
+
+#ifndef _XF86_H
+#define _XF86_H
+
+#if HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#elif HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <pciaccess.h>
+
+#include "xf86str.h"
+#include "xf86Opt.h"
+#include <X11/Xfuncproto.h>
+#include <stdarg.h>
+#ifdef RANDR
+#include <X11/extensions/randr.h>
+#endif
+
+#include "propertyst.h"
+
+/* General parameters */
+extern _X_EXPORT int xf86DoConfigure;
+extern _X_EXPORT int xf86DoShowOptions;
+extern _X_EXPORT Bool xf86DoConfigurePass1;
+extern _X_EXPORT DevPrivateKey xf86ScreenKey;
+extern _X_EXPORT DevPrivateKey xf86CreateRootWindowKey;
+extern _X_EXPORT DevPrivateKey xf86PixmapKey;
+extern _X_EXPORT ScrnInfoPtr *xf86Screens; /* List of pointers to ScrnInfoRecs */
+extern _X_EXPORT const unsigned char byte_reversed[256];
+extern _X_EXPORT Bool pciSlotClaimed;
+extern _X_EXPORT Bool fbSlotClaimed;
+#if defined(__sparc__) || defined(__sparc)
+extern _X_EXPORT Bool sbusSlotClaimed;
+#endif
+extern _X_EXPORT confDRIRec xf86ConfigDRI;
+extern _X_EXPORT Bool xf86inSuspend;
+extern _X_EXPORT Bool xf86DRI2Enabled(void);
+
+extern _X_EXPORT Bool VTSwitchEnabled; /* kbd driver */
+
+#define XF86SCRNINFO(p) ((ScrnInfoPtr)dixLookupPrivate(&(p)->devPrivates, \
+ xf86ScreenKey))
+#define XF86FLIP_PIXELS() \
+ do { \
+ if (xf86GetFlipPixels()) { \
+ pScreen->whitePixel = (pScreen->whitePixel) ? 0 : 1; \
+ pScreen->blackPixel = (pScreen->blackPixel) ? 0 : 1; \
+ } \
+ while (0)
+
+#define BOOLTOSTRING(b) ((b) ? "TRUE" : "FALSE")
+
+#define PIX24TOBPP(p) (((p) == Pix24Use24) ? 24 : \
+ (((p) == Pix24Use32) ? 32 : 0))
+
+/* Function Prototypes */
+#ifndef _NO_XF86_PROTOTYPES
+
+/* xf86Bus.c */
+
+extern _X_EXPORT Bool xf86CheckPciSlot( const struct pci_device * );
+extern _X_EXPORT int xf86ClaimPciSlot( struct pci_device *, DriverPtr drvp,
+ int chipset, GDevPtr dev, Bool active);
+extern _X_EXPORT void xf86UnclaimPciSlot(struct pci_device *);
+extern _X_EXPORT Bool xf86ParsePciBusString(const char *busID, int *bus, int *device,
+ int *func);
+extern _X_EXPORT Bool xf86ComparePciBusString(const char *busID, int bus, int device, int func);
+extern _X_EXPORT void xf86FormatPciBusNumber(int busnum, char *buffer);
+extern _X_EXPORT int xf86GetFbInfoForScreen(int scrnIndex);
+extern _X_EXPORT int xf86ClaimFbSlot(DriverPtr drvp, int chipset, GDevPtr dev, Bool active);
+extern _X_EXPORT int xf86ClaimNoSlot(DriverPtr drvp, int chipset, GDevPtr dev, Bool active);
+extern _X_EXPORT void xf86EnableAccess(ScrnInfoPtr pScrn);
+extern _X_EXPORT Bool xf86IsPrimaryPci(struct pci_device * pPci);
+/* new RAC */
+extern _X_EXPORT Bool xf86DriverHasEntities(DriverPtr drvp);
+extern _X_EXPORT void xf86AddEntityToScreen(ScrnInfoPtr pScrn, int entityIndex);
+extern _X_EXPORT void xf86SetEntityInstanceForScreen(ScrnInfoPtr pScrn, int entityIndex,
+ int instance);
+extern _X_EXPORT int xf86GetNumEntityInstances(int entityIndex);
+extern _X_EXPORT GDevPtr xf86GetDevFromEntity(int entityIndex, int instance);
+extern _X_EXPORT void xf86RemoveEntityFromScreen(ScrnInfoPtr pScrn, int entityIndex);
+extern _X_EXPORT EntityInfoPtr xf86GetEntityInfo(int entityIndex);
+extern _X_EXPORT struct pci_device * xf86GetPciInfoForEntity(int entityIndex);
+extern _X_EXPORT Bool xf86SetEntityFuncs(int entityIndex, EntityProc init,
+ EntityProc enter, EntityProc leave, pointer);
+extern _X_EXPORT Bool xf86CheckPciMemBase(struct pci_device * pPci, memType base);
+extern _X_EXPORT Bool xf86IsEntityPrimary(int entityIndex);
+extern _X_EXPORT void xf86EnterServerState(xf86State state);
+extern _X_EXPORT ScrnInfoPtr xf86FindScreenForEntity(int entityIndex);
+
+extern _X_EXPORT int xf86GetLastScrnFlag(int entityIndex);
+extern _X_EXPORT void xf86SetLastScrnFlag(int entityIndex, int scrnIndex);
+extern _X_EXPORT Bool xf86IsEntityShared(int entityIndex);
+extern _X_EXPORT void xf86SetEntityShared(int entityIndex);
+extern _X_EXPORT Bool xf86IsEntitySharable(int entityIndex);
+extern _X_EXPORT void xf86SetEntitySharable(int entityIndex);
+extern _X_EXPORT Bool xf86IsPrimInitDone(int entityIndex);
+extern _X_EXPORT void xf86SetPrimInitDone(int entityIndex);
+extern _X_EXPORT void xf86ClearPrimInitDone(int entityIndex);
+extern _X_EXPORT int xf86AllocateEntityPrivateIndex(void);
+extern _X_EXPORT DevUnion *xf86GetEntityPrivate(int entityIndex, int privIndex);
+
+/* xf86Configure.c */
+extern _X_EXPORT GDevPtr xf86AddBusDeviceToConfigure(const char *driver, BusType bus,
+ void *busData, int chipset);
+
+/* xf86Cursor.c */
+
+extern _X_EXPORT void xf86LockZoom(ScreenPtr pScreen, int lock);
+extern _X_EXPORT void xf86InitViewport(ScrnInfoPtr pScr);
+extern _X_EXPORT void xf86SetViewport(ScreenPtr pScreen, int x, int y);
+extern _X_EXPORT void xf86ZoomViewport(ScreenPtr pScreen, int zoom);
+extern _X_EXPORT Bool xf86SwitchMode(ScreenPtr pScreen, DisplayModePtr mode);
+extern _X_EXPORT void *xf86GetPointerScreenFuncs(void);
+extern _X_EXPORT void xf86InitOrigins(void);
+extern _X_EXPORT void xf86ReconfigureLayout(void);
+
+/* xf86cvt.c */
+extern _X_EXPORT DisplayModePtr xf86CVTMode(int HDisplay, int VDisplay, float VRefresh,
+ Bool Reduced, Bool Interlaced);
+
+/* xf86DPMS.c */
+
+extern _X_EXPORT Bool xf86DPMSInit(ScreenPtr pScreen, DPMSSetProcPtr set, int flags);
+
+#ifdef DPMSExtension
+extern _X_EXPORT int DPMSSet(ClientPtr client, int level);
+extern _X_EXPORT Bool DPMSSupported(void);
+#endif
+
+
+/* xf86DGA.c */
+
+#ifdef XFreeXDGA
+extern _X_EXPORT Bool DGAInit(ScreenPtr pScreen, DGAFunctionPtr funcs, DGAModePtr modes,
+ int num);
+extern _X_EXPORT Bool DGAReInitModes(ScreenPtr pScreen, DGAModePtr modes, int num);
+extern _X_EXPORT xf86SetDGAModeProc xf86SetDGAMode;
+#endif
+
+/* xf86Events.c */
+
+extern _X_EXPORT void SetTimeSinceLastInputEvent(void);
+extern _X_EXPORT pointer xf86AddInputHandler(int fd, InputHandlerProc proc, pointer data);
+extern _X_EXPORT int xf86RemoveInputHandler(pointer handler);
+extern _X_EXPORT void xf86DisableInputHandler(pointer handler);
+extern _X_EXPORT void xf86EnableInputHandler(pointer handler);
+extern _X_EXPORT pointer xf86AddGeneralHandler(int fd, InputHandlerProc proc, pointer data);
+extern _X_EXPORT int xf86RemoveGeneralHandler(pointer handler);
+extern _X_EXPORT void xf86DisableGeneralHandler(pointer handler);
+extern _X_EXPORT void xf86EnableGeneralHandler(pointer handler);
+extern _X_EXPORT void xf86InterceptSignals(int *signo);
+extern _X_EXPORT void xf86InterceptSigIll(void (*sigillhandler)(void));
+extern _X_EXPORT Bool xf86EnableVTSwitch(Bool new);
+extern _X_EXPORT void xf86ProcessActionEvent(ActionEvent action, void *arg);
+extern _X_EXPORT void xf86PrintBacktrace(void);
+
+/* xf86Helper.c */
+
+extern _X_EXPORT void xf86AddDriver(DriverPtr driver, pointer module, int flags);
+extern _X_EXPORT void xf86DeleteDriver(int drvIndex);
+extern _X_EXPORT ScrnInfoPtr xf86AllocateScreen(DriverPtr drv, int flags);
+extern _X_EXPORT void xf86DeleteScreen(int scrnIndex, int flags);
+extern _X_EXPORT int xf86AllocateScrnInfoPrivateIndex(void);
+extern _X_EXPORT Bool xf86AddPixFormat(ScrnInfoPtr pScrn, int depth, int bpp, int pad);
+extern _X_EXPORT Bool xf86SetDepthBpp(ScrnInfoPtr scrp, int depth, int bpp, int fbbpp,
+ int depth24flags);
+extern _X_EXPORT void xf86PrintDepthBpp(ScrnInfoPtr scrp);
+extern _X_EXPORT Bool xf86SetWeight(ScrnInfoPtr scrp, rgb weight, rgb mask);
+extern _X_EXPORT Bool xf86SetDefaultVisual(ScrnInfoPtr scrp, int visual);
+extern _X_EXPORT Bool xf86SetGamma(ScrnInfoPtr scrp, Gamma newGamma);
+extern _X_EXPORT void xf86SetDpi(ScrnInfoPtr pScrn, int x, int y);
+extern _X_EXPORT void xf86SetBlackWhitePixels(ScreenPtr pScreen);
+extern _X_EXPORT void xf86EnableDisableFBAccess(int scrnIndex, Bool enable);
+extern _X_EXPORT void xf86VDrvMsgVerb(int scrnIndex, MessageType type, int verb,
+ const char *format, va_list args);
+extern _X_EXPORT void xf86DrvMsgVerb(int scrnIndex, MessageType type, int verb,
+ const char *format, ...) _X_ATTRIBUTE_PRINTF(4,5);
+extern _X_EXPORT void xf86DrvMsg(int scrnIndex, MessageType type, const char *format, ...)
+ _X_ATTRIBUTE_PRINTF(3,4);
+extern _X_EXPORT void xf86MsgVerb(MessageType type, int verb, const char *format, ...)
+ _X_ATTRIBUTE_PRINTF(3,4);
+extern _X_EXPORT void xf86Msg(MessageType type, const char *format, ...) _X_ATTRIBUTE_PRINTF(2,3);
+extern _X_EXPORT void xf86ErrorFVerb(int verb, const char *format, ...) _X_ATTRIBUTE_PRINTF(2,3);
+extern _X_EXPORT void xf86ErrorF(const char *format, ...) _X_ATTRIBUTE_PRINTF(1,2);
+extern _X_EXPORT const char *xf86TokenToString(SymTabPtr table, int token);
+extern _X_EXPORT int xf86StringToToken(SymTabPtr table, const char *string);
+extern _X_EXPORT void xf86ShowClocks(ScrnInfoPtr scrp, MessageType from);
+extern _X_EXPORT void xf86PrintChipsets(const char *drvname, const char *drvmsg,
+ SymTabPtr chips);
+extern _X_EXPORT int xf86MatchDevice(const char *drivername, GDevPtr **driversectlist);
+extern _X_EXPORT int xf86MatchPciInstances(const char *driverName, int vendorID,
+ SymTabPtr chipsets, PciChipsets *PCIchipsets,
+ GDevPtr *devList, int numDevs, DriverPtr drvp,
+ int **foundEntities);
+extern _X_EXPORT void xf86GetClocks(ScrnInfoPtr pScrn, int num,
+ Bool (*ClockFunc)(ScrnInfoPtr, int),
+ void (*ProtectRegs)(ScrnInfoPtr, Bool),
+ void (*BlankScreen)(ScrnInfoPtr, Bool),
+ IOADDRESS vertsyncreg, int maskval,
+ int knownclkindex, int knownclkvalue);
+extern _X_EXPORT const char *xf86GetVisualName(int visual);
+extern _X_EXPORT int xf86GetVerbosity(void);
+extern _X_EXPORT Pix24Flags xf86GetPix24(void);
+extern _X_EXPORT int xf86GetDepth(void);
+extern _X_EXPORT rgb xf86GetWeight(void);
+extern _X_EXPORT Gamma xf86GetGamma(void);
+extern _X_EXPORT Bool xf86GetFlipPixels(void);
+extern _X_EXPORT const char *xf86GetServerName(void);
+extern _X_EXPORT Bool xf86ServerIsExiting(void);
+extern _X_EXPORT Bool xf86ServerIsResetting(void);
+extern _X_EXPORT Bool xf86ServerIsInitialising(void);
+extern _X_EXPORT Bool xf86ServerIsOnlyDetecting(void);
+extern _X_EXPORT Bool xf86CaughtSignal(void);
+extern _X_EXPORT Bool xf86GetVidModeAllowNonLocal(void);
+extern _X_EXPORT Bool xf86GetVidModeEnabled(void);
+extern _X_EXPORT Bool xf86GetModInDevAllowNonLocal(void);
+extern _X_EXPORT Bool xf86GetModInDevEnabled(void);
+extern _X_EXPORT Bool xf86GetAllowMouseOpenFail(void);
+extern _X_EXPORT Bool xf86IsPc98(void);
+extern _X_EXPORT void xf86DisableRandR(void);
+extern _X_EXPORT CARD32 xorgGetVersion(void);
+extern _X_EXPORT CARD32 xf86GetModuleVersion(pointer module);
+extern _X_EXPORT pointer xf86LoadDrvSubModule(DriverPtr drv, const char *name);
+extern _X_EXPORT pointer xf86LoadSubModule(ScrnInfoPtr pScrn, const char *name);
+extern _X_EXPORT pointer xf86LoadOneModule(char *name, pointer optlist);
+extern _X_EXPORT void xf86UnloadSubModule(pointer mod);
+extern _X_EXPORT Bool xf86LoaderCheckSymbol(const char *name);
+extern _X_EXPORT void xf86SetBackingStore(ScreenPtr pScreen);
+extern _X_EXPORT void xf86SetSilkenMouse(ScreenPtr pScreen);
+extern _X_EXPORT pointer xf86FindXvOptions(int scrnIndex, int adapt_index, char *port_name,
+ char **adaptor_name, pointer *adaptor_options);
+extern _X_EXPORT void xf86GetOS(const char **name, int *major, int *minor, int *teeny);
+extern _X_EXPORT ScrnInfoPtr xf86ConfigPciEntity(ScrnInfoPtr pScrn, int scrnFlag,
+ int entityIndex,PciChipsets *p_chip,
+ void *dummy, EntityProc init,
+ EntityProc enter, EntityProc leave,
+ pointer private);
+extern _X_EXPORT ScrnInfoPtr xf86ConfigFbEntity(ScrnInfoPtr pScrn, int scrnFlag,
+ int entityIndex, EntityProc init,
+ EntityProc enter, EntityProc leave,
+ pointer private);
+
+/* Obsolete! don't use */
+extern _X_EXPORT Bool xf86ConfigActivePciEntity(ScrnInfoPtr pScrn,
+ int entityIndex,PciChipsets *p_chip,
+ void *dummy, EntityProc init,
+ EntityProc enter, EntityProc leave,
+ pointer private);
+
+extern _X_EXPORT Bool xf86IsScreenPrimary(int scrnIndex);
+extern _X_EXPORT int xf86RegisterRootWindowProperty(int ScrnIndex, Atom property, Atom type,
+ int format, unsigned long len,
+ pointer value);
+extern _X_EXPORT Bool xf86IsUnblank(int mode);
+
+/* xf86Init.c */
+
+extern _X_EXPORT PixmapFormatPtr xf86GetPixFormat(ScrnInfoPtr pScrn, int depth);
+extern _X_EXPORT int xf86GetBppFromDepth(ScrnInfoPtr pScrn, int depth);
+
+/* xf86Mode.c */
+
+extern _X_EXPORT int xf86GetNearestClock(ScrnInfoPtr scrp, int freq, Bool allowDiv2,
+ int DivFactor, int MulFactor, int *divider);
+extern _X_EXPORT const char *xf86ModeStatusToString(ModeStatus status);
+extern _X_EXPORT ModeStatus xf86LookupMode(ScrnInfoPtr scrp, DisplayModePtr modep,
+ ClockRangePtr clockRanges, LookupModeFlags strategy);
+extern _X_EXPORT ModeStatus xf86CheckModeForMonitor(DisplayModePtr mode, MonPtr monitor);
+extern _X_EXPORT ModeStatus xf86InitialCheckModeForDriver(ScrnInfoPtr scrp, DisplayModePtr mode,
+ ClockRangePtr clockRanges,
+ LookupModeFlags strategy,
+ int maxPitch, int virtualX,
+ int virtualY);
+extern _X_EXPORT ModeStatus xf86CheckModeForDriver(ScrnInfoPtr scrp, DisplayModePtr mode,
+ int flags);
+extern _X_EXPORT int xf86ValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes,
+ char **modeNames, ClockRangePtr clockRanges,
+ int *linePitches, int minPitch, int maxPitch,
+ int minHeight, int maxHeight, int pitchInc,
+ int virtualX, int virtualY, int apertureSize,
+ LookupModeFlags strategy);
+extern _X_EXPORT void xf86DeleteMode(DisplayModePtr *modeList, DisplayModePtr mode);
+extern _X_EXPORT void xf86PruneDriverModes(ScrnInfoPtr scrp);
+extern _X_EXPORT void xf86SetCrtcForModes(ScrnInfoPtr scrp, int adjustFlags);
+extern _X_EXPORT void xf86PrintModes(ScrnInfoPtr scrp);
+extern _X_EXPORT void xf86ShowClockRanges(ScrnInfoPtr scrp, ClockRangePtr clockRanges);
+extern _X_EXPORT double xf86ModeHSync(const DisplayModeRec *mode);
+extern _X_EXPORT double xf86ModeVRefresh(const DisplayModeRec *mode);
+extern _X_EXPORT void xf86SetModeDefaultName(DisplayModePtr mode);
+extern _X_EXPORT void xf86SetModeCrtc(DisplayModePtr p, int adjustFlags);
+extern _X_EXPORT DisplayModePtr xf86DuplicateMode(const DisplayModeRec *pMode);
+extern _X_EXPORT DisplayModePtr xf86DuplicateModes(ScrnInfoPtr pScrn, DisplayModePtr modeList);
+extern _X_EXPORT Bool xf86ModesEqual(const DisplayModeRec *pMode1,
+ const DisplayModeRec *pMode2);
+extern _X_EXPORT void xf86PrintModeline(int scrnIndex,DisplayModePtr mode);
+extern _X_EXPORT DisplayModePtr xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new);
+
+/* xf86Option.c */
+
+extern _X_EXPORT void xf86CollectOptions(ScrnInfoPtr pScrn, pointer extraOpts);
+
+
+/* xf86RandR.c */
+#ifdef RANDR
+extern _X_EXPORT Bool xf86RandRInit (ScreenPtr pScreen);
+extern _X_EXPORT Rotation xf86GetRotation(ScreenPtr pScreen);
+extern _X_EXPORT Bool xf86RandRSetNewVirtualAndDimensions(ScreenPtr pScreen,
+ int newvirtX, int newvirtY,
+ int newmmWidth, int newmmHeight, Bool resetMode);
+#endif
+
+/* xf86VidModeExtentionInit.c */
+
+extern _X_EXPORT Bool VidModeExtensionInit(ScreenPtr pScreen);
+
+#endif /* _NO_XF86_PROTOTYPES */
+
+#endif /* _XF86_H */
diff --git a/xorg-server/hw/xfree86/common/xf86AutoConfig.c b/xorg-server/hw/xfree86/common/xf86AutoConfig.c
index 7b836b00d..88891e5a7 100644
--- a/xorg-server/hw/xfree86/common/xf86AutoConfig.c
+++ b/xorg-server/hw/xfree86/common/xf86AutoConfig.c
@@ -1,638 +1,638 @@
-/*
- * Copyright 2003 by David H. Dawes.
- * Copyright 2003 by X-Oz Technologies.
- * All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- *
- * Author: David Dawes <dawes@XFree86.Org>.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "xf86.h"
-#include "xf86Parser.h"
-#include "xf86tokens.h"
-#include "xf86Config.h"
-#include "xf86Priv.h"
-#include "xf86_OSlib.h"
-#ifdef __sparc__
-# include "xf86sbusBus.h"
-#endif
-#include "dirent.h"
-
-#ifdef sun
-# include <sys/visual_io.h>
-# include <ctype.h>
-#endif
-
-/* Sections for the default built-in configuration. */
-
-#define BUILTIN_DEVICE_NAME \
- "\"Builtin Default %s Device %d\""
-
-#define BUILTIN_DEVICE_SECTION_PRE \
- "Section \"Device\"\n" \
- "\tIdentifier\t" BUILTIN_DEVICE_NAME "\n" \
- "\tDriver\t\"%s\"\n"
-
-#define BUILTIN_DEVICE_SECTION_POST \
- "EndSection\n\n"
-
-#define BUILTIN_DEVICE_SECTION \
- BUILTIN_DEVICE_SECTION_PRE \
- BUILTIN_DEVICE_SECTION_POST
-
-#define BUILTIN_SCREEN_NAME \
- "\"Builtin Default %s Screen %d\""
-
-#define BUILTIN_SCREEN_SECTION \
- "Section \"Screen\"\n" \
- "\tIdentifier\t" BUILTIN_SCREEN_NAME "\n" \
- "\tDevice\t" BUILTIN_DEVICE_NAME "\n" \
- "EndSection\n\n"
-
-#define BUILTIN_LAYOUT_SECTION_PRE \
- "Section \"ServerLayout\"\n" \
- "\tIdentifier\t\"Builtin Default Layout\"\n"
-
-#define BUILTIN_LAYOUT_SCREEN_LINE \
- "\tScreen\t" BUILTIN_SCREEN_NAME "\n"
-
-#define BUILTIN_LAYOUT_SECTION_POST \
- "EndSection\n\n"
-
-static const char **builtinConfig = NULL;
-static int builtinLines = 0;
-
-static void listPossibleVideoDrivers(char *matches[], int nmatches);
-
-/*
- * A built-in config file is stored as an array of strings, with each string
- * representing a single line. AppendToConfig() breaks up the string "s"
- * into lines, and appends those lines it to builtinConfig.
- */
-
-static void
-AppendToList(const char *s, const char ***list, int *lines)
-{
- char *str, *newstr, *p;
-
- str = xnfstrdup(s);
- for (p = strtok(str, "\n"); p; p = strtok(NULL, "\n")) {
- (*lines)++;
- *list = xnfrealloc(*list, (*lines + 1) * sizeof(**list));
- newstr = xnfalloc(strlen(p) + 2);
- strcpy(newstr, p);
- strcat(newstr, "\n");
- (*list)[*lines - 1] = newstr;
- (*list)[*lines] = NULL;
- }
- xfree(str);
-}
-
-static void
-FreeList(const char ***list, int *lines)
-{
- int i;
-
- for (i = 0; i < *lines; i++) {
- if ((*list)[i])
- xfree((*list)[i]);
- }
- xfree(*list);
- *list = NULL;
- *lines = 0;
-}
-
-static void
-FreeConfig(void)
-{
- FreeList(&builtinConfig, &builtinLines);
-}
-
-static void
-AppendToConfig(const char *s)
-{
- AppendToList(s, &builtinConfig, &builtinLines);
-}
-
-static int
-videoPtrToDriverList(struct pci_device *dev,
- char *returnList[], int returnListMax)
-{
- int i;
- /* Add more entries here if we ever return more than 4 drivers for
- any device */
- char *driverList[5] = { NULL, NULL, NULL, NULL, NULL };
-
- switch (dev->vendor_id)
- {
- /* AMD Geode LX */
- case 0x1022:
- if (dev->device_id == 0x2081)
- driverList[0] = "geode";
- break;
- /* older Geode products acquired by AMD still carry an NSC vendor_id */
- case 0x100b:
- if (dev->device_id == 0x0030) {
- /* NSC Geode GX2 specifically */
- driverList[0] = "geode";
- /* GX2 support started its life in the NSC tree and was later
- forked by AMD for GEODE so we keep it as a backup */
- driverList[1] = "nsc";
- } else
- /* other NSC variant e.g. 0x0104 (SC1400), 0x0504 (SCx200) */
- driverList[0] = "nsc";
- break;
- /* Cyrix Geode GX1 */
- case 0x1078:
- if (dev->device_id == 0x0104)
- driverList[0] = "cyrix";
- break;
- case 0x1142: driverList[0] = "apm"; break;
- case 0xedd8: driverList[0] = "ark"; break;
- case 0x1a03: driverList[0] = "ast"; break;
- case 0x1002: driverList[0] = "ati"; break;
- case 0x102c: driverList[0] = "chips"; break;
- case 0x1013: driverList[0] = "cirrus"; break;
- case 0x3d3d: driverList[0] = "glint"; break;
- case 0x105d: driverList[0] = "i128"; break;
- case 0x8086:
- if ((dev->device_id == 0x00d1) || (dev->device_id == 0x7800)) {
- driverList[0] = "i740";
- } else if (dev->device_id == 0x8108) {
- break; /* "hooray" for poulsbo */
- } else {
- driverList[0] = "intel";
- }
- break;
- case 0x102b: driverList[0] = "mga"; break;
- case 0x10c8: driverList[0] = "neomagic"; break;
- case 0x10de: case 0x12d2: driverList[0] = "nv"; break;
- case 0x1106: driverList[0] = "openchrome"; break;
- case 0x1b36: driverList[0] = "qxl"; break;
- case 0x1163: driverList[0] = "rendition"; break;
- case 0x5333:
- switch (dev->device_id)
- {
- case 0x88d0: case 0x88d1: case 0x88f0: case 0x8811:
- case 0x8812: case 0x8814: case 0x8901:
- driverList[0] = "s3"; break;
- case 0x5631: case 0x883d: case 0x8a01: case 0x8a10:
- case 0x8c01: case 0x8c03: case 0x8904: case 0x8a13:
- driverList[0] = "s3virge"; break;
- default:
- driverList[0] = "savage"; break;
- }
- break;
- case 0x1039: driverList[0] = "sis"; break;
- case 0x126f: driverList[0] = "siliconmotion"; break;
- case 0x121a:
- if (dev->device_id < 0x0003)
- driverList[0] = "voodoo";
- else
- driverList[0] = "tdfx";
- break;
- case 0x1011: driverList[0] = "tga"; break;
- case 0x1023: driverList[0] = "trident"; break;
- case 0x100c: driverList[0] = "tseng"; break;
- case 0x80ee: driverList[0] = "vboxvideo"; break;
- case 0x15ad: driverList[0] = "vmware"; break;
- case 0x18ca:
- if (dev->device_id == 0x47)
- driverList[0] = "xgixp";
- else
- driverList[0] = "xgi";
- break;
- default: break;
- }
- for (i = 0; (i < returnListMax) && (driverList[i] != NULL); i++) {
- returnList[i] = xnfstrdup(driverList[i]);
- }
- return i; /* Number of entries added */
-}
-
-Bool
-xf86AutoConfig(void)
-{
- char *deviceList[20];
- char **p;
- const char **cp;
- char buf[1024];
- ConfigStatus ret;
-
- listPossibleVideoDrivers(deviceList, 20);
-
- for (p = deviceList; *p; p++) {
- snprintf(buf, sizeof(buf), BUILTIN_DEVICE_SECTION, *p, 0, *p);
- AppendToConfig(buf);
- snprintf(buf, sizeof(buf), BUILTIN_SCREEN_SECTION, *p, 0, *p, 0);
- AppendToConfig(buf);
- }
-
- AppendToConfig(BUILTIN_LAYOUT_SECTION_PRE);
- for (p = deviceList; *p; p++) {
- snprintf(buf, sizeof(buf), BUILTIN_LAYOUT_SCREEN_LINE, *p, 0);
- AppendToConfig(buf);
- }
- AppendToConfig(BUILTIN_LAYOUT_SECTION_POST);
-
- for (p = deviceList; *p; p++) {
- xfree(*p);
- }
-
- xf86MsgVerb(X_DEFAULT, 0,
- "Using default built-in configuration (%d lines)\n",
- builtinLines);
-
- xf86MsgVerb(X_DEFAULT, 3, "--- Start of built-in configuration ---\n");
- for (cp = builtinConfig; *cp; cp++)
- xf86ErrorFVerb(3, "\t%s", *cp);
- xf86MsgVerb(X_DEFAULT, 3, "--- End of built-in configuration ---\n");
-
- xf86initConfigFiles();
- xf86setBuiltinConfig(builtinConfig);
- ret = xf86HandleConfigFile(TRUE);
- FreeConfig();
-
- if (ret != CONFIG_OK)
- xf86Msg(X_ERROR, "Error parsing the built-in default configuration.\n");
-
- return (ret == CONFIG_OK);
-}
-
-static int
-xchomp(char *line)
-{
- size_t len = 0;
-
- if (!line) {
- return 1;
- }
-
- len = strlen(line);
- if (line[len - 1] == '\n' && len > 0) {
- line[len - 1] = '\0';
- }
- return 0;
-}
-
-#ifdef __linux__
-/* This function is used to provide a workaround for binary drivers that
- * don't export their PCI ID's properly. If distros don't end up using this
- * feature it can and should be removed because the symbol-based resolution
- * scheme should be the primary one */
-static void
-matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip)
-{
- DIR *idsdir;
- FILE *fp;
- struct dirent *direntry;
- char *line = NULL;
- size_t len;
- ssize_t read;
- char path_name[256], vendor_str[5], chip_str[5];
- uint16_t vendor, chip;
- int i, j;
-
- idsdir = opendir(PCI_TXT_IDS_PATH);
- if (!idsdir)
- return;
-
- xf86Msg(X_INFO, "Scanning %s directory for additional PCI ID's supported by the drivers\n", PCI_TXT_IDS_PATH);
- direntry = readdir(idsdir);
- /* Read the directory */
- while (direntry) {
- if (direntry->d_name[0] == '.') {
- direntry = readdir(idsdir);
- continue;
- }
- len = strlen(direntry->d_name);
- /* A tiny bit of sanity checking. We should probably do better */
- if (strncmp(&(direntry->d_name[len-4]), ".ids", 4) == 0) {
- /* We need the full path name to open the file */
- strncpy(path_name, PCI_TXT_IDS_PATH, 256);
- strncat(path_name, "/", 1);
- strncat(path_name, direntry->d_name, (256 - strlen(path_name) - 1));
- fp = fopen(path_name, "r");
- if (fp == NULL) {
- xf86Msg(X_ERROR, "Could not open %s for reading. Exiting.\n", path_name);
- goto end;
- }
- /* Read the file */
-#ifdef __GLIBC__
- while ((read = getline(&line, &len, fp)) != -1) {
-#else
- while ((line = fgetln(fp, &len)) != (char *)NULL) {
-#endif /* __GLIBC __ */
- xchomp(line);
- if (isdigit(line[0])) {
- strncpy(vendor_str, line, 4);
- vendor_str[4] = '\0';
- vendor = (int)strtol(vendor_str, NULL, 16);
- if ((strlen(&line[4])) == 0) {
- chip_str[0] = '\0';
- chip = -1;
- } else {
- /* Handle trailing whitespace */
- if (isspace(line[4])) {
- chip_str[0] = '\0';
- chip = -1;
- } else {
- /* Ok, it's a real ID */
- strncpy(chip_str, &line[4], 4);
- chip_str[4] = '\0';
- chip = (int)strtol(chip_str, NULL, 16);
- }
- }
- if (vendor == match_vendor && chip == match_chip ) {
- i = 0;
- while (matches[i]) {
- i++;
- }
- matches[i] = (char*)xalloc(sizeof(char) * strlen(direntry->d_name) - 3);
- if (!matches[i]) {
- xf86Msg(X_ERROR, "Could not allocate space for the module name. Exiting.\n");
- goto end;
- }
- /* hack off the .ids suffix. This should guard
- * against other problems, but it will end up
- * taking off anything after the first '.' */
- for (j = 0; j < (strlen(direntry->d_name) - 3) ; j++) {
- if (direntry->d_name[j] == '.') {
- matches[i][j] = '\0';
- break;
- } else {
- matches[i][j] = direntry->d_name[j];
- }
- }
- xf86Msg(X_INFO, "Matched %s from file name %s\n", matches[i], direntry->d_name);
- }
- } else {
- /* TODO Handle driver overrides here */
- }
- }
- fclose(fp);
- }
- direntry = readdir(idsdir);
- }
- end:
- xfree(line);
- closedir(idsdir);
-}
-#endif /* __linux__ */
-
-static void
-listPossibleVideoDrivers(char *matches[], int nmatches)
-{
- struct pci_device * info = NULL;
- struct pci_device_iterator *iter;
- int i;
-
- for (i = 0 ; i < nmatches ; i++) {
- matches[i] = NULL;
- }
- i = 0;
-
-#ifdef sun
- /* Check for driver type based on /dev/fb type and if valid, use
- it instead of PCI bus probe results */
- if (xf86Info.consoleFd >= 0) {
- struct vis_identifier visid;
- const char *cp;
- extern char xf86SolarisFbDev[PATH_MAX];
- int iret;
-
- SYSCALL(iret = ioctl(xf86Info.consoleFd, VIS_GETIDENTIFIER, &visid));
- if (iret < 0) {
- int fbfd;
-
- fbfd = open(xf86SolarisFbDev, O_RDONLY);
- if (fbfd >= 0) {
- SYSCALL(iret = ioctl(fbfd, VIS_GETIDENTIFIER, &visid));
- close(fbfd);
- }
- }
-
- if (iret < 0) {
- xf86Msg(X_WARNING,
- "could not get frame buffer identifier from %s\n",
- xf86SolarisFbDev);
- } else {
- xf86Msg(X_PROBED, "console driver: %s\n", visid.name);
-
- /* Special case from before the general case was set */
- if (strcmp(visid.name, "NVDAnvda") == 0) {
- matches[i++] = xnfstrdup("nvidia");
- }
-
- /* General case - split into vendor name (initial all-caps
- prefix) & driver name (rest of the string). */
- if (strcmp(visid.name, "SUNWtext") != 0) {
- for (cp = visid.name; (*cp != '\0') && isupper(*cp); cp++) {
- /* find end of all uppercase vendor section */
- }
- if ((cp != visid.name) && (*cp != '\0')) {
- char *driverName = xnfstrdup(cp);
- char *vendorName = xnfstrdup(visid.name);
- vendorName[cp - visid.name] = '\0';
-
- matches[i++] = vendorName;
- matches[i++] = driverName;
- }
- }
- }
- }
-#endif
-#ifdef __sparc__
- {
- char *sbusDriver = sparcDriverName();
- if (sbusDriver)
- matches[i++] = xnfstrdup(sbusDriver);
- }
-#endif
-
- /* Find the primary device, and get some information about it. */
- iter = pci_slot_match_iterator_create(NULL);
- while ((info = pci_device_next(iter)) != NULL) {
- if (xf86IsPrimaryPci(info)) {
- break;
- }
- }
-
- pci_iterator_destroy(iter);
-
- if (!info) {
- ErrorF("Primary device is not PCI\n");
- }
-#ifdef __linux__
- else {
- matchDriverFromFiles(matches, info->vendor_id, info->device_id);
- }
-#endif /* __linux__ */
-
- for (i = 0; (i < nmatches) && (matches[i]); i++) {
- /* find end of matches list */
- }
-
- if ((info != NULL) && (i < nmatches)) {
- i += videoPtrToDriverList(info, &(matches[i]), nmatches - i);
- }
-
- /* Fallback to platform default hardware */
- if (i < (nmatches - 1)) {
-#if defined(__i386__) || defined(__amd64__) || defined(__hurd__)
- matches[i++] = xnfstrdup("vesa");
-#elif defined(__sparc__) && !defined(sun)
- matches[i++] = xnfstrdup("sunffb");
-#endif
- }
-
- /* Fallback to platform default frame buffer driver */
- if (i < (nmatches - 1)) {
-#if !defined(__linux__) && defined(__sparc__)
- matches[i++] = xnfstrdup("wsfb");
-#else
- matches[i++] = xnfstrdup("fbdev");
-#endif
- }
-}
-
-/* copy a screen section and enter the desired driver
- * and insert it at i in the list of screens */
-static Bool
-copyScreen(confScreenPtr oscreen, GDevPtr odev, int i, char *driver)
-{
- GDevPtr cptr = NULL;
-
- xf86ConfigLayout.screens[i].screen = xnfcalloc(1, sizeof(confScreenRec));
- if(!xf86ConfigLayout.screens[i].screen)
- return FALSE;
- memcpy(xf86ConfigLayout.screens[i].screen, oscreen, sizeof(confScreenRec));
-
- cptr = xcalloc(1, sizeof(GDevRec));
- if (!cptr)
- return FALSE;
- memcpy(cptr, odev, sizeof(GDevRec));
-
- cptr->identifier = Xprintf("Autoconfigured Video Device %s", driver);
- cptr->driver = driver;
-
- /* now associate the new driver entry with the new screen entry */
- xf86ConfigLayout.screens[i].screen->device = cptr;
- cptr->myScreenSection = xf86ConfigLayout.screens[i].screen;
-
- return TRUE;
-}
-
-GDevPtr
-autoConfigDevice(GDevPtr preconf_device)
-{
- GDevPtr ptr = NULL;
- char *matches[20]; /* If we have more than 20 drivers we're in trouble */
- int num_matches = 0, num_screens = 0, i;
- screenLayoutPtr slp;
-
- if (!xf86configptr) {
- return NULL;
- }
-
- /* If there's a configured section with no driver chosen, use it */
- if (preconf_device) {
- ptr = preconf_device;
- } else {
- ptr = xcalloc(1, sizeof(GDevRec));
- if (!ptr) {
- return NULL;
- }
- ptr->chipID = -1;
- ptr->chipRev = -1;
- ptr->irq = -1;
-
- ptr->active = TRUE;
- ptr->claimed = FALSE;
- ptr->identifier = "Autoconfigured Video Device";
- ptr->driver = NULL;
- }
- if (!ptr->driver) {
- /* get all possible video drivers and count them */
- listPossibleVideoDrivers(matches, 20);
- for (; matches[num_matches]; num_matches++) {
- xf86Msg(X_DEFAULT, "Matched %s as autoconfigured driver %d\n",
- matches[num_matches], num_matches);
- }
-
- slp = xf86ConfigLayout.screens;
- if (slp) {
- /* count the number of screens and make space for
- * a new screen for each additional possible driver
- * minus one for the already existing first one
- * plus one for the terminating NULL */
- for (; slp[num_screens].screen; num_screens++);
- xf86ConfigLayout.screens = xnfcalloc(num_screens + num_matches,
- sizeof(screenLayoutRec));
- xf86ConfigLayout.screens[0] = slp[0];
-
- /* do the first match and set that for the original first screen */
- ptr->driver = matches[0];
- if (!xf86ConfigLayout.screens[0].screen->device) {
- xf86ConfigLayout.screens[0].screen->device = ptr;
- ptr->myScreenSection = xf86ConfigLayout.screens[0].screen;
- }
-
- /* for each other driver found, copy the first screen, insert it
- * into the list of screens and set the driver */
- i = 0;
- while (i++ < num_matches) {
- if (!copyScreen(slp[0].screen, ptr, i, matches[i]))
- return NULL;
- }
-
- /* shift the rest of the original screen list
- * to the end of the current screen list
- *
- * TODO Handle rest of multiple screen sections */
- for (i = 1; i < num_screens; i++) {
- xf86ConfigLayout.screens[i+num_matches] = slp[i];
- }
- xf86ConfigLayout.screens[num_screens+num_matches-1].screen = NULL;
- xfree(slp);
- } else {
- /* layout does not have any screens, not much to do */
- ptr->driver = matches[0];
- for (i = 1; matches[i] ; i++) {
- if (matches[i] != matches[0]) {
- xfree(matches[i]);
- }
- }
- }
- }
-
- xf86Msg(X_DEFAULT, "Assigned the driver to the xf86ConfigLayout\n");
-
- return ptr;
-}
+/*
+ * Copyright 2003 by David H. Dawes.
+ * Copyright 2003 by X-Oz Technologies.
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ *
+ * Author: David Dawes <dawes@XFree86.Org>.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "xf86.h"
+#include "xf86Parser.h"
+#include "xf86tokens.h"
+#include "xf86Config.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#ifdef __sparc__
+# include "xf86sbusBus.h"
+#endif
+#include "dirent.h"
+
+#ifdef sun
+# include <sys/visual_io.h>
+# include <ctype.h>
+#endif
+
+/* Sections for the default built-in configuration. */
+
+#define BUILTIN_DEVICE_NAME \
+ "\"Builtin Default %s Device %d\""
+
+#define BUILTIN_DEVICE_SECTION_PRE \
+ "Section \"Device\"\n" \
+ "\tIdentifier\t" BUILTIN_DEVICE_NAME "\n" \
+ "\tDriver\t\"%s\"\n"
+
+#define BUILTIN_DEVICE_SECTION_POST \
+ "EndSection\n\n"
+
+#define BUILTIN_DEVICE_SECTION \
+ BUILTIN_DEVICE_SECTION_PRE \
+ BUILTIN_DEVICE_SECTION_POST
+
+#define BUILTIN_SCREEN_NAME \
+ "\"Builtin Default %s Screen %d\""
+
+#define BUILTIN_SCREEN_SECTION \
+ "Section \"Screen\"\n" \
+ "\tIdentifier\t" BUILTIN_SCREEN_NAME "\n" \
+ "\tDevice\t" BUILTIN_DEVICE_NAME "\n" \
+ "EndSection\n\n"
+
+#define BUILTIN_LAYOUT_SECTION_PRE \
+ "Section \"ServerLayout\"\n" \
+ "\tIdentifier\t\"Builtin Default Layout\"\n"
+
+#define BUILTIN_LAYOUT_SCREEN_LINE \
+ "\tScreen\t" BUILTIN_SCREEN_NAME "\n"
+
+#define BUILTIN_LAYOUT_SECTION_POST \
+ "EndSection\n\n"
+
+static const char **builtinConfig = NULL;
+static int builtinLines = 0;
+
+static void listPossibleVideoDrivers(char *matches[], int nmatches);
+
+/*
+ * A built-in config file is stored as an array of strings, with each string
+ * representing a single line. AppendToConfig() breaks up the string "s"
+ * into lines, and appends those lines it to builtinConfig.
+ */
+
+static void
+AppendToList(const char *s, const char ***list, int *lines)
+{
+ char *str, *newstr, *p;
+
+ str = xnfstrdup(s);
+ for (p = strtok(str, "\n"); p; p = strtok(NULL, "\n")) {
+ (*lines)++;
+ *list = xnfrealloc(*list, (*lines + 1) * sizeof(**list));
+ newstr = xnfalloc(strlen(p) + 2);
+ strcpy(newstr, p);
+ strcat(newstr, "\n");
+ (*list)[*lines - 1] = newstr;
+ (*list)[*lines] = NULL;
+ }
+ free(str);
+}
+
+static void
+FreeList(const char ***list, int *lines)
+{
+ int i;
+
+ for (i = 0; i < *lines; i++) {
+ if ((*list)[i])
+ free((*list)[i]);
+ }
+ free(*list);
+ *list = NULL;
+ *lines = 0;
+}
+
+static void
+FreeConfig(void)
+{
+ FreeList(&builtinConfig, &builtinLines);
+}
+
+static void
+AppendToConfig(const char *s)
+{
+ AppendToList(s, &builtinConfig, &builtinLines);
+}
+
+static int
+videoPtrToDriverList(struct pci_device *dev,
+ char *returnList[], int returnListMax)
+{
+ int i;
+ /* Add more entries here if we ever return more than 4 drivers for
+ any device */
+ char *driverList[5] = { NULL, NULL, NULL, NULL, NULL };
+
+ switch (dev->vendor_id)
+ {
+ /* AMD Geode LX */
+ case 0x1022:
+ if (dev->device_id == 0x2081)
+ driverList[0] = "geode";
+ break;
+ /* older Geode products acquired by AMD still carry an NSC vendor_id */
+ case 0x100b:
+ if (dev->device_id == 0x0030) {
+ /* NSC Geode GX2 specifically */
+ driverList[0] = "geode";
+ /* GX2 support started its life in the NSC tree and was later
+ forked by AMD for GEODE so we keep it as a backup */
+ driverList[1] = "nsc";
+ } else
+ /* other NSC variant e.g. 0x0104 (SC1400), 0x0504 (SCx200) */
+ driverList[0] = "nsc";
+ break;
+ /* Cyrix Geode GX1 */
+ case 0x1078:
+ if (dev->device_id == 0x0104)
+ driverList[0] = "cyrix";
+ break;
+ case 0x1142: driverList[0] = "apm"; break;
+ case 0xedd8: driverList[0] = "ark"; break;
+ case 0x1a03: driverList[0] = "ast"; break;
+ case 0x1002: driverList[0] = "ati"; break;
+ case 0x102c: driverList[0] = "chips"; break;
+ case 0x1013: driverList[0] = "cirrus"; break;
+ case 0x3d3d: driverList[0] = "glint"; break;
+ case 0x105d: driverList[0] = "i128"; break;
+ case 0x8086:
+ if ((dev->device_id == 0x00d1) || (dev->device_id == 0x7800)) {
+ driverList[0] = "i740";
+ } else if (dev->device_id == 0x8108) {
+ break; /* "hooray" for poulsbo */
+ } else {
+ driverList[0] = "intel";
+ }
+ break;
+ case 0x102b: driverList[0] = "mga"; break;
+ case 0x10c8: driverList[0] = "neomagic"; break;
+ case 0x10de: case 0x12d2: driverList[0] = "nv"; break;
+ case 0x1106: driverList[0] = "openchrome"; break;
+ case 0x1b36: driverList[0] = "qxl"; break;
+ case 0x1163: driverList[0] = "rendition"; break;
+ case 0x5333:
+ switch (dev->device_id)
+ {
+ case 0x88d0: case 0x88d1: case 0x88f0: case 0x8811:
+ case 0x8812: case 0x8814: case 0x8901:
+ driverList[0] = "s3"; break;
+ case 0x5631: case 0x883d: case 0x8a01: case 0x8a10:
+ case 0x8c01: case 0x8c03: case 0x8904: case 0x8a13:
+ driverList[0] = "s3virge"; break;
+ default:
+ driverList[0] = "savage"; break;
+ }
+ break;
+ case 0x1039: driverList[0] = "sis"; break;
+ case 0x126f: driverList[0] = "siliconmotion"; break;
+ case 0x121a:
+ if (dev->device_id < 0x0003)
+ driverList[0] = "voodoo";
+ else
+ driverList[0] = "tdfx";
+ break;
+ case 0x1011: driverList[0] = "tga"; break;
+ case 0x1023: driverList[0] = "trident"; break;
+ case 0x100c: driverList[0] = "tseng"; break;
+ case 0x80ee: driverList[0] = "vboxvideo"; break;
+ case 0x15ad: driverList[0] = "vmware"; break;
+ case 0x18ca:
+ if (dev->device_id == 0x47)
+ driverList[0] = "xgixp";
+ else
+ driverList[0] = "xgi";
+ break;
+ default: break;
+ }
+ for (i = 0; (i < returnListMax) && (driverList[i] != NULL); i++) {
+ returnList[i] = xnfstrdup(driverList[i]);
+ }
+ return i; /* Number of entries added */
+}
+
+Bool
+xf86AutoConfig(void)
+{
+ char *deviceList[20];
+ char **p;
+ const char **cp;
+ char buf[1024];
+ ConfigStatus ret;
+
+ listPossibleVideoDrivers(deviceList, 20);
+
+ for (p = deviceList; *p; p++) {
+ snprintf(buf, sizeof(buf), BUILTIN_DEVICE_SECTION, *p, 0, *p);
+ AppendToConfig(buf);
+ snprintf(buf, sizeof(buf), BUILTIN_SCREEN_SECTION, *p, 0, *p, 0);
+ AppendToConfig(buf);
+ }
+
+ AppendToConfig(BUILTIN_LAYOUT_SECTION_PRE);
+ for (p = deviceList; *p; p++) {
+ snprintf(buf, sizeof(buf), BUILTIN_LAYOUT_SCREEN_LINE, *p, 0);
+ AppendToConfig(buf);
+ }
+ AppendToConfig(BUILTIN_LAYOUT_SECTION_POST);
+
+ for (p = deviceList; *p; p++) {
+ free(*p);
+ }
+
+ xf86MsgVerb(X_DEFAULT, 0,
+ "Using default built-in configuration (%d lines)\n",
+ builtinLines);
+
+ xf86MsgVerb(X_DEFAULT, 3, "--- Start of built-in configuration ---\n");
+ for (cp = builtinConfig; *cp; cp++)
+ xf86ErrorFVerb(3, "\t%s", *cp);
+ xf86MsgVerb(X_DEFAULT, 3, "--- End of built-in configuration ---\n");
+
+ xf86initConfigFiles();
+ xf86setBuiltinConfig(builtinConfig);
+ ret = xf86HandleConfigFile(TRUE);
+ FreeConfig();
+
+ if (ret != CONFIG_OK)
+ xf86Msg(X_ERROR, "Error parsing the built-in default configuration.\n");
+
+ return (ret == CONFIG_OK);
+}
+
+static int
+xchomp(char *line)
+{
+ size_t len = 0;
+
+ if (!line) {
+ return 1;
+ }
+
+ len = strlen(line);
+ if (line[len - 1] == '\n' && len > 0) {
+ line[len - 1] = '\0';
+ }
+ return 0;
+}
+
+#ifdef __linux__
+/* This function is used to provide a workaround for binary drivers that
+ * don't export their PCI ID's properly. If distros don't end up using this
+ * feature it can and should be removed because the symbol-based resolution
+ * scheme should be the primary one */
+static void
+matchDriverFromFiles (char** matches, uint16_t match_vendor, uint16_t match_chip)
+{
+ DIR *idsdir;
+ FILE *fp;
+ struct dirent *direntry;
+ char *line = NULL;
+ size_t len;
+ ssize_t read;
+ char path_name[256], vendor_str[5], chip_str[5];
+ uint16_t vendor, chip;
+ int i, j;
+
+ idsdir = opendir(PCI_TXT_IDS_PATH);
+ if (!idsdir)
+ return;
+
+ xf86Msg(X_INFO, "Scanning %s directory for additional PCI ID's supported by the drivers\n", PCI_TXT_IDS_PATH);
+ direntry = readdir(idsdir);
+ /* Read the directory */
+ while (direntry) {
+ if (direntry->d_name[0] == '.') {
+ direntry = readdir(idsdir);
+ continue;
+ }
+ len = strlen(direntry->d_name);
+ /* A tiny bit of sanity checking. We should probably do better */
+ if (strncmp(&(direntry->d_name[len-4]), ".ids", 4) == 0) {
+ /* We need the full path name to open the file */
+ strncpy(path_name, PCI_TXT_IDS_PATH, 256);
+ strncat(path_name, "/", 1);
+ strncat(path_name, direntry->d_name, (256 - strlen(path_name) - 1));
+ fp = fopen(path_name, "r");
+ if (fp == NULL) {
+ xf86Msg(X_ERROR, "Could not open %s for reading. Exiting.\n", path_name);
+ goto end;
+ }
+ /* Read the file */
+#ifdef __GLIBC__
+ while ((read = getline(&line, &len, fp)) != -1) {
+#else
+ while ((line = fgetln(fp, &len)) != (char *)NULL) {
+#endif /* __GLIBC __ */
+ xchomp(line);
+ if (isdigit(line[0])) {
+ strncpy(vendor_str, line, 4);
+ vendor_str[4] = '\0';
+ vendor = (int)strtol(vendor_str, NULL, 16);
+ if ((strlen(&line[4])) == 0) {
+ chip_str[0] = '\0';
+ chip = -1;
+ } else {
+ /* Handle trailing whitespace */
+ if (isspace(line[4])) {
+ chip_str[0] = '\0';
+ chip = -1;
+ } else {
+ /* Ok, it's a real ID */
+ strncpy(chip_str, &line[4], 4);
+ chip_str[4] = '\0';
+ chip = (int)strtol(chip_str, NULL, 16);
+ }
+ }
+ if (vendor == match_vendor && chip == match_chip ) {
+ i = 0;
+ while (matches[i]) {
+ i++;
+ }
+ matches[i] = (char*)malloc(sizeof(char) * strlen(direntry->d_name) - 3);
+ if (!matches[i]) {
+ xf86Msg(X_ERROR, "Could not allocate space for the module name. Exiting.\n");
+ goto end;
+ }
+ /* hack off the .ids suffix. This should guard
+ * against other problems, but it will end up
+ * taking off anything after the first '.' */
+ for (j = 0; j < (strlen(direntry->d_name) - 3) ; j++) {
+ if (direntry->d_name[j] == '.') {
+ matches[i][j] = '\0';
+ break;
+ } else {
+ matches[i][j] = direntry->d_name[j];
+ }
+ }
+ xf86Msg(X_INFO, "Matched %s from file name %s\n", matches[i], direntry->d_name);
+ }
+ } else {
+ /* TODO Handle driver overrides here */
+ }
+ }
+ fclose(fp);
+ }
+ direntry = readdir(idsdir);
+ }
+ end:
+ free(line);
+ closedir(idsdir);
+}
+#endif /* __linux__ */
+
+static void
+listPossibleVideoDrivers(char *matches[], int nmatches)
+{
+ struct pci_device * info = NULL;
+ struct pci_device_iterator *iter;
+ int i;
+
+ for (i = 0 ; i < nmatches ; i++) {
+ matches[i] = NULL;
+ }
+ i = 0;
+
+#ifdef sun
+ /* Check for driver type based on /dev/fb type and if valid, use
+ it instead of PCI bus probe results */
+ if (xf86Info.consoleFd >= 0) {
+ struct vis_identifier visid;
+ const char *cp;
+ extern char xf86SolarisFbDev[PATH_MAX];
+ int iret;
+
+ SYSCALL(iret = ioctl(xf86Info.consoleFd, VIS_GETIDENTIFIER, &visid));
+ if (iret < 0) {
+ int fbfd;
+
+ fbfd = open(xf86SolarisFbDev, O_RDONLY);
+ if (fbfd >= 0) {
+ SYSCALL(iret = ioctl(fbfd, VIS_GETIDENTIFIER, &visid));
+ close(fbfd);
+ }
+ }
+
+ if (iret < 0) {
+ xf86Msg(X_WARNING,
+ "could not get frame buffer identifier from %s\n",
+ xf86SolarisFbDev);
+ } else {
+ xf86Msg(X_PROBED, "console driver: %s\n", visid.name);
+
+ /* Special case from before the general case was set */
+ if (strcmp(visid.name, "NVDAnvda") == 0) {
+ matches[i++] = xnfstrdup("nvidia");
+ }
+
+ /* General case - split into vendor name (initial all-caps
+ prefix) & driver name (rest of the string). */
+ if (strcmp(visid.name, "SUNWtext") != 0) {
+ for (cp = visid.name; (*cp != '\0') && isupper(*cp); cp++) {
+ /* find end of all uppercase vendor section */
+ }
+ if ((cp != visid.name) && (*cp != '\0')) {
+ char *driverName = xnfstrdup(cp);
+ char *vendorName = xnfstrdup(visid.name);
+ vendorName[cp - visid.name] = '\0';
+
+ matches[i++] = vendorName;
+ matches[i++] = driverName;
+ }
+ }
+ }
+ }
+#endif
+#ifdef __sparc__
+ {
+ char *sbusDriver = sparcDriverName();
+ if (sbusDriver)
+ matches[i++] = xnfstrdup(sbusDriver);
+ }
+#endif
+
+ /* Find the primary device, and get some information about it. */
+ iter = pci_slot_match_iterator_create(NULL);
+ while ((info = pci_device_next(iter)) != NULL) {
+ if (xf86IsPrimaryPci(info)) {
+ break;
+ }
+ }
+
+ pci_iterator_destroy(iter);
+
+ if (!info) {
+ ErrorF("Primary device is not PCI\n");
+ }
+#ifdef __linux__
+ else {
+ matchDriverFromFiles(matches, info->vendor_id, info->device_id);
+ }
+#endif /* __linux__ */
+
+ for (i = 0; (i < nmatches) && (matches[i]); i++) {
+ /* find end of matches list */
+ }
+
+ if ((info != NULL) && (i < nmatches)) {
+ i += videoPtrToDriverList(info, &(matches[i]), nmatches - i);
+ }
+
+ /* Fallback to platform default hardware */
+ if (i < (nmatches - 1)) {
+#if defined(__i386__) || defined(__amd64__) || defined(__hurd__)
+ matches[i++] = xnfstrdup("vesa");
+#elif defined(__sparc__) && !defined(sun)
+ matches[i++] = xnfstrdup("sunffb");
+#endif
+ }
+
+ /* Fallback to platform default frame buffer driver */
+ if (i < (nmatches - 1)) {
+#if !defined(__linux__) && defined(__sparc__)
+ matches[i++] = xnfstrdup("wsfb");
+#else
+ matches[i++] = xnfstrdup("fbdev");
+#endif
+ }
+}
+
+/* copy a screen section and enter the desired driver
+ * and insert it at i in the list of screens */
+static Bool
+copyScreen(confScreenPtr oscreen, GDevPtr odev, int i, char *driver)
+{
+ GDevPtr cptr = NULL;
+
+ xf86ConfigLayout.screens[i].screen = xnfcalloc(1, sizeof(confScreenRec));
+ if(!xf86ConfigLayout.screens[i].screen)
+ return FALSE;
+ memcpy(xf86ConfigLayout.screens[i].screen, oscreen, sizeof(confScreenRec));
+
+ cptr = calloc(1, sizeof(GDevRec));
+ if (!cptr)
+ return FALSE;
+ memcpy(cptr, odev, sizeof(GDevRec));
+
+ cptr->identifier = Xprintf("Autoconfigured Video Device %s", driver);
+ cptr->driver = driver;
+
+ /* now associate the new driver entry with the new screen entry */
+ xf86ConfigLayout.screens[i].screen->device = cptr;
+ cptr->myScreenSection = xf86ConfigLayout.screens[i].screen;
+
+ return TRUE;
+}
+
+GDevPtr
+autoConfigDevice(GDevPtr preconf_device)
+{
+ GDevPtr ptr = NULL;
+ char *matches[20]; /* If we have more than 20 drivers we're in trouble */
+ int num_matches = 0, num_screens = 0, i;
+ screenLayoutPtr slp;
+
+ if (!xf86configptr) {
+ return NULL;
+ }
+
+ /* If there's a configured section with no driver chosen, use it */
+ if (preconf_device) {
+ ptr = preconf_device;
+ } else {
+ ptr = calloc(1, sizeof(GDevRec));
+ if (!ptr) {
+ return NULL;
+ }
+ ptr->chipID = -1;
+ ptr->chipRev = -1;
+ ptr->irq = -1;
+
+ ptr->active = TRUE;
+ ptr->claimed = FALSE;
+ ptr->identifier = "Autoconfigured Video Device";
+ ptr->driver = NULL;
+ }
+ if (!ptr->driver) {
+ /* get all possible video drivers and count them */
+ listPossibleVideoDrivers(matches, 20);
+ for (; matches[num_matches]; num_matches++) {
+ xf86Msg(X_DEFAULT, "Matched %s as autoconfigured driver %d\n",
+ matches[num_matches], num_matches);
+ }
+
+ slp = xf86ConfigLayout.screens;
+ if (slp) {
+ /* count the number of screens and make space for
+ * a new screen for each additional possible driver
+ * minus one for the already existing first one
+ * plus one for the terminating NULL */
+ for (; slp[num_screens].screen; num_screens++);
+ xf86ConfigLayout.screens = xnfcalloc(num_screens + num_matches,
+ sizeof(screenLayoutRec));
+ xf86ConfigLayout.screens[0] = slp[0];
+
+ /* do the first match and set that for the original first screen */
+ ptr->driver = matches[0];
+ if (!xf86ConfigLayout.screens[0].screen->device) {
+ xf86ConfigLayout.screens[0].screen->device = ptr;
+ ptr->myScreenSection = xf86ConfigLayout.screens[0].screen;
+ }
+
+ /* for each other driver found, copy the first screen, insert it
+ * into the list of screens and set the driver */
+ i = 0;
+ while (i++ < num_matches) {
+ if (!copyScreen(slp[0].screen, ptr, i, matches[i]))
+ return NULL;
+ }
+
+ /* shift the rest of the original screen list
+ * to the end of the current screen list
+ *
+ * TODO Handle rest of multiple screen sections */
+ for (i = 1; i < num_screens; i++) {
+ xf86ConfigLayout.screens[i+num_matches] = slp[i];
+ }
+ xf86ConfigLayout.screens[num_screens+num_matches-1].screen = NULL;
+ free(slp);
+ } else {
+ /* layout does not have any screens, not much to do */
+ ptr->driver = matches[0];
+ for (i = 1; matches[i] ; i++) {
+ if (matches[i] != matches[0]) {
+ free(matches[i]);
+ }
+ }
+ }
+ }
+
+ xf86Msg(X_DEFAULT, "Assigned the driver to the xf86ConfigLayout\n");
+
+ return ptr;
+}
diff --git a/xorg-server/hw/xfree86/common/xf86Bus.c b/xorg-server/hw/xfree86/common/xf86Bus.c
index 9d243c172..5c1668644 100644
--- a/xorg-server/hw/xfree86/common/xf86Bus.c
+++ b/xorg-server/hw/xfree86/common/xf86Bus.c
@@ -1,683 +1,683 @@
-/*
- * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-/*
- * This file contains the interfaces to the bus-specific code
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <ctype.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <X11/X.h>
-#include "os.h"
-#include "xf86.h"
-#include "xf86Priv.h"
-
-/* Bus-specific headers */
-
-#include "xf86Bus.h"
-
-#define XF86_OS_PRIVS
-#include "xf86_OSproc.h"
-#include "xf86VGAarbiter.h"
-
-#include "Pci.h"
-
-/* Entity data */
-EntityPtr *xf86Entities = NULL; /* Bus slots claimed by drivers */
-int xf86NumEntities = 0;
-static int xf86EntityPrivateCount = 0;
-
-BusRec primaryBus = { BUS_NONE, { 0 } };
-
-static Bool xf86ResAccessEnter = FALSE;
-
-static Bool doFramebufferMode = FALSE;
-
-/*
- * Call the bus probes relevant to the architecture.
- *
- * The only one available so far is for PCI and SBUS.
- */
-
-void
-xf86BusProbe(void)
-{
- xf86PciProbe();
-#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
- xf86SbusProbe();
-#endif
-}
-
-/*
- * Determine what bus type the busID string represents. The start of the
- * bus-dependent part of the string is returned as retID.
- */
-
-BusType
-StringToBusType(const char* busID, const char **retID)
-{
- char *p, *s;
- BusType ret = BUS_NONE;
-
- /* If no type field, Default to PCI */
- if (isdigit(busID[0])) {
- if (retID)
- *retID = busID;
- return BUS_PCI;
- }
-
- s = xstrdup(busID);
- p = strtok(s, ":");
- if (p == NULL || *p == 0) {
- xfree(s);
- return BUS_NONE;
- }
- if (!xf86NameCmp(p, "pci") || !xf86NameCmp(p, "agp"))
- ret = BUS_PCI;
- if (!xf86NameCmp(p, "sbus"))
- ret = BUS_SBUS;
- if (ret != BUS_NONE)
- if (retID)
- *retID = busID + strlen(p) + 1;
- xfree(s);
- return ret;
-}
-
-/*
- * Entity related code.
- */
-
-void
-xf86EntityInit(void)
-{
- int i;
-
- for (i = 0; i < xf86NumEntities; i++)
- if (xf86Entities[i]->entityInit) {
- xf86Entities[i]->entityInit(i,xf86Entities[i]->private);
- }
-}
-
-int
-xf86AllocateEntity(void)
-{
- xf86NumEntities++;
- xf86Entities = xnfrealloc(xf86Entities,
- sizeof(EntityPtr) * xf86NumEntities);
- xf86Entities[xf86NumEntities - 1] = xnfcalloc(1,sizeof(EntityRec));
- xf86Entities[xf86NumEntities - 1]->entityPrivates =
- xnfcalloc(sizeof(DevUnion) * xf86EntityPrivateCount, 1);
- return (xf86NumEntities - 1);
-}
-
-static void
-EntityEnter(void)
-{
- int i;
-
- for (i = 0; i < xf86NumEntities; i++)
- if (xf86Entities[i]->entityEnter) {
- xf86Entities[i]->entityEnter(i,xf86Entities[i]->private);
- }
-}
-
-static void
-EntityLeave(void)
-{
- int i;
-
- for (i = 0; i < xf86NumEntities; i++)
- if (xf86Entities[i]->entityLeave) {
- xf86Entities[i]->entityLeave(i,xf86Entities[i]->private);
- }
-}
-
-Bool
-xf86IsEntityPrimary(int entityIndex)
-{
- EntityPtr pEnt = xf86Entities[entityIndex];
-
- if (primaryBus.type != pEnt->bus.type) return FALSE;
-
- switch (pEnt->bus.type) {
- case BUS_PCI:
- return (pEnt->bus.id.pci == primaryBus.id.pci);
- case BUS_SBUS:
- return (pEnt->bus.id.sbus.fbNum == primaryBus.id.sbus.fbNum);
- default:
- return FALSE;
- }
-}
-
-Bool
-xf86SetEntityFuncs(int entityIndex, EntityProc init, EntityProc enter,
- EntityProc leave, pointer private)
-{
- if (entityIndex >= xf86NumEntities)
- return FALSE;
- xf86Entities[entityIndex]->entityInit = init;
- xf86Entities[entityIndex]->entityEnter = enter;
- xf86Entities[entityIndex]->entityLeave = leave;
- xf86Entities[entityIndex]->private = private;
- return TRUE;
-}
-
-Bool
-xf86DriverHasEntities(DriverPtr drvp)
-{
- int i;
- for (i = 0; i < xf86NumEntities; i++) {
- if (xf86Entities[i]->driver == drvp)
- return TRUE;
- }
- return FALSE;
-}
-
-void
-xf86AddEntityToScreen(ScrnInfoPtr pScrn, int entityIndex)
-{
- if (entityIndex == -1)
- return;
- if (xf86Entities[entityIndex]->inUse &&
- !(xf86Entities[entityIndex]->entityProp & IS_SHARED_ACCEL)) {
- ErrorF("Requested Entity already in use!\n");
- return;
- }
-
- pScrn->numEntities++;
- pScrn->entityList = xnfrealloc(pScrn->entityList,
- pScrn->numEntities * sizeof(int));
- pScrn->entityList[pScrn->numEntities - 1] = entityIndex;
- xf86Entities[entityIndex]->inUse = TRUE;
- pScrn->entityInstanceList = xnfrealloc(pScrn->entityInstanceList,
- pScrn->numEntities * sizeof(int));
- pScrn->entityInstanceList[pScrn->numEntities - 1] = 0;
- pScrn->domainIOBase = xf86Entities[entityIndex]->domainIO;
-}
-
-void
-xf86SetEntityInstanceForScreen(ScrnInfoPtr pScrn, int entityIndex, int instance)
-{
- int i;
-
- if (entityIndex == -1 || entityIndex >= xf86NumEntities)
- return;
-
- for (i = 0; i < pScrn->numEntities; i++) {
- if (pScrn->entityList[i] == entityIndex) {
- pScrn->entityInstanceList[i] = instance;
- break;
- }
- }
-}
-
-/*
- * XXX This needs to be updated for the case where a single entity may have
- * instances associated with more than one screen.
- */
-ScrnInfoPtr
-xf86FindScreenForEntity(int entityIndex)
-{
- int i,j;
-
- if (entityIndex == -1) return NULL;
-
- if (xf86Screens) {
- for (i = 0; i < xf86NumScreens; i++) {
- for (j = 0; j < xf86Screens[i]->numEntities; j++) {
- if ( xf86Screens[i]->entityList[j] == entityIndex )
- return (xf86Screens[i]);
- }
- }
- }
- return NULL;
-}
-
-void
-xf86RemoveEntityFromScreen(ScrnInfoPtr pScrn, int entityIndex)
-{
- int i;
-
- for (i = 0; i < pScrn->numEntities; i++) {
- if (pScrn->entityList[i] == entityIndex) {
- for (i++; i < pScrn->numEntities; i++)
- pScrn->entityList[i-1] = pScrn->entityList[i];
- pScrn->numEntities--;
- xf86Entities[entityIndex]->inUse = FALSE;
- break;
- }
- }
-}
-
-/*
- * xf86ClearEntitiesForScreen() - called when a screen is deleted
- * to mark it's entities unused. Called by xf86DeleteScreen().
- */
-void
-xf86ClearEntityListForScreen(int scrnIndex)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- int i, entityIndex;
-
- if (pScrn->entityList == NULL || pScrn->numEntities == 0) return;
-
- for (i = 0; i < pScrn->numEntities; i++) {
- entityIndex = pScrn->entityList[i];
- xf86Entities[entityIndex]->inUse = FALSE;
- /* disable resource: call the disable function */
- }
- xfree(pScrn->entityList);
- xfree(pScrn->entityInstanceList);
- pScrn->entityList = NULL;
- pScrn->entityInstanceList = NULL;
-}
-
-/*
- * Add an extra device section (GDevPtr) to an entity.
- */
-
-void
-xf86AddDevToEntity(int entityIndex, GDevPtr dev)
-{
- EntityPtr pEnt;
-
- if (entityIndex >= xf86NumEntities)
- return;
-
- pEnt = xf86Entities[entityIndex];
- pEnt->numInstances++;
- pEnt->devices = xnfrealloc(pEnt->devices,
- pEnt->numInstances * sizeof(GDevPtr));
- pEnt->devices[pEnt->numInstances - 1] = dev;
- dev->claimed = TRUE;
-}
-
-/*
- * xf86GetEntityInfo() -- This function hands information from the
- * EntityRec struct to the drivers. The EntityRec structure itself
- * remains invisible to the driver.
- */
-EntityInfoPtr
-xf86GetEntityInfo(int entityIndex)
-{
- EntityInfoPtr pEnt;
- int i;
-
- if (entityIndex == -1)
- return NULL;
-
- if (entityIndex >= xf86NumEntities)
- return NULL;
-
- pEnt = xnfcalloc(1,sizeof(EntityInfoRec));
- pEnt->index = entityIndex;
- pEnt->location = xf86Entities[entityIndex]->bus;
- pEnt->active = xf86Entities[entityIndex]->active;
- pEnt->chipset = xf86Entities[entityIndex]->chipset;
- pEnt->driver = xf86Entities[entityIndex]->driver;
- if ( (xf86Entities[entityIndex]->devices) &&
- (xf86Entities[entityIndex]->devices[0]) ) {
- for (i = 0; i < xf86Entities[entityIndex]->numInstances; i++)
- if (xf86Entities[entityIndex]->devices[i]->screen == 0)
- break;
- pEnt->device = xf86Entities[entityIndex]->devices[i];
- } else
- pEnt->device = NULL;
-
- return pEnt;
-}
-
-int
-xf86GetNumEntityInstances(int entityIndex)
-{
- if (entityIndex >= xf86NumEntities)
- return -1;
-
- return xf86Entities[entityIndex]->numInstances;
-}
-
-GDevPtr
-xf86GetDevFromEntity(int entityIndex, int instance)
-{
- int i;
-
- /* We might not use AddDevtoEntity */
- if ( (!xf86Entities[entityIndex]->devices) ||
- (!xf86Entities[entityIndex]->devices[0]) )
- return NULL;
-
- if (entityIndex >= xf86NumEntities ||
- instance >= xf86Entities[entityIndex]->numInstances)
- return NULL;
-
- for (i = 0; i < xf86Entities[entityIndex]->numInstances; i++)
- if (xf86Entities[entityIndex]->devices[i]->screen == instance)
- break;
- return xf86Entities[entityIndex]->devices[i];
-}
-
-/*
- * xf86AccessInit() - set up everything needed for access control
- * called only once on first server generation.
- */
-void
-xf86AccessInit(void)
-{
- xf86ResAccessEnter = TRUE;
-}
-
-/*
- * xf86AccessEnter() -- gets called to save the text mode VGA IO
- * resources when reentering the server after a VT switch.
- */
-void
-xf86AccessEnter(void)
-{
- if (xf86ResAccessEnter)
- return;
-
- /*
- * on enter we simply disable routing of special resources
- * to any bus and let the RAC code to "open" the right bridges.
- */
- EntityEnter();
- xf86EnterServerState(SETUP);
- xf86ResAccessEnter = TRUE;
-}
-
-/*
- * xf86AccessLeave() -- prepares access for and calls the
- * entityLeave() functions.
- * xf86AccessLeaveState() --- gets called to restore the
- * access to the VGA IO resources when switching VT or on
- * server exit.
- * This was split to call xf86AccessLeaveState() from
- * ddxGiveUp().
- */
-void
-xf86AccessLeave(void)
-{
- if (!xf86ResAccessEnter)
- return;
- EntityLeave();
-}
-
-/*
- * xf86EnableAccess() -- enable access to controlled resources.
- * To reduce latency when switching access the ScrnInfoRec has
- * a linked list of the EntityAccPtr of all screen entities.
- */
-/*
- * switching access needs to be done in te following oder:
- * disable
- * 1. disable old entity
- * 2. reroute bus
- * 3. enable new entity
- * Otherwise resources needed for access control might be shadowed
- * by other resources!
- */
-
-void
-xf86EnableAccess(ScrnInfoPtr pScrn)
-{
- DebugF("Enable access %i\n",pScrn->scrnIndex);
-
- return;
-}
-
-/*
- * xf86EnterServerState() -- set state the server is in.
- */
-
-typedef enum { TRI_UNSET, TRI_TRUE, TRI_FALSE } TriState;
-
-static void
-SetSIGIOForState(xf86State state)
-{
- static int sigio_state;
- static TriState sigio_blocked = TRI_UNSET;
-
- if ((state == SETUP) && (sigio_blocked != TRI_TRUE)) {
- sigio_state = xf86BlockSIGIO();
- sigio_blocked = TRI_TRUE;
- } else if ((state == OPERATING) && (sigio_blocked != TRI_UNSET)) {
- xf86UnblockSIGIO(sigio_state);
- sigio_blocked = TRI_FALSE;
- }
-}
-
-void
-xf86EnterServerState(xf86State state)
-{
- /*
- * This is a good place to block SIGIO during SETUP state.
- * SIGIO should be blocked in SETUP state otherwise (u)sleep()
- * might get interrupted early.
- * We take care not to call xf86BlockSIGIO() twice.
- */
- SetSIGIOForState(state);
- if (state == SETUP)
- DebugF("Entering SETUP state\n");
- else
- DebugF("Entering OPERATING state\n");
-
- return;
-}
-
-/*
- * xf86PostProbe() -- Allocate all non conflicting resources
- * This function gets called by xf86Init().
- */
-void
-xf86PostProbe(void)
-{
- if (fbSlotClaimed) {
- if (pciSlotClaimed
-#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
- || sbusSlotClaimed
-#endif
- ) {
- FatalError("Cannot run in framebuffer mode. Please specify busIDs "
- " for all framebuffer devices\n");
- return;
- } else {
- xf86Msg(X_INFO,"Running in FRAMEBUFFER Mode\n");
- doFramebufferMode = TRUE;
-
- return;
- }
- }
-}
-
-void
-xf86PostScreenInit(void)
-{
- if (doFramebufferMode) {
- SetSIGIOForState(OPERATING);
- return;
- }
-
- xf86VGAarbiterWrapFunctions();
-
- DebugF("PostScreenInit generation: %i\n",serverGeneration);
- xf86EnterServerState(OPERATING);
-}
-
-/*
- * xf86FindPrimaryDevice() - Find the display device which
- * was active when the server was started.
- */
-void
-xf86FindPrimaryDevice(void)
-{
- if (primaryBus.type != BUS_NONE) {
- char *bus;
- char loc[16];
-
- switch (primaryBus.type) {
- case BUS_PCI:
- bus = "PCI";
- snprintf(loc, sizeof(loc), " %2.2x@%2.2x:%2.2x:%1.1x",
- primaryBus.id.pci->bus,
- primaryBus.id.pci->domain,
- primaryBus.id.pci->dev,
- primaryBus.id.pci->func);
- break;
- case BUS_SBUS:
- bus = "SBUS";
- snprintf(loc, sizeof(loc), " %2.2x", primaryBus.id.sbus.fbNum);
- break;
- default:
- bus = "";
- loc[0] = '\0';
- }
-
- xf86MsgVerb(X_INFO, 2, "Primary Device is: %s%s\n",bus,loc);
- }
-}
-
-int
-xf86GetLastScrnFlag(int entityIndex)
-{
- if(entityIndex < xf86NumEntities) {
- return(xf86Entities[entityIndex]->lastScrnFlag);
- } else {
- return -1;
- }
-}
-
-void
-xf86SetLastScrnFlag(int entityIndex, int scrnIndex)
-{
- if(entityIndex < xf86NumEntities) {
- xf86Entities[entityIndex]->lastScrnFlag = scrnIndex;
- }
-}
-
-Bool
-xf86IsEntityShared(int entityIndex)
-{
- if(entityIndex < xf86NumEntities) {
- if(xf86Entities[entityIndex]->entityProp & IS_SHARED_ACCEL) {
- return TRUE;
- }
- }
- return FALSE;
-}
-
-void
-xf86SetEntityShared(int entityIndex)
-{
- if(entityIndex < xf86NumEntities) {
- xf86Entities[entityIndex]->entityProp |= IS_SHARED_ACCEL;
- }
-}
-
-Bool
-xf86IsEntitySharable(int entityIndex)
-{
- if(entityIndex < xf86NumEntities) {
- if(xf86Entities[entityIndex]->entityProp & ACCEL_IS_SHARABLE) {
- return TRUE;
- }
- }
- return FALSE;
-}
-
-void
-xf86SetEntitySharable(int entityIndex)
-{
- if(entityIndex < xf86NumEntities) {
- xf86Entities[entityIndex]->entityProp |= ACCEL_IS_SHARABLE;
- }
-}
-
-Bool
-xf86IsPrimInitDone(int entityIndex)
-{
- if(entityIndex < xf86NumEntities) {
- if(xf86Entities[entityIndex]->entityProp & SA_PRIM_INIT_DONE) {
- return TRUE;
- }
- }
- return FALSE;
-}
-
-void
-xf86SetPrimInitDone(int entityIndex)
-{
- if(entityIndex < xf86NumEntities) {
- xf86Entities[entityIndex]->entityProp |= SA_PRIM_INIT_DONE;
- }
-}
-
-void
-xf86ClearPrimInitDone(int entityIndex)
-{
- if(entityIndex < xf86NumEntities) {
- xf86Entities[entityIndex]->entityProp &= ~SA_PRIM_INIT_DONE;
- }
-}
-
-
-/*
- * Allocate a private in the entities.
- */
-
-int
-xf86AllocateEntityPrivateIndex(void)
-{
- int idx, i;
- EntityPtr pEnt;
- DevUnion *nprivs;
-
- idx = xf86EntityPrivateCount++;
- for (i = 0; i < xf86NumEntities; i++) {
- pEnt = xf86Entities[i];
- nprivs = xnfrealloc(pEnt->entityPrivates,
- xf86EntityPrivateCount * sizeof(DevUnion));
- /* Zero the new private */
- bzero(&nprivs[idx], sizeof(DevUnion));
- pEnt->entityPrivates = nprivs;
- }
- return idx;
-}
-
-DevUnion *
-xf86GetEntityPrivate(int entityIndex, int privIndex)
-{
- if (entityIndex >= xf86NumEntities || privIndex >= xf86EntityPrivateCount)
- return NULL;
-
- return &(xf86Entities[entityIndex]->entityPrivates[privIndex]);
-}
-
+/*
+ * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ * This file contains the interfaces to the bus-specific code
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <X11/X.h>
+#include "os.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+
+/* Bus-specific headers */
+
+#include "xf86Bus.h"
+
+#define XF86_OS_PRIVS
+#include "xf86_OSproc.h"
+#include "xf86VGAarbiter.h"
+
+#include "Pci.h"
+
+/* Entity data */
+EntityPtr *xf86Entities = NULL; /* Bus slots claimed by drivers */
+int xf86NumEntities = 0;
+static int xf86EntityPrivateCount = 0;
+
+BusRec primaryBus = { BUS_NONE, { 0 } };
+
+static Bool xf86ResAccessEnter = FALSE;
+
+static Bool doFramebufferMode = FALSE;
+
+/*
+ * Call the bus probes relevant to the architecture.
+ *
+ * The only one available so far is for PCI and SBUS.
+ */
+
+void
+xf86BusProbe(void)
+{
+ xf86PciProbe();
+#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
+ xf86SbusProbe();
+#endif
+}
+
+/*
+ * Determine what bus type the busID string represents. The start of the
+ * bus-dependent part of the string is returned as retID.
+ */
+
+BusType
+StringToBusType(const char* busID, const char **retID)
+{
+ char *p, *s;
+ BusType ret = BUS_NONE;
+
+ /* If no type field, Default to PCI */
+ if (isdigit(busID[0])) {
+ if (retID)
+ *retID = busID;
+ return BUS_PCI;
+ }
+
+ s = xstrdup(busID);
+ p = strtok(s, ":");
+ if (p == NULL || *p == 0) {
+ free(s);
+ return BUS_NONE;
+ }
+ if (!xf86NameCmp(p, "pci") || !xf86NameCmp(p, "agp"))
+ ret = BUS_PCI;
+ if (!xf86NameCmp(p, "sbus"))
+ ret = BUS_SBUS;
+ if (ret != BUS_NONE)
+ if (retID)
+ *retID = busID + strlen(p) + 1;
+ free(s);
+ return ret;
+}
+
+/*
+ * Entity related code.
+ */
+
+void
+xf86EntityInit(void)
+{
+ int i;
+
+ for (i = 0; i < xf86NumEntities; i++)
+ if (xf86Entities[i]->entityInit) {
+ xf86Entities[i]->entityInit(i,xf86Entities[i]->private);
+ }
+}
+
+int
+xf86AllocateEntity(void)
+{
+ xf86NumEntities++;
+ xf86Entities = xnfrealloc(xf86Entities,
+ sizeof(EntityPtr) * xf86NumEntities);
+ xf86Entities[xf86NumEntities - 1] = xnfcalloc(1,sizeof(EntityRec));
+ xf86Entities[xf86NumEntities - 1]->entityPrivates =
+ xnfcalloc(sizeof(DevUnion) * xf86EntityPrivateCount, 1);
+ return (xf86NumEntities - 1);
+}
+
+static void
+EntityEnter(void)
+{
+ int i;
+
+ for (i = 0; i < xf86NumEntities; i++)
+ if (xf86Entities[i]->entityEnter) {
+ xf86Entities[i]->entityEnter(i,xf86Entities[i]->private);
+ }
+}
+
+static void
+EntityLeave(void)
+{
+ int i;
+
+ for (i = 0; i < xf86NumEntities; i++)
+ if (xf86Entities[i]->entityLeave) {
+ xf86Entities[i]->entityLeave(i,xf86Entities[i]->private);
+ }
+}
+
+Bool
+xf86IsEntityPrimary(int entityIndex)
+{
+ EntityPtr pEnt = xf86Entities[entityIndex];
+
+ if (primaryBus.type != pEnt->bus.type) return FALSE;
+
+ switch (pEnt->bus.type) {
+ case BUS_PCI:
+ return (pEnt->bus.id.pci == primaryBus.id.pci);
+ case BUS_SBUS:
+ return (pEnt->bus.id.sbus.fbNum == primaryBus.id.sbus.fbNum);
+ default:
+ return FALSE;
+ }
+}
+
+Bool
+xf86SetEntityFuncs(int entityIndex, EntityProc init, EntityProc enter,
+ EntityProc leave, pointer private)
+{
+ if (entityIndex >= xf86NumEntities)
+ return FALSE;
+ xf86Entities[entityIndex]->entityInit = init;
+ xf86Entities[entityIndex]->entityEnter = enter;
+ xf86Entities[entityIndex]->entityLeave = leave;
+ xf86Entities[entityIndex]->private = private;
+ return TRUE;
+}
+
+Bool
+xf86DriverHasEntities(DriverPtr drvp)
+{
+ int i;
+ for (i = 0; i < xf86NumEntities; i++) {
+ if (xf86Entities[i]->driver == drvp)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+void
+xf86AddEntityToScreen(ScrnInfoPtr pScrn, int entityIndex)
+{
+ if (entityIndex == -1)
+ return;
+ if (xf86Entities[entityIndex]->inUse &&
+ !(xf86Entities[entityIndex]->entityProp & IS_SHARED_ACCEL)) {
+ ErrorF("Requested Entity already in use!\n");
+ return;
+ }
+
+ pScrn->numEntities++;
+ pScrn->entityList = xnfrealloc(pScrn->entityList,
+ pScrn->numEntities * sizeof(int));
+ pScrn->entityList[pScrn->numEntities - 1] = entityIndex;
+ xf86Entities[entityIndex]->inUse = TRUE;
+ pScrn->entityInstanceList = xnfrealloc(pScrn->entityInstanceList,
+ pScrn->numEntities * sizeof(int));
+ pScrn->entityInstanceList[pScrn->numEntities - 1] = 0;
+ pScrn->domainIOBase = xf86Entities[entityIndex]->domainIO;
+}
+
+void
+xf86SetEntityInstanceForScreen(ScrnInfoPtr pScrn, int entityIndex, int instance)
+{
+ int i;
+
+ if (entityIndex == -1 || entityIndex >= xf86NumEntities)
+ return;
+
+ for (i = 0; i < pScrn->numEntities; i++) {
+ if (pScrn->entityList[i] == entityIndex) {
+ pScrn->entityInstanceList[i] = instance;
+ break;
+ }
+ }
+}
+
+/*
+ * XXX This needs to be updated for the case where a single entity may have
+ * instances associated with more than one screen.
+ */
+ScrnInfoPtr
+xf86FindScreenForEntity(int entityIndex)
+{
+ int i,j;
+
+ if (entityIndex == -1) return NULL;
+
+ if (xf86Screens) {
+ for (i = 0; i < xf86NumScreens; i++) {
+ for (j = 0; j < xf86Screens[i]->numEntities; j++) {
+ if ( xf86Screens[i]->entityList[j] == entityIndex )
+ return (xf86Screens[i]);
+ }
+ }
+ }
+ return NULL;
+}
+
+void
+xf86RemoveEntityFromScreen(ScrnInfoPtr pScrn, int entityIndex)
+{
+ int i;
+
+ for (i = 0; i < pScrn->numEntities; i++) {
+ if (pScrn->entityList[i] == entityIndex) {
+ for (i++; i < pScrn->numEntities; i++)
+ pScrn->entityList[i-1] = pScrn->entityList[i];
+ pScrn->numEntities--;
+ xf86Entities[entityIndex]->inUse = FALSE;
+ break;
+ }
+ }
+}
+
+/*
+ * xf86ClearEntitiesForScreen() - called when a screen is deleted
+ * to mark it's entities unused. Called by xf86DeleteScreen().
+ */
+void
+xf86ClearEntityListForScreen(int scrnIndex)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ int i, entityIndex;
+
+ if (pScrn->entityList == NULL || pScrn->numEntities == 0) return;
+
+ for (i = 0; i < pScrn->numEntities; i++) {
+ entityIndex = pScrn->entityList[i];
+ xf86Entities[entityIndex]->inUse = FALSE;
+ /* disable resource: call the disable function */
+ }
+ free(pScrn->entityList);
+ free(pScrn->entityInstanceList);
+ pScrn->entityList = NULL;
+ pScrn->entityInstanceList = NULL;
+}
+
+/*
+ * Add an extra device section (GDevPtr) to an entity.
+ */
+
+void
+xf86AddDevToEntity(int entityIndex, GDevPtr dev)
+{
+ EntityPtr pEnt;
+
+ if (entityIndex >= xf86NumEntities)
+ return;
+
+ pEnt = xf86Entities[entityIndex];
+ pEnt->numInstances++;
+ pEnt->devices = xnfrealloc(pEnt->devices,
+ pEnt->numInstances * sizeof(GDevPtr));
+ pEnt->devices[pEnt->numInstances - 1] = dev;
+ dev->claimed = TRUE;
+}
+
+/*
+ * xf86GetEntityInfo() -- This function hands information from the
+ * EntityRec struct to the drivers. The EntityRec structure itself
+ * remains invisible to the driver.
+ */
+EntityInfoPtr
+xf86GetEntityInfo(int entityIndex)
+{
+ EntityInfoPtr pEnt;
+ int i;
+
+ if (entityIndex == -1)
+ return NULL;
+
+ if (entityIndex >= xf86NumEntities)
+ return NULL;
+
+ pEnt = xnfcalloc(1,sizeof(EntityInfoRec));
+ pEnt->index = entityIndex;
+ pEnt->location = xf86Entities[entityIndex]->bus;
+ pEnt->active = xf86Entities[entityIndex]->active;
+ pEnt->chipset = xf86Entities[entityIndex]->chipset;
+ pEnt->driver = xf86Entities[entityIndex]->driver;
+ if ( (xf86Entities[entityIndex]->devices) &&
+ (xf86Entities[entityIndex]->devices[0]) ) {
+ for (i = 0; i < xf86Entities[entityIndex]->numInstances; i++)
+ if (xf86Entities[entityIndex]->devices[i]->screen == 0)
+ break;
+ pEnt->device = xf86Entities[entityIndex]->devices[i];
+ } else
+ pEnt->device = NULL;
+
+ return pEnt;
+}
+
+int
+xf86GetNumEntityInstances(int entityIndex)
+{
+ if (entityIndex >= xf86NumEntities)
+ return -1;
+
+ return xf86Entities[entityIndex]->numInstances;
+}
+
+GDevPtr
+xf86GetDevFromEntity(int entityIndex, int instance)
+{
+ int i;
+
+ /* We might not use AddDevtoEntity */
+ if ( (!xf86Entities[entityIndex]->devices) ||
+ (!xf86Entities[entityIndex]->devices[0]) )
+ return NULL;
+
+ if (entityIndex >= xf86NumEntities ||
+ instance >= xf86Entities[entityIndex]->numInstances)
+ return NULL;
+
+ for (i = 0; i < xf86Entities[entityIndex]->numInstances; i++)
+ if (xf86Entities[entityIndex]->devices[i]->screen == instance)
+ break;
+ return xf86Entities[entityIndex]->devices[i];
+}
+
+/*
+ * xf86AccessInit() - set up everything needed for access control
+ * called only once on first server generation.
+ */
+void
+xf86AccessInit(void)
+{
+ xf86ResAccessEnter = TRUE;
+}
+
+/*
+ * xf86AccessEnter() -- gets called to save the text mode VGA IO
+ * resources when reentering the server after a VT switch.
+ */
+void
+xf86AccessEnter(void)
+{
+ if (xf86ResAccessEnter)
+ return;
+
+ /*
+ * on enter we simply disable routing of special resources
+ * to any bus and let the RAC code to "open" the right bridges.
+ */
+ EntityEnter();
+ xf86EnterServerState(SETUP);
+ xf86ResAccessEnter = TRUE;
+}
+
+/*
+ * xf86AccessLeave() -- prepares access for and calls the
+ * entityLeave() functions.
+ * xf86AccessLeaveState() --- gets called to restore the
+ * access to the VGA IO resources when switching VT or on
+ * server exit.
+ * This was split to call xf86AccessLeaveState() from
+ * ddxGiveUp().
+ */
+void
+xf86AccessLeave(void)
+{
+ if (!xf86ResAccessEnter)
+ return;
+ EntityLeave();
+}
+
+/*
+ * xf86EnableAccess() -- enable access to controlled resources.
+ * To reduce latency when switching access the ScrnInfoRec has
+ * a linked list of the EntityAccPtr of all screen entities.
+ */
+/*
+ * switching access needs to be done in te following oder:
+ * disable
+ * 1. disable old entity
+ * 2. reroute bus
+ * 3. enable new entity
+ * Otherwise resources needed for access control might be shadowed
+ * by other resources!
+ */
+
+void
+xf86EnableAccess(ScrnInfoPtr pScrn)
+{
+ DebugF("Enable access %i\n",pScrn->scrnIndex);
+
+ return;
+}
+
+/*
+ * xf86EnterServerState() -- set state the server is in.
+ */
+
+typedef enum { TRI_UNSET, TRI_TRUE, TRI_FALSE } TriState;
+
+static void
+SetSIGIOForState(xf86State state)
+{
+ static int sigio_state;
+ static TriState sigio_blocked = TRI_UNSET;
+
+ if ((state == SETUP) && (sigio_blocked != TRI_TRUE)) {
+ sigio_state = xf86BlockSIGIO();
+ sigio_blocked = TRI_TRUE;
+ } else if ((state == OPERATING) && (sigio_blocked != TRI_UNSET)) {
+ xf86UnblockSIGIO(sigio_state);
+ sigio_blocked = TRI_FALSE;
+ }
+}
+
+void
+xf86EnterServerState(xf86State state)
+{
+ /*
+ * This is a good place to block SIGIO during SETUP state.
+ * SIGIO should be blocked in SETUP state otherwise (u)sleep()
+ * might get interrupted early.
+ * We take care not to call xf86BlockSIGIO() twice.
+ */
+ SetSIGIOForState(state);
+ if (state == SETUP)
+ DebugF("Entering SETUP state\n");
+ else
+ DebugF("Entering OPERATING state\n");
+
+ return;
+}
+
+/*
+ * xf86PostProbe() -- Allocate all non conflicting resources
+ * This function gets called by xf86Init().
+ */
+void
+xf86PostProbe(void)
+{
+ if (fbSlotClaimed) {
+ if (pciSlotClaimed
+#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
+ || sbusSlotClaimed
+#endif
+ ) {
+ FatalError("Cannot run in framebuffer mode. Please specify busIDs "
+ " for all framebuffer devices\n");
+ return;
+ } else {
+ xf86Msg(X_INFO,"Running in FRAMEBUFFER Mode\n");
+ doFramebufferMode = TRUE;
+
+ return;
+ }
+ }
+}
+
+void
+xf86PostScreenInit(void)
+{
+ if (doFramebufferMode) {
+ SetSIGIOForState(OPERATING);
+ return;
+ }
+
+ xf86VGAarbiterWrapFunctions();
+
+ DebugF("PostScreenInit generation: %i\n",serverGeneration);
+ xf86EnterServerState(OPERATING);
+}
+
+/*
+ * xf86FindPrimaryDevice() - Find the display device which
+ * was active when the server was started.
+ */
+void
+xf86FindPrimaryDevice(void)
+{
+ if (primaryBus.type != BUS_NONE) {
+ char *bus;
+ char loc[16];
+
+ switch (primaryBus.type) {
+ case BUS_PCI:
+ bus = "PCI";
+ snprintf(loc, sizeof(loc), " %2.2x@%2.2x:%2.2x:%1.1x",
+ primaryBus.id.pci->bus,
+ primaryBus.id.pci->domain,
+ primaryBus.id.pci->dev,
+ primaryBus.id.pci->func);
+ break;
+ case BUS_SBUS:
+ bus = "SBUS";
+ snprintf(loc, sizeof(loc), " %2.2x", primaryBus.id.sbus.fbNum);
+ break;
+ default:
+ bus = "";
+ loc[0] = '\0';
+ }
+
+ xf86MsgVerb(X_INFO, 2, "Primary Device is: %s%s\n",bus,loc);
+ }
+}
+
+int
+xf86GetLastScrnFlag(int entityIndex)
+{
+ if(entityIndex < xf86NumEntities) {
+ return(xf86Entities[entityIndex]->lastScrnFlag);
+ } else {
+ return -1;
+ }
+}
+
+void
+xf86SetLastScrnFlag(int entityIndex, int scrnIndex)
+{
+ if(entityIndex < xf86NumEntities) {
+ xf86Entities[entityIndex]->lastScrnFlag = scrnIndex;
+ }
+}
+
+Bool
+xf86IsEntityShared(int entityIndex)
+{
+ if(entityIndex < xf86NumEntities) {
+ if(xf86Entities[entityIndex]->entityProp & IS_SHARED_ACCEL) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void
+xf86SetEntityShared(int entityIndex)
+{
+ if(entityIndex < xf86NumEntities) {
+ xf86Entities[entityIndex]->entityProp |= IS_SHARED_ACCEL;
+ }
+}
+
+Bool
+xf86IsEntitySharable(int entityIndex)
+{
+ if(entityIndex < xf86NumEntities) {
+ if(xf86Entities[entityIndex]->entityProp & ACCEL_IS_SHARABLE) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void
+xf86SetEntitySharable(int entityIndex)
+{
+ if(entityIndex < xf86NumEntities) {
+ xf86Entities[entityIndex]->entityProp |= ACCEL_IS_SHARABLE;
+ }
+}
+
+Bool
+xf86IsPrimInitDone(int entityIndex)
+{
+ if(entityIndex < xf86NumEntities) {
+ if(xf86Entities[entityIndex]->entityProp & SA_PRIM_INIT_DONE) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+void
+xf86SetPrimInitDone(int entityIndex)
+{
+ if(entityIndex < xf86NumEntities) {
+ xf86Entities[entityIndex]->entityProp |= SA_PRIM_INIT_DONE;
+ }
+}
+
+void
+xf86ClearPrimInitDone(int entityIndex)
+{
+ if(entityIndex < xf86NumEntities) {
+ xf86Entities[entityIndex]->entityProp &= ~SA_PRIM_INIT_DONE;
+ }
+}
+
+
+/*
+ * Allocate a private in the entities.
+ */
+
+int
+xf86AllocateEntityPrivateIndex(void)
+{
+ int idx, i;
+ EntityPtr pEnt;
+ DevUnion *nprivs;
+
+ idx = xf86EntityPrivateCount++;
+ for (i = 0; i < xf86NumEntities; i++) {
+ pEnt = xf86Entities[i];
+ nprivs = xnfrealloc(pEnt->entityPrivates,
+ xf86EntityPrivateCount * sizeof(DevUnion));
+ /* Zero the new private */
+ bzero(&nprivs[idx], sizeof(DevUnion));
+ pEnt->entityPrivates = nprivs;
+ }
+ return idx;
+}
+
+DevUnion *
+xf86GetEntityPrivate(int entityIndex, int privIndex)
+{
+ if (entityIndex >= xf86NumEntities || privIndex >= xf86EntityPrivateCount)
+ return NULL;
+
+ return &(xf86Entities[entityIndex]->entityPrivates[privIndex]);
+}
+
diff --git a/xorg-server/hw/xfree86/common/xf86Config.c b/xorg-server/hw/xfree86/common/xf86Config.c
index 9a2837e7b..33b38930f 100644
--- a/xorg-server/hw/xfree86/common/xf86Config.c
+++ b/xorg-server/hw/xfree86/common/xf86Config.c
@@ -1,2586 +1,2586 @@
-/*
- * Loosely based on code bearing the following copyright:
- *
- * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
- */
-
-/*
- * Copyright 1992-2003 by The XFree86 Project, Inc.
- * Copyright 1997 by Metro Link, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-/*
- *
- * Authors:
- * Dirk Hohndel <hohndel@XFree86.Org>
- * David Dawes <dawes@XFree86.Org>
- * Marc La France <tsi@XFree86.Org>
- * Egbert Eich <eich@XFree86.Org>
- * ... and others
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#ifdef XF86DRI
-#include <sys/types.h>
-#include <grp.h>
-#endif
-
-#include "xf86.h"
-#include "xf86Parser.h"
-#include "xf86tokens.h"
-#include "xf86Config.h"
-#include "xf86Priv.h"
-#include "xf86_OSlib.h"
-#include "configProcs.h"
-#include "globals.h"
-#include "extension.h"
-#include "Pci.h"
-
-#include "xf86Xinput.h"
-extern DeviceAssocRec mouse_assoc;
-
-#include "xkbsrv.h"
-
-#include "picture.h"
-
-/*
- * These paths define the way the config file search is done. The escape
- * sequences are documented in parser/scan.c.
- */
-#ifndef ROOT_CONFIGPATH
-#define ROOT_CONFIGPATH "%A," "%R," \
- "/etc/X11/%R," "%P/etc/X11/%R," \
- "%E," "%F," \
- "/etc/X11/%F," "%P/etc/X11/%F," \
- "/etc/X11/%X-%M," "/etc/X11/%X," "/etc/%X," \
- "%P/etc/X11/%X.%H," "%P/etc/X11/%X-%M," \
- "%P/etc/X11/%X," \
- "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \
- "%P/lib/X11/%X"
-#endif
-#ifndef USER_CONFIGPATH
-#define USER_CONFIGPATH "/etc/X11/%S," "%P/etc/X11/%S," \
- "/etc/X11/%G," "%P/etc/X11/%G," \
- "/etc/X11/%X-%M," "/etc/X11/%X," "/etc/%X," \
- "%P/etc/X11/%X.%H," "%P/etc/X11/%X-%M," \
- "%P/etc/X11/%X," \
- "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \
- "%P/lib/X11/%X"
-#endif
-#ifndef ROOT_CONFIGDIRPATH
-#define ROOT_CONFIGDIRPATH "%A," "%R," \
- "/etc/X11/%R," "%C/X11/%R," \
- "/etc/X11/%X," "%C/X11/%X"
-#endif
-#ifndef USER_CONFIGDIRPATH
-#define USER_CONFIGDIRPATH "/etc/X11/%R," "%C/X11/%R," \
- "/etc/X11/%X," "%C/X11/%X"
-#endif
-#ifndef SYS_CONFIGDIRPATH
-#define SYS_CONFIGDIRPATH "/usr/share/X11/%X," "%D/X11/%X"
-#endif
-#ifndef PROJECTROOT
-#define PROJECTROOT "/usr/X11R6"
-#endif
-
-static ModuleDefault ModuleDefaults[] = {
- {.name = "extmod", .toLoad = TRUE, .load_opt=NULL},
-#ifdef DBE
- {.name = "dbe", .toLoad = TRUE, .load_opt=NULL},
-#endif
-#ifdef GLXEXT
- {.name = "glx", .toLoad = TRUE, .load_opt=NULL},
-#endif
-#ifdef XRECORD
- {.name = "record", .toLoad = TRUE, .load_opt=NULL},
-#endif
-#ifdef XF86DRI
- {.name = "dri", .toLoad = TRUE, .load_opt=NULL},
-#endif
-#ifdef DRI2
- {.name = "dri2", .toLoad = TRUE, .load_opt=NULL},
-#endif
- {.name = NULL, .toLoad = FALSE, .load_opt=NULL}
-};
-
-
-/* Forward declarations */
-static Bool configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen,
- int scrnum, MessageType from);
-static Bool configMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor);
-static Bool configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device,
- Bool active);
-static Bool configInput(IDevPtr inputp, XF86ConfInputPtr conf_input,
- MessageType from);
-static Bool configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display);
-static Bool addDefaultModes(MonPtr monitorp);
-#ifdef XF86DRI
-static void configDRI(XF86ConfDRIPtr drip);
-#endif
-static void configExtensions(XF86ConfExtensionsPtr conf_ext);
-
-/*
- * xf86GetPathElem --
- * Extract a single element from the font path string starting at
- * pnt. The font path element will be returned, and pnt will be
- * updated to point to the start of the next element, or set to
- * NULL if there are no more.
- */
-static char *
-xf86GetPathElem(char **pnt)
-{
- char *p1;
-
- p1 = *pnt;
- *pnt = index(*pnt, ',');
- if (*pnt != NULL) {
- **pnt = '\0';
- *pnt += 1;
- }
- return(p1);
-}
-
-/*
- * xf86ValidateFontPath --
- * Validates the user-specified font path. Each element that
- * begins with a '/' is checked to make sure the directory exists.
- * If the directory exists, the existence of a file named 'fonts.dir'
- * is checked. If either check fails, an error is printed and the
- * element is removed from the font path.
- */
-
-#define DIR_FILE "/fonts.dir"
-static char *
-xf86ValidateFontPath(char *path)
-{
- char *tmp_path, *out_pnt, *path_elem, *next, *p1, *dir_elem;
- struct stat stat_buf;
- int flag;
- int dirlen;
-
- tmp_path = xcalloc(1,strlen(path)+1);
- out_pnt = tmp_path;
- path_elem = NULL;
- next = path;
- while (next != NULL) {
- path_elem = xf86GetPathElem(&next);
- if (*path_elem == '/') {
- dir_elem = xnfcalloc(1, strlen(path_elem) + 1);
- if ((p1 = strchr(path_elem, ':')) != 0)
- dirlen = p1 - path_elem;
- else
- dirlen = strlen(path_elem);
- strncpy(dir_elem, path_elem, dirlen);
- dir_elem[dirlen] = '\0';
- flag = stat(dir_elem, &stat_buf);
- if (flag == 0)
- if (!S_ISDIR(stat_buf.st_mode))
- flag = -1;
- if (flag != 0) {
- xf86Msg(X_WARNING, "The directory \"%s\" does not exist.\n", dir_elem);
- xf86ErrorF("\tEntry deleted from font path.\n");
- xfree(dir_elem);
- continue;
- }
- else {
- p1 = xnfalloc(strlen(dir_elem)+strlen(DIR_FILE)+1);
- strcpy(p1, dir_elem);
- strcat(p1, DIR_FILE);
- flag = stat(p1, &stat_buf);
- if (flag == 0)
- if (!S_ISREG(stat_buf.st_mode))
- flag = -1;
- xfree(p1);
- if (flag != 0) {
- xf86Msg(X_WARNING,
- "`fonts.dir' not found (or not valid) in \"%s\".\n",
- dir_elem);
- xf86ErrorF("\tEntry deleted from font path.\n");
- xf86ErrorF("\t(Run 'mkfontdir' on \"%s\").\n", dir_elem);
- xfree(dir_elem);
- continue;
- }
- }
- xfree(dir_elem);
- }
-
- /*
- * Either an OK directory, or a font server name. So add it to
- * the path.
- */
- if (out_pnt != tmp_path)
- *out_pnt++ = ',';
- strcat(out_pnt, path_elem);
- out_pnt += strlen(path_elem);
- }
- return(tmp_path);
-}
-
-
-/*
- * use the datastructure that the parser provides and pick out the parts
- * that we need at this point
- */
-char **
-xf86ModulelistFromConfig(pointer **optlist)
-{
- int count = 0, i = 0;
- char **modulearray;
- char *ignore[] = { "GLcore", "speedo", "bitmap", "drm",
- "freetype", "type1",
- NULL };
- pointer *optarray;
- XF86LoadPtr modp;
- Bool found;
-
- /*
- * make sure the config file has been parsed and that we have a
- * ModulePath set; if no ModulePath was given, use the default
- * ModulePath
- */
- if (xf86configptr == NULL) {
- xf86Msg(X_ERROR, "Cannot access global config data structure\n");
- return NULL;
- }
-
- if (xf86configptr->conf_modules) {
- /* Walk the disable list and let people know what we've parsed to
- * not be loaded
- */
- modp = xf86configptr->conf_modules->mod_disable_lst;
- while (modp) {
- xf86Msg(X_WARNING, "\"%s\" will not be loaded unless you've specified it to be loaded elsewhere.\n", modp->load_name);
- modp = (XF86LoadPtr) modp->list.next;
- }
- /*
- * Walk the default settings table. For each module listed to be
- * loaded, make sure it's in the mod_load_lst. If it's not, make
- * sure it's not in the mod_no_load_lst. If it's not disabled,
- * append it to mod_load_lst
- */
- for (i=0 ; ModuleDefaults[i].name != NULL ; i++) {
- if (ModuleDefaults[i].toLoad == FALSE) {
- xf86Msg(X_WARNING, "\"%s\" is not to be loaded by default. Skipping.\n", ModuleDefaults[i].name);
- continue;
- }
- found = FALSE;
- modp = xf86configptr->conf_modules->mod_load_lst;
- while (modp) {
- if (strcmp(modp->load_name, ModuleDefaults[i].name) == 0) {
- xf86Msg(X_INFO, "\"%s\" will be loaded. This was enabled by default and also specified in the config file.\n", ModuleDefaults[i].name);
- found = TRUE;
- break;
- }
- modp = (XF86LoadPtr) modp->list.next;
- }
- if (found == FALSE) {
- modp = xf86configptr->conf_modules->mod_disable_lst;
- while (modp) {
- if (strcmp(modp->load_name, ModuleDefaults[i].name) == 0) {
- xf86Msg(X_INFO, "\"%s\" will be loaded even though the default is to disable it.\n", ModuleDefaults[i].name);
- found = TRUE;
- break;
- }
- modp = (XF86LoadPtr) modp->list.next;
- }
- }
- if (found == FALSE) {
- XF86LoadPtr ptr = (XF86LoadPtr)xf86configptr->conf_modules;
- ptr = xf86addNewLoadDirective(ptr, ModuleDefaults[i].name, XF86_LOAD_MODULE, ModuleDefaults[i].load_opt);
- xf86Msg(X_INFO, "\"%s\" will be loaded by default.\n", ModuleDefaults[i].name);
- }
- }
- } else {
- xf86configptr->conf_modules = xnfcalloc(1, sizeof(XF86ConfModuleRec));
- for (i=0 ; ModuleDefaults[i].name != NULL ; i++) {
- if (ModuleDefaults[i].toLoad == TRUE) {
- XF86LoadPtr ptr = (XF86LoadPtr)xf86configptr->conf_modules;
- ptr = xf86addNewLoadDirective(ptr, ModuleDefaults[i].name, XF86_LOAD_MODULE, ModuleDefaults[i].load_opt);
- }
- }
- }
-
- /*
- * Walk the list of modules in the "Module" section to determine how
- * many we have.
- */
- modp = xf86configptr->conf_modules->mod_load_lst;
- while (modp) {
- for (i = 0; ignore[i]; i++) {
- if (strcmp(modp->load_name, ignore[i]) == 0)
- modp->ignore = 1;
- }
- if (!modp->ignore)
- count++;
- modp = (XF86LoadPtr) modp->list.next;
- }
-
- /*
- * allocate the memory and walk the list again to fill in the pointers
- */
- modulearray = xnfalloc((count + 1) * sizeof(char*));
- optarray = xnfalloc((count + 1) * sizeof(pointer));
- count = 0;
- if (xf86configptr->conf_modules) {
- modp = xf86configptr->conf_modules->mod_load_lst;
- while (modp) {
- if (!modp->ignore) {
- modulearray[count] = modp->load_name;
- optarray[count] = modp->load_opt;
- count++;
- }
- modp = (XF86LoadPtr) modp->list.next;
- }
- }
- modulearray[count] = NULL;
- optarray[count] = NULL;
- if (optlist)
- *optlist = optarray;
- else
- xfree(optarray);
- return modulearray;
-}
-
-
-char **
-xf86DriverlistFromConfig(void)
-{
- int count = 0;
- int j;
- char **modulearray;
- screenLayoutPtr slp;
-
- /*
- * make sure the config file has been parsed and that we have a
- * ModulePath set; if no ModulePath was given, use the default
- * ModulePath
- */
- if (xf86configptr == NULL) {
- xf86Msg(X_ERROR, "Cannot access global config data structure\n");
- return NULL;
- }
-
- /*
- * Walk the list of driver lines in active "Device" sections to
- * determine now many implicitly loaded modules there are.
- *
- */
- if (xf86ConfigLayout.screens) {
- slp = xf86ConfigLayout.screens;
- while ((slp++)->screen) {
- count++;
- }
- }
-
- /*
- * Handle the set of inactive "Device" sections.
- */
- j = 0;
- while (xf86ConfigLayout.inactives[j++].identifier)
- count++;
-
- if (count == 0)
- return NULL;
-
- /*
- * allocate the memory and walk the list again to fill in the pointers
- */
- modulearray = xnfalloc((count + 1) * sizeof(char*));
- count = 0;
- slp = xf86ConfigLayout.screens;
- while (slp->screen) {
- modulearray[count] = slp->screen->device->driver;
- count++;
- slp++;
- }
-
- j = 0;
-
- while (xf86ConfigLayout.inactives[j].identifier)
- modulearray[count++] = xf86ConfigLayout.inactives[j++].driver;
-
- modulearray[count] = NULL;
-
- /* Remove duplicates */
- for (count = 0; modulearray[count] != NULL; count++) {
- int i;
-
- for (i = 0; i < count; i++)
- if (xf86NameCmp(modulearray[i], modulearray[count]) == 0) {
- modulearray[count] = "";
- break;
- }
- }
- return modulearray;
-}
-
-char **
-xf86InputDriverlistFromConfig(void)
-{
- int count = 0;
- char **modulearray;
- IDevPtr* idp;
-
- /*
- * make sure the config file has been parsed and that we have a
- * ModulePath set; if no ModulePath was given, use the default
- * ModulePath
- */
- if (xf86configptr == NULL) {
- xf86Msg(X_ERROR, "Cannot access global config data structure\n");
- return NULL;
- }
-
- /*
- * Walk the list of driver lines in active "InputDevice" sections to
- * determine now many implicitly loaded modules there are.
- */
- if (xf86ConfigLayout.inputs) {
- idp = xf86ConfigLayout.inputs;
- while (*idp) {
- count++;
- idp++;
- }
- }
-
- if (count == 0)
- return NULL;
-
- /*
- * allocate the memory and walk the list again to fill in the pointers
- */
- modulearray = xnfalloc((count + 1) * sizeof(char*));
- count = 0;
- idp = xf86ConfigLayout.inputs;
- while (idp && *idp) {
- modulearray[count] = (*idp)->driver;
- count++;
- idp++;
- }
- modulearray[count] = NULL;
-
- /* Remove duplicates */
- for (count = 0; modulearray[count] != NULL; count++) {
- int i;
-
- for (i = 0; i < count; i++)
- if (xf86NameCmp(modulearray[i], modulearray[count]) == 0) {
- modulearray[count] = "";
- break;
- }
- }
- return modulearray;
-}
-
-static void
-fixup_video_driver_list(char **drivers)
-{
- static const char *fallback[4] = { "vesa", "fbdev", "wsfb", NULL };
- char **end, **drv;
- char *x;
- char **ati, **atimisc;
- int i;
-
- /* walk to the end of the list */
- for (end = drivers; *end && **end; end++) ;
- end--;
-
- /*
- * for each of the fallback drivers, if we find it in the list,
- * swap it with the last available non-fallback driver.
- */
- for (i = 0; fallback[i]; i++) {
- for (drv = drivers; drv != end; drv++) {
- if (strstr(*drv, fallback[i])) {
- x = *drv; *drv = *end; *end = x;
- end--;
- break;
- }
- }
- }
- /*
- * since the ati wrapper driver is gross and awful, sort ati before
- * atimisc, which makes sure all the ati symbols are visible in xorgcfg.
- */
- for (drv = drivers; drv != end; drv++) {
- if (!strcmp(*drv, "atimisc")) {
- atimisc = drv;
- for (drv = atimisc; drv != end; drv++) {
- if (!strcmp(*drv, "ati")) {
- ati = drv;
- x = *ati; *ati = *atimisc; *atimisc = x;
- return;
- }
- }
- /* if we get here, ati was already ahead of atimisc */
- return;
- }
- }
-}
-
-static char **
-GenerateDriverlist(char * dirname)
-{
- char **ret;
- const char *subdirs[] = { dirname, NULL };
- static const char *patlist[] = {"(.*)_drv\\.so", "(.*)_drv\\.o", NULL};
- ret = LoaderListDirs(subdirs, patlist);
-
- /* fix up the probe order for video drivers */
- if (strstr(dirname, "drivers") && ret != NULL)
- fixup_video_driver_list(ret);
-
- return ret;
-}
-
-char **
-xf86DriverlistFromCompile(void)
-{
- static char **driverlist = NULL;
-
- if (!driverlist)
- driverlist = GenerateDriverlist("drivers");
-
- return driverlist;
-}
-
-/*
- * xf86ConfigError --
- * Print a READABLE ErrorMessage!!! All information that is
- * available is printed.
- */
-static void
-xf86ConfigError(char *msg, ...)
-{
- va_list ap;
-
- ErrorF("\nConfig Error:\n");
- va_start(ap, msg);
- VErrorF(msg, ap);
- va_end(ap);
- ErrorF("\n");
- return;
-}
-
-static void
-configFiles(XF86ConfFilesPtr fileconf)
-{
- MessageType pathFrom;
- Bool must_copy;
- int size, countDirs;
- char *temp_path, *log_buf, *start, *end;
-
- /* FontPath */
- must_copy = TRUE;
-
- temp_path = defaultFontPath ? defaultFontPath : "";
- if (xf86fpFlag)
- pathFrom = X_CMDLINE;
- else if (fileconf && fileconf->file_fontpath) {
- pathFrom = X_CONFIG;
- if (xf86Info.useDefaultFontPath) {
- defaultFontPath = Xprintf("%s%s%s",
- fileconf->file_fontpath,
- *temp_path ? "," : "", temp_path);
- if (defaultFontPath != NULL) {
- must_copy = FALSE;
- }
- }
- else
- defaultFontPath = fileconf->file_fontpath;
- }
- else
- pathFrom = X_DEFAULT;
- temp_path = defaultFontPath ? defaultFontPath : "";
-
- /* xf86ValidateFontPath modifies its argument, but returns a copy of it. */
- temp_path = must_copy ? xnfstrdup(defaultFontPath) : defaultFontPath;
- defaultFontPath = xf86ValidateFontPath(temp_path);
- xfree(temp_path);
-
- /* make fontpath more readable in the logfiles */
- countDirs = 1;
- temp_path = defaultFontPath;
- while ((temp_path = index(temp_path, ',')) != NULL) {
- countDirs++;
- temp_path++;
- }
-
- log_buf = xnfalloc(strlen(defaultFontPath) + (2 * countDirs) + 1);
- temp_path = log_buf;
- start = defaultFontPath;
- while((end = index(start, ',')) != NULL) {
- size = (end - start) + 1;
- *(temp_path++) = '\t';
- strncpy(temp_path, start, size);
- temp_path += size;
- *(temp_path++) = '\n';
- start += size;
- }
- /* copy last entry */
- *(temp_path++) = '\t';
- strcpy(temp_path, start);
- xf86Msg(pathFrom, "FontPath set to:\n%s\n", log_buf);
- xfree(log_buf);
-
- /* ModulePath */
-
- if (fileconf) {
- if (xf86ModPathFrom != X_CMDLINE && fileconf->file_modulepath) {
- xf86ModulePath = fileconf->file_modulepath;
- xf86ModPathFrom = X_CONFIG;
- }
- }
-
- xf86Msg(xf86ModPathFrom, "ModulePath set to \"%s\"\n", xf86ModulePath);
-
- if (!xf86xkbdirFlag && fileconf && fileconf->file_xkbdir) {
- XkbBaseDirectory = fileconf->file_xkbdir;
- xf86Msg(X_CONFIG, "XKB base directory set to \"%s\"\n",
- XkbBaseDirectory);
- }
-#if 0
- /* LogFile */
- /*
- * XXX The problem with this is that the log file is already open.
- * One option might be to copy the exiting contents to the new location.
- * and re-open it. The down side is that the default location would
- * already have been overwritten. Another option would be to start with
- * unique temporary location, then copy it once the correct name is known.
- * A problem with this is what happens if the server exits before that
- * happens.
- */
- if (xf86LogFileFrom == X_DEFAULT && fileconf->file_logfile) {
- xf86LogFile = fileconf->file_logfile;
- xf86LogFileFrom = X_CONFIG;
- }
-#endif
-
- return;
-}
-
-typedef enum {
- FLAG_NOTRAPSIGNALS,
- FLAG_DONTVTSWITCH,
- FLAG_DONTZAP,
- FLAG_DONTZOOM,
- FLAG_DISABLEVIDMODE,
- FLAG_ALLOWNONLOCAL,
- FLAG_ALLOWMOUSEOPENFAIL,
- FLAG_VTSYSREQ,
- FLAG_SAVER_BLANKTIME,
- FLAG_DPMS_STANDBYTIME,
- FLAG_DPMS_SUSPENDTIME,
- FLAG_DPMS_OFFTIME,
- FLAG_PIXMAP,
- FLAG_PC98,
- FLAG_NOPM,
- FLAG_XINERAMA,
- FLAG_LOG,
- FLAG_RENDER_COLORMAP_MODE,
- FLAG_RANDR,
- FLAG_AIGLX,
- FLAG_IGNORE_ABI,
- FLAG_ALLOW_EMPTY_INPUT,
- FLAG_USE_DEFAULT_FONT_PATH,
- FLAG_AUTO_ADD_DEVICES,
- FLAG_AUTO_ENABLE_DEVICES,
- FLAG_GLX_VISUALS,
- FLAG_DRI2,
- FLAG_USE_SIGIO
-} FlagValues;
-
-/**
- * NOTE: the last value for each entry is NOT the default. It is set to TRUE
- * if the parser found the option in the config file.
- */
-static OptionInfoRec FlagOptions[] = {
- { FLAG_NOTRAPSIGNALS, "NoTrapSignals", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_DONTVTSWITCH, "DontVTSwitch", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_DONTZAP, "DontZap", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_DONTZOOM, "DontZoom", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_DISABLEVIDMODE, "DisableVidModeExtension", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_ALLOWNONLOCAL, "AllowNonLocalXvidtune", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_ALLOWMOUSEOPENFAIL, "AllowMouseOpenFail", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_VTSYSREQ, "VTSysReq", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_SAVER_BLANKTIME, "BlankTime" , OPTV_INTEGER,
- {0}, FALSE },
- { FLAG_DPMS_STANDBYTIME, "StandbyTime", OPTV_INTEGER,
- {0}, FALSE },
- { FLAG_DPMS_SUSPENDTIME, "SuspendTime", OPTV_INTEGER,
- {0}, FALSE },
- { FLAG_DPMS_OFFTIME, "OffTime", OPTV_INTEGER,
- {0}, FALSE },
- { FLAG_PIXMAP, "Pixmap", OPTV_INTEGER,
- {0}, FALSE },
- { FLAG_PC98, "PC98", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_NOPM, "NoPM", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_XINERAMA, "Xinerama", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_LOG, "Log", OPTV_STRING,
- {0}, FALSE },
- { FLAG_RENDER_COLORMAP_MODE, "RenderColormapMode", OPTV_STRING,
- {0}, FALSE },
- { FLAG_RANDR, "RandR", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_AIGLX, "AIGLX", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_ALLOW_EMPTY_INPUT, "AllowEmptyInput", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_IGNORE_ABI, "IgnoreABI", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_USE_DEFAULT_FONT_PATH, "UseDefaultFontPath", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_AUTO_ADD_DEVICES, "AutoAddDevices", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_AUTO_ENABLE_DEVICES, "AutoEnableDevices", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_GLX_VISUALS, "GlxVisuals", OPTV_STRING,
- {0}, FALSE },
- { FLAG_DRI2, "DRI2", OPTV_BOOLEAN,
- {0}, FALSE },
- { FLAG_USE_SIGIO, "UseSIGIO", OPTV_BOOLEAN,
- {0}, FALSE },
- { -1, NULL, OPTV_NONE,
- {0}, FALSE },
-};
-
-#ifdef SUPPORT_PC98
-static Bool
-detectPC98(void)
-{
- unsigned char buf[2];
-
- if (xf86ReadBIOS(0xf8000, 0xe80, buf, 2) != 2)
- return FALSE;
- if ((buf[0] == 0x98) && (buf[1] == 0x21))
- return TRUE;
- else
- return FALSE;
-}
-#endif
-
-static Bool
-configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
-{
- XF86OptionPtr optp, tmp;
- int i;
- Pix24Flags pix24 = Pix24DontCare;
- Bool value;
- MessageType from;
- const char *s;
- XkbRMLVOSet set;
- /* Default options. */
- set.rules = "base";
- set.model = "pc105";
- set.layout = "us";
- set.variant = NULL;
- set.options = NULL;
-
- /*
- * Merge the ServerLayout and ServerFlags options. The former have
- * precedence over the latter.
- */
- optp = NULL;
- if (flagsconf && flagsconf->flg_option_lst)
- optp = xf86optionListDup(flagsconf->flg_option_lst);
- if (layoutopts) {
- tmp = xf86optionListDup(layoutopts);
- if (optp)
- optp = xf86optionListMerge(optp, tmp);
- else
- optp = tmp;
- }
-
- xf86ProcessOptions(-1, optp, FlagOptions);
-
- xf86GetOptValBool(FlagOptions, FLAG_NOTRAPSIGNALS, &xf86Info.notrapSignals);
- xf86GetOptValBool(FlagOptions, FLAG_DONTVTSWITCH, &xf86Info.dontVTSwitch);
- xf86GetOptValBool(FlagOptions, FLAG_DONTZAP, &xf86Info.dontZap);
- xf86GetOptValBool(FlagOptions, FLAG_DONTZOOM, &xf86Info.dontZoom);
-
- xf86GetOptValBool(FlagOptions, FLAG_IGNORE_ABI, &xf86Info.ignoreABI);
- if (xf86Info.ignoreABI) {
- xf86Msg(X_CONFIG, "Ignoring ABI Version\n");
- }
-
- if (xf86SIGIOSupported()) {
- xf86Info.useSIGIO = xf86ReturnOptValBool(FlagOptions, FLAG_USE_SIGIO, USE_SIGIO_BY_DEFAULT);
- if (xf86IsOptionSet(FlagOptions, FLAG_USE_SIGIO)) {
- from = X_CONFIG;
- } else {
- from = X_DEFAULT;
- }
- if (!xf86Info.useSIGIO) {
- xf86Msg(from, "Disabling SIGIO handlers for input devices\n");
- } else if (from == X_CONFIG) {
- xf86Msg(from, "Enabling SIGIO handlers for input devices\n");
- }
- } else {
- xf86Info.useSIGIO = FALSE;
- }
-
- if (xf86IsOptionSet(FlagOptions, FLAG_AUTO_ADD_DEVICES)) {
- xf86GetOptValBool(FlagOptions, FLAG_AUTO_ADD_DEVICES,
- &xf86Info.autoAddDevices);
- from = X_CONFIG;
- }
- else {
- from = X_DEFAULT;
- }
- xf86Msg(from, "%sutomatically adding devices\n",
- xf86Info.autoAddDevices ? "A" : "Not a");
-
- if (xf86IsOptionSet(FlagOptions, FLAG_AUTO_ENABLE_DEVICES)) {
- xf86GetOptValBool(FlagOptions, FLAG_AUTO_ENABLE_DEVICES,
- &xf86Info.autoEnableDevices);
- from = X_CONFIG;
- }
- else {
- from = X_DEFAULT;
- }
- xf86Msg(from, "%sutomatically enabling devices\n",
- xf86Info.autoEnableDevices ? "A" : "Not a");
-
- /*
- * Set things up based on the config file information. Some of these
- * settings may be overridden later when the command line options are
- * checked.
- */
-#ifdef XF86VIDMODE
- if (xf86GetOptValBool(FlagOptions, FLAG_DISABLEVIDMODE, &value))
- xf86Info.vidModeEnabled = !value;
- if (xf86GetOptValBool(FlagOptions, FLAG_ALLOWNONLOCAL, &value))
- xf86Info.vidModeAllowNonLocal = value;
-#endif
-
- if (xf86GetOptValBool(FlagOptions, FLAG_ALLOWMOUSEOPENFAIL, &value))
- xf86Info.allowMouseOpenFail = value;
-
- if (xf86GetOptValBool(FlagOptions, FLAG_VTSYSREQ, &value)) {
-#ifdef USE_VT_SYSREQ
- xf86Info.vtSysreq = value;
- xf86Msg(X_CONFIG, "VTSysReq %s\n", value ? "enabled" : "disabled");
-#else
- if (value)
- xf86Msg(X_WARNING, "VTSysReq is not supported on this OS\n");
-#endif
- }
-
- xf86Info.pmFlag = TRUE;
- if (xf86GetOptValBool(FlagOptions, FLAG_NOPM, &value))
- xf86Info.pmFlag = !value;
- {
- if ((s = xf86GetOptValString(FlagOptions, FLAG_LOG))) {
- if (!xf86NameCmp(s,"flush")) {
- xf86Msg(X_CONFIG, "Flushing logfile enabled\n");
- xf86Info.log = LogFlush;
- LogSetParameter(XLOG_FLUSH, TRUE);
- } else if (!xf86NameCmp(s,"sync")) {
- xf86Msg(X_CONFIG, "Syncing logfile enabled\n");
- xf86Info.log = LogSync;
- LogSetParameter(XLOG_FLUSH, TRUE);
- LogSetParameter(XLOG_SYNC, TRUE);
- } else {
- xf86Msg(X_WARNING,"Unknown Log option\n");
- }
- }
- }
-
- {
- if ((s = xf86GetOptValString(FlagOptions, FLAG_RENDER_COLORMAP_MODE))){
- int policy = PictureParseCmapPolicy (s);
- if (policy == PictureCmapPolicyInvalid)
- xf86Msg(X_WARNING, "Unknown colormap policy \"%s\"\n", s);
- else
- {
- xf86Msg(X_CONFIG, "Render colormap policy set to %s\n", s);
- PictureCmapPolicy = policy;
- }
- }
- }
-
-#ifdef RANDR
- xf86Info.disableRandR = FALSE;
- xf86Info.randRFrom = X_DEFAULT;
- if (xf86GetOptValBool(FlagOptions, FLAG_RANDR, &value)) {
- xf86Info.disableRandR = !value;
- xf86Info.randRFrom = X_CONFIG;
- }
-#endif
-
- xf86Info.aiglx = TRUE;
- xf86Info.aiglxFrom = X_DEFAULT;
- if (xf86GetOptValBool(FlagOptions, FLAG_AIGLX, &value)) {
- xf86Info.aiglx = value;
- xf86Info.aiglxFrom = X_CONFIG;
- }
-
-#ifdef GLXEXT
- xf86Info.glxVisuals = XF86_GlxVisualsTypical;
- xf86Info.glxVisualsFrom = X_DEFAULT;
- if ((s = xf86GetOptValString(FlagOptions, FLAG_GLX_VISUALS))) {
- if (!xf86NameCmp(s, "minimal")) {
- xf86Info.glxVisuals = XF86_GlxVisualsMinimal;
- } else if (!xf86NameCmp(s, "typical")) {
- xf86Info.glxVisuals = XF86_GlxVisualsTypical;
- } else if (!xf86NameCmp(s, "all")) {
- xf86Info.glxVisuals = XF86_GlxVisualsAll;
- } else {
- xf86Msg(X_WARNING,"Unknown GlxVisuals option\n");
- }
- }
-
- if (xf86GetOptValBool(FlagOptions, FLAG_AIGLX, &value)) {
- xf86Info.aiglx = value;
- xf86Info.aiglxFrom = X_CONFIG;
- }
-#endif
-
- /* AllowEmptyInput is automatically true if we're hotplugging */
- xf86Info.allowEmptyInput = (xf86Info.autoAddDevices && xf86Info.autoEnableDevices);
- xf86GetOptValBool(FlagOptions, FLAG_ALLOW_EMPTY_INPUT, &xf86Info.allowEmptyInput);
-
- /* AEI on? Then we're not using kbd, so use the evdev rules set. */
-#if defined(linux)
- if (xf86Info.allowEmptyInput)
- set.rules = "evdev";
-#endif
- XkbSetRulesDflts(&set);
-
- xf86Info.useDefaultFontPath = TRUE;
- xf86Info.useDefaultFontPathFrom = X_DEFAULT;
- if (xf86GetOptValBool(FlagOptions, FLAG_USE_DEFAULT_FONT_PATH, &value)) {
- xf86Info.useDefaultFontPath = value;
- xf86Info.useDefaultFontPathFrom = X_CONFIG;
- }
-
-/* Make sure that timers don't overflow CARD32's after multiplying */
-#define MAX_TIME_IN_MIN (0x7fffffff / MILLI_PER_MIN)
-
- i = -1;
- xf86GetOptValInteger(FlagOptions, FLAG_SAVER_BLANKTIME, &i);
- if ((i >= 0) && (i < MAX_TIME_IN_MIN))
- ScreenSaverTime = defaultScreenSaverTime = i * MILLI_PER_MIN;
- else if (i != -1)
- xf86ConfigError("BlankTime value %d outside legal range of 0 - %d minutes",
- i, MAX_TIME_IN_MIN);
-
-#ifdef DPMSExtension
- i = -1;
- xf86GetOptValInteger(FlagOptions, FLAG_DPMS_STANDBYTIME, &i);
- if ((i >= 0) && (i < MAX_TIME_IN_MIN))
- DPMSStandbyTime = i * MILLI_PER_MIN;
- else if (i != -1)
- xf86ConfigError("StandbyTime value %d outside legal range of 0 - %d minutes",
- i, MAX_TIME_IN_MIN);
- i = -1;
- xf86GetOptValInteger(FlagOptions, FLAG_DPMS_SUSPENDTIME, &i);
- if ((i >= 0) && (i < MAX_TIME_IN_MIN))
- DPMSSuspendTime = i * MILLI_PER_MIN;
- else if (i != -1)
- xf86ConfigError("SuspendTime value %d outside legal range of 0 - %d minutes",
- i, MAX_TIME_IN_MIN);
- i = -1;
- xf86GetOptValInteger(FlagOptions, FLAG_DPMS_OFFTIME, &i);
- if ((i >= 0) && (i < MAX_TIME_IN_MIN))
- DPMSOffTime = i * MILLI_PER_MIN;
- else if (i != -1)
- xf86ConfigError("OffTime value %d outside legal range of 0 - %d minutes",
- i, MAX_TIME_IN_MIN);
-#endif
-
- i = -1;
- xf86GetOptValInteger(FlagOptions, FLAG_PIXMAP, &i);
- switch (i) {
- case 24:
- pix24 = Pix24Use24;
- break;
- case 32:
- pix24 = Pix24Use32;
- break;
- case -1:
- break;
- default:
- xf86ConfigError("Pixmap option's value (%d) must be 24 or 32\n", i);
- return FALSE;
- }
- if (xf86Pix24 != Pix24DontCare) {
- xf86Info.pixmap24 = xf86Pix24;
- xf86Info.pix24From = X_CMDLINE;
- } else if (pix24 != Pix24DontCare) {
- xf86Info.pixmap24 = pix24;
- xf86Info.pix24From = X_CONFIG;
- } else {
- xf86Info.pixmap24 = Pix24DontCare;
- xf86Info.pix24From = X_DEFAULT;
- }
-#ifdef SUPPORT_PC98
- if (xf86GetOptValBool(FlagOptions, FLAG_PC98, &value)) {
- xf86Info.pc98 = value;
- if (value) {
- xf86Msg(X_CONFIG, "Japanese PC98 architecture\n");
- }
- } else
- if (detectPC98()) {
- xf86Info.pc98 = TRUE;
- xf86Msg(X_PROBED, "Japanese PC98 architecture\n");
- }
-#endif
-
-#ifdef PANORAMIX
- from = X_DEFAULT;
- if (!noPanoramiXExtension)
- from = X_CMDLINE;
- else if (xf86GetOptValBool(FlagOptions, FLAG_XINERAMA, &value)) {
- noPanoramiXExtension = !value;
- from = X_CONFIG;
- }
- if (!noPanoramiXExtension)
- xf86Msg(from, "Xinerama: enabled\n");
-#endif
-
-#ifdef DRI2
- xf86Info.dri2 = FALSE;
- xf86Info.dri2From = X_DEFAULT;
- if (xf86GetOptValBool(FlagOptions, FLAG_DRI2, &value)) {
- xf86Info.dri2 = value;
- xf86Info.dri2From = X_CONFIG;
- }
-#endif
-
- return TRUE;
-}
-
-Bool xf86DRI2Enabled(void)
-{
- return xf86Info.dri2;
-}
-
-/*
- * Locate the core input devices. These can be specified/located in
- * the following ways, in order of priority:
- *
- * 1. The InputDevices named by the -pointer and -keyboard command line
- * options.
- * 2. The "CorePointer" and "CoreKeyboard" InputDevices referred to by
- * the active ServerLayout.
- * 3. The first InputDevices marked as "CorePointer" and "CoreKeyboard".
- * 4. The first InputDevices that use 'keyboard' or 'kbd' and a valid mouse
- * driver (mouse, synaptics, evdev, vmmouse, void)
- * 5. Default devices with an empty (default) configuration. These defaults
- * will reference the 'mouse' and 'keyboard' drivers.
- */
-
-static Bool
-checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout)
-{
- IDevPtr corePointer = NULL, coreKeyboard = NULL;
- Bool foundPointer = FALSE, foundKeyboard = FALSE;
- const char *pointerMsg = NULL, *keyboardMsg = NULL;
- IDevPtr *devs, /* iterator */
- indp;
- IDevRec Pointer, Keyboard;
- XF86ConfInputPtr confInput;
- XF86ConfInputRec defPtr, defKbd;
- int count = 0;
- MessageType from = X_DEFAULT;
- int found = 0;
- const char *mousedrivers[] = { "mouse", "synaptics", "evdev", "vmmouse",
- "void", NULL };
-
- /*
- * First check if a core pointer or core keyboard have been specified
- * in the active ServerLayout. If more than one is specified for either,
- * remove the core attribute from the later ones.
- */
- for (devs = servlayoutp->inputs; devs && *devs; devs++) {
- pointer opt1 = NULL, opt2 = NULL;
- indp = *devs;
- if (indp->commonOptions &&
- xf86CheckBoolOption(indp->commonOptions, "CorePointer", FALSE)) {
- opt1 = indp->commonOptions;
- }
- if (indp->extraOptions &&
- xf86CheckBoolOption(indp->extraOptions, "CorePointer", FALSE)) {
- opt2 = indp->extraOptions;
- }
- if (opt1 || opt2) {
- if (!corePointer) {
- corePointer = indp;
- } else {
- if (opt1)
- xf86ReplaceBoolOption(opt1, "CorePointer", FALSE);
- if (opt2)
- xf86ReplaceBoolOption(opt2, "CorePointer", FALSE);
- xf86Msg(X_WARNING, "Duplicate core pointer devices. "
- "Removing core pointer attribute from \"%s\"\n",
- indp->identifier);
- }
- }
- opt1 = opt2 = NULL;
- if (indp->commonOptions &&
- xf86CheckBoolOption(indp->commonOptions, "CoreKeyboard", FALSE)) {
- opt1 = indp->commonOptions;
- }
- if (indp->extraOptions &&
- xf86CheckBoolOption(indp->extraOptions, "CoreKeyboard", FALSE)) {
- opt2 = indp->extraOptions;
- }
- if (opt1 || opt2) {
- if (!coreKeyboard) {
- coreKeyboard = indp;
- } else {
- if (opt1)
- xf86ReplaceBoolOption(opt1, "CoreKeyboard", FALSE);
- if (opt2)
- xf86ReplaceBoolOption(opt2, "CoreKeyboard", FALSE);
- xf86Msg(X_WARNING, "Duplicate core keyboard devices. "
- "Removing core keyboard attribute from \"%s\"\n",
- indp->identifier);
- }
- }
- count++;
- }
-
- confInput = NULL;
-
- /* 1. Check for the -pointer command line option. */
- if (xf86PointerName) {
- confInput = xf86findInput(xf86PointerName,
- xf86configptr->conf_input_lst);
- if (!confInput) {
- xf86Msg(X_ERROR, "No InputDevice section called \"%s\"\n",
- xf86PointerName);
- return FALSE;
- }
- from = X_CMDLINE;
- /*
- * If one was already specified in the ServerLayout, it needs to be
- * removed.
- */
- if (corePointer) {
- for (devs = servlayoutp->inputs; devs && *devs; devs++)
- if (*devs == corePointer)
- {
- xfree(*devs);
- *devs = (IDevPtr)0x1; /* ensure we dont skip next loop*/
- break;
- }
- for (; devs && *devs; devs++)
- devs[0] = devs[1];
- count--;
- }
- corePointer = NULL;
- foundPointer = TRUE;
- }
-
- /* 2. ServerLayout-specified core pointer. */
- if (corePointer) {
- foundPointer = TRUE;
- from = X_CONFIG;
- }
-
- /* 3. First core pointer device. */
- if (!foundPointer && (!xf86Info.allowEmptyInput || implicitLayout)) {
- XF86ConfInputPtr p;
-
- for (p = xf86configptr->conf_input_lst; p; p = p->list.next) {
- if (p->inp_option_lst &&
- xf86CheckBoolOption(p->inp_option_lst, "CorePointer", FALSE)) {
- confInput = p;
- foundPointer = TRUE;
- from = X_DEFAULT;
- pointerMsg = "first core pointer device";
- break;
- }
- }
- }
-
- /* 4. First pointer with an allowed mouse driver. */
- if (!foundPointer && !xf86Info.allowEmptyInput) {
- const char **driver = mousedrivers;
- confInput = xf86findInput(CONF_IMPLICIT_POINTER,
- xf86configptr->conf_input_lst);
- while (*driver && !confInput) {
- confInput = xf86findInputByDriver(*driver,
- xf86configptr->conf_input_lst);
- driver++;
- }
- if (confInput) {
- foundPointer = TRUE;
- from = X_DEFAULT;
- pointerMsg = "first mouse device";
- }
- }
-
- /* 5. Built-in default. */
- if (!foundPointer && !xf86Info.allowEmptyInput) {
- bzero(&defPtr, sizeof(defPtr));
- defPtr.inp_identifier = strdup("<default pointer>");
- defPtr.inp_driver = strdup("mouse");
- confInput = &defPtr;
- foundPointer = TRUE;
- from = X_DEFAULT;
- pointerMsg = "default mouse configuration";
- }
-
- /* Add the core pointer device to the layout, and set it to Core. */
- if (foundPointer && confInput) {
- foundPointer = configInput(&Pointer, confInput, from);
- if (foundPointer) {
- count++;
- devs = xnfrealloc(servlayoutp->inputs,
- (count + 1) * sizeof(IDevPtr));
- devs[count - 1] = xnfalloc(sizeof(IDevRec));
- *devs[count - 1] = Pointer;
- devs[count - 1]->extraOptions =
- xf86addNewOption(NULL, xnfstrdup("CorePointer"), NULL);
- devs[count] = NULL;
- servlayoutp->inputs = devs;
- }
- }
-
- if (!foundPointer && !xf86Info.allowEmptyInput) {
- /* This shouldn't happen. */
- xf86Msg(X_ERROR, "Cannot locate a core pointer device.\n");
- return FALSE;
- }
-
- /*
- * always synthesize a 'mouse' section configured to send core
- * events, unless a 'void' section is found, in which case the user
- * probably wants to run footless.
- *
- * If you're using an evdev keyboard and expect a default mouse
- * section ... deal.
- */
- for (devs = servlayoutp->inputs; devs && *devs; devs++) {
- const char **driver = mousedrivers;
- while(*driver) {
- if (!strcmp((*devs)->driver, *driver)) {
- found = 1;
- break;
- }
- driver++;
- }
- }
- if (!found && !xf86Info.allowEmptyInput) {
- xf86Msg(X_INFO, "No default mouse found, adding one\n");
- bzero(&defPtr, sizeof(defPtr));
- defPtr.inp_identifier = strdup("<default pointer>");
- defPtr.inp_driver = strdup("mouse");
- confInput = &defPtr;
- foundPointer = configInput(&Pointer, confInput, from);
- if (foundPointer) {
- count++;
- devs = xnfrealloc(servlayoutp->inputs,
- (count + 1) * sizeof(IDevPtr));
- devs[count - 1] = xnfalloc(sizeof(IDevRec));
- *devs[count - 1] = Pointer;
- devs[count - 1]->extraOptions =
- xf86addNewOption(NULL, xnfstrdup("AlwaysCore"), NULL);
- devs[count] = NULL;
- servlayoutp->inputs = devs;
- }
- }
-
- confInput = NULL;
-
- /* 1. Check for the -keyboard command line option. */
- if (xf86KeyboardName) {
- confInput = xf86findInput(xf86KeyboardName,
- xf86configptr->conf_input_lst);
- if (!confInput) {
- xf86Msg(X_ERROR, "No InputDevice section called \"%s\"\n",
- xf86KeyboardName);
- return FALSE;
- }
- from = X_CMDLINE;
- /*
- * If one was already specified in the ServerLayout, it needs to be
- * removed.
- */
- if (coreKeyboard) {
- for (devs = servlayoutp->inputs; devs && *devs; devs++)
- if (*devs == coreKeyboard)
- {
- xfree(*devs);
- *devs = (IDevPtr)0x1; /* ensure we dont skip next loop */
- break;
- }
- for (; devs && *devs; devs++)
- devs[0] = devs[1];
- count--;
- }
- coreKeyboard = NULL;
- foundKeyboard = TRUE;
- }
-
- /* 2. ServerLayout-specified core keyboard. */
- if (coreKeyboard) {
- foundKeyboard = TRUE;
- from = X_CONFIG;
- }
-
- /* 3. First core keyboard device. */
- if (!foundKeyboard && (!xf86Info.allowEmptyInput || implicitLayout)) {
- XF86ConfInputPtr p;
-
- for (p = xf86configptr->conf_input_lst; p; p = p->list.next) {
- if (p->inp_option_lst &&
- xf86CheckBoolOption(p->inp_option_lst, "CoreKeyboard", FALSE)) {
- confInput = p;
- foundKeyboard = TRUE;
- from = X_DEFAULT;
- keyboardMsg = "first core keyboard device";
- break;
- }
- }
- }
-
- /* 4. First keyboard with 'keyboard' or 'kbd' as the driver. */
- if (!foundKeyboard && !xf86Info.allowEmptyInput) {
- confInput = xf86findInput(CONF_IMPLICIT_KEYBOARD,
- xf86configptr->conf_input_lst);
- if (!confInput) {
- confInput = xf86findInputByDriver("kbd",
- xf86configptr->conf_input_lst);
- }
- if (confInput) {
- foundKeyboard = TRUE;
- from = X_DEFAULT;
- keyboardMsg = "first keyboard device";
- }
- }
-
- /* 5. Built-in default. */
- if (!foundKeyboard && !xf86Info.allowEmptyInput) {
- bzero(&defKbd, sizeof(defKbd));
- defKbd.inp_identifier = strdup("<default keyboard>");
- defKbd.inp_driver = strdup("kbd");
- confInput = &defKbd;
- foundKeyboard = TRUE;
- keyboardMsg = "default keyboard configuration";
- from = X_DEFAULT;
- }
-
- /* Add the core keyboard device to the layout, and set it to Core. */
- if (foundKeyboard && confInput) {
- foundKeyboard = configInput(&Keyboard, confInput, from);
- if (foundKeyboard) {
- count++;
- devs = xnfrealloc(servlayoutp->inputs,
- (count + 1) * sizeof(IDevPtr));
- devs[count - 1] = xnfalloc(sizeof(IDevRec));
- *devs[count - 1] = Keyboard;
- devs[count - 1]->extraOptions =
- xf86addNewOption(NULL, xnfstrdup("CoreKeyboard"), NULL);
- devs[count] = NULL;
- servlayoutp->inputs = devs;
- }
- }
-
- if (!foundKeyboard && !xf86Info.allowEmptyInput) {
- /* This shouldn't happen. */
- xf86Msg(X_ERROR, "Cannot locate a core keyboard device.\n");
- return FALSE;
- }
-
- if (pointerMsg) {
- if (implicitLayout)
- xf86Msg(X_DEFAULT, "No Layout section. Using the %s.\n",
- pointerMsg);
- else
- xf86Msg(X_DEFAULT, "The core pointer device wasn't specified "
- "explicitly in the layout.\n"
- "\tUsing the %s.\n", pointerMsg);
- }
-
- if (keyboardMsg) {
- if (implicitLayout)
- xf86Msg(X_DEFAULT, "No Layout section. Using the %s.\n",
- keyboardMsg);
- else
- xf86Msg(X_DEFAULT, "The core keyboard device wasn't specified "
- "explicitly in the layout.\n"
- "\tUsing the %s.\n", keyboardMsg);
- }
-
- if (xf86Info.allowEmptyInput && !(foundPointer && foundKeyboard)) {
-#if defined(CONFIG_HAL) || defined(CONFIG_UDEV)
- const char *config_backend;
-#if defined(CONFIG_HAL)
- config_backend = "HAL";
-#else
- config_backend = "udev";
-#endif
- xf86Msg(X_INFO, "The server relies on %s to provide the list of "
- "input devices.\n\tIf no devices become available, "
- "reconfigure %s or disable AutoAddDevices.\n",
- config_backend, config_backend);
-#else
- xf86Msg(X_INFO, "Hotplugging is disabled and no input devices were configured.\n"
- "\tTry disabling AllowEmptyInput.\n");
-#endif
- }
-
- return TRUE;
-}
-
-typedef enum {
- LAYOUT_ISOLATEDEVICE,
- LAYOUT_SINGLECARD
-} LayoutValues;
-
-static OptionInfoRec LayoutOptions[] = {
- { LAYOUT_ISOLATEDEVICE, "IsolateDevice", OPTV_STRING,
- {0}, FALSE },
- { LAYOUT_SINGLECARD, "SingleCard", OPTV_BOOLEAN,
- {0}, FALSE },
- { -1, NULL, OPTV_NONE,
- {0}, FALSE },
-};
-
-static Bool
-configInputDevices(XF86ConfLayoutPtr layout, serverLayoutPtr servlayoutp)
-{
- XF86ConfInputrefPtr irp;
- IDevPtr *indp;
- int count = 0;
-
- /*
- * Count the number of input devices.
- */
- irp = layout->lay_input_lst;
- while (irp) {
- count++;
- irp = (XF86ConfInputrefPtr)irp->list.next;
- }
- DebugF("Found %d input devices in the layout section %s\n",
- count, layout->lay_identifier);
- indp = xnfcalloc((count + 1), sizeof(IDevPtr));
- indp[count] = NULL;
- irp = layout->lay_input_lst;
- count = 0;
- while (irp) {
- indp[count] = xnfalloc(sizeof(IDevRec));
- if (!configInput(indp[count], irp->iref_inputdev, X_CONFIG)) {
- while(count--)
- xfree(indp[count]);
- xfree(indp);
- return FALSE;
- }
- indp[count]->extraOptions = irp->iref_option_lst;
- count++;
- irp = (XF86ConfInputrefPtr)irp->list.next;
- }
- servlayoutp->inputs = indp;
-
- return TRUE;
-}
-
-
-/*
- * figure out which layout is active, which screens are used in that layout,
- * which drivers and monitors are used in these screens
- */
-static Bool
-configLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout,
- char *default_layout)
-{
- XF86ConfAdjacencyPtr adjp;
- XF86ConfInactivePtr idp;
- int count = 0;
- int scrnum;
- XF86ConfLayoutPtr l;
- MessageType from;
- screenLayoutPtr slp;
- GDevPtr gdp;
- int i = 0, j;
-
- if (!servlayoutp)
- return FALSE;
-
- /*
- * which layout section is the active one?
- *
- * If there is a -layout command line option, use that one, otherwise
- * pick the first one.
- */
- from = X_DEFAULT;
- if (xf86LayoutName != NULL)
- from = X_CMDLINE;
- else if (default_layout) {
- xf86LayoutName = default_layout;
- from = X_CONFIG;
- }
- if (xf86LayoutName != NULL) {
- if ((l = xf86findLayout(xf86LayoutName, conf_layout)) == NULL) {
- xf86Msg(X_ERROR, "No ServerLayout section called \"%s\"\n",
- xf86LayoutName);
- return FALSE;
- }
- conf_layout = l;
- }
- xf86Msg(from, "ServerLayout \"%s\"\n", conf_layout->lay_identifier);
- adjp = conf_layout->lay_adjacency_lst;
-
- /*
- * we know that each screen is referenced exactly once on the left side
- * of a layout statement in the Layout section. So to allocate the right
- * size for the array we do a quick walk of the list to figure out how
- * many sections we have
- */
- while (adjp) {
- count++;
- adjp = (XF86ConfAdjacencyPtr)adjp->list.next;
- }
-
- DebugF("Found %d screens in the layout section %s",
- count, conf_layout->lay_identifier);
- if (!count) /* alloc enough storage even if no screen is specified */
- count = 1;
-
- slp = xnfcalloc(1, (count + 1) * sizeof(screenLayoutRec));
- slp[count].screen = NULL;
- /*
- * now that we have storage, loop over the list again and fill in our
- * data structure; at this point we do not fill in the adjacency
- * information as it is not clear if we need it at all
- */
- adjp = conf_layout->lay_adjacency_lst;
- count = 0;
- while (adjp) {
- slp[count].screen = xnfcalloc(1, sizeof(confScreenRec));
- if (adjp->adj_scrnum < 0)
- scrnum = count;
- else
- scrnum = adjp->adj_scrnum;
- if (!configScreen(slp[count].screen, adjp->adj_screen, scrnum,
- X_CONFIG)) {
- xfree(slp);
- return FALSE;
- }
- slp[count].x = adjp->adj_x;
- slp[count].y = adjp->adj_y;
- slp[count].refname = adjp->adj_refscreen;
- switch (adjp->adj_where) {
- case CONF_ADJ_OBSOLETE:
- slp[count].where = PosObsolete;
- slp[count].topname = adjp->adj_top_str;
- slp[count].bottomname = adjp->adj_bottom_str;
- slp[count].leftname = adjp->adj_left_str;
- slp[count].rightname = adjp->adj_right_str;
- break;
- case CONF_ADJ_ABSOLUTE:
- slp[count].where = PosAbsolute;
- break;
- case CONF_ADJ_RIGHTOF:
- slp[count].where = PosRightOf;
- break;
- case CONF_ADJ_LEFTOF:
- slp[count].where = PosLeftOf;
- break;
- case CONF_ADJ_ABOVE:
- slp[count].where = PosAbove;
- break;
- case CONF_ADJ_BELOW:
- slp[count].where = PosBelow;
- break;
- case CONF_ADJ_RELATIVE:
- slp[count].where = PosRelative;
- break;
- }
- count++;
- adjp = (XF86ConfAdjacencyPtr)adjp->list.next;
- }
-
- /* No screen was specified in the layout. take the first one from the
- * config file, or - if it is NULL - configScreen autogenerates one for
- * us */
- if (!count)
- {
- slp[0].screen = xnfcalloc(1, sizeof(confScreenRec));
- if (!configScreen(slp[0].screen, xf86configptr->conf_screen_lst,
- 0, X_CONFIG)) {
- xfree(slp[0].screen);
- xfree(slp);
- return FALSE;
- }
- }
-
- /* XXX Need to tie down the upper left screen. */
-
- /* Fill in the refscreen and top/bottom/left/right values */
- for (i = 0; i < count; i++) {
- for (j = 0; j < count; j++) {
- if (slp[i].refname &&
- strcmp(slp[i].refname, slp[j].screen->id) == 0) {
- slp[i].refscreen = slp[j].screen;
- }
- if (slp[i].topname &&
- strcmp(slp[i].topname, slp[j].screen->id) == 0) {
- slp[i].top = slp[j].screen;
- }
- if (slp[i].bottomname &&
- strcmp(slp[i].bottomname, slp[j].screen->id) == 0) {
- slp[i].bottom = slp[j].screen;
- }
- if (slp[i].leftname &&
- strcmp(slp[i].leftname, slp[j].screen->id) == 0) {
- slp[i].left = slp[j].screen;
- }
- if (slp[i].rightname &&
- strcmp(slp[i].rightname, slp[j].screen->id) == 0) {
- slp[i].right = slp[j].screen;
- }
- }
- if (slp[i].where != PosObsolete
- && slp[i].where != PosAbsolute
- && !slp[i].refscreen) {
- xf86Msg(X_ERROR,"Screen %s doesn't exist: deleting placement\n",
- slp[i].refname);
- slp[i].where = PosAbsolute;
- slp[i].x = 0;
- slp[i].y = 0;
- }
- }
-
- /*
- * Count the number of inactive devices.
- */
- count = 0;
- idp = conf_layout->lay_inactive_lst;
- while (idp) {
- count++;
- idp = (XF86ConfInactivePtr)idp->list.next;
- }
- DebugF("Found %d inactive devices in the layout section %s\n",
- count, conf_layout->lay_identifier);
- gdp = xnfalloc((count + 1) * sizeof(GDevRec));
- gdp[count].identifier = NULL;
- idp = conf_layout->lay_inactive_lst;
- count = 0;
- while (idp) {
- if (!configDevice(&gdp[count], idp->inactive_device, FALSE)) {
- xfree(gdp);
- return FALSE;
- }
- count++;
- idp = (XF86ConfInactivePtr)idp->list.next;
- }
-
- if (!configInputDevices(conf_layout, servlayoutp))
- return FALSE;
-
- servlayoutp->id = conf_layout->lay_identifier;
- servlayoutp->screens = slp;
- servlayoutp->inactives = gdp;
- servlayoutp->options = conf_layout->lay_option_lst;
- from = X_DEFAULT;
-
- return TRUE;
-}
-
-/*
- * No layout section, so find the first Screen section and set that up as
- * the only active screen.
- */
-static Bool
-configImpliedLayout(serverLayoutPtr servlayoutp, XF86ConfScreenPtr conf_screen,
- XF86ConfigPtr xf86configptr)
-{
- MessageType from;
- XF86ConfScreenPtr s;
- screenLayoutPtr slp;
- IDevPtr *indp;
- XF86ConfLayoutRec layout;
-
- if (!servlayoutp)
- return FALSE;
-
- /*
- * which screen section is the active one?
- *
- * If there is a -screen option, use that one, otherwise use the first
- * one.
- */
-
- from = X_CONFIG;
- if (xf86ScreenName != NULL) {
- if ((s = xf86findScreen(xf86ScreenName, conf_screen)) == NULL) {
- xf86Msg(X_ERROR, "No Screen section called \"%s\"\n",
- xf86ScreenName);
- return FALSE;
- }
- conf_screen = s;
- from = X_CMDLINE;
- }
-
- /* We have exactly one screen */
-
- slp = xnfcalloc(1, 2 * sizeof(screenLayoutRec));
- slp[0].screen = xnfcalloc(1, sizeof(confScreenRec));
- slp[1].screen = NULL;
- if (!configScreen(slp[0].screen, conf_screen, 0, from)) {
- xfree(slp);
- return FALSE;
- }
- servlayoutp->id = "(implicit)";
- servlayoutp->screens = slp;
- servlayoutp->inactives = xnfcalloc(1, sizeof(GDevRec));
- servlayoutp->options = NULL;
-
- memset(&layout, 0, sizeof(layout));
- layout.lay_identifier = servlayoutp->id;
- if (xf86layoutAddInputDevices(xf86configptr, &layout) > 0) {
- if (!configInputDevices(&layout, servlayoutp))
- return FALSE;
- from = X_DEFAULT;
- } else {
- /* Set up an empty input device list, then look for some core devices. */
- indp = xnfalloc(sizeof(IDevPtr));
- *indp = NULL;
- servlayoutp->inputs = indp;
- }
-
- return TRUE;
-}
-
-static Bool
-configXvAdaptor(confXvAdaptorPtr adaptor, XF86ConfVideoAdaptorPtr conf_adaptor)
-{
- int count = 0;
- XF86ConfVideoPortPtr conf_port;
-
- xf86Msg(X_CONFIG, "| |-->VideoAdaptor \"%s\"\n",
- conf_adaptor->va_identifier);
- adaptor->identifier = conf_adaptor->va_identifier;
- adaptor->options = conf_adaptor->va_option_lst;
- if (conf_adaptor->va_busid || conf_adaptor->va_driver) {
- xf86Msg(X_CONFIG, "| | Unsupported device type, skipping entry\n");
- return FALSE;
- }
-
- /*
- * figure out how many videoport subsections there are and fill them in
- */
- conf_port = conf_adaptor->va_port_lst;
- while(conf_port) {
- count++;
- conf_port = (XF86ConfVideoPortPtr)conf_port->list.next;
- }
- adaptor->ports = xnfalloc((count) * sizeof(confXvPortRec));
- adaptor->numports = count;
- count = 0;
- conf_port = conf_adaptor->va_port_lst;
- while(conf_port) {
- adaptor->ports[count].identifier = conf_port->vp_identifier;
- adaptor->ports[count].options = conf_port->vp_option_lst;
- count++;
- conf_port = (XF86ConfVideoPortPtr)conf_port->list.next;
- }
-
- return TRUE;
-}
-
-static Bool
-configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum,
- MessageType from)
-{
- int count = 0;
- XF86ConfDisplayPtr dispptr;
- XF86ConfAdaptorLinkPtr conf_adaptor;
- Bool defaultMonitor = FALSE;
-
- if (!conf_screen) {
- conf_screen = xnfcalloc(1, sizeof(XF86ConfScreenRec));
- conf_screen->scrn_identifier = "Default Screen Section";
- xf86Msg(X_DEFAULT, "No screen section available. Using defaults.\n");
- }
-
- xf86Msg(from, "|-->Screen \"%s\" (%d)\n", conf_screen->scrn_identifier,
- scrnum);
- /*
- * now we fill in the elements of the screen
- */
- screenp->id = conf_screen->scrn_identifier;
- screenp->screennum = scrnum;
- screenp->defaultdepth = conf_screen->scrn_defaultdepth;
- screenp->defaultbpp = conf_screen->scrn_defaultbpp;
- screenp->defaultfbbpp = conf_screen->scrn_defaultfbbpp;
- screenp->monitor = xnfcalloc(1, sizeof(MonRec));
- /* If no monitor is specified, create a default one. */
- if (!conf_screen->scrn_monitor) {
- XF86ConfMonitorRec defMon;
-
- bzero(&defMon, sizeof(defMon));
- defMon.mon_identifier = "<default monitor>";
- if (!configMonitor(screenp->monitor, &defMon))
- return FALSE;
- defaultMonitor = TRUE;
- } else {
- if (!configMonitor(screenp->monitor,conf_screen->scrn_monitor))
- return FALSE;
- }
- /* Configure the device. If there isn't one configured, attach to the
- * first inactive one that we can configure. If there's none that work,
- * set it to NULL so that the section can be autoconfigured later */
- screenp->device = xnfcalloc(1, sizeof(GDevRec));
- if ((!conf_screen->scrn_device) && (xf86configptr->conf_device_lst)) {
- conf_screen->scrn_device = xf86configptr->conf_device_lst;
- xf86Msg(X_DEFAULT, "No device specified for screen \"%s\".\n"
- "\tUsing the first device section listed.\n", screenp->id);
- }
- if (configDevice(screenp->device,conf_screen->scrn_device, TRUE)) {
- screenp->device->myScreenSection = screenp;
- } else {
- screenp->device = NULL;
- }
- screenp->options = conf_screen->scrn_option_lst;
-
- /*
- * figure out how many display subsections there are and fill them in
- */
- dispptr = conf_screen->scrn_display_lst;
- while(dispptr) {
- count++;
- dispptr = (XF86ConfDisplayPtr)dispptr->list.next;
- }
- screenp->displays = xnfalloc((count) * sizeof(DispRec));
- screenp->numdisplays = count;
-
- /* Fill in the default Virtual size, if any */
- if (conf_screen->scrn_virtualX && conf_screen->scrn_virtualY) {
- for (count = 0, dispptr = conf_screen->scrn_display_lst;
- dispptr;
- dispptr = (XF86ConfDisplayPtr)dispptr->list.next, count++) {
- screenp->displays[count].virtualX = conf_screen->scrn_virtualX;
- screenp->displays[count].virtualY = conf_screen->scrn_virtualY;
- }
- }
-
- /* Now do the per-Display Virtual sizes */
- count = 0;
- dispptr = conf_screen->scrn_display_lst;
- while(dispptr) {
- configDisplay(&(screenp->displays[count]),dispptr);
- count++;
- dispptr = (XF86ConfDisplayPtr)dispptr->list.next;
- }
-
- /*
- * figure out how many videoadaptor references there are and fill them in
- */
- conf_adaptor = conf_screen->scrn_adaptor_lst;
- while(conf_adaptor) {
- count++;
- conf_adaptor = (XF86ConfAdaptorLinkPtr)conf_adaptor->list.next;
- }
- screenp->xvadaptors = xnfalloc((count) * sizeof(confXvAdaptorRec));
- screenp->numxvadaptors = 0;
- conf_adaptor = conf_screen->scrn_adaptor_lst;
- while(conf_adaptor) {
- if (configXvAdaptor(&(screenp->xvadaptors[screenp->numxvadaptors]),
- conf_adaptor->al_adaptor))
- screenp->numxvadaptors++;
- conf_adaptor = (XF86ConfAdaptorLinkPtr)conf_adaptor->list.next;
- }
-
- if (defaultMonitor) {
- xf86Msg(X_DEFAULT, "No monitor specified for screen \"%s\".\n"
- "\tUsing a default monitor configuration.\n", screenp->id);
- }
- return TRUE;
-}
-
-typedef enum {
- MON_REDUCEDBLANKING,
- MON_MAX_PIX_CLOCK,
-} MonitorValues;
-
-static OptionInfoRec MonitorOptions[] = {
- { MON_REDUCEDBLANKING, "ReducedBlanking", OPTV_BOOLEAN,
- {0}, FALSE },
- { MON_MAX_PIX_CLOCK, "MaxPixClock", OPTV_FREQ,
- {0}, FALSE },
- { -1, NULL, OPTV_NONE,
- {0}, FALSE },
-};
-
-static Bool
-configMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor)
-{
- int count;
- DisplayModePtr mode,last = NULL;
- XF86ConfModeLinePtr cmodep;
- XF86ConfModesPtr modes;
- XF86ConfModesLinkPtr modeslnk = conf_monitor->mon_modes_sect_lst;
- Gamma zeros = {0.0, 0.0, 0.0};
- float badgamma = 0.0;
- double maxPixClock;
-
- xf86Msg(X_CONFIG, "| |-->Monitor \"%s\"\n",
- conf_monitor->mon_identifier);
- monitorp->id = conf_monitor->mon_identifier;
- monitorp->vendor = conf_monitor->mon_vendor;
- monitorp->model = conf_monitor->mon_modelname;
- monitorp->Modes = NULL;
- monitorp->Last = NULL;
- monitorp->gamma = zeros;
- monitorp->widthmm = conf_monitor->mon_width;
- monitorp->heightmm = conf_monitor->mon_height;
- monitorp->reducedblanking = FALSE;
- monitorp->maxPixClock = 0;
- monitorp->options = conf_monitor->mon_option_lst;
-
- /*
- * fill in the monitor structure
- */
- for( count = 0 ;
- count < conf_monitor->mon_n_hsync && count < MAX_HSYNC;
- count++) {
- monitorp->hsync[count].hi = conf_monitor->mon_hsync[count].hi;
- monitorp->hsync[count].lo = conf_monitor->mon_hsync[count].lo;
- }
- monitorp->nHsync = count;
- for( count = 0 ;
- count < conf_monitor->mon_n_vrefresh && count < MAX_VREFRESH;
- count++) {
- monitorp->vrefresh[count].hi = conf_monitor->mon_vrefresh[count].hi;
- monitorp->vrefresh[count].lo = conf_monitor->mon_vrefresh[count].lo;
- }
- monitorp->nVrefresh = count;
-
- /*
- * first we collect the mode lines from the UseModes directive
- */
- while(modeslnk)
- {
- modes = xf86findModes (modeslnk->ml_modes_str,
- xf86configptr->conf_modes_lst);
- modeslnk->ml_modes = modes;
-
-
- /* now add the modes found in the modes
- section to the list of modes for this
- monitor unless it has been added before
- because we are reusing the same section
- for another screen */
- if (xf86itemNotSublist(
- (GenericListPtr)conf_monitor->mon_modeline_lst,
- (GenericListPtr)modes->mon_modeline_lst)) {
- conf_monitor->mon_modeline_lst = (XF86ConfModeLinePtr)
- xf86addListItem(
- (GenericListPtr)conf_monitor->mon_modeline_lst,
- (GenericListPtr)modes->mon_modeline_lst);
- }
- modeslnk = modeslnk->list.next;
- }
-
- /*
- * we need to hook in the mode lines now
- * here both data structures use lists, only our internal one
- * is double linked
- */
- cmodep = conf_monitor->mon_modeline_lst;
- while( cmodep ) {
- mode = xnfcalloc(1, sizeof(DisplayModeRec));
- mode->type = 0;
- mode->Clock = cmodep->ml_clock;
- mode->HDisplay = cmodep->ml_hdisplay;
- mode->HSyncStart = cmodep->ml_hsyncstart;
- mode->HSyncEnd = cmodep->ml_hsyncend;
- mode->HTotal = cmodep->ml_htotal;
- mode->VDisplay = cmodep->ml_vdisplay;
- mode->VSyncStart = cmodep->ml_vsyncstart;
- mode->VSyncEnd = cmodep->ml_vsyncend;
- mode->VTotal = cmodep->ml_vtotal;
- mode->Flags = cmodep->ml_flags;
- mode->HSkew = cmodep->ml_hskew;
- mode->VScan = cmodep->ml_vscan;
- mode->name = xnfstrdup(cmodep->ml_identifier);
- if( last ) {
- mode->prev = last;
- last->next = mode;
- }
- else {
- /*
- * this is the first mode
- */
- monitorp->Modes = mode;
- mode->prev = NULL;
- }
- last = mode;
- cmodep = (XF86ConfModeLinePtr)cmodep->list.next;
- }
- if(last){
- last->next = NULL;
- }
- monitorp->Last = last;
-
- /* add the (VESA) default modes */
- if (! addDefaultModes(monitorp) )
- return FALSE;
-
- if (conf_monitor->mon_gamma_red > GAMMA_ZERO)
- monitorp->gamma.red = conf_monitor->mon_gamma_red;
- if (conf_monitor->mon_gamma_green > GAMMA_ZERO)
- monitorp->gamma.green = conf_monitor->mon_gamma_green;
- if (conf_monitor->mon_gamma_blue > GAMMA_ZERO)
- monitorp->gamma.blue = conf_monitor->mon_gamma_blue;
-
- /* Check that the gamma values are within range */
- if (monitorp->gamma.red > GAMMA_ZERO &&
- (monitorp->gamma.red < GAMMA_MIN ||
- monitorp->gamma.red > GAMMA_MAX)) {
- badgamma = monitorp->gamma.red;
- } else if (monitorp->gamma.green > GAMMA_ZERO &&
- (monitorp->gamma.green < GAMMA_MIN ||
- monitorp->gamma.green > GAMMA_MAX)) {
- badgamma = monitorp->gamma.green;
- } else if (monitorp->gamma.blue > GAMMA_ZERO &&
- (monitorp->gamma.blue < GAMMA_MIN ||
- monitorp->gamma.blue > GAMMA_MAX)) {
- badgamma = monitorp->gamma.blue;
- }
- if (badgamma > GAMMA_ZERO) {
- xf86ConfigError("Gamma value %.f is out of range (%.2f - %.1f)\n",
- badgamma, GAMMA_MIN, GAMMA_MAX);
- return FALSE;
- }
-
- xf86ProcessOptions(-1, monitorp->options, MonitorOptions);
- xf86GetOptValBool(MonitorOptions, MON_REDUCEDBLANKING,
- &monitorp->reducedblanking);
- if (xf86GetOptValFreq(MonitorOptions, MON_MAX_PIX_CLOCK, OPTUNITS_KHZ,
- &maxPixClock) == TRUE) {
- monitorp->maxPixClock = (int) maxPixClock;
- }
-
- return TRUE;
-}
-
-static int
-lookupVisual(const char *visname)
-{
- int i;
-
- if (!visname || !*visname)
- return -1;
-
- for (i = 0; i <= DirectColor; i++) {
- if (!xf86nameCompare(visname, xf86VisualNames[i]))
- break;
- }
-
- if (i <= DirectColor)
- return i;
-
- return -1;
-}
-
-
-static Bool
-configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display)
-{
- int count = 0;
- XF86ModePtr modep;
-
- displayp->frameX0 = conf_display->disp_frameX0;
- displayp->frameY0 = conf_display->disp_frameY0;
- displayp->virtualX = conf_display->disp_virtualX;
- displayp->virtualY = conf_display->disp_virtualY;
- displayp->depth = conf_display->disp_depth;
- displayp->fbbpp = conf_display->disp_bpp;
- displayp->weight.red = conf_display->disp_weight.red;
- displayp->weight.green = conf_display->disp_weight.green;
- displayp->weight.blue = conf_display->disp_weight.blue;
- displayp->blackColour.red = conf_display->disp_black.red;
- displayp->blackColour.green = conf_display->disp_black.green;
- displayp->blackColour.blue = conf_display->disp_black.blue;
- displayp->whiteColour.red = conf_display->disp_white.red;
- displayp->whiteColour.green = conf_display->disp_white.green;
- displayp->whiteColour.blue = conf_display->disp_white.blue;
- displayp->options = conf_display->disp_option_lst;
- if (conf_display->disp_visual) {
- displayp->defaultVisual = lookupVisual(conf_display->disp_visual);
- if (displayp->defaultVisual == -1) {
- xf86ConfigError("Invalid visual name: \"%s\"",
- conf_display->disp_visual);
- return FALSE;
- }
- } else {
- displayp->defaultVisual = -1;
- }
-
- /*
- * now hook in the modes
- */
- modep = conf_display->disp_mode_lst;
- while(modep) {
- count++;
- modep = (XF86ModePtr)modep->list.next;
- }
- displayp->modes = xnfalloc((count+1) * sizeof(char*));
- modep = conf_display->disp_mode_lst;
- count = 0;
- while(modep) {
- displayp->modes[count] = modep->mode_name;
- count++;
- modep = (XF86ModePtr)modep->list.next;
- }
- displayp->modes[count] = NULL;
-
- return TRUE;
-}
-
-static Bool
-configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device, Bool active)
-{
- int i;
-
- if (!conf_device) {
- return FALSE;
- }
-
- if (active)
- xf86Msg(X_CONFIG, "| |-->Device \"%s\"\n",
- conf_device->dev_identifier);
- else
- xf86Msg(X_CONFIG, "|-->Inactive Device \"%s\"\n",
- conf_device->dev_identifier);
-
- devicep->identifier = conf_device->dev_identifier;
- devicep->vendor = conf_device->dev_vendor;
- devicep->board = conf_device->dev_board;
- devicep->chipset = conf_device->dev_chipset;
- devicep->ramdac = conf_device->dev_ramdac;
- devicep->driver = conf_device->dev_driver;
- devicep->active = active;
- devicep->videoRam = conf_device->dev_videoram;
- devicep->BiosBase = conf_device->dev_bios_base;
- devicep->MemBase = conf_device->dev_mem_base;
- devicep->IOBase = conf_device->dev_io_base;
- devicep->clockchip = conf_device->dev_clockchip;
- devicep->busID = conf_device->dev_busid;
- devicep->textClockFreq = conf_device->dev_textclockfreq;
- devicep->chipID = conf_device->dev_chipid;
- devicep->chipRev = conf_device->dev_chiprev;
- devicep->options = conf_device->dev_option_lst;
- devicep->irq = conf_device->dev_irq;
- devicep->screen = conf_device->dev_screen;
-
- for (i = 0; i < MAXDACSPEEDS; i++) {
- if (i < CONF_MAXDACSPEEDS)
- devicep->dacSpeeds[i] = conf_device->dev_dacSpeeds[i];
- else
- devicep->dacSpeeds[i] = 0;
- }
- devicep->numclocks = conf_device->dev_clocks;
- if (devicep->numclocks > MAXCLOCKS)
- devicep->numclocks = MAXCLOCKS;
- for (i = 0; i < devicep->numclocks; i++) {
- devicep->clock[i] = conf_device->dev_clock[i];
- }
- devicep->claimed = FALSE;
-
- return TRUE;
-}
-
-#ifdef XF86DRI
-static void
-configDRI(XF86ConfDRIPtr drip)
-{
- int count = 0;
- XF86ConfBuffersPtr bufs;
- int i;
- struct group *grp;
-
- xf86ConfigDRI.group = -1;
- xf86ConfigDRI.mode = 0;
- xf86ConfigDRI.bufs_count = 0;
- xf86ConfigDRI.bufs = NULL;
-
- if (drip) {
- if (drip->dri_group_name) {
- if ((grp = getgrnam(drip->dri_group_name)))
- xf86ConfigDRI.group = grp->gr_gid;
- } else {
- if (drip->dri_group >= 0)
- xf86ConfigDRI.group = drip->dri_group;
- }
- xf86ConfigDRI.mode = drip->dri_mode;
- for (bufs = drip->dri_buffers_lst; bufs; bufs = bufs->list.next)
- ++count;
-
- xf86ConfigDRI.bufs_count = count;
- xf86ConfigDRI.bufs = xnfalloc(count * sizeof(*xf86ConfigDRI.bufs));
-
- for (i = 0, bufs = drip->dri_buffers_lst;
- i < count;
- i++, bufs = bufs->list.next) {
-
- xf86ConfigDRI.bufs[i].count = bufs->buf_count;
- xf86ConfigDRI.bufs[i].size = bufs->buf_size;
- /* FIXME: Flags not implemented. These
- could be used, for example, to specify a
- contiguous block and/or write-combining
- cache policy. */
- xf86ConfigDRI.bufs[i].flags = 0;
- }
- }
-}
-#endif
-
-static void
-configExtensions(XF86ConfExtensionsPtr conf_ext)
-{
- XF86OptionPtr o;
-
- if (conf_ext && conf_ext->ext_option_lst) {
- for (o = conf_ext->ext_option_lst; o; o = xf86NextOption(o)) {
- char *name = xf86OptionName(o);
- char *val = xf86OptionValue(o);
- char *n;
- Bool enable = TRUE;
-
- /* Handle "No<ExtensionName>" */
- n = xf86NormalizeName(name);
- if (strncmp(n, "no", 2) == 0) {
- name += 2;
- enable = FALSE;
- }
-
- if (!val ||
- xf86NameCmp(val, "enable") == 0 ||
- xf86NameCmp(val, "enabled") == 0 ||
- xf86NameCmp(val, "on") == 0 ||
- xf86NameCmp(val, "1") == 0 ||
- xf86NameCmp(val, "yes") == 0 ||
- xf86NameCmp(val, "true") == 0) {
- /* NOTHING NEEDED -- enabling is handled below */
- } else if (xf86NameCmp(val, "disable") == 0 ||
- xf86NameCmp(val, "disabled") == 0 ||
- xf86NameCmp(val, "off") == 0 ||
- xf86NameCmp(val, "0") == 0 ||
- xf86NameCmp(val, "no") == 0 ||
- xf86NameCmp(val, "false") == 0) {
- enable = !enable;
- } else {
- xf86Msg(X_WARNING, "Ignoring unrecognized value \"%s\"\n", val);
- xfree(n);
- continue;
- }
-
- if (EnableDisableExtension(name, enable)) {
- xf86Msg(X_CONFIG, "Extension \"%s\" is %s\n",
- name, enable ? "enabled" : "disabled");
- } else {
- xf86Msg(X_WARNING, "Ignoring unrecognized extension \"%s\"\n",
- name);
- }
- xfree(n);
- }
- }
-}
-
-static Bool
-configInput(IDevPtr inputp, XF86ConfInputPtr conf_input, MessageType from)
-{
- xf86Msg(from, "|-->Input Device \"%s\"\n", conf_input->inp_identifier);
- inputp->identifier = conf_input->inp_identifier;
- inputp->driver = conf_input->inp_driver;
- inputp->commonOptions = conf_input->inp_option_lst;
- inputp->extraOptions = NULL;
-
- return TRUE;
-}
-
-static Bool
-modeIsPresent(DisplayModePtr mode, MonPtr monitorp)
-{
- DisplayModePtr knownmodes = monitorp->Modes;
-
- /* all I can think of is a linear search... */
- while(knownmodes != NULL)
- {
- if(!strcmp(mode->name, knownmodes->name) &&
- !(knownmodes->type & M_T_DEFAULT))
- return TRUE;
- knownmodes = knownmodes->next;
- }
- return FALSE;
-}
-
-static Bool
-addDefaultModes(MonPtr monitorp)
-{
- DisplayModePtr mode;
- DisplayModePtr last = monitorp->Last;
- int i = 0;
-
- for (i = 0; i < xf86NumDefaultModes; i++)
- {
- mode = xf86DuplicateMode(&xf86DefaultModes[i]);
- if (!modeIsPresent(mode, monitorp))
- {
- monitorp->Modes = xf86ModesAdd(monitorp->Modes, mode);
- last = mode;
- } else {
- xfree(mode);
- }
- }
- monitorp->Last = last;
-
- return TRUE;
-}
-
-static void
-checkInput(serverLayoutPtr layout, Bool implicit_layout) {
- checkCoreInputDevices(layout, implicit_layout);
-
- /* AllowEmptyInput and the "kbd" and "mouse" drivers are mutually
- * exclusive. Trawl the list for mouse/kbd devices and disable them.
- */
- if (xf86Info.allowEmptyInput && layout->inputs)
- {
- IDevPtr *dev = layout->inputs;
- BOOL warned = FALSE;
-
- while(*dev)
- {
- if (strcmp((*dev)->driver, "kbd") == 0 ||
- strcmp((*dev)->driver, "mouse") == 0 ||
- strcmp((*dev)->driver, "vmmouse") == 0)
- {
- IDevPtr *current;
- if (!warned)
- {
- xf86Msg(X_WARNING, "AllowEmptyInput is on, devices using "
- "drivers 'kbd', 'mouse' or 'vmmouse' will be disabled.\n");
- warned = TRUE;
- }
-
- xf86Msg(X_WARNING, "Disabling %s\n", (*dev)->identifier);
-
- current = dev;
- xfree(*dev);
-
- do {
- *current = *(current + 1);
- current++;
- } while(*current);
- } else
- dev++;
- }
- }
-}
-
-/*
- * load the config file and fill the global data structure
- */
-ConfigStatus
-xf86HandleConfigFile(Bool autoconfig)
-{
- const char *filename, *dirname, *sysdirname;
- char *filesearch, *dirsearch;
- MessageType filefrom = X_DEFAULT;
- MessageType dirfrom = X_DEFAULT;
- char *scanptr;
- Bool singlecard = 0;
- Bool implicit_layout = FALSE;
-
- if (!autoconfig) {
- if (getuid() == 0) {
- filesearch = ROOT_CONFIGPATH;
- dirsearch = ROOT_CONFIGDIRPATH;
- } else {
- filesearch = USER_CONFIGPATH;
- dirsearch = USER_CONFIGDIRPATH;
- }
-
- if (xf86ConfigFile)
- filefrom = X_CMDLINE;
- if (xf86ConfigDir)
- dirfrom = X_CMDLINE;
-
- xf86initConfigFiles();
- sysdirname = xf86openConfigDirFiles(SYS_CONFIGDIRPATH, NULL,
- PROJECTROOT);
- dirname = xf86openConfigDirFiles(dirsearch, xf86ConfigDir, PROJECTROOT);
- filename = xf86openConfigFile(filesearch, xf86ConfigFile, PROJECTROOT);
- if (filename) {
- xf86MsgVerb(filefrom, 0, "Using config file: \"%s\"\n", filename);
- xf86ConfigFile = xnfstrdup(filename);
- } else {
- if (xf86ConfigFile)
- xf86Msg(X_ERROR, "Unable to locate/open config file: \"%s\"\n",
- xf86ConfigFile);
- }
- if (dirname) {
- xf86MsgVerb(dirfrom, 0, "Using config directory: \"%s\"\n",
- dirname);
- xf86ConfigDir = xnfstrdup(dirname);
- } else {
- if (xf86ConfigDir)
- xf86Msg(X_ERROR,
- "Unable to locate/open config directory: \"%s\"\n",
- xf86ConfigDir);
- }
- if (sysdirname)
- xf86MsgVerb(X_DEFAULT, 0, "Using system config directory \"%s\"\n",
- sysdirname);
- if (!filename && !dirname && !sysdirname)
- return CONFIG_NOFILE;
- }
-
- if ((xf86configptr = xf86readConfigFile ()) == NULL) {
- xf86Msg(X_ERROR, "Problem parsing the config file\n");
- return CONFIG_PARSE_ERROR;
- }
- xf86closeConfigFile ();
-
- /* Initialise a few things. */
-
- /*
- * now we convert part of the information contained in the parser
- * structures into our own structures.
- * The important part here is to figure out which Screen Sections
- * in the XF86Config file are active so that we can piece together
- * the modes that we need later down the road.
- * And while we are at it, we'll decode the rest of the stuff as well
- */
-
- /* First check if a layout section is present, and if it is valid. */
-
- if (xf86configptr->conf_layout_lst == NULL || xf86ScreenName != NULL) {
- if (xf86ScreenName == NULL) {
- xf86Msg(X_DEFAULT,
- "No Layout section. Using the first Screen section.\n");
- }
- if (!configImpliedLayout(&xf86ConfigLayout,
- xf86configptr->conf_screen_lst,
- xf86configptr)) {
- xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
- return CONFIG_PARSE_ERROR;
- }
- implicit_layout = TRUE;
- } else {
- if (xf86configptr->conf_flags != NULL) {
- char *dfltlayout = NULL;
- pointer optlist = xf86configptr->conf_flags->flg_option_lst;
-
- if (optlist && xf86FindOption(optlist, "defaultserverlayout"))
- dfltlayout = xf86SetStrOption(optlist, "defaultserverlayout", NULL);
- if (!configLayout(&xf86ConfigLayout, xf86configptr->conf_layout_lst,
- dfltlayout)) {
- xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
- return CONFIG_PARSE_ERROR;
- }
- } else {
- if (!configLayout(&xf86ConfigLayout, xf86configptr->conf_layout_lst,
- NULL)) {
- xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
- return CONFIG_PARSE_ERROR;
- }
- }
- }
-
- xf86ProcessOptions(-1, xf86ConfigLayout.options, LayoutOptions);
-
- if ((scanptr = xf86GetOptValString(LayoutOptions, LAYOUT_ISOLATEDEVICE))) {
- ; /* IsolateDevice specified; overrides SingleCard */
- } else {
- xf86GetOptValBool(LayoutOptions, LAYOUT_SINGLECARD, &singlecard);
- if (singlecard)
- scanptr = xf86ConfigLayout.screens->screen->device->busID;
- }
- if (scanptr) {
- int bus, device, func;
- if (strncmp(scanptr, "PCI:", 4) != 0) {
- xf86Msg(X_WARNING, "Bus types other than PCI not yet isolable.\n"
- "\tIgnoring IsolateDevice option.\n");
- } else if (sscanf(scanptr, "PCI:%d:%d:%d", &bus, &device, &func) == 3) {
- xf86IsolateDevice.domain = PCI_DOM_FROM_BUS(bus);
- xf86IsolateDevice.bus = PCI_BUS_NO_DOMAIN(bus);
- xf86IsolateDevice.dev = device;
- xf86IsolateDevice.func = func;
- xf86Msg(X_INFO,
- "Isolating PCI bus \"%d:%d:%d\"\n", bus, device, func);
- }
- }
-
- /* Now process everything else */
- if (!configServerFlags(xf86configptr->conf_flags,xf86ConfigLayout.options)){
- ErrorF ("Problem when converting the config data structures\n");
- return CONFIG_PARSE_ERROR;
- }
-
- configFiles(xf86configptr->conf_files);
- configExtensions(xf86configptr->conf_extensions);
-#ifdef XF86DRI
- configDRI(xf86configptr->conf_dri);
-#endif
-
- checkInput(&xf86ConfigLayout, implicit_layout);
-
- /*
- * Handle some command line options that can override some of the
- * ServerFlags settings.
- */
-#ifdef XF86VIDMODE
- if (xf86VidModeDisabled)
- xf86Info.vidModeEnabled = FALSE;
- if (xf86VidModeAllowNonLocal)
- xf86Info.vidModeAllowNonLocal = TRUE;
-#endif
-
- if (xf86AllowMouseOpenFail)
- xf86Info.allowMouseOpenFail = TRUE;
-
- return CONFIG_OK;
-}
-
-Bool
-xf86PathIsSafe(const char *path)
-{
- return (xf86pathIsSafe(path) != 0);
-}
+/*
+ * Loosely based on code bearing the following copyright:
+ *
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+ */
+
+/*
+ * Copyright 1992-2003 by The XFree86 Project, Inc.
+ * Copyright 1997 by Metro Link, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ *
+ * Authors:
+ * Dirk Hohndel <hohndel@XFree86.Org>
+ * David Dawes <dawes@XFree86.Org>
+ * Marc La France <tsi@XFree86.Org>
+ * Egbert Eich <eich@XFree86.Org>
+ * ... and others
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#ifdef XF86DRI
+#include <sys/types.h>
+#include <grp.h>
+#endif
+
+#include "xf86.h"
+#include "xf86Parser.h"
+#include "xf86tokens.h"
+#include "xf86Config.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "configProcs.h"
+#include "globals.h"
+#include "extension.h"
+#include "Pci.h"
+
+#include "xf86Xinput.h"
+extern DeviceAssocRec mouse_assoc;
+
+#include "xkbsrv.h"
+
+#include "picture.h"
+
+/*
+ * These paths define the way the config file search is done. The escape
+ * sequences are documented in parser/scan.c.
+ */
+#ifndef ROOT_CONFIGPATH
+#define ROOT_CONFIGPATH "%A," "%R," \
+ "/etc/X11/%R," "%P/etc/X11/%R," \
+ "%E," "%F," \
+ "/etc/X11/%F," "%P/etc/X11/%F," \
+ "/etc/X11/%X-%M," "/etc/X11/%X," "/etc/%X," \
+ "%P/etc/X11/%X.%H," "%P/etc/X11/%X-%M," \
+ "%P/etc/X11/%X," \
+ "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \
+ "%P/lib/X11/%X"
+#endif
+#ifndef USER_CONFIGPATH
+#define USER_CONFIGPATH "/etc/X11/%S," "%P/etc/X11/%S," \
+ "/etc/X11/%G," "%P/etc/X11/%G," \
+ "/etc/X11/%X-%M," "/etc/X11/%X," "/etc/%X," \
+ "%P/etc/X11/%X.%H," "%P/etc/X11/%X-%M," \
+ "%P/etc/X11/%X," \
+ "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \
+ "%P/lib/X11/%X"
+#endif
+#ifndef ROOT_CONFIGDIRPATH
+#define ROOT_CONFIGDIRPATH "%A," "%R," \
+ "/etc/X11/%R," "%C/X11/%R," \
+ "/etc/X11/%X," "%C/X11/%X"
+#endif
+#ifndef USER_CONFIGDIRPATH
+#define USER_CONFIGDIRPATH "/etc/X11/%R," "%C/X11/%R," \
+ "/etc/X11/%X," "%C/X11/%X"
+#endif
+#ifndef SYS_CONFIGDIRPATH
+#define SYS_CONFIGDIRPATH "/usr/share/X11/%X," "%D/X11/%X"
+#endif
+#ifndef PROJECTROOT
+#define PROJECTROOT "/usr/X11R6"
+#endif
+
+static ModuleDefault ModuleDefaults[] = {
+ {.name = "extmod", .toLoad = TRUE, .load_opt=NULL},
+#ifdef DBE
+ {.name = "dbe", .toLoad = TRUE, .load_opt=NULL},
+#endif
+#ifdef GLXEXT
+ {.name = "glx", .toLoad = TRUE, .load_opt=NULL},
+#endif
+#ifdef XRECORD
+ {.name = "record", .toLoad = TRUE, .load_opt=NULL},
+#endif
+#ifdef XF86DRI
+ {.name = "dri", .toLoad = TRUE, .load_opt=NULL},
+#endif
+#ifdef DRI2
+ {.name = "dri2", .toLoad = TRUE, .load_opt=NULL},
+#endif
+ {.name = NULL, .toLoad = FALSE, .load_opt=NULL}
+};
+
+
+/* Forward declarations */
+static Bool configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen,
+ int scrnum, MessageType from);
+static Bool configMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor);
+static Bool configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device,
+ Bool active);
+static Bool configInput(IDevPtr inputp, XF86ConfInputPtr conf_input,
+ MessageType from);
+static Bool configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display);
+static Bool addDefaultModes(MonPtr monitorp);
+#ifdef XF86DRI
+static void configDRI(XF86ConfDRIPtr drip);
+#endif
+static void configExtensions(XF86ConfExtensionsPtr conf_ext);
+
+/*
+ * xf86GetPathElem --
+ * Extract a single element from the font path string starting at
+ * pnt. The font path element will be returned, and pnt will be
+ * updated to point to the start of the next element, or set to
+ * NULL if there are no more.
+ */
+static char *
+xf86GetPathElem(char **pnt)
+{
+ char *p1;
+
+ p1 = *pnt;
+ *pnt = index(*pnt, ',');
+ if (*pnt != NULL) {
+ **pnt = '\0';
+ *pnt += 1;
+ }
+ return(p1);
+}
+
+/*
+ * xf86ValidateFontPath --
+ * Validates the user-specified font path. Each element that
+ * begins with a '/' is checked to make sure the directory exists.
+ * If the directory exists, the existence of a file named 'fonts.dir'
+ * is checked. If either check fails, an error is printed and the
+ * element is removed from the font path.
+ */
+
+#define DIR_FILE "/fonts.dir"
+static char *
+xf86ValidateFontPath(char *path)
+{
+ char *tmp_path, *out_pnt, *path_elem, *next, *p1, *dir_elem;
+ struct stat stat_buf;
+ int flag;
+ int dirlen;
+
+ tmp_path = calloc(1,strlen(path)+1);
+ out_pnt = tmp_path;
+ path_elem = NULL;
+ next = path;
+ while (next != NULL) {
+ path_elem = xf86GetPathElem(&next);
+ if (*path_elem == '/') {
+ dir_elem = xnfcalloc(1, strlen(path_elem) + 1);
+ if ((p1 = strchr(path_elem, ':')) != 0)
+ dirlen = p1 - path_elem;
+ else
+ dirlen = strlen(path_elem);
+ strncpy(dir_elem, path_elem, dirlen);
+ dir_elem[dirlen] = '\0';
+ flag = stat(dir_elem, &stat_buf);
+ if (flag == 0)
+ if (!S_ISDIR(stat_buf.st_mode))
+ flag = -1;
+ if (flag != 0) {
+ xf86Msg(X_WARNING, "The directory \"%s\" does not exist.\n", dir_elem);
+ xf86ErrorF("\tEntry deleted from font path.\n");
+ free(dir_elem);
+ continue;
+ }
+ else {
+ p1 = xnfalloc(strlen(dir_elem)+strlen(DIR_FILE)+1);
+ strcpy(p1, dir_elem);
+ strcat(p1, DIR_FILE);
+ flag = stat(p1, &stat_buf);
+ if (flag == 0)
+ if (!S_ISREG(stat_buf.st_mode))
+ flag = -1;
+ free(p1);
+ if (flag != 0) {
+ xf86Msg(X_WARNING,
+ "`fonts.dir' not found (or not valid) in \"%s\".\n",
+ dir_elem);
+ xf86ErrorF("\tEntry deleted from font path.\n");
+ xf86ErrorF("\t(Run 'mkfontdir' on \"%s\").\n", dir_elem);
+ free(dir_elem);
+ continue;
+ }
+ }
+ free(dir_elem);
+ }
+
+ /*
+ * Either an OK directory, or a font server name. So add it to
+ * the path.
+ */
+ if (out_pnt != tmp_path)
+ *out_pnt++ = ',';
+ strcat(out_pnt, path_elem);
+ out_pnt += strlen(path_elem);
+ }
+ return(tmp_path);
+}
+
+
+/*
+ * use the datastructure that the parser provides and pick out the parts
+ * that we need at this point
+ */
+char **
+xf86ModulelistFromConfig(pointer **optlist)
+{
+ int count = 0, i = 0;
+ char **modulearray;
+ char *ignore[] = { "GLcore", "speedo", "bitmap", "drm",
+ "freetype", "type1",
+ NULL };
+ pointer *optarray;
+ XF86LoadPtr modp;
+ Bool found;
+
+ /*
+ * make sure the config file has been parsed and that we have a
+ * ModulePath set; if no ModulePath was given, use the default
+ * ModulePath
+ */
+ if (xf86configptr == NULL) {
+ xf86Msg(X_ERROR, "Cannot access global config data structure\n");
+ return NULL;
+ }
+
+ if (xf86configptr->conf_modules) {
+ /* Walk the disable list and let people know what we've parsed to
+ * not be loaded
+ */
+ modp = xf86configptr->conf_modules->mod_disable_lst;
+ while (modp) {
+ xf86Msg(X_WARNING, "\"%s\" will not be loaded unless you've specified it to be loaded elsewhere.\n", modp->load_name);
+ modp = (XF86LoadPtr) modp->list.next;
+ }
+ /*
+ * Walk the default settings table. For each module listed to be
+ * loaded, make sure it's in the mod_load_lst. If it's not, make
+ * sure it's not in the mod_no_load_lst. If it's not disabled,
+ * append it to mod_load_lst
+ */
+ for (i=0 ; ModuleDefaults[i].name != NULL ; i++) {
+ if (ModuleDefaults[i].toLoad == FALSE) {
+ xf86Msg(X_WARNING, "\"%s\" is not to be loaded by default. Skipping.\n", ModuleDefaults[i].name);
+ continue;
+ }
+ found = FALSE;
+ modp = xf86configptr->conf_modules->mod_load_lst;
+ while (modp) {
+ if (strcmp(modp->load_name, ModuleDefaults[i].name) == 0) {
+ xf86Msg(X_INFO, "\"%s\" will be loaded. This was enabled by default and also specified in the config file.\n", ModuleDefaults[i].name);
+ found = TRUE;
+ break;
+ }
+ modp = (XF86LoadPtr) modp->list.next;
+ }
+ if (found == FALSE) {
+ modp = xf86configptr->conf_modules->mod_disable_lst;
+ while (modp) {
+ if (strcmp(modp->load_name, ModuleDefaults[i].name) == 0) {
+ xf86Msg(X_INFO, "\"%s\" will be loaded even though the default is to disable it.\n", ModuleDefaults[i].name);
+ found = TRUE;
+ break;
+ }
+ modp = (XF86LoadPtr) modp->list.next;
+ }
+ }
+ if (found == FALSE) {
+ XF86LoadPtr ptr = (XF86LoadPtr)xf86configptr->conf_modules;
+ ptr = xf86addNewLoadDirective(ptr, ModuleDefaults[i].name, XF86_LOAD_MODULE, ModuleDefaults[i].load_opt);
+ xf86Msg(X_INFO, "\"%s\" will be loaded by default.\n", ModuleDefaults[i].name);
+ }
+ }
+ } else {
+ xf86configptr->conf_modules = xnfcalloc(1, sizeof(XF86ConfModuleRec));
+ for (i=0 ; ModuleDefaults[i].name != NULL ; i++) {
+ if (ModuleDefaults[i].toLoad == TRUE) {
+ XF86LoadPtr ptr = (XF86LoadPtr)xf86configptr->conf_modules;
+ ptr = xf86addNewLoadDirective(ptr, ModuleDefaults[i].name, XF86_LOAD_MODULE, ModuleDefaults[i].load_opt);
+ }
+ }
+ }
+
+ /*
+ * Walk the list of modules in the "Module" section to determine how
+ * many we have.
+ */
+ modp = xf86configptr->conf_modules->mod_load_lst;
+ while (modp) {
+ for (i = 0; ignore[i]; i++) {
+ if (strcmp(modp->load_name, ignore[i]) == 0)
+ modp->ignore = 1;
+ }
+ if (!modp->ignore)
+ count++;
+ modp = (XF86LoadPtr) modp->list.next;
+ }
+
+ /*
+ * allocate the memory and walk the list again to fill in the pointers
+ */
+ modulearray = xnfalloc((count + 1) * sizeof(char*));
+ optarray = xnfalloc((count + 1) * sizeof(pointer));
+ count = 0;
+ if (xf86configptr->conf_modules) {
+ modp = xf86configptr->conf_modules->mod_load_lst;
+ while (modp) {
+ if (!modp->ignore) {
+ modulearray[count] = modp->load_name;
+ optarray[count] = modp->load_opt;
+ count++;
+ }
+ modp = (XF86LoadPtr) modp->list.next;
+ }
+ }
+ modulearray[count] = NULL;
+ optarray[count] = NULL;
+ if (optlist)
+ *optlist = optarray;
+ else
+ free(optarray);
+ return modulearray;
+}
+
+
+char **
+xf86DriverlistFromConfig(void)
+{
+ int count = 0;
+ int j;
+ char **modulearray;
+ screenLayoutPtr slp;
+
+ /*
+ * make sure the config file has been parsed and that we have a
+ * ModulePath set; if no ModulePath was given, use the default
+ * ModulePath
+ */
+ if (xf86configptr == NULL) {
+ xf86Msg(X_ERROR, "Cannot access global config data structure\n");
+ return NULL;
+ }
+
+ /*
+ * Walk the list of driver lines in active "Device" sections to
+ * determine now many implicitly loaded modules there are.
+ *
+ */
+ if (xf86ConfigLayout.screens) {
+ slp = xf86ConfigLayout.screens;
+ while ((slp++)->screen) {
+ count++;
+ }
+ }
+
+ /*
+ * Handle the set of inactive "Device" sections.
+ */
+ j = 0;
+ while (xf86ConfigLayout.inactives[j++].identifier)
+ count++;
+
+ if (count == 0)
+ return NULL;
+
+ /*
+ * allocate the memory and walk the list again to fill in the pointers
+ */
+ modulearray = xnfalloc((count + 1) * sizeof(char*));
+ count = 0;
+ slp = xf86ConfigLayout.screens;
+ while (slp->screen) {
+ modulearray[count] = slp->screen->device->driver;
+ count++;
+ slp++;
+ }
+
+ j = 0;
+
+ while (xf86ConfigLayout.inactives[j].identifier)
+ modulearray[count++] = xf86ConfigLayout.inactives[j++].driver;
+
+ modulearray[count] = NULL;
+
+ /* Remove duplicates */
+ for (count = 0; modulearray[count] != NULL; count++) {
+ int i;
+
+ for (i = 0; i < count; i++)
+ if (xf86NameCmp(modulearray[i], modulearray[count]) == 0) {
+ modulearray[count] = "";
+ break;
+ }
+ }
+ return modulearray;
+}
+
+char **
+xf86InputDriverlistFromConfig(void)
+{
+ int count = 0;
+ char **modulearray;
+ IDevPtr* idp;
+
+ /*
+ * make sure the config file has been parsed and that we have a
+ * ModulePath set; if no ModulePath was given, use the default
+ * ModulePath
+ */
+ if (xf86configptr == NULL) {
+ xf86Msg(X_ERROR, "Cannot access global config data structure\n");
+ return NULL;
+ }
+
+ /*
+ * Walk the list of driver lines in active "InputDevice" sections to
+ * determine now many implicitly loaded modules there are.
+ */
+ if (xf86ConfigLayout.inputs) {
+ idp = xf86ConfigLayout.inputs;
+ while (*idp) {
+ count++;
+ idp++;
+ }
+ }
+
+ if (count == 0)
+ return NULL;
+
+ /*
+ * allocate the memory and walk the list again to fill in the pointers
+ */
+ modulearray = xnfalloc((count + 1) * sizeof(char*));
+ count = 0;
+ idp = xf86ConfigLayout.inputs;
+ while (idp && *idp) {
+ modulearray[count] = (*idp)->driver;
+ count++;
+ idp++;
+ }
+ modulearray[count] = NULL;
+
+ /* Remove duplicates */
+ for (count = 0; modulearray[count] != NULL; count++) {
+ int i;
+
+ for (i = 0; i < count; i++)
+ if (xf86NameCmp(modulearray[i], modulearray[count]) == 0) {
+ modulearray[count] = "";
+ break;
+ }
+ }
+ return modulearray;
+}
+
+static void
+fixup_video_driver_list(char **drivers)
+{
+ static const char *fallback[4] = { "vesa", "fbdev", "wsfb", NULL };
+ char **end, **drv;
+ char *x;
+ char **ati, **atimisc;
+ int i;
+
+ /* walk to the end of the list */
+ for (end = drivers; *end && **end; end++) ;
+ end--;
+
+ /*
+ * for each of the fallback drivers, if we find it in the list,
+ * swap it with the last available non-fallback driver.
+ */
+ for (i = 0; fallback[i]; i++) {
+ for (drv = drivers; drv != end; drv++) {
+ if (strstr(*drv, fallback[i])) {
+ x = *drv; *drv = *end; *end = x;
+ end--;
+ break;
+ }
+ }
+ }
+ /*
+ * since the ati wrapper driver is gross and awful, sort ati before
+ * atimisc, which makes sure all the ati symbols are visible in xorgcfg.
+ */
+ for (drv = drivers; drv != end; drv++) {
+ if (!strcmp(*drv, "atimisc")) {
+ atimisc = drv;
+ for (drv = atimisc; drv != end; drv++) {
+ if (!strcmp(*drv, "ati")) {
+ ati = drv;
+ x = *ati; *ati = *atimisc; *atimisc = x;
+ return;
+ }
+ }
+ /* if we get here, ati was already ahead of atimisc */
+ return;
+ }
+ }
+}
+
+static char **
+GenerateDriverlist(char * dirname)
+{
+ char **ret;
+ const char *subdirs[] = { dirname, NULL };
+ static const char *patlist[] = {"(.*)_drv\\.so", "(.*)_drv\\.o", NULL};
+ ret = LoaderListDirs(subdirs, patlist);
+
+ /* fix up the probe order for video drivers */
+ if (strstr(dirname, "drivers") && ret != NULL)
+ fixup_video_driver_list(ret);
+
+ return ret;
+}
+
+char **
+xf86DriverlistFromCompile(void)
+{
+ static char **driverlist = NULL;
+
+ if (!driverlist)
+ driverlist = GenerateDriverlist("drivers");
+
+ return driverlist;
+}
+
+/*
+ * xf86ConfigError --
+ * Print a READABLE ErrorMessage!!! All information that is
+ * available is printed.
+ */
+static void
+xf86ConfigError(char *msg, ...)
+{
+ va_list ap;
+
+ ErrorF("\nConfig Error:\n");
+ va_start(ap, msg);
+ VErrorF(msg, ap);
+ va_end(ap);
+ ErrorF("\n");
+ return;
+}
+
+static void
+configFiles(XF86ConfFilesPtr fileconf)
+{
+ MessageType pathFrom;
+ Bool must_copy;
+ int size, countDirs;
+ char *temp_path, *log_buf, *start, *end;
+
+ /* FontPath */
+ must_copy = TRUE;
+
+ temp_path = defaultFontPath ? defaultFontPath : "";
+ if (xf86fpFlag)
+ pathFrom = X_CMDLINE;
+ else if (fileconf && fileconf->file_fontpath) {
+ pathFrom = X_CONFIG;
+ if (xf86Info.useDefaultFontPath) {
+ defaultFontPath = Xprintf("%s%s%s",
+ fileconf->file_fontpath,
+ *temp_path ? "," : "", temp_path);
+ if (defaultFontPath != NULL) {
+ must_copy = FALSE;
+ }
+ }
+ else
+ defaultFontPath = fileconf->file_fontpath;
+ }
+ else
+ pathFrom = X_DEFAULT;
+ temp_path = defaultFontPath ? defaultFontPath : "";
+
+ /* xf86ValidateFontPath modifies its argument, but returns a copy of it. */
+ temp_path = must_copy ? xnfstrdup(defaultFontPath) : defaultFontPath;
+ defaultFontPath = xf86ValidateFontPath(temp_path);
+ free(temp_path);
+
+ /* make fontpath more readable in the logfiles */
+ countDirs = 1;
+ temp_path = defaultFontPath;
+ while ((temp_path = index(temp_path, ',')) != NULL) {
+ countDirs++;
+ temp_path++;
+ }
+
+ log_buf = xnfalloc(strlen(defaultFontPath) + (2 * countDirs) + 1);
+ temp_path = log_buf;
+ start = defaultFontPath;
+ while((end = index(start, ',')) != NULL) {
+ size = (end - start) + 1;
+ *(temp_path++) = '\t';
+ strncpy(temp_path, start, size);
+ temp_path += size;
+ *(temp_path++) = '\n';
+ start += size;
+ }
+ /* copy last entry */
+ *(temp_path++) = '\t';
+ strcpy(temp_path, start);
+ xf86Msg(pathFrom, "FontPath set to:\n%s\n", log_buf);
+ free(log_buf);
+
+ /* ModulePath */
+
+ if (fileconf) {
+ if (xf86ModPathFrom != X_CMDLINE && fileconf->file_modulepath) {
+ xf86ModulePath = fileconf->file_modulepath;
+ xf86ModPathFrom = X_CONFIG;
+ }
+ }
+
+ xf86Msg(xf86ModPathFrom, "ModulePath set to \"%s\"\n", xf86ModulePath);
+
+ if (!xf86xkbdirFlag && fileconf && fileconf->file_xkbdir) {
+ XkbBaseDirectory = fileconf->file_xkbdir;
+ xf86Msg(X_CONFIG, "XKB base directory set to \"%s\"\n",
+ XkbBaseDirectory);
+ }
+#if 0
+ /* LogFile */
+ /*
+ * XXX The problem with this is that the log file is already open.
+ * One option might be to copy the exiting contents to the new location.
+ * and re-open it. The down side is that the default location would
+ * already have been overwritten. Another option would be to start with
+ * unique temporary location, then copy it once the correct name is known.
+ * A problem with this is what happens if the server exits before that
+ * happens.
+ */
+ if (xf86LogFileFrom == X_DEFAULT && fileconf->file_logfile) {
+ xf86LogFile = fileconf->file_logfile;
+ xf86LogFileFrom = X_CONFIG;
+ }
+#endif
+
+ return;
+}
+
+typedef enum {
+ FLAG_NOTRAPSIGNALS,
+ FLAG_DONTVTSWITCH,
+ FLAG_DONTZAP,
+ FLAG_DONTZOOM,
+ FLAG_DISABLEVIDMODE,
+ FLAG_ALLOWNONLOCAL,
+ FLAG_ALLOWMOUSEOPENFAIL,
+ FLAG_VTSYSREQ,
+ FLAG_SAVER_BLANKTIME,
+ FLAG_DPMS_STANDBYTIME,
+ FLAG_DPMS_SUSPENDTIME,
+ FLAG_DPMS_OFFTIME,
+ FLAG_PIXMAP,
+ FLAG_PC98,
+ FLAG_NOPM,
+ FLAG_XINERAMA,
+ FLAG_LOG,
+ FLAG_RENDER_COLORMAP_MODE,
+ FLAG_RANDR,
+ FLAG_AIGLX,
+ FLAG_IGNORE_ABI,
+ FLAG_ALLOW_EMPTY_INPUT,
+ FLAG_USE_DEFAULT_FONT_PATH,
+ FLAG_AUTO_ADD_DEVICES,
+ FLAG_AUTO_ENABLE_DEVICES,
+ FLAG_GLX_VISUALS,
+ FLAG_DRI2,
+ FLAG_USE_SIGIO
+} FlagValues;
+
+/**
+ * NOTE: the last value for each entry is NOT the default. It is set to TRUE
+ * if the parser found the option in the config file.
+ */
+static OptionInfoRec FlagOptions[] = {
+ { FLAG_NOTRAPSIGNALS, "NoTrapSignals", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_DONTVTSWITCH, "DontVTSwitch", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_DONTZAP, "DontZap", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_DONTZOOM, "DontZoom", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_DISABLEVIDMODE, "DisableVidModeExtension", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_ALLOWNONLOCAL, "AllowNonLocalXvidtune", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_ALLOWMOUSEOPENFAIL, "AllowMouseOpenFail", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_VTSYSREQ, "VTSysReq", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_SAVER_BLANKTIME, "BlankTime" , OPTV_INTEGER,
+ {0}, FALSE },
+ { FLAG_DPMS_STANDBYTIME, "StandbyTime", OPTV_INTEGER,
+ {0}, FALSE },
+ { FLAG_DPMS_SUSPENDTIME, "SuspendTime", OPTV_INTEGER,
+ {0}, FALSE },
+ { FLAG_DPMS_OFFTIME, "OffTime", OPTV_INTEGER,
+ {0}, FALSE },
+ { FLAG_PIXMAP, "Pixmap", OPTV_INTEGER,
+ {0}, FALSE },
+ { FLAG_PC98, "PC98", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_NOPM, "NoPM", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_XINERAMA, "Xinerama", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_LOG, "Log", OPTV_STRING,
+ {0}, FALSE },
+ { FLAG_RENDER_COLORMAP_MODE, "RenderColormapMode", OPTV_STRING,
+ {0}, FALSE },
+ { FLAG_RANDR, "RandR", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_AIGLX, "AIGLX", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_ALLOW_EMPTY_INPUT, "AllowEmptyInput", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_IGNORE_ABI, "IgnoreABI", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_USE_DEFAULT_FONT_PATH, "UseDefaultFontPath", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_AUTO_ADD_DEVICES, "AutoAddDevices", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_AUTO_ENABLE_DEVICES, "AutoEnableDevices", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_GLX_VISUALS, "GlxVisuals", OPTV_STRING,
+ {0}, FALSE },
+ { FLAG_DRI2, "DRI2", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { FLAG_USE_SIGIO, "UseSIGIO", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { -1, NULL, OPTV_NONE,
+ {0}, FALSE },
+};
+
+#ifdef SUPPORT_PC98
+static Bool
+detectPC98(void)
+{
+ unsigned char buf[2];
+
+ if (xf86ReadBIOS(0xf8000, 0xe80, buf, 2) != 2)
+ return FALSE;
+ if ((buf[0] == 0x98) && (buf[1] == 0x21))
+ return TRUE;
+ else
+ return FALSE;
+}
+#endif
+
+static Bool
+configServerFlags(XF86ConfFlagsPtr flagsconf, XF86OptionPtr layoutopts)
+{
+ XF86OptionPtr optp, tmp;
+ int i;
+ Pix24Flags pix24 = Pix24DontCare;
+ Bool value;
+ MessageType from;
+ const char *s;
+ XkbRMLVOSet set;
+ /* Default options. */
+ set.rules = "base";
+ set.model = "pc105";
+ set.layout = "us";
+ set.variant = NULL;
+ set.options = NULL;
+
+ /*
+ * Merge the ServerLayout and ServerFlags options. The former have
+ * precedence over the latter.
+ */
+ optp = NULL;
+ if (flagsconf && flagsconf->flg_option_lst)
+ optp = xf86optionListDup(flagsconf->flg_option_lst);
+ if (layoutopts) {
+ tmp = xf86optionListDup(layoutopts);
+ if (optp)
+ optp = xf86optionListMerge(optp, tmp);
+ else
+ optp = tmp;
+ }
+
+ xf86ProcessOptions(-1, optp, FlagOptions);
+
+ xf86GetOptValBool(FlagOptions, FLAG_NOTRAPSIGNALS, &xf86Info.notrapSignals);
+ xf86GetOptValBool(FlagOptions, FLAG_DONTVTSWITCH, &xf86Info.dontVTSwitch);
+ xf86GetOptValBool(FlagOptions, FLAG_DONTZAP, &xf86Info.dontZap);
+ xf86GetOptValBool(FlagOptions, FLAG_DONTZOOM, &xf86Info.dontZoom);
+
+ xf86GetOptValBool(FlagOptions, FLAG_IGNORE_ABI, &xf86Info.ignoreABI);
+ if (xf86Info.ignoreABI) {
+ xf86Msg(X_CONFIG, "Ignoring ABI Version\n");
+ }
+
+ if (xf86SIGIOSupported()) {
+ xf86Info.useSIGIO = xf86ReturnOptValBool(FlagOptions, FLAG_USE_SIGIO, USE_SIGIO_BY_DEFAULT);
+ if (xf86IsOptionSet(FlagOptions, FLAG_USE_SIGIO)) {
+ from = X_CONFIG;
+ } else {
+ from = X_DEFAULT;
+ }
+ if (!xf86Info.useSIGIO) {
+ xf86Msg(from, "Disabling SIGIO handlers for input devices\n");
+ } else if (from == X_CONFIG) {
+ xf86Msg(from, "Enabling SIGIO handlers for input devices\n");
+ }
+ } else {
+ xf86Info.useSIGIO = FALSE;
+ }
+
+ if (xf86IsOptionSet(FlagOptions, FLAG_AUTO_ADD_DEVICES)) {
+ xf86GetOptValBool(FlagOptions, FLAG_AUTO_ADD_DEVICES,
+ &xf86Info.autoAddDevices);
+ from = X_CONFIG;
+ }
+ else {
+ from = X_DEFAULT;
+ }
+ xf86Msg(from, "%sutomatically adding devices\n",
+ xf86Info.autoAddDevices ? "A" : "Not a");
+
+ if (xf86IsOptionSet(FlagOptions, FLAG_AUTO_ENABLE_DEVICES)) {
+ xf86GetOptValBool(FlagOptions, FLAG_AUTO_ENABLE_DEVICES,
+ &xf86Info.autoEnableDevices);
+ from = X_CONFIG;
+ }
+ else {
+ from = X_DEFAULT;
+ }
+ xf86Msg(from, "%sutomatically enabling devices\n",
+ xf86Info.autoEnableDevices ? "A" : "Not a");
+
+ /*
+ * Set things up based on the config file information. Some of these
+ * settings may be overridden later when the command line options are
+ * checked.
+ */
+#ifdef XF86VIDMODE
+ if (xf86GetOptValBool(FlagOptions, FLAG_DISABLEVIDMODE, &value))
+ xf86Info.vidModeEnabled = !value;
+ if (xf86GetOptValBool(FlagOptions, FLAG_ALLOWNONLOCAL, &value))
+ xf86Info.vidModeAllowNonLocal = value;
+#endif
+
+ if (xf86GetOptValBool(FlagOptions, FLAG_ALLOWMOUSEOPENFAIL, &value))
+ xf86Info.allowMouseOpenFail = value;
+
+ if (xf86GetOptValBool(FlagOptions, FLAG_VTSYSREQ, &value)) {
+#ifdef USE_VT_SYSREQ
+ xf86Info.vtSysreq = value;
+ xf86Msg(X_CONFIG, "VTSysReq %s\n", value ? "enabled" : "disabled");
+#else
+ if (value)
+ xf86Msg(X_WARNING, "VTSysReq is not supported on this OS\n");
+#endif
+ }
+
+ xf86Info.pmFlag = TRUE;
+ if (xf86GetOptValBool(FlagOptions, FLAG_NOPM, &value))
+ xf86Info.pmFlag = !value;
+ {
+ if ((s = xf86GetOptValString(FlagOptions, FLAG_LOG))) {
+ if (!xf86NameCmp(s,"flush")) {
+ xf86Msg(X_CONFIG, "Flushing logfile enabled\n");
+ xf86Info.log = LogFlush;
+ LogSetParameter(XLOG_FLUSH, TRUE);
+ } else if (!xf86NameCmp(s,"sync")) {
+ xf86Msg(X_CONFIG, "Syncing logfile enabled\n");
+ xf86Info.log = LogSync;
+ LogSetParameter(XLOG_FLUSH, TRUE);
+ LogSetParameter(XLOG_SYNC, TRUE);
+ } else {
+ xf86Msg(X_WARNING,"Unknown Log option\n");
+ }
+ }
+ }
+
+ {
+ if ((s = xf86GetOptValString(FlagOptions, FLAG_RENDER_COLORMAP_MODE))){
+ int policy = PictureParseCmapPolicy (s);
+ if (policy == PictureCmapPolicyInvalid)
+ xf86Msg(X_WARNING, "Unknown colormap policy \"%s\"\n", s);
+ else
+ {
+ xf86Msg(X_CONFIG, "Render colormap policy set to %s\n", s);
+ PictureCmapPolicy = policy;
+ }
+ }
+ }
+
+#ifdef RANDR
+ xf86Info.disableRandR = FALSE;
+ xf86Info.randRFrom = X_DEFAULT;
+ if (xf86GetOptValBool(FlagOptions, FLAG_RANDR, &value)) {
+ xf86Info.disableRandR = !value;
+ xf86Info.randRFrom = X_CONFIG;
+ }
+#endif
+
+ xf86Info.aiglx = TRUE;
+ xf86Info.aiglxFrom = X_DEFAULT;
+ if (xf86GetOptValBool(FlagOptions, FLAG_AIGLX, &value)) {
+ xf86Info.aiglx = value;
+ xf86Info.aiglxFrom = X_CONFIG;
+ }
+
+#ifdef GLXEXT
+ xf86Info.glxVisuals = XF86_GlxVisualsTypical;
+ xf86Info.glxVisualsFrom = X_DEFAULT;
+ if ((s = xf86GetOptValString(FlagOptions, FLAG_GLX_VISUALS))) {
+ if (!xf86NameCmp(s, "minimal")) {
+ xf86Info.glxVisuals = XF86_GlxVisualsMinimal;
+ } else if (!xf86NameCmp(s, "typical")) {
+ xf86Info.glxVisuals = XF86_GlxVisualsTypical;
+ } else if (!xf86NameCmp(s, "all")) {
+ xf86Info.glxVisuals = XF86_GlxVisualsAll;
+ } else {
+ xf86Msg(X_WARNING,"Unknown GlxVisuals option\n");
+ }
+ }
+
+ if (xf86GetOptValBool(FlagOptions, FLAG_AIGLX, &value)) {
+ xf86Info.aiglx = value;
+ xf86Info.aiglxFrom = X_CONFIG;
+ }
+#endif
+
+ /* AllowEmptyInput is automatically true if we're hotplugging */
+ xf86Info.allowEmptyInput = (xf86Info.autoAddDevices && xf86Info.autoEnableDevices);
+ xf86GetOptValBool(FlagOptions, FLAG_ALLOW_EMPTY_INPUT, &xf86Info.allowEmptyInput);
+
+ /* AEI on? Then we're not using kbd, so use the evdev rules set. */
+#if defined(linux)
+ if (xf86Info.allowEmptyInput)
+ set.rules = "evdev";
+#endif
+ XkbSetRulesDflts(&set);
+
+ xf86Info.useDefaultFontPath = TRUE;
+ xf86Info.useDefaultFontPathFrom = X_DEFAULT;
+ if (xf86GetOptValBool(FlagOptions, FLAG_USE_DEFAULT_FONT_PATH, &value)) {
+ xf86Info.useDefaultFontPath = value;
+ xf86Info.useDefaultFontPathFrom = X_CONFIG;
+ }
+
+/* Make sure that timers don't overflow CARD32's after multiplying */
+#define MAX_TIME_IN_MIN (0x7fffffff / MILLI_PER_MIN)
+
+ i = -1;
+ xf86GetOptValInteger(FlagOptions, FLAG_SAVER_BLANKTIME, &i);
+ if ((i >= 0) && (i < MAX_TIME_IN_MIN))
+ ScreenSaverTime = defaultScreenSaverTime = i * MILLI_PER_MIN;
+ else if (i != -1)
+ xf86ConfigError("BlankTime value %d outside legal range of 0 - %d minutes",
+ i, MAX_TIME_IN_MIN);
+
+#ifdef DPMSExtension
+ i = -1;
+ xf86GetOptValInteger(FlagOptions, FLAG_DPMS_STANDBYTIME, &i);
+ if ((i >= 0) && (i < MAX_TIME_IN_MIN))
+ DPMSStandbyTime = i * MILLI_PER_MIN;
+ else if (i != -1)
+ xf86ConfigError("StandbyTime value %d outside legal range of 0 - %d minutes",
+ i, MAX_TIME_IN_MIN);
+ i = -1;
+ xf86GetOptValInteger(FlagOptions, FLAG_DPMS_SUSPENDTIME, &i);
+ if ((i >= 0) && (i < MAX_TIME_IN_MIN))
+ DPMSSuspendTime = i * MILLI_PER_MIN;
+ else if (i != -1)
+ xf86ConfigError("SuspendTime value %d outside legal range of 0 - %d minutes",
+ i, MAX_TIME_IN_MIN);
+ i = -1;
+ xf86GetOptValInteger(FlagOptions, FLAG_DPMS_OFFTIME, &i);
+ if ((i >= 0) && (i < MAX_TIME_IN_MIN))
+ DPMSOffTime = i * MILLI_PER_MIN;
+ else if (i != -1)
+ xf86ConfigError("OffTime value %d outside legal range of 0 - %d minutes",
+ i, MAX_TIME_IN_MIN);
+#endif
+
+ i = -1;
+ xf86GetOptValInteger(FlagOptions, FLAG_PIXMAP, &i);
+ switch (i) {
+ case 24:
+ pix24 = Pix24Use24;
+ break;
+ case 32:
+ pix24 = Pix24Use32;
+ break;
+ case -1:
+ break;
+ default:
+ xf86ConfigError("Pixmap option's value (%d) must be 24 or 32\n", i);
+ return FALSE;
+ }
+ if (xf86Pix24 != Pix24DontCare) {
+ xf86Info.pixmap24 = xf86Pix24;
+ xf86Info.pix24From = X_CMDLINE;
+ } else if (pix24 != Pix24DontCare) {
+ xf86Info.pixmap24 = pix24;
+ xf86Info.pix24From = X_CONFIG;
+ } else {
+ xf86Info.pixmap24 = Pix24DontCare;
+ xf86Info.pix24From = X_DEFAULT;
+ }
+#ifdef SUPPORT_PC98
+ if (xf86GetOptValBool(FlagOptions, FLAG_PC98, &value)) {
+ xf86Info.pc98 = value;
+ if (value) {
+ xf86Msg(X_CONFIG, "Japanese PC98 architecture\n");
+ }
+ } else
+ if (detectPC98()) {
+ xf86Info.pc98 = TRUE;
+ xf86Msg(X_PROBED, "Japanese PC98 architecture\n");
+ }
+#endif
+
+#ifdef PANORAMIX
+ from = X_DEFAULT;
+ if (!noPanoramiXExtension)
+ from = X_CMDLINE;
+ else if (xf86GetOptValBool(FlagOptions, FLAG_XINERAMA, &value)) {
+ noPanoramiXExtension = !value;
+ from = X_CONFIG;
+ }
+ if (!noPanoramiXExtension)
+ xf86Msg(from, "Xinerama: enabled\n");
+#endif
+
+#ifdef DRI2
+ xf86Info.dri2 = FALSE;
+ xf86Info.dri2From = X_DEFAULT;
+ if (xf86GetOptValBool(FlagOptions, FLAG_DRI2, &value)) {
+ xf86Info.dri2 = value;
+ xf86Info.dri2From = X_CONFIG;
+ }
+#endif
+
+ return TRUE;
+}
+
+Bool xf86DRI2Enabled(void)
+{
+ return xf86Info.dri2;
+}
+
+/*
+ * Locate the core input devices. These can be specified/located in
+ * the following ways, in order of priority:
+ *
+ * 1. The InputDevices named by the -pointer and -keyboard command line
+ * options.
+ * 2. The "CorePointer" and "CoreKeyboard" InputDevices referred to by
+ * the active ServerLayout.
+ * 3. The first InputDevices marked as "CorePointer" and "CoreKeyboard".
+ * 4. The first InputDevices that use 'keyboard' or 'kbd' and a valid mouse
+ * driver (mouse, synaptics, evdev, vmmouse, void)
+ * 5. Default devices with an empty (default) configuration. These defaults
+ * will reference the 'mouse' and 'keyboard' drivers.
+ */
+
+static Bool
+checkCoreInputDevices(serverLayoutPtr servlayoutp, Bool implicitLayout)
+{
+ IDevPtr corePointer = NULL, coreKeyboard = NULL;
+ Bool foundPointer = FALSE, foundKeyboard = FALSE;
+ const char *pointerMsg = NULL, *keyboardMsg = NULL;
+ IDevPtr *devs, /* iterator */
+ indp;
+ IDevRec Pointer, Keyboard;
+ XF86ConfInputPtr confInput;
+ XF86ConfInputRec defPtr, defKbd;
+ int count = 0;
+ MessageType from = X_DEFAULT;
+ int found = 0;
+ const char *mousedrivers[] = { "mouse", "synaptics", "evdev", "vmmouse",
+ "void", NULL };
+
+ /*
+ * First check if a core pointer or core keyboard have been specified
+ * in the active ServerLayout. If more than one is specified for either,
+ * remove the core attribute from the later ones.
+ */
+ for (devs = servlayoutp->inputs; devs && *devs; devs++) {
+ pointer opt1 = NULL, opt2 = NULL;
+ indp = *devs;
+ if (indp->commonOptions &&
+ xf86CheckBoolOption(indp->commonOptions, "CorePointer", FALSE)) {
+ opt1 = indp->commonOptions;
+ }
+ if (indp->extraOptions &&
+ xf86CheckBoolOption(indp->extraOptions, "CorePointer", FALSE)) {
+ opt2 = indp->extraOptions;
+ }
+ if (opt1 || opt2) {
+ if (!corePointer) {
+ corePointer = indp;
+ } else {
+ if (opt1)
+ xf86ReplaceBoolOption(opt1, "CorePointer", FALSE);
+ if (opt2)
+ xf86ReplaceBoolOption(opt2, "CorePointer", FALSE);
+ xf86Msg(X_WARNING, "Duplicate core pointer devices. "
+ "Removing core pointer attribute from \"%s\"\n",
+ indp->identifier);
+ }
+ }
+ opt1 = opt2 = NULL;
+ if (indp->commonOptions &&
+ xf86CheckBoolOption(indp->commonOptions, "CoreKeyboard", FALSE)) {
+ opt1 = indp->commonOptions;
+ }
+ if (indp->extraOptions &&
+ xf86CheckBoolOption(indp->extraOptions, "CoreKeyboard", FALSE)) {
+ opt2 = indp->extraOptions;
+ }
+ if (opt1 || opt2) {
+ if (!coreKeyboard) {
+ coreKeyboard = indp;
+ } else {
+ if (opt1)
+ xf86ReplaceBoolOption(opt1, "CoreKeyboard", FALSE);
+ if (opt2)
+ xf86ReplaceBoolOption(opt2, "CoreKeyboard", FALSE);
+ xf86Msg(X_WARNING, "Duplicate core keyboard devices. "
+ "Removing core keyboard attribute from \"%s\"\n",
+ indp->identifier);
+ }
+ }
+ count++;
+ }
+
+ confInput = NULL;
+
+ /* 1. Check for the -pointer command line option. */
+ if (xf86PointerName) {
+ confInput = xf86findInput(xf86PointerName,
+ xf86configptr->conf_input_lst);
+ if (!confInput) {
+ xf86Msg(X_ERROR, "No InputDevice section called \"%s\"\n",
+ xf86PointerName);
+ return FALSE;
+ }
+ from = X_CMDLINE;
+ /*
+ * If one was already specified in the ServerLayout, it needs to be
+ * removed.
+ */
+ if (corePointer) {
+ for (devs = servlayoutp->inputs; devs && *devs; devs++)
+ if (*devs == corePointer)
+ {
+ free(*devs);
+ *devs = (IDevPtr)0x1; /* ensure we dont skip next loop*/
+ break;
+ }
+ for (; devs && *devs; devs++)
+ devs[0] = devs[1];
+ count--;
+ }
+ corePointer = NULL;
+ foundPointer = TRUE;
+ }
+
+ /* 2. ServerLayout-specified core pointer. */
+ if (corePointer) {
+ foundPointer = TRUE;
+ from = X_CONFIG;
+ }
+
+ /* 3. First core pointer device. */
+ if (!foundPointer && (!xf86Info.allowEmptyInput || implicitLayout)) {
+ XF86ConfInputPtr p;
+
+ for (p = xf86configptr->conf_input_lst; p; p = p->list.next) {
+ if (p->inp_option_lst &&
+ xf86CheckBoolOption(p->inp_option_lst, "CorePointer", FALSE)) {
+ confInput = p;
+ foundPointer = TRUE;
+ from = X_DEFAULT;
+ pointerMsg = "first core pointer device";
+ break;
+ }
+ }
+ }
+
+ /* 4. First pointer with an allowed mouse driver. */
+ if (!foundPointer && !xf86Info.allowEmptyInput) {
+ const char **driver = mousedrivers;
+ confInput = xf86findInput(CONF_IMPLICIT_POINTER,
+ xf86configptr->conf_input_lst);
+ while (*driver && !confInput) {
+ confInput = xf86findInputByDriver(*driver,
+ xf86configptr->conf_input_lst);
+ driver++;
+ }
+ if (confInput) {
+ foundPointer = TRUE;
+ from = X_DEFAULT;
+ pointerMsg = "first mouse device";
+ }
+ }
+
+ /* 5. Built-in default. */
+ if (!foundPointer && !xf86Info.allowEmptyInput) {
+ bzero(&defPtr, sizeof(defPtr));
+ defPtr.inp_identifier = strdup("<default pointer>");
+ defPtr.inp_driver = strdup("mouse");
+ confInput = &defPtr;
+ foundPointer = TRUE;
+ from = X_DEFAULT;
+ pointerMsg = "default mouse configuration";
+ }
+
+ /* Add the core pointer device to the layout, and set it to Core. */
+ if (foundPointer && confInput) {
+ foundPointer = configInput(&Pointer, confInput, from);
+ if (foundPointer) {
+ count++;
+ devs = xnfrealloc(servlayoutp->inputs,
+ (count + 1) * sizeof(IDevPtr));
+ devs[count - 1] = xnfalloc(sizeof(IDevRec));
+ *devs[count - 1] = Pointer;
+ devs[count - 1]->extraOptions =
+ xf86addNewOption(NULL, xnfstrdup("CorePointer"), NULL);
+ devs[count] = NULL;
+ servlayoutp->inputs = devs;
+ }
+ }
+
+ if (!foundPointer && !xf86Info.allowEmptyInput) {
+ /* This shouldn't happen. */
+ xf86Msg(X_ERROR, "Cannot locate a core pointer device.\n");
+ return FALSE;
+ }
+
+ /*
+ * always synthesize a 'mouse' section configured to send core
+ * events, unless a 'void' section is found, in which case the user
+ * probably wants to run footless.
+ *
+ * If you're using an evdev keyboard and expect a default mouse
+ * section ... deal.
+ */
+ for (devs = servlayoutp->inputs; devs && *devs; devs++) {
+ const char **driver = mousedrivers;
+ while(*driver) {
+ if (!strcmp((*devs)->driver, *driver)) {
+ found = 1;
+ break;
+ }
+ driver++;
+ }
+ }
+ if (!found && !xf86Info.allowEmptyInput) {
+ xf86Msg(X_INFO, "No default mouse found, adding one\n");
+ bzero(&defPtr, sizeof(defPtr));
+ defPtr.inp_identifier = strdup("<default pointer>");
+ defPtr.inp_driver = strdup("mouse");
+ confInput = &defPtr;
+ foundPointer = configInput(&Pointer, confInput, from);
+ if (foundPointer) {
+ count++;
+ devs = xnfrealloc(servlayoutp->inputs,
+ (count + 1) * sizeof(IDevPtr));
+ devs[count - 1] = xnfalloc(sizeof(IDevRec));
+ *devs[count - 1] = Pointer;
+ devs[count - 1]->extraOptions =
+ xf86addNewOption(NULL, xnfstrdup("AlwaysCore"), NULL);
+ devs[count] = NULL;
+ servlayoutp->inputs = devs;
+ }
+ }
+
+ confInput = NULL;
+
+ /* 1. Check for the -keyboard command line option. */
+ if (xf86KeyboardName) {
+ confInput = xf86findInput(xf86KeyboardName,
+ xf86configptr->conf_input_lst);
+ if (!confInput) {
+ xf86Msg(X_ERROR, "No InputDevice section called \"%s\"\n",
+ xf86KeyboardName);
+ return FALSE;
+ }
+ from = X_CMDLINE;
+ /*
+ * If one was already specified in the ServerLayout, it needs to be
+ * removed.
+ */
+ if (coreKeyboard) {
+ for (devs = servlayoutp->inputs; devs && *devs; devs++)
+ if (*devs == coreKeyboard)
+ {
+ free(*devs);
+ *devs = (IDevPtr)0x1; /* ensure we dont skip next loop */
+ break;
+ }
+ for (; devs && *devs; devs++)
+ devs[0] = devs[1];
+ count--;
+ }
+ coreKeyboard = NULL;
+ foundKeyboard = TRUE;
+ }
+
+ /* 2. ServerLayout-specified core keyboard. */
+ if (coreKeyboard) {
+ foundKeyboard = TRUE;
+ from = X_CONFIG;
+ }
+
+ /* 3. First core keyboard device. */
+ if (!foundKeyboard && (!xf86Info.allowEmptyInput || implicitLayout)) {
+ XF86ConfInputPtr p;
+
+ for (p = xf86configptr->conf_input_lst; p; p = p->list.next) {
+ if (p->inp_option_lst &&
+ xf86CheckBoolOption(p->inp_option_lst, "CoreKeyboard", FALSE)) {
+ confInput = p;
+ foundKeyboard = TRUE;
+ from = X_DEFAULT;
+ keyboardMsg = "first core keyboard device";
+ break;
+ }
+ }
+ }
+
+ /* 4. First keyboard with 'keyboard' or 'kbd' as the driver. */
+ if (!foundKeyboard && !xf86Info.allowEmptyInput) {
+ confInput = xf86findInput(CONF_IMPLICIT_KEYBOARD,
+ xf86configptr->conf_input_lst);
+ if (!confInput) {
+ confInput = xf86findInputByDriver("kbd",
+ xf86configptr->conf_input_lst);
+ }
+ if (confInput) {
+ foundKeyboard = TRUE;
+ from = X_DEFAULT;
+ keyboardMsg = "first keyboard device";
+ }
+ }
+
+ /* 5. Built-in default. */
+ if (!foundKeyboard && !xf86Info.allowEmptyInput) {
+ bzero(&defKbd, sizeof(defKbd));
+ defKbd.inp_identifier = strdup("<default keyboard>");
+ defKbd.inp_driver = strdup("kbd");
+ confInput = &defKbd;
+ foundKeyboard = TRUE;
+ keyboardMsg = "default keyboard configuration";
+ from = X_DEFAULT;
+ }
+
+ /* Add the core keyboard device to the layout, and set it to Core. */
+ if (foundKeyboard && confInput) {
+ foundKeyboard = configInput(&Keyboard, confInput, from);
+ if (foundKeyboard) {
+ count++;
+ devs = xnfrealloc(servlayoutp->inputs,
+ (count + 1) * sizeof(IDevPtr));
+ devs[count - 1] = xnfalloc(sizeof(IDevRec));
+ *devs[count - 1] = Keyboard;
+ devs[count - 1]->extraOptions =
+ xf86addNewOption(NULL, xnfstrdup("CoreKeyboard"), NULL);
+ devs[count] = NULL;
+ servlayoutp->inputs = devs;
+ }
+ }
+
+ if (!foundKeyboard && !xf86Info.allowEmptyInput) {
+ /* This shouldn't happen. */
+ xf86Msg(X_ERROR, "Cannot locate a core keyboard device.\n");
+ return FALSE;
+ }
+
+ if (pointerMsg) {
+ if (implicitLayout)
+ xf86Msg(X_DEFAULT, "No Layout section. Using the %s.\n",
+ pointerMsg);
+ else
+ xf86Msg(X_DEFAULT, "The core pointer device wasn't specified "
+ "explicitly in the layout.\n"
+ "\tUsing the %s.\n", pointerMsg);
+ }
+
+ if (keyboardMsg) {
+ if (implicitLayout)
+ xf86Msg(X_DEFAULT, "No Layout section. Using the %s.\n",
+ keyboardMsg);
+ else
+ xf86Msg(X_DEFAULT, "The core keyboard device wasn't specified "
+ "explicitly in the layout.\n"
+ "\tUsing the %s.\n", keyboardMsg);
+ }
+
+ if (xf86Info.allowEmptyInput && !(foundPointer && foundKeyboard)) {
+#if defined(CONFIG_HAL) || defined(CONFIG_UDEV)
+ const char *config_backend;
+#if defined(CONFIG_HAL)
+ config_backend = "HAL";
+#else
+ config_backend = "udev";
+#endif
+ xf86Msg(X_INFO, "The server relies on %s to provide the list of "
+ "input devices.\n\tIf no devices become available, "
+ "reconfigure %s or disable AutoAddDevices.\n",
+ config_backend, config_backend);
+#else
+ xf86Msg(X_INFO, "Hotplugging is disabled and no input devices were configured.\n"
+ "\tTry disabling AllowEmptyInput.\n");
+#endif
+ }
+
+ return TRUE;
+}
+
+typedef enum {
+ LAYOUT_ISOLATEDEVICE,
+ LAYOUT_SINGLECARD
+} LayoutValues;
+
+static OptionInfoRec LayoutOptions[] = {
+ { LAYOUT_ISOLATEDEVICE, "IsolateDevice", OPTV_STRING,
+ {0}, FALSE },
+ { LAYOUT_SINGLECARD, "SingleCard", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { -1, NULL, OPTV_NONE,
+ {0}, FALSE },
+};
+
+static Bool
+configInputDevices(XF86ConfLayoutPtr layout, serverLayoutPtr servlayoutp)
+{
+ XF86ConfInputrefPtr irp;
+ IDevPtr *indp;
+ int count = 0;
+
+ /*
+ * Count the number of input devices.
+ */
+ irp = layout->lay_input_lst;
+ while (irp) {
+ count++;
+ irp = (XF86ConfInputrefPtr)irp->list.next;
+ }
+ DebugF("Found %d input devices in the layout section %s\n",
+ count, layout->lay_identifier);
+ indp = xnfcalloc((count + 1), sizeof(IDevPtr));
+ indp[count] = NULL;
+ irp = layout->lay_input_lst;
+ count = 0;
+ while (irp) {
+ indp[count] = xnfalloc(sizeof(IDevRec));
+ if (!configInput(indp[count], irp->iref_inputdev, X_CONFIG)) {
+ while(count--)
+ free(indp[count]);
+ free(indp);
+ return FALSE;
+ }
+ indp[count]->extraOptions = irp->iref_option_lst;
+ count++;
+ irp = (XF86ConfInputrefPtr)irp->list.next;
+ }
+ servlayoutp->inputs = indp;
+
+ return TRUE;
+}
+
+
+/*
+ * figure out which layout is active, which screens are used in that layout,
+ * which drivers and monitors are used in these screens
+ */
+static Bool
+configLayout(serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout,
+ char *default_layout)
+{
+ XF86ConfAdjacencyPtr adjp;
+ XF86ConfInactivePtr idp;
+ int count = 0;
+ int scrnum;
+ XF86ConfLayoutPtr l;
+ MessageType from;
+ screenLayoutPtr slp;
+ GDevPtr gdp;
+ int i = 0, j;
+
+ if (!servlayoutp)
+ return FALSE;
+
+ /*
+ * which layout section is the active one?
+ *
+ * If there is a -layout command line option, use that one, otherwise
+ * pick the first one.
+ */
+ from = X_DEFAULT;
+ if (xf86LayoutName != NULL)
+ from = X_CMDLINE;
+ else if (default_layout) {
+ xf86LayoutName = default_layout;
+ from = X_CONFIG;
+ }
+ if (xf86LayoutName != NULL) {
+ if ((l = xf86findLayout(xf86LayoutName, conf_layout)) == NULL) {
+ xf86Msg(X_ERROR, "No ServerLayout section called \"%s\"\n",
+ xf86LayoutName);
+ return FALSE;
+ }
+ conf_layout = l;
+ }
+ xf86Msg(from, "ServerLayout \"%s\"\n", conf_layout->lay_identifier);
+ adjp = conf_layout->lay_adjacency_lst;
+
+ /*
+ * we know that each screen is referenced exactly once on the left side
+ * of a layout statement in the Layout section. So to allocate the right
+ * size for the array we do a quick walk of the list to figure out how
+ * many sections we have
+ */
+ while (adjp) {
+ count++;
+ adjp = (XF86ConfAdjacencyPtr)adjp->list.next;
+ }
+
+ DebugF("Found %d screens in the layout section %s",
+ count, conf_layout->lay_identifier);
+ if (!count) /* alloc enough storage even if no screen is specified */
+ count = 1;
+
+ slp = xnfcalloc(1, (count + 1) * sizeof(screenLayoutRec));
+ slp[count].screen = NULL;
+ /*
+ * now that we have storage, loop over the list again and fill in our
+ * data structure; at this point we do not fill in the adjacency
+ * information as it is not clear if we need it at all
+ */
+ adjp = conf_layout->lay_adjacency_lst;
+ count = 0;
+ while (adjp) {
+ slp[count].screen = xnfcalloc(1, sizeof(confScreenRec));
+ if (adjp->adj_scrnum < 0)
+ scrnum = count;
+ else
+ scrnum = adjp->adj_scrnum;
+ if (!configScreen(slp[count].screen, adjp->adj_screen, scrnum,
+ X_CONFIG)) {
+ free(slp);
+ return FALSE;
+ }
+ slp[count].x = adjp->adj_x;
+ slp[count].y = adjp->adj_y;
+ slp[count].refname = adjp->adj_refscreen;
+ switch (adjp->adj_where) {
+ case CONF_ADJ_OBSOLETE:
+ slp[count].where = PosObsolete;
+ slp[count].topname = adjp->adj_top_str;
+ slp[count].bottomname = adjp->adj_bottom_str;
+ slp[count].leftname = adjp->adj_left_str;
+ slp[count].rightname = adjp->adj_right_str;
+ break;
+ case CONF_ADJ_ABSOLUTE:
+ slp[count].where = PosAbsolute;
+ break;
+ case CONF_ADJ_RIGHTOF:
+ slp[count].where = PosRightOf;
+ break;
+ case CONF_ADJ_LEFTOF:
+ slp[count].where = PosLeftOf;
+ break;
+ case CONF_ADJ_ABOVE:
+ slp[count].where = PosAbove;
+ break;
+ case CONF_ADJ_BELOW:
+ slp[count].where = PosBelow;
+ break;
+ case CONF_ADJ_RELATIVE:
+ slp[count].where = PosRelative;
+ break;
+ }
+ count++;
+ adjp = (XF86ConfAdjacencyPtr)adjp->list.next;
+ }
+
+ /* No screen was specified in the layout. take the first one from the
+ * config file, or - if it is NULL - configScreen autogenerates one for
+ * us */
+ if (!count)
+ {
+ slp[0].screen = xnfcalloc(1, sizeof(confScreenRec));
+ if (!configScreen(slp[0].screen, xf86configptr->conf_screen_lst,
+ 0, X_CONFIG)) {
+ free(slp[0].screen);
+ free(slp);
+ return FALSE;
+ }
+ }
+
+ /* XXX Need to tie down the upper left screen. */
+
+ /* Fill in the refscreen and top/bottom/left/right values */
+ for (i = 0; i < count; i++) {
+ for (j = 0; j < count; j++) {
+ if (slp[i].refname &&
+ strcmp(slp[i].refname, slp[j].screen->id) == 0) {
+ slp[i].refscreen = slp[j].screen;
+ }
+ if (slp[i].topname &&
+ strcmp(slp[i].topname, slp[j].screen->id) == 0) {
+ slp[i].top = slp[j].screen;
+ }
+ if (slp[i].bottomname &&
+ strcmp(slp[i].bottomname, slp[j].screen->id) == 0) {
+ slp[i].bottom = slp[j].screen;
+ }
+ if (slp[i].leftname &&
+ strcmp(slp[i].leftname, slp[j].screen->id) == 0) {
+ slp[i].left = slp[j].screen;
+ }
+ if (slp[i].rightname &&
+ strcmp(slp[i].rightname, slp[j].screen->id) == 0) {
+ slp[i].right = slp[j].screen;
+ }
+ }
+ if (slp[i].where != PosObsolete
+ && slp[i].where != PosAbsolute
+ && !slp[i].refscreen) {
+ xf86Msg(X_ERROR,"Screen %s doesn't exist: deleting placement\n",
+ slp[i].refname);
+ slp[i].where = PosAbsolute;
+ slp[i].x = 0;
+ slp[i].y = 0;
+ }
+ }
+
+ /*
+ * Count the number of inactive devices.
+ */
+ count = 0;
+ idp = conf_layout->lay_inactive_lst;
+ while (idp) {
+ count++;
+ idp = (XF86ConfInactivePtr)idp->list.next;
+ }
+ DebugF("Found %d inactive devices in the layout section %s\n",
+ count, conf_layout->lay_identifier);
+ gdp = xnfalloc((count + 1) * sizeof(GDevRec));
+ gdp[count].identifier = NULL;
+ idp = conf_layout->lay_inactive_lst;
+ count = 0;
+ while (idp) {
+ if (!configDevice(&gdp[count], idp->inactive_device, FALSE)) {
+ free(gdp);
+ return FALSE;
+ }
+ count++;
+ idp = (XF86ConfInactivePtr)idp->list.next;
+ }
+
+ if (!configInputDevices(conf_layout, servlayoutp))
+ return FALSE;
+
+ servlayoutp->id = conf_layout->lay_identifier;
+ servlayoutp->screens = slp;
+ servlayoutp->inactives = gdp;
+ servlayoutp->options = conf_layout->lay_option_lst;
+ from = X_DEFAULT;
+
+ return TRUE;
+}
+
+/*
+ * No layout section, so find the first Screen section and set that up as
+ * the only active screen.
+ */
+static Bool
+configImpliedLayout(serverLayoutPtr servlayoutp, XF86ConfScreenPtr conf_screen,
+ XF86ConfigPtr xf86configptr)
+{
+ MessageType from;
+ XF86ConfScreenPtr s;
+ screenLayoutPtr slp;
+ IDevPtr *indp;
+ XF86ConfLayoutRec layout;
+
+ if (!servlayoutp)
+ return FALSE;
+
+ /*
+ * which screen section is the active one?
+ *
+ * If there is a -screen option, use that one, otherwise use the first
+ * one.
+ */
+
+ from = X_CONFIG;
+ if (xf86ScreenName != NULL) {
+ if ((s = xf86findScreen(xf86ScreenName, conf_screen)) == NULL) {
+ xf86Msg(X_ERROR, "No Screen section called \"%s\"\n",
+ xf86ScreenName);
+ return FALSE;
+ }
+ conf_screen = s;
+ from = X_CMDLINE;
+ }
+
+ /* We have exactly one screen */
+
+ slp = xnfcalloc(1, 2 * sizeof(screenLayoutRec));
+ slp[0].screen = xnfcalloc(1, sizeof(confScreenRec));
+ slp[1].screen = NULL;
+ if (!configScreen(slp[0].screen, conf_screen, 0, from)) {
+ free(slp);
+ return FALSE;
+ }
+ servlayoutp->id = "(implicit)";
+ servlayoutp->screens = slp;
+ servlayoutp->inactives = xnfcalloc(1, sizeof(GDevRec));
+ servlayoutp->options = NULL;
+
+ memset(&layout, 0, sizeof(layout));
+ layout.lay_identifier = servlayoutp->id;
+ if (xf86layoutAddInputDevices(xf86configptr, &layout) > 0) {
+ if (!configInputDevices(&layout, servlayoutp))
+ return FALSE;
+ from = X_DEFAULT;
+ } else {
+ /* Set up an empty input device list, then look for some core devices. */
+ indp = xnfalloc(sizeof(IDevPtr));
+ *indp = NULL;
+ servlayoutp->inputs = indp;
+ }
+
+ return TRUE;
+}
+
+static Bool
+configXvAdaptor(confXvAdaptorPtr adaptor, XF86ConfVideoAdaptorPtr conf_adaptor)
+{
+ int count = 0;
+ XF86ConfVideoPortPtr conf_port;
+
+ xf86Msg(X_CONFIG, "| |-->VideoAdaptor \"%s\"\n",
+ conf_adaptor->va_identifier);
+ adaptor->identifier = conf_adaptor->va_identifier;
+ adaptor->options = conf_adaptor->va_option_lst;
+ if (conf_adaptor->va_busid || conf_adaptor->va_driver) {
+ xf86Msg(X_CONFIG, "| | Unsupported device type, skipping entry\n");
+ return FALSE;
+ }
+
+ /*
+ * figure out how many videoport subsections there are and fill them in
+ */
+ conf_port = conf_adaptor->va_port_lst;
+ while(conf_port) {
+ count++;
+ conf_port = (XF86ConfVideoPortPtr)conf_port->list.next;
+ }
+ adaptor->ports = xnfalloc((count) * sizeof(confXvPortRec));
+ adaptor->numports = count;
+ count = 0;
+ conf_port = conf_adaptor->va_port_lst;
+ while(conf_port) {
+ adaptor->ports[count].identifier = conf_port->vp_identifier;
+ adaptor->ports[count].options = conf_port->vp_option_lst;
+ count++;
+ conf_port = (XF86ConfVideoPortPtr)conf_port->list.next;
+ }
+
+ return TRUE;
+}
+
+static Bool
+configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum,
+ MessageType from)
+{
+ int count = 0;
+ XF86ConfDisplayPtr dispptr;
+ XF86ConfAdaptorLinkPtr conf_adaptor;
+ Bool defaultMonitor = FALSE;
+
+ if (!conf_screen) {
+ conf_screen = xnfcalloc(1, sizeof(XF86ConfScreenRec));
+ conf_screen->scrn_identifier = "Default Screen Section";
+ xf86Msg(X_DEFAULT, "No screen section available. Using defaults.\n");
+ }
+
+ xf86Msg(from, "|-->Screen \"%s\" (%d)\n", conf_screen->scrn_identifier,
+ scrnum);
+ /*
+ * now we fill in the elements of the screen
+ */
+ screenp->id = conf_screen->scrn_identifier;
+ screenp->screennum = scrnum;
+ screenp->defaultdepth = conf_screen->scrn_defaultdepth;
+ screenp->defaultbpp = conf_screen->scrn_defaultbpp;
+ screenp->defaultfbbpp = conf_screen->scrn_defaultfbbpp;
+ screenp->monitor = xnfcalloc(1, sizeof(MonRec));
+ /* If no monitor is specified, create a default one. */
+ if (!conf_screen->scrn_monitor) {
+ XF86ConfMonitorRec defMon;
+
+ bzero(&defMon, sizeof(defMon));
+ defMon.mon_identifier = "<default monitor>";
+ if (!configMonitor(screenp->monitor, &defMon))
+ return FALSE;
+ defaultMonitor = TRUE;
+ } else {
+ if (!configMonitor(screenp->monitor,conf_screen->scrn_monitor))
+ return FALSE;
+ }
+ /* Configure the device. If there isn't one configured, attach to the
+ * first inactive one that we can configure. If there's none that work,
+ * set it to NULL so that the section can be autoconfigured later */
+ screenp->device = xnfcalloc(1, sizeof(GDevRec));
+ if ((!conf_screen->scrn_device) && (xf86configptr->conf_device_lst)) {
+ conf_screen->scrn_device = xf86configptr->conf_device_lst;
+ xf86Msg(X_DEFAULT, "No device specified for screen \"%s\".\n"
+ "\tUsing the first device section listed.\n", screenp->id);
+ }
+ if (configDevice(screenp->device,conf_screen->scrn_device, TRUE)) {
+ screenp->device->myScreenSection = screenp;
+ } else {
+ screenp->device = NULL;
+ }
+ screenp->options = conf_screen->scrn_option_lst;
+
+ /*
+ * figure out how many display subsections there are and fill them in
+ */
+ dispptr = conf_screen->scrn_display_lst;
+ while(dispptr) {
+ count++;
+ dispptr = (XF86ConfDisplayPtr)dispptr->list.next;
+ }
+ screenp->displays = xnfalloc((count) * sizeof(DispRec));
+ screenp->numdisplays = count;
+
+ /* Fill in the default Virtual size, if any */
+ if (conf_screen->scrn_virtualX && conf_screen->scrn_virtualY) {
+ for (count = 0, dispptr = conf_screen->scrn_display_lst;
+ dispptr;
+ dispptr = (XF86ConfDisplayPtr)dispptr->list.next, count++) {
+ screenp->displays[count].virtualX = conf_screen->scrn_virtualX;
+ screenp->displays[count].virtualY = conf_screen->scrn_virtualY;
+ }
+ }
+
+ /* Now do the per-Display Virtual sizes */
+ count = 0;
+ dispptr = conf_screen->scrn_display_lst;
+ while(dispptr) {
+ configDisplay(&(screenp->displays[count]),dispptr);
+ count++;
+ dispptr = (XF86ConfDisplayPtr)dispptr->list.next;
+ }
+
+ /*
+ * figure out how many videoadaptor references there are and fill them in
+ */
+ conf_adaptor = conf_screen->scrn_adaptor_lst;
+ while(conf_adaptor) {
+ count++;
+ conf_adaptor = (XF86ConfAdaptorLinkPtr)conf_adaptor->list.next;
+ }
+ screenp->xvadaptors = xnfalloc((count) * sizeof(confXvAdaptorRec));
+ screenp->numxvadaptors = 0;
+ conf_adaptor = conf_screen->scrn_adaptor_lst;
+ while(conf_adaptor) {
+ if (configXvAdaptor(&(screenp->xvadaptors[screenp->numxvadaptors]),
+ conf_adaptor->al_adaptor))
+ screenp->numxvadaptors++;
+ conf_adaptor = (XF86ConfAdaptorLinkPtr)conf_adaptor->list.next;
+ }
+
+ if (defaultMonitor) {
+ xf86Msg(X_DEFAULT, "No monitor specified for screen \"%s\".\n"
+ "\tUsing a default monitor configuration.\n", screenp->id);
+ }
+ return TRUE;
+}
+
+typedef enum {
+ MON_REDUCEDBLANKING,
+ MON_MAX_PIX_CLOCK,
+} MonitorValues;
+
+static OptionInfoRec MonitorOptions[] = {
+ { MON_REDUCEDBLANKING, "ReducedBlanking", OPTV_BOOLEAN,
+ {0}, FALSE },
+ { MON_MAX_PIX_CLOCK, "MaxPixClock", OPTV_FREQ,
+ {0}, FALSE },
+ { -1, NULL, OPTV_NONE,
+ {0}, FALSE },
+};
+
+static Bool
+configMonitor(MonPtr monitorp, XF86ConfMonitorPtr conf_monitor)
+{
+ int count;
+ DisplayModePtr mode,last = NULL;
+ XF86ConfModeLinePtr cmodep;
+ XF86ConfModesPtr modes;
+ XF86ConfModesLinkPtr modeslnk = conf_monitor->mon_modes_sect_lst;
+ Gamma zeros = {0.0, 0.0, 0.0};
+ float badgamma = 0.0;
+ double maxPixClock;
+
+ xf86Msg(X_CONFIG, "| |-->Monitor \"%s\"\n",
+ conf_monitor->mon_identifier);
+ monitorp->id = conf_monitor->mon_identifier;
+ monitorp->vendor = conf_monitor->mon_vendor;
+ monitorp->model = conf_monitor->mon_modelname;
+ monitorp->Modes = NULL;
+ monitorp->Last = NULL;
+ monitorp->gamma = zeros;
+ monitorp->widthmm = conf_monitor->mon_width;
+ monitorp->heightmm = conf_monitor->mon_height;
+ monitorp->reducedblanking = FALSE;
+ monitorp->maxPixClock = 0;
+ monitorp->options = conf_monitor->mon_option_lst;
+
+ /*
+ * fill in the monitor structure
+ */
+ for( count = 0 ;
+ count < conf_monitor->mon_n_hsync && count < MAX_HSYNC;
+ count++) {
+ monitorp->hsync[count].hi = conf_monitor->mon_hsync[count].hi;
+ monitorp->hsync[count].lo = conf_monitor->mon_hsync[count].lo;
+ }
+ monitorp->nHsync = count;
+ for( count = 0 ;
+ count < conf_monitor->mon_n_vrefresh && count < MAX_VREFRESH;
+ count++) {
+ monitorp->vrefresh[count].hi = conf_monitor->mon_vrefresh[count].hi;
+ monitorp->vrefresh[count].lo = conf_monitor->mon_vrefresh[count].lo;
+ }
+ monitorp->nVrefresh = count;
+
+ /*
+ * first we collect the mode lines from the UseModes directive
+ */
+ while(modeslnk)
+ {
+ modes = xf86findModes (modeslnk->ml_modes_str,
+ xf86configptr->conf_modes_lst);
+ modeslnk->ml_modes = modes;
+
+
+ /* now add the modes found in the modes
+ section to the list of modes for this
+ monitor unless it has been added before
+ because we are reusing the same section
+ for another screen */
+ if (xf86itemNotSublist(
+ (GenericListPtr)conf_monitor->mon_modeline_lst,
+ (GenericListPtr)modes->mon_modeline_lst)) {
+ conf_monitor->mon_modeline_lst = (XF86ConfModeLinePtr)
+ xf86addListItem(
+ (GenericListPtr)conf_monitor->mon_modeline_lst,
+ (GenericListPtr)modes->mon_modeline_lst);
+ }
+ modeslnk = modeslnk->list.next;
+ }
+
+ /*
+ * we need to hook in the mode lines now
+ * here both data structures use lists, only our internal one
+ * is double linked
+ */
+ cmodep = conf_monitor->mon_modeline_lst;
+ while( cmodep ) {
+ mode = xnfcalloc(1, sizeof(DisplayModeRec));
+ mode->type = 0;
+ mode->Clock = cmodep->ml_clock;
+ mode->HDisplay = cmodep->ml_hdisplay;
+ mode->HSyncStart = cmodep->ml_hsyncstart;
+ mode->HSyncEnd = cmodep->ml_hsyncend;
+ mode->HTotal = cmodep->ml_htotal;
+ mode->VDisplay = cmodep->ml_vdisplay;
+ mode->VSyncStart = cmodep->ml_vsyncstart;
+ mode->VSyncEnd = cmodep->ml_vsyncend;
+ mode->VTotal = cmodep->ml_vtotal;
+ mode->Flags = cmodep->ml_flags;
+ mode->HSkew = cmodep->ml_hskew;
+ mode->VScan = cmodep->ml_vscan;
+ mode->name = xnfstrdup(cmodep->ml_identifier);
+ if( last ) {
+ mode->prev = last;
+ last->next = mode;
+ }
+ else {
+ /*
+ * this is the first mode
+ */
+ monitorp->Modes = mode;
+ mode->prev = NULL;
+ }
+ last = mode;
+ cmodep = (XF86ConfModeLinePtr)cmodep->list.next;
+ }
+ if(last){
+ last->next = NULL;
+ }
+ monitorp->Last = last;
+
+ /* add the (VESA) default modes */
+ if (! addDefaultModes(monitorp) )
+ return FALSE;
+
+ if (conf_monitor->mon_gamma_red > GAMMA_ZERO)
+ monitorp->gamma.red = conf_monitor->mon_gamma_red;
+ if (conf_monitor->mon_gamma_green > GAMMA_ZERO)
+ monitorp->gamma.green = conf_monitor->mon_gamma_green;
+ if (conf_monitor->mon_gamma_blue > GAMMA_ZERO)
+ monitorp->gamma.blue = conf_monitor->mon_gamma_blue;
+
+ /* Check that the gamma values are within range */
+ if (monitorp->gamma.red > GAMMA_ZERO &&
+ (monitorp->gamma.red < GAMMA_MIN ||
+ monitorp->gamma.red > GAMMA_MAX)) {
+ badgamma = monitorp->gamma.red;
+ } else if (monitorp->gamma.green > GAMMA_ZERO &&
+ (monitorp->gamma.green < GAMMA_MIN ||
+ monitorp->gamma.green > GAMMA_MAX)) {
+ badgamma = monitorp->gamma.green;
+ } else if (monitorp->gamma.blue > GAMMA_ZERO &&
+ (monitorp->gamma.blue < GAMMA_MIN ||
+ monitorp->gamma.blue > GAMMA_MAX)) {
+ badgamma = monitorp->gamma.blue;
+ }
+ if (badgamma > GAMMA_ZERO) {
+ xf86ConfigError("Gamma value %.f is out of range (%.2f - %.1f)\n",
+ badgamma, GAMMA_MIN, GAMMA_MAX);
+ return FALSE;
+ }
+
+ xf86ProcessOptions(-1, monitorp->options, MonitorOptions);
+ xf86GetOptValBool(MonitorOptions, MON_REDUCEDBLANKING,
+ &monitorp->reducedblanking);
+ if (xf86GetOptValFreq(MonitorOptions, MON_MAX_PIX_CLOCK, OPTUNITS_KHZ,
+ &maxPixClock) == TRUE) {
+ monitorp->maxPixClock = (int) maxPixClock;
+ }
+
+ return TRUE;
+}
+
+static int
+lookupVisual(const char *visname)
+{
+ int i;
+
+ if (!visname || !*visname)
+ return -1;
+
+ for (i = 0; i <= DirectColor; i++) {
+ if (!xf86nameCompare(visname, xf86VisualNames[i]))
+ break;
+ }
+
+ if (i <= DirectColor)
+ return i;
+
+ return -1;
+}
+
+
+static Bool
+configDisplay(DispPtr displayp, XF86ConfDisplayPtr conf_display)
+{
+ int count = 0;
+ XF86ModePtr modep;
+
+ displayp->frameX0 = conf_display->disp_frameX0;
+ displayp->frameY0 = conf_display->disp_frameY0;
+ displayp->virtualX = conf_display->disp_virtualX;
+ displayp->virtualY = conf_display->disp_virtualY;
+ displayp->depth = conf_display->disp_depth;
+ displayp->fbbpp = conf_display->disp_bpp;
+ displayp->weight.red = conf_display->disp_weight.red;
+ displayp->weight.green = conf_display->disp_weight.green;
+ displayp->weight.blue = conf_display->disp_weight.blue;
+ displayp->blackColour.red = conf_display->disp_black.red;
+ displayp->blackColour.green = conf_display->disp_black.green;
+ displayp->blackColour.blue = conf_display->disp_black.blue;
+ displayp->whiteColour.red = conf_display->disp_white.red;
+ displayp->whiteColour.green = conf_display->disp_white.green;
+ displayp->whiteColour.blue = conf_display->disp_white.blue;
+ displayp->options = conf_display->disp_option_lst;
+ if (conf_display->disp_visual) {
+ displayp->defaultVisual = lookupVisual(conf_display->disp_visual);
+ if (displayp->defaultVisual == -1) {
+ xf86ConfigError("Invalid visual name: \"%s\"",
+ conf_display->disp_visual);
+ return FALSE;
+ }
+ } else {
+ displayp->defaultVisual = -1;
+ }
+
+ /*
+ * now hook in the modes
+ */
+ modep = conf_display->disp_mode_lst;
+ while(modep) {
+ count++;
+ modep = (XF86ModePtr)modep->list.next;
+ }
+ displayp->modes = xnfalloc((count+1) * sizeof(char*));
+ modep = conf_display->disp_mode_lst;
+ count = 0;
+ while(modep) {
+ displayp->modes[count] = modep->mode_name;
+ count++;
+ modep = (XF86ModePtr)modep->list.next;
+ }
+ displayp->modes[count] = NULL;
+
+ return TRUE;
+}
+
+static Bool
+configDevice(GDevPtr devicep, XF86ConfDevicePtr conf_device, Bool active)
+{
+ int i;
+
+ if (!conf_device) {
+ return FALSE;
+ }
+
+ if (active)
+ xf86Msg(X_CONFIG, "| |-->Device \"%s\"\n",
+ conf_device->dev_identifier);
+ else
+ xf86Msg(X_CONFIG, "|-->Inactive Device \"%s\"\n",
+ conf_device->dev_identifier);
+
+ devicep->identifier = conf_device->dev_identifier;
+ devicep->vendor = conf_device->dev_vendor;
+ devicep->board = conf_device->dev_board;
+ devicep->chipset = conf_device->dev_chipset;
+ devicep->ramdac = conf_device->dev_ramdac;
+ devicep->driver = conf_device->dev_driver;
+ devicep->active = active;
+ devicep->videoRam = conf_device->dev_videoram;
+ devicep->BiosBase = conf_device->dev_bios_base;
+ devicep->MemBase = conf_device->dev_mem_base;
+ devicep->IOBase = conf_device->dev_io_base;
+ devicep->clockchip = conf_device->dev_clockchip;
+ devicep->busID = conf_device->dev_busid;
+ devicep->textClockFreq = conf_device->dev_textclockfreq;
+ devicep->chipID = conf_device->dev_chipid;
+ devicep->chipRev = conf_device->dev_chiprev;
+ devicep->options = conf_device->dev_option_lst;
+ devicep->irq = conf_device->dev_irq;
+ devicep->screen = conf_device->dev_screen;
+
+ for (i = 0; i < MAXDACSPEEDS; i++) {
+ if (i < CONF_MAXDACSPEEDS)
+ devicep->dacSpeeds[i] = conf_device->dev_dacSpeeds[i];
+ else
+ devicep->dacSpeeds[i] = 0;
+ }
+ devicep->numclocks = conf_device->dev_clocks;
+ if (devicep->numclocks > MAXCLOCKS)
+ devicep->numclocks = MAXCLOCKS;
+ for (i = 0; i < devicep->numclocks; i++) {
+ devicep->clock[i] = conf_device->dev_clock[i];
+ }
+ devicep->claimed = FALSE;
+
+ return TRUE;
+}
+
+#ifdef XF86DRI
+static void
+configDRI(XF86ConfDRIPtr drip)
+{
+ int count = 0;
+ XF86ConfBuffersPtr bufs;
+ int i;
+ struct group *grp;
+
+ xf86ConfigDRI.group = -1;
+ xf86ConfigDRI.mode = 0;
+ xf86ConfigDRI.bufs_count = 0;
+ xf86ConfigDRI.bufs = NULL;
+
+ if (drip) {
+ if (drip->dri_group_name) {
+ if ((grp = getgrnam(drip->dri_group_name)))
+ xf86ConfigDRI.group = grp->gr_gid;
+ } else {
+ if (drip->dri_group >= 0)
+ xf86ConfigDRI.group = drip->dri_group;
+ }
+ xf86ConfigDRI.mode = drip->dri_mode;
+ for (bufs = drip->dri_buffers_lst; bufs; bufs = bufs->list.next)
+ ++count;
+
+ xf86ConfigDRI.bufs_count = count;
+ xf86ConfigDRI.bufs = xnfalloc(count * sizeof(*xf86ConfigDRI.bufs));
+
+ for (i = 0, bufs = drip->dri_buffers_lst;
+ i < count;
+ i++, bufs = bufs->list.next) {
+
+ xf86ConfigDRI.bufs[i].count = bufs->buf_count;
+ xf86ConfigDRI.bufs[i].size = bufs->buf_size;
+ /* FIXME: Flags not implemented. These
+ could be used, for example, to specify a
+ contiguous block and/or write-combining
+ cache policy. */
+ xf86ConfigDRI.bufs[i].flags = 0;
+ }
+ }
+}
+#endif
+
+static void
+configExtensions(XF86ConfExtensionsPtr conf_ext)
+{
+ XF86OptionPtr o;
+
+ if (conf_ext && conf_ext->ext_option_lst) {
+ for (o = conf_ext->ext_option_lst; o; o = xf86NextOption(o)) {
+ char *name = xf86OptionName(o);
+ char *val = xf86OptionValue(o);
+ char *n;
+ Bool enable = TRUE;
+
+ /* Handle "No<ExtensionName>" */
+ n = xf86NormalizeName(name);
+ if (strncmp(n, "no", 2) == 0) {
+ name += 2;
+ enable = FALSE;
+ }
+
+ if (!val ||
+ xf86NameCmp(val, "enable") == 0 ||
+ xf86NameCmp(val, "enabled") == 0 ||
+ xf86NameCmp(val, "on") == 0 ||
+ xf86NameCmp(val, "1") == 0 ||
+ xf86NameCmp(val, "yes") == 0 ||
+ xf86NameCmp(val, "true") == 0) {
+ /* NOTHING NEEDED -- enabling is handled below */
+ } else if (xf86NameCmp(val, "disable") == 0 ||
+ xf86NameCmp(val, "disabled") == 0 ||
+ xf86NameCmp(val, "off") == 0 ||
+ xf86NameCmp(val, "0") == 0 ||
+ xf86NameCmp(val, "no") == 0 ||
+ xf86NameCmp(val, "false") == 0) {
+ enable = !enable;
+ } else {
+ xf86Msg(X_WARNING, "Ignoring unrecognized value \"%s\"\n", val);
+ free(n);
+ continue;
+ }
+
+ if (EnableDisableExtension(name, enable)) {
+ xf86Msg(X_CONFIG, "Extension \"%s\" is %s\n",
+ name, enable ? "enabled" : "disabled");
+ } else {
+ xf86Msg(X_WARNING, "Ignoring unrecognized extension \"%s\"\n",
+ name);
+ }
+ free(n);
+ }
+ }
+}
+
+static Bool
+configInput(IDevPtr inputp, XF86ConfInputPtr conf_input, MessageType from)
+{
+ xf86Msg(from, "|-->Input Device \"%s\"\n", conf_input->inp_identifier);
+ inputp->identifier = conf_input->inp_identifier;
+ inputp->driver = conf_input->inp_driver;
+ inputp->commonOptions = conf_input->inp_option_lst;
+ inputp->extraOptions = NULL;
+
+ return TRUE;
+}
+
+static Bool
+modeIsPresent(DisplayModePtr mode, MonPtr monitorp)
+{
+ DisplayModePtr knownmodes = monitorp->Modes;
+
+ /* all I can think of is a linear search... */
+ while(knownmodes != NULL)
+ {
+ if(!strcmp(mode->name, knownmodes->name) &&
+ !(knownmodes->type & M_T_DEFAULT))
+ return TRUE;
+ knownmodes = knownmodes->next;
+ }
+ return FALSE;
+}
+
+static Bool
+addDefaultModes(MonPtr monitorp)
+{
+ DisplayModePtr mode;
+ DisplayModePtr last = monitorp->Last;
+ int i = 0;
+
+ for (i = 0; i < xf86NumDefaultModes; i++)
+ {
+ mode = xf86DuplicateMode(&xf86DefaultModes[i]);
+ if (!modeIsPresent(mode, monitorp))
+ {
+ monitorp->Modes = xf86ModesAdd(monitorp->Modes, mode);
+ last = mode;
+ } else {
+ free(mode);
+ }
+ }
+ monitorp->Last = last;
+
+ return TRUE;
+}
+
+static void
+checkInput(serverLayoutPtr layout, Bool implicit_layout) {
+ checkCoreInputDevices(layout, implicit_layout);
+
+ /* AllowEmptyInput and the "kbd" and "mouse" drivers are mutually
+ * exclusive. Trawl the list for mouse/kbd devices and disable them.
+ */
+ if (xf86Info.allowEmptyInput && layout->inputs)
+ {
+ IDevPtr *dev = layout->inputs;
+ BOOL warned = FALSE;
+
+ while(*dev)
+ {
+ if (strcmp((*dev)->driver, "kbd") == 0 ||
+ strcmp((*dev)->driver, "mouse") == 0 ||
+ strcmp((*dev)->driver, "vmmouse") == 0)
+ {
+ IDevPtr *current;
+ if (!warned)
+ {
+ xf86Msg(X_WARNING, "AllowEmptyInput is on, devices using "
+ "drivers 'kbd', 'mouse' or 'vmmouse' will be disabled.\n");
+ warned = TRUE;
+ }
+
+ xf86Msg(X_WARNING, "Disabling %s\n", (*dev)->identifier);
+
+ current = dev;
+ free(*dev);
+
+ do {
+ *current = *(current + 1);
+ current++;
+ } while(*current);
+ } else
+ dev++;
+ }
+ }
+}
+
+/*
+ * load the config file and fill the global data structure
+ */
+ConfigStatus
+xf86HandleConfigFile(Bool autoconfig)
+{
+ const char *filename, *dirname, *sysdirname;
+ char *filesearch, *dirsearch;
+ MessageType filefrom = X_DEFAULT;
+ MessageType dirfrom = X_DEFAULT;
+ char *scanptr;
+ Bool singlecard = 0;
+ Bool implicit_layout = FALSE;
+
+ if (!autoconfig) {
+ if (getuid() == 0) {
+ filesearch = ROOT_CONFIGPATH;
+ dirsearch = ROOT_CONFIGDIRPATH;
+ } else {
+ filesearch = USER_CONFIGPATH;
+ dirsearch = USER_CONFIGDIRPATH;
+ }
+
+ if (xf86ConfigFile)
+ filefrom = X_CMDLINE;
+ if (xf86ConfigDir)
+ dirfrom = X_CMDLINE;
+
+ xf86initConfigFiles();
+ sysdirname = xf86openConfigDirFiles(SYS_CONFIGDIRPATH, NULL,
+ PROJECTROOT);
+ dirname = xf86openConfigDirFiles(dirsearch, xf86ConfigDir, PROJECTROOT);
+ filename = xf86openConfigFile(filesearch, xf86ConfigFile, PROJECTROOT);
+ if (filename) {
+ xf86MsgVerb(filefrom, 0, "Using config file: \"%s\"\n", filename);
+ xf86ConfigFile = xnfstrdup(filename);
+ } else {
+ if (xf86ConfigFile)
+ xf86Msg(X_ERROR, "Unable to locate/open config file: \"%s\"\n",
+ xf86ConfigFile);
+ }
+ if (dirname) {
+ xf86MsgVerb(dirfrom, 0, "Using config directory: \"%s\"\n",
+ dirname);
+ xf86ConfigDir = xnfstrdup(dirname);
+ } else {
+ if (xf86ConfigDir)
+ xf86Msg(X_ERROR,
+ "Unable to locate/open config directory: \"%s\"\n",
+ xf86ConfigDir);
+ }
+ if (sysdirname)
+ xf86MsgVerb(X_DEFAULT, 0, "Using system config directory \"%s\"\n",
+ sysdirname);
+ if (!filename && !dirname && !sysdirname)
+ return CONFIG_NOFILE;
+ }
+
+ if ((xf86configptr = xf86readConfigFile ()) == NULL) {
+ xf86Msg(X_ERROR, "Problem parsing the config file\n");
+ return CONFIG_PARSE_ERROR;
+ }
+ xf86closeConfigFile ();
+
+ /* Initialise a few things. */
+
+ /*
+ * now we convert part of the information contained in the parser
+ * structures into our own structures.
+ * The important part here is to figure out which Screen Sections
+ * in the XF86Config file are active so that we can piece together
+ * the modes that we need later down the road.
+ * And while we are at it, we'll decode the rest of the stuff as well
+ */
+
+ /* First check if a layout section is present, and if it is valid. */
+
+ if (xf86configptr->conf_layout_lst == NULL || xf86ScreenName != NULL) {
+ if (xf86ScreenName == NULL) {
+ xf86Msg(X_DEFAULT,
+ "No Layout section. Using the first Screen section.\n");
+ }
+ if (!configImpliedLayout(&xf86ConfigLayout,
+ xf86configptr->conf_screen_lst,
+ xf86configptr)) {
+ xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
+ return CONFIG_PARSE_ERROR;
+ }
+ implicit_layout = TRUE;
+ } else {
+ if (xf86configptr->conf_flags != NULL) {
+ char *dfltlayout = NULL;
+ pointer optlist = xf86configptr->conf_flags->flg_option_lst;
+
+ if (optlist && xf86FindOption(optlist, "defaultserverlayout"))
+ dfltlayout = xf86SetStrOption(optlist, "defaultserverlayout", NULL);
+ if (!configLayout(&xf86ConfigLayout, xf86configptr->conf_layout_lst,
+ dfltlayout)) {
+ xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
+ return CONFIG_PARSE_ERROR;
+ }
+ } else {
+ if (!configLayout(&xf86ConfigLayout, xf86configptr->conf_layout_lst,
+ NULL)) {
+ xf86Msg(X_ERROR, "Unable to determine the screen layout\n");
+ return CONFIG_PARSE_ERROR;
+ }
+ }
+ }
+
+ xf86ProcessOptions(-1, xf86ConfigLayout.options, LayoutOptions);
+
+ if ((scanptr = xf86GetOptValString(LayoutOptions, LAYOUT_ISOLATEDEVICE))) {
+ ; /* IsolateDevice specified; overrides SingleCard */
+ } else {
+ xf86GetOptValBool(LayoutOptions, LAYOUT_SINGLECARD, &singlecard);
+ if (singlecard)
+ scanptr = xf86ConfigLayout.screens->screen->device->busID;
+ }
+ if (scanptr) {
+ int bus, device, func;
+ if (strncmp(scanptr, "PCI:", 4) != 0) {
+ xf86Msg(X_WARNING, "Bus types other than PCI not yet isolable.\n"
+ "\tIgnoring IsolateDevice option.\n");
+ } else if (sscanf(scanptr, "PCI:%d:%d:%d", &bus, &device, &func) == 3) {
+ xf86IsolateDevice.domain = PCI_DOM_FROM_BUS(bus);
+ xf86IsolateDevice.bus = PCI_BUS_NO_DOMAIN(bus);
+ xf86IsolateDevice.dev = device;
+ xf86IsolateDevice.func = func;
+ xf86Msg(X_INFO,
+ "Isolating PCI bus \"%d:%d:%d\"\n", bus, device, func);
+ }
+ }
+
+ /* Now process everything else */
+ if (!configServerFlags(xf86configptr->conf_flags,xf86ConfigLayout.options)){
+ ErrorF ("Problem when converting the config data structures\n");
+ return CONFIG_PARSE_ERROR;
+ }
+
+ configFiles(xf86configptr->conf_files);
+ configExtensions(xf86configptr->conf_extensions);
+#ifdef XF86DRI
+ configDRI(xf86configptr->conf_dri);
+#endif
+
+ checkInput(&xf86ConfigLayout, implicit_layout);
+
+ /*
+ * Handle some command line options that can override some of the
+ * ServerFlags settings.
+ */
+#ifdef XF86VIDMODE
+ if (xf86VidModeDisabled)
+ xf86Info.vidModeEnabled = FALSE;
+ if (xf86VidModeAllowNonLocal)
+ xf86Info.vidModeAllowNonLocal = TRUE;
+#endif
+
+ if (xf86AllowMouseOpenFail)
+ xf86Info.allowMouseOpenFail = TRUE;
+
+ return CONFIG_OK;
+}
+
+Bool
+xf86PathIsSafe(const char *path)
+{
+ return (xf86pathIsSafe(path) != 0);
+}
diff --git a/xorg-server/hw/xfree86/common/xf86Configure.c b/xorg-server/hw/xfree86/common/xf86Configure.c
index 67bf08bbf..883c666a6 100644
--- a/xorg-server/hw/xfree86/common/xf86Configure.c
+++ b/xorg-server/hw/xfree86/common/xf86Configure.c
@@ -1,892 +1,892 @@
-/*
- * Copyright 2000-2002 by Alan Hourihane, Flint Mountain, North Wales.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Alan Hourihane not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Alan Hourihane makes no representations
- * about the suitability of this software for any purpose. It is provided
- * "as is" without express or implied warranty.
- *
- * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- * Author: Alan Hourihane, alanh@fairlite.demon.co.uk
- *
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "xf86.h"
-#include "xf86Config.h"
-#include "xf86_OSlib.h"
-#include "xf86Priv.h"
-#define IN_XSERVER
-#include "Configint.h"
-#include "xf86DDC.h"
-#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
-#include "xf86Bus.h"
-#include "xf86Sbus.h"
-#endif
-
-typedef struct _DevToConfig {
- GDevRec GDev;
- struct pci_device * pVideo;
-#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
- sbusDevicePtr sVideo;
-#endif
- int iDriver;
-} DevToConfigRec, *DevToConfigPtr;
-
-static DevToConfigPtr DevToConfig = NULL;
-static int nDevToConfig = 0, CurrentDriver;
-
-xf86MonPtr ConfiguredMonitor;
-Bool xf86DoConfigurePass1 = TRUE;
-static Bool foundMouse = FALSE;
-
-#if defined(__SCO__)
-static char *DFLT_MOUSE_PROTO = "OSMouse";
-#elif defined(__UNIXWARE__)
-static char *DFLT_MOUSE_PROTO = "OSMouse";
-static char *DFLT_MOUSE_DEV = "/dev/mouse";
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
-static char *DFLT_MOUSE_DEV = "/dev/sysmouse";
-static char *DFLT_MOUSE_PROTO = "auto";
-#elif defined(linux)
-static char DFLT_MOUSE_DEV[] = "/dev/input/mice";
-static char DFLT_MOUSE_PROTO[] = "auto";
-#else
-static char *DFLT_MOUSE_DEV = "/dev/mouse";
-static char *DFLT_MOUSE_PROTO = "auto";
-#endif
-
-static Bool
-bus_pci_configure(void *busData)
-{
- int i;
- struct pci_device * pVideo = NULL;
-
- pVideo = (struct pci_device *) busData;
- for (i = 0; i < nDevToConfig; i++)
- if (DevToConfig[i].pVideo &&
- (DevToConfig[i].pVideo->domain == pVideo->domain) &&
- (DevToConfig[i].pVideo->bus == pVideo->bus) &&
- (DevToConfig[i].pVideo->dev == pVideo->dev) &&
- (DevToConfig[i].pVideo->func == pVideo->func))
- return 0;
-
- return 1;
-}
-
-static Bool
-bus_sbus_configure(void *busData)
-{
-#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
- int i;
-
- for (i = 0; i < nDevToConfig; i++)
- if (DevToConfig[i].sVideo &&
- DevToConfig[i].sVideo->fbNum == ((sbusDevicePtr) busData)->fbNum)
- return 0;
-
-#endif
- return 1;
-}
-
-static void
-bus_pci_newdev_configure(void *busData, int i, int *chipset)
-{
- const char *VendorName;
- const char *CardName;
- char busnum[8];
- struct pci_device * pVideo = NULL;
-
- pVideo = (struct pci_device *) busData;
-
- DevToConfig[i].pVideo = pVideo;
-
- VendorName = pci_device_get_vendor_name( pVideo );
- CardName = pci_device_get_device_name( pVideo );
-
- if (!VendorName) {
- VendorName = xnfalloc(15);
- sprintf((char*)VendorName, "Unknown Vendor");
- }
-
- if (!CardName) {
- CardName = xnfalloc(14);
- sprintf((char*)CardName, "Unknown Board");
- }
-
- DevToConfig[i].GDev.identifier =
- xnfalloc(strlen(VendorName) + strlen(CardName) + 2);
- sprintf(DevToConfig[i].GDev.identifier, "%s %s", VendorName, CardName);
-
- DevToConfig[i].GDev.vendor = (char *)VendorName;
- DevToConfig[i].GDev.board = (char *)CardName;
-
- DevToConfig[i].GDev.busID = xnfalloc(16);
- xf86FormatPciBusNumber(pVideo->bus, busnum);
- sprintf(DevToConfig[i].GDev.busID, "PCI:%s:%d:%d",
- busnum, pVideo->dev, pVideo->func);
-
- DevToConfig[i].GDev.chipID = pVideo->device_id;
- DevToConfig[i].GDev.chipRev = pVideo->revision;
-
- if (*chipset < 0) {
- *chipset = (pVideo->vendor_id << 16) | pVideo->device_id;
- }
-}
-
-static void
-bus_sbus_newdev_configure(void *busData, int i)
-{
-#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
- char *promPath = NULL;
- DevToConfig[i].sVideo = (sbusDevicePtr) busData;
- DevToConfig[i].GDev.identifier = DevToConfig[i].sVideo->descr;
- if (sparcPromInit() >= 0) {
- promPath = sparcPromNode2Pathname(&DevToConfig[i].sVideo->node);
- sparcPromClose();
- }
- if (promPath) {
- DevToConfig[i].GDev.busID = xnfalloc(strlen(promPath) + 6);
- sprintf(DevToConfig[i].GDev.busID, "SBUS:%s", promPath);
- xfree(promPath);
- } else {
- DevToConfig[i].GDev.busID = xnfalloc(12);
- sprintf(DevToConfig[i].GDev.busID, "SBUS:fb%d",
- DevToConfig[i].sVideo->fbNum);
- }
-#endif
-}
-
-/*
- * This is called by the driver, either through xf86Match???Instances() or
- * directly. We allocate a GDevRec and fill it in as much as we can, letting
- * the caller fill in the rest and/or change it as it sees fit.
- */
-GDevPtr
-xf86AddBusDeviceToConfigure(const char *driver, BusType bus, void *busData, int chipset)
-{
- int ret, i, j;
-
- if (!xf86DoConfigure || !xf86DoConfigurePass1)
- return NULL;
-
- /* Check for duplicates */
- switch (bus) {
- case BUS_PCI:
- ret = bus_pci_configure(busData);
- break;
- case BUS_SBUS:
- ret = bus_sbus_configure(busData);
- break;
- default:
- return NULL;
- }
-
- if (ret == 0)
- goto out;
-
- /* Allocate new structure occurrence */
- i = nDevToConfig++;
- DevToConfig =
- xnfrealloc(DevToConfig, nDevToConfig * sizeof(DevToConfigRec));
- memset(DevToConfig + i, 0, sizeof(DevToConfigRec));
-
- DevToConfig[i].GDev.chipID =
- DevToConfig[i].GDev.chipRev = DevToConfig[i].GDev.irq = -1;
-
- DevToConfig[i].iDriver = CurrentDriver;
-
- /* Fill in what we know, converting the driver name to lower case */
- DevToConfig[i].GDev.driver = xnfalloc(strlen(driver) + 1);
- for (j = 0; (DevToConfig[i].GDev.driver[j] = tolower(driver[j])); j++);
-
- switch (bus) {
- case BUS_PCI:
- bus_pci_newdev_configure(busData, i, &chipset);
- break;
- case BUS_SBUS:
- bus_sbus_newdev_configure(busData, i);
- break;
- default:
- break;
- }
-
- /* Get driver's available options */
- if (xf86DriverList[CurrentDriver]->AvailableOptions)
- DevToConfig[i].GDev.options = (OptionInfoPtr)
- (*xf86DriverList[CurrentDriver]->AvailableOptions)(chipset,
- bus);
-
- return &DevToConfig[i].GDev;
-
-out:
- return NULL;
-}
-
-static XF86ConfInputPtr
-configureInputSection (void)
-{
- XF86ConfInputPtr mouse = NULL;
- parsePrologue (XF86ConfInputPtr, XF86ConfInputRec)
-
- ptr->inp_identifier = "Keyboard0";
- ptr->inp_driver = "kbd";
- ptr->list.next = NULL;
-
- /* Crude mechanism to auto-detect mouse (os dependent) */
- {
- int fd;
-#ifdef WSCONS_SUPPORT
- fd = open("/dev/wsmouse", 0);
- if (fd >= 0) {
- DFLT_MOUSE_DEV = "/dev/wsmouse";
- DFLT_MOUSE_PROTO = "wsmouse";
- close(fd);
- } else {
- ErrorF("cannot open /dev/wsmouse\n");
- }
-#endif
-
-#ifndef __SCO__
- fd = open(DFLT_MOUSE_DEV, 0);
- if (fd != -1) {
- foundMouse = TRUE;
- close(fd);
- }
-#else
- foundMouse = TRUE;
-#endif
- }
-
- mouse = calloc(1, sizeof(XF86ConfInputRec));
- mouse->inp_identifier = "Mouse0";
- mouse->inp_driver = "mouse";
- mouse->inp_option_lst =
- xf86addNewOption(mouse->inp_option_lst, xstrdup("Protocol"),
- xstrdup(DFLT_MOUSE_PROTO));
-#ifndef __SCO__
- mouse->inp_option_lst =
- xf86addNewOption(mouse->inp_option_lst, xstrdup("Device"),
- xstrdup(DFLT_MOUSE_DEV));
-#endif
- mouse->inp_option_lst =
- xf86addNewOption(mouse->inp_option_lst, xstrdup("ZAxisMapping"),
- xstrdup("4 5 6 7"));
- ptr = (XF86ConfInputPtr)xf86addListItem((glp)ptr, (glp)mouse);
- return ptr;
-}
-
-static XF86ConfScreenPtr
-configureScreenSection (int screennum)
-{
- int i;
- int depths[] = { 1, 4, 8, 15, 16, 24/*, 32*/ };
- parsePrologue (XF86ConfScreenPtr, XF86ConfScreenRec)
-
- ptr->scrn_identifier = malloc(18);
- sprintf(ptr->scrn_identifier, "Screen%d", screennum);
- ptr->scrn_monitor_str = malloc(19);
- sprintf(ptr->scrn_monitor_str, "Monitor%d", screennum);
- ptr->scrn_device_str = malloc(16);
- sprintf(ptr->scrn_device_str, "Card%d", screennum);
-
- for (i=0; i<sizeof(depths)/sizeof(depths[0]); i++)
- {
- XF86ConfDisplayPtr display;
-
- display = calloc(1, sizeof(XF86ConfDisplayRec));
- display->disp_depth = depths[i];
- display->disp_black.red = display->disp_white.red = -1;
- display->disp_black.green = display->disp_white.green = -1;
- display->disp_black.blue = display->disp_white.blue = -1;
- ptr->scrn_display_lst = (XF86ConfDisplayPtr)xf86addListItem(
- (glp)ptr->scrn_display_lst, (glp)display);
- }
-
- return ptr;
-}
-
-static const char*
-optionTypeToSting(OptionValueType type)
-{
- switch (type) {
- case OPTV_NONE:
- return "";
- case OPTV_INTEGER:
- return "<i>";
- case OPTV_STRING:
- return "<str>";
- case OPTV_ANYSTR:
- return "[<str>]";
- case OPTV_REAL:
- return "<f>";
- case OPTV_BOOLEAN:
- return "[<bool>]";
- case OPTV_FREQ:
- return "<freq>";
- default:
- return "";
- }
-}
-
-static XF86ConfDevicePtr
-configureDeviceSection (int screennum)
-{
- char identifier[16];
- OptionInfoPtr p;
- int i = 0;
- parsePrologue (XF86ConfDevicePtr, XF86ConfDeviceRec)
-
- /* Move device info to parser structure */
- sprintf(identifier, "Card%d", screennum);
- ptr->dev_identifier = strdup(identifier);
-/* ptr->dev_identifier = DevToConfig[screennum].GDev.identifier;*/
- ptr->dev_vendor = DevToConfig[screennum].GDev.vendor;
- ptr->dev_board = DevToConfig[screennum].GDev.board;
- ptr->dev_chipset = DevToConfig[screennum].GDev.chipset;
- ptr->dev_busid = DevToConfig[screennum].GDev.busID;
- ptr->dev_driver = DevToConfig[screennum].GDev.driver;
- ptr->dev_ramdac = DevToConfig[screennum].GDev.ramdac;
- for (i = 0; (i < MAXDACSPEEDS) && (i < CONF_MAXDACSPEEDS); i++)
- ptr->dev_dacSpeeds[i] = DevToConfig[screennum].GDev.dacSpeeds[i];
- ptr->dev_videoram = DevToConfig[screennum].GDev.videoRam;
- ptr->dev_textclockfreq = DevToConfig[screennum].GDev.textClockFreq;
- ptr->dev_bios_base = DevToConfig[screennum].GDev.BiosBase;
- ptr->dev_mem_base = DevToConfig[screennum].GDev.MemBase;
- ptr->dev_io_base = DevToConfig[screennum].GDev.IOBase;
- ptr->dev_clockchip = DevToConfig[screennum].GDev.clockchip;
- for (i = 0; (i < MAXCLOCKS) && (i < DevToConfig[screennum].GDev.numclocks); i++)
- ptr->dev_clock[i] = DevToConfig[screennum].GDev.clock[i];
- ptr->dev_clocks = i;
- ptr->dev_chipid = DevToConfig[screennum].GDev.chipID;
- ptr->dev_chiprev = DevToConfig[screennum].GDev.chipRev;
- ptr->dev_irq = DevToConfig[screennum].GDev.irq;
-
- /* Make sure older drivers don't segv */
- if (DevToConfig[screennum].GDev.options) {
- /* Fill in the available driver options for people to use */
- const char *descrip =
- " ### Available Driver options are:-\n"
- " ### Values: <i>: integer, <f>: float, "
- "<bool>: \"True\"/\"False\",\n"
- " ### <string>: \"String\", <freq>: \"<f> Hz/kHz/MHz\"\n"
- " ### [arg]: arg optional\n";
- ptr->dev_comment = xstrdup(descrip);
- if (ptr->dev_comment) {
- for (p = DevToConfig[screennum].GDev.options;
- p->name != NULL; p++) {
- char *p_e;
- const char *prefix = " #Option ";
- const char *middle = " \t# ";
- const char *suffix = "\n";
- const char *opttype = optionTypeToSting(p->type);
- char *optname;
- int len = strlen(ptr->dev_comment) + strlen(prefix) +
- strlen(middle) + strlen(suffix) + 1;
-
- optname = xalloc(strlen(p->name) + 2 + 1);
- if (!optname)
- break;
- sprintf(optname, "\"%s\"", p->name);
-
- len += max(20, strlen(optname));
- len += strlen(opttype);
-
- ptr->dev_comment = xrealloc(ptr->dev_comment, len);
- if (!ptr->dev_comment)
- break;
- p_e = ptr->dev_comment + strlen(ptr->dev_comment);
- sprintf(p_e, "%s%-20s%s%s%s", prefix, optname, middle,
- opttype, suffix);
- xfree(optname);
- }
- }
- }
-
- return ptr;
-}
-
-static XF86ConfLayoutPtr
-configureLayoutSection (void)
-{
- int scrnum = 0;
- parsePrologue (XF86ConfLayoutPtr, XF86ConfLayoutRec)
-
- ptr->lay_identifier = "X.org Configured";
-
- {
- XF86ConfInputrefPtr iptr;
-
- iptr = malloc (sizeof (XF86ConfInputrefRec));
- iptr->list.next = NULL;
- iptr->iref_option_lst = NULL;
- iptr->iref_inputdev_str = "Mouse0";
- iptr->iref_option_lst =
- xf86addNewOption (iptr->iref_option_lst, xstrdup("CorePointer"), NULL);
- ptr->lay_input_lst = (XF86ConfInputrefPtr)
- xf86addListItem ((glp) ptr->lay_input_lst, (glp) iptr);
- }
-
- {
- XF86ConfInputrefPtr iptr;
-
- iptr = malloc (sizeof (XF86ConfInputrefRec));
- iptr->list.next = NULL;
- iptr->iref_option_lst = NULL;
- iptr->iref_inputdev_str = "Keyboard0";
- iptr->iref_option_lst =
- xf86addNewOption (iptr->iref_option_lst, xstrdup("CoreKeyboard"), NULL);
- ptr->lay_input_lst = (XF86ConfInputrefPtr)
- xf86addListItem ((glp) ptr->lay_input_lst, (glp) iptr);
- }
-
- for (scrnum = 0; scrnum < nDevToConfig; scrnum++) {
- XF86ConfAdjacencyPtr aptr;
-
- aptr = malloc (sizeof (XF86ConfAdjacencyRec));
- aptr->list.next = NULL;
- aptr->adj_x = 0;
- aptr->adj_y = 0;
- aptr->adj_scrnum = scrnum;
- aptr->adj_screen_str = xnfalloc(18);
- sprintf(aptr->adj_screen_str, "Screen%d", scrnum);
- if (scrnum == 0) {
- aptr->adj_where = CONF_ADJ_ABSOLUTE;
- aptr->adj_refscreen = NULL;
- }
- else {
- aptr->adj_where = CONF_ADJ_RIGHTOF;
- aptr->adj_refscreen = xnfalloc(18);
- sprintf(aptr->adj_refscreen, "Screen%d", scrnum - 1);
- }
- ptr->lay_adjacency_lst =
- (XF86ConfAdjacencyPtr)xf86addListItem((glp)ptr->lay_adjacency_lst,
- (glp)aptr);
- }
-
- return ptr;
-}
-
-static XF86ConfFlagsPtr
-configureFlagsSection (void)
-{
- parsePrologue (XF86ConfFlagsPtr, XF86ConfFlagsRec)
-
- return ptr;
-}
-
-static XF86ConfModulePtr
-configureModuleSection (void)
-{
- char **elist, **el;
- /* Find the list of extension & font modules. */
- const char *esubdirs[] = {
- "extensions",
- "fonts",
- NULL
- };
- parsePrologue (XF86ConfModulePtr, XF86ConfModuleRec)
-
- elist = LoaderListDirs(esubdirs, NULL);
- if (elist) {
- for (el = elist; *el; el++) {
- XF86LoadPtr module;
-
- module = calloc(1, sizeof(XF86LoadRec));
- module->load_name = *el;
- ptr->mod_load_lst = (XF86LoadPtr)xf86addListItem(
- (glp)ptr->mod_load_lst, (glp)module);
- }
- xfree(elist);
- }
-
- return ptr;
-}
-
-static XF86ConfFilesPtr
-configureFilesSection (void)
-{
- parsePrologue (XF86ConfFilesPtr, XF86ConfFilesRec)
-
- if (xf86ModulePath)
- ptr->file_modulepath = strdup(xf86ModulePath);
- if (defaultFontPath)
- ptr->file_fontpath = strdup(defaultFontPath);
-
- return ptr;
-}
-
-static XF86ConfMonitorPtr
-configureMonitorSection (int screennum)
-{
- parsePrologue (XF86ConfMonitorPtr, XF86ConfMonitorRec)
-
- ptr->mon_identifier = malloc(19);
- sprintf(ptr->mon_identifier, "Monitor%d", screennum);
- ptr->mon_vendor = strdup("Monitor Vendor");
- ptr->mon_modelname = strdup("Monitor Model");
-
- return ptr;
-}
-
-/* Initialize Configure Monitor from Detailed Timing Block */
-static void handle_detailed_input(struct detailed_monitor_section *det_mon,
- void *data)
-{
- XF86ConfMonitorPtr ptr = (XF86ConfMonitorPtr) data;
-
- switch (det_mon->type) {
- case DS_NAME:
- ptr->mon_modelname = realloc(ptr->mon_modelname,
- strlen((char*)(det_mon->section.name)) +
- 1);
- strcpy(ptr->mon_modelname,
- (char*)(det_mon->section.name));
- break;
- case DS_RANGES:
- ptr->mon_hsync[ptr->mon_n_hsync].lo =
- det_mon->section.ranges.min_h;
- ptr->mon_hsync[ptr->mon_n_hsync].hi =
- det_mon->section.ranges.max_h;
- ptr->mon_n_vrefresh = 1;
- ptr->mon_vrefresh[ptr->mon_n_hsync].lo =
- det_mon->section.ranges.min_v;
- ptr->mon_vrefresh[ptr->mon_n_hsync].hi =
- det_mon->section.ranges.max_v;
- ptr->mon_n_hsync++;
- default:
- break;
- }
-}
-
-static XF86ConfMonitorPtr
-configureDDCMonitorSection (int screennum)
-{
- int len, mon_width, mon_height;
-#define displaySizeMaxLen 80
- char displaySize_string[displaySizeMaxLen];
- int displaySizeLen;
-
- parsePrologue (XF86ConfMonitorPtr, XF86ConfMonitorRec)
-
- ptr->mon_identifier = malloc(19);
- sprintf(ptr->mon_identifier, "Monitor%d", screennum);
- ptr->mon_vendor = strdup(ConfiguredMonitor->vendor.name);
- ptr->mon_modelname = malloc(12);
- sprintf(ptr->mon_modelname, "%x", ConfiguredMonitor->vendor.prod_id);
-
- /* features in centimetres, we want millimetres */
- mon_width = 10 * ConfiguredMonitor->features.hsize ;
- mon_height = 10 * ConfiguredMonitor->features.vsize ;
-
-#ifdef CONFIGURE_DISPLAYSIZE
- ptr->mon_width = mon_width;
- ptr->mon_height = mon_height;
-#else
- if (mon_width && mon_height) {
- /* when values available add DisplaySize option AS A COMMENT */
-
- displaySizeLen = snprintf(displaySize_string, displaySizeMaxLen,
- "\t#DisplaySize\t%5d %5d\t# mm\n",
- mon_width, mon_height);
-
- if (displaySizeLen>0 && displaySizeLen<displaySizeMaxLen) {
- if (ptr->mon_comment) {
- len = strlen(ptr->mon_comment);
- } else {
- len = 0;
- }
- if ((ptr->mon_comment =
- realloc(ptr->mon_comment, len + strlen(displaySize_string) + 1))) {
- strcpy(ptr->mon_comment + len, displaySize_string);
- }
- }
- }
-#endif /* def CONFIGURE_DISPLAYSIZE */
-
- xf86ForEachDetailedBlock(ConfiguredMonitor, handle_detailed_input,
- ptr);
-
- if (ConfiguredMonitor->features.dpms) {
- ptr->mon_option_lst = xf86addNewOption(ptr->mon_option_lst, xstrdup("DPMS"), NULL);
- }
-
- return ptr;
-}
-
-#if !defined(PATH_MAX)
-# define PATH_MAX 1024
-#endif
-
-void
-DoConfigure(void)
-{
- int i,j, screennum = -1;
- char *home = NULL;
- char filename[PATH_MAX];
- char *addslash = "";
- XF86ConfigPtr xf86config = NULL;
- char **vlist, **vl;
- int *dev2screen;
-
- vlist = xf86DriverlistFromCompile();
-
- if (!vlist) {
- ErrorF("Missing output drivers. Configuration failed.\n");
- goto bail;
- }
-
- ErrorF("List of video drivers:\n");
- for (vl = vlist; *vl; vl++)
- ErrorF("\t%s\n", *vl);
-
- /* Load all the drivers that were found. */
- xf86LoadModules(vlist, NULL);
-
- xfree(vlist);
-
- for (i = 0; i < xf86NumDrivers; i++) {
- xorgHWFlags flags;
- if (!xf86DriverList[i]->driverFunc
- || !xf86DriverList[i]->driverFunc(NULL,
- GET_REQUIRED_HW_INTERFACES,
- &flags)
- || NEED_IO_ENABLED(flags)) {
- xorgHWAccess = TRUE;
- break;
- }
- }
- /* Enable full I/O access */
- if (xorgHWAccess) {
- if(!xf86EnableIO())
- /* oops, we have failed */
- xorgHWAccess = FALSE;
- }
-
- xf86FindPrimaryDevice();
-
- /* Create XF86Config file structure */
- xf86config = calloc(1, sizeof(XF86ConfigRec));
-
- /* Call all of the probe functions, reporting the results. */
- for (CurrentDriver = 0; CurrentDriver < xf86NumDrivers; CurrentDriver++) {
- xorgHWFlags flags;
- Bool found_screen;
- DriverRec * const drv = xf86DriverList[CurrentDriver];
-
- if (!xorgHWAccess) {
- if (!drv->driverFunc
- || !drv->driverFunc( NULL, GET_REQUIRED_HW_INTERFACES, &flags )
- || NEED_IO_ENABLED(flags))
- continue;
- }
-
- found_screen = xf86CallDriverProbe( drv, TRUE );
- if ( found_screen && drv->Identify ) {
- (*drv->Identify)(0);
- }
- }
-
- if (nDevToConfig <= 0) {
- ErrorF("No devices to configure. Configuration failed.\n");
- goto bail;
- }
-
- /* Add device, monitor and screen sections for detected devices */
- for (screennum = 0; screennum < nDevToConfig; screennum++) {
- XF86ConfDevicePtr DevicePtr;
- XF86ConfMonitorPtr MonitorPtr;
- XF86ConfScreenPtr ScreenPtr;
-
- DevicePtr = configureDeviceSection(screennum);
- xf86config->conf_device_lst = (XF86ConfDevicePtr)xf86addListItem(
- (glp)xf86config->conf_device_lst, (glp)DevicePtr);
- MonitorPtr = configureMonitorSection(screennum);
- xf86config->conf_monitor_lst = (XF86ConfMonitorPtr)xf86addListItem(
- (glp)xf86config->conf_monitor_lst, (glp)MonitorPtr);
- ScreenPtr = configureScreenSection(screennum);
- xf86config->conf_screen_lst = (XF86ConfScreenPtr)xf86addListItem(
- (glp)xf86config->conf_screen_lst, (glp)ScreenPtr);
- }
-
- xf86config->conf_files = configureFilesSection();
- xf86config->conf_modules = configureModuleSection();
- xf86config->conf_flags = configureFlagsSection();
- xf86config->conf_videoadaptor_lst = NULL;
- xf86config->conf_modes_lst = NULL;
- xf86config->conf_vendor_lst = NULL;
- xf86config->conf_dri = NULL;
- xf86config->conf_input_lst = configureInputSection();
- xf86config->conf_layout_lst = configureLayoutSection();
-
- home = getenv("HOME");
- if ((home == NULL) || (home[0] == '\0')) {
- home = "/";
- } else {
- /* Determine if trailing slash is present or needed */
- int l = strlen(home);
-
- if (home[l-1] != '/') {
- addslash = "/";
- }
- }
-
- snprintf(filename, sizeof(filename), "%s%s" XF86CONFIGFILE ".new",
- home, addslash);
-
- if (xf86writeConfigFile(filename, xf86config) == 0) {
- xf86Msg(X_ERROR, "Unable to write config file: \"%s\": %s\n",
- filename, strerror(errno));
- goto bail;
- }
-
- xf86DoConfigurePass1 = FALSE;
- /* Try to get DDC information filled in */
- xf86ConfigFile = filename;
- if (xf86HandleConfigFile(FALSE) != CONFIG_OK) {
- goto bail;
- }
-
- xf86DoConfigurePass1 = FALSE;
-
- dev2screen = xnfcalloc(1,xf86NumDrivers*sizeof(int));
-
- {
- Bool *driverProbed = xnfcalloc(1,xf86NumDrivers*sizeof(Bool));
- for (screennum = 0; screennum < nDevToConfig; screennum++) {
- int k,l,n,oldNumScreens;
-
- i = DevToConfig[screennum].iDriver;
-
- if (driverProbed[i]) continue;
- driverProbed[i] = TRUE;
-
- oldNumScreens = xf86NumScreens;
-
- xf86CallDriverProbe( xf86DriverList[i], FALSE );
-
- /* reorder */
- k = screennum > 0 ? screennum : 1;
- for (l = oldNumScreens; l < xf86NumScreens; l++) {
- /* is screen primary? */
- Bool primary = FALSE;
- for (n = 0; n<xf86Screens[l]->numEntities; n++) {
- if (xf86IsEntityPrimary(xf86Screens[l]->entityList[n])) {
- dev2screen[0] = l;
- primary = TRUE;
- break;
- }
- }
- if (primary) continue;
- /* not primary: assign it to next device of same driver */
- /*
- * NOTE: we assume that devices in DevToConfig
- * and xf86Screens[] have the same order except
- * for the primary device which always comes first.
- */
- for (; k < nDevToConfig; k++) {
- if (DevToConfig[k].iDriver == i) {
- dev2screen[k++] = l;
- break;
- }
- }
- }
- }
- xfree(driverProbed);
- }
-
-
- if (nDevToConfig != xf86NumScreens) {
- ErrorF("Number of created screens does not match number of detected"
- " devices.\n Configuration failed.\n");
- goto bail;
- }
-
- xf86PostProbe();
- xf86EntityInit();
-
- for (j = 0; j < xf86NumScreens; j++) {
- xf86Screens[j]->scrnIndex = j;
- }
-
- xf86freeMonitorList(xf86config->conf_monitor_lst);
- xf86config->conf_monitor_lst = NULL;
- xf86freeScreenList(xf86config->conf_screen_lst);
- xf86config->conf_screen_lst = NULL;
- for (j = 0; j < xf86NumScreens; j++) {
- XF86ConfMonitorPtr MonitorPtr;
- XF86ConfScreenPtr ScreenPtr;
-
- ConfiguredMonitor = NULL;
-
- xf86EnableAccess(xf86Screens[dev2screen[j]]);
- if ((*xf86Screens[dev2screen[j]]->PreInit)(xf86Screens[dev2screen[j]],
- PROBE_DETECT) &&
- ConfiguredMonitor) {
- MonitorPtr = configureDDCMonitorSection(j);
- } else {
- MonitorPtr = configureMonitorSection(j);
- }
- ScreenPtr = configureScreenSection(j);
- xf86config->conf_monitor_lst = (XF86ConfMonitorPtr)xf86addListItem(
- (glp)xf86config->conf_monitor_lst, (glp)MonitorPtr);
- xf86config->conf_screen_lst = (XF86ConfScreenPtr)xf86addListItem(
- (glp)xf86config->conf_screen_lst, (glp)ScreenPtr);
- }
-
- if (xf86writeConfigFile(filename, xf86config) == 0) {
- xf86Msg(X_ERROR, "Unable to write config file: \"%s\": %s\n",
- filename, strerror(errno));
- goto bail;
- }
-
- ErrorF("\n");
-
-#ifdef __SCO__
- ErrorF("\n"__XSERVERNAME__
- " is using the kernel event driver to access the mouse.\n"
- "If you wish to use the internal "__XSERVERNAME__
- " mouse drivers, please\n"
- "edit the file and correct the Device.\n");
-#else /* !__SCO__ */
- if (!foundMouse) {
- ErrorF("\n"__XSERVERNAME__" is not able to detect your mouse.\n"
- "Edit the file and correct the Device.\n");
- } else {
- ErrorF("\n"__XSERVERNAME__" detected your mouse at device %s.\n"
- "Please check your config if the mouse is still not\n"
- "operational, as by default "__XSERVERNAME__
- " tries to autodetect\n"
- "the protocol.\n",DFLT_MOUSE_DEV);
- }
-#endif /* !__SCO__ */
-
- if (xf86NumScreens > 1) {
- ErrorF("\n"__XSERVERNAME__
- " has configured a multihead system, please check your config.\n");
- }
-
- ErrorF("\nYour %s file is %s\n\n", XF86CONFIGFILE ,filename);
- ErrorF("To test the server, run 'X -config %s'\n\n", filename);
-
-bail:
- OsCleanup(TRUE);
- AbortDDX();
- fflush(stderr);
- exit(0);
-}
+/*
+ * Copyright 2000-2002 by Alan Hourihane, Flint Mountain, North Wales.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Alan Hourihane, alanh@fairlite.demon.co.uk
+ *
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "xf86.h"
+#include "xf86Config.h"
+#include "xf86_OSlib.h"
+#include "xf86Priv.h"
+#define IN_XSERVER
+#include "Configint.h"
+#include "xf86DDC.h"
+#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
+#include "xf86Bus.h"
+#include "xf86Sbus.h"
+#endif
+
+typedef struct _DevToConfig {
+ GDevRec GDev;
+ struct pci_device * pVideo;
+#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
+ sbusDevicePtr sVideo;
+#endif
+ int iDriver;
+} DevToConfigRec, *DevToConfigPtr;
+
+static DevToConfigPtr DevToConfig = NULL;
+static int nDevToConfig = 0, CurrentDriver;
+
+xf86MonPtr ConfiguredMonitor;
+Bool xf86DoConfigurePass1 = TRUE;
+static Bool foundMouse = FALSE;
+
+#if defined(__SCO__)
+static char *DFLT_MOUSE_PROTO = "OSMouse";
+#elif defined(__UNIXWARE__)
+static char *DFLT_MOUSE_PROTO = "OSMouse";
+static char *DFLT_MOUSE_DEV = "/dev/mouse";
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
+static char *DFLT_MOUSE_DEV = "/dev/sysmouse";
+static char *DFLT_MOUSE_PROTO = "auto";
+#elif defined(linux)
+static char DFLT_MOUSE_DEV[] = "/dev/input/mice";
+static char DFLT_MOUSE_PROTO[] = "auto";
+#else
+static char *DFLT_MOUSE_DEV = "/dev/mouse";
+static char *DFLT_MOUSE_PROTO = "auto";
+#endif
+
+static Bool
+bus_pci_configure(void *busData)
+{
+ int i;
+ struct pci_device * pVideo = NULL;
+
+ pVideo = (struct pci_device *) busData;
+ for (i = 0; i < nDevToConfig; i++)
+ if (DevToConfig[i].pVideo &&
+ (DevToConfig[i].pVideo->domain == pVideo->domain) &&
+ (DevToConfig[i].pVideo->bus == pVideo->bus) &&
+ (DevToConfig[i].pVideo->dev == pVideo->dev) &&
+ (DevToConfig[i].pVideo->func == pVideo->func))
+ return 0;
+
+ return 1;
+}
+
+static Bool
+bus_sbus_configure(void *busData)
+{
+#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
+ int i;
+
+ for (i = 0; i < nDevToConfig; i++)
+ if (DevToConfig[i].sVideo &&
+ DevToConfig[i].sVideo->fbNum == ((sbusDevicePtr) busData)->fbNum)
+ return 0;
+
+#endif
+ return 1;
+}
+
+static void
+bus_pci_newdev_configure(void *busData, int i, int *chipset)
+{
+ const char *VendorName;
+ const char *CardName;
+ char busnum[8];
+ struct pci_device * pVideo = NULL;
+
+ pVideo = (struct pci_device *) busData;
+
+ DevToConfig[i].pVideo = pVideo;
+
+ VendorName = pci_device_get_vendor_name( pVideo );
+ CardName = pci_device_get_device_name( pVideo );
+
+ if (!VendorName) {
+ VendorName = xnfalloc(15);
+ sprintf((char*)VendorName, "Unknown Vendor");
+ }
+
+ if (!CardName) {
+ CardName = xnfalloc(14);
+ sprintf((char*)CardName, "Unknown Board");
+ }
+
+ DevToConfig[i].GDev.identifier =
+ xnfalloc(strlen(VendorName) + strlen(CardName) + 2);
+ sprintf(DevToConfig[i].GDev.identifier, "%s %s", VendorName, CardName);
+
+ DevToConfig[i].GDev.vendor = (char *)VendorName;
+ DevToConfig[i].GDev.board = (char *)CardName;
+
+ DevToConfig[i].GDev.busID = xnfalloc(16);
+ xf86FormatPciBusNumber(pVideo->bus, busnum);
+ sprintf(DevToConfig[i].GDev.busID, "PCI:%s:%d:%d",
+ busnum, pVideo->dev, pVideo->func);
+
+ DevToConfig[i].GDev.chipID = pVideo->device_id;
+ DevToConfig[i].GDev.chipRev = pVideo->revision;
+
+ if (*chipset < 0) {
+ *chipset = (pVideo->vendor_id << 16) | pVideo->device_id;
+ }
+}
+
+static void
+bus_sbus_newdev_configure(void *busData, int i)
+{
+#if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__)
+ char *promPath = NULL;
+ DevToConfig[i].sVideo = (sbusDevicePtr) busData;
+ DevToConfig[i].GDev.identifier = DevToConfig[i].sVideo->descr;
+ if (sparcPromInit() >= 0) {
+ promPath = sparcPromNode2Pathname(&DevToConfig[i].sVideo->node);
+ sparcPromClose();
+ }
+ if (promPath) {
+ DevToConfig[i].GDev.busID = xnfalloc(strlen(promPath) + 6);
+ sprintf(DevToConfig[i].GDev.busID, "SBUS:%s", promPath);
+ free(promPath);
+ } else {
+ DevToConfig[i].GDev.busID = xnfalloc(12);
+ sprintf(DevToConfig[i].GDev.busID, "SBUS:fb%d",
+ DevToConfig[i].sVideo->fbNum);
+ }
+#endif
+}
+
+/*
+ * This is called by the driver, either through xf86Match???Instances() or
+ * directly. We allocate a GDevRec and fill it in as much as we can, letting
+ * the caller fill in the rest and/or change it as it sees fit.
+ */
+GDevPtr
+xf86AddBusDeviceToConfigure(const char *driver, BusType bus, void *busData, int chipset)
+{
+ int ret, i, j;
+
+ if (!xf86DoConfigure || !xf86DoConfigurePass1)
+ return NULL;
+
+ /* Check for duplicates */
+ switch (bus) {
+ case BUS_PCI:
+ ret = bus_pci_configure(busData);
+ break;
+ case BUS_SBUS:
+ ret = bus_sbus_configure(busData);
+ break;
+ default:
+ return NULL;
+ }
+
+ if (ret == 0)
+ goto out;
+
+ /* Allocate new structure occurrence */
+ i = nDevToConfig++;
+ DevToConfig =
+ xnfrealloc(DevToConfig, nDevToConfig * sizeof(DevToConfigRec));
+ memset(DevToConfig + i, 0, sizeof(DevToConfigRec));
+
+ DevToConfig[i].GDev.chipID =
+ DevToConfig[i].GDev.chipRev = DevToConfig[i].GDev.irq = -1;
+
+ DevToConfig[i].iDriver = CurrentDriver;
+
+ /* Fill in what we know, converting the driver name to lower case */
+ DevToConfig[i].GDev.driver = xnfalloc(strlen(driver) + 1);
+ for (j = 0; (DevToConfig[i].GDev.driver[j] = tolower(driver[j])); j++);
+
+ switch (bus) {
+ case BUS_PCI:
+ bus_pci_newdev_configure(busData, i, &chipset);
+ break;
+ case BUS_SBUS:
+ bus_sbus_newdev_configure(busData, i);
+ break;
+ default:
+ break;
+ }
+
+ /* Get driver's available options */
+ if (xf86DriverList[CurrentDriver]->AvailableOptions)
+ DevToConfig[i].GDev.options = (OptionInfoPtr)
+ (*xf86DriverList[CurrentDriver]->AvailableOptions)(chipset,
+ bus);
+
+ return &DevToConfig[i].GDev;
+
+out:
+ return NULL;
+}
+
+static XF86ConfInputPtr
+configureInputSection (void)
+{
+ XF86ConfInputPtr mouse = NULL;
+ parsePrologue (XF86ConfInputPtr, XF86ConfInputRec)
+
+ ptr->inp_identifier = "Keyboard0";
+ ptr->inp_driver = "kbd";
+ ptr->list.next = NULL;
+
+ /* Crude mechanism to auto-detect mouse (os dependent) */
+ {
+ int fd;
+#ifdef WSCONS_SUPPORT
+ fd = open("/dev/wsmouse", 0);
+ if (fd >= 0) {
+ DFLT_MOUSE_DEV = "/dev/wsmouse";
+ DFLT_MOUSE_PROTO = "wsmouse";
+ close(fd);
+ } else {
+ ErrorF("cannot open /dev/wsmouse\n");
+ }
+#endif
+
+#ifndef __SCO__
+ fd = open(DFLT_MOUSE_DEV, 0);
+ if (fd != -1) {
+ foundMouse = TRUE;
+ close(fd);
+ }
+#else
+ foundMouse = TRUE;
+#endif
+ }
+
+ mouse = calloc(1, sizeof(XF86ConfInputRec));
+ mouse->inp_identifier = "Mouse0";
+ mouse->inp_driver = "mouse";
+ mouse->inp_option_lst =
+ xf86addNewOption(mouse->inp_option_lst, xstrdup("Protocol"),
+ xstrdup(DFLT_MOUSE_PROTO));
+#ifndef __SCO__
+ mouse->inp_option_lst =
+ xf86addNewOption(mouse->inp_option_lst, xstrdup("Device"),
+ xstrdup(DFLT_MOUSE_DEV));
+#endif
+ mouse->inp_option_lst =
+ xf86addNewOption(mouse->inp_option_lst, xstrdup("ZAxisMapping"),
+ xstrdup("4 5 6 7"));
+ ptr = (XF86ConfInputPtr)xf86addListItem((glp)ptr, (glp)mouse);
+ return ptr;
+}
+
+static XF86ConfScreenPtr
+configureScreenSection (int screennum)
+{
+ int i;
+ int depths[] = { 1, 4, 8, 15, 16, 24/*, 32*/ };
+ parsePrologue (XF86ConfScreenPtr, XF86ConfScreenRec)
+
+ ptr->scrn_identifier = malloc(18);
+ sprintf(ptr->scrn_identifier, "Screen%d", screennum);
+ ptr->scrn_monitor_str = malloc(19);
+ sprintf(ptr->scrn_monitor_str, "Monitor%d", screennum);
+ ptr->scrn_device_str = malloc(16);
+ sprintf(ptr->scrn_device_str, "Card%d", screennum);
+
+ for (i=0; i<sizeof(depths)/sizeof(depths[0]); i++)
+ {
+ XF86ConfDisplayPtr display;
+
+ display = calloc(1, sizeof(XF86ConfDisplayRec));
+ display->disp_depth = depths[i];
+ display->disp_black.red = display->disp_white.red = -1;
+ display->disp_black.green = display->disp_white.green = -1;
+ display->disp_black.blue = display->disp_white.blue = -1;
+ ptr->scrn_display_lst = (XF86ConfDisplayPtr)xf86addListItem(
+ (glp)ptr->scrn_display_lst, (glp)display);
+ }
+
+ return ptr;
+}
+
+static const char*
+optionTypeToSting(OptionValueType type)
+{
+ switch (type) {
+ case OPTV_NONE:
+ return "";
+ case OPTV_INTEGER:
+ return "<i>";
+ case OPTV_STRING:
+ return "<str>";
+ case OPTV_ANYSTR:
+ return "[<str>]";
+ case OPTV_REAL:
+ return "<f>";
+ case OPTV_BOOLEAN:
+ return "[<bool>]";
+ case OPTV_FREQ:
+ return "<freq>";
+ default:
+ return "";
+ }
+}
+
+static XF86ConfDevicePtr
+configureDeviceSection (int screennum)
+{
+ char identifier[16];
+ OptionInfoPtr p;
+ int i = 0;
+ parsePrologue (XF86ConfDevicePtr, XF86ConfDeviceRec)
+
+ /* Move device info to parser structure */
+ sprintf(identifier, "Card%d", screennum);
+ ptr->dev_identifier = strdup(identifier);
+/* ptr->dev_identifier = DevToConfig[screennum].GDev.identifier;*/
+ ptr->dev_vendor = DevToConfig[screennum].GDev.vendor;
+ ptr->dev_board = DevToConfig[screennum].GDev.board;
+ ptr->dev_chipset = DevToConfig[screennum].GDev.chipset;
+ ptr->dev_busid = DevToConfig[screennum].GDev.busID;
+ ptr->dev_driver = DevToConfig[screennum].GDev.driver;
+ ptr->dev_ramdac = DevToConfig[screennum].GDev.ramdac;
+ for (i = 0; (i < MAXDACSPEEDS) && (i < CONF_MAXDACSPEEDS); i++)
+ ptr->dev_dacSpeeds[i] = DevToConfig[screennum].GDev.dacSpeeds[i];
+ ptr->dev_videoram = DevToConfig[screennum].GDev.videoRam;
+ ptr->dev_textclockfreq = DevToConfig[screennum].GDev.textClockFreq;
+ ptr->dev_bios_base = DevToConfig[screennum].GDev.BiosBase;
+ ptr->dev_mem_base = DevToConfig[screennum].GDev.MemBase;
+ ptr->dev_io_base = DevToConfig[screennum].GDev.IOBase;
+ ptr->dev_clockchip = DevToConfig[screennum].GDev.clockchip;
+ for (i = 0; (i < MAXCLOCKS) && (i < DevToConfig[screennum].GDev.numclocks); i++)
+ ptr->dev_clock[i] = DevToConfig[screennum].GDev.clock[i];
+ ptr->dev_clocks = i;
+ ptr->dev_chipid = DevToConfig[screennum].GDev.chipID;
+ ptr->dev_chiprev = DevToConfig[screennum].GDev.chipRev;
+ ptr->dev_irq = DevToConfig[screennum].GDev.irq;
+
+ /* Make sure older drivers don't segv */
+ if (DevToConfig[screennum].GDev.options) {
+ /* Fill in the available driver options for people to use */
+ const char *descrip =
+ " ### Available Driver options are:-\n"
+ " ### Values: <i>: integer, <f>: float, "
+ "<bool>: \"True\"/\"False\",\n"
+ " ### <string>: \"String\", <freq>: \"<f> Hz/kHz/MHz\"\n"
+ " ### [arg]: arg optional\n";
+ ptr->dev_comment = xstrdup(descrip);
+ if (ptr->dev_comment) {
+ for (p = DevToConfig[screennum].GDev.options;
+ p->name != NULL; p++) {
+ char *p_e;
+ const char *prefix = " #Option ";
+ const char *middle = " \t# ";
+ const char *suffix = "\n";
+ const char *opttype = optionTypeToSting(p->type);
+ char *optname;
+ int len = strlen(ptr->dev_comment) + strlen(prefix) +
+ strlen(middle) + strlen(suffix) + 1;
+
+ optname = malloc(strlen(p->name) + 2 + 1);
+ if (!optname)
+ break;
+ sprintf(optname, "\"%s\"", p->name);
+
+ len += max(20, strlen(optname));
+ len += strlen(opttype);
+
+ ptr->dev_comment = realloc(ptr->dev_comment, len);
+ if (!ptr->dev_comment)
+ break;
+ p_e = ptr->dev_comment + strlen(ptr->dev_comment);
+ sprintf(p_e, "%s%-20s%s%s%s", prefix, optname, middle,
+ opttype, suffix);
+ free(optname);
+ }
+ }
+ }
+
+ return ptr;
+}
+
+static XF86ConfLayoutPtr
+configureLayoutSection (void)
+{
+ int scrnum = 0;
+ parsePrologue (XF86ConfLayoutPtr, XF86ConfLayoutRec)
+
+ ptr->lay_identifier = "X.org Configured";
+
+ {
+ XF86ConfInputrefPtr iptr;
+
+ iptr = malloc (sizeof (XF86ConfInputrefRec));
+ iptr->list.next = NULL;
+ iptr->iref_option_lst = NULL;
+ iptr->iref_inputdev_str = "Mouse0";
+ iptr->iref_option_lst =
+ xf86addNewOption (iptr->iref_option_lst, xstrdup("CorePointer"), NULL);
+ ptr->lay_input_lst = (XF86ConfInputrefPtr)
+ xf86addListItem ((glp) ptr->lay_input_lst, (glp) iptr);
+ }
+
+ {
+ XF86ConfInputrefPtr iptr;
+
+ iptr = malloc (sizeof (XF86ConfInputrefRec));
+ iptr->list.next = NULL;
+ iptr->iref_option_lst = NULL;
+ iptr->iref_inputdev_str = "Keyboard0";
+ iptr->iref_option_lst =
+ xf86addNewOption (iptr->iref_option_lst, xstrdup("CoreKeyboard"), NULL);
+ ptr->lay_input_lst = (XF86ConfInputrefPtr)
+ xf86addListItem ((glp) ptr->lay_input_lst, (glp) iptr);
+ }
+
+ for (scrnum = 0; scrnum < nDevToConfig; scrnum++) {
+ XF86ConfAdjacencyPtr aptr;
+
+ aptr = malloc (sizeof (XF86ConfAdjacencyRec));
+ aptr->list.next = NULL;
+ aptr->adj_x = 0;
+ aptr->adj_y = 0;
+ aptr->adj_scrnum = scrnum;
+ aptr->adj_screen_str = xnfalloc(18);
+ sprintf(aptr->adj_screen_str, "Screen%d", scrnum);
+ if (scrnum == 0) {
+ aptr->adj_where = CONF_ADJ_ABSOLUTE;
+ aptr->adj_refscreen = NULL;
+ }
+ else {
+ aptr->adj_where = CONF_ADJ_RIGHTOF;
+ aptr->adj_refscreen = xnfalloc(18);
+ sprintf(aptr->adj_refscreen, "Screen%d", scrnum - 1);
+ }
+ ptr->lay_adjacency_lst =
+ (XF86ConfAdjacencyPtr)xf86addListItem((glp)ptr->lay_adjacency_lst,
+ (glp)aptr);
+ }
+
+ return ptr;
+}
+
+static XF86ConfFlagsPtr
+configureFlagsSection (void)
+{
+ parsePrologue (XF86ConfFlagsPtr, XF86ConfFlagsRec)
+
+ return ptr;
+}
+
+static XF86ConfModulePtr
+configureModuleSection (void)
+{
+ char **elist, **el;
+ /* Find the list of extension & font modules. */
+ const char *esubdirs[] = {
+ "extensions",
+ "fonts",
+ NULL
+ };
+ parsePrologue (XF86ConfModulePtr, XF86ConfModuleRec)
+
+ elist = LoaderListDirs(esubdirs, NULL);
+ if (elist) {
+ for (el = elist; *el; el++) {
+ XF86LoadPtr module;
+
+ module = calloc(1, sizeof(XF86LoadRec));
+ module->load_name = *el;
+ ptr->mod_load_lst = (XF86LoadPtr)xf86addListItem(
+ (glp)ptr->mod_load_lst, (glp)module);
+ }
+ free(elist);
+ }
+
+ return ptr;
+}
+
+static XF86ConfFilesPtr
+configureFilesSection (void)
+{
+ parsePrologue (XF86ConfFilesPtr, XF86ConfFilesRec)
+
+ if (xf86ModulePath)
+ ptr->file_modulepath = strdup(xf86ModulePath);
+ if (defaultFontPath)
+ ptr->file_fontpath = strdup(defaultFontPath);
+
+ return ptr;
+}
+
+static XF86ConfMonitorPtr
+configureMonitorSection (int screennum)
+{
+ parsePrologue (XF86ConfMonitorPtr, XF86ConfMonitorRec)
+
+ ptr->mon_identifier = malloc(19);
+ sprintf(ptr->mon_identifier, "Monitor%d", screennum);
+ ptr->mon_vendor = strdup("Monitor Vendor");
+ ptr->mon_modelname = strdup("Monitor Model");
+
+ return ptr;
+}
+
+/* Initialize Configure Monitor from Detailed Timing Block */
+static void handle_detailed_input(struct detailed_monitor_section *det_mon,
+ void *data)
+{
+ XF86ConfMonitorPtr ptr = (XF86ConfMonitorPtr) data;
+
+ switch (det_mon->type) {
+ case DS_NAME:
+ ptr->mon_modelname = realloc(ptr->mon_modelname,
+ strlen((char*)(det_mon->section.name)) +
+ 1);
+ strcpy(ptr->mon_modelname,
+ (char*)(det_mon->section.name));
+ break;
+ case DS_RANGES:
+ ptr->mon_hsync[ptr->mon_n_hsync].lo =
+ det_mon->section.ranges.min_h;
+ ptr->mon_hsync[ptr->mon_n_hsync].hi =
+ det_mon->section.ranges.max_h;
+ ptr->mon_n_vrefresh = 1;
+ ptr->mon_vrefresh[ptr->mon_n_hsync].lo =
+ det_mon->section.ranges.min_v;
+ ptr->mon_vrefresh[ptr->mon_n_hsync].hi =
+ det_mon->section.ranges.max_v;
+ ptr->mon_n_hsync++;
+ default:
+ break;
+ }
+}
+
+static XF86ConfMonitorPtr
+configureDDCMonitorSection (int screennum)
+{
+ int len, mon_width, mon_height;
+#define displaySizeMaxLen 80
+ char displaySize_string[displaySizeMaxLen];
+ int displaySizeLen;
+
+ parsePrologue (XF86ConfMonitorPtr, XF86ConfMonitorRec)
+
+ ptr->mon_identifier = malloc(19);
+ sprintf(ptr->mon_identifier, "Monitor%d", screennum);
+ ptr->mon_vendor = strdup(ConfiguredMonitor->vendor.name);
+ ptr->mon_modelname = malloc(12);
+ sprintf(ptr->mon_modelname, "%x", ConfiguredMonitor->vendor.prod_id);
+
+ /* features in centimetres, we want millimetres */
+ mon_width = 10 * ConfiguredMonitor->features.hsize ;
+ mon_height = 10 * ConfiguredMonitor->features.vsize ;
+
+#ifdef CONFIGURE_DISPLAYSIZE
+ ptr->mon_width = mon_width;
+ ptr->mon_height = mon_height;
+#else
+ if (mon_width && mon_height) {
+ /* when values available add DisplaySize option AS A COMMENT */
+
+ displaySizeLen = snprintf(displaySize_string, displaySizeMaxLen,
+ "\t#DisplaySize\t%5d %5d\t# mm\n",
+ mon_width, mon_height);
+
+ if (displaySizeLen>0 && displaySizeLen<displaySizeMaxLen) {
+ if (ptr->mon_comment) {
+ len = strlen(ptr->mon_comment);
+ } else {
+ len = 0;
+ }
+ if ((ptr->mon_comment =
+ realloc(ptr->mon_comment, len + strlen(displaySize_string) + 1))) {
+ strcpy(ptr->mon_comment + len, displaySize_string);
+ }
+ }
+ }
+#endif /* def CONFIGURE_DISPLAYSIZE */
+
+ xf86ForEachDetailedBlock(ConfiguredMonitor, handle_detailed_input,
+ ptr);
+
+ if (ConfiguredMonitor->features.dpms) {
+ ptr->mon_option_lst = xf86addNewOption(ptr->mon_option_lst, xstrdup("DPMS"), NULL);
+ }
+
+ return ptr;
+}
+
+#if !defined(PATH_MAX)
+# define PATH_MAX 1024
+#endif
+
+void
+DoConfigure(void)
+{
+ int i,j, screennum = -1;
+ char *home = NULL;
+ char filename[PATH_MAX];
+ char *addslash = "";
+ XF86ConfigPtr xf86config = NULL;
+ char **vlist, **vl;
+ int *dev2screen;
+
+ vlist = xf86DriverlistFromCompile();
+
+ if (!vlist) {
+ ErrorF("Missing output drivers. Configuration failed.\n");
+ goto bail;
+ }
+
+ ErrorF("List of video drivers:\n");
+ for (vl = vlist; *vl; vl++)
+ ErrorF("\t%s\n", *vl);
+
+ /* Load all the drivers that were found. */
+ xf86LoadModules(vlist, NULL);
+
+ free(vlist);
+
+ for (i = 0; i < xf86NumDrivers; i++) {
+ xorgHWFlags flags;
+ if (!xf86DriverList[i]->driverFunc
+ || !xf86DriverList[i]->driverFunc(NULL,
+ GET_REQUIRED_HW_INTERFACES,
+ &flags)
+ || NEED_IO_ENABLED(flags)) {
+ xorgHWAccess = TRUE;
+ break;
+ }
+ }
+ /* Enable full I/O access */
+ if (xorgHWAccess) {
+ if(!xf86EnableIO())
+ /* oops, we have failed */
+ xorgHWAccess = FALSE;
+ }
+
+ xf86FindPrimaryDevice();
+
+ /* Create XF86Config file structure */
+ xf86config = calloc(1, sizeof(XF86ConfigRec));
+
+ /* Call all of the probe functions, reporting the results. */
+ for (CurrentDriver = 0; CurrentDriver < xf86NumDrivers; CurrentDriver++) {
+ xorgHWFlags flags;
+ Bool found_screen;
+ DriverRec * const drv = xf86DriverList[CurrentDriver];
+
+ if (!xorgHWAccess) {
+ if (!drv->driverFunc
+ || !drv->driverFunc( NULL, GET_REQUIRED_HW_INTERFACES, &flags )
+ || NEED_IO_ENABLED(flags))
+ continue;
+ }
+
+ found_screen = xf86CallDriverProbe( drv, TRUE );
+ if ( found_screen && drv->Identify ) {
+ (*drv->Identify)(0);
+ }
+ }
+
+ if (nDevToConfig <= 0) {
+ ErrorF("No devices to configure. Configuration failed.\n");
+ goto bail;
+ }
+
+ /* Add device, monitor and screen sections for detected devices */
+ for (screennum = 0; screennum < nDevToConfig; screennum++) {
+ XF86ConfDevicePtr DevicePtr;
+ XF86ConfMonitorPtr MonitorPtr;
+ XF86ConfScreenPtr ScreenPtr;
+
+ DevicePtr = configureDeviceSection(screennum);
+ xf86config->conf_device_lst = (XF86ConfDevicePtr)xf86addListItem(
+ (glp)xf86config->conf_device_lst, (glp)DevicePtr);
+ MonitorPtr = configureMonitorSection(screennum);
+ xf86config->conf_monitor_lst = (XF86ConfMonitorPtr)xf86addListItem(
+ (glp)xf86config->conf_monitor_lst, (glp)MonitorPtr);
+ ScreenPtr = configureScreenSection(screennum);
+ xf86config->conf_screen_lst = (XF86ConfScreenPtr)xf86addListItem(
+ (glp)xf86config->conf_screen_lst, (glp)ScreenPtr);
+ }
+
+ xf86config->conf_files = configureFilesSection();
+ xf86config->conf_modules = configureModuleSection();
+ xf86config->conf_flags = configureFlagsSection();
+ xf86config->conf_videoadaptor_lst = NULL;
+ xf86config->conf_modes_lst = NULL;
+ xf86config->conf_vendor_lst = NULL;
+ xf86config->conf_dri = NULL;
+ xf86config->conf_input_lst = configureInputSection();
+ xf86config->conf_layout_lst = configureLayoutSection();
+
+ home = getenv("HOME");
+ if ((home == NULL) || (home[0] == '\0')) {
+ home = "/";
+ } else {
+ /* Determine if trailing slash is present or needed */
+ int l = strlen(home);
+
+ if (home[l-1] != '/') {
+ addslash = "/";
+ }
+ }
+
+ snprintf(filename, sizeof(filename), "%s%s" XF86CONFIGFILE ".new",
+ home, addslash);
+
+ if (xf86writeConfigFile(filename, xf86config) == 0) {
+ xf86Msg(X_ERROR, "Unable to write config file: \"%s\": %s\n",
+ filename, strerror(errno));
+ goto bail;
+ }
+
+ xf86DoConfigurePass1 = FALSE;
+ /* Try to get DDC information filled in */
+ xf86ConfigFile = filename;
+ if (xf86HandleConfigFile(FALSE) != CONFIG_OK) {
+ goto bail;
+ }
+
+ xf86DoConfigurePass1 = FALSE;
+
+ dev2screen = xnfcalloc(1,xf86NumDrivers*sizeof(int));
+
+ {
+ Bool *driverProbed = xnfcalloc(1,xf86NumDrivers*sizeof(Bool));
+ for (screennum = 0; screennum < nDevToConfig; screennum++) {
+ int k,l,n,oldNumScreens;
+
+ i = DevToConfig[screennum].iDriver;
+
+ if (driverProbed[i]) continue;
+ driverProbed[i] = TRUE;
+
+ oldNumScreens = xf86NumScreens;
+
+ xf86CallDriverProbe( xf86DriverList[i], FALSE );
+
+ /* reorder */
+ k = screennum > 0 ? screennum : 1;
+ for (l = oldNumScreens; l < xf86NumScreens; l++) {
+ /* is screen primary? */
+ Bool primary = FALSE;
+ for (n = 0; n<xf86Screens[l]->numEntities; n++) {
+ if (xf86IsEntityPrimary(xf86Screens[l]->entityList[n])) {
+ dev2screen[0] = l;
+ primary = TRUE;
+ break;
+ }
+ }
+ if (primary) continue;
+ /* not primary: assign it to next device of same driver */
+ /*
+ * NOTE: we assume that devices in DevToConfig
+ * and xf86Screens[] have the same order except
+ * for the primary device which always comes first.
+ */
+ for (; k < nDevToConfig; k++) {
+ if (DevToConfig[k].iDriver == i) {
+ dev2screen[k++] = l;
+ break;
+ }
+ }
+ }
+ }
+ free(driverProbed);
+ }
+
+
+ if (nDevToConfig != xf86NumScreens) {
+ ErrorF("Number of created screens does not match number of detected"
+ " devices.\n Configuration failed.\n");
+ goto bail;
+ }
+
+ xf86PostProbe();
+ xf86EntityInit();
+
+ for (j = 0; j < xf86NumScreens; j++) {
+ xf86Screens[j]->scrnIndex = j;
+ }
+
+ xf86freeMonitorList(xf86config->conf_monitor_lst);
+ xf86config->conf_monitor_lst = NULL;
+ xf86freeScreenList(xf86config->conf_screen_lst);
+ xf86config->conf_screen_lst = NULL;
+ for (j = 0; j < xf86NumScreens; j++) {
+ XF86ConfMonitorPtr MonitorPtr;
+ XF86ConfScreenPtr ScreenPtr;
+
+ ConfiguredMonitor = NULL;
+
+ xf86EnableAccess(xf86Screens[dev2screen[j]]);
+ if ((*xf86Screens[dev2screen[j]]->PreInit)(xf86Screens[dev2screen[j]],
+ PROBE_DETECT) &&
+ ConfiguredMonitor) {
+ MonitorPtr = configureDDCMonitorSection(j);
+ } else {
+ MonitorPtr = configureMonitorSection(j);
+ }
+ ScreenPtr = configureScreenSection(j);
+ xf86config->conf_monitor_lst = (XF86ConfMonitorPtr)xf86addListItem(
+ (glp)xf86config->conf_monitor_lst, (glp)MonitorPtr);
+ xf86config->conf_screen_lst = (XF86ConfScreenPtr)xf86addListItem(
+ (glp)xf86config->conf_screen_lst, (glp)ScreenPtr);
+ }
+
+ if (xf86writeConfigFile(filename, xf86config) == 0) {
+ xf86Msg(X_ERROR, "Unable to write config file: \"%s\": %s\n",
+ filename, strerror(errno));
+ goto bail;
+ }
+
+ ErrorF("\n");
+
+#ifdef __SCO__
+ ErrorF("\n"__XSERVERNAME__
+ " is using the kernel event driver to access the mouse.\n"
+ "If you wish to use the internal "__XSERVERNAME__
+ " mouse drivers, please\n"
+ "edit the file and correct the Device.\n");
+#else /* !__SCO__ */
+ if (!foundMouse) {
+ ErrorF("\n"__XSERVERNAME__" is not able to detect your mouse.\n"
+ "Edit the file and correct the Device.\n");
+ } else {
+ ErrorF("\n"__XSERVERNAME__" detected your mouse at device %s.\n"
+ "Please check your config if the mouse is still not\n"
+ "operational, as by default "__XSERVERNAME__
+ " tries to autodetect\n"
+ "the protocol.\n",DFLT_MOUSE_DEV);
+ }
+#endif /* !__SCO__ */
+
+ if (xf86NumScreens > 1) {
+ ErrorF("\n"__XSERVERNAME__
+ " has configured a multihead system, please check your config.\n");
+ }
+
+ ErrorF("\nYour %s file is %s\n\n", XF86CONFIGFILE ,filename);
+ ErrorF("To test the server, run 'X -config %s'\n\n", filename);
+
+bail:
+ OsCleanup(TRUE);
+ AbortDDX();
+ fflush(stderr);
+ exit(0);
+}
diff --git a/xorg-server/hw/xfree86/common/xf86Cursor.c b/xorg-server/hw/xfree86/common/xf86Cursor.c
index 6740faf65..76490e52d 100644
--- a/xorg-server/hw/xfree86/common/xf86Cursor.c
+++ b/xorg-server/hw/xfree86/common/xf86Cursor.c
@@ -1,862 +1,862 @@
-/*
- * Copyright (c) 1994-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xmd.h>
-#include "input.h"
-#include "cursor.h"
-#include "mipointer.h"
-#include "scrnintstr.h"
-#include "globals.h"
-
-#include "compiler.h"
-
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86_OSproc.h"
-
-#include <X11/extensions/XIproto.h>
-#include "xf86Xinput.h"
-
-#ifdef XFreeXDGA
-#include "dgaproc.h"
-#endif
-
-typedef struct _xf86EdgeRec {
- short screen;
- short start;
- short end;
- DDXPointRec offset;
- struct _xf86EdgeRec *next;
-} xf86EdgeRec, *xf86EdgePtr;
-
-typedef struct {
- xf86EdgePtr left, right, up, down;
-} xf86ScreenLayoutRec, *xf86ScreenLayoutPtr;
-
-static Bool xf86CursorOffScreen(ScreenPtr *pScreen, int *x, int *y);
-static void xf86CrossScreen(ScreenPtr pScreen, Bool entering);
-static void xf86WarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y);
-
-static void xf86PointerMoved(int scrnIndex, int x, int y);
-
-static miPointerScreenFuncRec xf86PointerScreenFuncs = {
- xf86CursorOffScreen,
- xf86CrossScreen,
- xf86WarpCursor,
- /* let miPointerInitialize take care of these */
- NULL,
- NULL
-};
-
-static xf86ScreenLayoutRec xf86ScreenLayout[MAXSCREENS];
-
-static Bool HardEdges;
-
-/*
- * xf86InitViewport --
- * Initialize paning & zooming parameters, so that a driver must only
- * check what resolutions are possible and whether the virtual area
- * is valid if specified.
- */
-
-void
-xf86InitViewport(ScrnInfoPtr pScr)
-{
-
- pScr->PointerMoved = xf86PointerMoved;
-
- /*
- * Compute the initial Viewport if necessary
- */
- if (pScr->display) {
- if (pScr->display->frameX0 < 0) {
- pScr->frameX0 = (pScr->virtualX - pScr->modes->HDisplay) / 2;
- pScr->frameY0 = (pScr->virtualY - pScr->modes->VDisplay) / 2;
- } else {
- pScr->frameX0 = pScr->display->frameX0;
- pScr->frameY0 = pScr->display->frameY0;
- }
- }
-
- pScr->frameX1 = pScr->frameX0 + pScr->modes->HDisplay - 1;
- pScr->frameY1 = pScr->frameY0 + pScr->modes->VDisplay - 1;
-
- /*
- * Now adjust the initial Viewport, so it lies within the virtual area
- */
- if (pScr->frameX1 >= pScr->virtualX)
- {
- pScr->frameX0 = pScr->virtualX - pScr->modes->HDisplay;
- pScr->frameX1 = pScr->frameX0 + pScr->modes->HDisplay - 1;
- }
-
- if (pScr->frameY1 >= pScr->virtualY)
- {
- pScr->frameY0 = pScr->virtualY - pScr->modes->VDisplay;
- pScr->frameY1 = pScr->frameY0 + pScr->modes->VDisplay - 1;
- }
-}
-
-
-/*
- * xf86SetViewport --
- * Scroll the visual part of the screen so the pointer is visible.
- */
-
-void
-xf86SetViewport(ScreenPtr pScreen, int x, int y)
-{
- ScrnInfoPtr pScr = XF86SCRNINFO(pScreen);
-
- (*pScr->PointerMoved)(pScreen->myNum, x, y);
-}
-
-
-static void
-xf86PointerMoved(int scrnIndex, int x, int y)
-{
- Bool frameChanged = FALSE;
- ScrnInfoPtr pScr = xf86Screens[scrnIndex];
-
- /*
- * check wether (x,y) belongs to the visual part of the screen
- * if not, change the base of the displayed frame accoring
- */
- if ( pScr->frameX0 > x) {
- pScr->frameX0 = x;
- pScr->frameX1 = x + pScr->currentMode->HDisplay - 1;
- frameChanged = TRUE ;
- }
-
- if ( pScr->frameX1 < x) {
- pScr->frameX1 = x + 1;
- pScr->frameX0 = x - pScr->currentMode->HDisplay + 1;
- frameChanged = TRUE ;
- }
-
- if ( pScr->frameY0 > y) {
- pScr->frameY0 = y;
- pScr->frameY1 = y + pScr->currentMode->VDisplay - 1;
- frameChanged = TRUE;
- }
-
- if ( pScr->frameY1 < y) {
- pScr->frameY1 = y;
- pScr->frameY0 = y - pScr->currentMode->VDisplay + 1;
- frameChanged = TRUE;
- }
-
- if (frameChanged && pScr->AdjustFrame != NULL)
- pScr->AdjustFrame(pScr->scrnIndex, pScr->frameX0, pScr->frameY0, 0);
-}
-
-/*
- * xf86LockZoom --
- * Enable/disable ZoomViewport
- */
-
-void
-xf86LockZoom(ScreenPtr pScreen, Bool lock)
-{
- XF86SCRNINFO(pScreen)->zoomLocked = lock;
-}
-
-/*
- * xf86SwitchMode --
- * This is called by both keyboard processing and the VidMode extension to
- * set a new mode.
- */
-
-Bool
-xf86SwitchMode(ScreenPtr pScreen, DisplayModePtr mode)
-{
- ScrnInfoPtr pScr = XF86SCRNINFO(pScreen);
- ScreenPtr pCursorScreen;
- Bool Switched;
- int px, py;
- DeviceIntPtr dev, it;
-
- if (!pScr->vtSema || !mode || !pScr->SwitchMode)
- return FALSE;
-
-#ifdef XFreeXDGA
- if (DGAActive(pScr->scrnIndex))
- return FALSE;
-#endif
-
- if (mode == pScr->currentMode)
- return TRUE;
-
- if (mode->HDisplay > pScr->virtualX || mode->VDisplay > pScr->virtualY)
- return FALSE;
-
- /* Let's take an educated guess for which pointer to take here. And about as
- educated as it gets is to take the first pointer we find.
- */
- for (dev = inputInfo.devices; dev; dev = dev->next)
- {
- if (IsPointerDevice(dev) && dev->spriteInfo->spriteOwner)
- break;
- }
-
- pCursorScreen = miPointerGetScreen(dev);
- if (pScreen == pCursorScreen)
- miPointerGetPosition(dev, &px, &py);
-
- xf86EnterServerState(SETUP);
- Switched = (*pScr->SwitchMode)(pScr->scrnIndex, mode, 0);
- if (Switched) {
- pScr->currentMode = mode;
-
- /*
- * Adjust frame for new display size.
- * Frame is centered around cursor position if cursor is on same screen.
- */
- if (pScreen == pCursorScreen)
- pScr->frameX0 = px - (mode->HDisplay / 2) + 1;
- else
- pScr->frameX0 = (pScr->frameX0 + pScr->frameX1 + 1 - mode->HDisplay) / 2;
-
- if (pScr->frameX0 < 0)
- pScr->frameX0 = 0;
-
- pScr->frameX1 = pScr->frameX0 + mode->HDisplay - 1;
- if (pScr->frameX1 >= pScr->virtualX) {
- pScr->frameX0 = pScr->virtualX - mode->HDisplay;
- pScr->frameX1 = pScr->virtualX - 1;
- }
-
- if (pScreen == pCursorScreen)
- pScr->frameY0 = py - (mode->VDisplay / 2) + 1;
- else
- pScr->frameY0 = (pScr->frameY0 + pScr->frameY1 + 1 - mode->VDisplay) / 2;
-
- if (pScr->frameY0 < 0)
- pScr->frameY0 = 0;
-
- pScr->frameY1 = pScr->frameY0 + mode->VDisplay - 1;
- if (pScr->frameY1 >= pScr->virtualY) {
- pScr->frameY0 = pScr->virtualY - mode->VDisplay;
- pScr->frameY1 = pScr->virtualY - 1;
- }
- }
- xf86EnterServerState(OPERATING);
-
- if (pScr->AdjustFrame)
- (*pScr->AdjustFrame)(pScr->scrnIndex, pScr->frameX0, pScr->frameY0, 0);
-
- /* The original code centered the frame around the cursor if possible.
- * Since this is hard to achieve with multiple cursors, we do the following:
- * - center around the first pointer
- * - move all other pointers to the nearest edge on the screen (or leave
- * them unmodified if they are within the boundaries).
- */
- if (pScreen == pCursorScreen)
- {
- xf86WarpCursor(dev, pScreen, px, py);
- }
-
- for (it = inputInfo.devices; it; it = it->next)
- {
- if (it == dev)
- continue;
-
- if (IsPointerDevice(it) && it->spriteInfo->spriteOwner)
- {
- pCursorScreen = miPointerGetScreen(it);
- if (pScreen == pCursorScreen)
- {
- miPointerGetPosition(it, &px, &py);
- if (px < pScr->frameX0)
- px = pScr->frameX0;
- else if (px > pScr->frameX1)
- px = pScr->frameX1;
-
- if(py < pScr->frameY0)
- py = pScr->frameY0;
- else if(py > pScr->frameY1)
- py = pScr->frameY1;
-
- xf86WarpCursor(it, pScreen, px, py);
- }
- }
- }
-
- return Switched;
-}
-
-/*
- * xf86ZoomViewport --
- * Reinitialize the visual part of the screen for another mode.
- */
-
-void
-xf86ZoomViewport(ScreenPtr pScreen, int zoom)
-{
- ScrnInfoPtr pScr = XF86SCRNINFO(pScreen);
- DisplayModePtr mode;
-
- if (pScr->zoomLocked || !(mode = pScr->currentMode))
- return;
-
- do {
- if (zoom > 0)
- mode = mode->next;
- else
- mode = mode->prev;
- } while (mode != pScr->currentMode && !(mode->type & M_T_USERDEF));
-
- (void)xf86SwitchMode(pScreen, mode);
-}
-
-
-static xf86EdgePtr
-FindEdge(xf86EdgePtr edge, int val)
-{
- while(edge && (edge->end <= val))
- edge = edge->next;
-
- if(edge && (edge->start <= val))
- return edge;
-
- return NULL;
-}
-
-/*
- * xf86CursorOffScreen --
- * Check whether it is necessary to switch to another screen
- */
-
-static Bool
-xf86CursorOffScreen(ScreenPtr *pScreen, int *x, int *y)
-{
- xf86EdgePtr edge;
- int tmp;
-
- if(screenInfo.numScreens == 1)
- return FALSE;
-
- if(*x < 0) {
- tmp = *y;
- if(tmp < 0) tmp = 0;
- if(tmp >= (*pScreen)->height) tmp = (*pScreen)->height - 1;
-
- if((edge = xf86ScreenLayout[(*pScreen)->myNum].left))
- edge = FindEdge(edge, tmp);
-
- if(!edge) *x = 0;
- else {
- *x += edge->offset.x;
- *y += edge->offset.y;
- *pScreen = xf86Screens[edge->screen]->pScreen;
- }
- }
-
- if(*x >= (*pScreen)->width) {
- tmp = *y;
- if(tmp < 0) tmp = 0;
- if(tmp >= (*pScreen)->height) tmp = (*pScreen)->height - 1;
-
- if((edge = xf86ScreenLayout[(*pScreen)->myNum].right))
- edge = FindEdge(edge, tmp);
-
- if(!edge) *x = (*pScreen)->width - 1;
- else {
- *x += edge->offset.x;
- *y += edge->offset.y;
- *pScreen = xf86Screens[edge->screen]->pScreen;
- }
- }
-
- if(*y < 0) {
- tmp = *x;
- if(tmp < 0) tmp = 0;
- if(tmp >= (*pScreen)->width) tmp = (*pScreen)->width - 1;
-
- if((edge = xf86ScreenLayout[(*pScreen)->myNum].up))
- edge = FindEdge(edge, tmp);
-
- if(!edge) *y = 0;
- else {
- *x += edge->offset.x;
- *y += edge->offset.y;
- *pScreen = xf86Screens[edge->screen]->pScreen;
- }
- }
-
- if(*y >= (*pScreen)->height) {
- tmp = *x;
- if(tmp < 0) tmp = 0;
- if(tmp >= (*pScreen)->width) tmp = (*pScreen)->width - 1;
-
- if((edge = xf86ScreenLayout[(*pScreen)->myNum].down))
- edge = FindEdge(edge, tmp);
-
- if(!edge) *y = (*pScreen)->height - 1;
- else {
- *x += edge->offset.x;
- *y += edge->offset.y;
- (*pScreen) = xf86Screens[edge->screen]->pScreen;
- }
- }
-
-
-#if 0
- /* This presents problems for overlapping screens when
- HardEdges is used. Have to think about the logic more */
- if((*x < 0) || (*x >= (*pScreen)->width) ||
- (*y < 0) || (*y >= (*pScreen)->height)) {
- /* We may have crossed more than one screen */
- xf86CursorOffScreen(pScreen, x, y);
- }
-#endif
-
- return TRUE;
-}
-
-
-
-/*
- * xf86CrossScreen --
- * Switch to another screen
- *
- * Currently nothing special happens, but mi assumes the CrossScreen
- * method exists.
- */
-
-static void
-xf86CrossScreen (ScreenPtr pScreen, Bool entering)
-{
-}
-
-
-/*
- * xf86WarpCursor --
- * Warp possible to another screen
- */
-
-/* ARGSUSED */
-static void
-xf86WarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
-{
- int sigstate;
- sigstate = xf86BlockSIGIO ();
- miPointerWarpCursor(pDev, pScreen, x, y);
-
- xf86Info.currentScreen = pScreen;
- xf86UnblockSIGIO (sigstate);
-}
-
-
-void *
-xf86GetPointerScreenFuncs(void)
-{
- return (void *)&xf86PointerScreenFuncs;
-}
-
-
-static xf86EdgePtr
-AddEdge(
- xf86EdgePtr edge,
- short min,
- short max,
- short dx,
- short dy,
- short screen
-){
- xf86EdgePtr pEdge = edge, pPrev = NULL, pNew;
-
- while(1) {
- while(pEdge && (min >= pEdge->end)) {
- pPrev = pEdge;
- pEdge = pEdge->next;
- }
-
- if(!pEdge) {
- if(!(pNew = xalloc(sizeof(xf86EdgeRec))))
- break;
-
- pNew->screen = screen;
- pNew->start = min;
- pNew->end = max;
- pNew->offset.x = dx;
- pNew->offset.y = dy;
- pNew->next = NULL;
-
- if(pPrev)
- pPrev->next = pNew;
- else
- edge = pNew;
-
- break;
- } else if (min < pEdge->start) {
- if(!(pNew = xalloc(sizeof(xf86EdgeRec))))
- break;
-
- pNew->screen = screen;
- pNew->start = min;
- pNew->offset.x = dx;
- pNew->offset.y = dy;
- pNew->next = pEdge;
-
- if(pPrev) pPrev->next = pNew;
- else edge = pNew;
-
- if(max <= pEdge->start) {
- pNew->end = max;
- break;
- } else {
- pNew->end = pEdge->start;
- min = pEdge->end;
- }
- } else
- min = pEdge->end;
-
- pPrev = pEdge;
- pEdge = pEdge->next;
-
- if(max <= min) break;
- }
-
- return edge;
-}
-
-static void
-FillOutEdge(xf86EdgePtr pEdge, int limit)
-{
- xf86EdgePtr pNext;
- int diff;
-
- if(pEdge->start > 0) pEdge->start = 0;
-
- while((pNext = pEdge->next)) {
- diff = pNext->start - pEdge->end;
- if(diff > 0) {
- pEdge->end += diff >> 1;
- pNext->start -= diff - (diff >> 1);
- }
- pEdge = pNext;
- }
-
- if(pEdge->end < limit)
- pEdge->end = limit;
-}
-
-/*
- * xf86InitOrigins() can deal with a maximum of 32 screens
- * on 32 bit architectures, 64 on 64 bit architectures.
- */
-
-void
-xf86InitOrigins(void)
-{
- unsigned long screensLeft, prevScreensLeft, mask;
- screenLayoutPtr screen;
- ScreenPtr pScreen;
- int x1, x2, y1, y2, left, right, top, bottom;
- int i, j, ref, minX, minY, min, max;
- xf86ScreenLayoutPtr pLayout;
- Bool OldStyleConfig = FALSE;
-
- /* need to have this set up with a config file option */
- HardEdges = FALSE;
-
- bzero(xf86ScreenLayout, MAXSCREENS * sizeof(xf86ScreenLayoutRec));
-
- screensLeft = prevScreensLeft = (1 << xf86NumScreens) - 1;
-
- while(1) {
- for(mask = screensLeft, i = 0; mask; mask >>= 1, i++) {
- if(!(mask & 1L)) continue;
-
- screen = &xf86ConfigLayout.screens[i];
-
- if (screen->refscreen != NULL &&
- screen->refscreen->screennum >= xf86NumScreens) {
- screensLeft &= ~(1 << i);
- xf86Msg(X_WARNING, "Not including screen \"%s\" in origins calculation.\n",
- screen->screen->id);
- continue;
- }
-
- switch(screen->where) {
- case PosObsolete:
- OldStyleConfig = TRUE;
- pLayout = &xf86ScreenLayout[i];
- /* force edge lists */
- if(screen->left) {
- ref = screen->left->screennum;
- if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
- ErrorF("Referenced uninitialized screen in Layout!\n");
- break;
- }
- pLayout->left = AddEdge(pLayout->left,
- 0, xf86Screens[i]->pScreen->height,
- xf86Screens[ref]->pScreen->width, 0, ref);
- }
- if(screen->right) {
- ref = screen->right->screennum;
- if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
- ErrorF("Referenced uninitialized screen in Layout!\n");
- break;
- }
- pScreen = xf86Screens[i]->pScreen;
- pLayout->right = AddEdge(pLayout->right,
- 0, pScreen->height, -pScreen->width, 0, ref);
- }
- if(screen->top) {
- ref = screen->top->screennum;
- if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
- ErrorF("Referenced uninitialized screen in Layout!\n");
- break;
- }
- pLayout->up = AddEdge(pLayout->up,
- 0, xf86Screens[i]->pScreen->width,
- 0, xf86Screens[ref]->pScreen->height, ref);
- }
- if(screen->bottom) {
- ref = screen->bottom->screennum;
- if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
- ErrorF("Referenced uninitialized screen in Layout!\n");
- break;
- }
- pScreen = xf86Screens[i]->pScreen;
- pLayout->down = AddEdge(pLayout->down,
- 0, pScreen->width, 0, -pScreen->height, ref);
- }
- /* we could also try to place it based on those
- relative locations if we wanted to */
- screen->x = screen->y = 0;
- /* FALLTHROUGH */
- case PosAbsolute:
- dixScreenOrigins[i].x = screen->x;
- dixScreenOrigins[i].y = screen->y;
- screensLeft &= ~(1 << i);
- break;
- case PosRelative:
- ref = screen->refscreen->screennum;
- if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
- ErrorF("Referenced uninitialized screen in Layout!\n");
- break;
- }
- if(screensLeft & (1 << ref)) break;
- dixScreenOrigins[i].x = dixScreenOrigins[ref].x + screen->x;
- dixScreenOrigins[i].y = dixScreenOrigins[ref].y + screen->y;
- screensLeft &= ~(1 << i);
- break;
- case PosRightOf:
- ref = screen->refscreen->screennum;
- if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
- ErrorF("Referenced uninitialized screen in Layout!\n");
- break;
- }
- if(screensLeft & (1 << ref)) break;
- pScreen = xf86Screens[ref]->pScreen;
- dixScreenOrigins[i].x =
- dixScreenOrigins[ref].x + pScreen->width;
- dixScreenOrigins[i].y = dixScreenOrigins[ref].y;
- screensLeft &= ~(1 << i);
- break;
- case PosLeftOf:
- ref = screen->refscreen->screennum;
- if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
- ErrorF("Referenced uninitialized screen in Layout!\n");
- break;
- }
- if(screensLeft & (1 << ref)) break;
- pScreen = xf86Screens[i]->pScreen;
- dixScreenOrigins[i].x =
- dixScreenOrigins[ref].x - pScreen->width;
- dixScreenOrigins[i].y = dixScreenOrigins[ref].y;
- screensLeft &= ~(1 << i);
- break;
- case PosBelow:
- ref = screen->refscreen->screennum;
- if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
- ErrorF("Referenced uninitialized screen in Layout!\n");
- break;
- }
- if(screensLeft & (1 << ref)) break;
- pScreen = xf86Screens[ref]->pScreen;
- dixScreenOrigins[i].x = dixScreenOrigins[ref].x;
- dixScreenOrigins[i].y =
- dixScreenOrigins[ref].y + pScreen->height;
- screensLeft &= ~(1 << i);
- break;
- case PosAbove:
- ref = screen->refscreen->screennum;
- if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
- ErrorF("Referenced uninitialized screen in Layout!\n");
- break;
- }
- if(screensLeft & (1 << ref)) break;
- pScreen = xf86Screens[i]->pScreen;
- dixScreenOrigins[i].x = dixScreenOrigins[ref].x;
- dixScreenOrigins[i].y =
- dixScreenOrigins[ref].y - pScreen->height;
- screensLeft &= ~(1 << i);
- break;
- default:
- ErrorF("Illegal placement keyword in Layout!\n");
- break;
- }
-
- }
-
- if(!screensLeft) break;
-
- if(screensLeft == prevScreensLeft) {
- /* All the remaining screens are referencing each other.
- Assign a value to one of them and go through again */
- i = 0;
- while(!((1 << i) & screensLeft)){ i++; }
-
- ref = xf86ConfigLayout.screens[i].refscreen->screennum;
- dixScreenOrigins[ref].x = dixScreenOrigins[ref].y = 0;
- screensLeft &= ~(1 << ref);
- }
-
- prevScreensLeft = screensLeft;
- }
-
- /* justify the topmost and leftmost to (0,0) */
- minX = dixScreenOrigins[0].x;
- minY = dixScreenOrigins[0].y;
-
- for(i = 1; i < xf86NumScreens; i++) {
- if(dixScreenOrigins[i].x < minX)
- minX = dixScreenOrigins[i].x;
- if(dixScreenOrigins[i].y < minY)
- minY = dixScreenOrigins[i].y;
- }
-
- if (minX || minY) {
- for(i = 0; i < xf86NumScreens; i++) {
- dixScreenOrigins[i].x -= minX;
- dixScreenOrigins[i].y -= minY;
- }
- }
-
-
- /* Create the edge lists */
-
- if(!OldStyleConfig) {
- for(i = 0; i < xf86NumScreens; i++) {
- pLayout = &xf86ScreenLayout[i];
-
- pScreen = xf86Screens[i]->pScreen;
-
- left = dixScreenOrigins[i].x;
- right = left + pScreen->width;
- top = dixScreenOrigins[i].y;
- bottom = top + pScreen->height;
-
- for(j = 0; j < xf86NumScreens; j++) {
- if(i == j) continue;
-
- x1 = dixScreenOrigins[j].x;
- x2 = x1 + xf86Screens[j]->pScreen->width;
- y1 = dixScreenOrigins[j].y;
- y2 = y1 + xf86Screens[j]->pScreen->height;
-
- if((bottom > y1) && (top < y2)) {
- min = y1 - top;
- if(min < 0) min = 0;
- max = pScreen->height - (bottom - y2);
- if(max > pScreen->height) max = pScreen->height;
-
- if(((left - 1) >= x1) && ((left - 1) < x2))
- pLayout->left = AddEdge(pLayout->left, min, max,
- dixScreenOrigins[i].x - dixScreenOrigins[j].x,
- dixScreenOrigins[i].y - dixScreenOrigins[j].y, j);
-
- if((right >= x1) && (right < x2))
- pLayout->right = AddEdge(pLayout->right, min, max,
- dixScreenOrigins[i].x - dixScreenOrigins[j].x,
- dixScreenOrigins[i].y - dixScreenOrigins[j].y, j);
- }
-
-
- if((left < x2) && (right > x1)) {
- min = x1 - left;
- if(min < 0) min = 0;
- max = pScreen->width - (right - x2);
- if(max > pScreen->width) max = pScreen->width;
-
- if(((top - 1) >= y1) && ((top - 1) < y2))
- pLayout->up = AddEdge(pLayout->up, min, max,
- dixScreenOrigins[i].x - dixScreenOrigins[j].x,
- dixScreenOrigins[i].y - dixScreenOrigins[j].y, j);
-
- if((bottom >= y1) && (bottom < y2))
- pLayout->down = AddEdge(pLayout->down, min, max,
- dixScreenOrigins[i].x - dixScreenOrigins[j].x,
- dixScreenOrigins[i].y - dixScreenOrigins[j].y, j);
- }
- }
- }
- }
-
- if(!HardEdges && !OldStyleConfig) {
- for(i = 0; i < xf86NumScreens; i++) {
- pLayout = &xf86ScreenLayout[i];
- pScreen = xf86Screens[i]->pScreen;
- if(pLayout->left)
- FillOutEdge(pLayout->left, pScreen->height);
- if(pLayout->right)
- FillOutEdge(pLayout->right, pScreen->height);
- if(pLayout->up)
- FillOutEdge(pLayout->up, pScreen->width);
- if(pLayout->down)
- FillOutEdge(pLayout->down, pScreen->width);
- }
- }
-}
-
-void
-xf86ReconfigureLayout(void)
-{
- int i;
-
- for (i = 0; i < MAXSCREENS; i++) {
- xf86ScreenLayoutPtr sl = &xf86ScreenLayout[i];
- /* we don't have to zero these, xf86InitOrigins() takes care of that */
- if (sl->left) xfree(sl->left);
- if (sl->right) xfree(sl->right);
- if (sl->up) xfree(sl->up);
- if (sl->down) xfree(sl->down);
- }
-
- xf86InitOrigins();
-}
-
-
+/*
+ * Copyright (c) 1994-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xmd.h>
+#include "input.h"
+#include "cursor.h"
+#include "mipointer.h"
+#include "scrnintstr.h"
+#include "globals.h"
+
+#include "compiler.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSproc.h"
+
+#include <X11/extensions/XIproto.h>
+#include "xf86Xinput.h"
+
+#ifdef XFreeXDGA
+#include "dgaproc.h"
+#endif
+
+typedef struct _xf86EdgeRec {
+ short screen;
+ short start;
+ short end;
+ DDXPointRec offset;
+ struct _xf86EdgeRec *next;
+} xf86EdgeRec, *xf86EdgePtr;
+
+typedef struct {
+ xf86EdgePtr left, right, up, down;
+} xf86ScreenLayoutRec, *xf86ScreenLayoutPtr;
+
+static Bool xf86CursorOffScreen(ScreenPtr *pScreen, int *x, int *y);
+static void xf86CrossScreen(ScreenPtr pScreen, Bool entering);
+static void xf86WarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y);
+
+static void xf86PointerMoved(int scrnIndex, int x, int y);
+
+static miPointerScreenFuncRec xf86PointerScreenFuncs = {
+ xf86CursorOffScreen,
+ xf86CrossScreen,
+ xf86WarpCursor,
+ /* let miPointerInitialize take care of these */
+ NULL,
+ NULL
+};
+
+static xf86ScreenLayoutRec xf86ScreenLayout[MAXSCREENS];
+
+static Bool HardEdges;
+
+/*
+ * xf86InitViewport --
+ * Initialize paning & zooming parameters, so that a driver must only
+ * check what resolutions are possible and whether the virtual area
+ * is valid if specified.
+ */
+
+void
+xf86InitViewport(ScrnInfoPtr pScr)
+{
+
+ pScr->PointerMoved = xf86PointerMoved;
+
+ /*
+ * Compute the initial Viewport if necessary
+ */
+ if (pScr->display) {
+ if (pScr->display->frameX0 < 0) {
+ pScr->frameX0 = (pScr->virtualX - pScr->modes->HDisplay) / 2;
+ pScr->frameY0 = (pScr->virtualY - pScr->modes->VDisplay) / 2;
+ } else {
+ pScr->frameX0 = pScr->display->frameX0;
+ pScr->frameY0 = pScr->display->frameY0;
+ }
+ }
+
+ pScr->frameX1 = pScr->frameX0 + pScr->modes->HDisplay - 1;
+ pScr->frameY1 = pScr->frameY0 + pScr->modes->VDisplay - 1;
+
+ /*
+ * Now adjust the initial Viewport, so it lies within the virtual area
+ */
+ if (pScr->frameX1 >= pScr->virtualX)
+ {
+ pScr->frameX0 = pScr->virtualX - pScr->modes->HDisplay;
+ pScr->frameX1 = pScr->frameX0 + pScr->modes->HDisplay - 1;
+ }
+
+ if (pScr->frameY1 >= pScr->virtualY)
+ {
+ pScr->frameY0 = pScr->virtualY - pScr->modes->VDisplay;
+ pScr->frameY1 = pScr->frameY0 + pScr->modes->VDisplay - 1;
+ }
+}
+
+
+/*
+ * xf86SetViewport --
+ * Scroll the visual part of the screen so the pointer is visible.
+ */
+
+void
+xf86SetViewport(ScreenPtr pScreen, int x, int y)
+{
+ ScrnInfoPtr pScr = XF86SCRNINFO(pScreen);
+
+ (*pScr->PointerMoved)(pScreen->myNum, x, y);
+}
+
+
+static void
+xf86PointerMoved(int scrnIndex, int x, int y)
+{
+ Bool frameChanged = FALSE;
+ ScrnInfoPtr pScr = xf86Screens[scrnIndex];
+
+ /*
+ * check wether (x,y) belongs to the visual part of the screen
+ * if not, change the base of the displayed frame accoring
+ */
+ if ( pScr->frameX0 > x) {
+ pScr->frameX0 = x;
+ pScr->frameX1 = x + pScr->currentMode->HDisplay - 1;
+ frameChanged = TRUE ;
+ }
+
+ if ( pScr->frameX1 < x) {
+ pScr->frameX1 = x + 1;
+ pScr->frameX0 = x - pScr->currentMode->HDisplay + 1;
+ frameChanged = TRUE ;
+ }
+
+ if ( pScr->frameY0 > y) {
+ pScr->frameY0 = y;
+ pScr->frameY1 = y + pScr->currentMode->VDisplay - 1;
+ frameChanged = TRUE;
+ }
+
+ if ( pScr->frameY1 < y) {
+ pScr->frameY1 = y;
+ pScr->frameY0 = y - pScr->currentMode->VDisplay + 1;
+ frameChanged = TRUE;
+ }
+
+ if (frameChanged && pScr->AdjustFrame != NULL)
+ pScr->AdjustFrame(pScr->scrnIndex, pScr->frameX0, pScr->frameY0, 0);
+}
+
+/*
+ * xf86LockZoom --
+ * Enable/disable ZoomViewport
+ */
+
+void
+xf86LockZoom(ScreenPtr pScreen, Bool lock)
+{
+ XF86SCRNINFO(pScreen)->zoomLocked = lock;
+}
+
+/*
+ * xf86SwitchMode --
+ * This is called by both keyboard processing and the VidMode extension to
+ * set a new mode.
+ */
+
+Bool
+xf86SwitchMode(ScreenPtr pScreen, DisplayModePtr mode)
+{
+ ScrnInfoPtr pScr = XF86SCRNINFO(pScreen);
+ ScreenPtr pCursorScreen;
+ Bool Switched;
+ int px, py;
+ DeviceIntPtr dev, it;
+
+ if (!pScr->vtSema || !mode || !pScr->SwitchMode)
+ return FALSE;
+
+#ifdef XFreeXDGA
+ if (DGAActive(pScr->scrnIndex))
+ return FALSE;
+#endif
+
+ if (mode == pScr->currentMode)
+ return TRUE;
+
+ if (mode->HDisplay > pScr->virtualX || mode->VDisplay > pScr->virtualY)
+ return FALSE;
+
+ /* Let's take an educated guess for which pointer to take here. And about as
+ educated as it gets is to take the first pointer we find.
+ */
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (IsPointerDevice(dev) && dev->spriteInfo->spriteOwner)
+ break;
+ }
+
+ pCursorScreen = miPointerGetScreen(dev);
+ if (pScreen == pCursorScreen)
+ miPointerGetPosition(dev, &px, &py);
+
+ xf86EnterServerState(SETUP);
+ Switched = (*pScr->SwitchMode)(pScr->scrnIndex, mode, 0);
+ if (Switched) {
+ pScr->currentMode = mode;
+
+ /*
+ * Adjust frame for new display size.
+ * Frame is centered around cursor position if cursor is on same screen.
+ */
+ if (pScreen == pCursorScreen)
+ pScr->frameX0 = px - (mode->HDisplay / 2) + 1;
+ else
+ pScr->frameX0 = (pScr->frameX0 + pScr->frameX1 + 1 - mode->HDisplay) / 2;
+
+ if (pScr->frameX0 < 0)
+ pScr->frameX0 = 0;
+
+ pScr->frameX1 = pScr->frameX0 + mode->HDisplay - 1;
+ if (pScr->frameX1 >= pScr->virtualX) {
+ pScr->frameX0 = pScr->virtualX - mode->HDisplay;
+ pScr->frameX1 = pScr->virtualX - 1;
+ }
+
+ if (pScreen == pCursorScreen)
+ pScr->frameY0 = py - (mode->VDisplay / 2) + 1;
+ else
+ pScr->frameY0 = (pScr->frameY0 + pScr->frameY1 + 1 - mode->VDisplay) / 2;
+
+ if (pScr->frameY0 < 0)
+ pScr->frameY0 = 0;
+
+ pScr->frameY1 = pScr->frameY0 + mode->VDisplay - 1;
+ if (pScr->frameY1 >= pScr->virtualY) {
+ pScr->frameY0 = pScr->virtualY - mode->VDisplay;
+ pScr->frameY1 = pScr->virtualY - 1;
+ }
+ }
+ xf86EnterServerState(OPERATING);
+
+ if (pScr->AdjustFrame)
+ (*pScr->AdjustFrame)(pScr->scrnIndex, pScr->frameX0, pScr->frameY0, 0);
+
+ /* The original code centered the frame around the cursor if possible.
+ * Since this is hard to achieve with multiple cursors, we do the following:
+ * - center around the first pointer
+ * - move all other pointers to the nearest edge on the screen (or leave
+ * them unmodified if they are within the boundaries).
+ */
+ if (pScreen == pCursorScreen)
+ {
+ xf86WarpCursor(dev, pScreen, px, py);
+ }
+
+ for (it = inputInfo.devices; it; it = it->next)
+ {
+ if (it == dev)
+ continue;
+
+ if (IsPointerDevice(it) && it->spriteInfo->spriteOwner)
+ {
+ pCursorScreen = miPointerGetScreen(it);
+ if (pScreen == pCursorScreen)
+ {
+ miPointerGetPosition(it, &px, &py);
+ if (px < pScr->frameX0)
+ px = pScr->frameX0;
+ else if (px > pScr->frameX1)
+ px = pScr->frameX1;
+
+ if(py < pScr->frameY0)
+ py = pScr->frameY0;
+ else if(py > pScr->frameY1)
+ py = pScr->frameY1;
+
+ xf86WarpCursor(it, pScreen, px, py);
+ }
+ }
+ }
+
+ return Switched;
+}
+
+/*
+ * xf86ZoomViewport --
+ * Reinitialize the visual part of the screen for another mode.
+ */
+
+void
+xf86ZoomViewport(ScreenPtr pScreen, int zoom)
+{
+ ScrnInfoPtr pScr = XF86SCRNINFO(pScreen);
+ DisplayModePtr mode;
+
+ if (pScr->zoomLocked || !(mode = pScr->currentMode))
+ return;
+
+ do {
+ if (zoom > 0)
+ mode = mode->next;
+ else
+ mode = mode->prev;
+ } while (mode != pScr->currentMode && !(mode->type & M_T_USERDEF));
+
+ (void)xf86SwitchMode(pScreen, mode);
+}
+
+
+static xf86EdgePtr
+FindEdge(xf86EdgePtr edge, int val)
+{
+ while(edge && (edge->end <= val))
+ edge = edge->next;
+
+ if(edge && (edge->start <= val))
+ return edge;
+
+ return NULL;
+}
+
+/*
+ * xf86CursorOffScreen --
+ * Check whether it is necessary to switch to another screen
+ */
+
+static Bool
+xf86CursorOffScreen(ScreenPtr *pScreen, int *x, int *y)
+{
+ xf86EdgePtr edge;
+ int tmp;
+
+ if(screenInfo.numScreens == 1)
+ return FALSE;
+
+ if(*x < 0) {
+ tmp = *y;
+ if(tmp < 0) tmp = 0;
+ if(tmp >= (*pScreen)->height) tmp = (*pScreen)->height - 1;
+
+ if((edge = xf86ScreenLayout[(*pScreen)->myNum].left))
+ edge = FindEdge(edge, tmp);
+
+ if(!edge) *x = 0;
+ else {
+ *x += edge->offset.x;
+ *y += edge->offset.y;
+ *pScreen = xf86Screens[edge->screen]->pScreen;
+ }
+ }
+
+ if(*x >= (*pScreen)->width) {
+ tmp = *y;
+ if(tmp < 0) tmp = 0;
+ if(tmp >= (*pScreen)->height) tmp = (*pScreen)->height - 1;
+
+ if((edge = xf86ScreenLayout[(*pScreen)->myNum].right))
+ edge = FindEdge(edge, tmp);
+
+ if(!edge) *x = (*pScreen)->width - 1;
+ else {
+ *x += edge->offset.x;
+ *y += edge->offset.y;
+ *pScreen = xf86Screens[edge->screen]->pScreen;
+ }
+ }
+
+ if(*y < 0) {
+ tmp = *x;
+ if(tmp < 0) tmp = 0;
+ if(tmp >= (*pScreen)->width) tmp = (*pScreen)->width - 1;
+
+ if((edge = xf86ScreenLayout[(*pScreen)->myNum].up))
+ edge = FindEdge(edge, tmp);
+
+ if(!edge) *y = 0;
+ else {
+ *x += edge->offset.x;
+ *y += edge->offset.y;
+ *pScreen = xf86Screens[edge->screen]->pScreen;
+ }
+ }
+
+ if(*y >= (*pScreen)->height) {
+ tmp = *x;
+ if(tmp < 0) tmp = 0;
+ if(tmp >= (*pScreen)->width) tmp = (*pScreen)->width - 1;
+
+ if((edge = xf86ScreenLayout[(*pScreen)->myNum].down))
+ edge = FindEdge(edge, tmp);
+
+ if(!edge) *y = (*pScreen)->height - 1;
+ else {
+ *x += edge->offset.x;
+ *y += edge->offset.y;
+ (*pScreen) = xf86Screens[edge->screen]->pScreen;
+ }
+ }
+
+
+#if 0
+ /* This presents problems for overlapping screens when
+ HardEdges is used. Have to think about the logic more */
+ if((*x < 0) || (*x >= (*pScreen)->width) ||
+ (*y < 0) || (*y >= (*pScreen)->height)) {
+ /* We may have crossed more than one screen */
+ xf86CursorOffScreen(pScreen, x, y);
+ }
+#endif
+
+ return TRUE;
+}
+
+
+
+/*
+ * xf86CrossScreen --
+ * Switch to another screen
+ *
+ * Currently nothing special happens, but mi assumes the CrossScreen
+ * method exists.
+ */
+
+static void
+xf86CrossScreen (ScreenPtr pScreen, Bool entering)
+{
+}
+
+
+/*
+ * xf86WarpCursor --
+ * Warp possible to another screen
+ */
+
+/* ARGSUSED */
+static void
+xf86WarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
+{
+ int sigstate;
+ sigstate = xf86BlockSIGIO ();
+ miPointerWarpCursor(pDev, pScreen, x, y);
+
+ xf86Info.currentScreen = pScreen;
+ xf86UnblockSIGIO (sigstate);
+}
+
+
+void *
+xf86GetPointerScreenFuncs(void)
+{
+ return (void *)&xf86PointerScreenFuncs;
+}
+
+
+static xf86EdgePtr
+AddEdge(
+ xf86EdgePtr edge,
+ short min,
+ short max,
+ short dx,
+ short dy,
+ short screen
+){
+ xf86EdgePtr pEdge = edge, pPrev = NULL, pNew;
+
+ while(1) {
+ while(pEdge && (min >= pEdge->end)) {
+ pPrev = pEdge;
+ pEdge = pEdge->next;
+ }
+
+ if(!pEdge) {
+ if(!(pNew = malloc(sizeof(xf86EdgeRec))))
+ break;
+
+ pNew->screen = screen;
+ pNew->start = min;
+ pNew->end = max;
+ pNew->offset.x = dx;
+ pNew->offset.y = dy;
+ pNew->next = NULL;
+
+ if(pPrev)
+ pPrev->next = pNew;
+ else
+ edge = pNew;
+
+ break;
+ } else if (min < pEdge->start) {
+ if(!(pNew = malloc(sizeof(xf86EdgeRec))))
+ break;
+
+ pNew->screen = screen;
+ pNew->start = min;
+ pNew->offset.x = dx;
+ pNew->offset.y = dy;
+ pNew->next = pEdge;
+
+ if(pPrev) pPrev->next = pNew;
+ else edge = pNew;
+
+ if(max <= pEdge->start) {
+ pNew->end = max;
+ break;
+ } else {
+ pNew->end = pEdge->start;
+ min = pEdge->end;
+ }
+ } else
+ min = pEdge->end;
+
+ pPrev = pEdge;
+ pEdge = pEdge->next;
+
+ if(max <= min) break;
+ }
+
+ return edge;
+}
+
+static void
+FillOutEdge(xf86EdgePtr pEdge, int limit)
+{
+ xf86EdgePtr pNext;
+ int diff;
+
+ if(pEdge->start > 0) pEdge->start = 0;
+
+ while((pNext = pEdge->next)) {
+ diff = pNext->start - pEdge->end;
+ if(diff > 0) {
+ pEdge->end += diff >> 1;
+ pNext->start -= diff - (diff >> 1);
+ }
+ pEdge = pNext;
+ }
+
+ if(pEdge->end < limit)
+ pEdge->end = limit;
+}
+
+/*
+ * xf86InitOrigins() can deal with a maximum of 32 screens
+ * on 32 bit architectures, 64 on 64 bit architectures.
+ */
+
+void
+xf86InitOrigins(void)
+{
+ unsigned long screensLeft, prevScreensLeft, mask;
+ screenLayoutPtr screen;
+ ScreenPtr pScreen;
+ int x1, x2, y1, y2, left, right, top, bottom;
+ int i, j, ref, minX, minY, min, max;
+ xf86ScreenLayoutPtr pLayout;
+ Bool OldStyleConfig = FALSE;
+
+ /* need to have this set up with a config file option */
+ HardEdges = FALSE;
+
+ bzero(xf86ScreenLayout, MAXSCREENS * sizeof(xf86ScreenLayoutRec));
+
+ screensLeft = prevScreensLeft = (1 << xf86NumScreens) - 1;
+
+ while(1) {
+ for(mask = screensLeft, i = 0; mask; mask >>= 1, i++) {
+ if(!(mask & 1L)) continue;
+
+ screen = &xf86ConfigLayout.screens[i];
+
+ if (screen->refscreen != NULL &&
+ screen->refscreen->screennum >= xf86NumScreens) {
+ screensLeft &= ~(1 << i);
+ xf86Msg(X_WARNING, "Not including screen \"%s\" in origins calculation.\n",
+ screen->screen->id);
+ continue;
+ }
+
+ switch(screen->where) {
+ case PosObsolete:
+ OldStyleConfig = TRUE;
+ pLayout = &xf86ScreenLayout[i];
+ /* force edge lists */
+ if(screen->left) {
+ ref = screen->left->screennum;
+ if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
+ ErrorF("Referenced uninitialized screen in Layout!\n");
+ break;
+ }
+ pLayout->left = AddEdge(pLayout->left,
+ 0, xf86Screens[i]->pScreen->height,
+ xf86Screens[ref]->pScreen->width, 0, ref);
+ }
+ if(screen->right) {
+ ref = screen->right->screennum;
+ if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
+ ErrorF("Referenced uninitialized screen in Layout!\n");
+ break;
+ }
+ pScreen = xf86Screens[i]->pScreen;
+ pLayout->right = AddEdge(pLayout->right,
+ 0, pScreen->height, -pScreen->width, 0, ref);
+ }
+ if(screen->top) {
+ ref = screen->top->screennum;
+ if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
+ ErrorF("Referenced uninitialized screen in Layout!\n");
+ break;
+ }
+ pLayout->up = AddEdge(pLayout->up,
+ 0, xf86Screens[i]->pScreen->width,
+ 0, xf86Screens[ref]->pScreen->height, ref);
+ }
+ if(screen->bottom) {
+ ref = screen->bottom->screennum;
+ if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
+ ErrorF("Referenced uninitialized screen in Layout!\n");
+ break;
+ }
+ pScreen = xf86Screens[i]->pScreen;
+ pLayout->down = AddEdge(pLayout->down,
+ 0, pScreen->width, 0, -pScreen->height, ref);
+ }
+ /* we could also try to place it based on those
+ relative locations if we wanted to */
+ screen->x = screen->y = 0;
+ /* FALLTHROUGH */
+ case PosAbsolute:
+ dixScreenOrigins[i].x = screen->x;
+ dixScreenOrigins[i].y = screen->y;
+ screensLeft &= ~(1 << i);
+ break;
+ case PosRelative:
+ ref = screen->refscreen->screennum;
+ if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
+ ErrorF("Referenced uninitialized screen in Layout!\n");
+ break;
+ }
+ if(screensLeft & (1 << ref)) break;
+ dixScreenOrigins[i].x = dixScreenOrigins[ref].x + screen->x;
+ dixScreenOrigins[i].y = dixScreenOrigins[ref].y + screen->y;
+ screensLeft &= ~(1 << i);
+ break;
+ case PosRightOf:
+ ref = screen->refscreen->screennum;
+ if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
+ ErrorF("Referenced uninitialized screen in Layout!\n");
+ break;
+ }
+ if(screensLeft & (1 << ref)) break;
+ pScreen = xf86Screens[ref]->pScreen;
+ dixScreenOrigins[i].x =
+ dixScreenOrigins[ref].x + pScreen->width;
+ dixScreenOrigins[i].y = dixScreenOrigins[ref].y;
+ screensLeft &= ~(1 << i);
+ break;
+ case PosLeftOf:
+ ref = screen->refscreen->screennum;
+ if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
+ ErrorF("Referenced uninitialized screen in Layout!\n");
+ break;
+ }
+ if(screensLeft & (1 << ref)) break;
+ pScreen = xf86Screens[i]->pScreen;
+ dixScreenOrigins[i].x =
+ dixScreenOrigins[ref].x - pScreen->width;
+ dixScreenOrigins[i].y = dixScreenOrigins[ref].y;
+ screensLeft &= ~(1 << i);
+ break;
+ case PosBelow:
+ ref = screen->refscreen->screennum;
+ if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
+ ErrorF("Referenced uninitialized screen in Layout!\n");
+ break;
+ }
+ if(screensLeft & (1 << ref)) break;
+ pScreen = xf86Screens[ref]->pScreen;
+ dixScreenOrigins[i].x = dixScreenOrigins[ref].x;
+ dixScreenOrigins[i].y =
+ dixScreenOrigins[ref].y + pScreen->height;
+ screensLeft &= ~(1 << i);
+ break;
+ case PosAbove:
+ ref = screen->refscreen->screennum;
+ if (! xf86Screens[ref] || ! xf86Screens[ref]->pScreen) {
+ ErrorF("Referenced uninitialized screen in Layout!\n");
+ break;
+ }
+ if(screensLeft & (1 << ref)) break;
+ pScreen = xf86Screens[i]->pScreen;
+ dixScreenOrigins[i].x = dixScreenOrigins[ref].x;
+ dixScreenOrigins[i].y =
+ dixScreenOrigins[ref].y - pScreen->height;
+ screensLeft &= ~(1 << i);
+ break;
+ default:
+ ErrorF("Illegal placement keyword in Layout!\n");
+ break;
+ }
+
+ }
+
+ if(!screensLeft) break;
+
+ if(screensLeft == prevScreensLeft) {
+ /* All the remaining screens are referencing each other.
+ Assign a value to one of them and go through again */
+ i = 0;
+ while(!((1 << i) & screensLeft)){ i++; }
+
+ ref = xf86ConfigLayout.screens[i].refscreen->screennum;
+ dixScreenOrigins[ref].x = dixScreenOrigins[ref].y = 0;
+ screensLeft &= ~(1 << ref);
+ }
+
+ prevScreensLeft = screensLeft;
+ }
+
+ /* justify the topmost and leftmost to (0,0) */
+ minX = dixScreenOrigins[0].x;
+ minY = dixScreenOrigins[0].y;
+
+ for(i = 1; i < xf86NumScreens; i++) {
+ if(dixScreenOrigins[i].x < minX)
+ minX = dixScreenOrigins[i].x;
+ if(dixScreenOrigins[i].y < minY)
+ minY = dixScreenOrigins[i].y;
+ }
+
+ if (minX || minY) {
+ for(i = 0; i < xf86NumScreens; i++) {
+ dixScreenOrigins[i].x -= minX;
+ dixScreenOrigins[i].y -= minY;
+ }
+ }
+
+
+ /* Create the edge lists */
+
+ if(!OldStyleConfig) {
+ for(i = 0; i < xf86NumScreens; i++) {
+ pLayout = &xf86ScreenLayout[i];
+
+ pScreen = xf86Screens[i]->pScreen;
+
+ left = dixScreenOrigins[i].x;
+ right = left + pScreen->width;
+ top = dixScreenOrigins[i].y;
+ bottom = top + pScreen->height;
+
+ for(j = 0; j < xf86NumScreens; j++) {
+ if(i == j) continue;
+
+ x1 = dixScreenOrigins[j].x;
+ x2 = x1 + xf86Screens[j]->pScreen->width;
+ y1 = dixScreenOrigins[j].y;
+ y2 = y1 + xf86Screens[j]->pScreen->height;
+
+ if((bottom > y1) && (top < y2)) {
+ min = y1 - top;
+ if(min < 0) min = 0;
+ max = pScreen->height - (bottom - y2);
+ if(max > pScreen->height) max = pScreen->height;
+
+ if(((left - 1) >= x1) && ((left - 1) < x2))
+ pLayout->left = AddEdge(pLayout->left, min, max,
+ dixScreenOrigins[i].x - dixScreenOrigins[j].x,
+ dixScreenOrigins[i].y - dixScreenOrigins[j].y, j);
+
+ if((right >= x1) && (right < x2))
+ pLayout->right = AddEdge(pLayout->right, min, max,
+ dixScreenOrigins[i].x - dixScreenOrigins[j].x,
+ dixScreenOrigins[i].y - dixScreenOrigins[j].y, j);
+ }
+
+
+ if((left < x2) && (right > x1)) {
+ min = x1 - left;
+ if(min < 0) min = 0;
+ max = pScreen->width - (right - x2);
+ if(max > pScreen->width) max = pScreen->width;
+
+ if(((top - 1) >= y1) && ((top - 1) < y2))
+ pLayout->up = AddEdge(pLayout->up, min, max,
+ dixScreenOrigins[i].x - dixScreenOrigins[j].x,
+ dixScreenOrigins[i].y - dixScreenOrigins[j].y, j);
+
+ if((bottom >= y1) && (bottom < y2))
+ pLayout->down = AddEdge(pLayout->down, min, max,
+ dixScreenOrigins[i].x - dixScreenOrigins[j].x,
+ dixScreenOrigins[i].y - dixScreenOrigins[j].y, j);
+ }
+ }
+ }
+ }
+
+ if(!HardEdges && !OldStyleConfig) {
+ for(i = 0; i < xf86NumScreens; i++) {
+ pLayout = &xf86ScreenLayout[i];
+ pScreen = xf86Screens[i]->pScreen;
+ if(pLayout->left)
+ FillOutEdge(pLayout->left, pScreen->height);
+ if(pLayout->right)
+ FillOutEdge(pLayout->right, pScreen->height);
+ if(pLayout->up)
+ FillOutEdge(pLayout->up, pScreen->width);
+ if(pLayout->down)
+ FillOutEdge(pLayout->down, pScreen->width);
+ }
+ }
+}
+
+void
+xf86ReconfigureLayout(void)
+{
+ int i;
+
+ for (i = 0; i < MAXSCREENS; i++) {
+ xf86ScreenLayoutPtr sl = &xf86ScreenLayout[i];
+ /* we don't have to zero these, xf86InitOrigins() takes care of that */
+ if (sl->left) free(sl->left);
+ if (sl->right) free(sl->right);
+ if (sl->up) free(sl->up);
+ if (sl->down) free(sl->down);
+ }
+
+ xf86InitOrigins();
+}
+
+
diff --git a/xorg-server/hw/xfree86/common/xf86DGA.c b/xorg-server/hw/xfree86/common/xf86DGA.c
index 794a13171..ac8302169 100644
--- a/xorg-server/hw/xfree86/common/xf86DGA.c
+++ b/xorg-server/hw/xfree86/common/xf86DGA.c
@@ -1,1227 +1,1227 @@
-/*
- * Copyright (c) 1998-2002 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- *
- * Written by Mark Vojkovich
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "xf86.h"
-#include "xf86str.h"
-#include "xf86Priv.h"
-#include "dgaproc.h"
-#include <X11/extensions/xf86dgaproto.h>
-#include "colormapst.h"
-#include "pixmapstr.h"
-#include "inputstr.h"
-#include "globals.h"
-#include "servermd.h"
-#include "micmap.h"
-#include "xkbsrv.h"
-#include "xf86Xinput.h"
-#include "exglobals.h"
-#include "exevents.h"
-#include "eventstr.h"
-#include "eventconvert.h"
-
-#include "mi.h"
-
-static int DGAScreenKeyIndex;
-static DevPrivateKey DGAScreenKey;
-static int mieq_installed = 0;
-
-static Bool DGACloseScreen(int i, ScreenPtr pScreen);
-static void DGADestroyColormap(ColormapPtr pmap);
-static void DGAInstallColormap(ColormapPtr pmap);
-static void DGAUninstallColormap(ColormapPtr pmap);
-static void DGAHandleEvent(int screen_num, InternalEvent *event,
- DeviceIntPtr device);
-
-static void
-DGACopyModeInfo(
- DGAModePtr mode,
- XDGAModePtr xmode
-);
-
-int *XDGAEventBase = NULL;
-
-#define DGA_GET_SCREEN_PRIV(pScreen) ((DGAScreenPtr) \
- dixLookupPrivate(&(pScreen)->devPrivates, DGAScreenKey))
-
-
-typedef struct _FakedVisualList{
- Bool free;
- VisualPtr pVisual;
- struct _FakedVisualList *next;
-} FakedVisualList;
-
-
-typedef struct {
- ScrnInfoPtr pScrn;
- int numModes;
- DGAModePtr modes;
- CloseScreenProcPtr CloseScreen;
- DestroyColormapProcPtr DestroyColormap;
- InstallColormapProcPtr InstallColormap;
- UninstallColormapProcPtr UninstallColormap;
- DGADevicePtr current;
- DGAFunctionPtr funcs;
- int input;
- ClientPtr client;
- int pixmapMode;
- FakedVisualList *fakedVisuals;
- ColormapPtr dgaColormap;
- ColormapPtr savedColormap;
- Bool grabMouse;
- Bool grabKeyboard;
-} DGAScreenRec, *DGAScreenPtr;
-
-Bool
-DGAInit(
- ScreenPtr pScreen,
- DGAFunctionPtr funcs,
- DGAModePtr modes,
- int num
-){
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- DGAScreenPtr pScreenPriv;
- int i;
-
- if(!funcs || !funcs->SetMode || !funcs->OpenFramebuffer)
- return FALSE;
-
- if(!modes || num <= 0)
- return FALSE;
-
- DGAScreenKey = &DGAScreenKeyIndex;
-
- pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
-
- if (!pScreenPriv)
- {
- if(!(pScreenPriv = (DGAScreenPtr)xalloc(sizeof(DGAScreenRec))))
- return FALSE;
- dixSetPrivate(&pScreen->devPrivates, DGAScreenKey, pScreenPriv);
- pScreenPriv->CloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = DGACloseScreen;
- pScreenPriv->DestroyColormap = pScreen->DestroyColormap;
- pScreen->DestroyColormap = DGADestroyColormap;
- pScreenPriv->InstallColormap = pScreen->InstallColormap;
- pScreen->InstallColormap = DGAInstallColormap;
- pScreenPriv->UninstallColormap = pScreen->UninstallColormap;
- pScreen->UninstallColormap = DGAUninstallColormap;
- }
-
- pScreenPriv->pScrn = pScrn;
- pScreenPriv->numModes = num;
- pScreenPriv->modes = modes;
- pScreenPriv->current = NULL;
-
- pScreenPriv->funcs = funcs;
- pScreenPriv->input = 0;
- pScreenPriv->client = NULL;
- pScreenPriv->fakedVisuals = NULL;
- pScreenPriv->dgaColormap = NULL;
- pScreenPriv->savedColormap = NULL;
- pScreenPriv->grabMouse = FALSE;
- pScreenPriv->grabKeyboard = FALSE;
-
- for(i = 0; i < num; i++)
- modes[i].num = i + 1;
-
-#ifdef PANORAMIX
- if(!noPanoramiXExtension)
- for(i = 0; i < num; i++)
- modes[i].flags &= ~DGA_PIXMAP_AVAILABLE;
-#endif
-
- return TRUE;
-}
-
-/* DGAReInitModes allows the driver to re-initialize
- * the DGA mode list.
- */
-
-Bool
-DGAReInitModes(
- ScreenPtr pScreen,
- DGAModePtr modes,
- int num
-){
- DGAScreenPtr pScreenPriv;
- int i;
-
- /* No DGA? Ignore call (but don't make it look like it failed) */
- if(DGAScreenKey == NULL)
- return TRUE;
-
- pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
-
- /* Same as above */
- if(!pScreenPriv)
- return TRUE;
-
- /* Can't do this while DGA is active */
- if(pScreenPriv->current)
- return FALSE;
-
- /* Quick sanity check */
- if(!num)
- modes = NULL;
- else if(!modes)
- num = 0;
-
- pScreenPriv->numModes = num;
- pScreenPriv->modes = modes;
-
- /* This practically disables DGA. So be it. */
- if(!num)
- return TRUE;
-
- for(i = 0; i < num; i++)
- modes[i].num = i + 1;
-
-#ifdef PANORAMIX
- if(!noPanoramiXExtension)
- for(i = 0; i < num; i++)
- modes[i].flags &= ~DGA_PIXMAP_AVAILABLE;
-#endif
-
- return TRUE;
-}
-
-static void
-FreeMarkedVisuals(ScreenPtr pScreen)
-{
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
- FakedVisualList *prev, *curr, *tmp;
-
- if(!pScreenPriv->fakedVisuals)
- return;
-
- prev = NULL;
- curr = pScreenPriv->fakedVisuals;
-
- while(curr) {
- if(curr->free) {
- tmp = curr;
- curr = curr->next;
- if(prev)
- prev->next = curr;
- else
- pScreenPriv->fakedVisuals = curr;
- xfree(tmp->pVisual);
- xfree(tmp);
- } else {
- prev = curr;
- curr = curr->next;
- }
- }
-}
-
-static Bool
-DGACloseScreen(int i, ScreenPtr pScreen)
-{
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
-
- if (XDGAEventBase) {
- mieqSetHandler(ET_DGAEvent, NULL);
- }
-
- FreeMarkedVisuals(pScreen);
-
- pScreen->CloseScreen = pScreenPriv->CloseScreen;
- pScreen->DestroyColormap = pScreenPriv->DestroyColormap;
- pScreen->InstallColormap = pScreenPriv->InstallColormap;
- pScreen->UninstallColormap = pScreenPriv->UninstallColormap;
-
- /* DGAShutdown() should have ensured that no DGA
- screen were active by here */
-
- xfree(pScreenPriv);
-
- return((*pScreen->CloseScreen)(i, pScreen));
-}
-
-
-static void
-DGADestroyColormap(ColormapPtr pmap)
-{
- ScreenPtr pScreen = pmap->pScreen;
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
- VisualPtr pVisual = pmap->pVisual;
-
- if(pScreenPriv->fakedVisuals) {
- FakedVisualList *curr = pScreenPriv->fakedVisuals;
-
- while(curr) {
- if(curr->pVisual == pVisual) {
- /* We can't get rid of them yet since FreeColormap
- still needs the pVisual during the cleanup */
- curr->free = TRUE;
- break;
- }
- curr = curr->next;
- }
- }
-
- if(pScreenPriv->DestroyColormap) {
- pScreen->DestroyColormap = pScreenPriv->DestroyColormap;
- (*pScreen->DestroyColormap)(pmap);
- pScreen->DestroyColormap = DGADestroyColormap;
- }
-}
-
-
-static void
-DGAInstallColormap(ColormapPtr pmap)
-{
- ScreenPtr pScreen = pmap->pScreen;
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
-
- if(pScreenPriv->current && pScreenPriv->dgaColormap) {
- if (pmap != pScreenPriv->dgaColormap) {
- pScreenPriv->savedColormap = pmap;
- pmap = pScreenPriv->dgaColormap;
- }
- }
-
- pScreen->InstallColormap = pScreenPriv->InstallColormap;
- (*pScreen->InstallColormap)(pmap);
- pScreen->InstallColormap = DGAInstallColormap;
-}
-
-static void
-DGAUninstallColormap(ColormapPtr pmap)
-{
- ScreenPtr pScreen = pmap->pScreen;
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
-
- if(pScreenPriv->current && pScreenPriv->dgaColormap) {
- if (pmap == pScreenPriv->dgaColormap) {
- pScreenPriv->dgaColormap = NULL;
- }
- }
-
- pScreen->UninstallColormap = pScreenPriv->UninstallColormap;
- (*pScreen->UninstallColormap)(pmap);
- pScreen->UninstallColormap = DGAUninstallColormap;
-}
-
-int
-xf86SetDGAMode(
- int index,
- int num,
- DGADevicePtr devRet
-){
- ScreenPtr pScreen = screenInfo.screens[index];
- DGAScreenPtr pScreenPriv;
- ScrnInfoPtr pScrn;
- DGADevicePtr device;
- PixmapPtr pPix = NULL;
- DGAModePtr pMode = NULL;
-
- /* First check if DGAInit was successful on this screen */
- if (DGAScreenKey == NULL)
- return BadValue;
- pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
- if (!pScreenPriv)
- return BadValue;
- pScrn = pScreenPriv->pScrn;
-
- if(!num) {
- if(pScreenPriv->current) {
- PixmapPtr oldPix = pScreenPriv->current->pPix;
- if(oldPix) {
- if(oldPix->drawable.id)
- FreeResource(oldPix->drawable.id, RT_NONE);
- else
- (*pScreen->DestroyPixmap)(oldPix);
- }
- xfree(pScreenPriv->current);
- pScreenPriv->current = NULL;
- pScrn->vtSema = TRUE;
- (*pScreenPriv->funcs->SetMode)(pScrn, NULL);
- if(pScreenPriv->savedColormap) {
- (*pScreen->InstallColormap)(pScreenPriv->savedColormap);
- pScreenPriv->savedColormap = NULL;
- }
- pScreenPriv->dgaColormap = NULL;
- (*pScrn->EnableDisableFBAccess)(index, TRUE);
-
- FreeMarkedVisuals(pScreen);
- }
-
- pScreenPriv->grabMouse = FALSE;
- pScreenPriv->grabKeyboard = FALSE;
-
- return Success;
- }
-
- if(!pScrn->vtSema && !pScreenPriv->current) /* Really switched away */
- return BadAlloc;
-
- if((num > 0) && (num <= pScreenPriv->numModes))
- pMode = &(pScreenPriv->modes[num - 1]);
- else
- return BadValue;
-
- if(!(device = (DGADevicePtr)xalloc(sizeof(DGADeviceRec))))
- return BadAlloc;
-
- if(!pScreenPriv->current) {
- Bool oldVTSema = pScrn->vtSema;
-
- pScrn->vtSema = FALSE; /* kludge until we rewrite VT switching */
- (*pScrn->EnableDisableFBAccess)(index, FALSE);
- pScrn->vtSema = oldVTSema;
- }
-
- if(!(*pScreenPriv->funcs->SetMode)(pScrn, pMode)) {
- xfree(device);
- return BadAlloc;
- }
-
- pScrn->currentMode = pMode->mode;
-
- if(!pScreenPriv->current && !pScreenPriv->input) {
- /* if it's multihead we need to warp the cursor off of
- our screen so it doesn't get trapped */
- }
-
- pScrn->vtSema = FALSE;
-
- if(pScreenPriv->current) {
- PixmapPtr oldPix = pScreenPriv->current->pPix;
- if(oldPix) {
- if(oldPix->drawable.id)
- FreeResource(oldPix->drawable.id, RT_NONE);
- else
- (*pScreen->DestroyPixmap)(oldPix);
- }
- xfree(pScreenPriv->current);
- pScreenPriv->current = NULL;
- }
-
- if(pMode->flags & DGA_PIXMAP_AVAILABLE) {
- if((pPix = (*pScreen->CreatePixmap)(pScreen, 0, 0, pMode->depth, 0))) {
- (*pScreen->ModifyPixmapHeader)(pPix,
- pMode->pixmapWidth, pMode->pixmapHeight,
- pMode->depth, pMode->bitsPerPixel,
- pMode->bytesPerScanline,
- (pointer)(pMode->address));
- }
- }
-
- devRet->mode = device->mode = pMode;
- devRet->pPix = device->pPix = pPix;
- pScreenPriv->current = device;
- pScreenPriv->pixmapMode = FALSE;
- pScreenPriv->grabMouse = TRUE;
- pScreenPriv->grabKeyboard = TRUE;
-
- return Success;
-}
-
-
-
-/*********** exported ones ***************/
-
-void
-DGASetInputMode(int index, Bool keyboard, Bool mouse)
-{
- ScreenPtr pScreen = screenInfo.screens[index];
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
-
- if (pScreenPriv)
- {
- pScreenPriv->grabMouse = mouse;
- pScreenPriv->grabKeyboard = keyboard;
-
- if (!mieq_installed) {
- mieqSetHandler(ET_DGAEvent, DGAHandleEvent);
- mieq_installed = 1;
- }
- }
-}
-
-Bool
-DGAChangePixmapMode(int index, int *x, int *y, int mode)
-{
- DGAScreenPtr pScreenPriv;
- DGADevicePtr pDev;
- DGAModePtr pMode;
- PixmapPtr pPix;
-
- if(DGAScreenKey == NULL)
- return FALSE;
-
- pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
-
- if(!pScreenPriv || !pScreenPriv->current || !pScreenPriv->current->pPix)
- return FALSE;
-
- pDev = pScreenPriv->current;
- pPix = pDev->pPix;
- pMode = pDev->mode;
-
- if(mode) {
- int shift = 2;
-
- if(*x > (pMode->pixmapWidth - pMode->viewportWidth))
- *x = pMode->pixmapWidth - pMode->viewportWidth;
- if(*y > (pMode->pixmapHeight - pMode->viewportHeight))
- *y = pMode->pixmapHeight - pMode->viewportHeight;
-
- switch(xf86Screens[index]->bitsPerPixel) {
- case 16: shift = 1; break;
- case 32: shift = 0; break;
- default: break;
- }
-
- if(BITMAP_SCANLINE_PAD == 64)
- shift++;
-
- *x = (*x >> shift) << shift;
-
- pPix->drawable.x = *x;
- pPix->drawable.y = *y;
- pPix->drawable.width = pMode->viewportWidth;
- pPix->drawable.height = pMode->viewportHeight;
- } else {
- pPix->drawable.x = 0;
- pPix->drawable.y = 0;
- pPix->drawable.width = pMode->pixmapWidth;
- pPix->drawable.height = pMode->pixmapHeight;
- }
- pPix->drawable.serialNumber = NEXT_SERIAL_NUMBER;
- pScreenPriv->pixmapMode = mode;
-
- return TRUE;
-}
-
-Bool
-DGAAvailable(int index)
-{
- if(DGAScreenKey == NULL)
- return FALSE;
-
- if(DGA_GET_SCREEN_PRIV(screenInfo.screens[index]))
- return TRUE;
-
- return FALSE;
-}
-
-Bool
-DGAActive(int index)
-{
- DGAScreenPtr pScreenPriv;
-
- if(DGAScreenKey == NULL)
- return FALSE;
-
- pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
-
- if(pScreenPriv && pScreenPriv->current)
- return TRUE;
-
- return FALSE;
-}
-
-
-
-/* Called by the event code in case the server is abruptly terminated */
-
-void
-DGAShutdown(void)
-{
- ScrnInfoPtr pScrn;
- int i;
-
- if(DGAScreenKey == NULL)
- return;
-
- for(i = 0; i < screenInfo.numScreens; i++) {
- pScrn = xf86Screens[i];
-
- (void)(*pScrn->SetDGAMode)(pScrn->scrnIndex, 0, NULL);
- }
-}
-
-/* Called by the extension to initialize a mode */
-
-int
-DGASetMode(
- int index,
- int num,
- XDGAModePtr mode,
- PixmapPtr *pPix
-){
- ScrnInfoPtr pScrn = xf86Screens[index];
- DGADeviceRec device;
- int ret;
-
- /* We rely on the extension to check that DGA is available */
-
- ret = (*pScrn->SetDGAMode)(index, num, &device);
- if((ret == Success) && num) {
- DGACopyModeInfo(device.mode, mode);
- *pPix = device.pPix;
- }
-
- return ret;
-}
-
-/* Called from the extension to let the DDX know which events are requested */
-
-void
-DGASelectInput(
- int index,
- ClientPtr client,
- long mask
-){
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
-
- /* We rely on the extension to check that DGA is available */
- pScreenPriv->client = client;
- pScreenPriv->input = mask;
-}
-
-int
-DGAGetViewportStatus(int index)
-{
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
-
- /* We rely on the extension to check that DGA is active */
-
- if (!pScreenPriv->funcs->GetViewport)
- return 0;
-
- return (*pScreenPriv->funcs->GetViewport)(pScreenPriv->pScrn);
-}
-
-int
-DGASetViewport(
- int index,
- int x, int y,
- int mode
-){
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
-
- if (pScreenPriv->funcs->SetViewport)
- (*pScreenPriv->funcs->SetViewport)(pScreenPriv->pScrn, x, y, mode);
- return Success;
-}
-
-
-static int
-BitsClear(CARD32 data)
-{
- int bits = 0;
- CARD32 mask;
-
- for(mask = 1; mask; mask <<= 1) {
- if(!(data & mask)) bits++;
- else break;
- }
-
- return bits;
-}
-
-int
-DGACreateColormap(int index, ClientPtr client, int id, int mode, int alloc)
-{
- ScreenPtr pScreen = screenInfo.screens[index];
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
- FakedVisualList *fvlp;
- VisualPtr pVisual;
- DGAModePtr pMode;
- ColormapPtr pmap;
-
- if(!mode || (mode > pScreenPriv->numModes))
- return BadValue;
-
- if((alloc != AllocNone) && (alloc != AllocAll))
- return BadValue;
-
- pMode = &(pScreenPriv->modes[mode - 1]);
-
- if(!(pVisual = xalloc(sizeof(VisualRec))))
- return BadAlloc;
-
- pVisual->vid = FakeClientID(0);
- pVisual->class = pMode->visualClass;
- pVisual->nplanes = pMode->depth;
- pVisual->ColormapEntries = 1 << pMode->depth;
- pVisual->bitsPerRGBValue = (pMode->depth + 2) / 3;
-
- switch (pVisual->class) {
- case PseudoColor:
- case GrayScale:
- case StaticGray:
- pVisual->bitsPerRGBValue = 8; /* not quite */
- pVisual->redMask = 0;
- pVisual->greenMask = 0;
- pVisual->blueMask = 0;
- pVisual->offsetRed = 0;
- pVisual->offsetGreen = 0;
- pVisual->offsetBlue = 0;
- break;
- case DirectColor:
- case TrueColor:
- pVisual->ColormapEntries = 1 << pVisual->bitsPerRGBValue;
- /* fall through */
- case StaticColor:
- pVisual->redMask = pMode->red_mask;
- pVisual->greenMask = pMode->green_mask;
- pVisual->blueMask = pMode->blue_mask;
- pVisual->offsetRed = BitsClear(pVisual->redMask);
- pVisual->offsetGreen = BitsClear(pVisual->greenMask);
- pVisual->offsetBlue = BitsClear(pVisual->blueMask);
- }
-
- if(!(fvlp = xalloc(sizeof(FakedVisualList)))) {
- xfree(pVisual);
- return BadAlloc;
- }
-
- fvlp->free = FALSE;
- fvlp->pVisual = pVisual;
- fvlp->next = pScreenPriv->fakedVisuals;
- pScreenPriv->fakedVisuals = fvlp;
-
- LEGAL_NEW_RESOURCE(id, client);
-
- return CreateColormap(id, pScreen, pVisual, &pmap, alloc, client->index);
-}
-
-/* Called by the extension to install a colormap on DGA active screens */
-
-void
-DGAInstallCmap(ColormapPtr cmap)
-{
- ScreenPtr pScreen = cmap->pScreen;
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
-
- /* We rely on the extension to check that DGA is active */
-
- if(!pScreenPriv->dgaColormap)
- pScreenPriv->savedColormap = GetInstalledmiColormap(pScreen);
-
- pScreenPriv->dgaColormap = cmap;
-
- (*pScreen->InstallColormap)(cmap);
-}
-
-int
-DGASync(int index)
-{
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
-
- /* We rely on the extension to check that DGA is active */
-
- if (pScreenPriv->funcs->Sync)
- (*pScreenPriv->funcs->Sync)(pScreenPriv->pScrn);
-
- return Success;
-}
-
-int
-DGAFillRect(
- int index,
- int x, int y, int w, int h,
- unsigned long color
-){
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
-
- /* We rely on the extension to check that DGA is active */
-
- if(pScreenPriv->funcs->FillRect &&
- (pScreenPriv->current->mode->flags & DGA_FILL_RECT)) {
-
- (*pScreenPriv->funcs->FillRect)(pScreenPriv->pScrn, x, y, w, h, color);
- return Success;
- }
- return BadMatch;
-}
-
-int
-DGABlitRect(
- int index,
- int srcx, int srcy,
- int w, int h,
- int dstx, int dsty
-){
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
-
- /* We rely on the extension to check that DGA is active */
-
- if(pScreenPriv->funcs->BlitRect &&
- (pScreenPriv->current->mode->flags & DGA_BLIT_RECT)) {
-
- (*pScreenPriv->funcs->BlitRect)(pScreenPriv->pScrn,
- srcx, srcy, w, h, dstx, dsty);
- return Success;
- }
- return BadMatch;
-}
-
-int
-DGABlitTransRect(
- int index,
- int srcx, int srcy,
- int w, int h,
- int dstx, int dsty,
- unsigned long color
-){
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
-
- /* We rely on the extension to check that DGA is active */
-
- if(pScreenPriv->funcs->BlitTransRect &&
- (pScreenPriv->current->mode->flags & DGA_BLIT_RECT_TRANS)) {
-
- (*pScreenPriv->funcs->BlitTransRect)(pScreenPriv->pScrn,
- srcx, srcy, w, h, dstx, dsty, color);
- return Success;
- }
- return BadMatch;
-}
-
-
-int
-DGAGetModes(int index)
-{
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
- /* We rely on the extension to check that DGA is available */
-
- return pScreenPriv->numModes;
-}
-
-
-int
-DGAGetModeInfo(
- int index,
- XDGAModePtr mode,
- int num
-){
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
- /* We rely on the extension to check that DGA is available */
-
- if((num <= 0) || (num > pScreenPriv->numModes))
- return BadValue;
-
- DGACopyModeInfo(&(pScreenPriv->modes[num - 1]), mode);
-
- return Success;
-}
-
-
-static void
-DGACopyModeInfo(
- DGAModePtr mode,
- XDGAModePtr xmode
-){
- DisplayModePtr dmode = mode->mode;
-
- xmode->num = mode->num;
- xmode->name = dmode->name;
- xmode->VSync_num = (int)(dmode->VRefresh * 1000.0);
- xmode->VSync_den = 1000;
- xmode->flags = mode->flags;
- xmode->imageWidth = mode->imageWidth;
- xmode->imageHeight = mode->imageHeight;
- xmode->pixmapWidth = mode->pixmapWidth;
- xmode->pixmapHeight = mode->pixmapHeight;
- xmode->bytesPerScanline = mode->bytesPerScanline;
- xmode->byteOrder = mode->byteOrder;
- xmode->depth = mode->depth;
- xmode->bitsPerPixel = mode->bitsPerPixel;
- xmode->red_mask = mode->red_mask;
- xmode->green_mask = mode->green_mask;
- xmode->blue_mask = mode->blue_mask;
- xmode->visualClass = mode->visualClass;
- xmode->viewportWidth = mode->viewportWidth;
- xmode->viewportHeight = mode->viewportHeight;
- xmode->xViewportStep = mode->xViewportStep;
- xmode->yViewportStep = mode->yViewportStep;
- xmode->maxViewportX = mode->maxViewportX;
- xmode->maxViewportY = mode->maxViewportY;
- xmode->viewportFlags = mode->viewportFlags;
- xmode->reserved1 = mode->reserved1;
- xmode->reserved2 = mode->reserved2;
- xmode->offset = mode->offset;
-
- if(dmode->Flags & V_INTERLACE) xmode->flags |= DGA_INTERLACED;
- if(dmode->Flags & V_DBLSCAN) xmode->flags |= DGA_DOUBLESCAN;
-}
-
-
-Bool
-DGAVTSwitch(void)
-{
- ScreenPtr pScreen;
- int i;
-
- for(i = 0; i < screenInfo.numScreens; i++) {
- pScreen = screenInfo.screens[i];
-
- /* Alternatively, this could send events to DGA clients */
-
- if(DGAScreenKey) {
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
-
- if(pScreenPriv && pScreenPriv->current)
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-Bool
-DGAStealKeyEvent(DeviceIntPtr dev, int index, int key_code, int is_down)
-{
- DGAScreenPtr pScreenPriv;
- DGAEvent event;
-
- if(DGAScreenKey == NULL) /* no DGA */
- return FALSE;
-
- if (key_code < 8 || key_code > 255)
- return FALSE;
-
- pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
-
- if(!pScreenPriv || !pScreenPriv->grabKeyboard) /* no direct mode */
- return FALSE;
-
- memset(&event, 0, sizeof(event));
- event.header = ET_Internal;
- event.type = ET_DGAEvent;
- event.length = sizeof(event);
- event.time = GetTimeInMillis();
- event.subtype = (is_down ? ET_KeyPress : ET_KeyRelease);
- event.detail = key_code;
- event.dx = 0;
- event.dy = 0;
- mieqEnqueue (dev, (InternalEvent*)&event);
-
- return TRUE;
-}
-
-static int DGAMouseX, DGAMouseY;
-
-Bool
-DGAStealMotionEvent(DeviceIntPtr dev, int index, int dx, int dy)
-{
- DGAScreenPtr pScreenPriv;
- DGAEvent event;
-
- if(DGAScreenKey == NULL) /* no DGA */
- return FALSE;
-
- pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
-
- if(!pScreenPriv || !pScreenPriv->grabMouse) /* no direct mode */
- return FALSE;
-
- DGAMouseX += dx;
- if (DGAMouseX < 0)
- DGAMouseX = 0;
- else if (DGAMouseX > screenInfo.screens[index]->width)
- DGAMouseX = screenInfo.screens[index]->width;
- DGAMouseY += dy;
- if (DGAMouseY < 0)
- DGAMouseY = 0;
- else if (DGAMouseY > screenInfo.screens[index]->height)
- DGAMouseY = screenInfo.screens[index]->height;
-
- memset(&event, 0, sizeof(event));
- event.header = ET_Internal;
- event.type = ET_DGAEvent;
- event.length = sizeof(event);
- event.time = GetTimeInMillis();
- event.subtype = ET_Motion;
- event.detail = 0;
- event.dx = dx;
- event.dy = dy;
- mieqEnqueue (dev, (InternalEvent*)&event);
- return TRUE;
-}
-
-Bool
-DGAStealButtonEvent(DeviceIntPtr dev, int index, int button, int is_down)
-{
- DGAScreenPtr pScreenPriv;
- DGAEvent event;
-
- if (DGAScreenKey == NULL)
- return FALSE;
-
- pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
-
- if (!pScreenPriv || !pScreenPriv->grabMouse)
- return FALSE;
-
- memset(&event, 0, sizeof(event));
- event.header = ET_Internal;
- event.type = ET_DGAEvent;
- event.length = sizeof(event);
- event.time = GetTimeInMillis();
- event.subtype = (is_down ? ET_ButtonPress : ET_ButtonRelease);
- event.detail = button;
- event.dx = 0;
- event.dy = 0;
- mieqEnqueue (dev, (InternalEvent*)&event);
-
- return TRUE;
-}
-
-/* We have the power to steal or modify events that are about to get queued */
-
-Bool
-DGAIsDgaEvent (xEvent *e)
-{
- int coreEquiv;
- if (DGAScreenKey == NULL || XDGAEventBase == 0)
- return FALSE;
- coreEquiv = e->u.u.type - *XDGAEventBase;
- if (KeyPress <= coreEquiv && coreEquiv <= MotionNotify)
- return TRUE;
- return FALSE;
-}
-
-#define NoSuchEvent 0x80000000 /* so doesn't match NoEventMask */
-static Mask filters[] =
-{
- NoSuchEvent, /* 0 */
- NoSuchEvent, /* 1 */
- KeyPressMask, /* KeyPress */
- KeyReleaseMask, /* KeyRelease */
- ButtonPressMask, /* ButtonPress */
- ButtonReleaseMask, /* ButtonRelease */
- PointerMotionMask, /* MotionNotify (initial state) */
-};
-
-static void
-DGAProcessKeyboardEvent (ScreenPtr pScreen, DGAEvent *event, DeviceIntPtr keybd)
-{
- KeyClassPtr keyc = keybd->key;
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
- DeviceIntPtr pointer = GetPairedDevice(keybd);
- DeviceEvent ev;
-
- memset(&ev, 0, sizeof(ev));
- ev.length = sizeof(ev);
- ev.detail.key = event->detail;
- ev.type = event->subtype;
- ev.root_x = 0;
- ev.root_y = 0;
- ev.corestate = XkbStateFieldFromRec(&keyc->xkbInfo->state);
- ev.corestate |= pointer->button->state;
-
- UpdateDeviceState(keybd, &ev);
-
- /*
- * Deliver the DGA event
- */
- if (pScreenPriv->client)
- {
- dgaEvent de;
- de.u.u.type = *XDGAEventBase + GetCoreType((InternalEvent*)&ev);
- de.u.u.detail = event->detail;
- de.u.event.time = event->time;
- de.u.event.dx = 0;
- de.u.event.dy = 0;
- de.u.event.screen = pScreen->myNum;
- de.u.event.state = ev.corestate;
-
- /* If the DGA client has selected input, then deliver based on the usual filter */
- TryClientEvents (pScreenPriv->client, keybd, (xEvent *)&de, 1,
- filters[ev.type], pScreenPriv->input, 0);
- }
- else
- {
- /* If the keyboard is actively grabbed, deliver a grabbed core event */
- if (keybd->deviceGrab.grab && !keybd->deviceGrab.fromPassiveGrab)
- {
- ev.detail.key = event->detail;
- ev.time = event->time;
- ev.root_x = event->dx;
- ev.root_y = event->dy;
- ev.corestate = event->state;
- ev.deviceid = keybd->id;
- DeliverGrabbedEvent ((InternalEvent*)&ev, keybd, FALSE);
- }
- }
-}
-
-static void
-DGAProcessPointerEvent (ScreenPtr pScreen, DGAEvent *event, DeviceIntPtr mouse)
-{
- ButtonClassPtr butc = mouse->button;
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
- DeviceEvent ev;
- DeviceIntPtr master = GetMaster(mouse, MASTER_KEYBOARD);
-
- memset(&ev, 0, sizeof(ev));
- ev.header = ET_Internal;
- ev.length = sizeof(ev);
- ev.type = event->subtype;
- ev.corestate = butc->state;
- if (master && master->key)
- ev.corestate |= XkbStateFieldFromRec(&master->key->xkbInfo->state);
-
- UpdateDeviceState(mouse, &ev);
-
- /*
- * Deliver the DGA event
- */
- if (pScreenPriv->client)
- {
- dgaEvent de;
- int coreEquiv;
-
- coreEquiv = GetCoreType((InternalEvent*)&ev);
-
- de.u.u.type = *XDGAEventBase + coreEquiv;
- de.u.u.detail = event->detail;
- de.u.event.time = event->time;
- de.u.event.dx = 0;
- de.u.event.dy = 0;
- de.u.event.screen = pScreen->myNum;
- de.u.event.state = ev.corestate;
-
- /* If the DGA client has selected input, then deliver based on the usual filter */
- TryClientEvents (pScreenPriv->client, mouse, (xEvent *)&de, 1,
- filters[coreEquiv], pScreenPriv->input, 0);
- }
- else
- {
- /* If the pointer is actively grabbed, deliver a grabbed core event */
- if (mouse->deviceGrab.grab && !mouse->deviceGrab.fromPassiveGrab)
- {
- ev.detail.button = event->detail;
- ev.time = event->time;
- ev.root_x = event->dx;
- ev.root_y = event->dy;
- ev.corestate = event->state;
- DeliverGrabbedEvent ((InternalEvent*)&ev, mouse, FALSE);
- }
- }
-}
-
-Bool
-DGAOpenFramebuffer(
- int index,
- char **name,
- unsigned char **mem,
- int *size,
- int *offset,
- int *flags
-){
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
-
- /* We rely on the extension to check that DGA is available */
-
- return (*pScreenPriv->funcs->OpenFramebuffer)(pScreenPriv->pScrn,
- name, mem, size, offset, flags);
-}
-
-void
-DGACloseFramebuffer(int index)
-{
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
-
- /* We rely on the extension to check that DGA is available */
- if(pScreenPriv->funcs->CloseFramebuffer)
- (*pScreenPriv->funcs->CloseFramebuffer)(pScreenPriv->pScrn);
-}
-
-/* For DGA 1.0 backwards compatibility only */
-
-int
-DGAGetOldDGAMode(int index)
-{
- DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
- ScrnInfoPtr pScrn = pScreenPriv->pScrn;
- DGAModePtr mode;
- int i, w, h, p;
-
- /* We rely on the extension to check that DGA is available */
-
- w = pScrn->currentMode->HDisplay;
- h = pScrn->currentMode->VDisplay;
- p = pad_to_int32(pScrn->displayWidth * bits_to_bytes(pScrn->bitsPerPixel));
-
- for(i = 0; i < pScreenPriv->numModes; i++) {
- mode = &(pScreenPriv->modes[i]);
-
- if((mode->viewportWidth == w) && (mode->viewportHeight == h) &&
- (mode->bytesPerScanline == p) &&
- (mode->bitsPerPixel == pScrn->bitsPerPixel) &&
- (mode->depth == pScrn->depth)) {
-
- return mode->num;
- }
- }
-
- return 0;
-}
-
-static void
-DGAHandleEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
-{
- DGAEvent *event= &ev->dga_event;
- ScreenPtr pScreen = screenInfo.screens[screen_num];
- DGAScreenPtr pScreenPriv;
-
- /* no DGA */
- if (DGAScreenKey == NULL || XDGAEventBase == 0)
- return;
- pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
-
- /* DGA not initialized on this screen */
- if (!pScreenPriv)
- return;
-
- switch (event->subtype) {
- case KeyPress:
- case KeyRelease:
- DGAProcessKeyboardEvent (pScreen, event, device);
- break;
- case MotionNotify:
- case ButtonPress:
- case ButtonRelease:
- DGAProcessPointerEvent (pScreen, event, device);
- break;
- default:
- break;
- }
-}
+/*
+ * Copyright (c) 1998-2002 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ *
+ * Written by Mark Vojkovich
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "xf86.h"
+#include "xf86str.h"
+#include "xf86Priv.h"
+#include "dgaproc.h"
+#include <X11/extensions/xf86dgaproto.h>
+#include "colormapst.h"
+#include "pixmapstr.h"
+#include "inputstr.h"
+#include "globals.h"
+#include "servermd.h"
+#include "micmap.h"
+#include "xkbsrv.h"
+#include "xf86Xinput.h"
+#include "exglobals.h"
+#include "exevents.h"
+#include "eventstr.h"
+#include "eventconvert.h"
+
+#include "mi.h"
+
+static int DGAScreenKeyIndex;
+static DevPrivateKey DGAScreenKey;
+static int mieq_installed = 0;
+
+static Bool DGACloseScreen(int i, ScreenPtr pScreen);
+static void DGADestroyColormap(ColormapPtr pmap);
+static void DGAInstallColormap(ColormapPtr pmap);
+static void DGAUninstallColormap(ColormapPtr pmap);
+static void DGAHandleEvent(int screen_num, InternalEvent *event,
+ DeviceIntPtr device);
+
+static void
+DGACopyModeInfo(
+ DGAModePtr mode,
+ XDGAModePtr xmode
+);
+
+int *XDGAEventBase = NULL;
+
+#define DGA_GET_SCREEN_PRIV(pScreen) ((DGAScreenPtr) \
+ dixLookupPrivate(&(pScreen)->devPrivates, DGAScreenKey))
+
+
+typedef struct _FakedVisualList{
+ Bool free;
+ VisualPtr pVisual;
+ struct _FakedVisualList *next;
+} FakedVisualList;
+
+
+typedef struct {
+ ScrnInfoPtr pScrn;
+ int numModes;
+ DGAModePtr modes;
+ CloseScreenProcPtr CloseScreen;
+ DestroyColormapProcPtr DestroyColormap;
+ InstallColormapProcPtr InstallColormap;
+ UninstallColormapProcPtr UninstallColormap;
+ DGADevicePtr current;
+ DGAFunctionPtr funcs;
+ int input;
+ ClientPtr client;
+ int pixmapMode;
+ FakedVisualList *fakedVisuals;
+ ColormapPtr dgaColormap;
+ ColormapPtr savedColormap;
+ Bool grabMouse;
+ Bool grabKeyboard;
+} DGAScreenRec, *DGAScreenPtr;
+
+Bool
+DGAInit(
+ ScreenPtr pScreen,
+ DGAFunctionPtr funcs,
+ DGAModePtr modes,
+ int num
+){
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ DGAScreenPtr pScreenPriv;
+ int i;
+
+ if(!funcs || !funcs->SetMode || !funcs->OpenFramebuffer)
+ return FALSE;
+
+ if(!modes || num <= 0)
+ return FALSE;
+
+ DGAScreenKey = &DGAScreenKeyIndex;
+
+ pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
+
+ if (!pScreenPriv)
+ {
+ if(!(pScreenPriv = (DGAScreenPtr)malloc(sizeof(DGAScreenRec))))
+ return FALSE;
+ dixSetPrivate(&pScreen->devPrivates, DGAScreenKey, pScreenPriv);
+ pScreenPriv->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = DGACloseScreen;
+ pScreenPriv->DestroyColormap = pScreen->DestroyColormap;
+ pScreen->DestroyColormap = DGADestroyColormap;
+ pScreenPriv->InstallColormap = pScreen->InstallColormap;
+ pScreen->InstallColormap = DGAInstallColormap;
+ pScreenPriv->UninstallColormap = pScreen->UninstallColormap;
+ pScreen->UninstallColormap = DGAUninstallColormap;
+ }
+
+ pScreenPriv->pScrn = pScrn;
+ pScreenPriv->numModes = num;
+ pScreenPriv->modes = modes;
+ pScreenPriv->current = NULL;
+
+ pScreenPriv->funcs = funcs;
+ pScreenPriv->input = 0;
+ pScreenPriv->client = NULL;
+ pScreenPriv->fakedVisuals = NULL;
+ pScreenPriv->dgaColormap = NULL;
+ pScreenPriv->savedColormap = NULL;
+ pScreenPriv->grabMouse = FALSE;
+ pScreenPriv->grabKeyboard = FALSE;
+
+ for(i = 0; i < num; i++)
+ modes[i].num = i + 1;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ for(i = 0; i < num; i++)
+ modes[i].flags &= ~DGA_PIXMAP_AVAILABLE;
+#endif
+
+ return TRUE;
+}
+
+/* DGAReInitModes allows the driver to re-initialize
+ * the DGA mode list.
+ */
+
+Bool
+DGAReInitModes(
+ ScreenPtr pScreen,
+ DGAModePtr modes,
+ int num
+){
+ DGAScreenPtr pScreenPriv;
+ int i;
+
+ /* No DGA? Ignore call (but don't make it look like it failed) */
+ if(DGAScreenKey == NULL)
+ return TRUE;
+
+ pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
+
+ /* Same as above */
+ if(!pScreenPriv)
+ return TRUE;
+
+ /* Can't do this while DGA is active */
+ if(pScreenPriv->current)
+ return FALSE;
+
+ /* Quick sanity check */
+ if(!num)
+ modes = NULL;
+ else if(!modes)
+ num = 0;
+
+ pScreenPriv->numModes = num;
+ pScreenPriv->modes = modes;
+
+ /* This practically disables DGA. So be it. */
+ if(!num)
+ return TRUE;
+
+ for(i = 0; i < num; i++)
+ modes[i].num = i + 1;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ for(i = 0; i < num; i++)
+ modes[i].flags &= ~DGA_PIXMAP_AVAILABLE;
+#endif
+
+ return TRUE;
+}
+
+static void
+FreeMarkedVisuals(ScreenPtr pScreen)
+{
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
+ FakedVisualList *prev, *curr, *tmp;
+
+ if(!pScreenPriv->fakedVisuals)
+ return;
+
+ prev = NULL;
+ curr = pScreenPriv->fakedVisuals;
+
+ while(curr) {
+ if(curr->free) {
+ tmp = curr;
+ curr = curr->next;
+ if(prev)
+ prev->next = curr;
+ else
+ pScreenPriv->fakedVisuals = curr;
+ free(tmp->pVisual);
+ free(tmp);
+ } else {
+ prev = curr;
+ curr = curr->next;
+ }
+ }
+}
+
+static Bool
+DGACloseScreen(int i, ScreenPtr pScreen)
+{
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
+
+ if (XDGAEventBase) {
+ mieqSetHandler(ET_DGAEvent, NULL);
+ }
+
+ FreeMarkedVisuals(pScreen);
+
+ pScreen->CloseScreen = pScreenPriv->CloseScreen;
+ pScreen->DestroyColormap = pScreenPriv->DestroyColormap;
+ pScreen->InstallColormap = pScreenPriv->InstallColormap;
+ pScreen->UninstallColormap = pScreenPriv->UninstallColormap;
+
+ /* DGAShutdown() should have ensured that no DGA
+ screen were active by here */
+
+ free(pScreenPriv);
+
+ return((*pScreen->CloseScreen)(i, pScreen));
+}
+
+
+static void
+DGADestroyColormap(ColormapPtr pmap)
+{
+ ScreenPtr pScreen = pmap->pScreen;
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
+ VisualPtr pVisual = pmap->pVisual;
+
+ if(pScreenPriv->fakedVisuals) {
+ FakedVisualList *curr = pScreenPriv->fakedVisuals;
+
+ while(curr) {
+ if(curr->pVisual == pVisual) {
+ /* We can't get rid of them yet since FreeColormap
+ still needs the pVisual during the cleanup */
+ curr->free = TRUE;
+ break;
+ }
+ curr = curr->next;
+ }
+ }
+
+ if(pScreenPriv->DestroyColormap) {
+ pScreen->DestroyColormap = pScreenPriv->DestroyColormap;
+ (*pScreen->DestroyColormap)(pmap);
+ pScreen->DestroyColormap = DGADestroyColormap;
+ }
+}
+
+
+static void
+DGAInstallColormap(ColormapPtr pmap)
+{
+ ScreenPtr pScreen = pmap->pScreen;
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
+
+ if(pScreenPriv->current && pScreenPriv->dgaColormap) {
+ if (pmap != pScreenPriv->dgaColormap) {
+ pScreenPriv->savedColormap = pmap;
+ pmap = pScreenPriv->dgaColormap;
+ }
+ }
+
+ pScreen->InstallColormap = pScreenPriv->InstallColormap;
+ (*pScreen->InstallColormap)(pmap);
+ pScreen->InstallColormap = DGAInstallColormap;
+}
+
+static void
+DGAUninstallColormap(ColormapPtr pmap)
+{
+ ScreenPtr pScreen = pmap->pScreen;
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
+
+ if(pScreenPriv->current && pScreenPriv->dgaColormap) {
+ if (pmap == pScreenPriv->dgaColormap) {
+ pScreenPriv->dgaColormap = NULL;
+ }
+ }
+
+ pScreen->UninstallColormap = pScreenPriv->UninstallColormap;
+ (*pScreen->UninstallColormap)(pmap);
+ pScreen->UninstallColormap = DGAUninstallColormap;
+}
+
+int
+xf86SetDGAMode(
+ int index,
+ int num,
+ DGADevicePtr devRet
+){
+ ScreenPtr pScreen = screenInfo.screens[index];
+ DGAScreenPtr pScreenPriv;
+ ScrnInfoPtr pScrn;
+ DGADevicePtr device;
+ PixmapPtr pPix = NULL;
+ DGAModePtr pMode = NULL;
+
+ /* First check if DGAInit was successful on this screen */
+ if (DGAScreenKey == NULL)
+ return BadValue;
+ pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
+ if (!pScreenPriv)
+ return BadValue;
+ pScrn = pScreenPriv->pScrn;
+
+ if(!num) {
+ if(pScreenPriv->current) {
+ PixmapPtr oldPix = pScreenPriv->current->pPix;
+ if(oldPix) {
+ if(oldPix->drawable.id)
+ FreeResource(oldPix->drawable.id, RT_NONE);
+ else
+ (*pScreen->DestroyPixmap)(oldPix);
+ }
+ free(pScreenPriv->current);
+ pScreenPriv->current = NULL;
+ pScrn->vtSema = TRUE;
+ (*pScreenPriv->funcs->SetMode)(pScrn, NULL);
+ if(pScreenPriv->savedColormap) {
+ (*pScreen->InstallColormap)(pScreenPriv->savedColormap);
+ pScreenPriv->savedColormap = NULL;
+ }
+ pScreenPriv->dgaColormap = NULL;
+ (*pScrn->EnableDisableFBAccess)(index, TRUE);
+
+ FreeMarkedVisuals(pScreen);
+ }
+
+ pScreenPriv->grabMouse = FALSE;
+ pScreenPriv->grabKeyboard = FALSE;
+
+ return Success;
+ }
+
+ if(!pScrn->vtSema && !pScreenPriv->current) /* Really switched away */
+ return BadAlloc;
+
+ if((num > 0) && (num <= pScreenPriv->numModes))
+ pMode = &(pScreenPriv->modes[num - 1]);
+ else
+ return BadValue;
+
+ if(!(device = (DGADevicePtr)malloc(sizeof(DGADeviceRec))))
+ return BadAlloc;
+
+ if(!pScreenPriv->current) {
+ Bool oldVTSema = pScrn->vtSema;
+
+ pScrn->vtSema = FALSE; /* kludge until we rewrite VT switching */
+ (*pScrn->EnableDisableFBAccess)(index, FALSE);
+ pScrn->vtSema = oldVTSema;
+ }
+
+ if(!(*pScreenPriv->funcs->SetMode)(pScrn, pMode)) {
+ free(device);
+ return BadAlloc;
+ }
+
+ pScrn->currentMode = pMode->mode;
+
+ if(!pScreenPriv->current && !pScreenPriv->input) {
+ /* if it's multihead we need to warp the cursor off of
+ our screen so it doesn't get trapped */
+ }
+
+ pScrn->vtSema = FALSE;
+
+ if(pScreenPriv->current) {
+ PixmapPtr oldPix = pScreenPriv->current->pPix;
+ if(oldPix) {
+ if(oldPix->drawable.id)
+ FreeResource(oldPix->drawable.id, RT_NONE);
+ else
+ (*pScreen->DestroyPixmap)(oldPix);
+ }
+ free(pScreenPriv->current);
+ pScreenPriv->current = NULL;
+ }
+
+ if(pMode->flags & DGA_PIXMAP_AVAILABLE) {
+ if((pPix = (*pScreen->CreatePixmap)(pScreen, 0, 0, pMode->depth, 0))) {
+ (*pScreen->ModifyPixmapHeader)(pPix,
+ pMode->pixmapWidth, pMode->pixmapHeight,
+ pMode->depth, pMode->bitsPerPixel,
+ pMode->bytesPerScanline,
+ (pointer)(pMode->address));
+ }
+ }
+
+ devRet->mode = device->mode = pMode;
+ devRet->pPix = device->pPix = pPix;
+ pScreenPriv->current = device;
+ pScreenPriv->pixmapMode = FALSE;
+ pScreenPriv->grabMouse = TRUE;
+ pScreenPriv->grabKeyboard = TRUE;
+
+ return Success;
+}
+
+
+
+/*********** exported ones ***************/
+
+void
+DGASetInputMode(int index, Bool keyboard, Bool mouse)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
+
+ if (pScreenPriv)
+ {
+ pScreenPriv->grabMouse = mouse;
+ pScreenPriv->grabKeyboard = keyboard;
+
+ if (!mieq_installed) {
+ mieqSetHandler(ET_DGAEvent, DGAHandleEvent);
+ mieq_installed = 1;
+ }
+ }
+}
+
+Bool
+DGAChangePixmapMode(int index, int *x, int *y, int mode)
+{
+ DGAScreenPtr pScreenPriv;
+ DGADevicePtr pDev;
+ DGAModePtr pMode;
+ PixmapPtr pPix;
+
+ if(DGAScreenKey == NULL)
+ return FALSE;
+
+ pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+
+ if(!pScreenPriv || !pScreenPriv->current || !pScreenPriv->current->pPix)
+ return FALSE;
+
+ pDev = pScreenPriv->current;
+ pPix = pDev->pPix;
+ pMode = pDev->mode;
+
+ if(mode) {
+ int shift = 2;
+
+ if(*x > (pMode->pixmapWidth - pMode->viewportWidth))
+ *x = pMode->pixmapWidth - pMode->viewportWidth;
+ if(*y > (pMode->pixmapHeight - pMode->viewportHeight))
+ *y = pMode->pixmapHeight - pMode->viewportHeight;
+
+ switch(xf86Screens[index]->bitsPerPixel) {
+ case 16: shift = 1; break;
+ case 32: shift = 0; break;
+ default: break;
+ }
+
+ if(BITMAP_SCANLINE_PAD == 64)
+ shift++;
+
+ *x = (*x >> shift) << shift;
+
+ pPix->drawable.x = *x;
+ pPix->drawable.y = *y;
+ pPix->drawable.width = pMode->viewportWidth;
+ pPix->drawable.height = pMode->viewportHeight;
+ } else {
+ pPix->drawable.x = 0;
+ pPix->drawable.y = 0;
+ pPix->drawable.width = pMode->pixmapWidth;
+ pPix->drawable.height = pMode->pixmapHeight;
+ }
+ pPix->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pScreenPriv->pixmapMode = mode;
+
+ return TRUE;
+}
+
+Bool
+DGAAvailable(int index)
+{
+ if(DGAScreenKey == NULL)
+ return FALSE;
+
+ if(DGA_GET_SCREEN_PRIV(screenInfo.screens[index]))
+ return TRUE;
+
+ return FALSE;
+}
+
+Bool
+DGAActive(int index)
+{
+ DGAScreenPtr pScreenPriv;
+
+ if(DGAScreenKey == NULL)
+ return FALSE;
+
+ pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+
+ if(pScreenPriv && pScreenPriv->current)
+ return TRUE;
+
+ return FALSE;
+}
+
+
+
+/* Called by the event code in case the server is abruptly terminated */
+
+void
+DGAShutdown(void)
+{
+ ScrnInfoPtr pScrn;
+ int i;
+
+ if(DGAScreenKey == NULL)
+ return;
+
+ for(i = 0; i < screenInfo.numScreens; i++) {
+ pScrn = xf86Screens[i];
+
+ (void)(*pScrn->SetDGAMode)(pScrn->scrnIndex, 0, NULL);
+ }
+}
+
+/* Called by the extension to initialize a mode */
+
+int
+DGASetMode(
+ int index,
+ int num,
+ XDGAModePtr mode,
+ PixmapPtr *pPix
+){
+ ScrnInfoPtr pScrn = xf86Screens[index];
+ DGADeviceRec device;
+ int ret;
+
+ /* We rely on the extension to check that DGA is available */
+
+ ret = (*pScrn->SetDGAMode)(index, num, &device);
+ if((ret == Success) && num) {
+ DGACopyModeInfo(device.mode, mode);
+ *pPix = device.pPix;
+ }
+
+ return ret;
+}
+
+/* Called from the extension to let the DDX know which events are requested */
+
+void
+DGASelectInput(
+ int index,
+ ClientPtr client,
+ long mask
+){
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+
+ /* We rely on the extension to check that DGA is available */
+ pScreenPriv->client = client;
+ pScreenPriv->input = mask;
+}
+
+int
+DGAGetViewportStatus(int index)
+{
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+
+ /* We rely on the extension to check that DGA is active */
+
+ if (!pScreenPriv->funcs->GetViewport)
+ return 0;
+
+ return (*pScreenPriv->funcs->GetViewport)(pScreenPriv->pScrn);
+}
+
+int
+DGASetViewport(
+ int index,
+ int x, int y,
+ int mode
+){
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+
+ if (pScreenPriv->funcs->SetViewport)
+ (*pScreenPriv->funcs->SetViewport)(pScreenPriv->pScrn, x, y, mode);
+ return Success;
+}
+
+
+static int
+BitsClear(CARD32 data)
+{
+ int bits = 0;
+ CARD32 mask;
+
+ for(mask = 1; mask; mask <<= 1) {
+ if(!(data & mask)) bits++;
+ else break;
+ }
+
+ return bits;
+}
+
+int
+DGACreateColormap(int index, ClientPtr client, int id, int mode, int alloc)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
+ FakedVisualList *fvlp;
+ VisualPtr pVisual;
+ DGAModePtr pMode;
+ ColormapPtr pmap;
+
+ if(!mode || (mode > pScreenPriv->numModes))
+ return BadValue;
+
+ if((alloc != AllocNone) && (alloc != AllocAll))
+ return BadValue;
+
+ pMode = &(pScreenPriv->modes[mode - 1]);
+
+ if(!(pVisual = malloc(sizeof(VisualRec))))
+ return BadAlloc;
+
+ pVisual->vid = FakeClientID(0);
+ pVisual->class = pMode->visualClass;
+ pVisual->nplanes = pMode->depth;
+ pVisual->ColormapEntries = 1 << pMode->depth;
+ pVisual->bitsPerRGBValue = (pMode->depth + 2) / 3;
+
+ switch (pVisual->class) {
+ case PseudoColor:
+ case GrayScale:
+ case StaticGray:
+ pVisual->bitsPerRGBValue = 8; /* not quite */
+ pVisual->redMask = 0;
+ pVisual->greenMask = 0;
+ pVisual->blueMask = 0;
+ pVisual->offsetRed = 0;
+ pVisual->offsetGreen = 0;
+ pVisual->offsetBlue = 0;
+ break;
+ case DirectColor:
+ case TrueColor:
+ pVisual->ColormapEntries = 1 << pVisual->bitsPerRGBValue;
+ /* fall through */
+ case StaticColor:
+ pVisual->redMask = pMode->red_mask;
+ pVisual->greenMask = pMode->green_mask;
+ pVisual->blueMask = pMode->blue_mask;
+ pVisual->offsetRed = BitsClear(pVisual->redMask);
+ pVisual->offsetGreen = BitsClear(pVisual->greenMask);
+ pVisual->offsetBlue = BitsClear(pVisual->blueMask);
+ }
+
+ if(!(fvlp = malloc(sizeof(FakedVisualList)))) {
+ free(pVisual);
+ return BadAlloc;
+ }
+
+ fvlp->free = FALSE;
+ fvlp->pVisual = pVisual;
+ fvlp->next = pScreenPriv->fakedVisuals;
+ pScreenPriv->fakedVisuals = fvlp;
+
+ LEGAL_NEW_RESOURCE(id, client);
+
+ return CreateColormap(id, pScreen, pVisual, &pmap, alloc, client->index);
+}
+
+/* Called by the extension to install a colormap on DGA active screens */
+
+void
+DGAInstallCmap(ColormapPtr cmap)
+{
+ ScreenPtr pScreen = cmap->pScreen;
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
+
+ /* We rely on the extension to check that DGA is active */
+
+ if(!pScreenPriv->dgaColormap)
+ pScreenPriv->savedColormap = GetInstalledmiColormap(pScreen);
+
+ pScreenPriv->dgaColormap = cmap;
+
+ (*pScreen->InstallColormap)(cmap);
+}
+
+int
+DGASync(int index)
+{
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+
+ /* We rely on the extension to check that DGA is active */
+
+ if (pScreenPriv->funcs->Sync)
+ (*pScreenPriv->funcs->Sync)(pScreenPriv->pScrn);
+
+ return Success;
+}
+
+int
+DGAFillRect(
+ int index,
+ int x, int y, int w, int h,
+ unsigned long color
+){
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+
+ /* We rely on the extension to check that DGA is active */
+
+ if(pScreenPriv->funcs->FillRect &&
+ (pScreenPriv->current->mode->flags & DGA_FILL_RECT)) {
+
+ (*pScreenPriv->funcs->FillRect)(pScreenPriv->pScrn, x, y, w, h, color);
+ return Success;
+ }
+ return BadMatch;
+}
+
+int
+DGABlitRect(
+ int index,
+ int srcx, int srcy,
+ int w, int h,
+ int dstx, int dsty
+){
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+
+ /* We rely on the extension to check that DGA is active */
+
+ if(pScreenPriv->funcs->BlitRect &&
+ (pScreenPriv->current->mode->flags & DGA_BLIT_RECT)) {
+
+ (*pScreenPriv->funcs->BlitRect)(pScreenPriv->pScrn,
+ srcx, srcy, w, h, dstx, dsty);
+ return Success;
+ }
+ return BadMatch;
+}
+
+int
+DGABlitTransRect(
+ int index,
+ int srcx, int srcy,
+ int w, int h,
+ int dstx, int dsty,
+ unsigned long color
+){
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+
+ /* We rely on the extension to check that DGA is active */
+
+ if(pScreenPriv->funcs->BlitTransRect &&
+ (pScreenPriv->current->mode->flags & DGA_BLIT_RECT_TRANS)) {
+
+ (*pScreenPriv->funcs->BlitTransRect)(pScreenPriv->pScrn,
+ srcx, srcy, w, h, dstx, dsty, color);
+ return Success;
+ }
+ return BadMatch;
+}
+
+
+int
+DGAGetModes(int index)
+{
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+ /* We rely on the extension to check that DGA is available */
+
+ return pScreenPriv->numModes;
+}
+
+
+int
+DGAGetModeInfo(
+ int index,
+ XDGAModePtr mode,
+ int num
+){
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+ /* We rely on the extension to check that DGA is available */
+
+ if((num <= 0) || (num > pScreenPriv->numModes))
+ return BadValue;
+
+ DGACopyModeInfo(&(pScreenPriv->modes[num - 1]), mode);
+
+ return Success;
+}
+
+
+static void
+DGACopyModeInfo(
+ DGAModePtr mode,
+ XDGAModePtr xmode
+){
+ DisplayModePtr dmode = mode->mode;
+
+ xmode->num = mode->num;
+ xmode->name = dmode->name;
+ xmode->VSync_num = (int)(dmode->VRefresh * 1000.0);
+ xmode->VSync_den = 1000;
+ xmode->flags = mode->flags;
+ xmode->imageWidth = mode->imageWidth;
+ xmode->imageHeight = mode->imageHeight;
+ xmode->pixmapWidth = mode->pixmapWidth;
+ xmode->pixmapHeight = mode->pixmapHeight;
+ xmode->bytesPerScanline = mode->bytesPerScanline;
+ xmode->byteOrder = mode->byteOrder;
+ xmode->depth = mode->depth;
+ xmode->bitsPerPixel = mode->bitsPerPixel;
+ xmode->red_mask = mode->red_mask;
+ xmode->green_mask = mode->green_mask;
+ xmode->blue_mask = mode->blue_mask;
+ xmode->visualClass = mode->visualClass;
+ xmode->viewportWidth = mode->viewportWidth;
+ xmode->viewportHeight = mode->viewportHeight;
+ xmode->xViewportStep = mode->xViewportStep;
+ xmode->yViewportStep = mode->yViewportStep;
+ xmode->maxViewportX = mode->maxViewportX;
+ xmode->maxViewportY = mode->maxViewportY;
+ xmode->viewportFlags = mode->viewportFlags;
+ xmode->reserved1 = mode->reserved1;
+ xmode->reserved2 = mode->reserved2;
+ xmode->offset = mode->offset;
+
+ if(dmode->Flags & V_INTERLACE) xmode->flags |= DGA_INTERLACED;
+ if(dmode->Flags & V_DBLSCAN) xmode->flags |= DGA_DOUBLESCAN;
+}
+
+
+Bool
+DGAVTSwitch(void)
+{
+ ScreenPtr pScreen;
+ int i;
+
+ for(i = 0; i < screenInfo.numScreens; i++) {
+ pScreen = screenInfo.screens[i];
+
+ /* Alternatively, this could send events to DGA clients */
+
+ if(DGAScreenKey) {
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
+
+ if(pScreenPriv && pScreenPriv->current)
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+Bool
+DGAStealKeyEvent(DeviceIntPtr dev, int index, int key_code, int is_down)
+{
+ DGAScreenPtr pScreenPriv;
+ DGAEvent event;
+
+ if(DGAScreenKey == NULL) /* no DGA */
+ return FALSE;
+
+ if (key_code < 8 || key_code > 255)
+ return FALSE;
+
+ pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+
+ if(!pScreenPriv || !pScreenPriv->grabKeyboard) /* no direct mode */
+ return FALSE;
+
+ memset(&event, 0, sizeof(event));
+ event.header = ET_Internal;
+ event.type = ET_DGAEvent;
+ event.length = sizeof(event);
+ event.time = GetTimeInMillis();
+ event.subtype = (is_down ? ET_KeyPress : ET_KeyRelease);
+ event.detail = key_code;
+ event.dx = 0;
+ event.dy = 0;
+ mieqEnqueue (dev, (InternalEvent*)&event);
+
+ return TRUE;
+}
+
+static int DGAMouseX, DGAMouseY;
+
+Bool
+DGAStealMotionEvent(DeviceIntPtr dev, int index, int dx, int dy)
+{
+ DGAScreenPtr pScreenPriv;
+ DGAEvent event;
+
+ if(DGAScreenKey == NULL) /* no DGA */
+ return FALSE;
+
+ pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+
+ if(!pScreenPriv || !pScreenPriv->grabMouse) /* no direct mode */
+ return FALSE;
+
+ DGAMouseX += dx;
+ if (DGAMouseX < 0)
+ DGAMouseX = 0;
+ else if (DGAMouseX > screenInfo.screens[index]->width)
+ DGAMouseX = screenInfo.screens[index]->width;
+ DGAMouseY += dy;
+ if (DGAMouseY < 0)
+ DGAMouseY = 0;
+ else if (DGAMouseY > screenInfo.screens[index]->height)
+ DGAMouseY = screenInfo.screens[index]->height;
+
+ memset(&event, 0, sizeof(event));
+ event.header = ET_Internal;
+ event.type = ET_DGAEvent;
+ event.length = sizeof(event);
+ event.time = GetTimeInMillis();
+ event.subtype = ET_Motion;
+ event.detail = 0;
+ event.dx = dx;
+ event.dy = dy;
+ mieqEnqueue (dev, (InternalEvent*)&event);
+ return TRUE;
+}
+
+Bool
+DGAStealButtonEvent(DeviceIntPtr dev, int index, int button, int is_down)
+{
+ DGAScreenPtr pScreenPriv;
+ DGAEvent event;
+
+ if (DGAScreenKey == NULL)
+ return FALSE;
+
+ pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+
+ if (!pScreenPriv || !pScreenPriv->grabMouse)
+ return FALSE;
+
+ memset(&event, 0, sizeof(event));
+ event.header = ET_Internal;
+ event.type = ET_DGAEvent;
+ event.length = sizeof(event);
+ event.time = GetTimeInMillis();
+ event.subtype = (is_down ? ET_ButtonPress : ET_ButtonRelease);
+ event.detail = button;
+ event.dx = 0;
+ event.dy = 0;
+ mieqEnqueue (dev, (InternalEvent*)&event);
+
+ return TRUE;
+}
+
+/* We have the power to steal or modify events that are about to get queued */
+
+Bool
+DGAIsDgaEvent (xEvent *e)
+{
+ int coreEquiv;
+ if (DGAScreenKey == NULL || XDGAEventBase == 0)
+ return FALSE;
+ coreEquiv = e->u.u.type - *XDGAEventBase;
+ if (KeyPress <= coreEquiv && coreEquiv <= MotionNotify)
+ return TRUE;
+ return FALSE;
+}
+
+#define NoSuchEvent 0x80000000 /* so doesn't match NoEventMask */
+static Mask filters[] =
+{
+ NoSuchEvent, /* 0 */
+ NoSuchEvent, /* 1 */
+ KeyPressMask, /* KeyPress */
+ KeyReleaseMask, /* KeyRelease */
+ ButtonPressMask, /* ButtonPress */
+ ButtonReleaseMask, /* ButtonRelease */
+ PointerMotionMask, /* MotionNotify (initial state) */
+};
+
+static void
+DGAProcessKeyboardEvent (ScreenPtr pScreen, DGAEvent *event, DeviceIntPtr keybd)
+{
+ KeyClassPtr keyc = keybd->key;
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
+ DeviceIntPtr pointer = GetPairedDevice(keybd);
+ DeviceEvent ev;
+
+ memset(&ev, 0, sizeof(ev));
+ ev.length = sizeof(ev);
+ ev.detail.key = event->detail;
+ ev.type = event->subtype;
+ ev.root_x = 0;
+ ev.root_y = 0;
+ ev.corestate = XkbStateFieldFromRec(&keyc->xkbInfo->state);
+ ev.corestate |= pointer->button->state;
+
+ UpdateDeviceState(keybd, &ev);
+
+ /*
+ * Deliver the DGA event
+ */
+ if (pScreenPriv->client)
+ {
+ dgaEvent de;
+ de.u.u.type = *XDGAEventBase + GetCoreType((InternalEvent*)&ev);
+ de.u.u.detail = event->detail;
+ de.u.event.time = event->time;
+ de.u.event.dx = 0;
+ de.u.event.dy = 0;
+ de.u.event.screen = pScreen->myNum;
+ de.u.event.state = ev.corestate;
+
+ /* If the DGA client has selected input, then deliver based on the usual filter */
+ TryClientEvents (pScreenPriv->client, keybd, (xEvent *)&de, 1,
+ filters[ev.type], pScreenPriv->input, 0);
+ }
+ else
+ {
+ /* If the keyboard is actively grabbed, deliver a grabbed core event */
+ if (keybd->deviceGrab.grab && !keybd->deviceGrab.fromPassiveGrab)
+ {
+ ev.detail.key = event->detail;
+ ev.time = event->time;
+ ev.root_x = event->dx;
+ ev.root_y = event->dy;
+ ev.corestate = event->state;
+ ev.deviceid = keybd->id;
+ DeliverGrabbedEvent ((InternalEvent*)&ev, keybd, FALSE);
+ }
+ }
+}
+
+static void
+DGAProcessPointerEvent (ScreenPtr pScreen, DGAEvent *event, DeviceIntPtr mouse)
+{
+ ButtonClassPtr butc = mouse->button;
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
+ DeviceEvent ev;
+ DeviceIntPtr master = GetMaster(mouse, MASTER_KEYBOARD);
+
+ memset(&ev, 0, sizeof(ev));
+ ev.header = ET_Internal;
+ ev.length = sizeof(ev);
+ ev.type = event->subtype;
+ ev.corestate = butc->state;
+ if (master && master->key)
+ ev.corestate |= XkbStateFieldFromRec(&master->key->xkbInfo->state);
+
+ UpdateDeviceState(mouse, &ev);
+
+ /*
+ * Deliver the DGA event
+ */
+ if (pScreenPriv->client)
+ {
+ dgaEvent de;
+ int coreEquiv;
+
+ coreEquiv = GetCoreType((InternalEvent*)&ev);
+
+ de.u.u.type = *XDGAEventBase + coreEquiv;
+ de.u.u.detail = event->detail;
+ de.u.event.time = event->time;
+ de.u.event.dx = 0;
+ de.u.event.dy = 0;
+ de.u.event.screen = pScreen->myNum;
+ de.u.event.state = ev.corestate;
+
+ /* If the DGA client has selected input, then deliver based on the usual filter */
+ TryClientEvents (pScreenPriv->client, mouse, (xEvent *)&de, 1,
+ filters[coreEquiv], pScreenPriv->input, 0);
+ }
+ else
+ {
+ /* If the pointer is actively grabbed, deliver a grabbed core event */
+ if (mouse->deviceGrab.grab && !mouse->deviceGrab.fromPassiveGrab)
+ {
+ ev.detail.button = event->detail;
+ ev.time = event->time;
+ ev.root_x = event->dx;
+ ev.root_y = event->dy;
+ ev.corestate = event->state;
+ DeliverGrabbedEvent ((InternalEvent*)&ev, mouse, FALSE);
+ }
+ }
+}
+
+Bool
+DGAOpenFramebuffer(
+ int index,
+ char **name,
+ unsigned char **mem,
+ int *size,
+ int *offset,
+ int *flags
+){
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+
+ /* We rely on the extension to check that DGA is available */
+
+ return (*pScreenPriv->funcs->OpenFramebuffer)(pScreenPriv->pScrn,
+ name, mem, size, offset, flags);
+}
+
+void
+DGACloseFramebuffer(int index)
+{
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+
+ /* We rely on the extension to check that DGA is available */
+ if(pScreenPriv->funcs->CloseFramebuffer)
+ (*pScreenPriv->funcs->CloseFramebuffer)(pScreenPriv->pScrn);
+}
+
+/* For DGA 1.0 backwards compatibility only */
+
+int
+DGAGetOldDGAMode(int index)
+{
+ DGAScreenPtr pScreenPriv = DGA_GET_SCREEN_PRIV(screenInfo.screens[index]);
+ ScrnInfoPtr pScrn = pScreenPriv->pScrn;
+ DGAModePtr mode;
+ int i, w, h, p;
+
+ /* We rely on the extension to check that DGA is available */
+
+ w = pScrn->currentMode->HDisplay;
+ h = pScrn->currentMode->VDisplay;
+ p = pad_to_int32(pScrn->displayWidth * bits_to_bytes(pScrn->bitsPerPixel));
+
+ for(i = 0; i < pScreenPriv->numModes; i++) {
+ mode = &(pScreenPriv->modes[i]);
+
+ if((mode->viewportWidth == w) && (mode->viewportHeight == h) &&
+ (mode->bytesPerScanline == p) &&
+ (mode->bitsPerPixel == pScrn->bitsPerPixel) &&
+ (mode->depth == pScrn->depth)) {
+
+ return mode->num;
+ }
+ }
+
+ return 0;
+}
+
+static void
+DGAHandleEvent(int screen_num, InternalEvent *ev, DeviceIntPtr device)
+{
+ DGAEvent *event= &ev->dga_event;
+ ScreenPtr pScreen = screenInfo.screens[screen_num];
+ DGAScreenPtr pScreenPriv;
+
+ /* no DGA */
+ if (DGAScreenKey == NULL || XDGAEventBase == 0)
+ return;
+ pScreenPriv = DGA_GET_SCREEN_PRIV(pScreen);
+
+ /* DGA not initialized on this screen */
+ if (!pScreenPriv)
+ return;
+
+ switch (event->subtype) {
+ case KeyPress:
+ case KeyRelease:
+ DGAProcessKeyboardEvent (pScreen, event, device);
+ break;
+ case MotionNotify:
+ case ButtonPress:
+ case ButtonRelease:
+ DGAProcessPointerEvent (pScreen, event, device);
+ break;
+ default:
+ break;
+ }
+}
diff --git a/xorg-server/hw/xfree86/common/xf86DPMS.c b/xorg-server/hw/xfree86/common/xf86DPMS.c
index 22174c74e..3040cb294 100644
--- a/xorg-server/hw/xfree86/common/xf86DPMS.c
+++ b/xorg-server/hw/xfree86/common/xf86DPMS.c
@@ -1,200 +1,200 @@
-/*
- * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-/*
- * This file contains the DPMS functions required by the extension.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <X11/X.h>
-#include "os.h"
-#include "globals.h"
-#include "xf86.h"
-#include "xf86Priv.h"
-#ifdef DPMSExtension
-#include <X11/extensions/dpmsconst.h>
-#include "dpmsproc.h"
-#endif
-#include "xf86VGAarbiter.h"
-
-
-#ifdef DPMSExtension
-static int DPMSKeyIndex;
-static DevPrivateKey DPMSKey;
-static Bool DPMSClose(int i, ScreenPtr pScreen);
-static int DPMSCount = 0;
-#endif
-
-
-Bool
-xf86DPMSInit(ScreenPtr pScreen, DPMSSetProcPtr set, int flags)
-{
-#ifdef DPMSExtension
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- DPMSPtr pDPMS;
- pointer DPMSOpt;
- MessageType enabled_from;
-
- DPMSKey = &DPMSKeyIndex;
-
- if (!dixSetPrivate(&pScreen->devPrivates, DPMSKey,
- xcalloc(sizeof(DPMSRec), 1)))
- return FALSE;
-
- pDPMS = dixLookupPrivate(&pScreen->devPrivates, DPMSKey);
- pScrn->DPMSSet = set;
- pDPMS->Flags = flags;
- DPMSOpt = xf86FindOption(pScrn->options, "dpms");
- if (DPMSDisabledSwitch) {
- enabled_from = X_CMDLINE;
- DPMSEnabled = FALSE;
- }
- else if (DPMSOpt) {
- enabled_from = X_CONFIG;
- DPMSEnabled = xf86CheckBoolOption(pScrn->options, "dpms", FALSE);
- xf86MarkOptionUsed(DPMSOpt);
- }
- else {
- enabled_from = X_DEFAULT;
- DPMSEnabled = TRUE;
- }
- if (DPMSEnabled)
- xf86DrvMsg(pScreen->myNum, enabled_from, "DPMS enabled\n");
- pDPMS->Enabled = DPMSEnabled;
- pDPMS->CloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = DPMSClose;
- DPMSCount++;
- return TRUE;
-#else
- return FALSE;
-#endif
-}
-
-
-#ifdef DPMSExtension
-
-static Bool
-DPMSClose(int i, ScreenPtr pScreen)
-{
- DPMSPtr pDPMS;
-
- /* This shouldn't happen */
- if (DPMSKey == NULL)
- return FALSE;
-
- pDPMS = dixLookupPrivate(&pScreen->devPrivates, DPMSKey);
-
- /* This shouldn't happen */
- if (!pDPMS)
- return FALSE;
-
- pScreen->CloseScreen = pDPMS->CloseScreen;
-
- /*
- * Turn on DPMS when shutting down. If this function can be used
- * depends on the order the driver wraps things. If this is called
- * after the driver has shut down everything the driver will have
- * to deal with this internally.
- */
- if (xf86Screens[i]->vtSema && xf86Screens[i]->DPMSSet) {
- xf86Screens[i]->DPMSSet(xf86Screens[i],DPMSModeOn,0);
- }
-
- xfree(pDPMS);
- dixSetPrivate(&pScreen->devPrivates, DPMSKey, NULL);
- if (--DPMSCount == 0)
- DPMSKey = NULL;
- return pScreen->CloseScreen(i, pScreen);
-}
-
-
-/*
- * DPMSSet --
- * Device dependent DPMS mode setting hook. This is called whenever
- * the DPMS mode is to be changed.
- */
-int
-DPMSSet(ClientPtr client, int level)
-{
- int rc, i;
- DPMSPtr pDPMS;
- ScrnInfoPtr pScrn;
-
- DPMSPowerLevel = level;
-
- if (DPMSKey == NULL)
- return Success;
-
- if (level != DPMSModeOn) {
- rc = dixSaveScreens(client, SCREEN_SAVER_FORCER, ScreenSaverActive);
- if (rc != Success)
- return rc;
- }
-
- /* For each screen, set the DPMS level */
- for (i = 0; i < xf86NumScreens; i++) {
- pScrn = xf86Screens[i];
- pDPMS = dixLookupPrivate(&screenInfo.screens[i]->devPrivates, DPMSKey);
- if (pDPMS && pScrn->DPMSSet && pDPMS->Enabled && pScrn->vtSema) {
- xf86VGAarbiterLock(pScrn);
- pScrn->DPMSSet(pScrn, level, 0);
- xf86VGAarbiterUnlock(pScrn);
- }
- }
- return Success;
-}
-
-
-/*
- * DPMSSupported --
- * Return TRUE if any screen supports DPMS.
- */
-Bool
-DPMSSupported(void)
-{
- int i;
- DPMSPtr pDPMS;
- ScrnInfoPtr pScrn;
-
- if (DPMSKey == NULL) {
- return FALSE;
- }
-
- /* For each screen, check if DPMS is supported */
- for (i = 0; i < xf86NumScreens; i++) {
- pScrn = xf86Screens[i];
- pDPMS = dixLookupPrivate(&screenInfo.screens[i]->devPrivates, DPMSKey);
- if (pDPMS && pScrn->DPMSSet)
- return TRUE;
- }
- return FALSE;
-}
-
-#endif /* DPMSExtension */
+/*
+ * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ * This file contains the DPMS functions required by the extension.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <X11/X.h>
+#include "os.h"
+#include "globals.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#ifdef DPMSExtension
+#include <X11/extensions/dpmsconst.h>
+#include "dpmsproc.h"
+#endif
+#include "xf86VGAarbiter.h"
+
+
+#ifdef DPMSExtension
+static int DPMSKeyIndex;
+static DevPrivateKey DPMSKey;
+static Bool DPMSClose(int i, ScreenPtr pScreen);
+static int DPMSCount = 0;
+#endif
+
+
+Bool
+xf86DPMSInit(ScreenPtr pScreen, DPMSSetProcPtr set, int flags)
+{
+#ifdef DPMSExtension
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ DPMSPtr pDPMS;
+ pointer DPMSOpt;
+ MessageType enabled_from;
+
+ DPMSKey = &DPMSKeyIndex;
+
+ if (!dixSetPrivate(&pScreen->devPrivates, DPMSKey,
+ calloc(sizeof(DPMSRec), 1)))
+ return FALSE;
+
+ pDPMS = dixLookupPrivate(&pScreen->devPrivates, DPMSKey);
+ pScrn->DPMSSet = set;
+ pDPMS->Flags = flags;
+ DPMSOpt = xf86FindOption(pScrn->options, "dpms");
+ if (DPMSDisabledSwitch) {
+ enabled_from = X_CMDLINE;
+ DPMSEnabled = FALSE;
+ }
+ else if (DPMSOpt) {
+ enabled_from = X_CONFIG;
+ DPMSEnabled = xf86CheckBoolOption(pScrn->options, "dpms", FALSE);
+ xf86MarkOptionUsed(DPMSOpt);
+ }
+ else {
+ enabled_from = X_DEFAULT;
+ DPMSEnabled = TRUE;
+ }
+ if (DPMSEnabled)
+ xf86DrvMsg(pScreen->myNum, enabled_from, "DPMS enabled\n");
+ pDPMS->Enabled = DPMSEnabled;
+ pDPMS->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = DPMSClose;
+ DPMSCount++;
+ return TRUE;
+#else
+ return FALSE;
+#endif
+}
+
+
+#ifdef DPMSExtension
+
+static Bool
+DPMSClose(int i, ScreenPtr pScreen)
+{
+ DPMSPtr pDPMS;
+
+ /* This shouldn't happen */
+ if (DPMSKey == NULL)
+ return FALSE;
+
+ pDPMS = dixLookupPrivate(&pScreen->devPrivates, DPMSKey);
+
+ /* This shouldn't happen */
+ if (!pDPMS)
+ return FALSE;
+
+ pScreen->CloseScreen = pDPMS->CloseScreen;
+
+ /*
+ * Turn on DPMS when shutting down. If this function can be used
+ * depends on the order the driver wraps things. If this is called
+ * after the driver has shut down everything the driver will have
+ * to deal with this internally.
+ */
+ if (xf86Screens[i]->vtSema && xf86Screens[i]->DPMSSet) {
+ xf86Screens[i]->DPMSSet(xf86Screens[i],DPMSModeOn,0);
+ }
+
+ free(pDPMS);
+ dixSetPrivate(&pScreen->devPrivates, DPMSKey, NULL);
+ if (--DPMSCount == 0)
+ DPMSKey = NULL;
+ return pScreen->CloseScreen(i, pScreen);
+}
+
+
+/*
+ * DPMSSet --
+ * Device dependent DPMS mode setting hook. This is called whenever
+ * the DPMS mode is to be changed.
+ */
+int
+DPMSSet(ClientPtr client, int level)
+{
+ int rc, i;
+ DPMSPtr pDPMS;
+ ScrnInfoPtr pScrn;
+
+ DPMSPowerLevel = level;
+
+ if (DPMSKey == NULL)
+ return Success;
+
+ if (level != DPMSModeOn) {
+ rc = dixSaveScreens(client, SCREEN_SAVER_FORCER, ScreenSaverActive);
+ if (rc != Success)
+ return rc;
+ }
+
+ /* For each screen, set the DPMS level */
+ for (i = 0; i < xf86NumScreens; i++) {
+ pScrn = xf86Screens[i];
+ pDPMS = dixLookupPrivate(&screenInfo.screens[i]->devPrivates, DPMSKey);
+ if (pDPMS && pScrn->DPMSSet && pDPMS->Enabled && pScrn->vtSema) {
+ xf86VGAarbiterLock(pScrn);
+ pScrn->DPMSSet(pScrn, level, 0);
+ xf86VGAarbiterUnlock(pScrn);
+ }
+ }
+ return Success;
+}
+
+
+/*
+ * DPMSSupported --
+ * Return TRUE if any screen supports DPMS.
+ */
+Bool
+DPMSSupported(void)
+{
+ int i;
+ DPMSPtr pDPMS;
+ ScrnInfoPtr pScrn;
+
+ if (DPMSKey == NULL) {
+ return FALSE;
+ }
+
+ /* For each screen, check if DPMS is supported */
+ for (i = 0; i < xf86NumScreens; i++) {
+ pScrn = xf86Screens[i];
+ pDPMS = dixLookupPrivate(&screenInfo.screens[i]->devPrivates, DPMSKey);
+ if (pDPMS && pScrn->DPMSSet)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+#endif /* DPMSExtension */
diff --git a/xorg-server/hw/xfree86/common/xf86Events.c b/xorg-server/hw/xfree86/common/xf86Events.c
index ee4835233..9d3a58f91 100644
--- a/xorg-server/hw/xfree86/common/xf86Events.c
+++ b/xorg-server/hw/xfree86/common/xf86Events.c
@@ -567,7 +567,7 @@ addInputHandler(int fd, InputHandlerProc proc, pointer data)
if (fd < 0 || !proc)
return NULL;
- ih = xcalloc(sizeof(*ih), 1);
+ ih = calloc(sizeof(*ih), 1);
if (!ih)
return NULL;
@@ -616,7 +616,7 @@ removeInputHandler(IHPtr ih)
if (ih)
p->next = ih->next;
}
- xfree(ih);
+ free(ih);
}
int
diff --git a/xorg-server/hw/xfree86/common/xf86Helper.c b/xorg-server/hw/xfree86/common/xf86Helper.c
index 1cc1526c9..4cc543fc4 100644
--- a/xorg-server/hw/xfree86/common/xf86Helper.c
+++ b/xorg-server/hw/xfree86/common/xf86Helper.c
@@ -1,2588 +1,2588 @@
-/*
- * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-/*
- * Authors: Dirk Hohndel <hohndel@XFree86.Org>
- * David Dawes <dawes@XFree86.Org>
- * ... and others
- *
- * This file includes the helper functions that the server provides for
- * different drivers.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <pciaccess.h>
-#include "Pci.h"
-
-#include <X11/X.h>
-#include "os.h"
-#include "servermd.h"
-#include "pixmapstr.h"
-#include "windowstr.h"
-#include "propertyst.h"
-#include "gcstruct.h"
-#include "loaderProcs.h"
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86_OSlib.h"
-#include "micmap.h"
-#include "xf86DDC.h"
-#include "xf86Xinput.h"
-#include "xf86InPriv.h"
-#include "mivalidate.h"
-#include "xf86Bus.h"
-#include "xf86Crtc.h"
-
-/* For xf86GetClocks */
-#if defined(CSRG_BASED) || defined(__GNU__)
-#define HAS_SETPRIORITY
-#include <sys/resource.h>
-#endif
-
-static int xf86ScrnInfoPrivateCount = 0;
-
-
-/* Add a pointer to a new DriverRec to xf86DriverList */
-
-void
-xf86AddDriver(DriverPtr driver, pointer module, int flags)
-{
- /* Don't add null entries */
- if (!driver)
- return;
-
- if (xf86DriverList == NULL)
- xf86NumDrivers = 0;
-
- xf86NumDrivers++;
- xf86DriverList = xnfrealloc(xf86DriverList,
- xf86NumDrivers * sizeof(DriverPtr));
- xf86DriverList[xf86NumDrivers - 1] = xnfalloc(sizeof(DriverRec));
- if (flags & HaveDriverFuncs)
- *xf86DriverList[xf86NumDrivers - 1] = *driver;
- else {
- (void) memset( xf86DriverList[xf86NumDrivers - 1], 0,
- sizeof( DriverRec ) );
- (void) memcpy( xf86DriverList[xf86NumDrivers - 1], driver,
- sizeof(DriverRec1));
-
- }
- xf86DriverList[xf86NumDrivers - 1]->module = module;
- xf86DriverList[xf86NumDrivers - 1]->refCount = 0;
-}
-
-void
-xf86DeleteDriver(int drvIndex)
-{
- if (xf86DriverList[drvIndex]
- && (!xf86DriverHasEntities(xf86DriverList[drvIndex]))) {
- if (xf86DriverList[drvIndex]->module)
- UnloadModule(xf86DriverList[drvIndex]->module);
- xfree(xf86DriverList[drvIndex]);
- xf86DriverList[drvIndex] = NULL;
- }
-}
-
-/* Add a pointer to a new InputDriverRec to xf86InputDriverList */
-
-void
-xf86AddInputDriver(InputDriverPtr driver, pointer module, int flags)
-{
- /* Don't add null entries */
- if (!driver)
- return;
-
- if (xf86InputDriverList == NULL)
- xf86NumInputDrivers = 0;
-
- xf86NumInputDrivers++;
- xf86InputDriverList = xnfrealloc(xf86InputDriverList,
- xf86NumInputDrivers * sizeof(InputDriverPtr));
- xf86InputDriverList[xf86NumInputDrivers - 1] =
- xnfalloc(sizeof(InputDriverRec));
- *xf86InputDriverList[xf86NumInputDrivers - 1] = *driver;
- xf86InputDriverList[xf86NumInputDrivers - 1]->module = module;
- xf86InputDriverList[xf86NumInputDrivers - 1]->refCount = 0;
-}
-
-void
-xf86DeleteInputDriver(int drvIndex)
-{
- if (xf86InputDriverList[drvIndex] && xf86InputDriverList[drvIndex]->module)
- UnloadModule(xf86InputDriverList[drvIndex]->module);
- xfree(xf86InputDriverList[drvIndex]);
- xf86InputDriverList[drvIndex] = NULL;
-}
-
-InputDriverPtr
-xf86LookupInputDriver(const char *name)
-{
- int i;
-
- for (i = 0; i < xf86NumInputDrivers; i++) {
- if (xf86InputDriverList[i] && xf86InputDriverList[i]->driverName &&
- xf86NameCmp(name, xf86InputDriverList[i]->driverName) == 0)
- return xf86InputDriverList[i];
- }
- return NULL;
-}
-
-InputInfoPtr
-xf86LookupInput(const char *name)
-{
- InputInfoPtr p;
-
- for (p = xf86InputDevs; p != NULL; p = p->next) {
- if (strcmp(name, p->name) == 0)
- return p;
- }
-
- return NULL;
-}
-
-/* Allocate a new ScrnInfoRec in xf86Screens */
-
-ScrnInfoPtr
-xf86AllocateScreen(DriverPtr drv, int flags)
-{
- int i;
-
- if (xf86Screens == NULL)
- xf86NumScreens = 0;
-
- i = xf86NumScreens++;
- xf86Screens = xnfrealloc(xf86Screens, xf86NumScreens * sizeof(ScrnInfoPtr));
- xf86Screens[i] = xnfcalloc(sizeof(ScrnInfoRec), 1);
- xf86Screens[i]->scrnIndex = i; /* Changes when a screen is removed */
- xf86Screens[i]->origIndex = i; /* This never changes */
- xf86Screens[i]->privates = xnfcalloc(sizeof(DevUnion),
- xf86ScrnInfoPrivateCount);
- /*
- * EnableDisableFBAccess now gets initialized in InitOutput()
- * xf86Screens[i]->EnableDisableFBAccess = xf86EnableDisableFBAccess;
- */
-
- xf86Screens[i]->drv = drv;
- drv->refCount++;
- xf86Screens[i]->module = DuplicateModule(drv->module, NULL);
-
- xf86Screens[i]->DriverFunc = drv->driverFunc;
-
- return xf86Screens[i];
-}
-
-
-/*
- * Remove an entry from xf86Screens. Ideally it should free all allocated
- * data. To do this properly may require a driver hook.
- */
-
-void
-xf86DeleteScreen(int scrnIndex, int flags)
-{
- ScrnInfoPtr pScrn;
- int i;
-
- /* First check if the screen is valid */
- if (xf86NumScreens == 0 || xf86Screens == NULL)
- return;
-
- if (scrnIndex > xf86NumScreens - 1)
- return;
-
- if (!(pScrn = xf86Screens[scrnIndex]))
- return;
-
- /* If a FreeScreen function is defined, call it here */
- if (pScrn->FreeScreen != NULL)
- pScrn->FreeScreen(scrnIndex, 0);
-
- while (pScrn->modes)
- xf86DeleteMode(&pScrn->modes, pScrn->modes);
-
- while (pScrn->modePool)
- xf86DeleteMode(&pScrn->modePool, pScrn->modePool);
-
- xf86OptionListFree(pScrn->options);
-
- if (pScrn->module)
- UnloadModule(pScrn->module);
-
- if (pScrn->drv)
- pScrn->drv->refCount--;
-
- if (pScrn->privates)
- xfree(pScrn->privates);
-
- xf86ClearEntityListForScreen(scrnIndex);
-
- xfree(pScrn);
-
- /* Move the other entries down, updating their scrnIndex fields */
-
- xf86NumScreens--;
-
- for (i = scrnIndex; i < xf86NumScreens; i++) {
- xf86Screens[i] = xf86Screens[i + 1];
- xf86Screens[i]->scrnIndex = i;
- /* Also need to take care of the screen layout settings */
- }
-}
-
-/*
- * Allocate a private in ScrnInfoRec.
- */
-
-int
-xf86AllocateScrnInfoPrivateIndex(void)
-{
- int idx, i;
- ScrnInfoPtr pScr;
- DevUnion *nprivs;
-
- idx = xf86ScrnInfoPrivateCount++;
- for (i = 0; i < xf86NumScreens; i++) {
- pScr = xf86Screens[i];
- nprivs = xnfrealloc(pScr->privates,
- xf86ScrnInfoPrivateCount * sizeof(DevUnion));
- /* Zero the new private */
- bzero(&nprivs[idx], sizeof(DevUnion));
- pScr->privates = nprivs;
- }
- return idx;
-}
-
-/* Allocate a new InputInfoRec and append it to the tail of xf86InputDevs. */
-InputInfoPtr
-xf86AllocateInput(InputDriverPtr drv, int flags)
-{
- InputInfoPtr new, *prev = NULL;
-
- if (!(new = xcalloc(sizeof(InputInfoRec), 1)))
- return NULL;
-
- new->drv = drv;
- drv->refCount++;
- new->module = DuplicateModule(drv->module, NULL);
-
- for (prev = &xf86InputDevs; *prev; prev = &(*prev)->next)
- ;
-
- *prev = new;
- new->next = NULL;
-
- return new;
-}
-
-
-/*
- * Remove an entry from xf86InputDevs. Ideally it should free all allocated
- * data. To do this properly may require a driver hook.
- */
-
-void
-xf86DeleteInput(InputInfoPtr pInp, int flags)
-{
- InputInfoPtr p;
-
- /* First check if the inputdev is valid. */
- if (pInp == NULL)
- return;
-
-#if 0
- /* If a free function is defined, call it here. */
- if (pInp->free)
- pInp->free(pInp, 0);
-#endif
-
- if (pInp->module)
- UnloadModule(pInp->module);
-
- if (pInp->drv)
- pInp->drv->refCount--;
-
- /* This should *really* be handled in drv->UnInit(dev) call instead, but
- * if the driver forgets about it make sure we free it or at least crash
- * with flying colors */
- if (pInp->private)
- xfree(pInp->private);
-
- /* Remove the entry from the list. */
- if (pInp == xf86InputDevs)
- xf86InputDevs = pInp->next;
- else {
- p = xf86InputDevs;
- while (p && p->next != pInp)
- p = p->next;
- if (p)
- p->next = pInp->next;
- /* Else the entry wasn't in the xf86InputDevs list (ignore this). */
- }
- xfree(pInp);
-}
-
-Bool
-xf86AddPixFormat(ScrnInfoPtr pScrn, int depth, int bpp, int pad)
-{
- int i;
-
- if (pScrn->numFormats >= MAXFORMATS)
- return FALSE;
-
- if (bpp <= 0) {
- if (depth == 1)
- bpp = 1;
- else if (depth <= 8)
- bpp = 8;
- else if (depth <= 16)
- bpp = 16;
- else if (depth <= 32)
- bpp = 32;
- else
- return FALSE;
- }
- if (pad <= 0)
- pad = BITMAP_SCANLINE_PAD;
-
- i = pScrn->numFormats++;
- pScrn->formats[i].depth = depth;
- pScrn->formats[i].bitsPerPixel = bpp;
- pScrn->formats[i].scanlinePad = pad;
- return TRUE;
-}
-
-/*
- * Set the depth we are using based on (in the following order of preference):
- * - values given on the command line
- * - values given in the config file
- * - values provided by the driver
- * - an overall default when nothing else is given
- *
- * Also find a Display subsection matching the depth/bpp found.
- *
- * Sets the following ScrnInfoRec fields:
- * bitsPerPixel, pixmap24, depth, display, imageByteOrder,
- * bitmapScanlinePad, bitmapScanlineUnit, bitmapBitOrder, numFormats,
- * formats, fbFormat.
- */
-
-/* Can the screen handle 24 bpp pixmaps */
-#define DO_PIX24(f) ((f & Support24bppFb) || \
- ((f & Support32bppFb) && (f & SupportConvert24to32)))
-
-/* Can the screen handle 32 bpp pixmaps */
-#define DO_PIX32(f) ((f & Support32bppFb) || \
- ((f & Support24bppFb) && (f & SupportConvert32to24)))
-
-/* Does the screen prefer 32bpp fb for 24bpp pixmaps */
-#define CHOOSE32FOR24(f) ((f & Support32bppFb) && (f & SupportConvert24to32) \
- && (f & PreferConvert24to32))
-
-/* Does the screen prefer 24bpp fb for 32bpp pixmaps */
-#define CHOOSE24FOR32(f) ((f & Support24bppFb) && (f & SupportConvert32to24) \
- && (f & PreferConvert32to24))
-
-/* Can the screen handle 32bpp pixmaps for 24bpp fb */
-#define DO_PIX32FOR24(f) ((f & Support24bppFb) && (f & SupportConvert32to24))
-
-/* Can the screen handle 24bpp pixmaps for 32bpp fb */
-#define DO_PIX24FOR32(f) ((f & Support32bppFb) && (f & SupportConvert24to32))
-
-#ifndef GLOBAL_DEFAULT_DEPTH
-#define GLOBAL_DEFAULT_DEPTH 24
-#endif
-
-Bool
-xf86SetDepthBpp(ScrnInfoPtr scrp, int depth, int dummy, int fbbpp,
- int depth24flags)
-{
- int i;
- DispPtr disp;
- Pix24Flags pix24 = xf86Info.pixmap24;
- Bool nomatch = FALSE;
-
- scrp->bitsPerPixel = -1;
- scrp->depth = -1;
- scrp->pixmap24 = Pix24DontCare;
- scrp->bitsPerPixelFrom = X_DEFAULT;
- scrp->depthFrom = X_DEFAULT;
-
- if (xf86FbBpp > 0) {
- scrp->bitsPerPixel = xf86FbBpp;
- scrp->bitsPerPixelFrom = X_CMDLINE;
- }
-
- if (xf86Depth > 0) {
- scrp->depth = xf86Depth;
- scrp->depthFrom = X_CMDLINE;
- }
-
- if (xf86FbBpp < 0 && xf86Depth < 0) {
- if (scrp->confScreen->defaultfbbpp > 0) {
- scrp->bitsPerPixel = scrp->confScreen->defaultfbbpp;
- scrp->bitsPerPixelFrom = X_CONFIG;
- }
- if (scrp->confScreen->defaultdepth > 0) {
- scrp->depth = scrp->confScreen->defaultdepth;
- scrp->depthFrom = X_CONFIG;
- }
-
- if (scrp->confScreen->defaultfbbpp <= 0 &&
- scrp->confScreen->defaultdepth <= 0) {
- /*
- * Check for DefaultDepth and DefaultFbBpp options in the
- * Device sections.
- */
- int i;
- GDevPtr device;
- Bool found = FALSE;
-
- for (i = 0; i < scrp->numEntities; i++) {
- device = xf86GetDevFromEntity(scrp->entityList[i],
- scrp->entityInstanceList[i]);
- if (device && device->options) {
- if (xf86FindOption(device->options, "DefaultDepth")) {
- scrp->depth = xf86SetIntOption(device->options,
- "DefaultDepth", -1);
- scrp->depthFrom = X_CONFIG;
- found = TRUE;
- }
- if (xf86FindOption(device->options, "DefaultFbBpp")) {
- scrp->bitsPerPixel = xf86SetIntOption(device->options,
- "DefaultFbBpp",
- -1);
- scrp->bitsPerPixelFrom = X_CONFIG;
- found = TRUE;
- }
- }
- if (found)
- break;
- }
- }
- }
-
- /* If none of these is set, pick a default */
- if (scrp->bitsPerPixel < 0 && scrp->depth < 0) {
- if (fbbpp > 0 || depth > 0) {
- if (fbbpp > 0)
- scrp->bitsPerPixel = fbbpp;
- if (depth > 0)
- scrp->depth = depth;
- } else {
- scrp->depth = GLOBAL_DEFAULT_DEPTH;
- }
- }
-
- /* If any are not given, determine a default for the others */
-
- if (scrp->bitsPerPixel < 0) {
- /* The depth must be set */
- if (scrp->depth > -1) {
- if (scrp->depth == 1)
- scrp->bitsPerPixel = 1;
- else if (scrp->depth <= 4)
- scrp->bitsPerPixel = 4;
- else if (scrp->depth <= 8)
- scrp->bitsPerPixel = 8;
- else if (scrp->depth <= 16)
- scrp->bitsPerPixel = 16;
- else if (scrp->depth <= 24) {
- /*
- * Figure out if a choice is possible based on the depth24
- * and pix24 flags.
- */
- /* Check pix24 first */
- if (pix24 != Pix24DontCare) {
- if (pix24 == Pix24Use32) {
- if (DO_PIX32(depth24flags)) {
- if (CHOOSE24FOR32(depth24flags))
- scrp->bitsPerPixel = 24;
- else
- scrp->bitsPerPixel = 32;
- } else {
- nomatch = TRUE;
- }
- } else if (pix24 == Pix24Use24) {
- if (DO_PIX24(depth24flags)) {
- if (CHOOSE32FOR24(depth24flags))
- scrp->bitsPerPixel = 32;
- else
- scrp->bitsPerPixel = 24;
- } else {
- nomatch = TRUE;
- }
- }
- } else {
- if (DO_PIX32(depth24flags)) {
- if (CHOOSE24FOR32(depth24flags))
- scrp->bitsPerPixel = 24;
- else
- scrp->bitsPerPixel = 32;
- } else if (DO_PIX24(depth24flags)) {
- if (CHOOSE32FOR24(depth24flags))
- scrp->bitsPerPixel = 32;
- else
- scrp->bitsPerPixel = 24;
- }
- }
- } else if (scrp->depth <= 32)
- scrp->bitsPerPixel = 32;
- else {
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Specified depth (%d) is greater than 32\n",
- scrp->depth);
- return FALSE;
- }
- } else {
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "xf86SetDepthBpp: internal error: depth and fbbpp"
- " are both not set\n");
- return FALSE;
- }
- if (scrp->bitsPerPixel < 0) {
- if (nomatch)
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Driver can't support depth 24 pixmap format (%d)\n",
- PIX24TOBPP(pix24));
- else if ((depth24flags & (Support24bppFb | Support32bppFb)) ==
- NoDepth24Support)
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Driver can't support depth 24\n");
- else
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Can't find fbbpp for depth 24\n");
- return FALSE;
- }
- scrp->bitsPerPixelFrom = X_PROBED;
- }
-
- if (scrp->depth <= 0) {
- /* bitsPerPixel is already set */
- switch (scrp->bitsPerPixel) {
- case 32:
- scrp->depth = 24;
- break;
- default:
- /* 1, 4, 8, 16 and 24 */
- scrp->depth = scrp->bitsPerPixel;
- break;
- }
- scrp->depthFrom = X_PROBED;
- }
-
- /* Sanity checks */
- if (scrp->depth < 1 || scrp->depth > 32) {
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Specified depth (%d) is not in the range 1-32\n",
- scrp->depth);
- return FALSE;
- }
- switch (scrp->bitsPerPixel) {
- case 1:
- case 4:
- case 8:
- case 16:
- case 24:
- case 32:
- break;
- default:
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Specified fbbpp (%d) is not a permitted value\n",
- scrp->bitsPerPixel);
- return FALSE;
- }
- if (scrp->depth > scrp->bitsPerPixel) {
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Specified depth (%d) is greater than the fbbpp (%d)\n",
- scrp->depth, scrp->bitsPerPixel);
- return FALSE;
- }
-
- /* set scrp->pixmap24 if the driver isn't flexible */
- if (scrp->bitsPerPixel == 24 && !DO_PIX32FOR24(depth24flags)) {
- scrp->pixmap24 = Pix24Use24;
- }
- if (scrp->bitsPerPixel == 32 && !DO_PIX24FOR32(depth24flags)) {
- scrp->pixmap24 = Pix24Use32;
- }
-
- /*
- * Find the Display subsection matching the depth/fbbpp and initialise
- * scrp->display with it.
- */
- for (i = 0, disp = scrp->confScreen->displays;
- i < scrp->confScreen->numdisplays; i++, disp++) {
- if ((disp->depth == scrp->depth && disp->fbbpp == scrp->bitsPerPixel)
- || (disp->depth == scrp->depth && disp->fbbpp <= 0)
- || (disp->fbbpp == scrp->bitsPerPixel && disp->depth <= 0)) {
- scrp->display = disp;
- break;
- }
- }
-
- /*
- * If an exact match can't be found, see if there is one with no
- * depth or fbbpp specified.
- */
- if (i == scrp->confScreen->numdisplays) {
- for (i = 0, disp = scrp->confScreen->displays;
- i < scrp->confScreen->numdisplays; i++, disp++) {
- if (disp->depth <= 0 && disp->fbbpp <= 0) {
- scrp->display = disp;
- break;
- }
- }
- }
-
- /*
- * If all else fails, create a default one.
- */
- if (i == scrp->confScreen->numdisplays) {
- scrp->confScreen->numdisplays++;
- scrp->confScreen->displays =
- xnfrealloc(scrp->confScreen->displays,
- scrp->confScreen->numdisplays * sizeof(DispRec));
- xf86DrvMsg(scrp->scrnIndex, X_INFO,
- "Creating default Display subsection in Screen section\n"
- "\t\"%s\" for depth/fbbpp %d/%d\n",
- scrp->confScreen->id, scrp->depth, scrp->bitsPerPixel);
- memset(&scrp->confScreen->displays[i], 0, sizeof(DispRec));
- scrp->confScreen->displays[i].blackColour.red = -1;
- scrp->confScreen->displays[i].blackColour.green = -1;
- scrp->confScreen->displays[i].blackColour.blue = -1;
- scrp->confScreen->displays[i].whiteColour.red = -1;
- scrp->confScreen->displays[i].whiteColour.green = -1;
- scrp->confScreen->displays[i].whiteColour.blue = -1;
- scrp->confScreen->displays[i].defaultVisual = -1;
- scrp->confScreen->displays[i].modes = xnfalloc(sizeof(char *));
- scrp->confScreen->displays[i].modes[0] = NULL;
- scrp->confScreen->displays[i].depth = depth;
- scrp->confScreen->displays[i].fbbpp = fbbpp;
- scrp->display = &scrp->confScreen->displays[i];
- }
-
- /*
- * Setup defaults for the display-wide attributes the framebuffer will
- * need. These defaults should eventually be set globally, and not
- * dependent on the screens.
- */
- scrp->imageByteOrder = IMAGE_BYTE_ORDER;
- scrp->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
- if (scrp->depth < 8) {
- /* Planar modes need these settings */
- scrp->bitmapScanlineUnit = 8;
- scrp->bitmapBitOrder = MSBFirst;
- } else {
- scrp->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
- scrp->bitmapBitOrder = BITMAP_BIT_ORDER;
- }
-
- /*
- * If an unusual depth is required, add it to scrp->formats. The formats
- * for the common depths are handled globally in InitOutput
- */
- switch (scrp->depth) {
- case 1:
- case 4:
- case 8:
- case 15:
- case 16:
- case 24:
- /* Common depths. Nothing to do for them */
- break;
- default:
- if (!xf86AddPixFormat(scrp, scrp->depth, 0, 0)) {
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Can't add pixmap format for depth %d\n", scrp->depth);
- return FALSE;
- }
- }
-
- /* Initialise the framebuffer format for this screen */
- scrp->fbFormat.depth = scrp->depth;
- scrp->fbFormat.bitsPerPixel = scrp->bitsPerPixel;
- scrp->fbFormat.scanlinePad = BITMAP_SCANLINE_PAD;
-
- return TRUE;
-}
-
-/*
- * Print out the selected depth and bpp.
- */
-void
-xf86PrintDepthBpp(ScrnInfoPtr scrp)
-{
- xf86DrvMsg(scrp->scrnIndex, scrp->depthFrom, "Depth %d, ", scrp->depth);
- xf86Msg(scrp->bitsPerPixelFrom, "framebuffer bpp %d\n", scrp->bitsPerPixel);
-}
-
-/*
- * xf86SetWeight sets scrp->weight, scrp->mask, scrp->offset, and for depths
- * greater than MAX_PSEUDO_DEPTH also scrp->rgbBits.
- */
-Bool
-xf86SetWeight(ScrnInfoPtr scrp, rgb weight, rgb mask)
-{
- MessageType weightFrom = X_DEFAULT;
-
- scrp->weight.red = 0;
- scrp->weight.green = 0;
- scrp->weight.blue = 0;
-
- if (xf86Weight.red > 0 && xf86Weight.green > 0 && xf86Weight.blue > 0) {
- scrp->weight = xf86Weight;
- weightFrom = X_CMDLINE;
- } else if (scrp->display->weight.red > 0 && scrp->display->weight.green > 0
- && scrp->display->weight.blue > 0) {
- scrp->weight = scrp->display->weight;
- weightFrom = X_CONFIG;
- } else if (weight.red > 0 && weight.green > 0 && weight.blue > 0) {
- scrp->weight = weight;
- } else {
- switch (scrp->depth) {
- case 1:
- case 4:
- case 8:
- scrp->weight.red = scrp->weight.green =
- scrp->weight.blue = scrp->rgbBits;
- break;
- case 15:
- scrp->weight.red = scrp->weight.green = scrp->weight.blue = 5;
- break;
- case 16:
- scrp->weight.red = scrp->weight.blue = 5;
- scrp->weight.green = 6;
- break;
- case 24:
- scrp->weight.red = scrp->weight.green = scrp->weight.blue = 8;
- break;
- case 30:
- scrp->weight.red = scrp->weight.green = scrp->weight.blue = 10;
- break;
- }
- }
-
- if (scrp->weight.red)
- xf86DrvMsg(scrp->scrnIndex, weightFrom, "RGB weight %d%d%d\n",
- (int)scrp->weight.red, (int)scrp->weight.green,
- (int)scrp->weight.blue);
-
- if (scrp->depth > MAX_PSEUDO_DEPTH &&
- (scrp->depth != scrp->weight.red + scrp->weight.green +
- scrp->weight.blue)) {
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Weight given (%d%d%d) is inconsistent with the "
- "depth (%d)\n",
- (int)scrp->weight.red, (int)scrp->weight.green,
- (int)scrp->weight.blue, scrp->depth);
- return FALSE;
- }
- if (scrp->depth > MAX_PSEUDO_DEPTH && scrp->weight.red) {
- /*
- * XXX Does this even mean anything for TrueColor visuals?
- * If not, we shouldn't even be setting it here. However, this
- * matches the behaviour of 3.x versions of XFree86.
- */
- scrp->rgbBits = scrp->weight.red;
- if (scrp->weight.green > scrp->rgbBits)
- scrp->rgbBits = scrp->weight.green;
- if (scrp->weight.blue > scrp->rgbBits)
- scrp->rgbBits = scrp->weight.blue;
- }
-
- /* Set the mask and offsets */
- if (mask.red == 0 || mask.green == 0 || mask.blue == 0) {
- /* Default to a setting common to PC hardware */
- scrp->offset.red = scrp->weight.green + scrp->weight.blue;
- scrp->offset.green = scrp->weight.blue;
- scrp->offset.blue = 0;
- scrp->mask.red = ((1 << scrp->weight.red) - 1) << scrp->offset.red;
- scrp->mask.green = ((1 << scrp->weight.green) - 1)
- << scrp->offset.green;
- scrp->mask.blue = (1 << scrp->weight.blue) - 1;
- } else {
- /* Initialise to the values passed */
- scrp->mask.red = mask.red;
- scrp->mask.green = mask.green;
- scrp->mask.blue = mask.blue;
- scrp->offset.red = ffs(mask.red);
- scrp->offset.green = ffs(mask.green);
- scrp->offset.blue = ffs(mask.blue);
- }
- return TRUE;
-}
-
-Bool
-xf86SetDefaultVisual(ScrnInfoPtr scrp, int visual)
-{
- MessageType visualFrom = X_DEFAULT;
-
- if (defaultColorVisualClass >= 0) {
- scrp->defaultVisual = defaultColorVisualClass;
- visualFrom = X_CMDLINE;
- } else if (scrp->display->defaultVisual >= 0) {
- scrp->defaultVisual = scrp->display->defaultVisual;
- visualFrom = X_CONFIG;
- } else if (visual >= 0) {
- scrp->defaultVisual = visual;
- } else {
- if (scrp->depth == 1)
- scrp->defaultVisual = StaticGray;
- else if (scrp->depth == 4)
- scrp->defaultVisual = StaticColor;
- else if (scrp->depth <= MAX_PSEUDO_DEPTH)
- scrp->defaultVisual = PseudoColor;
- else
- scrp->defaultVisual = TrueColor;
- }
- switch (scrp->defaultVisual) {
- case StaticGray:
- case GrayScale:
- case StaticColor:
- case PseudoColor:
- case TrueColor:
- case DirectColor:
- xf86DrvMsg(scrp->scrnIndex, visualFrom, "Default visual is %s\n",
- xf86VisualNames[scrp->defaultVisual]);
- return TRUE;
- default:
-
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Invalid default visual class (%d)\n", scrp->defaultVisual);
- return FALSE;
- }
-}
-
-#define TEST_GAMMA(g) \
- (g).red > GAMMA_ZERO || (g).green > GAMMA_ZERO || (g).blue > GAMMA_ZERO
-
-#define SET_GAMMA(g) \
- (g) > GAMMA_ZERO ? (g) : 1.0
-
-Bool
-xf86SetGamma(ScrnInfoPtr scrp, Gamma gamma)
-{
- MessageType from = X_DEFAULT;
-#if 0
- xf86MonPtr DDC = (xf86MonPtr)(scrp->monitor->DDC);
-#endif
- if (TEST_GAMMA(xf86Gamma)) {
- from = X_CMDLINE;
- scrp->gamma.red = SET_GAMMA(xf86Gamma.red);
- scrp->gamma.green = SET_GAMMA(xf86Gamma.green);
- scrp->gamma.blue = SET_GAMMA(xf86Gamma.blue);
- } else if (TEST_GAMMA(scrp->monitor->gamma)) {
- from = X_CONFIG;
- scrp->gamma.red = SET_GAMMA(scrp->monitor->gamma.red);
- scrp->gamma.green = SET_GAMMA(scrp->monitor->gamma.green);
- scrp->gamma.blue = SET_GAMMA(scrp->monitor->gamma.blue);
-#if 0
- } else if ( DDC && DDC->features.gamma > GAMMA_ZERO ) {
- from = X_PROBED;
- scrp->gamma.red = SET_GAMMA(DDC->features.gamma);
- scrp->gamma.green = SET_GAMMA(DDC->features.gamma);
- scrp->gamma.blue = SET_GAMMA(DDC->features.gamma);
- /* EDID structure version 2 gives optional seperate red, green & blue gamma values
- * in bytes 0x57-0x59 */
-#endif
- } else if (TEST_GAMMA(gamma)) {
- scrp->gamma.red = SET_GAMMA(gamma.red);
- scrp->gamma.green = SET_GAMMA(gamma.green);
- scrp->gamma.blue = SET_GAMMA(gamma.blue);
- } else {
- scrp->gamma.red = 1.0;
- scrp->gamma.green = 1.0;
- scrp->gamma.blue = 1.0;
- }
- /* Pretend we succeeded if we support better a gamma system.
- * This avoids a confusing message.
- */
- if (xf86_crtc_supports_gamma(scrp))
- return TRUE;
- xf86DrvMsg(scrp->scrnIndex, from,
- "Using gamma correction (%.1f, %.1f, %.1f)\n",
- scrp->gamma.red, scrp->gamma.green, scrp->gamma.blue);
-
- return TRUE;
-}
-
-#undef TEST_GAMMA
-#undef SET_GAMMA
-
-
-/*
- * Set the DPI from the command line option. XXX should allow it to be
- * calculated from the widthmm/heightmm values.
- */
-
-#undef MMPERINCH
-#define MMPERINCH 25.4
-
-void
-xf86SetDpi(ScrnInfoPtr pScrn, int x, int y)
-{
- MessageType from = X_DEFAULT;
- xf86MonPtr DDC = (xf86MonPtr)(pScrn->monitor->DDC);
- int ddcWidthmm, ddcHeightmm;
- int widthErr, heightErr;
-
- /* XXX Maybe there is no need for widthmm/heightmm in ScrnInfoRec */
- pScrn->widthmm = pScrn->monitor->widthmm;
- pScrn->heightmm = pScrn->monitor->heightmm;
-
- if (DDC && (DDC->features.hsize > 0 && DDC->features.vsize > 0) ) {
- /* DDC gives display size in mm for individual modes,
- * but cm for monitor
- */
- ddcWidthmm = DDC->features.hsize * 10; /* 10mm in 1cm */
- ddcHeightmm = DDC->features.vsize * 10; /* 10mm in 1cm */
- } else {
- ddcWidthmm = ddcHeightmm = 0;
- }
-
- if (monitorResolution > 0) {
- pScrn->xDpi = monitorResolution;
- pScrn->yDpi = monitorResolution;
- from = X_CMDLINE;
- } else if (pScrn->widthmm > 0 || pScrn->heightmm > 0) {
- from = X_CONFIG;
- if (pScrn->widthmm > 0) {
- pScrn->xDpi =
- (int)((double)pScrn->virtualX * MMPERINCH / pScrn->widthmm);
- }
- if (pScrn->heightmm > 0) {
- pScrn->yDpi =
- (int)((double)pScrn->virtualY * MMPERINCH / pScrn->heightmm);
- }
- if (pScrn->xDpi > 0 && pScrn->yDpi <= 0)
- pScrn->yDpi = pScrn->xDpi;
- if (pScrn->yDpi > 0 && pScrn->xDpi <= 0)
- pScrn->xDpi = pScrn->yDpi;
- xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n",
- pScrn->widthmm, pScrn->heightmm);
-
- /* Warn if config and probe disagree about display size */
- if ( ddcWidthmm && ddcHeightmm ) {
- if (pScrn->widthmm > 0) {
- widthErr = abs(ddcWidthmm - pScrn->widthmm);
- } else {
- widthErr = 0;
- }
- if (pScrn->heightmm > 0) {
- heightErr = abs(ddcHeightmm - pScrn->heightmm);
- } else {
- heightErr = 0;
- }
- if (widthErr>10 || heightErr>10) {
- /* Should include config file name for monitor here */
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "Probed monitor is %dx%d mm, using Displaysize %dx%d mm\n",
- ddcWidthmm,ddcHeightmm, pScrn->widthmm,pScrn->heightmm);
- }
- }
- } else if ( ddcWidthmm && ddcHeightmm ) {
- from = X_PROBED;
- xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n",
- ddcWidthmm, ddcHeightmm );
- pScrn->widthmm = ddcWidthmm;
- pScrn->heightmm = ddcHeightmm;
- if (pScrn->widthmm > 0) {
- pScrn->xDpi =
- (int)((double)pScrn->virtualX * MMPERINCH / pScrn->widthmm);
- }
- if (pScrn->heightmm > 0) {
- pScrn->yDpi =
- (int)((double)pScrn->virtualY * MMPERINCH / pScrn->heightmm);
- }
- if (pScrn->xDpi > 0 && pScrn->yDpi <= 0)
- pScrn->yDpi = pScrn->xDpi;
- if (pScrn->yDpi > 0 && pScrn->xDpi <= 0)
- pScrn->xDpi = pScrn->yDpi;
- } else {
- if (x > 0)
- pScrn->xDpi = x;
- else
- pScrn->xDpi = DEFAULT_DPI;
- if (y > 0)
- pScrn->yDpi = y;
- else
- pScrn->yDpi = DEFAULT_DPI;
- }
- xf86DrvMsg(pScrn->scrnIndex, from, "DPI set to (%d, %d)\n",
- pScrn->xDpi, pScrn->yDpi);
-}
-
-#undef MMPERINCH
-
-
-void
-xf86SetBlackWhitePixels(ScreenPtr pScreen)
-{
- if (xf86FlipPixels) {
- pScreen->whitePixel = 0;
- pScreen->blackPixel = 1;
- } else {
- pScreen->whitePixel = 1;
- pScreen->blackPixel = 0;
- }
-}
-
-/*
- * xf86SetRootClip --
- * Enable or disable rendering to the screen by
- * setting the root clip list and revalidating
- * all of the windows
- */
-
-static void
-xf86SetRootClip (ScreenPtr pScreen, Bool enable)
-{
- WindowPtr pWin = WindowTable[pScreen->myNum];
- WindowPtr pChild;
- Bool WasViewable = (Bool)(pWin->viewable);
- Bool anyMarked = FALSE;
- WindowPtr pLayerWin;
- BoxRec box;
-
- if (WasViewable)
- {
- for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
- {
- (void) (*pScreen->MarkOverlappedWindows)(pChild,
- pChild,
- &pLayerWin);
- }
- (*pScreen->MarkWindow) (pWin);
- anyMarked = TRUE;
- if (pWin->valdata)
- {
- if (HasBorder (pWin))
- {
- RegionPtr borderVisible;
-
- borderVisible = REGION_CREATE(pScreen, NullBox, 1);
- REGION_SUBTRACT(pScreen, borderVisible,
- &pWin->borderClip, &pWin->winSize);
- pWin->valdata->before.borderVisible = borderVisible;
- }
- pWin->valdata->before.resized = TRUE;
- }
- }
-
- /*
- * Use REGION_BREAK to avoid optimizations in ValidateTree
- * that assume the root borderClip can't change well, normally
- * it doesn't...)
- */
- if (enable)
- {
- box.x1 = 0;
- box.y1 = 0;
- box.x2 = pScreen->width;
- box.y2 = pScreen->height;
- REGION_INIT (pScreen, &pWin->winSize, &box, 1);
- REGION_INIT (pScreen, &pWin->borderSize, &box, 1);
- if (WasViewable)
- REGION_RESET(pScreen, &pWin->borderClip, &box);
- pWin->drawable.width = pScreen->width;
- pWin->drawable.height = pScreen->height;
- REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
- }
- else
- {
- REGION_EMPTY(pScreen, &pWin->borderClip);
- REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
- }
-
- ResizeChildrenWinSize (pWin, 0, 0, 0, 0);
-
- if (WasViewable)
- {
- if (pWin->firstChild)
- {
- anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin->firstChild,
- pWin->firstChild,
- (WindowPtr *)NULL);
- }
- else
- {
- (*pScreen->MarkWindow) (pWin);
- anyMarked = TRUE;
- }
-
-
- if (anyMarked)
- (*pScreen->ValidateTree)(pWin, NullWindow, VTOther);
- }
-
- if (WasViewable)
- {
- if (anyMarked)
- (*pScreen->HandleExposures)(pWin);
- if (anyMarked && pScreen->PostValidateTree)
- (*pScreen->PostValidateTree)(pWin, NullWindow, VTOther);
- }
- if (pWin->realized)
- WindowsRestructured ();
- FlushAllOutput ();
-}
-
-/*
- * Function to enable/disable access to the frame buffer
- *
- * This is used when VT switching and when entering/leaving DGA direct mode.
- *
- * This has been rewritten again to eliminate the saved pixmap. The
- * devPrivate field in the screen pixmap is set to NULL to catch code
- * accidentally referencing the frame buffer while the X server is not
- * supposed to touch it.
- *
- * Here, we exchange the pixmap private data, rather than the pixmaps
- * themselves to avoid having to find and change any references to the screen
- * pixmap such as GC's, window privates etc. This also means that this code
- * does not need to know exactly how the pixmap pixels are accessed. Further,
- * this exchange is >not< done through the screen's ModifyPixmapHeader()
- * vector. This means the called frame buffer code layers can determine
- * whether they are switched in or out by keeping track of the root pixmap's
- * private data, and therefore don't need to access pScrnInfo->vtSema.
- */
-void
-xf86EnableDisableFBAccess(int scrnIndex, Bool enable)
-{
- ScrnInfoPtr pScrnInfo = xf86Screens[scrnIndex];
- ScreenPtr pScreen = pScrnInfo->pScreen;
- PixmapPtr pspix;
-
- pspix = (*pScreen->GetScreenPixmap) (pScreen);
- if (enable)
- {
- /*
- * Restore the screen pixmap devPrivate field
- */
- pspix->devPrivate = pScrnInfo->pixmapPrivate;
- /*
- * Restore all of the clip lists on the screen
- */
- if (!xf86Resetting)
- xf86SetRootClip (pScreen, TRUE);
-
- }
- else
- {
- /*
- * Empty all of the clip lists on the screen
- */
- xf86SetRootClip (pScreen, FALSE);
- /*
- * save the screen pixmap devPrivate field and
- * replace it with NULL so accidental references
- * to the frame buffer are caught
- */
- pScrnInfo->pixmapPrivate = pspix->devPrivate;
- pspix->devPrivate.ptr = NULL;
- }
-}
-
-/* Print driver messages in the standard format */
-
-#undef PREFIX_SIZE
-#define PREFIX_SIZE 14
-
-void
-xf86VDrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format,
- va_list args)
-{
- char *tmpFormat;
-
- /* Prefix the scrnIndex name to the format string. */
- if (scrnIndex >= 0 && scrnIndex < xf86NumScreens &&
- xf86Screens[scrnIndex]->name) {
- tmpFormat = xalloc(strlen(format) +
- strlen(xf86Screens[scrnIndex]->name) +
- PREFIX_SIZE + 1);
- if (!tmpFormat)
- return;
-
- snprintf(tmpFormat, PREFIX_SIZE + 1, "%s(%d): ",
- xf86Screens[scrnIndex]->name, scrnIndex);
-
- strcat(tmpFormat, format);
- LogVMessageVerb(type, verb, tmpFormat, args);
- xfree(tmpFormat);
- } else
- LogVMessageVerb(type, verb, format, args);
-}
-#undef PREFIX_SIZE
-
-/* Print driver messages, with verbose level specified directly */
-void
-xf86DrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format,
- ...)
-{
- va_list ap;
-
- va_start(ap, format);
- xf86VDrvMsgVerb(scrnIndex, type, verb, format, ap);
- va_end(ap);
-}
-
-/* Print driver messages, with verbose level of 1 (default) */
-void
-xf86DrvMsg(int scrnIndex, MessageType type, const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- xf86VDrvMsgVerb(scrnIndex, type, 1, format, ap);
- va_end(ap);
-}
-
-/* Print non-driver messages with verbose level specified directly */
-void
-xf86MsgVerb(MessageType type, int verb, const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- xf86VDrvMsgVerb(-1, type, verb, format, ap);
- va_end(ap);
-}
-
-/* Print non-driver messages with verbose level of 1 (default) */
-void
-xf86Msg(MessageType type, const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- xf86VDrvMsgVerb(-1, type, 1, format, ap);
- va_end(ap);
-}
-
-/* Just like ErrorF, but with the verbose level checked */
-void
-xf86ErrorFVerb(int verb, const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- if (xf86Verbose >= verb || xf86LogVerbose >= verb)
- LogVWrite(verb, format, ap);
- va_end(ap);
-}
-
-/* Like xf86ErrorFVerb, but with an implied verbose level of 1 */
-void
-xf86ErrorF(const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- if (xf86Verbose >= 1 || xf86LogVerbose >= 1)
- LogVWrite(1, format, ap);
- va_end(ap);
-}
-
-
-void
-xf86LogInit(void)
-{
- char *lf = NULL;
-
-#define LOGSUFFIX ".log"
-#define LOGOLDSUFFIX ".old"
-
- /* Get the log file name */
- if (xf86LogFileFrom == X_DEFAULT) {
- /* Append the display number and ".log" */
- lf = malloc(strlen(xf86LogFile) + strlen("%s") +
- strlen(LOGSUFFIX) + 1);
- if (!lf)
- FatalError("Cannot allocate space for the log file name\n");
- sprintf(lf, "%s%%s" LOGSUFFIX, xf86LogFile);
- xf86LogFile = lf;
- }
-
- xf86LogFile = LogInit(xf86LogFile, LOGOLDSUFFIX);
- xf86LogFileWasOpened = TRUE;
-
- xf86SetVerbosity(xf86Verbose);
- xf86SetLogVerbosity(xf86LogVerbose);
-
-#undef LOGSUFFIX
-#undef LOGOLDSUFFIX
-
- free(lf);
-}
-
-void
-xf86CloseLog(void)
-{
- LogClose();
-}
-
-
-/*
- * Drivers can use these for using their own SymTabRecs.
- */
-
-const char *
-xf86TokenToString(SymTabPtr table, int token)
-{
- int i;
-
- for (i = 0; table[i].token >= 0 && table[i].token != token; i++)
- ;
-
- if (table[i].token < 0)
- return NULL;
- else
- return(table[i].name);
-}
-
-int
-xf86StringToToken(SymTabPtr table, const char *string)
-{
- int i;
-
- if (string == NULL)
- return -1;
-
- for (i = 0; table[i].token >= 0 && xf86NameCmp(string, table[i].name); i++)
- ;
-
- return(table[i].token);
-}
-
-/*
- * helper to display the clocks found on a card
- */
-void
-xf86ShowClocks(ScrnInfoPtr scrp, MessageType from)
-{
- int j;
-
- xf86DrvMsg(scrp->scrnIndex, from, "Pixel clocks available:");
- for (j=0; j < scrp->numClocks; j++) {
- if ((j % 4) == 0) {
- xf86ErrorF("\n");
- xf86DrvMsg(scrp->scrnIndex, from, "pixel clocks:");
- }
- xf86ErrorF(" %7.3f", (double)scrp->clock[j] / 1000.0);
- }
- xf86ErrorF("\n");
-}
-
-
-/*
- * This prints out the driver identify message, including the names of
- * the supported chipsets.
- *
- * XXX This makes assumptions about the line width, etc. Maybe we could
- * use a more general "pretty print" function for messages.
- */
-void
-xf86PrintChipsets(const char *drvname, const char *drvmsg, SymTabPtr chips)
-{
- int len, i;
-
- len = 6 + strlen(drvname) + 2 + strlen(drvmsg) + 2;
- xf86Msg(X_INFO, "%s: %s:", drvname, drvmsg);
- for (i = 0; chips[i].name != NULL; i++) {
- if (i != 0) {
- xf86ErrorF(",");
- len++;
- }
- if (len + 2 + strlen(chips[i].name) < 78) {
- xf86ErrorF(" ");
- len++;
- } else {
- xf86ErrorF("\n\t");
- len = 8;
- }
- xf86ErrorF("%s", chips[i].name);
- len += strlen(chips[i].name);
- }
- xf86ErrorF("\n");
-}
-
-
-int
-xf86MatchDevice(const char *drivername, GDevPtr **sectlist)
-{
- GDevPtr gdp, *pgdp = NULL;
- confScreenPtr screensecptr;
- int i,j;
-
- if (sectlist)
- *sectlist = NULL;
-
- if (xf86DoConfigure && xf86DoConfigurePass1) return 1;
-
- /*
- * This is a very important function that matches the device sections
- * as they show up in the config file with the drivers that the server
- * loads at run time.
- *
- * ChipProbe can call
- * int xf86MatchDevice(char * drivername, GDevPtr ** sectlist)
- * with its driver name. The function allocates an array of GDevPtr and
- * returns this via sectlist and returns the number of elements in
- * this list as return value. 0 means none found, -1 means fatal error.
- *
- * It can figure out which of the Device sections to use for which card
- * (using things like the Card statement, etc). For single headed servers
- * there will of course be just one such Device section.
- */
- i = 0;
-
- /*
- * first we need to loop over all the Screens sections to get to all
- * 'active' device sections
- */
- for (j=0; xf86ConfigLayout.screens[j].screen != NULL; j++) {
- screensecptr = xf86ConfigLayout.screens[j].screen;
- if ((screensecptr->device->driver != NULL)
- && (xf86NameCmp( screensecptr->device->driver,drivername) == 0)
- && (! screensecptr->device->claimed)) {
- /*
- * we have a matching driver that wasn't claimed, yet
- */
- pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr));
- pgdp[i++] = screensecptr->device;
- }
- }
-
- /* Then handle the inactive devices */
- j = 0;
- while (xf86ConfigLayout.inactives[j].identifier) {
- gdp = &xf86ConfigLayout.inactives[j];
- if (gdp->driver && !gdp->claimed &&
- !xf86NameCmp(gdp->driver,drivername)) {
- /* we have a matching driver that wasn't claimed yet */
- pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr));
- pgdp[i++] = gdp;
- }
- j++;
- }
-
- /*
- * make the array NULL terminated and return its address
- */
- if (i)
- pgdp[i] = NULL;
-
- if (sectlist)
- *sectlist = pgdp;
- else
- xfree(pgdp);
- return i;
-}
-
-static Bool
-pciDeviceHasBars(struct pci_device *pci)
-{
- int i;
-
- for (i = 0; i < 6; i++)
- if (pci->regions[i].size)
- return TRUE;
-
- if (pci->rom_size)
- return TRUE;
-
- return FALSE;
-}
-
-struct Inst {
- struct pci_device * pci;
- GDevPtr dev;
- Bool foundHW; /* PCIid in list of supported chipsets */
- Bool claimed; /* BusID matches with a device section */
- int chip;
- int screen;
-};
-
-
-/**
- * Find set of unclaimed devices matching a given vendor ID.
- *
- * Used by drivers to find as yet unclaimed devices matching the specified
- * vendor ID.
- *
- * \param driverName Name of the driver. This is used to find Device
- * sections in the config file.
- * \param vendorID PCI vendor ID of associated devices. If zero, then
- * the true vendor ID must be encoded in the \c PCIid
- * fields of the \c PCIchipsets entries.
- * \param chipsets Symbol table used to associate chipset names with
- * PCI IDs.
- * \param devList List of Device sections parsed from the config file.
- * \param numDevs Number of entries in \c devList.
- * \param drvp Pointer the driver's control structure.
- * \param foundEntities Returned list of entity indicies associated with the
- * driver.
- *
- * \returns
- * The number of elements in returned in \c foundEntities on success or zero
- * on failure.
- *
- * \todo
- * This function does a bit more than short description says. Fill in some
- * more of the details of its operation.
- *
- * \todo
- * The \c driverName parameter is redundant. It is the same as
- * \c DriverRec::driverName. In a future version of this function, remove
- * that parameter.
- */
-int
-xf86MatchPciInstances(const char *driverName, int vendorID,
- SymTabPtr chipsets, PciChipsets *PCIchipsets,
- GDevPtr *devList, int numDevs, DriverPtr drvp,
- int **foundEntities)
-{
- int i,j;
- struct pci_device * pPci;
- struct pci_device_iterator *iter;
- struct Inst *instances = NULL;
- int numClaimedInstances = 0;
- int allocatedInstances = 0;
- int numFound = 0;
- SymTabRec *c;
- PciChipsets *id;
- int *retEntities = NULL;
-
- *foundEntities = NULL;
-
-
- /* Each PCI device will contribute at least one entry. Each device
- * section can contribute at most one entry. The sum of the two is
- * guaranteed to be larger than the maximum possible number of entries.
- * Do this calculation and memory allocation once now to eliminate the
- * need for realloc calls inside the loop.
- */
- if (!(xf86DoConfigure && xf86DoConfigurePass1)) {
- unsigned max_entries = numDevs;
-
- iter = pci_slot_match_iterator_create(NULL);
- while ((pPci = pci_device_next(iter)) != NULL) {
- max_entries++;
- }
-
- pci_iterator_destroy(iter);
- instances = xnfalloc(max_entries * sizeof(struct Inst));
- }
-
- iter = pci_slot_match_iterator_create(NULL);
- while ((pPci = pci_device_next(iter)) != NULL) {
- unsigned device_class = pPci->device_class;
- Bool foundVendor = FALSE;
-
-
- /* Convert the pre-PCI 2.0 device class for a VGA adapter to the
- * 2.0 version of the same class.
- */
- if ( device_class == 0x00000101 ) {
- device_class = 0x00030000;
- }
-
-
- /* Find PCI devices that match the given vendor ID. The vendor ID is
- * either specified explicitly as a parameter to the function or
- * implicitly encoded in the high bits of id->PCIid.
- *
- * The first device with a matching vendor is recorded, even if the
- * device ID doesn't match. This is done because the Device section
- * in the xorg.conf file can over-ride the device ID. A matching PCI
- * ID might not be found now, but after the device ID over-ride is
- * applied there /might/ be a match.
- */
- for (id = PCIchipsets; id->PCIid != -1; id++) {
- const unsigned vendor_id = ((id->PCIid & 0xFFFF0000) >> 16)
- | vendorID;
- const unsigned device_id = (id->PCIid & 0x0000FFFF);
- const unsigned match_class = 0x00030000 | id->PCIid;
-
- if ((vendor_id == pPci->vendor_id)
- || ((vendorID == PCI_VENDOR_GENERIC) && (match_class == device_class))) {
- if (!foundVendor && (instances != NULL)) {
- ++allocatedInstances;
- instances[allocatedInstances - 1].pci = pPci;
- instances[allocatedInstances - 1].dev = NULL;
- instances[allocatedInstances - 1].claimed = FALSE;
- instances[allocatedInstances - 1].foundHW = FALSE;
- instances[allocatedInstances - 1].screen = 0;
- }
-
- foundVendor = TRUE;
-
- if ( (device_id == pPci->device_id)
- || ((vendorID == PCI_VENDOR_GENERIC)
- && (match_class == device_class)) ) {
- if ( instances != NULL ) {
- instances[allocatedInstances - 1].foundHW = TRUE;
- instances[allocatedInstances - 1].chip = id->numChipset;
- }
-
-
- if ( xf86DoConfigure && xf86DoConfigurePass1 ) {
- if (xf86CheckPciSlot(pPci)) {
- GDevPtr pGDev =
- xf86AddBusDeviceToConfigure(drvp->driverName,
- BUS_PCI, pPci, -1);
- if (pGDev) {
- /* After configure pass 1, chipID and chipRev
- * are treated as over-rides, so clobber them
- * here.
- */
- pGDev->chipID = -1;
- pGDev->chipRev = -1;
- }
-
- numFound++;
- }
- }
- else {
- numFound++;
- }
-
- break;
- }
- }
- }
- }
-
- pci_iterator_destroy(iter);
-
-
- /* In "probe only" or "configure" mode (signaled by instances being NULL),
- * our work is done. Return the number of detected devices.
- */
- if ( instances == NULL ) {
- return numFound;
- }
-
-
- /*
- * This may be debatable, but if no PCI devices with a matching vendor
- * type is found, return zero now. It is probably not desirable to
- * allow the config file to override this.
- */
- if (allocatedInstances <= 0) {
- xfree(instances);
- return 0;
- }
-
-
- DebugF("%s instances found: %d\n", driverName, allocatedInstances);
-
- /*
- * Check for devices that need duplicated instances. This is required
- * when there is more than one screen per entity.
- *
- * XXX This currently doesn't work for cases where the BusID isn't
- * specified explicitly in the config file.
- */
-
- for (j = 0; j < numDevs; j++) {
- if (devList[j]->screen > 0 && devList[j]->busID
- && *devList[j]->busID) {
- for (i = 0; i < allocatedInstances; i++) {
- pPci = instances[i].pci;
- if (xf86ComparePciBusString(devList[j]->busID,
- PCI_MAKE_BUS( pPci->domain, pPci->bus ),
- pPci->dev,
- pPci->func)) {
- allocatedInstances++;
- instances[allocatedInstances - 1] = instances[i];
- instances[allocatedInstances - 1].screen =
- devList[j]->screen;
- numFound++;
- break;
- }
- }
- }
- }
-
- for (i = 0; i < allocatedInstances; i++) {
- GDevPtr dev = NULL;
- GDevPtr devBus = NULL;
-
- pPci = instances[i].pci;
- for (j = 0; j < numDevs; j++) {
- if (devList[j]->busID && *devList[j]->busID) {
- if (xf86ComparePciBusString(devList[j]->busID,
- PCI_MAKE_BUS( pPci->domain, pPci->bus ),
- pPci->dev,
- pPci->func) &&
- devList[j]->screen == instances[i].screen) {
-
- if (devBus)
- xf86MsgVerb(X_WARNING,0,
- "%s: More than one matching Device section for "
- "instances\n\t(BusID: %s) found: %s\n",
- driverName, devList[j]->busID,
- devList[j]->identifier);
- else
- devBus = devList[j];
- }
- } else {
- /*
- * if device section without BusID is found
- * only assign to it to the primary device.
- */
- if (xf86IsPrimaryPci(pPci)) {
- xf86Msg(X_PROBED, "Assigning device section with no busID"
- " to primary device\n");
- if (dev || devBus)
- xf86MsgVerb(X_WARNING, 0,
- "%s: More than one matching Device section "
- "found: %s\n", driverName, devList[j]->identifier);
- else
- dev = devList[j];
- }
- }
- }
- if (devBus) dev = devBus; /* busID preferred */
- if (!dev) {
- if (xf86CheckPciSlot(pPci) && pciDeviceHasBars(pPci)) {
- xf86MsgVerb(X_WARNING, 0, "%s: No matching Device section "
- "for instance (BusID PCI:%u@%u:%u:%u) found\n",
- driverName, pPci->domain, pPci->bus, pPci->dev,
- pPci->func);
- }
- } else {
- numClaimedInstances++;
- instances[i].claimed = TRUE;
- instances[i].dev = dev;
- }
- }
- DebugF("%s instances found: %d\n", driverName, numClaimedInstances);
- /*
- * Now check that a chipset or chipID override in the device section
- * is valid. Chipset has precedence over chipID.
- * If chipset is not valid ignore BusSlot completely.
- */
- for (i = 0; i < allocatedInstances && numClaimedInstances > 0; i++) {
- MessageType from = X_PROBED;
-
- if (!instances[i].claimed) {
- continue;
- }
- if (instances[i].dev->chipset) {
- for (c = chipsets; c->token >= 0; c++) {
- if (xf86NameCmp(c->name, instances[i].dev->chipset) == 0)
- break;
- }
- if (c->token == -1) {
- instances[i].claimed = FALSE;
- numClaimedInstances--;
- xf86MsgVerb(X_WARNING, 0, "%s: Chipset \"%s\" in Device "
- "section \"%s\" isn't valid for this driver\n",
- driverName, instances[i].dev->chipset,
- instances[i].dev->identifier);
- } else {
- instances[i].chip = c->token;
-
- for (id = PCIchipsets; id->numChipset >= 0; id++) {
- if (id->numChipset == instances[i].chip)
- break;
- }
- if(id->numChipset >=0){
- xf86Msg(X_CONFIG,"Chipset override: %s\n",
- instances[i].dev->chipset);
- from = X_CONFIG;
- } else {
- instances[i].claimed = FALSE;
- numClaimedInstances--;
- xf86MsgVerb(X_WARNING, 0, "%s: Chipset \"%s\" in Device "
- "section \"%s\" isn't a valid PCI chipset\n",
- driverName, instances[i].dev->chipset,
- instances[i].dev->identifier);
- }
- }
- } else if (instances[i].dev->chipID > 0) {
- for (id = PCIchipsets; id->numChipset >= 0; id++) {
- if (id->PCIid == instances[i].dev->chipID)
- break;
- }
- if (id->numChipset == -1) {
- instances[i].claimed = FALSE;
- numClaimedInstances--;
- xf86MsgVerb(X_WARNING, 0, "%s: ChipID 0x%04X in Device "
- "section \"%s\" isn't valid for this driver\n",
- driverName, instances[i].dev->chipID,
- instances[i].dev->identifier);
- } else {
- instances[i].chip = id->numChipset;
-
- xf86Msg( X_CONFIG,"ChipID override: 0x%04X\n",
- instances[i].dev->chipID);
- from = X_CONFIG;
- }
- } else if (!instances[i].foundHW) {
- /*
- * This means that there was no override and the PCI chipType
- * doesn't match one that is supported
- */
- instances[i].claimed = FALSE;
- numClaimedInstances--;
- }
- if (instances[i].claimed == TRUE){
- for (c = chipsets; c->token >= 0; c++) {
- if (c->token == instances[i].chip)
- break;
- }
- xf86Msg(from,"Chipset %s found\n",
- c->name);
- }
- }
-
- /*
- * Of the claimed instances, check that another driver hasn't already
- * claimed its slot.
- */
- numFound = 0;
- for (i = 0; i < allocatedInstances && numClaimedInstances > 0; i++) {
-
- if (!instances[i].claimed)
- continue;
- pPci = instances[i].pci;
-
-
- /*
- * Allow the same entity to be used more than once for devices with
- * multiple screens per entity. This assumes implicitly that there
- * will be a screen == 0 instance.
- *
- * XXX Need to make sure that two different drivers don't claim
- * the same screen > 0 instance.
- */
- if (instances[i].screen == 0 && !xf86CheckPciSlot( pPci ))
- continue;
-
- DebugF("%s: card at %d:%d:%d is claimed by a Device section\n",
- driverName, pPci->bus, pPci->dev, pPci->func);
-
- /* Allocate an entry in the lists to be returned */
- numFound++;
- retEntities = xnfrealloc(retEntities, numFound * sizeof(int));
- retEntities[numFound - 1] = xf86ClaimPciSlot( pPci, drvp,
- instances[i].chip,
- instances[i].dev,
- instances[i].dev->active);
- if (retEntities[numFound - 1] == -1 && instances[i].screen > 0) {
- for (j = 0; j < xf86NumEntities; j++) {
- EntityPtr pEnt = xf86Entities[j];
- if (pEnt->bus.type != BUS_PCI)
- continue;
- if (pEnt->bus.id.pci == pPci) {
- retEntities[numFound - 1] = j;
- xf86AddDevToEntity(j, instances[i].dev);
- break;
- }
- }
- }
- }
- xfree(instances);
- if (numFound > 0) {
- *foundEntities = retEntities;
- }
-
- return numFound;
-}
-
-/*
- * xf86GetClocks -- get the dot-clocks via a BIG BAD hack ...
- */
-void
-xf86GetClocks(ScrnInfoPtr pScrn, int num, Bool (*ClockFunc)(ScrnInfoPtr, int),
- void (*ProtectRegs)(ScrnInfoPtr, Bool),
- void (*BlankScreen)(ScrnInfoPtr, Bool), IOADDRESS vertsyncreg,
- int maskval, int knownclkindex, int knownclkvalue)
-{
- register int status = vertsyncreg;
- unsigned long i, cnt, rcnt, sync;
-
- /* First save registers that get written on */
- (*ClockFunc)(pScrn, CLK_REG_SAVE);
-
- if (num > MAXCLOCKS)
- num = MAXCLOCKS;
-
- for (i = 0; i < num; i++)
- {
- if (ProtectRegs)
- (*ProtectRegs)(pScrn, TRUE);
- if (!(*ClockFunc)(pScrn, i))
- {
- pScrn->clock[i] = -1;
- continue;
- }
- if (ProtectRegs)
- (*ProtectRegs)(pScrn, FALSE);
- if (BlankScreen)
- (*BlankScreen)(pScrn, FALSE);
-
- usleep(50000); /* let VCO stabilise */
-
- cnt = 0;
- sync = 200000;
-
- while ((inb(status) & maskval) == 0x00)
- if (sync-- == 0) goto finish;
- /* Something appears to be happening, so reset sync count */
- sync = 200000;
- while ((inb(status) & maskval) == maskval)
- if (sync-- == 0) goto finish;
- /* Something appears to be happening, so reset sync count */
- sync = 200000;
- while ((inb(status) & maskval) == 0x00)
- if (sync-- == 0) goto finish;
-
- for (rcnt = 0; rcnt < 5; rcnt++)
- {
- while (!(inb(status) & maskval))
- cnt++;
- while ((inb(status) & maskval))
- cnt++;
- }
-
-finish:
- pScrn->clock[i] = cnt ? cnt : -1;
- if (BlankScreen)
- (*BlankScreen)(pScrn, TRUE);
- }
-
- for (i = 0; i < num; i++)
- {
- if (i != knownclkindex)
- {
- if (pScrn->clock[i] == -1)
- {
- pScrn->clock[i] = 0;
- }
- else
- {
- pScrn->clock[i] = (int)(0.5 +
- (((float)knownclkvalue) * pScrn->clock[knownclkindex]) /
- (pScrn->clock[i]));
- /* Round to nearest 10KHz */
- pScrn->clock[i] += 5;
- pScrn->clock[i] /= 10;
- pScrn->clock[i] *= 10;
- }
- }
- }
-
- pScrn->clock[knownclkindex] = knownclkvalue;
- pScrn->numClocks = num;
-
- /* Restore registers that were written on */
- (*ClockFunc)(pScrn, CLK_REG_RESTORE);
-}
-
-const char *
-xf86GetVisualName(int visual)
-{
- if (visual < 0 || visual > DirectColor)
- return NULL;
-
- return xf86VisualNames[visual];
-}
-
-
-int
-xf86GetVerbosity(void)
-{
- return max(xf86Verbose, xf86LogVerbose);
-}
-
-Pix24Flags
-xf86GetPix24(void)
-{
- return xf86Info.pixmap24;
-}
-
-
-int
-xf86GetDepth(void)
-{
- return xf86Depth;
-}
-
-
-rgb
-xf86GetWeight(void)
-{
- return xf86Weight;
-}
-
-
-Gamma
-xf86GetGamma(void)
-{
- return xf86Gamma;
-}
-
-
-Bool
-xf86GetFlipPixels(void)
-{
- return xf86FlipPixels;
-}
-
-
-const char *
-xf86GetServerName(void)
-{
- return xf86ServerName;
-}
-
-
-Bool
-xf86ServerIsExiting(void)
-{
- return (dispatchException & DE_TERMINATE) == DE_TERMINATE;
-}
-
-
-Bool
-xf86ServerIsResetting(void)
-{
- return xf86Resetting;
-}
-
-
-Bool
-xf86ServerIsInitialising(void)
-{
- return xf86Initialising;
-}
-
-
-Bool
-xf86ServerIsOnlyDetecting(void)
-{
- return xf86DoConfigure;
-}
-
-
-Bool
-xf86CaughtSignal(void)
-{
- return xf86Info.caughtSignal;
-}
-
-
-Bool
-xf86GetVidModeAllowNonLocal(void)
-{
- return xf86Info.vidModeAllowNonLocal;
-}
-
-
-Bool
-xf86GetVidModeEnabled(void)
-{
- return xf86Info.vidModeEnabled;
-}
-
-Bool
-xf86GetModInDevAllowNonLocal(void)
-{
- return xf86Info.miscModInDevAllowNonLocal;
-}
-
-
-Bool
-xf86GetModInDevEnabled(void)
-{
- return xf86Info.miscModInDevEnabled;
-}
-
-
-Bool
-xf86GetAllowMouseOpenFail(void)
-{
- return xf86Info.allowMouseOpenFail;
-}
-
-
-Bool
-xf86IsPc98(void)
-{
-#if SUPPORT_PC98
- return xf86Info.pc98;
-#else
- return FALSE;
-#endif
-}
-
-void
-xf86DisableRandR(void)
-{
- xf86Info.disableRandR = TRUE;
- xf86Info.randRFrom = X_PROBED;
-}
-
-CARD32
-xf86GetModuleVersion(pointer module)
-{
- return (CARD32)LoaderGetModuleVersion(module);
-}
-
-pointer
-xf86LoadDrvSubModule(DriverPtr drv, const char *name)
-{
- pointer ret;
- int errmaj = 0, errmin = 0;
-
- ret = LoadSubModule(drv->module, name, NULL, NULL, NULL, NULL,
- &errmaj, &errmin);
- if (!ret)
- LoaderErrorMsg(NULL, name, errmaj, errmin);
- return ret;
-}
-
-pointer
-xf86LoadSubModule(ScrnInfoPtr pScrn, const char *name)
-{
- pointer ret;
- int errmaj = 0, errmin = 0;
-
- ret = LoadSubModule(pScrn->module, name, NULL, NULL, NULL, NULL,
- &errmaj, &errmin);
- if (!ret)
- LoaderErrorMsg(pScrn->name, name, errmaj, errmin);
- return ret;
-}
-
-/*
- * xf86LoadOneModule loads a single module.
- */
-pointer
-xf86LoadOneModule(char *name, pointer opt)
-{
- int errmaj, errmin;
- char *Name;
- pointer mod;
-
- if (!name)
- return NULL;
-
- /* Normalise the module name */
- Name = xf86NormalizeName(name);
-
- /* Skip empty names */
- if (Name == NULL)
- return NULL;
- if (*Name == '\0') {
- xfree(Name);
- return NULL;
- }
-
- mod = LoadModule(Name, NULL, NULL, NULL, opt, NULL, &errmaj, &errmin);
- if (!mod)
- LoaderErrorMsg(NULL, Name, errmaj, errmin);
- xfree(Name);
- return mod;
-}
-
-void
-xf86UnloadSubModule(pointer mod)
-{
- /*
- * This is disabled for now. The loader isn't smart enough yet to undo
- * relocations.
- */
-#if 0
- UnloadSubModule(mod);
-#endif
-}
-
-Bool
-xf86LoaderCheckSymbol(const char *name)
-{
- return LoaderSymbol(name) != NULL;
-}
-
-typedef enum {
- OPTION_BACKING_STORE
-} BSOpts;
-
-static const OptionInfoRec BSOptions[] = {
- { OPTION_BACKING_STORE, "BackingStore", OPTV_BOOLEAN, {0}, FALSE },
- { -1, NULL, OPTV_NONE, {0}, FALSE }
-};
-
-void
-xf86SetBackingStore(ScreenPtr pScreen)
-{
- Bool useBS = FALSE;
- MessageType from = X_DEFAULT;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- OptionInfoPtr options;
-
- options = xnfalloc(sizeof(BSOptions));
- (void)memcpy(options, BSOptions, sizeof(BSOptions));
- xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
-
- /* check for commandline option here */
- if (xf86bsEnableFlag) {
- from = X_CMDLINE;
- useBS = TRUE;
- } else if (xf86bsDisableFlag) {
- from = X_CMDLINE;
- useBS = FALSE;
- } else {
- if (xf86GetOptValBool(options, OPTION_BACKING_STORE, &useBS))
- from = X_CONFIG;
- }
- xfree(options);
- pScreen->backingStoreSupport = useBS ? Always : NotUseful;
- if (serverGeneration == 1)
- xf86DrvMsg(pScreen->myNum, from, "Backing store %s\n",
- useBS ? "enabled" : "disabled");
-}
-
-
-typedef enum {
- OPTION_SILKEN_MOUSE
-} SMOpts;
-
-static const OptionInfoRec SMOptions[] = {
- { OPTION_SILKEN_MOUSE, "SilkenMouse", OPTV_BOOLEAN, {0}, FALSE },
- { -1, NULL, OPTV_NONE, {0}, FALSE }
-};
-
-void
-xf86SetSilkenMouse (ScreenPtr pScreen)
-{
- Bool useSM = TRUE;
- MessageType from = X_DEFAULT;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- OptionInfoPtr options;
-
- options = xnfalloc(sizeof(SMOptions));
- (void)memcpy(options, SMOptions, sizeof(SMOptions));
- xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
-
- /* check for commandline option here */
- /* disable if screen shares resources */
- /* TODO VGA arb disable silken mouse */
- if (xf86silkenMouseDisableFlag) {
- from = X_CMDLINE;
- useSM = FALSE;
- } else {
- if (xf86GetOptValBool(options, OPTION_SILKEN_MOUSE, &useSM))
- from = X_CONFIG;
- }
- xfree(options);
- /*
- * XXX quick hack to report correctly for OSs that can't do SilkenMouse
- * yet. Should handle this differently so that alternate async methods
- * work correctly with this too.
- */
- pScrn->silkenMouse = useSM && xf86Info.useSIGIO && xf86SIGIOSupported();
- if (serverGeneration == 1)
- xf86DrvMsg(pScreen->myNum, from, "Silken mouse %s\n",
- pScrn->silkenMouse ? "enabled" : "disabled");
-}
-
-/* Wrote this function for the PM2 Xv driver, preliminary. */
-
-pointer
-xf86FindXvOptions(int scrnIndex, int adaptor_index, char *port_name,
- char **adaptor_name, pointer *adaptor_options)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- confXvAdaptorPtr adaptor;
- int i;
-
- if (adaptor_index >= pScrn->confScreen->numxvadaptors) {
- if (adaptor_name) *adaptor_name = NULL;
- if (adaptor_options) *adaptor_options = NULL;
- return NULL;
- }
-
- adaptor = &pScrn->confScreen->xvadaptors[adaptor_index];
- if (adaptor_name) *adaptor_name = adaptor->identifier;
- if (adaptor_options) *adaptor_options = adaptor->options;
-
- for (i = 0; i < adaptor->numports; i++)
- if (!xf86NameCmp(adaptor->ports[i].identifier, port_name))
- return adaptor->ports[i].options;
-
- return NULL;
-}
-
-/* Rather than duplicate loader's get OS function, just include it directly */
-#define LoaderGetOS xf86GetOS
-#include "loader/os.c"
-
-/* new RAC */
-/*
- * xf86ConfigPciEntityInactive() -- This function can be used
- * to configure an inactive entity as well as to reconfigure an
- * previously active entity inactive. If the entity has been
- * assigned to a screen before it will be removed. If p_chip is
- * non-NULL all static resources listed there will be registered.
- */
-static void
-xf86ConfigPciEntityInactive(EntityInfoPtr pEnt, PciChipsets *p_chip,
- EntityProc init, EntityProc enter,
- EntityProc leave, pointer private)
-{
- ScrnInfoPtr pScrn;
-
- if ((pScrn = xf86FindScreenForEntity(pEnt->index)))
- xf86RemoveEntityFromScreen(pScrn,pEnt->index);
-
- /* shared resources are only needed when entity is active: remove */
- xf86SetEntityFuncs(pEnt->index,init,enter,leave,private);
-}
-
-static void
-xf86ConfigFbEntityInactive(EntityInfoPtr pEnt, EntityProc init,
- EntityProc enter, EntityProc leave, pointer private)
-{
- ScrnInfoPtr pScrn;
-
- if ((pScrn = xf86FindScreenForEntity(pEnt->index)))
- xf86RemoveEntityFromScreen(pScrn,pEnt->index);
- xf86SetEntityFuncs(pEnt->index,init,enter,leave,private);
-}
-
-ScrnInfoPtr
-xf86ConfigPciEntity(ScrnInfoPtr pScrn, int scrnFlag, int entityIndex,
- PciChipsets *p_chip, void *dummy, EntityProc init,
- EntityProc enter, EntityProc leave, pointer private)
-{
- EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex);
- if (!pEnt) return pScrn;
-
- if (!(pEnt->location.type == BUS_PCI)
- || !xf86GetPciInfoForEntity(entityIndex)) {
- xfree(pEnt);
- return pScrn;
- }
- if (!pEnt->active) {
- xf86ConfigPciEntityInactive(pEnt, p_chip, init, enter,
- leave, private);
- xfree(pEnt);
- return pScrn;
- }
-
- if (!pScrn)
- pScrn = xf86AllocateScreen(pEnt->driver,scrnFlag);
- if (xf86IsEntitySharable(entityIndex)) {
- xf86SetEntityShared(entityIndex);
- }
- xf86AddEntityToScreen(pScrn,entityIndex);
- if (xf86IsEntityShared(entityIndex)) {
- return pScrn;
- }
- xfree(pEnt);
-
- xf86SetEntityFuncs(entityIndex,init,enter,leave,private);
-
- return pScrn;
-}
-
-ScrnInfoPtr
-xf86ConfigFbEntity(ScrnInfoPtr pScrn, int scrnFlag, int entityIndex,
- EntityProc init, EntityProc enter, EntityProc leave,
- pointer private)
-{
- EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex);
- if (!pEnt) return pScrn;
-
- if (!(pEnt->location.type == BUS_NONE)) {
- xfree(pEnt);
- return pScrn;
- }
-
- if (!pEnt->active) {
- xf86ConfigFbEntityInactive(pEnt, init, enter, leave, private);
- xfree(pEnt);
- return pScrn;
- }
-
- if (!pScrn)
- pScrn = xf86AllocateScreen(pEnt->driver,scrnFlag);
- xf86AddEntityToScreen(pScrn,entityIndex);
-
- xf86SetEntityFuncs(entityIndex,init,enter,leave,private);
-
- return pScrn;
-}
-
-/*
- *
- * OBSOLETE ! xf86ConfigActivePciEntity() is an obsolete function.
- * It is likely to be removed. Don't use!
- */
-
-Bool
-xf86ConfigActivePciEntity(ScrnInfoPtr pScrn, int entityIndex,
- PciChipsets *p_chip, void *dummy, EntityProc init,
- EntityProc enter, EntityProc leave, pointer private)
-{
- EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex);
- if (!pEnt) return FALSE;
-
- if (!pEnt->active || !(pEnt->location.type == BUS_PCI)) {
- xfree(pEnt);
- return FALSE;
- }
- xf86AddEntityToScreen(pScrn,entityIndex);
-
- xfree(pEnt);
- if (!xf86SetEntityFuncs(entityIndex,init,enter,leave,private))
- return FALSE;
-
- return TRUE;
-}
-
-Bool
-xf86IsScreenPrimary(int scrnIndex)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- int i;
-
- for (i=0 ; i < pScrn->numEntities; i++) {
- if (xf86IsEntityPrimary(i))
- return TRUE;
- }
- return FALSE;
-}
-
-int
-xf86RegisterRootWindowProperty(int ScrnIndex, Atom property, Atom type,
- int format, unsigned long len, pointer value )
-{
- RootWinPropPtr pNewProp = NULL, pRegProp;
- int i;
- Bool existing = FALSE;
-
- DebugF("xf86RegisterRootWindowProperty(%d, %ld, %ld, %d, %ld, %p)\n",
- ScrnIndex, property, type, format, len, value);
-
- if (ScrnIndex<0 || ScrnIndex>=xf86NumScreens) {
- return(BadMatch);
- }
-
- if (xf86RegisteredPropertiesTable &&
- xf86RegisteredPropertiesTable[ScrnIndex]) {
- for (pNewProp = xf86RegisteredPropertiesTable[ScrnIndex];
- pNewProp; pNewProp = pNewProp->next) {
- if (strcmp(pNewProp->name, NameForAtom(property)) == 0)
- break;
- }
- }
-
- if (!pNewProp) {
- if ((pNewProp = (RootWinPropPtr)xalloc(sizeof(RootWinProp))) == NULL) {
- return(BadAlloc);
- }
- /*
- * We will put this property at the end of the list so that
- * the changes are made in the order they were requested.
- */
- pNewProp->next = NULL;
- } else {
- if (pNewProp->name)
- xfree(pNewProp->name);
- existing = TRUE;
- }
-
- pNewProp->name = xnfstrdup(NameForAtom(property));
- pNewProp->type = type;
- pNewProp->format = format;
- pNewProp->size = len;
- pNewProp->data = value;
-
- DebugF("new property filled\n");
-
- if (NULL==xf86RegisteredPropertiesTable) {
- DebugF("creating xf86RegisteredPropertiesTable[] size %d\n",
- xf86NumScreens);
- if ( NULL==(xf86RegisteredPropertiesTable=(RootWinPropPtr*)xnfcalloc(sizeof(RootWinProp),xf86NumScreens) )) {
- return(BadAlloc);
- }
- for (i=0; i<xf86NumScreens; i++) {
- xf86RegisteredPropertiesTable[i] = NULL;
- }
- }
-
- DebugF("xf86RegisteredPropertiesTable %p\n",
- (void *)xf86RegisteredPropertiesTable);
- DebugF("xf86RegisteredPropertiesTable[%d] %p\n",
- ScrnIndex, (void *)xf86RegisteredPropertiesTable[ScrnIndex]);
-
- if (!existing) {
- if ( xf86RegisteredPropertiesTable[ScrnIndex] == NULL) {
- xf86RegisteredPropertiesTable[ScrnIndex] = pNewProp;
- } else {
- pRegProp = xf86RegisteredPropertiesTable[ScrnIndex];
- while (pRegProp->next != NULL) {
- DebugF("- next %p\n", (void *)pRegProp);
- pRegProp = pRegProp->next;
- }
- pRegProp->next = pNewProp;
- }
- }
- DebugF("xf86RegisterRootWindowProperty succeeded\n");
- return(Success);
-}
-
-Bool
-xf86IsUnblank(int mode)
-{
- switch(mode) {
- case SCREEN_SAVER_OFF:
- case SCREEN_SAVER_FORCER:
- return TRUE;
- case SCREEN_SAVER_ON:
- case SCREEN_SAVER_CYCLE:
- return FALSE;
- default:
- xf86MsgVerb(X_WARNING, 0, "Unexpected save screen mode: %d\n", mode);
- return TRUE;
- }
-}
-
-void
-xf86MotionHistoryAllocate(LocalDevicePtr local)
-{
- AllocateMotionHistory(local->dev);
-}
+/*
+ * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ * Authors: Dirk Hohndel <hohndel@XFree86.Org>
+ * David Dawes <dawes@XFree86.Org>
+ * ... and others
+ *
+ * This file includes the helper functions that the server provides for
+ * different drivers.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <pciaccess.h>
+#include "Pci.h"
+
+#include <X11/X.h>
+#include "os.h"
+#include "servermd.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "propertyst.h"
+#include "gcstruct.h"
+#include "loaderProcs.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "micmap.h"
+#include "xf86DDC.h"
+#include "xf86Xinput.h"
+#include "xf86InPriv.h"
+#include "mivalidate.h"
+#include "xf86Bus.h"
+#include "xf86Crtc.h"
+
+/* For xf86GetClocks */
+#if defined(CSRG_BASED) || defined(__GNU__)
+#define HAS_SETPRIORITY
+#include <sys/resource.h>
+#endif
+
+static int xf86ScrnInfoPrivateCount = 0;
+
+
+/* Add a pointer to a new DriverRec to xf86DriverList */
+
+void
+xf86AddDriver(DriverPtr driver, pointer module, int flags)
+{
+ /* Don't add null entries */
+ if (!driver)
+ return;
+
+ if (xf86DriverList == NULL)
+ xf86NumDrivers = 0;
+
+ xf86NumDrivers++;
+ xf86DriverList = xnfrealloc(xf86DriverList,
+ xf86NumDrivers * sizeof(DriverPtr));
+ xf86DriverList[xf86NumDrivers - 1] = xnfalloc(sizeof(DriverRec));
+ if (flags & HaveDriverFuncs)
+ *xf86DriverList[xf86NumDrivers - 1] = *driver;
+ else {
+ (void) memset( xf86DriverList[xf86NumDrivers - 1], 0,
+ sizeof( DriverRec ) );
+ (void) memcpy( xf86DriverList[xf86NumDrivers - 1], driver,
+ sizeof(DriverRec1));
+
+ }
+ xf86DriverList[xf86NumDrivers - 1]->module = module;
+ xf86DriverList[xf86NumDrivers - 1]->refCount = 0;
+}
+
+void
+xf86DeleteDriver(int drvIndex)
+{
+ if (xf86DriverList[drvIndex]
+ && (!xf86DriverHasEntities(xf86DriverList[drvIndex]))) {
+ if (xf86DriverList[drvIndex]->module)
+ UnloadModule(xf86DriverList[drvIndex]->module);
+ free(xf86DriverList[drvIndex]);
+ xf86DriverList[drvIndex] = NULL;
+ }
+}
+
+/* Add a pointer to a new InputDriverRec to xf86InputDriverList */
+
+void
+xf86AddInputDriver(InputDriverPtr driver, pointer module, int flags)
+{
+ /* Don't add null entries */
+ if (!driver)
+ return;
+
+ if (xf86InputDriverList == NULL)
+ xf86NumInputDrivers = 0;
+
+ xf86NumInputDrivers++;
+ xf86InputDriverList = xnfrealloc(xf86InputDriverList,
+ xf86NumInputDrivers * sizeof(InputDriverPtr));
+ xf86InputDriverList[xf86NumInputDrivers - 1] =
+ xnfalloc(sizeof(InputDriverRec));
+ *xf86InputDriverList[xf86NumInputDrivers - 1] = *driver;
+ xf86InputDriverList[xf86NumInputDrivers - 1]->module = module;
+ xf86InputDriverList[xf86NumInputDrivers - 1]->refCount = 0;
+}
+
+void
+xf86DeleteInputDriver(int drvIndex)
+{
+ if (xf86InputDriverList[drvIndex] && xf86InputDriverList[drvIndex]->module)
+ UnloadModule(xf86InputDriverList[drvIndex]->module);
+ free(xf86InputDriverList[drvIndex]);
+ xf86InputDriverList[drvIndex] = NULL;
+}
+
+InputDriverPtr
+xf86LookupInputDriver(const char *name)
+{
+ int i;
+
+ for (i = 0; i < xf86NumInputDrivers; i++) {
+ if (xf86InputDriverList[i] && xf86InputDriverList[i]->driverName &&
+ xf86NameCmp(name, xf86InputDriverList[i]->driverName) == 0)
+ return xf86InputDriverList[i];
+ }
+ return NULL;
+}
+
+InputInfoPtr
+xf86LookupInput(const char *name)
+{
+ InputInfoPtr p;
+
+ for (p = xf86InputDevs; p != NULL; p = p->next) {
+ if (strcmp(name, p->name) == 0)
+ return p;
+ }
+
+ return NULL;
+}
+
+/* Allocate a new ScrnInfoRec in xf86Screens */
+
+ScrnInfoPtr
+xf86AllocateScreen(DriverPtr drv, int flags)
+{
+ int i;
+
+ if (xf86Screens == NULL)
+ xf86NumScreens = 0;
+
+ i = xf86NumScreens++;
+ xf86Screens = xnfrealloc(xf86Screens, xf86NumScreens * sizeof(ScrnInfoPtr));
+ xf86Screens[i] = xnfcalloc(sizeof(ScrnInfoRec), 1);
+ xf86Screens[i]->scrnIndex = i; /* Changes when a screen is removed */
+ xf86Screens[i]->origIndex = i; /* This never changes */
+ xf86Screens[i]->privates = xnfcalloc(sizeof(DevUnion),
+ xf86ScrnInfoPrivateCount);
+ /*
+ * EnableDisableFBAccess now gets initialized in InitOutput()
+ * xf86Screens[i]->EnableDisableFBAccess = xf86EnableDisableFBAccess;
+ */
+
+ xf86Screens[i]->drv = drv;
+ drv->refCount++;
+ xf86Screens[i]->module = DuplicateModule(drv->module, NULL);
+
+ xf86Screens[i]->DriverFunc = drv->driverFunc;
+
+ return xf86Screens[i];
+}
+
+
+/*
+ * Remove an entry from xf86Screens. Ideally it should free all allocated
+ * data. To do this properly may require a driver hook.
+ */
+
+void
+xf86DeleteScreen(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn;
+ int i;
+
+ /* First check if the screen is valid */
+ if (xf86NumScreens == 0 || xf86Screens == NULL)
+ return;
+
+ if (scrnIndex > xf86NumScreens - 1)
+ return;
+
+ if (!(pScrn = xf86Screens[scrnIndex]))
+ return;
+
+ /* If a FreeScreen function is defined, call it here */
+ if (pScrn->FreeScreen != NULL)
+ pScrn->FreeScreen(scrnIndex, 0);
+
+ while (pScrn->modes)
+ xf86DeleteMode(&pScrn->modes, pScrn->modes);
+
+ while (pScrn->modePool)
+ xf86DeleteMode(&pScrn->modePool, pScrn->modePool);
+
+ xf86OptionListFree(pScrn->options);
+
+ if (pScrn->module)
+ UnloadModule(pScrn->module);
+
+ if (pScrn->drv)
+ pScrn->drv->refCount--;
+
+ if (pScrn->privates)
+ free(pScrn->privates);
+
+ xf86ClearEntityListForScreen(scrnIndex);
+
+ free(pScrn);
+
+ /* Move the other entries down, updating their scrnIndex fields */
+
+ xf86NumScreens--;
+
+ for (i = scrnIndex; i < xf86NumScreens; i++) {
+ xf86Screens[i] = xf86Screens[i + 1];
+ xf86Screens[i]->scrnIndex = i;
+ /* Also need to take care of the screen layout settings */
+ }
+}
+
+/*
+ * Allocate a private in ScrnInfoRec.
+ */
+
+int
+xf86AllocateScrnInfoPrivateIndex(void)
+{
+ int idx, i;
+ ScrnInfoPtr pScr;
+ DevUnion *nprivs;
+
+ idx = xf86ScrnInfoPrivateCount++;
+ for (i = 0; i < xf86NumScreens; i++) {
+ pScr = xf86Screens[i];
+ nprivs = xnfrealloc(pScr->privates,
+ xf86ScrnInfoPrivateCount * sizeof(DevUnion));
+ /* Zero the new private */
+ bzero(&nprivs[idx], sizeof(DevUnion));
+ pScr->privates = nprivs;
+ }
+ return idx;
+}
+
+/* Allocate a new InputInfoRec and append it to the tail of xf86InputDevs. */
+InputInfoPtr
+xf86AllocateInput(InputDriverPtr drv, int flags)
+{
+ InputInfoPtr new, *prev = NULL;
+
+ if (!(new = calloc(sizeof(InputInfoRec), 1)))
+ return NULL;
+
+ new->drv = drv;
+ drv->refCount++;
+ new->module = DuplicateModule(drv->module, NULL);
+
+ for (prev = &xf86InputDevs; *prev; prev = &(*prev)->next)
+ ;
+
+ *prev = new;
+ new->next = NULL;
+
+ return new;
+}
+
+
+/*
+ * Remove an entry from xf86InputDevs. Ideally it should free all allocated
+ * data. To do this properly may require a driver hook.
+ */
+
+void
+xf86DeleteInput(InputInfoPtr pInp, int flags)
+{
+ InputInfoPtr p;
+
+ /* First check if the inputdev is valid. */
+ if (pInp == NULL)
+ return;
+
+#if 0
+ /* If a free function is defined, call it here. */
+ if (pInp->free)
+ pInp->free(pInp, 0);
+#endif
+
+ if (pInp->module)
+ UnloadModule(pInp->module);
+
+ if (pInp->drv)
+ pInp->drv->refCount--;
+
+ /* This should *really* be handled in drv->UnInit(dev) call instead, but
+ * if the driver forgets about it make sure we free it or at least crash
+ * with flying colors */
+ if (pInp->private)
+ free(pInp->private);
+
+ /* Remove the entry from the list. */
+ if (pInp == xf86InputDevs)
+ xf86InputDevs = pInp->next;
+ else {
+ p = xf86InputDevs;
+ while (p && p->next != pInp)
+ p = p->next;
+ if (p)
+ p->next = pInp->next;
+ /* Else the entry wasn't in the xf86InputDevs list (ignore this). */
+ }
+ free(pInp);
+}
+
+Bool
+xf86AddPixFormat(ScrnInfoPtr pScrn, int depth, int bpp, int pad)
+{
+ int i;
+
+ if (pScrn->numFormats >= MAXFORMATS)
+ return FALSE;
+
+ if (bpp <= 0) {
+ if (depth == 1)
+ bpp = 1;
+ else if (depth <= 8)
+ bpp = 8;
+ else if (depth <= 16)
+ bpp = 16;
+ else if (depth <= 32)
+ bpp = 32;
+ else
+ return FALSE;
+ }
+ if (pad <= 0)
+ pad = BITMAP_SCANLINE_PAD;
+
+ i = pScrn->numFormats++;
+ pScrn->formats[i].depth = depth;
+ pScrn->formats[i].bitsPerPixel = bpp;
+ pScrn->formats[i].scanlinePad = pad;
+ return TRUE;
+}
+
+/*
+ * Set the depth we are using based on (in the following order of preference):
+ * - values given on the command line
+ * - values given in the config file
+ * - values provided by the driver
+ * - an overall default when nothing else is given
+ *
+ * Also find a Display subsection matching the depth/bpp found.
+ *
+ * Sets the following ScrnInfoRec fields:
+ * bitsPerPixel, pixmap24, depth, display, imageByteOrder,
+ * bitmapScanlinePad, bitmapScanlineUnit, bitmapBitOrder, numFormats,
+ * formats, fbFormat.
+ */
+
+/* Can the screen handle 24 bpp pixmaps */
+#define DO_PIX24(f) ((f & Support24bppFb) || \
+ ((f & Support32bppFb) && (f & SupportConvert24to32)))
+
+/* Can the screen handle 32 bpp pixmaps */
+#define DO_PIX32(f) ((f & Support32bppFb) || \
+ ((f & Support24bppFb) && (f & SupportConvert32to24)))
+
+/* Does the screen prefer 32bpp fb for 24bpp pixmaps */
+#define CHOOSE32FOR24(f) ((f & Support32bppFb) && (f & SupportConvert24to32) \
+ && (f & PreferConvert24to32))
+
+/* Does the screen prefer 24bpp fb for 32bpp pixmaps */
+#define CHOOSE24FOR32(f) ((f & Support24bppFb) && (f & SupportConvert32to24) \
+ && (f & PreferConvert32to24))
+
+/* Can the screen handle 32bpp pixmaps for 24bpp fb */
+#define DO_PIX32FOR24(f) ((f & Support24bppFb) && (f & SupportConvert32to24))
+
+/* Can the screen handle 24bpp pixmaps for 32bpp fb */
+#define DO_PIX24FOR32(f) ((f & Support32bppFb) && (f & SupportConvert24to32))
+
+#ifndef GLOBAL_DEFAULT_DEPTH
+#define GLOBAL_DEFAULT_DEPTH 24
+#endif
+
+Bool
+xf86SetDepthBpp(ScrnInfoPtr scrp, int depth, int dummy, int fbbpp,
+ int depth24flags)
+{
+ int i;
+ DispPtr disp;
+ Pix24Flags pix24 = xf86Info.pixmap24;
+ Bool nomatch = FALSE;
+
+ scrp->bitsPerPixel = -1;
+ scrp->depth = -1;
+ scrp->pixmap24 = Pix24DontCare;
+ scrp->bitsPerPixelFrom = X_DEFAULT;
+ scrp->depthFrom = X_DEFAULT;
+
+ if (xf86FbBpp > 0) {
+ scrp->bitsPerPixel = xf86FbBpp;
+ scrp->bitsPerPixelFrom = X_CMDLINE;
+ }
+
+ if (xf86Depth > 0) {
+ scrp->depth = xf86Depth;
+ scrp->depthFrom = X_CMDLINE;
+ }
+
+ if (xf86FbBpp < 0 && xf86Depth < 0) {
+ if (scrp->confScreen->defaultfbbpp > 0) {
+ scrp->bitsPerPixel = scrp->confScreen->defaultfbbpp;
+ scrp->bitsPerPixelFrom = X_CONFIG;
+ }
+ if (scrp->confScreen->defaultdepth > 0) {
+ scrp->depth = scrp->confScreen->defaultdepth;
+ scrp->depthFrom = X_CONFIG;
+ }
+
+ if (scrp->confScreen->defaultfbbpp <= 0 &&
+ scrp->confScreen->defaultdepth <= 0) {
+ /*
+ * Check for DefaultDepth and DefaultFbBpp options in the
+ * Device sections.
+ */
+ int i;
+ GDevPtr device;
+ Bool found = FALSE;
+
+ for (i = 0; i < scrp->numEntities; i++) {
+ device = xf86GetDevFromEntity(scrp->entityList[i],
+ scrp->entityInstanceList[i]);
+ if (device && device->options) {
+ if (xf86FindOption(device->options, "DefaultDepth")) {
+ scrp->depth = xf86SetIntOption(device->options,
+ "DefaultDepth", -1);
+ scrp->depthFrom = X_CONFIG;
+ found = TRUE;
+ }
+ if (xf86FindOption(device->options, "DefaultFbBpp")) {
+ scrp->bitsPerPixel = xf86SetIntOption(device->options,
+ "DefaultFbBpp",
+ -1);
+ scrp->bitsPerPixelFrom = X_CONFIG;
+ found = TRUE;
+ }
+ }
+ if (found)
+ break;
+ }
+ }
+ }
+
+ /* If none of these is set, pick a default */
+ if (scrp->bitsPerPixel < 0 && scrp->depth < 0) {
+ if (fbbpp > 0 || depth > 0) {
+ if (fbbpp > 0)
+ scrp->bitsPerPixel = fbbpp;
+ if (depth > 0)
+ scrp->depth = depth;
+ } else {
+ scrp->depth = GLOBAL_DEFAULT_DEPTH;
+ }
+ }
+
+ /* If any are not given, determine a default for the others */
+
+ if (scrp->bitsPerPixel < 0) {
+ /* The depth must be set */
+ if (scrp->depth > -1) {
+ if (scrp->depth == 1)
+ scrp->bitsPerPixel = 1;
+ else if (scrp->depth <= 4)
+ scrp->bitsPerPixel = 4;
+ else if (scrp->depth <= 8)
+ scrp->bitsPerPixel = 8;
+ else if (scrp->depth <= 16)
+ scrp->bitsPerPixel = 16;
+ else if (scrp->depth <= 24) {
+ /*
+ * Figure out if a choice is possible based on the depth24
+ * and pix24 flags.
+ */
+ /* Check pix24 first */
+ if (pix24 != Pix24DontCare) {
+ if (pix24 == Pix24Use32) {
+ if (DO_PIX32(depth24flags)) {
+ if (CHOOSE24FOR32(depth24flags))
+ scrp->bitsPerPixel = 24;
+ else
+ scrp->bitsPerPixel = 32;
+ } else {
+ nomatch = TRUE;
+ }
+ } else if (pix24 == Pix24Use24) {
+ if (DO_PIX24(depth24flags)) {
+ if (CHOOSE32FOR24(depth24flags))
+ scrp->bitsPerPixel = 32;
+ else
+ scrp->bitsPerPixel = 24;
+ } else {
+ nomatch = TRUE;
+ }
+ }
+ } else {
+ if (DO_PIX32(depth24flags)) {
+ if (CHOOSE24FOR32(depth24flags))
+ scrp->bitsPerPixel = 24;
+ else
+ scrp->bitsPerPixel = 32;
+ } else if (DO_PIX24(depth24flags)) {
+ if (CHOOSE32FOR24(depth24flags))
+ scrp->bitsPerPixel = 32;
+ else
+ scrp->bitsPerPixel = 24;
+ }
+ }
+ } else if (scrp->depth <= 32)
+ scrp->bitsPerPixel = 32;
+ else {
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Specified depth (%d) is greater than 32\n",
+ scrp->depth);
+ return FALSE;
+ }
+ } else {
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "xf86SetDepthBpp: internal error: depth and fbbpp"
+ " are both not set\n");
+ return FALSE;
+ }
+ if (scrp->bitsPerPixel < 0) {
+ if (nomatch)
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Driver can't support depth 24 pixmap format (%d)\n",
+ PIX24TOBPP(pix24));
+ else if ((depth24flags & (Support24bppFb | Support32bppFb)) ==
+ NoDepth24Support)
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Driver can't support depth 24\n");
+ else
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Can't find fbbpp for depth 24\n");
+ return FALSE;
+ }
+ scrp->bitsPerPixelFrom = X_PROBED;
+ }
+
+ if (scrp->depth <= 0) {
+ /* bitsPerPixel is already set */
+ switch (scrp->bitsPerPixel) {
+ case 32:
+ scrp->depth = 24;
+ break;
+ default:
+ /* 1, 4, 8, 16 and 24 */
+ scrp->depth = scrp->bitsPerPixel;
+ break;
+ }
+ scrp->depthFrom = X_PROBED;
+ }
+
+ /* Sanity checks */
+ if (scrp->depth < 1 || scrp->depth > 32) {
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Specified depth (%d) is not in the range 1-32\n",
+ scrp->depth);
+ return FALSE;
+ }
+ switch (scrp->bitsPerPixel) {
+ case 1:
+ case 4:
+ case 8:
+ case 16:
+ case 24:
+ case 32:
+ break;
+ default:
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Specified fbbpp (%d) is not a permitted value\n",
+ scrp->bitsPerPixel);
+ return FALSE;
+ }
+ if (scrp->depth > scrp->bitsPerPixel) {
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Specified depth (%d) is greater than the fbbpp (%d)\n",
+ scrp->depth, scrp->bitsPerPixel);
+ return FALSE;
+ }
+
+ /* set scrp->pixmap24 if the driver isn't flexible */
+ if (scrp->bitsPerPixel == 24 && !DO_PIX32FOR24(depth24flags)) {
+ scrp->pixmap24 = Pix24Use24;
+ }
+ if (scrp->bitsPerPixel == 32 && !DO_PIX24FOR32(depth24flags)) {
+ scrp->pixmap24 = Pix24Use32;
+ }
+
+ /*
+ * Find the Display subsection matching the depth/fbbpp and initialise
+ * scrp->display with it.
+ */
+ for (i = 0, disp = scrp->confScreen->displays;
+ i < scrp->confScreen->numdisplays; i++, disp++) {
+ if ((disp->depth == scrp->depth && disp->fbbpp == scrp->bitsPerPixel)
+ || (disp->depth == scrp->depth && disp->fbbpp <= 0)
+ || (disp->fbbpp == scrp->bitsPerPixel && disp->depth <= 0)) {
+ scrp->display = disp;
+ break;
+ }
+ }
+
+ /*
+ * If an exact match can't be found, see if there is one with no
+ * depth or fbbpp specified.
+ */
+ if (i == scrp->confScreen->numdisplays) {
+ for (i = 0, disp = scrp->confScreen->displays;
+ i < scrp->confScreen->numdisplays; i++, disp++) {
+ if (disp->depth <= 0 && disp->fbbpp <= 0) {
+ scrp->display = disp;
+ break;
+ }
+ }
+ }
+
+ /*
+ * If all else fails, create a default one.
+ */
+ if (i == scrp->confScreen->numdisplays) {
+ scrp->confScreen->numdisplays++;
+ scrp->confScreen->displays =
+ xnfrealloc(scrp->confScreen->displays,
+ scrp->confScreen->numdisplays * sizeof(DispRec));
+ xf86DrvMsg(scrp->scrnIndex, X_INFO,
+ "Creating default Display subsection in Screen section\n"
+ "\t\"%s\" for depth/fbbpp %d/%d\n",
+ scrp->confScreen->id, scrp->depth, scrp->bitsPerPixel);
+ memset(&scrp->confScreen->displays[i], 0, sizeof(DispRec));
+ scrp->confScreen->displays[i].blackColour.red = -1;
+ scrp->confScreen->displays[i].blackColour.green = -1;
+ scrp->confScreen->displays[i].blackColour.blue = -1;
+ scrp->confScreen->displays[i].whiteColour.red = -1;
+ scrp->confScreen->displays[i].whiteColour.green = -1;
+ scrp->confScreen->displays[i].whiteColour.blue = -1;
+ scrp->confScreen->displays[i].defaultVisual = -1;
+ scrp->confScreen->displays[i].modes = xnfalloc(sizeof(char *));
+ scrp->confScreen->displays[i].modes[0] = NULL;
+ scrp->confScreen->displays[i].depth = depth;
+ scrp->confScreen->displays[i].fbbpp = fbbpp;
+ scrp->display = &scrp->confScreen->displays[i];
+ }
+
+ /*
+ * Setup defaults for the display-wide attributes the framebuffer will
+ * need. These defaults should eventually be set globally, and not
+ * dependent on the screens.
+ */
+ scrp->imageByteOrder = IMAGE_BYTE_ORDER;
+ scrp->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
+ if (scrp->depth < 8) {
+ /* Planar modes need these settings */
+ scrp->bitmapScanlineUnit = 8;
+ scrp->bitmapBitOrder = MSBFirst;
+ } else {
+ scrp->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
+ scrp->bitmapBitOrder = BITMAP_BIT_ORDER;
+ }
+
+ /*
+ * If an unusual depth is required, add it to scrp->formats. The formats
+ * for the common depths are handled globally in InitOutput
+ */
+ switch (scrp->depth) {
+ case 1:
+ case 4:
+ case 8:
+ case 15:
+ case 16:
+ case 24:
+ /* Common depths. Nothing to do for them */
+ break;
+ default:
+ if (!xf86AddPixFormat(scrp, scrp->depth, 0, 0)) {
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Can't add pixmap format for depth %d\n", scrp->depth);
+ return FALSE;
+ }
+ }
+
+ /* Initialise the framebuffer format for this screen */
+ scrp->fbFormat.depth = scrp->depth;
+ scrp->fbFormat.bitsPerPixel = scrp->bitsPerPixel;
+ scrp->fbFormat.scanlinePad = BITMAP_SCANLINE_PAD;
+
+ return TRUE;
+}
+
+/*
+ * Print out the selected depth and bpp.
+ */
+void
+xf86PrintDepthBpp(ScrnInfoPtr scrp)
+{
+ xf86DrvMsg(scrp->scrnIndex, scrp->depthFrom, "Depth %d, ", scrp->depth);
+ xf86Msg(scrp->bitsPerPixelFrom, "framebuffer bpp %d\n", scrp->bitsPerPixel);
+}
+
+/*
+ * xf86SetWeight sets scrp->weight, scrp->mask, scrp->offset, and for depths
+ * greater than MAX_PSEUDO_DEPTH also scrp->rgbBits.
+ */
+Bool
+xf86SetWeight(ScrnInfoPtr scrp, rgb weight, rgb mask)
+{
+ MessageType weightFrom = X_DEFAULT;
+
+ scrp->weight.red = 0;
+ scrp->weight.green = 0;
+ scrp->weight.blue = 0;
+
+ if (xf86Weight.red > 0 && xf86Weight.green > 0 && xf86Weight.blue > 0) {
+ scrp->weight = xf86Weight;
+ weightFrom = X_CMDLINE;
+ } else if (scrp->display->weight.red > 0 && scrp->display->weight.green > 0
+ && scrp->display->weight.blue > 0) {
+ scrp->weight = scrp->display->weight;
+ weightFrom = X_CONFIG;
+ } else if (weight.red > 0 && weight.green > 0 && weight.blue > 0) {
+ scrp->weight = weight;
+ } else {
+ switch (scrp->depth) {
+ case 1:
+ case 4:
+ case 8:
+ scrp->weight.red = scrp->weight.green =
+ scrp->weight.blue = scrp->rgbBits;
+ break;
+ case 15:
+ scrp->weight.red = scrp->weight.green = scrp->weight.blue = 5;
+ break;
+ case 16:
+ scrp->weight.red = scrp->weight.blue = 5;
+ scrp->weight.green = 6;
+ break;
+ case 24:
+ scrp->weight.red = scrp->weight.green = scrp->weight.blue = 8;
+ break;
+ case 30:
+ scrp->weight.red = scrp->weight.green = scrp->weight.blue = 10;
+ break;
+ }
+ }
+
+ if (scrp->weight.red)
+ xf86DrvMsg(scrp->scrnIndex, weightFrom, "RGB weight %d%d%d\n",
+ (int)scrp->weight.red, (int)scrp->weight.green,
+ (int)scrp->weight.blue);
+
+ if (scrp->depth > MAX_PSEUDO_DEPTH &&
+ (scrp->depth != scrp->weight.red + scrp->weight.green +
+ scrp->weight.blue)) {
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Weight given (%d%d%d) is inconsistent with the "
+ "depth (%d)\n",
+ (int)scrp->weight.red, (int)scrp->weight.green,
+ (int)scrp->weight.blue, scrp->depth);
+ return FALSE;
+ }
+ if (scrp->depth > MAX_PSEUDO_DEPTH && scrp->weight.red) {
+ /*
+ * XXX Does this even mean anything for TrueColor visuals?
+ * If not, we shouldn't even be setting it here. However, this
+ * matches the behaviour of 3.x versions of XFree86.
+ */
+ scrp->rgbBits = scrp->weight.red;
+ if (scrp->weight.green > scrp->rgbBits)
+ scrp->rgbBits = scrp->weight.green;
+ if (scrp->weight.blue > scrp->rgbBits)
+ scrp->rgbBits = scrp->weight.blue;
+ }
+
+ /* Set the mask and offsets */
+ if (mask.red == 0 || mask.green == 0 || mask.blue == 0) {
+ /* Default to a setting common to PC hardware */
+ scrp->offset.red = scrp->weight.green + scrp->weight.blue;
+ scrp->offset.green = scrp->weight.blue;
+ scrp->offset.blue = 0;
+ scrp->mask.red = ((1 << scrp->weight.red) - 1) << scrp->offset.red;
+ scrp->mask.green = ((1 << scrp->weight.green) - 1)
+ << scrp->offset.green;
+ scrp->mask.blue = (1 << scrp->weight.blue) - 1;
+ } else {
+ /* Initialise to the values passed */
+ scrp->mask.red = mask.red;
+ scrp->mask.green = mask.green;
+ scrp->mask.blue = mask.blue;
+ scrp->offset.red = ffs(mask.red);
+ scrp->offset.green = ffs(mask.green);
+ scrp->offset.blue = ffs(mask.blue);
+ }
+ return TRUE;
+}
+
+Bool
+xf86SetDefaultVisual(ScrnInfoPtr scrp, int visual)
+{
+ MessageType visualFrom = X_DEFAULT;
+
+ if (defaultColorVisualClass >= 0) {
+ scrp->defaultVisual = defaultColorVisualClass;
+ visualFrom = X_CMDLINE;
+ } else if (scrp->display->defaultVisual >= 0) {
+ scrp->defaultVisual = scrp->display->defaultVisual;
+ visualFrom = X_CONFIG;
+ } else if (visual >= 0) {
+ scrp->defaultVisual = visual;
+ } else {
+ if (scrp->depth == 1)
+ scrp->defaultVisual = StaticGray;
+ else if (scrp->depth == 4)
+ scrp->defaultVisual = StaticColor;
+ else if (scrp->depth <= MAX_PSEUDO_DEPTH)
+ scrp->defaultVisual = PseudoColor;
+ else
+ scrp->defaultVisual = TrueColor;
+ }
+ switch (scrp->defaultVisual) {
+ case StaticGray:
+ case GrayScale:
+ case StaticColor:
+ case PseudoColor:
+ case TrueColor:
+ case DirectColor:
+ xf86DrvMsg(scrp->scrnIndex, visualFrom, "Default visual is %s\n",
+ xf86VisualNames[scrp->defaultVisual]);
+ return TRUE;
+ default:
+
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Invalid default visual class (%d)\n", scrp->defaultVisual);
+ return FALSE;
+ }
+}
+
+#define TEST_GAMMA(g) \
+ (g).red > GAMMA_ZERO || (g).green > GAMMA_ZERO || (g).blue > GAMMA_ZERO
+
+#define SET_GAMMA(g) \
+ (g) > GAMMA_ZERO ? (g) : 1.0
+
+Bool
+xf86SetGamma(ScrnInfoPtr scrp, Gamma gamma)
+{
+ MessageType from = X_DEFAULT;
+#if 0
+ xf86MonPtr DDC = (xf86MonPtr)(scrp->monitor->DDC);
+#endif
+ if (TEST_GAMMA(xf86Gamma)) {
+ from = X_CMDLINE;
+ scrp->gamma.red = SET_GAMMA(xf86Gamma.red);
+ scrp->gamma.green = SET_GAMMA(xf86Gamma.green);
+ scrp->gamma.blue = SET_GAMMA(xf86Gamma.blue);
+ } else if (TEST_GAMMA(scrp->monitor->gamma)) {
+ from = X_CONFIG;
+ scrp->gamma.red = SET_GAMMA(scrp->monitor->gamma.red);
+ scrp->gamma.green = SET_GAMMA(scrp->monitor->gamma.green);
+ scrp->gamma.blue = SET_GAMMA(scrp->monitor->gamma.blue);
+#if 0
+ } else if ( DDC && DDC->features.gamma > GAMMA_ZERO ) {
+ from = X_PROBED;
+ scrp->gamma.red = SET_GAMMA(DDC->features.gamma);
+ scrp->gamma.green = SET_GAMMA(DDC->features.gamma);
+ scrp->gamma.blue = SET_GAMMA(DDC->features.gamma);
+ /* EDID structure version 2 gives optional seperate red, green & blue gamma values
+ * in bytes 0x57-0x59 */
+#endif
+ } else if (TEST_GAMMA(gamma)) {
+ scrp->gamma.red = SET_GAMMA(gamma.red);
+ scrp->gamma.green = SET_GAMMA(gamma.green);
+ scrp->gamma.blue = SET_GAMMA(gamma.blue);
+ } else {
+ scrp->gamma.red = 1.0;
+ scrp->gamma.green = 1.0;
+ scrp->gamma.blue = 1.0;
+ }
+ /* Pretend we succeeded if we support better a gamma system.
+ * This avoids a confusing message.
+ */
+ if (xf86_crtc_supports_gamma(scrp))
+ return TRUE;
+ xf86DrvMsg(scrp->scrnIndex, from,
+ "Using gamma correction (%.1f, %.1f, %.1f)\n",
+ scrp->gamma.red, scrp->gamma.green, scrp->gamma.blue);
+
+ return TRUE;
+}
+
+#undef TEST_GAMMA
+#undef SET_GAMMA
+
+
+/*
+ * Set the DPI from the command line option. XXX should allow it to be
+ * calculated from the widthmm/heightmm values.
+ */
+
+#undef MMPERINCH
+#define MMPERINCH 25.4
+
+void
+xf86SetDpi(ScrnInfoPtr pScrn, int x, int y)
+{
+ MessageType from = X_DEFAULT;
+ xf86MonPtr DDC = (xf86MonPtr)(pScrn->monitor->DDC);
+ int ddcWidthmm, ddcHeightmm;
+ int widthErr, heightErr;
+
+ /* XXX Maybe there is no need for widthmm/heightmm in ScrnInfoRec */
+ pScrn->widthmm = pScrn->monitor->widthmm;
+ pScrn->heightmm = pScrn->monitor->heightmm;
+
+ if (DDC && (DDC->features.hsize > 0 && DDC->features.vsize > 0) ) {
+ /* DDC gives display size in mm for individual modes,
+ * but cm for monitor
+ */
+ ddcWidthmm = DDC->features.hsize * 10; /* 10mm in 1cm */
+ ddcHeightmm = DDC->features.vsize * 10; /* 10mm in 1cm */
+ } else {
+ ddcWidthmm = ddcHeightmm = 0;
+ }
+
+ if (monitorResolution > 0) {
+ pScrn->xDpi = monitorResolution;
+ pScrn->yDpi = monitorResolution;
+ from = X_CMDLINE;
+ } else if (pScrn->widthmm > 0 || pScrn->heightmm > 0) {
+ from = X_CONFIG;
+ if (pScrn->widthmm > 0) {
+ pScrn->xDpi =
+ (int)((double)pScrn->virtualX * MMPERINCH / pScrn->widthmm);
+ }
+ if (pScrn->heightmm > 0) {
+ pScrn->yDpi =
+ (int)((double)pScrn->virtualY * MMPERINCH / pScrn->heightmm);
+ }
+ if (pScrn->xDpi > 0 && pScrn->yDpi <= 0)
+ pScrn->yDpi = pScrn->xDpi;
+ if (pScrn->yDpi > 0 && pScrn->xDpi <= 0)
+ pScrn->xDpi = pScrn->yDpi;
+ xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n",
+ pScrn->widthmm, pScrn->heightmm);
+
+ /* Warn if config and probe disagree about display size */
+ if ( ddcWidthmm && ddcHeightmm ) {
+ if (pScrn->widthmm > 0) {
+ widthErr = abs(ddcWidthmm - pScrn->widthmm);
+ } else {
+ widthErr = 0;
+ }
+ if (pScrn->heightmm > 0) {
+ heightErr = abs(ddcHeightmm - pScrn->heightmm);
+ } else {
+ heightErr = 0;
+ }
+ if (widthErr>10 || heightErr>10) {
+ /* Should include config file name for monitor here */
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Probed monitor is %dx%d mm, using Displaysize %dx%d mm\n",
+ ddcWidthmm,ddcHeightmm, pScrn->widthmm,pScrn->heightmm);
+ }
+ }
+ } else if ( ddcWidthmm && ddcHeightmm ) {
+ from = X_PROBED;
+ xf86DrvMsg(pScrn->scrnIndex, from, "Display dimensions: (%d, %d) mm\n",
+ ddcWidthmm, ddcHeightmm );
+ pScrn->widthmm = ddcWidthmm;
+ pScrn->heightmm = ddcHeightmm;
+ if (pScrn->widthmm > 0) {
+ pScrn->xDpi =
+ (int)((double)pScrn->virtualX * MMPERINCH / pScrn->widthmm);
+ }
+ if (pScrn->heightmm > 0) {
+ pScrn->yDpi =
+ (int)((double)pScrn->virtualY * MMPERINCH / pScrn->heightmm);
+ }
+ if (pScrn->xDpi > 0 && pScrn->yDpi <= 0)
+ pScrn->yDpi = pScrn->xDpi;
+ if (pScrn->yDpi > 0 && pScrn->xDpi <= 0)
+ pScrn->xDpi = pScrn->yDpi;
+ } else {
+ if (x > 0)
+ pScrn->xDpi = x;
+ else
+ pScrn->xDpi = DEFAULT_DPI;
+ if (y > 0)
+ pScrn->yDpi = y;
+ else
+ pScrn->yDpi = DEFAULT_DPI;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, from, "DPI set to (%d, %d)\n",
+ pScrn->xDpi, pScrn->yDpi);
+}
+
+#undef MMPERINCH
+
+
+void
+xf86SetBlackWhitePixels(ScreenPtr pScreen)
+{
+ if (xf86FlipPixels) {
+ pScreen->whitePixel = 0;
+ pScreen->blackPixel = 1;
+ } else {
+ pScreen->whitePixel = 1;
+ pScreen->blackPixel = 0;
+ }
+}
+
+/*
+ * xf86SetRootClip --
+ * Enable or disable rendering to the screen by
+ * setting the root clip list and revalidating
+ * all of the windows
+ */
+
+static void
+xf86SetRootClip (ScreenPtr pScreen, Bool enable)
+{
+ WindowPtr pWin = WindowTable[pScreen->myNum];
+ WindowPtr pChild;
+ Bool WasViewable = (Bool)(pWin->viewable);
+ Bool anyMarked = FALSE;
+ WindowPtr pLayerWin;
+ BoxRec box;
+
+ if (WasViewable)
+ {
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+ {
+ (void) (*pScreen->MarkOverlappedWindows)(pChild,
+ pChild,
+ &pLayerWin);
+ }
+ (*pScreen->MarkWindow) (pWin);
+ anyMarked = TRUE;
+ if (pWin->valdata)
+ {
+ if (HasBorder (pWin))
+ {
+ RegionPtr borderVisible;
+
+ borderVisible = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_SUBTRACT(pScreen, borderVisible,
+ &pWin->borderClip, &pWin->winSize);
+ pWin->valdata->before.borderVisible = borderVisible;
+ }
+ pWin->valdata->before.resized = TRUE;
+ }
+ }
+
+ /*
+ * Use REGION_BREAK to avoid optimizations in ValidateTree
+ * that assume the root borderClip can't change well, normally
+ * it doesn't...)
+ */
+ if (enable)
+ {
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pScreen->width;
+ box.y2 = pScreen->height;
+ REGION_INIT (pScreen, &pWin->winSize, &box, 1);
+ REGION_INIT (pScreen, &pWin->borderSize, &box, 1);
+ if (WasViewable)
+ REGION_RESET(pScreen, &pWin->borderClip, &box);
+ pWin->drawable.width = pScreen->width;
+ pWin->drawable.height = pScreen->height;
+ REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
+ }
+ else
+ {
+ REGION_EMPTY(pScreen, &pWin->borderClip);
+ REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
+ }
+
+ ResizeChildrenWinSize (pWin, 0, 0, 0, 0);
+
+ if (WasViewable)
+ {
+ if (pWin->firstChild)
+ {
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin->firstChild,
+ pWin->firstChild,
+ (WindowPtr *)NULL);
+ }
+ else
+ {
+ (*pScreen->MarkWindow) (pWin);
+ anyMarked = TRUE;
+ }
+
+
+ if (anyMarked)
+ (*pScreen->ValidateTree)(pWin, NullWindow, VTOther);
+ }
+
+ if (WasViewable)
+ {
+ if (anyMarked)
+ (*pScreen->HandleExposures)(pWin);
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pWin, NullWindow, VTOther);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+ FlushAllOutput ();
+}
+
+/*
+ * Function to enable/disable access to the frame buffer
+ *
+ * This is used when VT switching and when entering/leaving DGA direct mode.
+ *
+ * This has been rewritten again to eliminate the saved pixmap. The
+ * devPrivate field in the screen pixmap is set to NULL to catch code
+ * accidentally referencing the frame buffer while the X server is not
+ * supposed to touch it.
+ *
+ * Here, we exchange the pixmap private data, rather than the pixmaps
+ * themselves to avoid having to find and change any references to the screen
+ * pixmap such as GC's, window privates etc. This also means that this code
+ * does not need to know exactly how the pixmap pixels are accessed. Further,
+ * this exchange is >not< done through the screen's ModifyPixmapHeader()
+ * vector. This means the called frame buffer code layers can determine
+ * whether they are switched in or out by keeping track of the root pixmap's
+ * private data, and therefore don't need to access pScrnInfo->vtSema.
+ */
+void
+xf86EnableDisableFBAccess(int scrnIndex, Bool enable)
+{
+ ScrnInfoPtr pScrnInfo = xf86Screens[scrnIndex];
+ ScreenPtr pScreen = pScrnInfo->pScreen;
+ PixmapPtr pspix;
+
+ pspix = (*pScreen->GetScreenPixmap) (pScreen);
+ if (enable)
+ {
+ /*
+ * Restore the screen pixmap devPrivate field
+ */
+ pspix->devPrivate = pScrnInfo->pixmapPrivate;
+ /*
+ * Restore all of the clip lists on the screen
+ */
+ if (!xf86Resetting)
+ xf86SetRootClip (pScreen, TRUE);
+
+ }
+ else
+ {
+ /*
+ * Empty all of the clip lists on the screen
+ */
+ xf86SetRootClip (pScreen, FALSE);
+ /*
+ * save the screen pixmap devPrivate field and
+ * replace it with NULL so accidental references
+ * to the frame buffer are caught
+ */
+ pScrnInfo->pixmapPrivate = pspix->devPrivate;
+ pspix->devPrivate.ptr = NULL;
+ }
+}
+
+/* Print driver messages in the standard format */
+
+#undef PREFIX_SIZE
+#define PREFIX_SIZE 14
+
+void
+xf86VDrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format,
+ va_list args)
+{
+ char *tmpFormat;
+
+ /* Prefix the scrnIndex name to the format string. */
+ if (scrnIndex >= 0 && scrnIndex < xf86NumScreens &&
+ xf86Screens[scrnIndex]->name) {
+ tmpFormat = malloc(strlen(format) +
+ strlen(xf86Screens[scrnIndex]->name) +
+ PREFIX_SIZE + 1);
+ if (!tmpFormat)
+ return;
+
+ snprintf(tmpFormat, PREFIX_SIZE + 1, "%s(%d): ",
+ xf86Screens[scrnIndex]->name, scrnIndex);
+
+ strcat(tmpFormat, format);
+ LogVMessageVerb(type, verb, tmpFormat, args);
+ free(tmpFormat);
+ } else
+ LogVMessageVerb(type, verb, format, args);
+}
+#undef PREFIX_SIZE
+
+/* Print driver messages, with verbose level specified directly */
+void
+xf86DrvMsgVerb(int scrnIndex, MessageType type, int verb, const char *format,
+ ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ xf86VDrvMsgVerb(scrnIndex, type, verb, format, ap);
+ va_end(ap);
+}
+
+/* Print driver messages, with verbose level of 1 (default) */
+void
+xf86DrvMsg(int scrnIndex, MessageType type, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ xf86VDrvMsgVerb(scrnIndex, type, 1, format, ap);
+ va_end(ap);
+}
+
+/* Print non-driver messages with verbose level specified directly */
+void
+xf86MsgVerb(MessageType type, int verb, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ xf86VDrvMsgVerb(-1, type, verb, format, ap);
+ va_end(ap);
+}
+
+/* Print non-driver messages with verbose level of 1 (default) */
+void
+xf86Msg(MessageType type, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ xf86VDrvMsgVerb(-1, type, 1, format, ap);
+ va_end(ap);
+}
+
+/* Just like ErrorF, but with the verbose level checked */
+void
+xf86ErrorFVerb(int verb, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ if (xf86Verbose >= verb || xf86LogVerbose >= verb)
+ LogVWrite(verb, format, ap);
+ va_end(ap);
+}
+
+/* Like xf86ErrorFVerb, but with an implied verbose level of 1 */
+void
+xf86ErrorF(const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ if (xf86Verbose >= 1 || xf86LogVerbose >= 1)
+ LogVWrite(1, format, ap);
+ va_end(ap);
+}
+
+
+void
+xf86LogInit(void)
+{
+ char *lf = NULL;
+
+#define LOGSUFFIX ".log"
+#define LOGOLDSUFFIX ".old"
+
+ /* Get the log file name */
+ if (xf86LogFileFrom == X_DEFAULT) {
+ /* Append the display number and ".log" */
+ lf = malloc(strlen(xf86LogFile) + strlen("%s") +
+ strlen(LOGSUFFIX) + 1);
+ if (!lf)
+ FatalError("Cannot allocate space for the log file name\n");
+ sprintf(lf, "%s%%s" LOGSUFFIX, xf86LogFile);
+ xf86LogFile = lf;
+ }
+
+ xf86LogFile = LogInit(xf86LogFile, LOGOLDSUFFIX);
+ xf86LogFileWasOpened = TRUE;
+
+ xf86SetVerbosity(xf86Verbose);
+ xf86SetLogVerbosity(xf86LogVerbose);
+
+#undef LOGSUFFIX
+#undef LOGOLDSUFFIX
+
+ free(lf);
+}
+
+void
+xf86CloseLog(void)
+{
+ LogClose();
+}
+
+
+/*
+ * Drivers can use these for using their own SymTabRecs.
+ */
+
+const char *
+xf86TokenToString(SymTabPtr table, int token)
+{
+ int i;
+
+ for (i = 0; table[i].token >= 0 && table[i].token != token; i++)
+ ;
+
+ if (table[i].token < 0)
+ return NULL;
+ else
+ return(table[i].name);
+}
+
+int
+xf86StringToToken(SymTabPtr table, const char *string)
+{
+ int i;
+
+ if (string == NULL)
+ return -1;
+
+ for (i = 0; table[i].token >= 0 && xf86NameCmp(string, table[i].name); i++)
+ ;
+
+ return(table[i].token);
+}
+
+/*
+ * helper to display the clocks found on a card
+ */
+void
+xf86ShowClocks(ScrnInfoPtr scrp, MessageType from)
+{
+ int j;
+
+ xf86DrvMsg(scrp->scrnIndex, from, "Pixel clocks available:");
+ for (j=0; j < scrp->numClocks; j++) {
+ if ((j % 4) == 0) {
+ xf86ErrorF("\n");
+ xf86DrvMsg(scrp->scrnIndex, from, "pixel clocks:");
+ }
+ xf86ErrorF(" %7.3f", (double)scrp->clock[j] / 1000.0);
+ }
+ xf86ErrorF("\n");
+}
+
+
+/*
+ * This prints out the driver identify message, including the names of
+ * the supported chipsets.
+ *
+ * XXX This makes assumptions about the line width, etc. Maybe we could
+ * use a more general "pretty print" function for messages.
+ */
+void
+xf86PrintChipsets(const char *drvname, const char *drvmsg, SymTabPtr chips)
+{
+ int len, i;
+
+ len = 6 + strlen(drvname) + 2 + strlen(drvmsg) + 2;
+ xf86Msg(X_INFO, "%s: %s:", drvname, drvmsg);
+ for (i = 0; chips[i].name != NULL; i++) {
+ if (i != 0) {
+ xf86ErrorF(",");
+ len++;
+ }
+ if (len + 2 + strlen(chips[i].name) < 78) {
+ xf86ErrorF(" ");
+ len++;
+ } else {
+ xf86ErrorF("\n\t");
+ len = 8;
+ }
+ xf86ErrorF("%s", chips[i].name);
+ len += strlen(chips[i].name);
+ }
+ xf86ErrorF("\n");
+}
+
+
+int
+xf86MatchDevice(const char *drivername, GDevPtr **sectlist)
+{
+ GDevPtr gdp, *pgdp = NULL;
+ confScreenPtr screensecptr;
+ int i,j;
+
+ if (sectlist)
+ *sectlist = NULL;
+
+ if (xf86DoConfigure && xf86DoConfigurePass1) return 1;
+
+ /*
+ * This is a very important function that matches the device sections
+ * as they show up in the config file with the drivers that the server
+ * loads at run time.
+ *
+ * ChipProbe can call
+ * int xf86MatchDevice(char * drivername, GDevPtr ** sectlist)
+ * with its driver name. The function allocates an array of GDevPtr and
+ * returns this via sectlist and returns the number of elements in
+ * this list as return value. 0 means none found, -1 means fatal error.
+ *
+ * It can figure out which of the Device sections to use for which card
+ * (using things like the Card statement, etc). For single headed servers
+ * there will of course be just one such Device section.
+ */
+ i = 0;
+
+ /*
+ * first we need to loop over all the Screens sections to get to all
+ * 'active' device sections
+ */
+ for (j=0; xf86ConfigLayout.screens[j].screen != NULL; j++) {
+ screensecptr = xf86ConfigLayout.screens[j].screen;
+ if ((screensecptr->device->driver != NULL)
+ && (xf86NameCmp( screensecptr->device->driver,drivername) == 0)
+ && (! screensecptr->device->claimed)) {
+ /*
+ * we have a matching driver that wasn't claimed, yet
+ */
+ pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr));
+ pgdp[i++] = screensecptr->device;
+ }
+ }
+
+ /* Then handle the inactive devices */
+ j = 0;
+ while (xf86ConfigLayout.inactives[j].identifier) {
+ gdp = &xf86ConfigLayout.inactives[j];
+ if (gdp->driver && !gdp->claimed &&
+ !xf86NameCmp(gdp->driver,drivername)) {
+ /* we have a matching driver that wasn't claimed yet */
+ pgdp = xnfrealloc(pgdp, (i + 2) * sizeof(GDevPtr));
+ pgdp[i++] = gdp;
+ }
+ j++;
+ }
+
+ /*
+ * make the array NULL terminated and return its address
+ */
+ if (i)
+ pgdp[i] = NULL;
+
+ if (sectlist)
+ *sectlist = pgdp;
+ else
+ free(pgdp);
+ return i;
+}
+
+static Bool
+pciDeviceHasBars(struct pci_device *pci)
+{
+ int i;
+
+ for (i = 0; i < 6; i++)
+ if (pci->regions[i].size)
+ return TRUE;
+
+ if (pci->rom_size)
+ return TRUE;
+
+ return FALSE;
+}
+
+struct Inst {
+ struct pci_device * pci;
+ GDevPtr dev;
+ Bool foundHW; /* PCIid in list of supported chipsets */
+ Bool claimed; /* BusID matches with a device section */
+ int chip;
+ int screen;
+};
+
+
+/**
+ * Find set of unclaimed devices matching a given vendor ID.
+ *
+ * Used by drivers to find as yet unclaimed devices matching the specified
+ * vendor ID.
+ *
+ * \param driverName Name of the driver. This is used to find Device
+ * sections in the config file.
+ * \param vendorID PCI vendor ID of associated devices. If zero, then
+ * the true vendor ID must be encoded in the \c PCIid
+ * fields of the \c PCIchipsets entries.
+ * \param chipsets Symbol table used to associate chipset names with
+ * PCI IDs.
+ * \param devList List of Device sections parsed from the config file.
+ * \param numDevs Number of entries in \c devList.
+ * \param drvp Pointer the driver's control structure.
+ * \param foundEntities Returned list of entity indicies associated with the
+ * driver.
+ *
+ * \returns
+ * The number of elements in returned in \c foundEntities on success or zero
+ * on failure.
+ *
+ * \todo
+ * This function does a bit more than short description says. Fill in some
+ * more of the details of its operation.
+ *
+ * \todo
+ * The \c driverName parameter is redundant. It is the same as
+ * \c DriverRec::driverName. In a future version of this function, remove
+ * that parameter.
+ */
+int
+xf86MatchPciInstances(const char *driverName, int vendorID,
+ SymTabPtr chipsets, PciChipsets *PCIchipsets,
+ GDevPtr *devList, int numDevs, DriverPtr drvp,
+ int **foundEntities)
+{
+ int i,j;
+ struct pci_device * pPci;
+ struct pci_device_iterator *iter;
+ struct Inst *instances = NULL;
+ int numClaimedInstances = 0;
+ int allocatedInstances = 0;
+ int numFound = 0;
+ SymTabRec *c;
+ PciChipsets *id;
+ int *retEntities = NULL;
+
+ *foundEntities = NULL;
+
+
+ /* Each PCI device will contribute at least one entry. Each device
+ * section can contribute at most one entry. The sum of the two is
+ * guaranteed to be larger than the maximum possible number of entries.
+ * Do this calculation and memory allocation once now to eliminate the
+ * need for realloc calls inside the loop.
+ */
+ if (!(xf86DoConfigure && xf86DoConfigurePass1)) {
+ unsigned max_entries = numDevs;
+
+ iter = pci_slot_match_iterator_create(NULL);
+ while ((pPci = pci_device_next(iter)) != NULL) {
+ max_entries++;
+ }
+
+ pci_iterator_destroy(iter);
+ instances = xnfalloc(max_entries * sizeof(struct Inst));
+ }
+
+ iter = pci_slot_match_iterator_create(NULL);
+ while ((pPci = pci_device_next(iter)) != NULL) {
+ unsigned device_class = pPci->device_class;
+ Bool foundVendor = FALSE;
+
+
+ /* Convert the pre-PCI 2.0 device class for a VGA adapter to the
+ * 2.0 version of the same class.
+ */
+ if ( device_class == 0x00000101 ) {
+ device_class = 0x00030000;
+ }
+
+
+ /* Find PCI devices that match the given vendor ID. The vendor ID is
+ * either specified explicitly as a parameter to the function or
+ * implicitly encoded in the high bits of id->PCIid.
+ *
+ * The first device with a matching vendor is recorded, even if the
+ * device ID doesn't match. This is done because the Device section
+ * in the xorg.conf file can over-ride the device ID. A matching PCI
+ * ID might not be found now, but after the device ID over-ride is
+ * applied there /might/ be a match.
+ */
+ for (id = PCIchipsets; id->PCIid != -1; id++) {
+ const unsigned vendor_id = ((id->PCIid & 0xFFFF0000) >> 16)
+ | vendorID;
+ const unsigned device_id = (id->PCIid & 0x0000FFFF);
+ const unsigned match_class = 0x00030000 | id->PCIid;
+
+ if ((vendor_id == pPci->vendor_id)
+ || ((vendorID == PCI_VENDOR_GENERIC) && (match_class == device_class))) {
+ if (!foundVendor && (instances != NULL)) {
+ ++allocatedInstances;
+ instances[allocatedInstances - 1].pci = pPci;
+ instances[allocatedInstances - 1].dev = NULL;
+ instances[allocatedInstances - 1].claimed = FALSE;
+ instances[allocatedInstances - 1].foundHW = FALSE;
+ instances[allocatedInstances - 1].screen = 0;
+ }
+
+ foundVendor = TRUE;
+
+ if ( (device_id == pPci->device_id)
+ || ((vendorID == PCI_VENDOR_GENERIC)
+ && (match_class == device_class)) ) {
+ if ( instances != NULL ) {
+ instances[allocatedInstances - 1].foundHW = TRUE;
+ instances[allocatedInstances - 1].chip = id->numChipset;
+ }
+
+
+ if ( xf86DoConfigure && xf86DoConfigurePass1 ) {
+ if (xf86CheckPciSlot(pPci)) {
+ GDevPtr pGDev =
+ xf86AddBusDeviceToConfigure(drvp->driverName,
+ BUS_PCI, pPci, -1);
+ if (pGDev) {
+ /* After configure pass 1, chipID and chipRev
+ * are treated as over-rides, so clobber them
+ * here.
+ */
+ pGDev->chipID = -1;
+ pGDev->chipRev = -1;
+ }
+
+ numFound++;
+ }
+ }
+ else {
+ numFound++;
+ }
+
+ break;
+ }
+ }
+ }
+ }
+
+ pci_iterator_destroy(iter);
+
+
+ /* In "probe only" or "configure" mode (signaled by instances being NULL),
+ * our work is done. Return the number of detected devices.
+ */
+ if ( instances == NULL ) {
+ return numFound;
+ }
+
+
+ /*
+ * This may be debatable, but if no PCI devices with a matching vendor
+ * type is found, return zero now. It is probably not desirable to
+ * allow the config file to override this.
+ */
+ if (allocatedInstances <= 0) {
+ free(instances);
+ return 0;
+ }
+
+
+ DebugF("%s instances found: %d\n", driverName, allocatedInstances);
+
+ /*
+ * Check for devices that need duplicated instances. This is required
+ * when there is more than one screen per entity.
+ *
+ * XXX This currently doesn't work for cases where the BusID isn't
+ * specified explicitly in the config file.
+ */
+
+ for (j = 0; j < numDevs; j++) {
+ if (devList[j]->screen > 0 && devList[j]->busID
+ && *devList[j]->busID) {
+ for (i = 0; i < allocatedInstances; i++) {
+ pPci = instances[i].pci;
+ if (xf86ComparePciBusString(devList[j]->busID,
+ PCI_MAKE_BUS( pPci->domain, pPci->bus ),
+ pPci->dev,
+ pPci->func)) {
+ allocatedInstances++;
+ instances[allocatedInstances - 1] = instances[i];
+ instances[allocatedInstances - 1].screen =
+ devList[j]->screen;
+ numFound++;
+ break;
+ }
+ }
+ }
+ }
+
+ for (i = 0; i < allocatedInstances; i++) {
+ GDevPtr dev = NULL;
+ GDevPtr devBus = NULL;
+
+ pPci = instances[i].pci;
+ for (j = 0; j < numDevs; j++) {
+ if (devList[j]->busID && *devList[j]->busID) {
+ if (xf86ComparePciBusString(devList[j]->busID,
+ PCI_MAKE_BUS( pPci->domain, pPci->bus ),
+ pPci->dev,
+ pPci->func) &&
+ devList[j]->screen == instances[i].screen) {
+
+ if (devBus)
+ xf86MsgVerb(X_WARNING,0,
+ "%s: More than one matching Device section for "
+ "instances\n\t(BusID: %s) found: %s\n",
+ driverName, devList[j]->busID,
+ devList[j]->identifier);
+ else
+ devBus = devList[j];
+ }
+ } else {
+ /*
+ * if device section without BusID is found
+ * only assign to it to the primary device.
+ */
+ if (xf86IsPrimaryPci(pPci)) {
+ xf86Msg(X_PROBED, "Assigning device section with no busID"
+ " to primary device\n");
+ if (dev || devBus)
+ xf86MsgVerb(X_WARNING, 0,
+ "%s: More than one matching Device section "
+ "found: %s\n", driverName, devList[j]->identifier);
+ else
+ dev = devList[j];
+ }
+ }
+ }
+ if (devBus) dev = devBus; /* busID preferred */
+ if (!dev) {
+ if (xf86CheckPciSlot(pPci) && pciDeviceHasBars(pPci)) {
+ xf86MsgVerb(X_WARNING, 0, "%s: No matching Device section "
+ "for instance (BusID PCI:%u@%u:%u:%u) found\n",
+ driverName, pPci->domain, pPci->bus, pPci->dev,
+ pPci->func);
+ }
+ } else {
+ numClaimedInstances++;
+ instances[i].claimed = TRUE;
+ instances[i].dev = dev;
+ }
+ }
+ DebugF("%s instances found: %d\n", driverName, numClaimedInstances);
+ /*
+ * Now check that a chipset or chipID override in the device section
+ * is valid. Chipset has precedence over chipID.
+ * If chipset is not valid ignore BusSlot completely.
+ */
+ for (i = 0; i < allocatedInstances && numClaimedInstances > 0; i++) {
+ MessageType from = X_PROBED;
+
+ if (!instances[i].claimed) {
+ continue;
+ }
+ if (instances[i].dev->chipset) {
+ for (c = chipsets; c->token >= 0; c++) {
+ if (xf86NameCmp(c->name, instances[i].dev->chipset) == 0)
+ break;
+ }
+ if (c->token == -1) {
+ instances[i].claimed = FALSE;
+ numClaimedInstances--;
+ xf86MsgVerb(X_WARNING, 0, "%s: Chipset \"%s\" in Device "
+ "section \"%s\" isn't valid for this driver\n",
+ driverName, instances[i].dev->chipset,
+ instances[i].dev->identifier);
+ } else {
+ instances[i].chip = c->token;
+
+ for (id = PCIchipsets; id->numChipset >= 0; id++) {
+ if (id->numChipset == instances[i].chip)
+ break;
+ }
+ if(id->numChipset >=0){
+ xf86Msg(X_CONFIG,"Chipset override: %s\n",
+ instances[i].dev->chipset);
+ from = X_CONFIG;
+ } else {
+ instances[i].claimed = FALSE;
+ numClaimedInstances--;
+ xf86MsgVerb(X_WARNING, 0, "%s: Chipset \"%s\" in Device "
+ "section \"%s\" isn't a valid PCI chipset\n",
+ driverName, instances[i].dev->chipset,
+ instances[i].dev->identifier);
+ }
+ }
+ } else if (instances[i].dev->chipID > 0) {
+ for (id = PCIchipsets; id->numChipset >= 0; id++) {
+ if (id->PCIid == instances[i].dev->chipID)
+ break;
+ }
+ if (id->numChipset == -1) {
+ instances[i].claimed = FALSE;
+ numClaimedInstances--;
+ xf86MsgVerb(X_WARNING, 0, "%s: ChipID 0x%04X in Device "
+ "section \"%s\" isn't valid for this driver\n",
+ driverName, instances[i].dev->chipID,
+ instances[i].dev->identifier);
+ } else {
+ instances[i].chip = id->numChipset;
+
+ xf86Msg( X_CONFIG,"ChipID override: 0x%04X\n",
+ instances[i].dev->chipID);
+ from = X_CONFIG;
+ }
+ } else if (!instances[i].foundHW) {
+ /*
+ * This means that there was no override and the PCI chipType
+ * doesn't match one that is supported
+ */
+ instances[i].claimed = FALSE;
+ numClaimedInstances--;
+ }
+ if (instances[i].claimed == TRUE){
+ for (c = chipsets; c->token >= 0; c++) {
+ if (c->token == instances[i].chip)
+ break;
+ }
+ xf86Msg(from,"Chipset %s found\n",
+ c->name);
+ }
+ }
+
+ /*
+ * Of the claimed instances, check that another driver hasn't already
+ * claimed its slot.
+ */
+ numFound = 0;
+ for (i = 0; i < allocatedInstances && numClaimedInstances > 0; i++) {
+
+ if (!instances[i].claimed)
+ continue;
+ pPci = instances[i].pci;
+
+
+ /*
+ * Allow the same entity to be used more than once for devices with
+ * multiple screens per entity. This assumes implicitly that there
+ * will be a screen == 0 instance.
+ *
+ * XXX Need to make sure that two different drivers don't claim
+ * the same screen > 0 instance.
+ */
+ if (instances[i].screen == 0 && !xf86CheckPciSlot( pPci ))
+ continue;
+
+ DebugF("%s: card at %d:%d:%d is claimed by a Device section\n",
+ driverName, pPci->bus, pPci->dev, pPci->func);
+
+ /* Allocate an entry in the lists to be returned */
+ numFound++;
+ retEntities = xnfrealloc(retEntities, numFound * sizeof(int));
+ retEntities[numFound - 1] = xf86ClaimPciSlot( pPci, drvp,
+ instances[i].chip,
+ instances[i].dev,
+ instances[i].dev->active);
+ if (retEntities[numFound - 1] == -1 && instances[i].screen > 0) {
+ for (j = 0; j < xf86NumEntities; j++) {
+ EntityPtr pEnt = xf86Entities[j];
+ if (pEnt->bus.type != BUS_PCI)
+ continue;
+ if (pEnt->bus.id.pci == pPci) {
+ retEntities[numFound - 1] = j;
+ xf86AddDevToEntity(j, instances[i].dev);
+ break;
+ }
+ }
+ }
+ }
+ free(instances);
+ if (numFound > 0) {
+ *foundEntities = retEntities;
+ }
+
+ return numFound;
+}
+
+/*
+ * xf86GetClocks -- get the dot-clocks via a BIG BAD hack ...
+ */
+void
+xf86GetClocks(ScrnInfoPtr pScrn, int num, Bool (*ClockFunc)(ScrnInfoPtr, int),
+ void (*ProtectRegs)(ScrnInfoPtr, Bool),
+ void (*BlankScreen)(ScrnInfoPtr, Bool), IOADDRESS vertsyncreg,
+ int maskval, int knownclkindex, int knownclkvalue)
+{
+ register int status = vertsyncreg;
+ unsigned long i, cnt, rcnt, sync;
+
+ /* First save registers that get written on */
+ (*ClockFunc)(pScrn, CLK_REG_SAVE);
+
+ if (num > MAXCLOCKS)
+ num = MAXCLOCKS;
+
+ for (i = 0; i < num; i++)
+ {
+ if (ProtectRegs)
+ (*ProtectRegs)(pScrn, TRUE);
+ if (!(*ClockFunc)(pScrn, i))
+ {
+ pScrn->clock[i] = -1;
+ continue;
+ }
+ if (ProtectRegs)
+ (*ProtectRegs)(pScrn, FALSE);
+ if (BlankScreen)
+ (*BlankScreen)(pScrn, FALSE);
+
+ usleep(50000); /* let VCO stabilise */
+
+ cnt = 0;
+ sync = 200000;
+
+ while ((inb(status) & maskval) == 0x00)
+ if (sync-- == 0) goto finish;
+ /* Something appears to be happening, so reset sync count */
+ sync = 200000;
+ while ((inb(status) & maskval) == maskval)
+ if (sync-- == 0) goto finish;
+ /* Something appears to be happening, so reset sync count */
+ sync = 200000;
+ while ((inb(status) & maskval) == 0x00)
+ if (sync-- == 0) goto finish;
+
+ for (rcnt = 0; rcnt < 5; rcnt++)
+ {
+ while (!(inb(status) & maskval))
+ cnt++;
+ while ((inb(status) & maskval))
+ cnt++;
+ }
+
+finish:
+ pScrn->clock[i] = cnt ? cnt : -1;
+ if (BlankScreen)
+ (*BlankScreen)(pScrn, TRUE);
+ }
+
+ for (i = 0; i < num; i++)
+ {
+ if (i != knownclkindex)
+ {
+ if (pScrn->clock[i] == -1)
+ {
+ pScrn->clock[i] = 0;
+ }
+ else
+ {
+ pScrn->clock[i] = (int)(0.5 +
+ (((float)knownclkvalue) * pScrn->clock[knownclkindex]) /
+ (pScrn->clock[i]));
+ /* Round to nearest 10KHz */
+ pScrn->clock[i] += 5;
+ pScrn->clock[i] /= 10;
+ pScrn->clock[i] *= 10;
+ }
+ }
+ }
+
+ pScrn->clock[knownclkindex] = knownclkvalue;
+ pScrn->numClocks = num;
+
+ /* Restore registers that were written on */
+ (*ClockFunc)(pScrn, CLK_REG_RESTORE);
+}
+
+const char *
+xf86GetVisualName(int visual)
+{
+ if (visual < 0 || visual > DirectColor)
+ return NULL;
+
+ return xf86VisualNames[visual];
+}
+
+
+int
+xf86GetVerbosity(void)
+{
+ return max(xf86Verbose, xf86LogVerbose);
+}
+
+Pix24Flags
+xf86GetPix24(void)
+{
+ return xf86Info.pixmap24;
+}
+
+
+int
+xf86GetDepth(void)
+{
+ return xf86Depth;
+}
+
+
+rgb
+xf86GetWeight(void)
+{
+ return xf86Weight;
+}
+
+
+Gamma
+xf86GetGamma(void)
+{
+ return xf86Gamma;
+}
+
+
+Bool
+xf86GetFlipPixels(void)
+{
+ return xf86FlipPixels;
+}
+
+
+const char *
+xf86GetServerName(void)
+{
+ return xf86ServerName;
+}
+
+
+Bool
+xf86ServerIsExiting(void)
+{
+ return (dispatchException & DE_TERMINATE) == DE_TERMINATE;
+}
+
+
+Bool
+xf86ServerIsResetting(void)
+{
+ return xf86Resetting;
+}
+
+
+Bool
+xf86ServerIsInitialising(void)
+{
+ return xf86Initialising;
+}
+
+
+Bool
+xf86ServerIsOnlyDetecting(void)
+{
+ return xf86DoConfigure;
+}
+
+
+Bool
+xf86CaughtSignal(void)
+{
+ return xf86Info.caughtSignal;
+}
+
+
+Bool
+xf86GetVidModeAllowNonLocal(void)
+{
+ return xf86Info.vidModeAllowNonLocal;
+}
+
+
+Bool
+xf86GetVidModeEnabled(void)
+{
+ return xf86Info.vidModeEnabled;
+}
+
+Bool
+xf86GetModInDevAllowNonLocal(void)
+{
+ return xf86Info.miscModInDevAllowNonLocal;
+}
+
+
+Bool
+xf86GetModInDevEnabled(void)
+{
+ return xf86Info.miscModInDevEnabled;
+}
+
+
+Bool
+xf86GetAllowMouseOpenFail(void)
+{
+ return xf86Info.allowMouseOpenFail;
+}
+
+
+Bool
+xf86IsPc98(void)
+{
+#if SUPPORT_PC98
+ return xf86Info.pc98;
+#else
+ return FALSE;
+#endif
+}
+
+void
+xf86DisableRandR(void)
+{
+ xf86Info.disableRandR = TRUE;
+ xf86Info.randRFrom = X_PROBED;
+}
+
+CARD32
+xf86GetModuleVersion(pointer module)
+{
+ return (CARD32)LoaderGetModuleVersion(module);
+}
+
+pointer
+xf86LoadDrvSubModule(DriverPtr drv, const char *name)
+{
+ pointer ret;
+ int errmaj = 0, errmin = 0;
+
+ ret = LoadSubModule(drv->module, name, NULL, NULL, NULL, NULL,
+ &errmaj, &errmin);
+ if (!ret)
+ LoaderErrorMsg(NULL, name, errmaj, errmin);
+ return ret;
+}
+
+pointer
+xf86LoadSubModule(ScrnInfoPtr pScrn, const char *name)
+{
+ pointer ret;
+ int errmaj = 0, errmin = 0;
+
+ ret = LoadSubModule(pScrn->module, name, NULL, NULL, NULL, NULL,
+ &errmaj, &errmin);
+ if (!ret)
+ LoaderErrorMsg(pScrn->name, name, errmaj, errmin);
+ return ret;
+}
+
+/*
+ * xf86LoadOneModule loads a single module.
+ */
+pointer
+xf86LoadOneModule(char *name, pointer opt)
+{
+ int errmaj, errmin;
+ char *Name;
+ pointer mod;
+
+ if (!name)
+ return NULL;
+
+ /* Normalise the module name */
+ Name = xf86NormalizeName(name);
+
+ /* Skip empty names */
+ if (Name == NULL)
+ return NULL;
+ if (*Name == '\0') {
+ free(Name);
+ return NULL;
+ }
+
+ mod = LoadModule(Name, NULL, NULL, NULL, opt, NULL, &errmaj, &errmin);
+ if (!mod)
+ LoaderErrorMsg(NULL, Name, errmaj, errmin);
+ free(Name);
+ return mod;
+}
+
+void
+xf86UnloadSubModule(pointer mod)
+{
+ /*
+ * This is disabled for now. The loader isn't smart enough yet to undo
+ * relocations.
+ */
+#if 0
+ UnloadSubModule(mod);
+#endif
+}
+
+Bool
+xf86LoaderCheckSymbol(const char *name)
+{
+ return LoaderSymbol(name) != NULL;
+}
+
+typedef enum {
+ OPTION_BACKING_STORE
+} BSOpts;
+
+static const OptionInfoRec BSOptions[] = {
+ { OPTION_BACKING_STORE, "BackingStore", OPTV_BOOLEAN, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+void
+xf86SetBackingStore(ScreenPtr pScreen)
+{
+ Bool useBS = FALSE;
+ MessageType from = X_DEFAULT;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ OptionInfoPtr options;
+
+ options = xnfalloc(sizeof(BSOptions));
+ (void)memcpy(options, BSOptions, sizeof(BSOptions));
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
+
+ /* check for commandline option here */
+ if (xf86bsEnableFlag) {
+ from = X_CMDLINE;
+ useBS = TRUE;
+ } else if (xf86bsDisableFlag) {
+ from = X_CMDLINE;
+ useBS = FALSE;
+ } else {
+ if (xf86GetOptValBool(options, OPTION_BACKING_STORE, &useBS))
+ from = X_CONFIG;
+ }
+ free(options);
+ pScreen->backingStoreSupport = useBS ? Always : NotUseful;
+ if (serverGeneration == 1)
+ xf86DrvMsg(pScreen->myNum, from, "Backing store %s\n",
+ useBS ? "enabled" : "disabled");
+}
+
+
+typedef enum {
+ OPTION_SILKEN_MOUSE
+} SMOpts;
+
+static const OptionInfoRec SMOptions[] = {
+ { OPTION_SILKEN_MOUSE, "SilkenMouse", OPTV_BOOLEAN, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+void
+xf86SetSilkenMouse (ScreenPtr pScreen)
+{
+ Bool useSM = TRUE;
+ MessageType from = X_DEFAULT;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ OptionInfoPtr options;
+
+ options = xnfalloc(sizeof(SMOptions));
+ (void)memcpy(options, SMOptions, sizeof(SMOptions));
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
+
+ /* check for commandline option here */
+ /* disable if screen shares resources */
+ /* TODO VGA arb disable silken mouse */
+ if (xf86silkenMouseDisableFlag) {
+ from = X_CMDLINE;
+ useSM = FALSE;
+ } else {
+ if (xf86GetOptValBool(options, OPTION_SILKEN_MOUSE, &useSM))
+ from = X_CONFIG;
+ }
+ free(options);
+ /*
+ * XXX quick hack to report correctly for OSs that can't do SilkenMouse
+ * yet. Should handle this differently so that alternate async methods
+ * work correctly with this too.
+ */
+ pScrn->silkenMouse = useSM && xf86Info.useSIGIO && xf86SIGIOSupported();
+ if (serverGeneration == 1)
+ xf86DrvMsg(pScreen->myNum, from, "Silken mouse %s\n",
+ pScrn->silkenMouse ? "enabled" : "disabled");
+}
+
+/* Wrote this function for the PM2 Xv driver, preliminary. */
+
+pointer
+xf86FindXvOptions(int scrnIndex, int adaptor_index, char *port_name,
+ char **adaptor_name, pointer *adaptor_options)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ confXvAdaptorPtr adaptor;
+ int i;
+
+ if (adaptor_index >= pScrn->confScreen->numxvadaptors) {
+ if (adaptor_name) *adaptor_name = NULL;
+ if (adaptor_options) *adaptor_options = NULL;
+ return NULL;
+ }
+
+ adaptor = &pScrn->confScreen->xvadaptors[adaptor_index];
+ if (adaptor_name) *adaptor_name = adaptor->identifier;
+ if (adaptor_options) *adaptor_options = adaptor->options;
+
+ for (i = 0; i < adaptor->numports; i++)
+ if (!xf86NameCmp(adaptor->ports[i].identifier, port_name))
+ return adaptor->ports[i].options;
+
+ return NULL;
+}
+
+/* Rather than duplicate loader's get OS function, just include it directly */
+#define LoaderGetOS xf86GetOS
+#include "loader/os.c"
+
+/* new RAC */
+/*
+ * xf86ConfigPciEntityInactive() -- This function can be used
+ * to configure an inactive entity as well as to reconfigure an
+ * previously active entity inactive. If the entity has been
+ * assigned to a screen before it will be removed. If p_chip is
+ * non-NULL all static resources listed there will be registered.
+ */
+static void
+xf86ConfigPciEntityInactive(EntityInfoPtr pEnt, PciChipsets *p_chip,
+ EntityProc init, EntityProc enter,
+ EntityProc leave, pointer private)
+{
+ ScrnInfoPtr pScrn;
+
+ if ((pScrn = xf86FindScreenForEntity(pEnt->index)))
+ xf86RemoveEntityFromScreen(pScrn,pEnt->index);
+
+ /* shared resources are only needed when entity is active: remove */
+ xf86SetEntityFuncs(pEnt->index,init,enter,leave,private);
+}
+
+static void
+xf86ConfigFbEntityInactive(EntityInfoPtr pEnt, EntityProc init,
+ EntityProc enter, EntityProc leave, pointer private)
+{
+ ScrnInfoPtr pScrn;
+
+ if ((pScrn = xf86FindScreenForEntity(pEnt->index)))
+ xf86RemoveEntityFromScreen(pScrn,pEnt->index);
+ xf86SetEntityFuncs(pEnt->index,init,enter,leave,private);
+}
+
+ScrnInfoPtr
+xf86ConfigPciEntity(ScrnInfoPtr pScrn, int scrnFlag, int entityIndex,
+ PciChipsets *p_chip, void *dummy, EntityProc init,
+ EntityProc enter, EntityProc leave, pointer private)
+{
+ EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex);
+ if (!pEnt) return pScrn;
+
+ if (!(pEnt->location.type == BUS_PCI)
+ || !xf86GetPciInfoForEntity(entityIndex)) {
+ free(pEnt);
+ return pScrn;
+ }
+ if (!pEnt->active) {
+ xf86ConfigPciEntityInactive(pEnt, p_chip, init, enter,
+ leave, private);
+ free(pEnt);
+ return pScrn;
+ }
+
+ if (!pScrn)
+ pScrn = xf86AllocateScreen(pEnt->driver,scrnFlag);
+ if (xf86IsEntitySharable(entityIndex)) {
+ xf86SetEntityShared(entityIndex);
+ }
+ xf86AddEntityToScreen(pScrn,entityIndex);
+ if (xf86IsEntityShared(entityIndex)) {
+ return pScrn;
+ }
+ free(pEnt);
+
+ xf86SetEntityFuncs(entityIndex,init,enter,leave,private);
+
+ return pScrn;
+}
+
+ScrnInfoPtr
+xf86ConfigFbEntity(ScrnInfoPtr pScrn, int scrnFlag, int entityIndex,
+ EntityProc init, EntityProc enter, EntityProc leave,
+ pointer private)
+{
+ EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex);
+ if (!pEnt) return pScrn;
+
+ if (!(pEnt->location.type == BUS_NONE)) {
+ free(pEnt);
+ return pScrn;
+ }
+
+ if (!pEnt->active) {
+ xf86ConfigFbEntityInactive(pEnt, init, enter, leave, private);
+ free(pEnt);
+ return pScrn;
+ }
+
+ if (!pScrn)
+ pScrn = xf86AllocateScreen(pEnt->driver,scrnFlag);
+ xf86AddEntityToScreen(pScrn,entityIndex);
+
+ xf86SetEntityFuncs(entityIndex,init,enter,leave,private);
+
+ return pScrn;
+}
+
+/*
+ *
+ * OBSOLETE ! xf86ConfigActivePciEntity() is an obsolete function.
+ * It is likely to be removed. Don't use!
+ */
+
+Bool
+xf86ConfigActivePciEntity(ScrnInfoPtr pScrn, int entityIndex,
+ PciChipsets *p_chip, void *dummy, EntityProc init,
+ EntityProc enter, EntityProc leave, pointer private)
+{
+ EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex);
+ if (!pEnt) return FALSE;
+
+ if (!pEnt->active || !(pEnt->location.type == BUS_PCI)) {
+ free(pEnt);
+ return FALSE;
+ }
+ xf86AddEntityToScreen(pScrn,entityIndex);
+
+ free(pEnt);
+ if (!xf86SetEntityFuncs(entityIndex,init,enter,leave,private))
+ return FALSE;
+
+ return TRUE;
+}
+
+Bool
+xf86IsScreenPrimary(int scrnIndex)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ int i;
+
+ for (i=0 ; i < pScrn->numEntities; i++) {
+ if (xf86IsEntityPrimary(i))
+ return TRUE;
+ }
+ return FALSE;
+}
+
+int
+xf86RegisterRootWindowProperty(int ScrnIndex, Atom property, Atom type,
+ int format, unsigned long len, pointer value )
+{
+ RootWinPropPtr pNewProp = NULL, pRegProp;
+ int i;
+ Bool existing = FALSE;
+
+ DebugF("xf86RegisterRootWindowProperty(%d, %ld, %ld, %d, %ld, %p)\n",
+ ScrnIndex, property, type, format, len, value);
+
+ if (ScrnIndex<0 || ScrnIndex>=xf86NumScreens) {
+ return(BadMatch);
+ }
+
+ if (xf86RegisteredPropertiesTable &&
+ xf86RegisteredPropertiesTable[ScrnIndex]) {
+ for (pNewProp = xf86RegisteredPropertiesTable[ScrnIndex];
+ pNewProp; pNewProp = pNewProp->next) {
+ if (strcmp(pNewProp->name, NameForAtom(property)) == 0)
+ break;
+ }
+ }
+
+ if (!pNewProp) {
+ if ((pNewProp = (RootWinPropPtr)malloc(sizeof(RootWinProp))) == NULL) {
+ return(BadAlloc);
+ }
+ /*
+ * We will put this property at the end of the list so that
+ * the changes are made in the order they were requested.
+ */
+ pNewProp->next = NULL;
+ } else {
+ if (pNewProp->name)
+ free(pNewProp->name);
+ existing = TRUE;
+ }
+
+ pNewProp->name = xnfstrdup(NameForAtom(property));
+ pNewProp->type = type;
+ pNewProp->format = format;
+ pNewProp->size = len;
+ pNewProp->data = value;
+
+ DebugF("new property filled\n");
+
+ if (NULL==xf86RegisteredPropertiesTable) {
+ DebugF("creating xf86RegisteredPropertiesTable[] size %d\n",
+ xf86NumScreens);
+ if ( NULL==(xf86RegisteredPropertiesTable=(RootWinPropPtr*)xnfcalloc(sizeof(RootWinProp),xf86NumScreens) )) {
+ return(BadAlloc);
+ }
+ for (i=0; i<xf86NumScreens; i++) {
+ xf86RegisteredPropertiesTable[i] = NULL;
+ }
+ }
+
+ DebugF("xf86RegisteredPropertiesTable %p\n",
+ (void *)xf86RegisteredPropertiesTable);
+ DebugF("xf86RegisteredPropertiesTable[%d] %p\n",
+ ScrnIndex, (void *)xf86RegisteredPropertiesTable[ScrnIndex]);
+
+ if (!existing) {
+ if ( xf86RegisteredPropertiesTable[ScrnIndex] == NULL) {
+ xf86RegisteredPropertiesTable[ScrnIndex] = pNewProp;
+ } else {
+ pRegProp = xf86RegisteredPropertiesTable[ScrnIndex];
+ while (pRegProp->next != NULL) {
+ DebugF("- next %p\n", (void *)pRegProp);
+ pRegProp = pRegProp->next;
+ }
+ pRegProp->next = pNewProp;
+ }
+ }
+ DebugF("xf86RegisterRootWindowProperty succeeded\n");
+ return(Success);
+}
+
+Bool
+xf86IsUnblank(int mode)
+{
+ switch(mode) {
+ case SCREEN_SAVER_OFF:
+ case SCREEN_SAVER_FORCER:
+ return TRUE;
+ case SCREEN_SAVER_ON:
+ case SCREEN_SAVER_CYCLE:
+ return FALSE;
+ default:
+ xf86MsgVerb(X_WARNING, 0, "Unexpected save screen mode: %d\n", mode);
+ return TRUE;
+ }
+}
+
+void
+xf86MotionHistoryAllocate(LocalDevicePtr local)
+{
+ AllocateMotionHistory(local->dev);
+}
diff --git a/xorg-server/hw/xfree86/common/xf86Init.c b/xorg-server/hw/xfree86/common/xf86Init.c
index 55d7a6209..d78d3d1db 100644
--- a/xorg-server/hw/xfree86/common/xf86Init.c
+++ b/xorg-server/hw/xfree86/common/xf86Init.c
@@ -1,1822 +1,1822 @@
-/*
- * Loosely based on code bearing the following copyright:
- *
- * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
- */
-/*
- * Copyright (c) 1992-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <stdlib.h>
-#include <errno.h>
-
-#undef HAS_UTSNAME
-#if !defined(WIN32)
-#define HAS_UTSNAME 1
-#include <sys/utsname.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xmd.h>
-#include <X11/Xproto.h>
-#include <X11/Xatom.h>
-#include "input.h"
-#include "servermd.h"
-#include "windowstr.h"
-#include "scrnintstr.h"
-#include "site.h"
-#include "mi.h"
-
-#include "compiler.h"
-
-#include "loaderProcs.h"
-#ifdef XFreeXDGA
-#include "dgaproc.h"
-#endif
-
-#define XF86_OS_PRIVS
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86Config.h"
-#include "xf86_OSlib.h"
-#include "xorgVersion.h"
-#include "xf86Build.h"
-#include "mipointer.h"
-#include <X11/extensions/XI.h>
-#include <X11/extensions/XIproto.h>
-#include "xf86DDC.h"
-#include "xf86Xinput.h"
-#include "xf86InPriv.h"
-#include "picturestr.h"
-
-#include "xf86VGAarbiter.h"
-#include "globals.h"
-
-#ifdef DPMSExtension
-#include <X11/extensions/dpmsconst.h>
-#include "dpmsproc.h"
-#endif
-
-#include <pciaccess.h>
-#include "Pci.h"
-#include "xf86Bus.h"
-
-#include <hotplug.h>
-
-/* forward declarations */
-static Bool probe_devices_from_device_sections(DriverPtr drvp);
-static Bool add_matching_devices_to_configure_list(DriverPtr drvp);
-
-#ifdef XF86PM
-void (*xf86OSPMClose)(void) = NULL;
-#endif
-static Bool xorgHWOpenConsole = FALSE;
-
-/* Common pixmap formats */
-
-static PixmapFormatRec formats[MAXFORMATS] = {
- { 1, 1, BITMAP_SCANLINE_PAD },
- { 4, 8, BITMAP_SCANLINE_PAD },
- { 8, 8, BITMAP_SCANLINE_PAD },
- { 15, 16, BITMAP_SCANLINE_PAD },
- { 16, 16, BITMAP_SCANLINE_PAD },
- { 24, 32, BITMAP_SCANLINE_PAD },
- { 32, 32, BITMAP_SCANLINE_PAD },
-};
-static int numFormats = 7;
-static Bool formatsDone = FALSE;
-
-#ifndef OSNAME
-#define OSNAME " unknown"
-#endif
-#ifndef OSVENDOR
-#define OSVENDOR ""
-#endif
-#ifndef PRE_RELEASE
-#define PRE_RELEASE XORG_VERSION_SNAP
-#endif
-
-static void
-xf86PrintBanner(void)
-{
-#if PRE_RELEASE
- xf86ErrorFVerb(0, "\n"
- "This is a pre-release version of the X server from " XVENDORNAME ".\n"
- "It is not supported in any way.\n"
- "Bugs may be filed in the bugzilla at http://bugs.freedesktop.org/.\n"
- "Select the \"xorg\" product for bugs you find in this release.\n"
- "Before reporting bugs in pre-release versions please check the\n"
- "latest version in the X.Org Foundation git repository.\n"
- "See http://wiki.x.org/wiki/GitPage for git access instructions.\n");
-#endif
- xf86ErrorFVerb(0, "\nX.Org X Server %d.%d.%d",
- XORG_VERSION_MAJOR,
- XORG_VERSION_MINOR,
- XORG_VERSION_PATCH);
-#if XORG_VERSION_SNAP > 0
- xf86ErrorFVerb(0, ".%d", XORG_VERSION_SNAP);
-#endif
-
-#if XORG_VERSION_SNAP >= 900
- /* When the minor number is 99, that signifies that the we are making
- * a release candidate for a major version. (X.0.0)
- * When the patch number is 99, that signifies that the we are making
- * a release candidate for a minor version. (X.Y.0)
- * When the patch number is < 99, then we are making a release
- * candidate for the next point release. (X.Y.Z)
- */
-#if XORG_VERSION_MINOR >= 99
- xf86ErrorFVerb(0, " (%d.0.0 RC %d)", XORG_VERSION_MAJOR+1,
- XORG_VERSION_SNAP - 900);
-#elif XORG_VERSION_PATCH == 99
- xf86ErrorFVerb(0, " (%d.%d.0 RC %d)", XORG_VERSION_MAJOR,
- XORG_VERSION_MINOR + 1, XORG_VERSION_SNAP - 900);
-#else
- xf86ErrorFVerb(0, " (%d.%d.%d RC %d)", XORG_VERSION_MAJOR,
- XORG_VERSION_MINOR, XORG_VERSION_PATCH + 1,
- XORG_VERSION_SNAP - 900);
-#endif
-#endif
-
-#ifdef XORG_CUSTOM_VERSION
- xf86ErrorFVerb(0, " (%s)", XORG_CUSTOM_VERSION);
-#endif
-#ifndef XORG_DATE
-# define XORG_DATE "Unknown"
-#endif
- xf86ErrorFVerb(0, "\nRelease Date: %s\n", XORG_DATE);
- xf86ErrorFVerb(0, "X Protocol Version %d, Revision %d\n",
- X_PROTOCOL, X_PROTOCOL_REVISION);
- xf86ErrorFVerb(0, "Build Operating System: %s %s\n", OSNAME, OSVENDOR);
-#ifdef HAS_UTSNAME
- {
- struct utsname name;
-
- /* Linux & BSD state that 0 is success, SysV (including Solaris, HP-UX,
- and Irix) and Single Unix Spec 3 just say that non-negative is success.
- All agree that failure is represented by a negative number.
- */
- if (uname(&name) >= 0) {
- xf86ErrorFVerb(0, "Current Operating System: %s %s %s %s %s\n",
- name.sysname, name.nodename, name.release, name.version, name.machine);
-#ifdef linux
- do {
- char buf[80];
- int fd = open("/proc/cmdline", O_RDONLY);
- if (fd != -1) {
- xf86ErrorFVerb(0, "Kernel command line: ");
- memset(buf, 0, 80);
- while (read(fd, buf, 80) > 0) {
- xf86ErrorFVerb(0, "%.80s", buf);
- memset(buf, 0, 80);
- }
- close(fd);
- }
- } while (0);
-#endif
- }
- }
-#endif
-#if defined(BUILD_DATE) && (BUILD_DATE > 19000000)
- {
- struct tm t;
- char buf[100];
-
- bzero(&t, sizeof(t));
- bzero(buf, sizeof(buf));
- t.tm_mday = BUILD_DATE % 100;
- t.tm_mon = (BUILD_DATE / 100) % 100 - 1;
- t.tm_year = BUILD_DATE / 10000 - 1900;
-#if defined(BUILD_TIME)
- t.tm_sec = BUILD_TIME % 100;
- t.tm_min = (BUILD_TIME / 100) % 100;
- t.tm_hour = (BUILD_TIME / 10000) % 100;
- if (strftime(buf, sizeof(buf), "%d %B %Y %I:%M:%S%p", &t))
- xf86ErrorFVerb(0, "Build Date: %s\n", buf);
-#else
- if (strftime(buf, sizeof(buf), "%d %B %Y", &t))
- xf86ErrorFVerb(0, "Build Date: %s\n", buf);
-#endif
- }
-#endif
-#if defined(BUILDERSTRING)
- xf86ErrorFVerb(0, "%s \n", BUILDERSTRING);
-#endif
- xf86ErrorFVerb(0, "Current version of pixman: %s\n",
- pixman_version_string());
- xf86ErrorFVerb(0, "\tBefore reporting problems, check "
- ""__VENDORDWEBSUPPORT__"\n"
- "\tto make sure that you have the latest version.\n");
-}
-
-static void
-xf86PrintMarkers(void)
-{
- LogPrintMarkers();
-}
-
-static Bool
-xf86CreateRootWindow(WindowPtr pWin)
-{
- int ret = TRUE;
- int err = Success;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- RootWinPropPtr pProp;
- CreateWindowProcPtr CreateWindow = (CreateWindowProcPtr)
- dixLookupPrivate(&pScreen->devPrivates, xf86CreateRootWindowKey);
-
- DebugF("xf86CreateRootWindow(%p)\n", pWin);
-
- if ( pScreen->CreateWindow != xf86CreateRootWindow ) {
- /* Can't find hook we are hung on */
- xf86DrvMsg(pScreen->myNum, X_WARNING /* X_ERROR */,
- "xf86CreateRootWindow %p called when not in pScreen->CreateWindow %p n",
- (void *)xf86CreateRootWindow,
- (void *)pScreen->CreateWindow );
- }
-
- /* Unhook this function ... */
- pScreen->CreateWindow = CreateWindow;
- dixSetPrivate(&pScreen->devPrivates, xf86CreateRootWindowKey, NULL);
-
- /* ... and call the previous CreateWindow fuction, if any */
- if (NULL!=pScreen->CreateWindow) {
- ret = (*pScreen->CreateWindow)(pWin);
- }
-
- /* Now do our stuff */
- if (xf86RegisteredPropertiesTable != NULL) {
- if (pWin->parent == NULL && xf86RegisteredPropertiesTable != NULL) {
- for (pProp = xf86RegisteredPropertiesTable[pScreen->myNum];
- pProp != NULL && err==Success;
- pProp = pProp->next )
- {
- Atom prop;
-
- prop = MakeAtom(pProp->name, strlen(pProp->name), TRUE);
- err = dixChangeWindowProperty(serverClient, pWin,
- prop, pProp->type,
- pProp->format, PropModeReplace,
- pProp->size, pProp->data,
- FALSE);
- }
-
- /* Look at err */
- ret &= (err==Success);
-
- } else {
- xf86Msg(X_ERROR, "xf86CreateRootWindow unexpectedly called with "
- "non-root window %p (parent %p)\n",
- (void *)pWin, (void *)pWin->parent);
- ret = FALSE;
- }
- }
-
- DebugF("xf86CreateRootWindow() returns %d\n", ret);
- return (ret);
-}
-
-
-static void
-InstallSignalHandlers(void)
-{
- /*
- * Install signal handler for unexpected signals
- */
- xf86Info.caughtSignal=FALSE;
- if (!xf86Info.notrapSignals) {
- OsRegisterSigWrapper(xf86SigWrapper);
- } else {
- signal(SIGSEGV, SIG_DFL);
- signal(SIGILL, SIG_DFL);
-#ifdef SIGEMT
- signal(SIGEMT, SIG_DFL);
-#endif
- signal(SIGFPE, SIG_DFL);
-#ifdef SIGBUS
- signal(SIGBUS, SIG_DFL);
-#endif
-#ifdef SIGSYS
- signal(SIGSYS, SIG_DFL);
-#endif
-#ifdef SIGXCPU
- signal(SIGXCPU, SIG_DFL);
-#endif
-#ifdef SIGXFSZ
- signal(SIGXFSZ, SIG_DFL);
-#endif
- }
-}
-
-
-#define END_OF_MATCHES(m) \
- (((m).vendor_id == 0) && ((m).device_id == 0) && ((m).subvendor_id == 0))
-
-Bool
-probe_devices_from_device_sections(DriverPtr drvp)
-{
- int i, j;
- struct pci_device * pPci;
- Bool foundScreen = FALSE;
- const struct pci_id_match * const devices = drvp->supported_devices;
- GDevPtr *devList;
- const unsigned numDevs = xf86MatchDevice(drvp->driverName, & devList);
-
-
- for ( i = 0 ; i < numDevs ; i++ ) {
- struct pci_device_iterator *iter;
- unsigned device_id;
-
-
- /* Find the pciVideoRec associated with this device section.
- */
- iter = pci_id_match_iterator_create(NULL);
- while ((pPci = pci_device_next(iter)) != NULL) {
- if (devList[i]->busID && *devList[i]->busID) {
- if (xf86ComparePciBusString(devList[i]->busID,
- ((pPci->domain << 8)
- | pPci->bus),
- pPci->dev,
- pPci->func)) {
- break;
- }
- }
- else if (xf86IsPrimaryPci(pPci)) {
- break;
- }
- }
-
- pci_iterator_destroy(iter);
-
- if (pPci == NULL) {
- continue;
- }
-
- device_id = (devList[i]->chipID > 0)
- ? devList[i]->chipID : pPci->device_id;
-
-
- /* Once the pciVideoRec is found, determine if the device is supported
- * by the driver. If it is, probe it!
- */
- for ( j = 0 ; ! END_OF_MATCHES( devices[j] ) ; j++ ) {
- if ( PCI_ID_COMPARE( devices[j].vendor_id, pPci->vendor_id )
- && PCI_ID_COMPARE( devices[j].device_id, device_id )
- && ((devices[j].device_class_mask & pPci->device_class)
- == devices[j].device_class) ) {
- int entry;
-
- /* Allow the same entity to be used more than once for
- * devices with multiple screens per entity. This assumes
- * implicitly that there will be a screen == 0 instance.
- *
- * FIXME Need to make sure that two different drivers don't
- * FIXME claim the same screen > 0 instance.
- */
- if ( (devList[i]->screen == 0) && !xf86CheckPciSlot( pPci ) )
- continue;
-
- DebugF("%s: card at %d:%d:%d is claimed by a Device section\n",
- drvp->driverName, pPci->bus, pPci->dev, pPci->func);
-
- /* Allocate an entry in the lists to be returned */
- entry = xf86ClaimPciSlot(pPci, drvp, device_id,
- devList[i], devList[i]->active);
-
- if ((entry == -1) && (devList[i]->screen > 0)) {
- unsigned k;
-
- for ( k = 0; k < xf86NumEntities; k++ ) {
- EntityPtr pEnt = xf86Entities[k];
- if (pEnt->bus.type != BUS_PCI)
- continue;
-
- if (pEnt->bus.id.pci == pPci) {
- entry = k;
- xf86AddDevToEntity(k, devList[i]);
- break;
- }
- }
- }
-
- if (entry != -1) {
- if ((*drvp->PciProbe)(drvp, entry, pPci,
- devices[j].match_data)) {
- foundScreen = TRUE;
- } else
- xf86UnclaimPciSlot(pPci);
- }
-
- break;
- }
- }
- }
- xfree(devList);
-
- return foundScreen;
-}
-
-
-Bool
-add_matching_devices_to_configure_list(DriverPtr drvp)
-{
- const struct pci_id_match * const devices = drvp->supported_devices;
- int j;
- struct pci_device *pPci;
- struct pci_device_iterator *iter;
- int numFound = 0;
-
-
- iter = pci_id_match_iterator_create(NULL);
- while ((pPci = pci_device_next(iter)) != NULL) {
- /* Determine if this device is supported by the driver. If it is,
- * add it to the list of devices to configure.
- */
- for (j = 0 ; ! END_OF_MATCHES(devices[j]) ; j++) {
- if ( PCI_ID_COMPARE( devices[j].vendor_id, pPci->vendor_id )
- && PCI_ID_COMPARE( devices[j].device_id, pPci->device_id )
- && ((devices[j].device_class_mask & pPci->device_class)
- == devices[j].device_class) ) {
- if (xf86CheckPciSlot(pPci)) {
- GDevPtr pGDev = xf86AddBusDeviceToConfigure(
- drvp->driverName, BUS_PCI, pPci, -1);
- if (pGDev != NULL) {
- /* After configure pass 1, chipID and chipRev are
- * treated as over-rides, so clobber them here.
- */
- pGDev->chipID = -1;
- pGDev->chipRev = -1;
- }
-
- numFound++;
- }
-
- break;
- }
- }
- }
-
- pci_iterator_destroy(iter);
-
-
- return (numFound != 0);
-}
-
-/**
- * Call the driver's correct probe function.
- *
- * If the driver implements the \c DriverRec::PciProbe entry-point and an
- * appropriate PCI device (with matching Device section in the xorg.conf file)
- * is found, it is called. If \c DriverRec::PciProbe or no devices can be
- * successfully probed with it (e.g., only non-PCI devices are available),
- * the driver's \c DriverRec::Probe function is called.
- *
- * \param drv Driver to probe
- *
- * \return
- * If a device can be successfully probed by the driver, \c TRUE is
- * returned. Otherwise, \c FALSE is returned.
- */
-Bool
-xf86CallDriverProbe( DriverPtr drv, Bool detect_only )
-{
- Bool foundScreen = FALSE;
-
- if ( drv->PciProbe != NULL ) {
- if ( xf86DoConfigure && xf86DoConfigurePass1 ) {
- assert( detect_only );
- foundScreen = add_matching_devices_to_configure_list( drv );
- }
- else {
- assert( ! detect_only );
- foundScreen = probe_devices_from_device_sections( drv );
- }
- }
-
- if ( ! foundScreen && (drv->Probe != NULL) ) {
- xf86Msg( X_WARNING, "Falling back to old probe method for %s\n",
- drv->driverName );
- foundScreen = (*drv->Probe)( drv, (detect_only) ? PROBE_DETECT
- : PROBE_DEFAULT );
- }
-
- return foundScreen;
-}
-
-/*
- * InitOutput --
- * Initialize screenInfo for all actually accessible framebuffers.
- * That includes vt-manager setup, querying all possible devices and
- * collecting the pixmap formats.
- */
-void
-InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
-{
- int i, j, k, scr_index;
- char **modulelist;
- pointer *optionlist;
- screenLayoutPtr layout;
- Pix24Flags screenpix24, pix24;
- MessageType pix24From = X_DEFAULT;
- Bool pix24Fail = FALSE;
- Bool autoconfig = FALSE;
- GDevPtr configured_device;
-
- xf86Initialising = TRUE;
-
- if (serverGeneration == 1) {
- if ((xf86ServerName = strrchr(argv[0], '/')) != 0)
- xf86ServerName++;
- else
- xf86ServerName = argv[0];
-
- xf86PrintBanner();
- xf86PrintMarkers();
- if (xf86LogFile) {
- time_t t;
- const char *ct;
- t = time(NULL);
- ct = ctime(&t);
- xf86MsgVerb(xf86LogFileFrom, 0, "Log file: \"%s\", Time: %s",
- xf86LogFile, ct);
- }
-
- /* Read and parse the config file */
- if (!xf86DoConfigure && !xf86DoShowOptions) {
- switch (xf86HandleConfigFile(FALSE)) {
- case CONFIG_OK:
- break;
- case CONFIG_PARSE_ERROR:
- xf86Msg(X_ERROR, "Error parsing the config file\n");
- return;
- case CONFIG_NOFILE:
- autoconfig = TRUE;
- break;
- }
- }
-
- InstallSignalHandlers();
-
- /* Initialise the loader */
- LoaderInit();
-
- /* Tell the loader the default module search path */
- LoaderSetPath(xf86ModulePath);
-
- if (xf86Info.ignoreABI) {
- LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL);
- }
-
- if (xf86DoShowOptions)
- DoShowOptions();
-
- /* Do a general bus probe. This will be a PCI probe for x86 platforms */
- xf86BusProbe();
-
- if (xf86DoConfigure)
- DoConfigure();
-
- if (autoconfig) {
- if (!xf86AutoConfig()) {
- xf86Msg(X_ERROR, "Auto configuration failed\n");
- return;
- }
- }
-
-#ifdef XF86PM
- xf86OSPMClose = xf86OSPMOpen();
-#endif
-
- /* Load all modules specified explicitly in the config file */
- if ((modulelist = xf86ModulelistFromConfig(&optionlist))) {
- xf86LoadModules(modulelist, optionlist);
- xfree(modulelist);
- xfree(optionlist);
- }
-
- /* Load all driver modules specified in the config file */
- /* If there aren't any specified in the config file, autoconfig them */
- /* FIXME: Does not handle multiple active screen sections, but I'm not
- * sure if we really want to handle that case*/
- configured_device = xf86ConfigLayout.screens->screen->device;
- if ((!configured_device) || (!configured_device->driver)) {
- if (!autoConfigDevice(configured_device)) {
- xf86Msg(X_ERROR, "Automatic driver configuration failed\n");
- return ;
- }
- }
- if ((modulelist = xf86DriverlistFromConfig())) {
- xf86LoadModules(modulelist, NULL);
- xfree(modulelist);
- }
-
- /* Load all input driver modules specified in the config file. */
- if ((modulelist = xf86InputDriverlistFromConfig())) {
- xf86LoadModules(modulelist, NULL);
- xfree(modulelist);
- }
-
- /*
- * It is expected that xf86AddDriver()/xf86AddInputDriver will be
- * called for each driver as it is loaded. Those functions save the
- * module pointers for drivers.
- * XXX Nothing keeps track of them for other modules.
- */
- /* XXX What do we do if not all of these could be loaded? */
-
- /*
- * At this point, xf86DriverList[] is all filled in with entries for
- * each of the drivers to try and xf86NumDrivers has the number of
- * drivers. If there are none, return now.
- */
-
- if (xf86NumDrivers == 0) {
- xf86Msg(X_ERROR, "No drivers available.\n");
- return;
- }
-
- /*
- * Call each of the Identify functions and call the driverFunc to check
- * if HW access is required. The Identify functions print out some
- * identifying information, and anything else that might be
- * needed at this early stage.
- */
-
- for (i = 0; i < xf86NumDrivers; i++) {
- if (xf86DriverList[i]->Identify != NULL)
- xf86DriverList[i]->Identify(0);
-
- if (!xorgHWAccess || !xorgHWOpenConsole) {
- xorgHWFlags flags;
- if(!xf86DriverList[i]->driverFunc
- || !xf86DriverList[i]->driverFunc(NULL,
- GET_REQUIRED_HW_INTERFACES,
- &flags))
- flags = HW_IO;
-
- if(NEED_IO_ENABLED(flags))
- xorgHWAccess = TRUE;
- if(!(flags & HW_SKIP_CONSOLE))
- xorgHWOpenConsole = TRUE;
- }
- }
-
- if (xorgHWOpenConsole)
- xf86OpenConsole();
- else
- xf86Info.dontVTSwitch = TRUE;
-
- /* Enable full I/O access */
- if (xorgHWAccess)
- xorgHWAccess = xf86EnableIO();
-
- /*
- * Locate bus slot that had register IO enabled at server startup
- */
- if (xorgHWAccess) {
- xf86AccessInit();
- xf86FindPrimaryDevice();
- }
- /*
- * Now call each of the Probe functions. Each successful probe will
- * result in an extra entry added to the xf86Screens[] list for each
- * instance of the hardware found.
- */
-
- for (i = 0; i < xf86NumDrivers; i++) {
- xorgHWFlags flags;
- if (!xorgHWAccess) {
- if (!xf86DriverList[i]->driverFunc
- || !xf86DriverList[i]->driverFunc(NULL,
- GET_REQUIRED_HW_INTERFACES,
- &flags)
- || NEED_IO_ENABLED(flags))
- continue;
- }
-
- xf86CallDriverProbe( xf86DriverList[i], FALSE );
- }
-
- /*
- * If nothing was detected, return now.
- */
-
- if (xf86NumScreens == 0) {
- xf86Msg(X_ERROR, "No devices detected.\n");
- return;
- }
-
- xf86VGAarbiterInit();
-
- /*
- * Match up the screens found by the probes against those specified
- * in the config file. Remove the ones that won't be used. Sort
- * them in the order specified.
- */
-
- /*
- * What is the best way to do this?
- *
- * For now, go through the screens allocated by the probes, and
- * look for screen config entry which refers to the same device
- * section as picked out by the probe.
- *
- */
-
- for (i = 0; i < xf86NumScreens; i++) {
- for (layout = xf86ConfigLayout.screens; layout->screen != NULL;
- layout++) {
- Bool found = FALSE;
- for (j = 0; j < xf86Screens[i]->numEntities; j++) {
-
- GDevPtr dev =
- xf86GetDevFromEntity(xf86Screens[i]->entityList[j],
- xf86Screens[i]->entityInstanceList[j]);
-
- if (dev == layout->screen->device) {
- /* A match has been found */
- xf86Screens[i]->confScreen = layout->screen;
- found = TRUE;
- break;
- }
- }
- if (found) break;
- }
- if (layout->screen == NULL) {
- /* No match found */
- xf86Msg(X_ERROR,
- "Screen %d deleted because of no matching config section.\n", i);
- xf86DeleteScreen(i--, 0);
- }
- }
-
- /*
- * If no screens left, return now.
- */
-
- if (xf86NumScreens == 0) {
- xf86Msg(X_ERROR,
- "Device(s) detected, but none match those in the config file.\n");
- return;
- }
-
- xf86PostProbe();
- xf86EntityInit();
-
- /*
- * Sort the drivers to match the requested ording. Using a slow
- * bubble sort.
- */
- for (j = 0; j < xf86NumScreens - 1; j++) {
- for (i = 0; i < xf86NumScreens - j - 1; i++) {
- if (xf86Screens[i + 1]->confScreen->screennum <
- xf86Screens[i]->confScreen->screennum) {
- ScrnInfoPtr tmpScrn = xf86Screens[i + 1];
- xf86Screens[i + 1] = xf86Screens[i];
- xf86Screens[i] = tmpScrn;
- }
- }
- }
- /* Fix up the indexes */
- for (i = 0; i < xf86NumScreens; i++) {
- xf86Screens[i]->scrnIndex = i;
- }
-
- /*
- * Call the driver's PreInit()'s to complete initialisation for the first
- * generation.
- */
-
- for (i = 0; i < xf86NumScreens; i++) {
- xf86VGAarbiterScrnInit(xf86Screens[i]);
- xf86VGAarbiterLock(xf86Screens[i]);
- if (xf86Screens[i]->PreInit &&
- xf86Screens[i]->PreInit(xf86Screens[i], 0))
- xf86Screens[i]->configured = TRUE;
- xf86VGAarbiterUnlock(xf86Screens[i]);
- }
- for (i = 0; i < xf86NumScreens; i++)
- if (!xf86Screens[i]->configured)
- xf86DeleteScreen(i--, 0);
-
- /*
- * If no screens left, return now.
- */
-
- if (xf86NumScreens == 0) {
- xf86Msg(X_ERROR,
- "Screen(s) found, but none have a usable configuration.\n");
- return;
- }
-
- for (i = 0; i < xf86NumScreens; i++) {
- if (xf86Screens[i]->name == NULL) {
- xf86Screens[i]->name = xnfalloc(strlen("screen") + 10 + 1);
- sprintf(xf86Screens[i]->name, "screen%d", i);
- xf86MsgVerb(X_WARNING, 0,
- "Screen driver %d has no name set, using `%s'.\n",
- i, xf86Screens[i]->name);
- }
- }
-
- /* Remove (unload) drivers that are not required */
- for (i = 0; i < xf86NumDrivers; i++)
- if (xf86DriverList[i] && xf86DriverList[i]->refCount <= 0)
- xf86DeleteDriver(i);
-
- /*
- * At this stage we know how many screens there are.
- */
-
- for (i = 0; i < xf86NumScreens; i++)
- xf86InitViewport(xf86Screens[i]);
-
- /*
- * Collect all pixmap formats and check for conflicts at the display
- * level. Should we die here? Or just delete the offending screens?
- */
- screenpix24 = Pix24DontCare;
- for (i = 0; i < xf86NumScreens; i++) {
- if (xf86Screens[i]->imageByteOrder !=
- xf86Screens[0]->imageByteOrder)
- FatalError("Inconsistent display bitmapBitOrder. Exiting\n");
- if (xf86Screens[i]->bitmapScanlinePad !=
- xf86Screens[0]->bitmapScanlinePad)
- FatalError("Inconsistent display bitmapScanlinePad. Exiting\n");
- if (xf86Screens[i]->bitmapScanlineUnit !=
- xf86Screens[0]->bitmapScanlineUnit)
- FatalError("Inconsistent display bitmapScanlineUnit. Exiting\n");
- if (xf86Screens[i]->bitmapBitOrder !=
- xf86Screens[0]->bitmapBitOrder)
- FatalError("Inconsistent display bitmapBitOrder. Exiting\n");
-
- /* Determine the depth 24 pixmap format the screens would like */
- if (xf86Screens[i]->pixmap24 != Pix24DontCare) {
- if (screenpix24 == Pix24DontCare)
- screenpix24 = xf86Screens[i]->pixmap24;
- else if (screenpix24 != xf86Screens[i]->pixmap24)
- FatalError("Inconsistent depth 24 pixmap format. Exiting\n");
- }
- }
- /* check if screenpix24 is consistent with the config/cmdline */
- if (xf86Info.pixmap24 != Pix24DontCare) {
- pix24 = xf86Info.pixmap24;
- pix24From = xf86Info.pix24From;
- if (screenpix24 != Pix24DontCare && screenpix24 != xf86Info.pixmap24)
- pix24Fail = TRUE;
- } else if (screenpix24 != Pix24DontCare) {
- pix24 = screenpix24;
- pix24From = X_PROBED;
- } else
- pix24 = Pix24Use32;
-
- if (pix24Fail)
- FatalError("Screen(s) can't use the required depth 24 pixmap format"
- " (%d). Exiting\n", PIX24TOBPP(pix24));
-
- /* Initialise the depth 24 format */
- for (j = 0; j < numFormats && formats[j].depth != 24; j++)
- ;
- formats[j].bitsPerPixel = PIX24TOBPP(pix24);
-
- /* Collect additional formats */
- for (i = 0; i < xf86NumScreens; i++) {
- for (j = 0; j < xf86Screens[i]->numFormats; j++) {
- for (k = 0; ; k++) {
- if (k >= numFormats) {
- if (k >= MAXFORMATS)
- FatalError("Too many pixmap formats! Exiting\n");
- formats[k] = xf86Screens[i]->formats[j];
- numFormats++;
- break;
- }
- if (formats[k].depth == xf86Screens[i]->formats[j].depth) {
- if ((formats[k].bitsPerPixel ==
- xf86Screens[i]->formats[j].bitsPerPixel) &&
- (formats[k].scanlinePad ==
- xf86Screens[i]->formats[j].scanlinePad))
- break;
- FatalError("Inconsistent pixmap format for depth %d."
- " Exiting\n", formats[k].depth);
- }
- }
- }
- }
- formatsDone = TRUE;
-
- if (xf86Info.vtno >= 0 ) {
-#define VT_ATOM_NAME "XFree86_VT"
- Atom VTAtom=-1;
- CARD32 *VT = NULL;
- int ret;
-
- /* This memory needs to stay available until the screen has been
- initialized, and we can create the property for real.
- */
- if ( (VT = xalloc(sizeof(CARD32)))==NULL ) {
- FatalError("Unable to make VT property - out of memory. Exiting...\n");
- }
- *VT = xf86Info.vtno;
-
- VTAtom = MakeAtom(VT_ATOM_NAME, sizeof(VT_ATOM_NAME) - 1, TRUE);
-
- for (i = 0, ret = Success; i < xf86NumScreens && ret == Success; i++) {
- ret = xf86RegisterRootWindowProperty(xf86Screens[i]->scrnIndex,
- VTAtom, XA_INTEGER, 32,
- 1, VT );
- if (ret != Success)
- xf86DrvMsg(xf86Screens[i]->scrnIndex, X_WARNING,
- "Failed to register VT property\n");
- }
- }
-
- /* If a screen uses depth 24, show what the pixmap format is */
- for (i = 0; i < xf86NumScreens; i++) {
- if (xf86Screens[i]->depth == 24) {
- xf86Msg(pix24From, "Depth 24 pixmap format is %d bpp\n",
- PIX24TOBPP(pix24));
- break;
- }
- }
- } else {
- /*
- * serverGeneration != 1; some OSs have to do things here, too.
- */
- if (xorgHWOpenConsole)
- xf86OpenConsole();
-
-#ifdef XF86PM
- /*
- should we reopen it here? We need to deal with an already opened
- device. We could leave this to the OS layer. For now we simply
- close it here
- */
- if (xf86OSPMClose)
- xf86OSPMClose();
- if ((xf86OSPMClose = xf86OSPMOpen()) != NULL)
- xf86MsgVerb(X_INFO, 3, "APM registered successfully\n");
-#endif
-
- /* Make sure full I/O access is enabled */
- if (xorgHWAccess)
- xf86EnableIO();
- }
-
- /*
- * Use the previously collected parts to setup pScreenInfo
- */
-
- pScreenInfo->imageByteOrder = xf86Screens[0]->imageByteOrder;
- pScreenInfo->bitmapScanlinePad = xf86Screens[0]->bitmapScanlinePad;
- pScreenInfo->bitmapScanlineUnit = xf86Screens[0]->bitmapScanlineUnit;
- pScreenInfo->bitmapBitOrder = xf86Screens[0]->bitmapBitOrder;
- pScreenInfo->numPixmapFormats = numFormats;
- for (i = 0; i < numFormats; i++)
- pScreenInfo->formats[i] = formats[i];
-
- /* Make sure the server's VT is active */
-
- if (serverGeneration != 1) {
- xf86Resetting = TRUE;
- /* All screens are in the same state, so just check the first */
- if (!xf86Screens[0]->vtSema) {
-#ifdef HAS_USL_VTS
- ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ);
-#endif
- xf86AccessEnter();
- xf86EnterServerState(SETUP);
- }
- }
-#ifdef SCO325
- else {
- /*
- * Under SCO we must ack that we got the console at startup,
- * I think this is the safest way to assure it.
- */
- static int once = 1;
- if (once) {
- once = 0;
- if (ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ) < 0)
- xf86Msg(X_WARNING, "VT_ACKACQ failed");
- }
- }
-#endif /* SCO325 */
-
- for (i = 0; i < xf86NumScreens; i++) {
- xf86VGAarbiterLock(xf86Screens[i]);
- /*
- * Almost everything uses these defaults, and many of those that
- * don't, will wrap them.
- */
- xf86Screens[i]->EnableDisableFBAccess = xf86EnableDisableFBAccess;
-#ifdef XFreeXDGA
- xf86Screens[i]->SetDGAMode = xf86SetDGAMode;
-#endif
- xf86Screens[i]->DPMSSet = NULL;
- xf86Screens[i]->LoadPalette = NULL;
- xf86Screens[i]->SetOverscan = NULL;
- xf86Screens[i]->DriverFunc = NULL;
- xf86Screens[i]->pScreen = NULL;
- scr_index = AddScreen(xf86Screens[i]->ScreenInit, argc, argv);
- xf86VGAarbiterUnlock(xf86Screens[i]);
- if (scr_index == i) {
- /*
- * Hook in our ScrnInfoRec, and initialise some other pScreen
- * fields.
- */
- dixSetPrivate(&screenInfo.screens[scr_index]->devPrivates,
- xf86ScreenKey, xf86Screens[i]);
- xf86Screens[i]->pScreen = screenInfo.screens[scr_index];
- /* The driver should set this, but make sure it is set anyway */
- xf86Screens[i]->vtSema = TRUE;
- } else {
- /* This shouldn't normally happen */
- FatalError("AddScreen/ScreenInit failed for driver %d\n", i);
- }
-
- DebugF("InitOutput - xf86Screens[%d]->pScreen = %p\n",
- i, xf86Screens[i]->pScreen );
- DebugF("xf86Screens[%d]->pScreen->CreateWindow = %p\n",
- i, xf86Screens[i]->pScreen->CreateWindow );
-
- dixSetPrivate(&screenInfo.screens[scr_index]->devPrivates,
- xf86CreateRootWindowKey,
- xf86Screens[i]->pScreen->CreateWindow);
- xf86Screens[i]->pScreen->CreateWindow = xf86CreateRootWindow;
-
- if (PictureGetSubpixelOrder (xf86Screens[i]->pScreen) == SubPixelUnknown)
- {
- xf86MonPtr DDC = (xf86MonPtr)(xf86Screens[i]->monitor->DDC);
- PictureSetSubpixelOrder (xf86Screens[i]->pScreen,
- DDC ?
- (DDC->features.input_type ?
- SubPixelHorizontalRGB : SubPixelNone) :
- SubPixelUnknown);
- }
-#ifdef RANDR
- if (!xf86Info.disableRandR)
- xf86RandRInit (screenInfo.screens[scr_index]);
- xf86Msg(xf86Info.randRFrom, "RandR %s\n",
- xf86Info.disableRandR ? "disabled" : "enabled");
-#endif
- }
-
- xf86PostScreenInit();
-
- xf86InitOrigins();
-
- xf86Resetting = FALSE;
- xf86Initialising = FALSE;
-
- RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, xf86Wakeup,
- NULL);
-}
-
-/*
- * InitInput --
- * Initialize all supported input devices.
- */
-
-void
-InitInput(int argc, char **argv)
-{
- IDevPtr* pDev;
- DeviceIntPtr dev;
-
- xf86Info.vtRequestsPending = FALSE;
-
- mieqInit();
-
- GetEventList(&xf86Events);
-
- /* Call the PreInit function for each input device instance. */
- for (pDev = xf86ConfigLayout.inputs; pDev && *pDev; pDev++) {
- /* Replace obsolete keyboard driver with kbd */
- if (!xf86NameCmp((*pDev)->driver, "keyboard")) {
- strcpy((*pDev)->driver, "kbd");
- }
-
- /* If one fails, the others will too */
- if (xf86NewInputDevice(*pDev, &dev, TRUE) == BadAlloc)
- break;
- }
-
- config_init();
-}
-
-void
-CloseInput (void)
-{
- config_fini();
-}
-
-/*
- * OsVendorInit --
- * OS/Vendor-specific initialisations. Called from OsInit(), which
- * is called by dix before establishing the well known sockets.
- */
-
-void
-OsVendorInit(void)
-{
- static Bool beenHere = FALSE;
-
-#ifdef SIGCHLD
- signal(SIGCHLD, SIG_DFL); /* Need to wait for child processes */
-#endif
-
- if (!beenHere) {
- umask(022);
- xf86LogInit();
- }
-
- /* Set stderr to non-blocking. */
-#ifndef O_NONBLOCK
-#if defined(FNDELAY)
-#define O_NONBLOCK FNDELAY
-#elif defined(O_NDELAY)
-#define O_NONBLOCK O_NDELAY
-#endif
-
-#ifdef O_NONBLOCK
- if (!beenHere) {
- if (geteuid() == 0 && getuid() != geteuid())
- {
- int status;
-
- status = fcntl(fileno(stderr), F_GETFL, 0);
- if (status != -1) {
- fcntl(fileno(stderr), F_SETFL, status | O_NONBLOCK);
- }
- }
- }
-#endif
-#endif
-
- beenHere = TRUE;
-}
-
-/*
- * ddxGiveUp --
- * Device dependent cleanup. Called by by dix before normal server death.
- * For SYSV386 we must switch the terminal back to normal mode. No error-
- * checking here, since there should be restored as much as possible.
- */
-
-void
-ddxGiveUp(void)
-{
- int i;
-
- xf86VGAarbiterFini();
-
-#ifdef XF86PM
- if (xf86OSPMClose)
- xf86OSPMClose();
- xf86OSPMClose = NULL;
-#endif
-
- for (i = 0; i < xf86NumScreens; i++) {
- /*
- * zero all access functions to
- * trap calls when switched away.
- */
- xf86Screens[i]->vtSema = FALSE;
- }
-
-#ifdef XFreeXDGA
- DGAShutdown();
-#endif
-
- if (xorgHWOpenConsole)
- xf86CloseConsole();
-
- xf86CloseLog();
-
- /* If an unexpected signal was caught, dump a core for debugging */
- if (xf86Info.caughtSignal)
- OsAbort();
-}
-
-
-
-/*
- * AbortDDX --
- * DDX - specific abort routine. Called by AbortServer(). The attempt is
- * made to restore all original setting of the displays. Also all devices
- * are closed.
- */
-
-void
-AbortDDX(void)
-{
- int i;
-
- /*
- * try to restore the original video state
- */
-#ifdef DPMSExtension /* Turn screens back on */
- if (DPMSPowerLevel != DPMSModeOn)
- DPMSSet(serverClient, DPMSModeOn);
-#endif
- if (xf86Screens) {
- if (xf86Screens[0]->vtSema)
- xf86EnterServerState(SETUP);
- for (i = 0; i < xf86NumScreens; i++)
- if (xf86Screens[i]->vtSema) {
- /*
- * if we are aborting before ScreenInit() has finished
- * we might not have been wrapped yet. Therefore enable
- * screen explicitely.
- */
- xf86VGAarbiterLock(xf86Screens[i]);
- (xf86Screens[i]->LeaveVT)(i, 0);
- xf86VGAarbiterUnlock(xf86Screens[i]);
- }
- }
-
- xf86AccessLeave();
-
- /*
- * This is needed for an abnormal server exit, since the normal exit stuff
- * MUST also be performed (i.e. the vt must be left in a defined state)
- */
- ddxGiveUp();
-}
-
-void
-OsVendorFatalError(void)
-{
-#ifdef VENDORSUPPORT
- ErrorF("\nPlease refer to your Operating System Vendor support pages\n"
- "at %s for support on this crash.\n",VENDORSUPPORT);
-#else
- ErrorF("\nPlease consult the "XVENDORNAME" support \n"
- "\t at "__VENDORDWEBSUPPORT__"\n for help. \n");
-#endif
- if (xf86LogFile && xf86LogFileWasOpened)
- ErrorF("Please also check the log file at \"%s\" for additional "
- "information.\n", xf86LogFile);
- ErrorF("\n");
-}
-
-int
-xf86SetVerbosity(int verb)
-{
- int save = xf86Verbose;
-
- xf86Verbose = verb;
- LogSetParameter(XLOG_VERBOSITY, verb);
- return save;
-}
-
-int
-xf86SetLogVerbosity(int verb)
-{
- int save = xf86LogVerbose;
-
- xf86LogVerbose = verb;
- LogSetParameter(XLOG_FILE_VERBOSITY, verb);
- return save;
-}
-
-static void
-xf86PrintDefaultModulePath(void)
-{
- ErrorF("%s\n", DEFAULT_MODULE_PATH);
-}
-
-static void
-xf86PrintDefaultLibraryPath(void)
-{
- ErrorF("%s\n", DEFAULT_LIBRARY_PATH);
-}
-
-/*
- * ddxProcessArgument --
- * Process device-dependent command line args. Returns 0 if argument is
- * not device dependent, otherwise Count of number of elements of argv
- * that are part of a device dependent commandline option.
- *
- */
-
-/* ARGSUSED */
-int
-ddxProcessArgument(int argc, char **argv, int i)
-{
- /*
- * Note: can't use xalloc/xfree here because OsInit() hasn't been called
- * yet. Use malloc/free instead.
- */
-
-#define CHECK_FOR_REQUIRED_ARGUMENT() \
- if (((i + 1) >= argc) || (!argv[i + 1])) { \
- ErrorF("Required argument to %s not specified\n", argv[i]); \
- UseMsg(); \
- FatalError("Required argument to %s not specified\n", argv[i]); \
- }
-
- /* First the options that are only allowed for root */
- if (!strcmp(argv[i], "-modulepath") || !strcmp(argv[i], "-logfile")) {
- if ( (geteuid() == 0) && (getuid() != 0) ) {
- FatalError("The '%s' option can only be used by root.\n", argv[i]);
- }
- else if (!strcmp(argv[i], "-modulepath"))
- {
- char *mp;
- CHECK_FOR_REQUIRED_ARGUMENT();
- mp = malloc(strlen(argv[i + 1]) + 1);
- if (!mp)
- FatalError("Can't allocate memory for ModulePath\n");
- strcpy(mp, argv[i + 1]);
- xf86ModulePath = mp;
- xf86ModPathFrom = X_CMDLINE;
- return 2;
- }
- else if (!strcmp(argv[i], "-logfile"))
- {
- char *lf;
- CHECK_FOR_REQUIRED_ARGUMENT();
- lf = malloc(strlen(argv[i + 1]) + 1);
- if (!lf)
- FatalError("Can't allocate memory for LogFile\n");
- strcpy(lf, argv[i + 1]);
- xf86LogFile = lf;
- xf86LogFileFrom = X_CMDLINE;
- return 2;
- }
- }
- if (!strcmp(argv[i], "-config") || !strcmp(argv[i], "-xf86config"))
- {
- CHECK_FOR_REQUIRED_ARGUMENT();
- if (getuid() != 0 && !xf86PathIsSafe(argv[i + 1])) {
- FatalError("\nInvalid argument for %s\n"
- "\tFor non-root users, the file specified with %s must be\n"
- "\ta relative path and must not contain any \"..\" elements.\n"
- "\tUsing default "__XCONFIGFILE__" search path.\n\n",
- argv[i], argv[i]);
- }
- xf86ConfigFile = argv[i + 1];
- return 2;
- }
- if (!strcmp(argv[i], "-configdir"))
- {
- CHECK_FOR_REQUIRED_ARGUMENT();
- if (getuid() != 0 && !xf86PathIsSafe(argv[i + 1])) {
- FatalError("\nInvalid argument for %s\n"
- "\tFor non-root users, the file specified with %s must be\n"
- "\ta relative path and must not contain any \"..\" elements.\n"
- "\tUsing default "__XCONFIGDIR__" search path.\n\n",
- argv[i], argv[i]);
- }
- xf86ConfigDir = argv[i + 1];
- return 2;
- }
- if (!strcmp(argv[i],"-flipPixels"))
- {
- xf86FlipPixels = TRUE;
- return 1;
- }
-#ifdef XF86VIDMODE
- if (!strcmp(argv[i],"-disableVidMode"))
- {
- xf86VidModeDisabled = TRUE;
- return 1;
- }
- if (!strcmp(argv[i],"-allowNonLocalXvidtune"))
- {
- xf86VidModeAllowNonLocal = TRUE;
- return 1;
- }
-#endif
- if (!strcmp(argv[i],"-allowMouseOpenFail"))
- {
- xf86AllowMouseOpenFail = TRUE;
- return 1;
- }
- if (!strcmp(argv[i],"-ignoreABI"))
- {
- LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL);
- return 1;
- }
- if (!strcmp(argv[i],"-verbose"))
- {
- if (++i < argc && argv[i])
- {
- char *end;
- long val;
- val = strtol(argv[i], &end, 0);
- if (*end == '\0')
- {
- xf86SetVerbosity(val);
- return 2;
- }
- }
- xf86SetVerbosity(++xf86Verbose);
- return 1;
- }
- if (!strcmp(argv[i],"-logverbose"))
- {
- if (++i < argc && argv[i])
- {
- char *end;
- long val;
- val = strtol(argv[i], &end, 0);
- if (*end == '\0')
- {
- xf86SetLogVerbosity(val);
- return 2;
- }
- }
- xf86SetLogVerbosity(++xf86LogVerbose);
- return 1;
- }
- if (!strcmp(argv[i],"-quiet"))
- {
- xf86SetVerbosity(-1);
- return 1;
- }
- if (!strcmp(argv[i],"-showconfig") || !strcmp(argv[i],"-version"))
- {
- xf86PrintBanner();
- exit(0);
- }
- if (!strcmp(argv[i],"-showDefaultModulePath"))
- {
- xf86PrintDefaultModulePath();
- exit(0);
- }
- if (!strcmp(argv[i],"-showDefaultLibPath"))
- {
- xf86PrintDefaultLibraryPath();
- exit(0);
- }
- /* Notice the -fp flag, but allow it to pass to the dix layer */
- if (!strcmp(argv[i], "-fp"))
- {
- xf86fpFlag = TRUE;
- return 0;
- }
- /* Notice the -bs flag, but allow it to pass to the dix layer */
- if (!strcmp(argv[i], "-bs"))
- {
- xf86bsDisableFlag = TRUE;
- return 0;
- }
- /* Notice the +bs flag, but allow it to pass to the dix layer */
- if (!strcmp(argv[i], "+bs"))
- {
- xf86bsEnableFlag = TRUE;
- return 0;
- }
- /* Notice the -s flag, but allow it to pass to the dix layer */
- if (!strcmp(argv[i], "-s"))
- {
- xf86sFlag = TRUE;
- return 0;
- }
- if (!strcmp(argv[i], "-pixmap24"))
- {
- xf86Pix24 = Pix24Use24;
- return 1;
- }
- if (!strcmp(argv[i], "-pixmap32"))
- {
- xf86Pix24 = Pix24Use32;
- return 1;
- }
- if (!strcmp(argv[i], "-fbbpp"))
- {
- int bpp;
- CHECK_FOR_REQUIRED_ARGUMENT();
- if (sscanf(argv[++i], "%d", &bpp) == 1)
- {
- xf86FbBpp = bpp;
- return 2;
- }
- else
- {
- ErrorF("Invalid fbbpp\n");
- return 0;
- }
- }
- if (!strcmp(argv[i], "-depth"))
- {
- int depth;
- CHECK_FOR_REQUIRED_ARGUMENT();
- if (sscanf(argv[++i], "%d", &depth) == 1)
- {
- xf86Depth = depth;
- return 2;
- }
- else
- {
- ErrorF("Invalid depth\n");
- return 0;
- }
- }
- if (!strcmp(argv[i], "-weight"))
- {
- int red, green, blue;
- CHECK_FOR_REQUIRED_ARGUMENT();
- if (sscanf(argv[++i], "%1d%1d%1d", &red, &green, &blue) == 3)
- {
- xf86Weight.red = red;
- xf86Weight.green = green;
- xf86Weight.blue = blue;
- return 2;
- }
- else
- {
- ErrorF("Invalid weighting\n");
- return 0;
- }
- }
- if (!strcmp(argv[i], "-gamma") || !strcmp(argv[i], "-rgamma") ||
- !strcmp(argv[i], "-ggamma") || !strcmp(argv[i], "-bgamma"))
- {
- double gamma;
- CHECK_FOR_REQUIRED_ARGUMENT();
- if (sscanf(argv[++i], "%lf", &gamma) == 1) {
- if (gamma < GAMMA_MIN || gamma > GAMMA_MAX) {
- ErrorF("gamma out of range, only %.2f <= gamma_value <= %.1f"
- " is valid\n", GAMMA_MIN, GAMMA_MAX);
- return 0;
- }
- if (!strcmp(argv[i-1], "-gamma"))
- xf86Gamma.red = xf86Gamma.green = xf86Gamma.blue = gamma;
- else if (!strcmp(argv[i-1], "-rgamma")) xf86Gamma.red = gamma;
- else if (!strcmp(argv[i-1], "-ggamma")) xf86Gamma.green = gamma;
- else if (!strcmp(argv[i-1], "-bgamma")) xf86Gamma.blue = gamma;
- return 2;
- }
- }
- if (!strcmp(argv[i], "-layout"))
- {
- CHECK_FOR_REQUIRED_ARGUMENT();
- xf86LayoutName = argv[++i];
- return 2;
- }
- if (!strcmp(argv[i], "-screen"))
- {
- CHECK_FOR_REQUIRED_ARGUMENT();
- xf86ScreenName = argv[++i];
- return 2;
- }
- if (!strcmp(argv[i], "-pointer"))
- {
- CHECK_FOR_REQUIRED_ARGUMENT();
- xf86PointerName = argv[++i];
- return 2;
- }
- if (!strcmp(argv[i], "-keyboard"))
- {
- CHECK_FOR_REQUIRED_ARGUMENT();
- xf86KeyboardName = argv[++i];
- return 2;
- }
- if (!strcmp(argv[i], "-nosilk"))
- {
- xf86silkenMouseDisableFlag = TRUE;
- return 1;
- }
-#ifdef HAVE_ACPI
- if (!strcmp(argv[i], "-noacpi"))
- {
- xf86acpiDisableFlag = TRUE;
- return 1;
- }
-#endif
- if (!strcmp(argv[i], "-configure"))
- {
- if (getuid() != 0 && geteuid() == 0) {
- ErrorF("The '-configure' option can only be used by root.\n");
- exit(1);
- }
- xf86DoConfigure = TRUE;
- xf86AllowMouseOpenFail = TRUE;
- return 1;
- }
- if (!strcmp(argv[i], "-showopts"))
- {
- if (getuid() != 0 && geteuid() == 0) {
- ErrorF("The '-showopts' option can only be used by root.\n");
- exit(1);
- }
- xf86DoShowOptions = TRUE;
- return 1;
- }
- if (!strcmp(argv[i], "-isolateDevice"))
- {
- int bus, device, func;
- CHECK_FOR_REQUIRED_ARGUMENT();
- if (strncmp(argv[++i], "PCI:", 4)) {
- FatalError("Bus types other than PCI not yet isolable\n");
- }
- if (sscanf(argv[i], "PCI:%d:%d:%d", &bus, &device, &func) == 3) {
- xf86IsolateDevice.domain = PCI_DOM_FROM_BUS(bus);
- xf86IsolateDevice.bus = PCI_BUS_NO_DOMAIN(bus);
- xf86IsolateDevice.dev = device;
- xf86IsolateDevice.func = func;
- return 2;
- } else {
- FatalError("Invalid isolated device specification\n");
- }
- }
- /* Notice cmdline xkbdir, but pass to dix as well */
- if (!strcmp(argv[i], "-xkbdir"))
- {
- xf86xkbdirFlag = TRUE;
- return 0;
- }
-
- /* OS-specific processing */
- return xf86ProcessArgument(argc, argv, i);
-}
-
-/*
- * ddxUseMsg --
- * Print out correct use of device dependent commandline options.
- * Maybe the user now knows what really to do ...
- */
-
-void
-ddxUseMsg(void)
-{
- ErrorF("\n");
- ErrorF("\n");
- ErrorF("Device Dependent Usage\n");
- if (getuid() == 0 || geteuid() != 0)
- {
- ErrorF("-modulepath paths specify the module search path\n");
- ErrorF("-logfile file specify a log file name\n");
- ErrorF("-configure probe for devices and write an "__XCONFIGFILE__"\n");
- ErrorF("-showopts print available options for all installed drivers\n");
- }
- ErrorF("-config file specify a configuration file, relative to the\n");
- ErrorF(" "__XCONFIGFILE__" search path, only root can use absolute\n");
- ErrorF("-configdir dir specify a configuration directory, relative to the\n");
- ErrorF(" "__XCONFIGDIR__" search path, only root can use absolute\n");
- ErrorF("-verbose [n] verbose startup messages\n");
- ErrorF("-logverbose [n] verbose log messages\n");
- ErrorF("-quiet minimal startup messages\n");
- ErrorF("-pixmap24 use 24bpp pixmaps for depth 24\n");
- ErrorF("-pixmap32 use 32bpp pixmaps for depth 24\n");
- ErrorF("-fbbpp n set bpp for the framebuffer. Default: 8\n");
- ErrorF("-depth n set colour depth. Default: 8\n");
- ErrorF("-gamma f set gamma value (0.1 < f < 10.0) Default: 1.0\n");
- ErrorF("-rgamma f set gamma value for red phase\n");
- ErrorF("-ggamma f set gamma value for green phase\n");
- ErrorF("-bgamma f set gamma value for blue phase\n");
- ErrorF("-weight nnn set RGB weighting at 16 bpp. Default: 565\n");
- ErrorF("-layout name specify the ServerLayout section name\n");
- ErrorF("-screen name specify the Screen section name\n");
- ErrorF("-keyboard name specify the core keyboard InputDevice name\n");
- ErrorF("-pointer name specify the core pointer InputDevice name\n");
- ErrorF("-nosilk disable Silken Mouse\n");
- ErrorF("-flipPixels swap default black/white Pixel values\n");
-#ifdef XF86VIDMODE
- ErrorF("-disableVidMode disable mode adjustments with xvidtune\n");
- ErrorF("-allowNonLocalXvidtune allow xvidtune to be run as a non-local client\n");
-#endif
- ErrorF("-allowMouseOpenFail start server even if the mouse can't be initialized\n");
- ErrorF("-ignoreABI make module ABI mismatches non-fatal\n");
- ErrorF("-isolateDevice bus_id restrict device resets to bus_id (PCI only)\n");
- ErrorF("-version show the server version\n");
- ErrorF("-showDefaultModulePath show the server default module path\n");
- ErrorF("-showDefaultLibPath show the server default library path\n");
- /* OS-specific usage */
- xf86UseMsg();
- ErrorF("\n");
-}
-
-
-/*
- * xf86LoadModules iterates over a list that is being passed in.
- */
-Bool
-xf86LoadModules(char **list, pointer *optlist)
-{
- int errmaj, errmin;
- pointer opt;
- int i;
- char *name;
- Bool failed = FALSE;
-
- if (!list)
- return TRUE;
-
- for (i = 0; list[i] != NULL; i++) {
-
- /* Normalise the module name */
- name = xf86NormalizeName(list[i]);
-
- /* Skip empty names */
- if (name == NULL || *name == '\0')
- continue;
-
- /* Replace obsolete keyboard driver with kbd */
- if (!xf86NameCmp(name, "keyboard")) {
- strcpy(name, "kbd");
- }
-
- if (optlist)
- opt = optlist[i];
- else
- opt = NULL;
-
- if (!LoadModule(name, NULL, NULL, NULL, opt, NULL, &errmaj, &errmin)) {
- LoaderErrorMsg(NULL, name, errmaj, errmin);
- failed = TRUE;
- }
- xfree(name);
- }
- return !failed;
-}
-
-/* Pixmap format stuff */
-
-PixmapFormatPtr
-xf86GetPixFormat(ScrnInfoPtr pScrn, int depth)
-{
- int i;
- static PixmapFormatRec format; /* XXX not reentrant */
-
- /*
- * When the formats[] list initialisation isn't complete, check the
- * depth 24 pixmap config/cmdline options and screen-specified formats.
- */
-
- if (!formatsDone) {
- if (depth == 24) {
- Pix24Flags pix24 = Pix24DontCare;
-
- format.depth = 24;
- format.scanlinePad = BITMAP_SCANLINE_PAD;
- if (xf86Info.pixmap24 != Pix24DontCare)
- pix24 = xf86Info.pixmap24;
- else if (pScrn->pixmap24 != Pix24DontCare)
- pix24 = pScrn->pixmap24;
- if (pix24 == Pix24Use24)
- format.bitsPerPixel = 24;
- else
- format.bitsPerPixel = 32;
- return &format;
- }
- }
-
- for (i = 0; i < numFormats; i++)
- if (formats[i].depth == depth)
- break;
- if (i != numFormats)
- return &formats[i];
- else if (!formatsDone) {
- /* Check for screen-specified formats */
- for (i = 0; i < pScrn->numFormats; i++)
- if (pScrn->formats[i].depth == depth)
- break;
- if (i != pScrn->numFormats)
- return &pScrn->formats[i];
- }
- return NULL;
-}
-
-int
-xf86GetBppFromDepth(ScrnInfoPtr pScrn, int depth)
-{
- PixmapFormatPtr format;
-
-
- format = xf86GetPixFormat(pScrn, depth);
- if (format)
- return format->bitsPerPixel;
- else
- return 0;
-}
+/*
+ * Loosely based on code bearing the following copyright:
+ *
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+ */
+/*
+ * Copyright (c) 1992-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <stdlib.h>
+#include <errno.h>
+
+#undef HAS_UTSNAME
+#if !defined(WIN32)
+#define HAS_UTSNAME 1
+#include <sys/utsname.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xmd.h>
+#include <X11/Xproto.h>
+#include <X11/Xatom.h>
+#include "input.h"
+#include "servermd.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "site.h"
+#include "mi.h"
+
+#include "compiler.h"
+
+#include "loaderProcs.h"
+#ifdef XFreeXDGA
+#include "dgaproc.h"
+#endif
+
+#define XF86_OS_PRIVS
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86Config.h"
+#include "xf86_OSlib.h"
+#include "xorgVersion.h"
+#include "xf86Build.h"
+#include "mipointer.h"
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XIproto.h>
+#include "xf86DDC.h"
+#include "xf86Xinput.h"
+#include "xf86InPriv.h"
+#include "picturestr.h"
+
+#include "xf86VGAarbiter.h"
+#include "globals.h"
+
+#ifdef DPMSExtension
+#include <X11/extensions/dpmsconst.h>
+#include "dpmsproc.h"
+#endif
+
+#include <pciaccess.h>
+#include "Pci.h"
+#include "xf86Bus.h"
+
+#include <hotplug.h>
+
+/* forward declarations */
+static Bool probe_devices_from_device_sections(DriverPtr drvp);
+static Bool add_matching_devices_to_configure_list(DriverPtr drvp);
+
+#ifdef XF86PM
+void (*xf86OSPMClose)(void) = NULL;
+#endif
+static Bool xorgHWOpenConsole = FALSE;
+
+/* Common pixmap formats */
+
+static PixmapFormatRec formats[MAXFORMATS] = {
+ { 1, 1, BITMAP_SCANLINE_PAD },
+ { 4, 8, BITMAP_SCANLINE_PAD },
+ { 8, 8, BITMAP_SCANLINE_PAD },
+ { 15, 16, BITMAP_SCANLINE_PAD },
+ { 16, 16, BITMAP_SCANLINE_PAD },
+ { 24, 32, BITMAP_SCANLINE_PAD },
+ { 32, 32, BITMAP_SCANLINE_PAD },
+};
+static int numFormats = 7;
+static Bool formatsDone = FALSE;
+
+#ifndef OSNAME
+#define OSNAME " unknown"
+#endif
+#ifndef OSVENDOR
+#define OSVENDOR ""
+#endif
+#ifndef PRE_RELEASE
+#define PRE_RELEASE XORG_VERSION_SNAP
+#endif
+
+static void
+xf86PrintBanner(void)
+{
+#if PRE_RELEASE
+ xf86ErrorFVerb(0, "\n"
+ "This is a pre-release version of the X server from " XVENDORNAME ".\n"
+ "It is not supported in any way.\n"
+ "Bugs may be filed in the bugzilla at http://bugs.freedesktop.org/.\n"
+ "Select the \"xorg\" product for bugs you find in this release.\n"
+ "Before reporting bugs in pre-release versions please check the\n"
+ "latest version in the X.Org Foundation git repository.\n"
+ "See http://wiki.x.org/wiki/GitPage for git access instructions.\n");
+#endif
+ xf86ErrorFVerb(0, "\nX.Org X Server %d.%d.%d",
+ XORG_VERSION_MAJOR,
+ XORG_VERSION_MINOR,
+ XORG_VERSION_PATCH);
+#if XORG_VERSION_SNAP > 0
+ xf86ErrorFVerb(0, ".%d", XORG_VERSION_SNAP);
+#endif
+
+#if XORG_VERSION_SNAP >= 900
+ /* When the minor number is 99, that signifies that the we are making
+ * a release candidate for a major version. (X.0.0)
+ * When the patch number is 99, that signifies that the we are making
+ * a release candidate for a minor version. (X.Y.0)
+ * When the patch number is < 99, then we are making a release
+ * candidate for the next point release. (X.Y.Z)
+ */
+#if XORG_VERSION_MINOR >= 99
+ xf86ErrorFVerb(0, " (%d.0.0 RC %d)", XORG_VERSION_MAJOR+1,
+ XORG_VERSION_SNAP - 900);
+#elif XORG_VERSION_PATCH == 99
+ xf86ErrorFVerb(0, " (%d.%d.0 RC %d)", XORG_VERSION_MAJOR,
+ XORG_VERSION_MINOR + 1, XORG_VERSION_SNAP - 900);
+#else
+ xf86ErrorFVerb(0, " (%d.%d.%d RC %d)", XORG_VERSION_MAJOR,
+ XORG_VERSION_MINOR, XORG_VERSION_PATCH + 1,
+ XORG_VERSION_SNAP - 900);
+#endif
+#endif
+
+#ifdef XORG_CUSTOM_VERSION
+ xf86ErrorFVerb(0, " (%s)", XORG_CUSTOM_VERSION);
+#endif
+#ifndef XORG_DATE
+# define XORG_DATE "Unknown"
+#endif
+ xf86ErrorFVerb(0, "\nRelease Date: %s\n", XORG_DATE);
+ xf86ErrorFVerb(0, "X Protocol Version %d, Revision %d\n",
+ X_PROTOCOL, X_PROTOCOL_REVISION);
+ xf86ErrorFVerb(0, "Build Operating System: %s %s\n", OSNAME, OSVENDOR);
+#ifdef HAS_UTSNAME
+ {
+ struct utsname name;
+
+ /* Linux & BSD state that 0 is success, SysV (including Solaris, HP-UX,
+ and Irix) and Single Unix Spec 3 just say that non-negative is success.
+ All agree that failure is represented by a negative number.
+ */
+ if (uname(&name) >= 0) {
+ xf86ErrorFVerb(0, "Current Operating System: %s %s %s %s %s\n",
+ name.sysname, name.nodename, name.release, name.version, name.machine);
+#ifdef linux
+ do {
+ char buf[80];
+ int fd = open("/proc/cmdline", O_RDONLY);
+ if (fd != -1) {
+ xf86ErrorFVerb(0, "Kernel command line: ");
+ memset(buf, 0, 80);
+ while (read(fd, buf, 80) > 0) {
+ xf86ErrorFVerb(0, "%.80s", buf);
+ memset(buf, 0, 80);
+ }
+ close(fd);
+ }
+ } while (0);
+#endif
+ }
+ }
+#endif
+#if defined(BUILD_DATE) && (BUILD_DATE > 19000000)
+ {
+ struct tm t;
+ char buf[100];
+
+ bzero(&t, sizeof(t));
+ bzero(buf, sizeof(buf));
+ t.tm_mday = BUILD_DATE % 100;
+ t.tm_mon = (BUILD_DATE / 100) % 100 - 1;
+ t.tm_year = BUILD_DATE / 10000 - 1900;
+#if defined(BUILD_TIME)
+ t.tm_sec = BUILD_TIME % 100;
+ t.tm_min = (BUILD_TIME / 100) % 100;
+ t.tm_hour = (BUILD_TIME / 10000) % 100;
+ if (strftime(buf, sizeof(buf), "%d %B %Y %I:%M:%S%p", &t))
+ xf86ErrorFVerb(0, "Build Date: %s\n", buf);
+#else
+ if (strftime(buf, sizeof(buf), "%d %B %Y", &t))
+ xf86ErrorFVerb(0, "Build Date: %s\n", buf);
+#endif
+ }
+#endif
+#if defined(BUILDERSTRING)
+ xf86ErrorFVerb(0, "%s \n", BUILDERSTRING);
+#endif
+ xf86ErrorFVerb(0, "Current version of pixman: %s\n",
+ pixman_version_string());
+ xf86ErrorFVerb(0, "\tBefore reporting problems, check "
+ ""__VENDORDWEBSUPPORT__"\n"
+ "\tto make sure that you have the latest version.\n");
+}
+
+static void
+xf86PrintMarkers(void)
+{
+ LogPrintMarkers();
+}
+
+static Bool
+xf86CreateRootWindow(WindowPtr pWin)
+{
+ int ret = TRUE;
+ int err = Success;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ RootWinPropPtr pProp;
+ CreateWindowProcPtr CreateWindow = (CreateWindowProcPtr)
+ dixLookupPrivate(&pScreen->devPrivates, xf86CreateRootWindowKey);
+
+ DebugF("xf86CreateRootWindow(%p)\n", pWin);
+
+ if ( pScreen->CreateWindow != xf86CreateRootWindow ) {
+ /* Can't find hook we are hung on */
+ xf86DrvMsg(pScreen->myNum, X_WARNING /* X_ERROR */,
+ "xf86CreateRootWindow %p called when not in pScreen->CreateWindow %p n",
+ (void *)xf86CreateRootWindow,
+ (void *)pScreen->CreateWindow );
+ }
+
+ /* Unhook this function ... */
+ pScreen->CreateWindow = CreateWindow;
+ dixSetPrivate(&pScreen->devPrivates, xf86CreateRootWindowKey, NULL);
+
+ /* ... and call the previous CreateWindow fuction, if any */
+ if (NULL!=pScreen->CreateWindow) {
+ ret = (*pScreen->CreateWindow)(pWin);
+ }
+
+ /* Now do our stuff */
+ if (xf86RegisteredPropertiesTable != NULL) {
+ if (pWin->parent == NULL && xf86RegisteredPropertiesTable != NULL) {
+ for (pProp = xf86RegisteredPropertiesTable[pScreen->myNum];
+ pProp != NULL && err==Success;
+ pProp = pProp->next )
+ {
+ Atom prop;
+
+ prop = MakeAtom(pProp->name, strlen(pProp->name), TRUE);
+ err = dixChangeWindowProperty(serverClient, pWin,
+ prop, pProp->type,
+ pProp->format, PropModeReplace,
+ pProp->size, pProp->data,
+ FALSE);
+ }
+
+ /* Look at err */
+ ret &= (err==Success);
+
+ } else {
+ xf86Msg(X_ERROR, "xf86CreateRootWindow unexpectedly called with "
+ "non-root window %p (parent %p)\n",
+ (void *)pWin, (void *)pWin->parent);
+ ret = FALSE;
+ }
+ }
+
+ DebugF("xf86CreateRootWindow() returns %d\n", ret);
+ return (ret);
+}
+
+
+static void
+InstallSignalHandlers(void)
+{
+ /*
+ * Install signal handler for unexpected signals
+ */
+ xf86Info.caughtSignal=FALSE;
+ if (!xf86Info.notrapSignals) {
+ OsRegisterSigWrapper(xf86SigWrapper);
+ } else {
+ signal(SIGSEGV, SIG_DFL);
+ signal(SIGILL, SIG_DFL);
+#ifdef SIGEMT
+ signal(SIGEMT, SIG_DFL);
+#endif
+ signal(SIGFPE, SIG_DFL);
+#ifdef SIGBUS
+ signal(SIGBUS, SIG_DFL);
+#endif
+#ifdef SIGSYS
+ signal(SIGSYS, SIG_DFL);
+#endif
+#ifdef SIGXCPU
+ signal(SIGXCPU, SIG_DFL);
+#endif
+#ifdef SIGXFSZ
+ signal(SIGXFSZ, SIG_DFL);
+#endif
+ }
+}
+
+
+#define END_OF_MATCHES(m) \
+ (((m).vendor_id == 0) && ((m).device_id == 0) && ((m).subvendor_id == 0))
+
+Bool
+probe_devices_from_device_sections(DriverPtr drvp)
+{
+ int i, j;
+ struct pci_device * pPci;
+ Bool foundScreen = FALSE;
+ const struct pci_id_match * const devices = drvp->supported_devices;
+ GDevPtr *devList;
+ const unsigned numDevs = xf86MatchDevice(drvp->driverName, & devList);
+
+
+ for ( i = 0 ; i < numDevs ; i++ ) {
+ struct pci_device_iterator *iter;
+ unsigned device_id;
+
+
+ /* Find the pciVideoRec associated with this device section.
+ */
+ iter = pci_id_match_iterator_create(NULL);
+ while ((pPci = pci_device_next(iter)) != NULL) {
+ if (devList[i]->busID && *devList[i]->busID) {
+ if (xf86ComparePciBusString(devList[i]->busID,
+ ((pPci->domain << 8)
+ | pPci->bus),
+ pPci->dev,
+ pPci->func)) {
+ break;
+ }
+ }
+ else if (xf86IsPrimaryPci(pPci)) {
+ break;
+ }
+ }
+
+ pci_iterator_destroy(iter);
+
+ if (pPci == NULL) {
+ continue;
+ }
+
+ device_id = (devList[i]->chipID > 0)
+ ? devList[i]->chipID : pPci->device_id;
+
+
+ /* Once the pciVideoRec is found, determine if the device is supported
+ * by the driver. If it is, probe it!
+ */
+ for ( j = 0 ; ! END_OF_MATCHES( devices[j] ) ; j++ ) {
+ if ( PCI_ID_COMPARE( devices[j].vendor_id, pPci->vendor_id )
+ && PCI_ID_COMPARE( devices[j].device_id, device_id )
+ && ((devices[j].device_class_mask & pPci->device_class)
+ == devices[j].device_class) ) {
+ int entry;
+
+ /* Allow the same entity to be used more than once for
+ * devices with multiple screens per entity. This assumes
+ * implicitly that there will be a screen == 0 instance.
+ *
+ * FIXME Need to make sure that two different drivers don't
+ * FIXME claim the same screen > 0 instance.
+ */
+ if ( (devList[i]->screen == 0) && !xf86CheckPciSlot( pPci ) )
+ continue;
+
+ DebugF("%s: card at %d:%d:%d is claimed by a Device section\n",
+ drvp->driverName, pPci->bus, pPci->dev, pPci->func);
+
+ /* Allocate an entry in the lists to be returned */
+ entry = xf86ClaimPciSlot(pPci, drvp, device_id,
+ devList[i], devList[i]->active);
+
+ if ((entry == -1) && (devList[i]->screen > 0)) {
+ unsigned k;
+
+ for ( k = 0; k < xf86NumEntities; k++ ) {
+ EntityPtr pEnt = xf86Entities[k];
+ if (pEnt->bus.type != BUS_PCI)
+ continue;
+
+ if (pEnt->bus.id.pci == pPci) {
+ entry = k;
+ xf86AddDevToEntity(k, devList[i]);
+ break;
+ }
+ }
+ }
+
+ if (entry != -1) {
+ if ((*drvp->PciProbe)(drvp, entry, pPci,
+ devices[j].match_data)) {
+ foundScreen = TRUE;
+ } else
+ xf86UnclaimPciSlot(pPci);
+ }
+
+ break;
+ }
+ }
+ }
+ free(devList);
+
+ return foundScreen;
+}
+
+
+Bool
+add_matching_devices_to_configure_list(DriverPtr drvp)
+{
+ const struct pci_id_match * const devices = drvp->supported_devices;
+ int j;
+ struct pci_device *pPci;
+ struct pci_device_iterator *iter;
+ int numFound = 0;
+
+
+ iter = pci_id_match_iterator_create(NULL);
+ while ((pPci = pci_device_next(iter)) != NULL) {
+ /* Determine if this device is supported by the driver. If it is,
+ * add it to the list of devices to configure.
+ */
+ for (j = 0 ; ! END_OF_MATCHES(devices[j]) ; j++) {
+ if ( PCI_ID_COMPARE( devices[j].vendor_id, pPci->vendor_id )
+ && PCI_ID_COMPARE( devices[j].device_id, pPci->device_id )
+ && ((devices[j].device_class_mask & pPci->device_class)
+ == devices[j].device_class) ) {
+ if (xf86CheckPciSlot(pPci)) {
+ GDevPtr pGDev = xf86AddBusDeviceToConfigure(
+ drvp->driverName, BUS_PCI, pPci, -1);
+ if (pGDev != NULL) {
+ /* After configure pass 1, chipID and chipRev are
+ * treated as over-rides, so clobber them here.
+ */
+ pGDev->chipID = -1;
+ pGDev->chipRev = -1;
+ }
+
+ numFound++;
+ }
+
+ break;
+ }
+ }
+ }
+
+ pci_iterator_destroy(iter);
+
+
+ return (numFound != 0);
+}
+
+/**
+ * Call the driver's correct probe function.
+ *
+ * If the driver implements the \c DriverRec::PciProbe entry-point and an
+ * appropriate PCI device (with matching Device section in the xorg.conf file)
+ * is found, it is called. If \c DriverRec::PciProbe or no devices can be
+ * successfully probed with it (e.g., only non-PCI devices are available),
+ * the driver's \c DriverRec::Probe function is called.
+ *
+ * \param drv Driver to probe
+ *
+ * \return
+ * If a device can be successfully probed by the driver, \c TRUE is
+ * returned. Otherwise, \c FALSE is returned.
+ */
+Bool
+xf86CallDriverProbe( DriverPtr drv, Bool detect_only )
+{
+ Bool foundScreen = FALSE;
+
+ if ( drv->PciProbe != NULL ) {
+ if ( xf86DoConfigure && xf86DoConfigurePass1 ) {
+ assert( detect_only );
+ foundScreen = add_matching_devices_to_configure_list( drv );
+ }
+ else {
+ assert( ! detect_only );
+ foundScreen = probe_devices_from_device_sections( drv );
+ }
+ }
+
+ if ( ! foundScreen && (drv->Probe != NULL) ) {
+ xf86Msg( X_WARNING, "Falling back to old probe method for %s\n",
+ drv->driverName );
+ foundScreen = (*drv->Probe)( drv, (detect_only) ? PROBE_DETECT
+ : PROBE_DEFAULT );
+ }
+
+ return foundScreen;
+}
+
+/*
+ * InitOutput --
+ * Initialize screenInfo for all actually accessible framebuffers.
+ * That includes vt-manager setup, querying all possible devices and
+ * collecting the pixmap formats.
+ */
+void
+InitOutput(ScreenInfo *pScreenInfo, int argc, char **argv)
+{
+ int i, j, k, scr_index;
+ char **modulelist;
+ pointer *optionlist;
+ screenLayoutPtr layout;
+ Pix24Flags screenpix24, pix24;
+ MessageType pix24From = X_DEFAULT;
+ Bool pix24Fail = FALSE;
+ Bool autoconfig = FALSE;
+ GDevPtr configured_device;
+
+ xf86Initialising = TRUE;
+
+ if (serverGeneration == 1) {
+ if ((xf86ServerName = strrchr(argv[0], '/')) != 0)
+ xf86ServerName++;
+ else
+ xf86ServerName = argv[0];
+
+ xf86PrintBanner();
+ xf86PrintMarkers();
+ if (xf86LogFile) {
+ time_t t;
+ const char *ct;
+ t = time(NULL);
+ ct = ctime(&t);
+ xf86MsgVerb(xf86LogFileFrom, 0, "Log file: \"%s\", Time: %s",
+ xf86LogFile, ct);
+ }
+
+ /* Read and parse the config file */
+ if (!xf86DoConfigure && !xf86DoShowOptions) {
+ switch (xf86HandleConfigFile(FALSE)) {
+ case CONFIG_OK:
+ break;
+ case CONFIG_PARSE_ERROR:
+ xf86Msg(X_ERROR, "Error parsing the config file\n");
+ return;
+ case CONFIG_NOFILE:
+ autoconfig = TRUE;
+ break;
+ }
+ }
+
+ InstallSignalHandlers();
+
+ /* Initialise the loader */
+ LoaderInit();
+
+ /* Tell the loader the default module search path */
+ LoaderSetPath(xf86ModulePath);
+
+ if (xf86Info.ignoreABI) {
+ LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL);
+ }
+
+ if (xf86DoShowOptions)
+ DoShowOptions();
+
+ /* Do a general bus probe. This will be a PCI probe for x86 platforms */
+ xf86BusProbe();
+
+ if (xf86DoConfigure)
+ DoConfigure();
+
+ if (autoconfig) {
+ if (!xf86AutoConfig()) {
+ xf86Msg(X_ERROR, "Auto configuration failed\n");
+ return;
+ }
+ }
+
+#ifdef XF86PM
+ xf86OSPMClose = xf86OSPMOpen();
+#endif
+
+ /* Load all modules specified explicitly in the config file */
+ if ((modulelist = xf86ModulelistFromConfig(&optionlist))) {
+ xf86LoadModules(modulelist, optionlist);
+ free(modulelist);
+ free(optionlist);
+ }
+
+ /* Load all driver modules specified in the config file */
+ /* If there aren't any specified in the config file, autoconfig them */
+ /* FIXME: Does not handle multiple active screen sections, but I'm not
+ * sure if we really want to handle that case*/
+ configured_device = xf86ConfigLayout.screens->screen->device;
+ if ((!configured_device) || (!configured_device->driver)) {
+ if (!autoConfigDevice(configured_device)) {
+ xf86Msg(X_ERROR, "Automatic driver configuration failed\n");
+ return ;
+ }
+ }
+ if ((modulelist = xf86DriverlistFromConfig())) {
+ xf86LoadModules(modulelist, NULL);
+ free(modulelist);
+ }
+
+ /* Load all input driver modules specified in the config file. */
+ if ((modulelist = xf86InputDriverlistFromConfig())) {
+ xf86LoadModules(modulelist, NULL);
+ free(modulelist);
+ }
+
+ /*
+ * It is expected that xf86AddDriver()/xf86AddInputDriver will be
+ * called for each driver as it is loaded. Those functions save the
+ * module pointers for drivers.
+ * XXX Nothing keeps track of them for other modules.
+ */
+ /* XXX What do we do if not all of these could be loaded? */
+
+ /*
+ * At this point, xf86DriverList[] is all filled in with entries for
+ * each of the drivers to try and xf86NumDrivers has the number of
+ * drivers. If there are none, return now.
+ */
+
+ if (xf86NumDrivers == 0) {
+ xf86Msg(X_ERROR, "No drivers available.\n");
+ return;
+ }
+
+ /*
+ * Call each of the Identify functions and call the driverFunc to check
+ * if HW access is required. The Identify functions print out some
+ * identifying information, and anything else that might be
+ * needed at this early stage.
+ */
+
+ for (i = 0; i < xf86NumDrivers; i++) {
+ if (xf86DriverList[i]->Identify != NULL)
+ xf86DriverList[i]->Identify(0);
+
+ if (!xorgHWAccess || !xorgHWOpenConsole) {
+ xorgHWFlags flags;
+ if(!xf86DriverList[i]->driverFunc
+ || !xf86DriverList[i]->driverFunc(NULL,
+ GET_REQUIRED_HW_INTERFACES,
+ &flags))
+ flags = HW_IO;
+
+ if(NEED_IO_ENABLED(flags))
+ xorgHWAccess = TRUE;
+ if(!(flags & HW_SKIP_CONSOLE))
+ xorgHWOpenConsole = TRUE;
+ }
+ }
+
+ if (xorgHWOpenConsole)
+ xf86OpenConsole();
+ else
+ xf86Info.dontVTSwitch = TRUE;
+
+ /* Enable full I/O access */
+ if (xorgHWAccess)
+ xorgHWAccess = xf86EnableIO();
+
+ /*
+ * Locate bus slot that had register IO enabled at server startup
+ */
+ if (xorgHWAccess) {
+ xf86AccessInit();
+ xf86FindPrimaryDevice();
+ }
+ /*
+ * Now call each of the Probe functions. Each successful probe will
+ * result in an extra entry added to the xf86Screens[] list for each
+ * instance of the hardware found.
+ */
+
+ for (i = 0; i < xf86NumDrivers; i++) {
+ xorgHWFlags flags;
+ if (!xorgHWAccess) {
+ if (!xf86DriverList[i]->driverFunc
+ || !xf86DriverList[i]->driverFunc(NULL,
+ GET_REQUIRED_HW_INTERFACES,
+ &flags)
+ || NEED_IO_ENABLED(flags))
+ continue;
+ }
+
+ xf86CallDriverProbe( xf86DriverList[i], FALSE );
+ }
+
+ /*
+ * If nothing was detected, return now.
+ */
+
+ if (xf86NumScreens == 0) {
+ xf86Msg(X_ERROR, "No devices detected.\n");
+ return;
+ }
+
+ xf86VGAarbiterInit();
+
+ /*
+ * Match up the screens found by the probes against those specified
+ * in the config file. Remove the ones that won't be used. Sort
+ * them in the order specified.
+ */
+
+ /*
+ * What is the best way to do this?
+ *
+ * For now, go through the screens allocated by the probes, and
+ * look for screen config entry which refers to the same device
+ * section as picked out by the probe.
+ *
+ */
+
+ for (i = 0; i < xf86NumScreens; i++) {
+ for (layout = xf86ConfigLayout.screens; layout->screen != NULL;
+ layout++) {
+ Bool found = FALSE;
+ for (j = 0; j < xf86Screens[i]->numEntities; j++) {
+
+ GDevPtr dev =
+ xf86GetDevFromEntity(xf86Screens[i]->entityList[j],
+ xf86Screens[i]->entityInstanceList[j]);
+
+ if (dev == layout->screen->device) {
+ /* A match has been found */
+ xf86Screens[i]->confScreen = layout->screen;
+ found = TRUE;
+ break;
+ }
+ }
+ if (found) break;
+ }
+ if (layout->screen == NULL) {
+ /* No match found */
+ xf86Msg(X_ERROR,
+ "Screen %d deleted because of no matching config section.\n", i);
+ xf86DeleteScreen(i--, 0);
+ }
+ }
+
+ /*
+ * If no screens left, return now.
+ */
+
+ if (xf86NumScreens == 0) {
+ xf86Msg(X_ERROR,
+ "Device(s) detected, but none match those in the config file.\n");
+ return;
+ }
+
+ xf86PostProbe();
+ xf86EntityInit();
+
+ /*
+ * Sort the drivers to match the requested ording. Using a slow
+ * bubble sort.
+ */
+ for (j = 0; j < xf86NumScreens - 1; j++) {
+ for (i = 0; i < xf86NumScreens - j - 1; i++) {
+ if (xf86Screens[i + 1]->confScreen->screennum <
+ xf86Screens[i]->confScreen->screennum) {
+ ScrnInfoPtr tmpScrn = xf86Screens[i + 1];
+ xf86Screens[i + 1] = xf86Screens[i];
+ xf86Screens[i] = tmpScrn;
+ }
+ }
+ }
+ /* Fix up the indexes */
+ for (i = 0; i < xf86NumScreens; i++) {
+ xf86Screens[i]->scrnIndex = i;
+ }
+
+ /*
+ * Call the driver's PreInit()'s to complete initialisation for the first
+ * generation.
+ */
+
+ for (i = 0; i < xf86NumScreens; i++) {
+ xf86VGAarbiterScrnInit(xf86Screens[i]);
+ xf86VGAarbiterLock(xf86Screens[i]);
+ if (xf86Screens[i]->PreInit &&
+ xf86Screens[i]->PreInit(xf86Screens[i], 0))
+ xf86Screens[i]->configured = TRUE;
+ xf86VGAarbiterUnlock(xf86Screens[i]);
+ }
+ for (i = 0; i < xf86NumScreens; i++)
+ if (!xf86Screens[i]->configured)
+ xf86DeleteScreen(i--, 0);
+
+ /*
+ * If no screens left, return now.
+ */
+
+ if (xf86NumScreens == 0) {
+ xf86Msg(X_ERROR,
+ "Screen(s) found, but none have a usable configuration.\n");
+ return;
+ }
+
+ for (i = 0; i < xf86NumScreens; i++) {
+ if (xf86Screens[i]->name == NULL) {
+ xf86Screens[i]->name = xnfalloc(strlen("screen") + 10 + 1);
+ sprintf(xf86Screens[i]->name, "screen%d", i);
+ xf86MsgVerb(X_WARNING, 0,
+ "Screen driver %d has no name set, using `%s'.\n",
+ i, xf86Screens[i]->name);
+ }
+ }
+
+ /* Remove (unload) drivers that are not required */
+ for (i = 0; i < xf86NumDrivers; i++)
+ if (xf86DriverList[i] && xf86DriverList[i]->refCount <= 0)
+ xf86DeleteDriver(i);
+
+ /*
+ * At this stage we know how many screens there are.
+ */
+
+ for (i = 0; i < xf86NumScreens; i++)
+ xf86InitViewport(xf86Screens[i]);
+
+ /*
+ * Collect all pixmap formats and check for conflicts at the display
+ * level. Should we die here? Or just delete the offending screens?
+ */
+ screenpix24 = Pix24DontCare;
+ for (i = 0; i < xf86NumScreens; i++) {
+ if (xf86Screens[i]->imageByteOrder !=
+ xf86Screens[0]->imageByteOrder)
+ FatalError("Inconsistent display bitmapBitOrder. Exiting\n");
+ if (xf86Screens[i]->bitmapScanlinePad !=
+ xf86Screens[0]->bitmapScanlinePad)
+ FatalError("Inconsistent display bitmapScanlinePad. Exiting\n");
+ if (xf86Screens[i]->bitmapScanlineUnit !=
+ xf86Screens[0]->bitmapScanlineUnit)
+ FatalError("Inconsistent display bitmapScanlineUnit. Exiting\n");
+ if (xf86Screens[i]->bitmapBitOrder !=
+ xf86Screens[0]->bitmapBitOrder)
+ FatalError("Inconsistent display bitmapBitOrder. Exiting\n");
+
+ /* Determine the depth 24 pixmap format the screens would like */
+ if (xf86Screens[i]->pixmap24 != Pix24DontCare) {
+ if (screenpix24 == Pix24DontCare)
+ screenpix24 = xf86Screens[i]->pixmap24;
+ else if (screenpix24 != xf86Screens[i]->pixmap24)
+ FatalError("Inconsistent depth 24 pixmap format. Exiting\n");
+ }
+ }
+ /* check if screenpix24 is consistent with the config/cmdline */
+ if (xf86Info.pixmap24 != Pix24DontCare) {
+ pix24 = xf86Info.pixmap24;
+ pix24From = xf86Info.pix24From;
+ if (screenpix24 != Pix24DontCare && screenpix24 != xf86Info.pixmap24)
+ pix24Fail = TRUE;
+ } else if (screenpix24 != Pix24DontCare) {
+ pix24 = screenpix24;
+ pix24From = X_PROBED;
+ } else
+ pix24 = Pix24Use32;
+
+ if (pix24Fail)
+ FatalError("Screen(s) can't use the required depth 24 pixmap format"
+ " (%d). Exiting\n", PIX24TOBPP(pix24));
+
+ /* Initialise the depth 24 format */
+ for (j = 0; j < numFormats && formats[j].depth != 24; j++)
+ ;
+ formats[j].bitsPerPixel = PIX24TOBPP(pix24);
+
+ /* Collect additional formats */
+ for (i = 0; i < xf86NumScreens; i++) {
+ for (j = 0; j < xf86Screens[i]->numFormats; j++) {
+ for (k = 0; ; k++) {
+ if (k >= numFormats) {
+ if (k >= MAXFORMATS)
+ FatalError("Too many pixmap formats! Exiting\n");
+ formats[k] = xf86Screens[i]->formats[j];
+ numFormats++;
+ break;
+ }
+ if (formats[k].depth == xf86Screens[i]->formats[j].depth) {
+ if ((formats[k].bitsPerPixel ==
+ xf86Screens[i]->formats[j].bitsPerPixel) &&
+ (formats[k].scanlinePad ==
+ xf86Screens[i]->formats[j].scanlinePad))
+ break;
+ FatalError("Inconsistent pixmap format for depth %d."
+ " Exiting\n", formats[k].depth);
+ }
+ }
+ }
+ }
+ formatsDone = TRUE;
+
+ if (xf86Info.vtno >= 0 ) {
+#define VT_ATOM_NAME "XFree86_VT"
+ Atom VTAtom=-1;
+ CARD32 *VT = NULL;
+ int ret;
+
+ /* This memory needs to stay available until the screen has been
+ initialized, and we can create the property for real.
+ */
+ if ( (VT = malloc(sizeof(CARD32)))==NULL ) {
+ FatalError("Unable to make VT property - out of memory. Exiting...\n");
+ }
+ *VT = xf86Info.vtno;
+
+ VTAtom = MakeAtom(VT_ATOM_NAME, sizeof(VT_ATOM_NAME) - 1, TRUE);
+
+ for (i = 0, ret = Success; i < xf86NumScreens && ret == Success; i++) {
+ ret = xf86RegisterRootWindowProperty(xf86Screens[i]->scrnIndex,
+ VTAtom, XA_INTEGER, 32,
+ 1, VT );
+ if (ret != Success)
+ xf86DrvMsg(xf86Screens[i]->scrnIndex, X_WARNING,
+ "Failed to register VT property\n");
+ }
+ }
+
+ /* If a screen uses depth 24, show what the pixmap format is */
+ for (i = 0; i < xf86NumScreens; i++) {
+ if (xf86Screens[i]->depth == 24) {
+ xf86Msg(pix24From, "Depth 24 pixmap format is %d bpp\n",
+ PIX24TOBPP(pix24));
+ break;
+ }
+ }
+ } else {
+ /*
+ * serverGeneration != 1; some OSs have to do things here, too.
+ */
+ if (xorgHWOpenConsole)
+ xf86OpenConsole();
+
+#ifdef XF86PM
+ /*
+ should we reopen it here? We need to deal with an already opened
+ device. We could leave this to the OS layer. For now we simply
+ close it here
+ */
+ if (xf86OSPMClose)
+ xf86OSPMClose();
+ if ((xf86OSPMClose = xf86OSPMOpen()) != NULL)
+ xf86MsgVerb(X_INFO, 3, "APM registered successfully\n");
+#endif
+
+ /* Make sure full I/O access is enabled */
+ if (xorgHWAccess)
+ xf86EnableIO();
+ }
+
+ /*
+ * Use the previously collected parts to setup pScreenInfo
+ */
+
+ pScreenInfo->imageByteOrder = xf86Screens[0]->imageByteOrder;
+ pScreenInfo->bitmapScanlinePad = xf86Screens[0]->bitmapScanlinePad;
+ pScreenInfo->bitmapScanlineUnit = xf86Screens[0]->bitmapScanlineUnit;
+ pScreenInfo->bitmapBitOrder = xf86Screens[0]->bitmapBitOrder;
+ pScreenInfo->numPixmapFormats = numFormats;
+ for (i = 0; i < numFormats; i++)
+ pScreenInfo->formats[i] = formats[i];
+
+ /* Make sure the server's VT is active */
+
+ if (serverGeneration != 1) {
+ xf86Resetting = TRUE;
+ /* All screens are in the same state, so just check the first */
+ if (!xf86Screens[0]->vtSema) {
+#ifdef HAS_USL_VTS
+ ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ);
+#endif
+ xf86AccessEnter();
+ xf86EnterServerState(SETUP);
+ }
+ }
+#ifdef SCO325
+ else {
+ /*
+ * Under SCO we must ack that we got the console at startup,
+ * I think this is the safest way to assure it.
+ */
+ static int once = 1;
+ if (once) {
+ once = 0;
+ if (ioctl(xf86Info.consoleFd, VT_RELDISP, VT_ACKACQ) < 0)
+ xf86Msg(X_WARNING, "VT_ACKACQ failed");
+ }
+ }
+#endif /* SCO325 */
+
+ for (i = 0; i < xf86NumScreens; i++) {
+ xf86VGAarbiterLock(xf86Screens[i]);
+ /*
+ * Almost everything uses these defaults, and many of those that
+ * don't, will wrap them.
+ */
+ xf86Screens[i]->EnableDisableFBAccess = xf86EnableDisableFBAccess;
+#ifdef XFreeXDGA
+ xf86Screens[i]->SetDGAMode = xf86SetDGAMode;
+#endif
+ xf86Screens[i]->DPMSSet = NULL;
+ xf86Screens[i]->LoadPalette = NULL;
+ xf86Screens[i]->SetOverscan = NULL;
+ xf86Screens[i]->DriverFunc = NULL;
+ xf86Screens[i]->pScreen = NULL;
+ scr_index = AddScreen(xf86Screens[i]->ScreenInit, argc, argv);
+ xf86VGAarbiterUnlock(xf86Screens[i]);
+ if (scr_index == i) {
+ /*
+ * Hook in our ScrnInfoRec, and initialise some other pScreen
+ * fields.
+ */
+ dixSetPrivate(&screenInfo.screens[scr_index]->devPrivates,
+ xf86ScreenKey, xf86Screens[i]);
+ xf86Screens[i]->pScreen = screenInfo.screens[scr_index];
+ /* The driver should set this, but make sure it is set anyway */
+ xf86Screens[i]->vtSema = TRUE;
+ } else {
+ /* This shouldn't normally happen */
+ FatalError("AddScreen/ScreenInit failed for driver %d\n", i);
+ }
+
+ DebugF("InitOutput - xf86Screens[%d]->pScreen = %p\n",
+ i, xf86Screens[i]->pScreen );
+ DebugF("xf86Screens[%d]->pScreen->CreateWindow = %p\n",
+ i, xf86Screens[i]->pScreen->CreateWindow );
+
+ dixSetPrivate(&screenInfo.screens[scr_index]->devPrivates,
+ xf86CreateRootWindowKey,
+ xf86Screens[i]->pScreen->CreateWindow);
+ xf86Screens[i]->pScreen->CreateWindow = xf86CreateRootWindow;
+
+ if (PictureGetSubpixelOrder (xf86Screens[i]->pScreen) == SubPixelUnknown)
+ {
+ xf86MonPtr DDC = (xf86MonPtr)(xf86Screens[i]->monitor->DDC);
+ PictureSetSubpixelOrder (xf86Screens[i]->pScreen,
+ DDC ?
+ (DDC->features.input_type ?
+ SubPixelHorizontalRGB : SubPixelNone) :
+ SubPixelUnknown);
+ }
+#ifdef RANDR
+ if (!xf86Info.disableRandR)
+ xf86RandRInit (screenInfo.screens[scr_index]);
+ xf86Msg(xf86Info.randRFrom, "RandR %s\n",
+ xf86Info.disableRandR ? "disabled" : "enabled");
+#endif
+ }
+
+ xf86PostScreenInit();
+
+ xf86InitOrigins();
+
+ xf86Resetting = FALSE;
+ xf86Initialising = FALSE;
+
+ RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA, xf86Wakeup,
+ NULL);
+}
+
+/*
+ * InitInput --
+ * Initialize all supported input devices.
+ */
+
+void
+InitInput(int argc, char **argv)
+{
+ IDevPtr* pDev;
+ DeviceIntPtr dev;
+
+ xf86Info.vtRequestsPending = FALSE;
+
+ mieqInit();
+
+ GetEventList(&xf86Events);
+
+ /* Call the PreInit function for each input device instance. */
+ for (pDev = xf86ConfigLayout.inputs; pDev && *pDev; pDev++) {
+ /* Replace obsolete keyboard driver with kbd */
+ if (!xf86NameCmp((*pDev)->driver, "keyboard")) {
+ strcpy((*pDev)->driver, "kbd");
+ }
+
+ /* If one fails, the others will too */
+ if (xf86NewInputDevice(*pDev, &dev, TRUE) == BadAlloc)
+ break;
+ }
+
+ config_init();
+}
+
+void
+CloseInput (void)
+{
+ config_fini();
+}
+
+/*
+ * OsVendorInit --
+ * OS/Vendor-specific initialisations. Called from OsInit(), which
+ * is called by dix before establishing the well known sockets.
+ */
+
+void
+OsVendorInit(void)
+{
+ static Bool beenHere = FALSE;
+
+#ifdef SIGCHLD
+ signal(SIGCHLD, SIG_DFL); /* Need to wait for child processes */
+#endif
+
+ if (!beenHere) {
+ umask(022);
+ xf86LogInit();
+ }
+
+ /* Set stderr to non-blocking. */
+#ifndef O_NONBLOCK
+#if defined(FNDELAY)
+#define O_NONBLOCK FNDELAY
+#elif defined(O_NDELAY)
+#define O_NONBLOCK O_NDELAY
+#endif
+
+#ifdef O_NONBLOCK
+ if (!beenHere) {
+ if (geteuid() == 0 && getuid() != geteuid())
+ {
+ int status;
+
+ status = fcntl(fileno(stderr), F_GETFL, 0);
+ if (status != -1) {
+ fcntl(fileno(stderr), F_SETFL, status | O_NONBLOCK);
+ }
+ }
+ }
+#endif
+#endif
+
+ beenHere = TRUE;
+}
+
+/*
+ * ddxGiveUp --
+ * Device dependent cleanup. Called by by dix before normal server death.
+ * For SYSV386 we must switch the terminal back to normal mode. No error-
+ * checking here, since there should be restored as much as possible.
+ */
+
+void
+ddxGiveUp(void)
+{
+ int i;
+
+ xf86VGAarbiterFini();
+
+#ifdef XF86PM
+ if (xf86OSPMClose)
+ xf86OSPMClose();
+ xf86OSPMClose = NULL;
+#endif
+
+ for (i = 0; i < xf86NumScreens; i++) {
+ /*
+ * zero all access functions to
+ * trap calls when switched away.
+ */
+ xf86Screens[i]->vtSema = FALSE;
+ }
+
+#ifdef XFreeXDGA
+ DGAShutdown();
+#endif
+
+ if (xorgHWOpenConsole)
+ xf86CloseConsole();
+
+ xf86CloseLog();
+
+ /* If an unexpected signal was caught, dump a core for debugging */
+ if (xf86Info.caughtSignal)
+ OsAbort();
+}
+
+
+
+/*
+ * AbortDDX --
+ * DDX - specific abort routine. Called by AbortServer(). The attempt is
+ * made to restore all original setting of the displays. Also all devices
+ * are closed.
+ */
+
+void
+AbortDDX(void)
+{
+ int i;
+
+ /*
+ * try to restore the original video state
+ */
+#ifdef DPMSExtension /* Turn screens back on */
+ if (DPMSPowerLevel != DPMSModeOn)
+ DPMSSet(serverClient, DPMSModeOn);
+#endif
+ if (xf86Screens) {
+ if (xf86Screens[0]->vtSema)
+ xf86EnterServerState(SETUP);
+ for (i = 0; i < xf86NumScreens; i++)
+ if (xf86Screens[i]->vtSema) {
+ /*
+ * if we are aborting before ScreenInit() has finished
+ * we might not have been wrapped yet. Therefore enable
+ * screen explicitely.
+ */
+ xf86VGAarbiterLock(xf86Screens[i]);
+ (xf86Screens[i]->LeaveVT)(i, 0);
+ xf86VGAarbiterUnlock(xf86Screens[i]);
+ }
+ }
+
+ xf86AccessLeave();
+
+ /*
+ * This is needed for an abnormal server exit, since the normal exit stuff
+ * MUST also be performed (i.e. the vt must be left in a defined state)
+ */
+ ddxGiveUp();
+}
+
+void
+OsVendorFatalError(void)
+{
+#ifdef VENDORSUPPORT
+ ErrorF("\nPlease refer to your Operating System Vendor support pages\n"
+ "at %s for support on this crash.\n",VENDORSUPPORT);
+#else
+ ErrorF("\nPlease consult the "XVENDORNAME" support \n"
+ "\t at "__VENDORDWEBSUPPORT__"\n for help. \n");
+#endif
+ if (xf86LogFile && xf86LogFileWasOpened)
+ ErrorF("Please also check the log file at \"%s\" for additional "
+ "information.\n", xf86LogFile);
+ ErrorF("\n");
+}
+
+int
+xf86SetVerbosity(int verb)
+{
+ int save = xf86Verbose;
+
+ xf86Verbose = verb;
+ LogSetParameter(XLOG_VERBOSITY, verb);
+ return save;
+}
+
+int
+xf86SetLogVerbosity(int verb)
+{
+ int save = xf86LogVerbose;
+
+ xf86LogVerbose = verb;
+ LogSetParameter(XLOG_FILE_VERBOSITY, verb);
+ return save;
+}
+
+static void
+xf86PrintDefaultModulePath(void)
+{
+ ErrorF("%s\n", DEFAULT_MODULE_PATH);
+}
+
+static void
+xf86PrintDefaultLibraryPath(void)
+{
+ ErrorF("%s\n", DEFAULT_LIBRARY_PATH);
+}
+
+/*
+ * ddxProcessArgument --
+ * Process device-dependent command line args. Returns 0 if argument is
+ * not device dependent, otherwise Count of number of elements of argv
+ * that are part of a device dependent commandline option.
+ *
+ */
+
+/* ARGSUSED */
+int
+ddxProcessArgument(int argc, char **argv, int i)
+{
+ /*
+ * Note: can't use xalloc/xfree here because OsInit() hasn't been called
+ * yet. Use malloc/free instead.
+ */
+
+#define CHECK_FOR_REQUIRED_ARGUMENT() \
+ if (((i + 1) >= argc) || (!argv[i + 1])) { \
+ ErrorF("Required argument to %s not specified\n", argv[i]); \
+ UseMsg(); \
+ FatalError("Required argument to %s not specified\n", argv[i]); \
+ }
+
+ /* First the options that are only allowed for root */
+ if (!strcmp(argv[i], "-modulepath") || !strcmp(argv[i], "-logfile")) {
+ if ( (geteuid() == 0) && (getuid() != 0) ) {
+ FatalError("The '%s' option can only be used by root.\n", argv[i]);
+ }
+ else if (!strcmp(argv[i], "-modulepath"))
+ {
+ char *mp;
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ mp = malloc(strlen(argv[i + 1]) + 1);
+ if (!mp)
+ FatalError("Can't allocate memory for ModulePath\n");
+ strcpy(mp, argv[i + 1]);
+ xf86ModulePath = mp;
+ xf86ModPathFrom = X_CMDLINE;
+ return 2;
+ }
+ else if (!strcmp(argv[i], "-logfile"))
+ {
+ char *lf;
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ lf = malloc(strlen(argv[i + 1]) + 1);
+ if (!lf)
+ FatalError("Can't allocate memory for LogFile\n");
+ strcpy(lf, argv[i + 1]);
+ xf86LogFile = lf;
+ xf86LogFileFrom = X_CMDLINE;
+ return 2;
+ }
+ }
+ if (!strcmp(argv[i], "-config") || !strcmp(argv[i], "-xf86config"))
+ {
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ if (getuid() != 0 && !xf86PathIsSafe(argv[i + 1])) {
+ FatalError("\nInvalid argument for %s\n"
+ "\tFor non-root users, the file specified with %s must be\n"
+ "\ta relative path and must not contain any \"..\" elements.\n"
+ "\tUsing default "__XCONFIGFILE__" search path.\n\n",
+ argv[i], argv[i]);
+ }
+ xf86ConfigFile = argv[i + 1];
+ return 2;
+ }
+ if (!strcmp(argv[i], "-configdir"))
+ {
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ if (getuid() != 0 && !xf86PathIsSafe(argv[i + 1])) {
+ FatalError("\nInvalid argument for %s\n"
+ "\tFor non-root users, the file specified with %s must be\n"
+ "\ta relative path and must not contain any \"..\" elements.\n"
+ "\tUsing default "__XCONFIGDIR__" search path.\n\n",
+ argv[i], argv[i]);
+ }
+ xf86ConfigDir = argv[i + 1];
+ return 2;
+ }
+ if (!strcmp(argv[i],"-flipPixels"))
+ {
+ xf86FlipPixels = TRUE;
+ return 1;
+ }
+#ifdef XF86VIDMODE
+ if (!strcmp(argv[i],"-disableVidMode"))
+ {
+ xf86VidModeDisabled = TRUE;
+ return 1;
+ }
+ if (!strcmp(argv[i],"-allowNonLocalXvidtune"))
+ {
+ xf86VidModeAllowNonLocal = TRUE;
+ return 1;
+ }
+#endif
+ if (!strcmp(argv[i],"-allowMouseOpenFail"))
+ {
+ xf86AllowMouseOpenFail = TRUE;
+ return 1;
+ }
+ if (!strcmp(argv[i],"-ignoreABI"))
+ {
+ LoaderSetOptions(LDR_OPT_ABI_MISMATCH_NONFATAL);
+ return 1;
+ }
+ if (!strcmp(argv[i],"-verbose"))
+ {
+ if (++i < argc && argv[i])
+ {
+ char *end;
+ long val;
+ val = strtol(argv[i], &end, 0);
+ if (*end == '\0')
+ {
+ xf86SetVerbosity(val);
+ return 2;
+ }
+ }
+ xf86SetVerbosity(++xf86Verbose);
+ return 1;
+ }
+ if (!strcmp(argv[i],"-logverbose"))
+ {
+ if (++i < argc && argv[i])
+ {
+ char *end;
+ long val;
+ val = strtol(argv[i], &end, 0);
+ if (*end == '\0')
+ {
+ xf86SetLogVerbosity(val);
+ return 2;
+ }
+ }
+ xf86SetLogVerbosity(++xf86LogVerbose);
+ return 1;
+ }
+ if (!strcmp(argv[i],"-quiet"))
+ {
+ xf86SetVerbosity(-1);
+ return 1;
+ }
+ if (!strcmp(argv[i],"-showconfig") || !strcmp(argv[i],"-version"))
+ {
+ xf86PrintBanner();
+ exit(0);
+ }
+ if (!strcmp(argv[i],"-showDefaultModulePath"))
+ {
+ xf86PrintDefaultModulePath();
+ exit(0);
+ }
+ if (!strcmp(argv[i],"-showDefaultLibPath"))
+ {
+ xf86PrintDefaultLibraryPath();
+ exit(0);
+ }
+ /* Notice the -fp flag, but allow it to pass to the dix layer */
+ if (!strcmp(argv[i], "-fp"))
+ {
+ xf86fpFlag = TRUE;
+ return 0;
+ }
+ /* Notice the -bs flag, but allow it to pass to the dix layer */
+ if (!strcmp(argv[i], "-bs"))
+ {
+ xf86bsDisableFlag = TRUE;
+ return 0;
+ }
+ /* Notice the +bs flag, but allow it to pass to the dix layer */
+ if (!strcmp(argv[i], "+bs"))
+ {
+ xf86bsEnableFlag = TRUE;
+ return 0;
+ }
+ /* Notice the -s flag, but allow it to pass to the dix layer */
+ if (!strcmp(argv[i], "-s"))
+ {
+ xf86sFlag = TRUE;
+ return 0;
+ }
+ if (!strcmp(argv[i], "-pixmap24"))
+ {
+ xf86Pix24 = Pix24Use24;
+ return 1;
+ }
+ if (!strcmp(argv[i], "-pixmap32"))
+ {
+ xf86Pix24 = Pix24Use32;
+ return 1;
+ }
+ if (!strcmp(argv[i], "-fbbpp"))
+ {
+ int bpp;
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ if (sscanf(argv[++i], "%d", &bpp) == 1)
+ {
+ xf86FbBpp = bpp;
+ return 2;
+ }
+ else
+ {
+ ErrorF("Invalid fbbpp\n");
+ return 0;
+ }
+ }
+ if (!strcmp(argv[i], "-depth"))
+ {
+ int depth;
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ if (sscanf(argv[++i], "%d", &depth) == 1)
+ {
+ xf86Depth = depth;
+ return 2;
+ }
+ else
+ {
+ ErrorF("Invalid depth\n");
+ return 0;
+ }
+ }
+ if (!strcmp(argv[i], "-weight"))
+ {
+ int red, green, blue;
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ if (sscanf(argv[++i], "%1d%1d%1d", &red, &green, &blue) == 3)
+ {
+ xf86Weight.red = red;
+ xf86Weight.green = green;
+ xf86Weight.blue = blue;
+ return 2;
+ }
+ else
+ {
+ ErrorF("Invalid weighting\n");
+ return 0;
+ }
+ }
+ if (!strcmp(argv[i], "-gamma") || !strcmp(argv[i], "-rgamma") ||
+ !strcmp(argv[i], "-ggamma") || !strcmp(argv[i], "-bgamma"))
+ {
+ double gamma;
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ if (sscanf(argv[++i], "%lf", &gamma) == 1) {
+ if (gamma < GAMMA_MIN || gamma > GAMMA_MAX) {
+ ErrorF("gamma out of range, only %.2f <= gamma_value <= %.1f"
+ " is valid\n", GAMMA_MIN, GAMMA_MAX);
+ return 0;
+ }
+ if (!strcmp(argv[i-1], "-gamma"))
+ xf86Gamma.red = xf86Gamma.green = xf86Gamma.blue = gamma;
+ else if (!strcmp(argv[i-1], "-rgamma")) xf86Gamma.red = gamma;
+ else if (!strcmp(argv[i-1], "-ggamma")) xf86Gamma.green = gamma;
+ else if (!strcmp(argv[i-1], "-bgamma")) xf86Gamma.blue = gamma;
+ return 2;
+ }
+ }
+ if (!strcmp(argv[i], "-layout"))
+ {
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ xf86LayoutName = argv[++i];
+ return 2;
+ }
+ if (!strcmp(argv[i], "-screen"))
+ {
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ xf86ScreenName = argv[++i];
+ return 2;
+ }
+ if (!strcmp(argv[i], "-pointer"))
+ {
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ xf86PointerName = argv[++i];
+ return 2;
+ }
+ if (!strcmp(argv[i], "-keyboard"))
+ {
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ xf86KeyboardName = argv[++i];
+ return 2;
+ }
+ if (!strcmp(argv[i], "-nosilk"))
+ {
+ xf86silkenMouseDisableFlag = TRUE;
+ return 1;
+ }
+#ifdef HAVE_ACPI
+ if (!strcmp(argv[i], "-noacpi"))
+ {
+ xf86acpiDisableFlag = TRUE;
+ return 1;
+ }
+#endif
+ if (!strcmp(argv[i], "-configure"))
+ {
+ if (getuid() != 0 && geteuid() == 0) {
+ ErrorF("The '-configure' option can only be used by root.\n");
+ exit(1);
+ }
+ xf86DoConfigure = TRUE;
+ xf86AllowMouseOpenFail = TRUE;
+ return 1;
+ }
+ if (!strcmp(argv[i], "-showopts"))
+ {
+ if (getuid() != 0 && geteuid() == 0) {
+ ErrorF("The '-showopts' option can only be used by root.\n");
+ exit(1);
+ }
+ xf86DoShowOptions = TRUE;
+ return 1;
+ }
+ if (!strcmp(argv[i], "-isolateDevice"))
+ {
+ int bus, device, func;
+ CHECK_FOR_REQUIRED_ARGUMENT();
+ if (strncmp(argv[++i], "PCI:", 4)) {
+ FatalError("Bus types other than PCI not yet isolable\n");
+ }
+ if (sscanf(argv[i], "PCI:%d:%d:%d", &bus, &device, &func) == 3) {
+ xf86IsolateDevice.domain = PCI_DOM_FROM_BUS(bus);
+ xf86IsolateDevice.bus = PCI_BUS_NO_DOMAIN(bus);
+ xf86IsolateDevice.dev = device;
+ xf86IsolateDevice.func = func;
+ return 2;
+ } else {
+ FatalError("Invalid isolated device specification\n");
+ }
+ }
+ /* Notice cmdline xkbdir, but pass to dix as well */
+ if (!strcmp(argv[i], "-xkbdir"))
+ {
+ xf86xkbdirFlag = TRUE;
+ return 0;
+ }
+
+ /* OS-specific processing */
+ return xf86ProcessArgument(argc, argv, i);
+}
+
+/*
+ * ddxUseMsg --
+ * Print out correct use of device dependent commandline options.
+ * Maybe the user now knows what really to do ...
+ */
+
+void
+ddxUseMsg(void)
+{
+ ErrorF("\n");
+ ErrorF("\n");
+ ErrorF("Device Dependent Usage\n");
+ if (getuid() == 0 || geteuid() != 0)
+ {
+ ErrorF("-modulepath paths specify the module search path\n");
+ ErrorF("-logfile file specify a log file name\n");
+ ErrorF("-configure probe for devices and write an "__XCONFIGFILE__"\n");
+ ErrorF("-showopts print available options for all installed drivers\n");
+ }
+ ErrorF("-config file specify a configuration file, relative to the\n");
+ ErrorF(" "__XCONFIGFILE__" search path, only root can use absolute\n");
+ ErrorF("-configdir dir specify a configuration directory, relative to the\n");
+ ErrorF(" "__XCONFIGDIR__" search path, only root can use absolute\n");
+ ErrorF("-verbose [n] verbose startup messages\n");
+ ErrorF("-logverbose [n] verbose log messages\n");
+ ErrorF("-quiet minimal startup messages\n");
+ ErrorF("-pixmap24 use 24bpp pixmaps for depth 24\n");
+ ErrorF("-pixmap32 use 32bpp pixmaps for depth 24\n");
+ ErrorF("-fbbpp n set bpp for the framebuffer. Default: 8\n");
+ ErrorF("-depth n set colour depth. Default: 8\n");
+ ErrorF("-gamma f set gamma value (0.1 < f < 10.0) Default: 1.0\n");
+ ErrorF("-rgamma f set gamma value for red phase\n");
+ ErrorF("-ggamma f set gamma value for green phase\n");
+ ErrorF("-bgamma f set gamma value for blue phase\n");
+ ErrorF("-weight nnn set RGB weighting at 16 bpp. Default: 565\n");
+ ErrorF("-layout name specify the ServerLayout section name\n");
+ ErrorF("-screen name specify the Screen section name\n");
+ ErrorF("-keyboard name specify the core keyboard InputDevice name\n");
+ ErrorF("-pointer name specify the core pointer InputDevice name\n");
+ ErrorF("-nosilk disable Silken Mouse\n");
+ ErrorF("-flipPixels swap default black/white Pixel values\n");
+#ifdef XF86VIDMODE
+ ErrorF("-disableVidMode disable mode adjustments with xvidtune\n");
+ ErrorF("-allowNonLocalXvidtune allow xvidtune to be run as a non-local client\n");
+#endif
+ ErrorF("-allowMouseOpenFail start server even if the mouse can't be initialized\n");
+ ErrorF("-ignoreABI make module ABI mismatches non-fatal\n");
+ ErrorF("-isolateDevice bus_id restrict device resets to bus_id (PCI only)\n");
+ ErrorF("-version show the server version\n");
+ ErrorF("-showDefaultModulePath show the server default module path\n");
+ ErrorF("-showDefaultLibPath show the server default library path\n");
+ /* OS-specific usage */
+ xf86UseMsg();
+ ErrorF("\n");
+}
+
+
+/*
+ * xf86LoadModules iterates over a list that is being passed in.
+ */
+Bool
+xf86LoadModules(char **list, pointer *optlist)
+{
+ int errmaj, errmin;
+ pointer opt;
+ int i;
+ char *name;
+ Bool failed = FALSE;
+
+ if (!list)
+ return TRUE;
+
+ for (i = 0; list[i] != NULL; i++) {
+
+ /* Normalise the module name */
+ name = xf86NormalizeName(list[i]);
+
+ /* Skip empty names */
+ if (name == NULL || *name == '\0')
+ continue;
+
+ /* Replace obsolete keyboard driver with kbd */
+ if (!xf86NameCmp(name, "keyboard")) {
+ strcpy(name, "kbd");
+ }
+
+ if (optlist)
+ opt = optlist[i];
+ else
+ opt = NULL;
+
+ if (!LoadModule(name, NULL, NULL, NULL, opt, NULL, &errmaj, &errmin)) {
+ LoaderErrorMsg(NULL, name, errmaj, errmin);
+ failed = TRUE;
+ }
+ free(name);
+ }
+ return !failed;
+}
+
+/* Pixmap format stuff */
+
+PixmapFormatPtr
+xf86GetPixFormat(ScrnInfoPtr pScrn, int depth)
+{
+ int i;
+ static PixmapFormatRec format; /* XXX not reentrant */
+
+ /*
+ * When the formats[] list initialisation isn't complete, check the
+ * depth 24 pixmap config/cmdline options and screen-specified formats.
+ */
+
+ if (!formatsDone) {
+ if (depth == 24) {
+ Pix24Flags pix24 = Pix24DontCare;
+
+ format.depth = 24;
+ format.scanlinePad = BITMAP_SCANLINE_PAD;
+ if (xf86Info.pixmap24 != Pix24DontCare)
+ pix24 = xf86Info.pixmap24;
+ else if (pScrn->pixmap24 != Pix24DontCare)
+ pix24 = pScrn->pixmap24;
+ if (pix24 == Pix24Use24)
+ format.bitsPerPixel = 24;
+ else
+ format.bitsPerPixel = 32;
+ return &format;
+ }
+ }
+
+ for (i = 0; i < numFormats; i++)
+ if (formats[i].depth == depth)
+ break;
+ if (i != numFormats)
+ return &formats[i];
+ else if (!formatsDone) {
+ /* Check for screen-specified formats */
+ for (i = 0; i < pScrn->numFormats; i++)
+ if (pScrn->formats[i].depth == depth)
+ break;
+ if (i != pScrn->numFormats)
+ return &pScrn->formats[i];
+ }
+ return NULL;
+}
+
+int
+xf86GetBppFromDepth(ScrnInfoPtr pScrn, int depth)
+{
+ PixmapFormatPtr format;
+
+
+ format = xf86GetPixFormat(pScrn, depth);
+ if (format)
+ return format->bitsPerPixel;
+ else
+ return 0;
+}
diff --git a/xorg-server/hw/xfree86/common/xf86Mode.c b/xorg-server/hw/xfree86/common/xf86Mode.c
index 5d30a782c..af738e703 100644
--- a/xorg-server/hw/xfree86/common/xf86Mode.c
+++ b/xorg-server/hw/xfree86/common/xf86Mode.c
@@ -1,2067 +1,2067 @@
-/*
- * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-/*
- * LCM() and scanLineWidth() are:
- *
- * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of Marc Aurele La France not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. Marc Aurele La France makes no representations
- * about the suitability of this software for any purpose. It is provided
- * "as-is" without express or implied warranty.
- *
- * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
- * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- * Copyright 1990,91,92,93 by Thomas Roell, Germany.
- * Copyright 1991,92,93 by SGCS (Snitily Graphics Consulting Services), USA.
- *
- * Permission to use, copy, modify, distribute, and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and
- * that both that copyright notice and this permission notice appear
- * in supporting documentation, and that the name of Thomas Roell nor
- * SGCS be used in advertising or publicity pertaining to distribution
- * of the software without specific, written prior permission.
- * Thomas Roell nor SGCS makes no representations about the suitability
- * of this software for any purpose. It is provided "as is" without
- * express or implied warranty.
- *
- * THOMAS ROELL AND SGCS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL THOMAS ROELL OR SGCS BE LIABLE FOR ANY
- * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
- * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
- * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
- * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * Authors: Dirk Hohndel <hohndel@XFree86.Org>
- * David Dawes <dawes@XFree86.Org>
- * Marc La France <tsi@XFree86.Org>
- * ... and others
- *
- * This file includes helper functions for mode related things.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <X11/X.h>
-#include "xf86Modes.h"
-#include "os.h"
-#include "servermd.h"
-#include "globals.h"
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "edid.h"
-
-static void
-printModeRejectMessage(int index, DisplayModePtr p, int status)
-{
- char *type;
-
- if (p->type & M_T_BUILTIN)
- type = "built-in ";
- else if (p->type & M_T_DEFAULT)
- type = "default ";
- else if (p->type & M_T_DRIVER)
- type = "driver ";
- else
- type = "";
-
- xf86DrvMsg(index, X_INFO, "Not using %smode \"%s\" (%s)\n", type, p->name,
- xf86ModeStatusToString(status));
-}
-
-/*
- * xf86GetNearestClock --
- * Find closest clock to given frequency (in kHz). This assumes the
- * number of clocks is greater than zero.
- */
-int
-xf86GetNearestClock(ScrnInfoPtr scrp, int freq, Bool allowDiv2,
- int DivFactor, int MulFactor, int *divider)
-{
- int nearestClock = 0, nearestDiv = 1;
- int minimumGap = abs(freq - scrp->clock[0]);
- int i, j, k, gap;
-
- if (allowDiv2)
- k = 2;
- else
- k = 1;
-
- /* Must set this here in case the best match is scrp->clock[0] */
- if (divider != NULL)
- *divider = 0;
-
- for (i = 0; i < scrp->numClocks; i++) {
- for (j = 1; j <= k; j++) {
- gap = abs((freq * j) - ((scrp->clock[i] * DivFactor) / MulFactor));
- if ((gap < minimumGap) ||
- ((gap == minimumGap) && (j < nearestDiv))) {
- minimumGap = gap;
- nearestClock = i;
- nearestDiv = j;
- if (divider != NULL)
- *divider = (j - 1) * V_CLKDIV2;
- }
- }
- }
- return nearestClock;
-}
-
-/*
- * xf86ModeStatusToString
- *
- * Convert a ModeStatus value to a printable message
- */
-
-const char *
-xf86ModeStatusToString(ModeStatus status)
-{
- switch (status) {
- case MODE_OK:
- return "Mode OK";
- case MODE_HSYNC:
- return "hsync out of range";
- case MODE_VSYNC:
- return "vrefresh out of range";
- case MODE_H_ILLEGAL:
- return "illegal horizontal timings";
- case MODE_V_ILLEGAL:
- return "illegal vertical timings";
- case MODE_BAD_WIDTH:
- return "width requires unsupported line pitch";
- case MODE_NOMODE:
- return "no mode of this name";
- case MODE_NO_INTERLACE:
- return "interlace mode not supported";
- case MODE_NO_DBLESCAN:
- return "doublescan mode not supported";
- case MODE_NO_VSCAN:
- return "multiscan mode not supported";
- case MODE_MEM:
- return "insufficient memory for mode";
- case MODE_VIRTUAL_X:
- return "width too large for virtual size";
- case MODE_VIRTUAL_Y:
- return "height too large for virtual size";
- case MODE_MEM_VIRT:
- return "insufficient memory given virtual size";
- case MODE_NOCLOCK:
- return "no clock available for mode";
- case MODE_CLOCK_HIGH:
- return "mode clock too high";
- case MODE_CLOCK_LOW:
- return "mode clock too low";
- case MODE_CLOCK_RANGE:
- return "bad mode clock/interlace/doublescan";
- case MODE_BAD_HVALUE:
- return "horizontal timing out of range";
- case MODE_BAD_VVALUE:
- return "vertical timing out of range";
- case MODE_BAD_VSCAN:
- return "VScan value out of range";
- case MODE_HSYNC_NARROW:
- return "horizontal sync too narrow";
- case MODE_HSYNC_WIDE:
- return "horizontal sync too wide";
- case MODE_HBLANK_NARROW:
- return "horizontal blanking too narrow";
- case MODE_HBLANK_WIDE:
- return "horizontal blanking too wide";
- case MODE_VSYNC_NARROW:
- return "vertical sync too narrow";
- case MODE_VSYNC_WIDE:
- return "vertical sync too wide";
- case MODE_VBLANK_NARROW:
- return "vertical blanking too narrow";
- case MODE_VBLANK_WIDE:
- return "vertical blanking too wide";
- case MODE_PANEL:
- return "exceeds panel dimensions";
- case MODE_INTERLACE_WIDTH:
- return "width too large for interlaced mode";
- case MODE_ONE_WIDTH:
- return "all modes must have the same width";
- case MODE_ONE_HEIGHT:
- return "all modes must have the same height";
- case MODE_ONE_SIZE:
- return "all modes must have the same resolution";
- case MODE_NO_REDUCED:
- return "monitor doesn't support reduced blanking";
- case MODE_BANDWIDTH:
- return "mode requires too much memory bandwidth";
- case MODE_BAD:
- return "unknown reason";
- case MODE_ERROR:
- return "internal error";
- default:
- return "unknown";
- }
-}
-
-/*
- * xf86ShowClockRanges() -- Print the clock ranges allowed
- * and the clock values scaled by ClockMulFactor and ClockDivFactor
- */
-void
-xf86ShowClockRanges(ScrnInfoPtr scrp, ClockRangePtr clockRanges)
-{
- ClockRangePtr cp;
- int MulFactor = 1;
- int DivFactor = 1;
- int i, j;
- int scaledClock;
-
- for (cp = clockRanges; cp != NULL; cp = cp->next) {
- DivFactor = max(1, cp->ClockDivFactor);
- MulFactor = max(1, cp->ClockMulFactor);
- if (scrp->progClock) {
- if (cp->minClock) {
- if (cp->maxClock) {
- xf86DrvMsg(scrp->scrnIndex, X_INFO,
- "Clock range: %6.2f to %6.2f MHz\n",
- (double)cp->minClock / 1000.0,
- (double)cp->maxClock / 1000.0);
- } else {
- xf86DrvMsg(scrp->scrnIndex, X_INFO,
- "Minimum clock: %6.2f MHz\n",
- (double)cp->minClock / 1000.0);
- }
- } else {
- if (cp->maxClock) {
- xf86DrvMsg(scrp->scrnIndex, X_INFO,
- "Maximum clock: %6.2f MHz\n",
- (double)cp->maxClock / 1000.0);
- }
- }
- } else if (DivFactor > 1 || MulFactor > 1) {
- j = 0;
- for (i = 0; i < scrp->numClocks; i++) {
- scaledClock = (scrp->clock[i] * DivFactor) / MulFactor;
- if (scaledClock >= cp->minClock && scaledClock <= cp->maxClock) {
- if ((j % 8) == 0) {
- if (j > 0)
- xf86ErrorF("\n");
- xf86DrvMsg(scrp->scrnIndex, X_INFO, "scaled clocks:");
- }
- xf86ErrorF(" %6.2f", (double)scaledClock / 1000.0);
- j++;
- }
- }
- xf86ErrorF("\n");
- }
- }
-}
-
-static Bool
-modeInClockRange(ClockRangePtr cp, DisplayModePtr p)
-{
- return ((p->Clock >= cp->minClock) &&
- (p->Clock <= cp->maxClock) &&
- (cp->interlaceAllowed || !(p->Flags & V_INTERLACE)) &&
- (cp->doubleScanAllowed ||
- ((p->VScan <= 1) && !(p->Flags & V_DBLSCAN))));
-}
-
-/*
- * xf86FindClockRangeForMode() [... like the name says ...]
- */
-static ClockRangePtr
-xf86FindClockRangeForMode(ClockRangePtr clockRanges, DisplayModePtr p)
-{
- ClockRangePtr cp;
-
- for (cp = clockRanges; ; cp = cp->next)
- if (!cp || modeInClockRange(cp, p))
- return cp;
-}
-
-
-/*
- * xf86HandleBuiltinMode() - handles built-in modes
- */
-static ModeStatus
-xf86HandleBuiltinMode(ScrnInfoPtr scrp,
- DisplayModePtr p,
- DisplayModePtr modep,
- ClockRangePtr clockRanges,
- Bool allowDiv2)
-{
- ClockRangePtr cp;
- int extraFlags = 0;
- int MulFactor = 1;
- int DivFactor = 1;
- int clockIndex;
-
- /* Reject previously rejected modes */
- if (p->status != MODE_OK)
- return p->status;
-
- /* Reject previously considered modes */
- if (p->prev)
- return MODE_NOMODE;
-
- if ((p->type & M_T_CLOCK_C) == M_T_CLOCK_C) {
- /* Check clock is in range */
- cp = xf86FindClockRangeForMode(clockRanges, p);
- if (cp == NULL){
- modep->type = p->type;
- p->status = MODE_CLOCK_RANGE;
- return MODE_CLOCK_RANGE;
- }
- DivFactor = cp->ClockDivFactor;
- MulFactor = cp->ClockMulFactor;
- if (!scrp->progClock) {
- clockIndex = xf86GetNearestClock(scrp, p->Clock, allowDiv2,
- cp->ClockDivFactor,
- cp->ClockMulFactor, &extraFlags);
- modep->Clock = (scrp->clock[clockIndex] * DivFactor)
- / MulFactor;
- modep->ClockIndex = clockIndex;
- modep->SynthClock = scrp->clock[clockIndex];
- if (extraFlags & V_CLKDIV2) {
- modep->Clock /= 2;
- modep->SynthClock /= 2;
- }
- } else {
- modep->Clock = p->Clock;
- modep->ClockIndex = -1;
- modep->SynthClock = (modep->Clock * MulFactor)
- / DivFactor;
- }
- modep->PrivFlags = cp->PrivFlags;
- } else {
- if(!scrp->progClock) {
- modep->Clock = p->Clock;
- modep->ClockIndex = p->ClockIndex;
- modep->SynthClock = p->SynthClock;
- } else {
- modep->Clock = p->Clock;
- modep->ClockIndex = -1;
- modep->SynthClock = p->SynthClock;
- }
- modep->PrivFlags = p->PrivFlags;
- }
- modep->type = p->type;
- modep->HDisplay = p->HDisplay;
- modep->HSyncStart = p->HSyncStart;
- modep->HSyncEnd = p->HSyncEnd;
- modep->HTotal = p->HTotal;
- modep->HSkew = p->HSkew;
- modep->VDisplay = p->VDisplay;
- modep->VSyncStart = p->VSyncStart;
- modep->VSyncEnd = p->VSyncEnd;
- modep->VTotal = p->VTotal;
- modep->VScan = p->VScan;
- modep->Flags = p->Flags | extraFlags;
- modep->CrtcHDisplay = p->CrtcHDisplay;
- modep->CrtcHBlankStart = p->CrtcHBlankStart;
- modep->CrtcHSyncStart = p->CrtcHSyncStart;
- modep->CrtcHSyncEnd = p->CrtcHSyncEnd;
- modep->CrtcHBlankEnd = p->CrtcHBlankEnd;
- modep->CrtcHTotal = p->CrtcHTotal;
- modep->CrtcHSkew = p->CrtcHSkew;
- modep->CrtcVDisplay = p->CrtcVDisplay;
- modep->CrtcVBlankStart = p->CrtcVBlankStart;
- modep->CrtcVSyncStart = p->CrtcVSyncStart;
- modep->CrtcVSyncEnd = p->CrtcVSyncEnd;
- modep->CrtcVBlankEnd = p->CrtcVBlankEnd;
- modep->CrtcVTotal = p->CrtcVTotal;
- modep->CrtcHAdjusted = p->CrtcHAdjusted;
- modep->CrtcVAdjusted = p->CrtcVAdjusted;
- modep->HSync = p->HSync;
- modep->VRefresh = p->VRefresh;
- modep->Private = p->Private;
- modep->PrivSize = p->PrivSize;
-
- p->prev = modep;
-
- return MODE_OK;
-}
-
-/*
- * xf86LookupMode
- *
- * This function returns a mode from the given list which matches the
- * given name. When multiple modes with the same name are available,
- * the method of picking the matching mode is determined by the
- * strategy selected.
- *
- * This function takes the following parameters:
- * scrp ScrnInfoPtr
- * modep pointer to the returned mode, which must have the name
- * field filled in.
- * clockRanges a list of clock ranges. This is optional when all the
- * modes are built-in modes.
- * strategy how to decide which mode to use from multiple modes with
- * the same name
- *
- * In addition, the following fields from the ScrnInfoRec are used:
- * modePool the list of monitor modes compatible with the driver
- * clocks a list of discrete clocks
- * numClocks number of discrete clocks
- * progClock clock is programmable
- *
- * If a mode was found, its values are filled in to the area pointed to
- * by modep, If a mode was not found the return value indicates the
- * reason.
- */
-
-ModeStatus
-xf86LookupMode(ScrnInfoPtr scrp, DisplayModePtr modep,
- ClockRangePtr clockRanges, LookupModeFlags strategy)
-{
- DisplayModePtr p, bestMode = NULL;
- ClockRangePtr cp;
- int i, k, gap, minimumGap = CLOCK_TOLERANCE + 1;
- double refresh, bestRefresh = 0.0;
- Bool found = FALSE;
- int extraFlags = 0;
- int clockIndex = -1;
- int MulFactor = 1;
- int DivFactor = 1;
- int ModePrivFlags = 0;
- ModeStatus status = MODE_NOMODE;
- Bool allowDiv2 = (strategy & LOOKUP_CLKDIV2) != 0;
- int n;
- const int types[] = {
- M_T_BUILTIN | M_T_PREFERRED,
- M_T_BUILTIN,
- M_T_USERDEF | M_T_PREFERRED,
- M_T_USERDEF,
- M_T_DRIVER | M_T_PREFERRED,
- M_T_DRIVER,
- 0
- };
- const int ntypes = sizeof(types) / sizeof(int);
-
- strategy &= ~(LOOKUP_CLKDIV2 | LOOKUP_OPTIONAL_TOLERANCES);
-
- /* Some sanity checking */
- if (scrp == NULL || scrp->modePool == NULL ||
- (!scrp->progClock && scrp->numClocks == 0)) {
- ErrorF("xf86LookupMode: called with invalid scrnInfoRec\n");
- return MODE_ERROR;
- }
- if (modep == NULL || modep->name == NULL) {
- ErrorF("xf86LookupMode: called with invalid modep\n");
- return MODE_ERROR;
- }
- for (cp = clockRanges; cp != NULL; cp = cp->next) {
- /* DivFactor and MulFactor must be > 0 */
- cp->ClockDivFactor = max(1, cp->ClockDivFactor);
- cp->ClockMulFactor = max(1, cp->ClockMulFactor);
- }
-
- /* Scan the mode pool for matching names */
- for (n = 0; n < ntypes; n++) {
- int type = types[n];
- for (p = scrp->modePool; p != NULL; p = p->next) {
-
- /* scan through the modes in the sort order above */
- if ((p->type & type) != type)
- continue;
-
- if (strcmp(p->name, modep->name) == 0) {
-
- /* Skip over previously rejected modes */
- if (p->status != MODE_OK) {
- if (!found)
- status = p->status;
- continue;
- }
-
- /* Skip over previously considered modes */
- if (p->prev)
- continue;
-
- if (p->type & M_T_BUILTIN) {
- return xf86HandleBuiltinMode(scrp, p,modep, clockRanges,
- allowDiv2);
- }
-
- /* Check clock is in range */
- cp = xf86FindClockRangeForMode(clockRanges, p);
- if (cp == NULL) {
- /*
- * XXX Could do more here to provide a more detailed
- * reason for not finding a mode.
- */
- p->status = MODE_CLOCK_RANGE;
- if (!found)
- status = MODE_CLOCK_RANGE;
- continue;
- }
-
- /*
- * If programmable clock and strategy is not
- * LOOKUP_BEST_REFRESH, the required mode has been found,
- * otherwise record the refresh and continue looking.
- */
- if (scrp->progClock) {
- found = TRUE;
- if (strategy != LOOKUP_BEST_REFRESH) {
- bestMode = p;
- DivFactor = cp->ClockDivFactor;
- MulFactor = cp->ClockMulFactor;
- ModePrivFlags = cp->PrivFlags;
- break;
- }
- refresh = xf86ModeVRefresh(p);
- if (p->Flags & V_INTERLACE)
- refresh /= INTERLACE_REFRESH_WEIGHT;
- if (refresh > bestRefresh) {
- bestMode = p;
- DivFactor = cp->ClockDivFactor;
- MulFactor = cp->ClockMulFactor;
- ModePrivFlags = cp->PrivFlags;
- bestRefresh = refresh;
- }
- continue;
- }
-
- /*
- * Clock is in range, so if it is not a programmable clock, find
- * a matching clock.
- */
-
- i = xf86GetNearestClock(scrp, p->Clock, allowDiv2,
- cp->ClockDivFactor, cp->ClockMulFactor, &k);
- /*
- * If the clock is too far from the requested clock, this
- * mode is no good.
- */
- if (k & V_CLKDIV2)
- gap = abs((p->Clock * 2) -
- ((scrp->clock[i] * cp->ClockDivFactor) /
- cp->ClockMulFactor));
- else
- gap = abs(p->Clock -
- ((scrp->clock[i] * cp->ClockDivFactor) /
- cp->ClockMulFactor));
- if (gap > minimumGap) {
- p->status = MODE_NOCLOCK;
- if (!found)
- status = MODE_NOCLOCK;
- continue;
- }
- found = TRUE;
-
- if (strategy == LOOKUP_BEST_REFRESH) {
- refresh = xf86ModeVRefresh(p);
- if (p->Flags & V_INTERLACE)
- refresh /= INTERLACE_REFRESH_WEIGHT;
- if (refresh > bestRefresh) {
- bestMode = p;
- DivFactor = cp->ClockDivFactor;
- MulFactor = cp->ClockMulFactor;
- ModePrivFlags = cp->PrivFlags;
- extraFlags = k;
- clockIndex = i;
- bestRefresh = refresh;
- }
- continue;
- }
- if (strategy == LOOKUP_CLOSEST_CLOCK) {
- if (gap < minimumGap) {
- bestMode = p;
- DivFactor = cp->ClockDivFactor;
- MulFactor = cp->ClockMulFactor;
- ModePrivFlags = cp->PrivFlags;
- extraFlags = k;
- clockIndex = i;
- minimumGap = gap;
- }
- continue;
- }
- /*
- * If strategy is neither LOOKUP_BEST_REFRESH or
- * LOOKUP_CLOSEST_CLOCK the required mode has been found.
- */
- bestMode = p;
- DivFactor = cp->ClockDivFactor;
- MulFactor = cp->ClockMulFactor;
- ModePrivFlags = cp->PrivFlags;
- extraFlags = k;
- clockIndex = i;
- break;
- }
- }
- if (found) break;
- }
- if (!found || bestMode == NULL)
- return status;
-
- /* Fill in the mode parameters */
- if (scrp->progClock) {
- modep->Clock = bestMode->Clock;
- modep->ClockIndex = -1;
- modep->SynthClock = (modep->Clock * MulFactor) / DivFactor;
- } else {
- modep->Clock = (scrp->clock[clockIndex] * DivFactor) /
- MulFactor;
- modep->ClockIndex = clockIndex;
- modep->SynthClock = scrp->clock[clockIndex];
- if (extraFlags & V_CLKDIV2) {
- modep->Clock /= 2;
- modep->SynthClock /= 2;
- }
- }
- modep->type = bestMode->type;
- modep->PrivFlags = ModePrivFlags;
- modep->HDisplay = bestMode->HDisplay;
- modep->HSyncStart = bestMode->HSyncStart;
- modep->HSyncEnd = bestMode->HSyncEnd;
- modep->HTotal = bestMode->HTotal;
- modep->HSkew = bestMode->HSkew;
- modep->VDisplay = bestMode->VDisplay;
- modep->VSyncStart = bestMode->VSyncStart;
- modep->VSyncEnd = bestMode->VSyncEnd;
- modep->VTotal = bestMode->VTotal;
- modep->VScan = bestMode->VScan;
- modep->Flags = bestMode->Flags | extraFlags;
- modep->CrtcHDisplay = bestMode->CrtcHDisplay;
- modep->CrtcHBlankStart = bestMode->CrtcHBlankStart;
- modep->CrtcHSyncStart = bestMode->CrtcHSyncStart;
- modep->CrtcHSyncEnd = bestMode->CrtcHSyncEnd;
- modep->CrtcHBlankEnd = bestMode->CrtcHBlankEnd;
- modep->CrtcHTotal = bestMode->CrtcHTotal;
- modep->CrtcHSkew = bestMode->CrtcHSkew;
- modep->CrtcVDisplay = bestMode->CrtcVDisplay;
- modep->CrtcVBlankStart = bestMode->CrtcVBlankStart;
- modep->CrtcVSyncStart = bestMode->CrtcVSyncStart;
- modep->CrtcVSyncEnd = bestMode->CrtcVSyncEnd;
- modep->CrtcVBlankEnd = bestMode->CrtcVBlankEnd;
- modep->CrtcVTotal = bestMode->CrtcVTotal;
- modep->CrtcHAdjusted = bestMode->CrtcHAdjusted;
- modep->CrtcVAdjusted = bestMode->CrtcVAdjusted;
- modep->HSync = bestMode->HSync;
- modep->VRefresh = bestMode->VRefresh;
- modep->Private = bestMode->Private;
- modep->PrivSize = bestMode->PrivSize;
-
- bestMode->prev = modep;
-
- return MODE_OK;
-}
-
-/*
- * xf86CheckModeForMonitor
- *
- * This function takes a mode and monitor description, and determines
- * if the mode is valid for the monitor.
- */
-ModeStatus
-xf86CheckModeForMonitor(DisplayModePtr mode, MonPtr monitor)
-{
- int i;
-
- /* Sanity checks */
- if (mode == NULL || monitor == NULL) {
- ErrorF("xf86CheckModeForMonitor: called with invalid parameters\n");
- return MODE_ERROR;
- }
-
- DebugF("xf86CheckModeForMonitor(%p %s, %p %s)\n",
- mode, mode->name, monitor, monitor->id);
-
- /* Some basic mode validity checks */
- if (0 >= mode->HDisplay || mode->HDisplay > mode->HSyncStart ||
- mode->HSyncStart >= mode->HSyncEnd || mode->HSyncEnd >= mode->HTotal)
- return MODE_H_ILLEGAL;
-
- if (0 >= mode->VDisplay || mode->VDisplay > mode->VSyncStart ||
- mode->VSyncStart >= mode->VSyncEnd || mode->VSyncEnd >= mode->VTotal)
- return MODE_V_ILLEGAL;
-
- if (monitor->nHsync > 0) {
- /* Check hsync against the allowed ranges */
- float hsync = xf86ModeHSync(mode);
- for (i = 0; i < monitor->nHsync; i++)
- if ((hsync > monitor->hsync[i].lo * (1.0 - SYNC_TOLERANCE)) &&
- (hsync < monitor->hsync[i].hi * (1.0 + SYNC_TOLERANCE)))
- break;
-
- /* Now see whether we ran out of sync ranges without finding a match */
- if (i == monitor->nHsync)
- return MODE_HSYNC;
- }
-
- if (monitor->nVrefresh > 0) {
- /* Check vrefresh against the allowed ranges */
- float vrefrsh = xf86ModeVRefresh(mode);
- for (i = 0; i < monitor->nVrefresh; i++)
- if ((vrefrsh > monitor->vrefresh[i].lo * (1.0 - SYNC_TOLERANCE)) &&
- (vrefrsh < monitor->vrefresh[i].hi * (1.0 + SYNC_TOLERANCE)))
- break;
-
- /* Now see whether we ran out of refresh ranges without finding a match */
- if (i == monitor->nVrefresh)
- return MODE_VSYNC;
- }
-
- /* Force interlaced modes to have an odd VTotal */
- if (mode->Flags & V_INTERLACE)
- mode->CrtcVTotal = mode->VTotal |= 1;
-
- /*
- * This code stops cvt -r modes, and only cvt -r modes, from hitting 15y+
- * old CRTs which might, when there is a lot of solar flare activity and
- * when the celestial bodies are unfavourably aligned, implode trying to
- * sync to it. It's called "Protecting the user from doing anything stupid".
- * -- libv
- */
-
- if (xf86ModeIsReduced(mode)) {
- if (!monitor->reducedblanking && !(mode->type & M_T_DRIVER))
- return MODE_NO_REDUCED;
- }
-
- if ((monitor->maxPixClock) && (mode->Clock > monitor->maxPixClock))
- return MODE_CLOCK_HIGH;
-
- return MODE_OK;
-}
-
-/*
- * xf86CheckModeSize
- *
- * An internal routine to check if a mode fits in video memory. This tries to
- * avoid overflows that would otherwise occur when video memory size is greater
- * than 256MB.
- */
-static Bool
-xf86CheckModeSize(ScrnInfoPtr scrp, int w, int x, int y)
-{
- int bpp = scrp->fbFormat.bitsPerPixel,
- pad = scrp->fbFormat.scanlinePad;
- int lineWidth, lastWidth;
-
- if (scrp->depth == 4)
- pad *= 4; /* 4 planes */
-
- /* Sanity check */
- if ((w < 0) || (x < 0) || (y <= 0))
- return FALSE;
-
- lineWidth = (((w * bpp) + pad - 1) / pad) * pad;
- lastWidth = x * bpp;
-
- /*
- * At this point, we need to compare
- *
- * (lineWidth * (y - 1)) + lastWidth
- *
- * against
- *
- * scrp->videoRam * (1024 * 8)
- *
- * These are bit quantities. To avoid overflows, do the comparison in
- * terms of BITMAP_SCANLINE_PAD units. This assumes BITMAP_SCANLINE_PAD
- * is a power of 2. We currently use 32, which limits us to a video
- * memory size of 8GB.
- */
-
- lineWidth = (lineWidth + (BITMAP_SCANLINE_PAD - 1)) / BITMAP_SCANLINE_PAD;
- lastWidth = (lastWidth + (BITMAP_SCANLINE_PAD - 1)) / BITMAP_SCANLINE_PAD;
-
- if ((lineWidth * (y - 1) + lastWidth) >
- (scrp->videoRam * ((1024 * 8) / BITMAP_SCANLINE_PAD)))
- return FALSE;
-
- return TRUE;
-}
-
-/*
- * xf86InitialCheckModeForDriver
- *
- * This function checks if a mode satisfies a driver's initial requirements:
- * - mode size fits within the available pixel area (memory)
- * - width lies within the range of supported line pitches
- * - mode size fits within virtual size (if fixed)
- * - horizontal timings are in range
- *
- * This function takes the following parameters:
- * scrp ScrnInfoPtr
- * mode mode to check
- * maxPitch (optional) maximum line pitch
- * virtualX (optional) virtual width requested
- * virtualY (optional) virtual height requested
- *
- * In addition, the following fields from the ScrnInfoRec are used:
- * monitor pointer to structure for monitor section
- * fbFormat pixel format for the framebuffer
- * videoRam video memory size (in kB)
- * maxHValue maximum horizontal timing value
- * maxVValue maximum vertical timing value
- */
-
-ModeStatus
-xf86InitialCheckModeForDriver(ScrnInfoPtr scrp, DisplayModePtr mode,
- ClockRangePtr clockRanges,
- LookupModeFlags strategy,
- int maxPitch, int virtualX, int virtualY)
-{
- ClockRangePtr cp;
- ModeStatus status;
- Bool allowDiv2 = (strategy & LOOKUP_CLKDIV2) != 0;
- int i, needDiv2;
-
- /* Sanity checks */
- if (!scrp || !mode || !clockRanges) {
- ErrorF("xf86InitialCheckModeForDriver: "
- "called with invalid parameters\n");
- return MODE_ERROR;
- }
-
- DebugF("xf86InitialCheckModeForDriver(%p, %p %s, %p, 0x%x, %d, %d, %d)\n",
- scrp, mode, mode->name , clockRanges, strategy, maxPitch, virtualX, virtualY);
-
- /* Some basic mode validity checks */
- if (0 >= mode->HDisplay || mode->HDisplay > mode->HSyncStart ||
- mode->HSyncStart >= mode->HSyncEnd || mode->HSyncEnd >= mode->HTotal)
- return MODE_H_ILLEGAL;
-
- if (0 >= mode->VDisplay || mode->VDisplay > mode->VSyncStart ||
- mode->VSyncStart >= mode->VSyncEnd || mode->VSyncEnd >= mode->VTotal)
- return MODE_V_ILLEGAL;
-
- if (!xf86CheckModeSize(scrp, mode->HDisplay, mode->HDisplay,
- mode->VDisplay))
- return MODE_MEM;
-
- if (maxPitch > 0 && mode->HDisplay > maxPitch)
- return MODE_BAD_WIDTH;
-
- if (virtualX > 0 && mode->HDisplay > virtualX)
- return MODE_VIRTUAL_X;
-
- if (virtualY > 0 && mode->VDisplay > virtualY)
- return MODE_VIRTUAL_Y;
-
- if (scrp->maxHValue > 0 && mode->HTotal > scrp->maxHValue)
- return MODE_BAD_HVALUE;
-
- if (scrp->maxVValue > 0 && mode->VTotal > scrp->maxVValue)
- return MODE_BAD_VVALUE;
-
- /*
- * The use of the DisplayModeRec's Crtc* and SynthClock elements below is
- * provisional, in that they are later reused by the driver at mode-set
- * time. Here, they are temporarily enlisted to contain the mode timings
- * as seen by the CRT or panel (rather than the CRTC). The driver's
- * ValidMode() is allowed to modify these so it can deal with such things
- * as mode stretching and/or centering. The driver should >NOT< modify the
- * user-supplied values as these are reported back when mode validation is
- * said and done.
- */
- /*
- * NOTE: We (ab)use the mode->Crtc* values here to store timing
- * information for the calculation of Hsync and Vrefresh. Before
- * these values are calculated the driver is given the opportunity
- * to either set these HSync and VRefresh itself or modify the timing
- * values.
- * The difference to the final calculation is small but imortand:
- * here we pass the flag INTERLACE_HALVE_V regardless if the driver
- * sets it or not. This way our calculation of VRefresh has the same
- * effect as if we do if (flags & V_INTERLACE) refresh *= 2.0
- * This dual use of the mode->Crtc* values will certainly create
- * confusion and is bad software design. However since it's part of
- * the driver API it's hard to change.
- */
-
- if (scrp->ValidMode) {
-
- xf86SetModeCrtc(mode, INTERLACE_HALVE_V);
-
- cp = xf86FindClockRangeForMode(clockRanges, mode);
- if (!cp)
- return MODE_CLOCK_RANGE;
-
- if (cp->ClockMulFactor < 1)
- cp->ClockMulFactor = 1;
- if (cp->ClockDivFactor < 1)
- cp->ClockDivFactor = 1;
-
- /*
- * XXX The effect of clock dividers and multipliers on the monitor's
- * pixel clock needs to be verified.
- */
- if (scrp->progClock) {
- mode->SynthClock = mode->Clock;
- } else {
- i = xf86GetNearestClock(scrp, mode->Clock, allowDiv2,
- cp->ClockDivFactor, cp->ClockMulFactor,
- &needDiv2);
- mode->SynthClock = (scrp->clock[i] * cp->ClockDivFactor) /
- cp->ClockMulFactor;
- if (needDiv2 & V_CLKDIV2)
- mode->SynthClock /= 2;
- }
-
- status = (*scrp->ValidMode)(scrp->scrnIndex, mode, FALSE,
- MODECHECK_INITIAL);
- if (status != MODE_OK)
- return status;
-
- if (mode->HSync <= 0.0)
- mode->HSync = (float)mode->SynthClock / (float)mode->CrtcHTotal;
- if (mode->VRefresh <= 0.0)
- mode->VRefresh = (mode->SynthClock * 1000.0)
- / (mode->CrtcHTotal * mode->CrtcVTotal);
- }
-
- mode->HSync = xf86ModeHSync(mode);
- mode->VRefresh = xf86ModeVRefresh(mode);
-
- /* Assume it is OK */
- return MODE_OK;
-}
-
-/*
- * xf86CheckModeForDriver
- *
- * This function is for checking modes while the server is running (for
- * use mainly by the VidMode extension).
- *
- * This function checks if a mode satisfies a driver's requirements:
- * - width lies within the line pitch
- * - mode size fits within virtual size
- * - horizontal/vertical timings are in range
- *
- * This function takes the following parameters:
- * scrp ScrnInfoPtr
- * mode mode to check
- * flags not (currently) used
- *
- * In addition, the following fields from the ScrnInfoRec are used:
- * maxHValue maximum horizontal timing value
- * maxVValue maximum vertical timing value
- * virtualX virtual width
- * virtualY virtual height
- * clockRanges allowable clock ranges
- */
-
-ModeStatus
-xf86CheckModeForDriver(ScrnInfoPtr scrp, DisplayModePtr mode, int flags)
-{
- ClockRangePtr cp;
- int i, k, gap, minimumGap = CLOCK_TOLERANCE + 1;
- int extraFlags = 0;
- int clockIndex = -1;
- int MulFactor = 1;
- int DivFactor = 1;
- int ModePrivFlags = 0;
- ModeStatus status = MODE_NOMODE;
-
- /* Some sanity checking */
- if (scrp == NULL || (!scrp->progClock && scrp->numClocks == 0)) {
- ErrorF("xf86CheckModeForDriver: called with invalid scrnInfoRec\n");
- return MODE_ERROR;
- }
- if (mode == NULL) {
- ErrorF("xf86CheckModeForDriver: called with invalid modep\n");
- return MODE_ERROR;
- }
-
- /* Check the mode size */
- if (mode->HDisplay > scrp->virtualX)
- return MODE_VIRTUAL_X;
-
- if (mode->VDisplay > scrp->virtualY)
- return MODE_VIRTUAL_Y;
-
- if (scrp->maxHValue > 0 && mode->HTotal > scrp->maxHValue)
- return MODE_BAD_HVALUE;
-
- if (scrp->maxVValue > 0 && mode->VTotal > scrp->maxVValue)
- return MODE_BAD_VVALUE;
-
- for (cp = scrp->clockRanges; cp != NULL; cp = cp->next) {
- /* DivFactor and MulFactor must be > 0 */
- cp->ClockDivFactor = max(1, cp->ClockDivFactor);
- cp->ClockMulFactor = max(1, cp->ClockMulFactor);
- }
-
- if (scrp->progClock) {
- /* Check clock is in range */
- for (cp = scrp->clockRanges; cp != NULL; cp = cp->next) {
- if (modeInClockRange(cp, mode))
- break;
- }
- if (cp == NULL) {
- return MODE_CLOCK_RANGE;
- }
- /*
- * If programmable clock the required mode has been found
- */
- DivFactor = cp->ClockDivFactor;
- MulFactor = cp->ClockMulFactor;
- ModePrivFlags = cp->PrivFlags;
- } else {
- status = MODE_CLOCK_RANGE;
- /* Check clock is in range */
- for (cp = scrp->clockRanges; cp != NULL; cp = cp->next) {
- if (modeInClockRange(cp, mode)) {
- /*
- * Clock is in range, so if it is not a programmable clock,
- * find a matching clock.
- */
-
- i = xf86GetNearestClock(scrp, mode->Clock, 0,
- cp->ClockDivFactor, cp->ClockMulFactor, &k);
- /*
- * If the clock is too far from the requested clock, this
- * mode is no good.
- */
- if (k & V_CLKDIV2)
- gap = abs((mode->Clock * 2) -
- ((scrp->clock[i] * cp->ClockDivFactor) /
- cp->ClockMulFactor));
- else
- gap = abs(mode->Clock -
- ((scrp->clock[i] * cp->ClockDivFactor) /
- cp->ClockMulFactor));
- if (gap > minimumGap) {
- status = MODE_NOCLOCK;
- continue;
- }
-
- DivFactor = cp->ClockDivFactor;
- MulFactor = cp->ClockMulFactor;
- ModePrivFlags = cp->PrivFlags;
- extraFlags = k;
- clockIndex = i;
- break;
- }
- }
- if (cp == NULL)
- return status;
- }
-
- /* Fill in the mode parameters */
- if (scrp->progClock) {
- mode->ClockIndex = -1;
- mode->SynthClock = (mode->Clock * MulFactor) / DivFactor;
- } else {
- mode->Clock = (scrp->clock[clockIndex] * DivFactor) / MulFactor;
- mode->ClockIndex = clockIndex;
- mode->SynthClock = scrp->clock[clockIndex];
- if (extraFlags & V_CLKDIV2) {
- mode->Clock /= 2;
- mode->SynthClock /= 2;
- }
- }
- mode->PrivFlags = ModePrivFlags;
-
- return MODE_OK;
-}
-
-static int
-inferVirtualSize(ScrnInfoPtr scrp, DisplayModePtr modes, int *vx, int *vy)
-{
- float aspect = 0.0;
- MonPtr mon = scrp->monitor;
- xf86MonPtr DDC;
- int x = 0, y = 0;
- DisplayModePtr mode;
-
- if (!mon) return 0;
- DDC = mon->DDC;
-
- if (DDC && DDC->ver.revision >= 4) {
- /* For 1.4, we might actually get native pixel format. How novel. */
- if (PREFERRED_TIMING_MODE(DDC->features.msc)) {
- for (mode = modes; mode; mode = mode->next) {
- if (mode->type & (M_T_DRIVER | M_T_PREFERRED)) {
- x = mode->HDisplay;
- y = mode->VDisplay;
- goto found;
- }
- }
- }
- /*
- * Even if we don't, we might get aspect ratio from extra CVT info
- * or from the monitor size fields. TODO.
- */
- }
-
- /*
- * Technically this triggers if either is zero. That wasn't legal
- * before EDID 1.4, but right now we'll get that wrong. TODO.
- */
- if (!aspect) {
- if (!mon->widthmm || !mon->heightmm)
- aspect = 4.0/3.0;
- else
- aspect = (float)mon->widthmm / (float)mon->heightmm;
- }
-
- /* find the largest M_T_DRIVER mode with that aspect ratio */
- for (mode = modes; mode; mode = mode->next) {
- float mode_aspect, metaspect;
- if (!(mode->type & (M_T_DRIVER|M_T_USERDEF)))
- continue;
- mode_aspect = (float)mode->HDisplay / (float)mode->VDisplay;
- metaspect = aspect / mode_aspect;
- /* 5% slop or so, since we only get size in centimeters */
- if (fabs(1.0 - metaspect) < 0.05) {
- if ((mode->HDisplay > x) && (mode->VDisplay > y)) {
- x = mode->HDisplay;
- y = mode->VDisplay;
- }
- }
- }
-
- if (!x || !y) {
- xf86DrvMsg(scrp->scrnIndex, X_WARNING,
- "Unable to estimate virtual size\n");
- return 0;
- }
-
-found:
- *vx = x;
- *vy = y;
-
- xf86DrvMsg(scrp->scrnIndex, X_INFO,
- "Estimated virtual size for aspect ratio %.4f is %dx%d\n",
- aspect, *vx, *vy);
-
- return 1;
-}
-
-/* Least common multiple */
-static unsigned int
-LCM(unsigned int x, unsigned int y)
-{
- unsigned int m = x, n = y, o;
-
- while ((o = m % n))
- {
- m = n;
- n = o;
- }
-
- return (x / n) * y;
-}
-
-/*
- * Given various screen attributes, determine the minimum scanline width such
- * that each scanline is server and DDX padded and any pixels with imbedded
- * bank boundaries are off-screen. This function returns -1 if such a width
- * cannot exist.
- */
-static int
-scanLineWidth(
- unsigned int xsize, /* pixels */
- unsigned int ysize, /* pixels */
- unsigned int width, /* pixels */
- unsigned long BankSize, /* char's */
- PixmapFormatRec *pBankFormat,
- unsigned int nWidthUnit /* bits */
-)
-{
- unsigned long nBitsPerBank, nBitsPerScanline, nBitsPerScanlinePadUnit;
- unsigned long minBitsPerScanline, maxBitsPerScanline;
-
- /* Sanity checks */
-
- if (!nWidthUnit || !pBankFormat)
- return -1;
-
- nBitsPerBank = BankSize * 8;
- if (nBitsPerBank % pBankFormat->scanlinePad)
- return -1;
-
- if (xsize > width)
- width = xsize;
- nBitsPerScanlinePadUnit = LCM(pBankFormat->scanlinePad, nWidthUnit);
- nBitsPerScanline =
- (((width * pBankFormat->bitsPerPixel) + nBitsPerScanlinePadUnit - 1) /
- nBitsPerScanlinePadUnit) * nBitsPerScanlinePadUnit;
- width = nBitsPerScanline / pBankFormat->bitsPerPixel;
-
- if (!xsize || !(nBitsPerBank % pBankFormat->bitsPerPixel))
- return (int)width;
-
- /*
- * Scanlines will be server-pad aligned at this point. They will also be
- * a multiple of nWidthUnit bits long. Ensure that pixels with imbedded
- * bank boundaries are off-screen.
- *
- * It seems reasonable to limit total frame buffer size to 1/16 of the
- * theoretical maximum address space size. On a machine with 32-bit
- * addresses (to 8-bit quantities) this turns out to be 256MB. Not only
- * does this provide a simple limiting condition for the loops below, but
- * it also prevents unsigned long wraparounds.
- */
- if (!ysize)
- return -1;
-
- minBitsPerScanline = xsize * pBankFormat->bitsPerPixel;
- if (minBitsPerScanline > nBitsPerBank)
- return -1;
-
- if (ysize == 1)
- return (int)width;
-
- maxBitsPerScanline =
- (((unsigned long)(-1) >> 1) - minBitsPerScanline) / (ysize - 1);
- while (nBitsPerScanline <= maxBitsPerScanline)
- {
- unsigned long BankBase, BankUnit;
-
- BankUnit = ((nBitsPerBank + nBitsPerScanline - 1) / nBitsPerBank) *
- nBitsPerBank;
- if (!(BankUnit % nBitsPerScanline))
- return (int)width;
-
- for (BankBase = BankUnit; ; BankBase += nBitsPerBank)
- {
- unsigned long x, y;
-
- y = BankBase / nBitsPerScanline;
- if (y >= ysize)
- return (int)width;
-
- x = BankBase % nBitsPerScanline;
- if (!(x % pBankFormat->bitsPerPixel))
- continue;
-
- if (x < minBitsPerScanline)
- {
- /*
- * Skip ahead certain widths by dividing the excess scanline
- * amongst the y's.
- */
- y *= nBitsPerScanlinePadUnit;
- nBitsPerScanline +=
- ((x + y - 1) / y) * nBitsPerScanlinePadUnit;
- width = nBitsPerScanline / pBankFormat->bitsPerPixel;
- break;
- }
-
- if (BankBase != BankUnit)
- continue;
-
- if (!(nBitsPerScanline % x))
- return (int)width;
-
- BankBase = ((nBitsPerScanline - minBitsPerScanline) /
- (nBitsPerScanline - x)) * BankUnit;
- }
- }
-
- return -1;
-}
-
-/*
- * xf86ValidateModes
- *
- * This function takes a set of mode names, modes and limiting conditions,
- * and selects a set of modes and parameters based on those conditions.
- *
- * This function takes the following parameters:
- * scrp ScrnInfoPtr
- * availModes the list of modes available for the monitor
- * modeNames (optional) list of mode names that the screen is requesting
- * clockRanges a list of clock ranges
- * linePitches (optional) a list of line pitches
- * minPitch (optional) minimum line pitch (in pixels)
- * maxPitch (optional) maximum line pitch (in pixels)
- * pitchInc (mandatory) pitch increment (in bits)
- * minHeight (optional) minimum virtual height (in pixels)
- * maxHeight (optional) maximum virtual height (in pixels)
- * virtualX (optional) virtual width requested (in pixels)
- * virtualY (optional) virtual height requested (in pixels)
- * apertureSize size of video aperture (in bytes)
- * strategy how to decide which mode to use from multiple modes with
- * the same name
- *
- * In addition, the following fields from the ScrnInfoRec are used:
- * clocks a list of discrete clocks
- * numClocks number of discrete clocks
- * progClock clock is programmable
- * monitor pointer to structure for monitor section
- * fbFormat format of the framebuffer
- * videoRam video memory size
- * maxHValue maximum horizontal timing value
- * maxVValue maximum vertical timing value
- * xInc horizontal timing increment (defaults to 8 pixels)
- *
- * The function fills in the following ScrnInfoRec fields:
- * modePool A subset of the modes available to the monitor which
- * are compatible with the driver.
- * modes one mode entry for each of the requested modes, with the
- * status field filled in to indicate if the mode has been
- * accepted or not.
- * virtualX the resulting virtual width
- * virtualY the resulting virtual height
- * displayWidth the resulting line pitch
- *
- * The function's return value is the number of matching modes found, or -1
- * if an unrecoverable error was encountered.
- */
-
-int
-xf86ValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes,
- char **modeNames, ClockRangePtr clockRanges,
- int *linePitches, int minPitch, int maxPitch, int pitchInc,
- int minHeight, int maxHeight, int virtualX, int virtualY,
- int apertureSize, LookupModeFlags strategy)
-{
- DisplayModePtr p, q, r, new, last, *endp;
- int i, numModes = 0;
- ModeStatus status;
- int linePitch = -1, virtX = 0, virtY = 0;
- int newLinePitch, newVirtX, newVirtY;
- int modeSize; /* in pixels */
- Bool validateAllDefaultModes = FALSE;
- Bool userModes = FALSE;
- int saveType;
- PixmapFormatRec *BankFormat;
- ClockRangePtr cp;
- ClockRangePtr storeClockRanges;
- int numTimings = 0;
- range hsync[MAX_HSYNC];
- range vrefresh[MAX_VREFRESH];
- Bool inferred_virtual = FALSE;
-
- DebugF("xf86ValidateModes(%p, %p, %p, %p,\n\t\t %p, %d, %d, %d, %d, %d, %d, %d, %d, 0x%x)\n",
- scrp, availModes, modeNames, clockRanges,
- linePitches, minPitch, maxPitch, pitchInc,
- minHeight, maxHeight, virtualX, virtualY,
- apertureSize, strategy
- );
-
- /* Some sanity checking */
- if (scrp == NULL || scrp->name == NULL || !scrp->monitor ||
- (!scrp->progClock && scrp->numClocks == 0)) {
- ErrorF("xf86ValidateModes: called with invalid scrnInfoRec\n");
- return -1;
- }
- if (linePitches != NULL && linePitches[0] <= 0) {
- ErrorF("xf86ValidateModes: called with invalid linePitches\n");
- return -1;
- }
- if (pitchInc <= 0) {
- ErrorF("xf86ValidateModes: called with invalid pitchInc\n");
- return -1;
- }
- if ((virtualX > 0) != (virtualY > 0)) {
- ErrorF("xf86ValidateModes: called with invalid virtual resolution\n");
- return -1;
- }
-
- /*
- * If requested by the driver, allow missing hsync and/or vrefresh ranges
- * in the monitor section.
- */
- if (strategy & LOOKUP_OPTIONAL_TOLERANCES) {
- strategy &= ~LOOKUP_OPTIONAL_TOLERANCES;
- } else {
- const char *type = "";
-
- if (scrp->monitor->nHsync <= 0) {
- if (numTimings > 0) {
- scrp->monitor->nHsync = numTimings;
- for (i = 0; i < numTimings; i++) {
- scrp->monitor->hsync[i].lo = hsync[i].lo;
- scrp->monitor->hsync[i].hi = hsync[i].hi;
- }
- } else {
- scrp->monitor->hsync[0].lo = 31.5;
- scrp->monitor->hsync[0].hi = 37.9;
- scrp->monitor->nHsync = 1;
- }
- type = "default ";
- }
- for (i = 0; i < scrp->monitor->nHsync; i++) {
- if (scrp->monitor->hsync[i].lo == scrp->monitor->hsync[i].hi)
- xf86DrvMsg(scrp->scrnIndex, X_INFO,
- "%s: Using %shsync value of %.2f kHz\n",
- scrp->monitor->id, type,
- scrp->monitor->hsync[i].lo);
- else
- xf86DrvMsg(scrp->scrnIndex, X_INFO,
- "%s: Using %shsync range of %.2f-%.2f kHz\n",
- scrp->monitor->id, type,
- scrp->monitor->hsync[i].lo,
- scrp->monitor->hsync[i].hi);
- }
-
- type = "";
- if (scrp->monitor->nVrefresh <= 0) {
- if (numTimings > 0) {
- scrp->monitor->nVrefresh = numTimings;
- for (i = 0; i < numTimings; i++) {
- scrp->monitor->vrefresh[i].lo = vrefresh[i].lo;
- scrp->monitor->vrefresh[i].hi = vrefresh[i].hi;
- }
- } else {
- scrp->monitor->vrefresh[0].lo = 50;
- scrp->monitor->vrefresh[0].hi = 70;
- scrp->monitor->nVrefresh = 1;
- }
- type = "default ";
- }
- for (i = 0; i < scrp->monitor->nVrefresh; i++) {
- if (scrp->monitor->vrefresh[i].lo == scrp->monitor->vrefresh[i].hi)
- xf86DrvMsg(scrp->scrnIndex, X_INFO,
- "%s: Using %svrefresh value of %.2f Hz\n",
- scrp->monitor->id, type,
- scrp->monitor->vrefresh[i].lo);
- else
- xf86DrvMsg(scrp->scrnIndex, X_INFO,
- "%s: Using %svrefresh range of %.2f-%.2f Hz\n",
- scrp->monitor->id, type,
- scrp->monitor->vrefresh[i].lo,
- scrp->monitor->vrefresh[i].hi);
- }
- if (scrp->monitor->maxPixClock) {
- xf86DrvMsg(scrp->scrnIndex, X_INFO,
- "%s: Using maximum pixel clock of %.2f MHz\n",
- scrp->monitor->id,
- (float)scrp->monitor->maxPixClock / 1000.0);
- }
- }
-
- /*
- * Store the clockRanges for later use by the VidMode extension.
- */
- storeClockRanges = scrp->clockRanges;
- while (storeClockRanges != NULL) {
- storeClockRanges = storeClockRanges->next;
- }
- for (cp = clockRanges; cp != NULL; cp = cp->next,
- storeClockRanges = storeClockRanges->next) {
- storeClockRanges = xnfalloc(sizeof(ClockRange));
- if (scrp->clockRanges == NULL)
- scrp->clockRanges = storeClockRanges;
- memcpy(storeClockRanges, cp, sizeof(ClockRange));
- }
-
- /* Determine which pixmap format to pass to scanLineWidth() */
- if (scrp->depth > 4)
- BankFormat = &scrp->fbFormat;
- else
- BankFormat = xf86GetPixFormat(scrp, 1); /* >not< scrp->depth! */
-
- if (scrp->xInc <= 0)
- scrp->xInc = 8; /* Suitable for VGA and others */
-
-#define _VIRTUALX(x) ((((x) + scrp->xInc - 1) / scrp->xInc) * scrp->xInc)
-
- /*
- * Determine maxPitch if it wasn't given explicitly. Note linePitches
- * always takes precedence if is non-NULL. In that case the minPitch and
- * maxPitch values passed are ignored.
- */
- if (linePitches) {
- minPitch = maxPitch = linePitches[0];
- for (i = 1; linePitches[i] > 0; i++) {
- if (linePitches[i] > maxPitch)
- maxPitch = linePitches[i];
- if (linePitches[i] < minPitch)
- minPitch = linePitches[i];
- }
- }
-
- /* Initial check of virtual size against other constraints */
- scrp->virtualFrom = X_PROBED;
- /*
- * Initialise virtX and virtY if the values are fixed.
- */
- if (virtualY > 0) {
- if (maxHeight > 0 && virtualY > maxHeight) {
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Virtual height (%d) is too large for the hardware "
- "(max %d)\n", virtualY, maxHeight);
- return -1;
- }
-
- if (minHeight > 0 && virtualY < minHeight) {
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Virtual height (%d) is too small for the hardware "
- "(min %d)\n", virtualY, minHeight);
- return -1;
- }
-
- virtualX = _VIRTUALX(virtualX);
- if (linePitches != NULL) {
- for (i = 0; linePitches[i] != 0; i++) {
- if ((linePitches[i] >= virtualX) &&
- (linePitches[i] ==
- scanLineWidth(virtualX, virtualY, linePitches[i],
- apertureSize, BankFormat, pitchInc))) {
- linePitch = linePitches[i];
- break;
- }
- }
- } else {
- linePitch = scanLineWidth(virtualX, virtualY, minPitch,
- apertureSize, BankFormat, pitchInc);
- }
-
- if ((linePitch < minPitch) || (linePitch > maxPitch)) {
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Virtual width (%d) is too large for the hardware "
- "(max %d)\n", virtualX, maxPitch);
- return -1;
- }
-
- if (!xf86CheckModeSize(scrp, linePitch, virtualX, virtualY)) {
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Virtual size (%dx%d) (pitch %d) exceeds video memory\n",
- virtualX, virtualY, linePitch);
- return -1;
- }
-
- virtX = virtualX;
- virtY = virtualY;
- scrp->virtualFrom = X_CONFIG;
- } else if (!modeNames || !*modeNames) {
- /* No virtual size given in the config, try to infer */
- /* XXX this doesn't take m{in,ax}Pitch into account; oh well */
- inferred_virtual = inferVirtualSize(scrp, availModes, &virtX, &virtY);
- if (inferred_virtual)
- linePitch = scanLineWidth(virtX, virtY, minPitch, apertureSize,
- BankFormat, pitchInc);
- }
-
- /* Print clock ranges and scaled clocks */
- xf86ShowClockRanges(scrp, clockRanges);
-
- /*
- * If scrp->modePool hasn't been setup yet, set it up now. This allows the
- * modes that the driver definitely can't use to be weeded out early. Note
- * that a modePool mode's prev field is used to hold a pointer to the
- * member of the scrp->modes list for which a match was considered.
- */
- if (scrp->modePool == NULL) {
- q = NULL;
- for (p = availModes; p != NULL; p = p->next) {
- status = xf86InitialCheckModeForDriver(scrp, p, clockRanges,
- strategy, maxPitch,
- virtX, virtY);
-
- if (status == MODE_OK) {
- status = xf86CheckModeForMonitor(p, scrp->monitor);
- }
-
- if (status == MODE_OK) {
- new = xnfalloc(sizeof(DisplayModeRec));
- *new = *p;
- new->next = NULL;
- if (!q) {
- scrp->modePool = new;
- } else {
- q->next = new;
- }
- new->prev = NULL;
- q = new;
- q->name = xnfstrdup(p->name);
- q->status = MODE_OK;
- } else {
- printModeRejectMessage(scrp->scrnIndex, p, status);
- }
- }
-
- if (scrp->modePool == NULL) {
- xf86DrvMsg(scrp->scrnIndex, X_WARNING, "Mode pool is empty\n");
- return 0;
- }
- } else {
- for (p = scrp->modePool; p != NULL; p = p->next) {
- p->prev = NULL;
- p->status = MODE_OK;
- }
- }
-
- /*
- * Allocate one entry in scrp->modes for each named mode.
- */
- while (scrp->modes)
- xf86DeleteMode(&scrp->modes, scrp->modes);
- endp = &scrp->modes;
- last = NULL;
- if (modeNames != NULL) {
- for (i = 0; modeNames[i] != NULL; i++) {
- userModes = TRUE;
- new = xnfcalloc(1, sizeof(DisplayModeRec));
- new->prev = last;
- new->type = M_T_USERDEF;
- new->name = xnfalloc(strlen(modeNames[i]) + 1);
- strcpy(new->name, modeNames[i]);
- if (new->prev)
- new->prev->next = new;
- *endp = last = new;
- endp = &new->next;
- }
- }
-
- /* Lookup each mode */
-#ifdef RANDR
- if (!xf86Info.disableRandR
-#ifdef PANORAMIX
- && noPanoramiXExtension
-#endif
- )
- validateAllDefaultModes = TRUE;
-#endif
-
- for (p = scrp->modes; ; p = p->next) {
- Bool repeat;
-
- /*
- * If the supplied mode names don't produce a valid mode, scan through
- * unconsidered modePool members until one survives validation. This
- * is done in decreasing order by mode pixel area.
- */
-
- if (p == NULL) {
- if ((numModes > 0) && !validateAllDefaultModes)
- break;
-
- validateAllDefaultModes = TRUE;
- r = NULL;
- modeSize = 0;
- for (q = scrp->modePool; q != NULL; q = q->next) {
- if ((q->prev == NULL) && (q->status == MODE_OK)) {
- /*
- * Deal with the case where this mode wasn't considered
- * because of a builtin mode of the same name.
- */
- for (p = scrp->modes; p != NULL; p = p->next) {
- if ((p->status != MODE_OK) &&
- !strcmp(p->name, q->name))
- break;
- }
-
- if (p != NULL)
- q->prev = p;
- else {
- /*
- * A quick check to not allow default modes with
- * horizontal timing parameters that CRTs may have
- * problems with.
- */
- if (!scrp->monitor->reducedblanking &&
- (q->type & M_T_DEFAULT) &&
- ((double)q->HTotal / (double)q->HDisplay) < 1.15)
- continue;
-
- if (modeSize < (q->HDisplay * q->VDisplay)) {
- r = q;
- modeSize = q->HDisplay * q->VDisplay;
- }
- }
- }
- }
-
- if (r == NULL)
- break;
-
- p = xnfcalloc(1, sizeof(DisplayModeRec));
- p->prev = last;
- p->name = xnfalloc(strlen(r->name) + 1);
- if (!userModes)
- p->type = M_T_USERDEF;
- strcpy(p->name, r->name);
- if (p->prev)
- p->prev->next = p;
- *endp = last = p;
- endp = &p->next;
- }
-
- repeat = FALSE;
- lookupNext:
- if (repeat && ((status = p->status) != MODE_OK))
- printModeRejectMessage(scrp->scrnIndex, p, status);
- saveType = p->type;
- status = xf86LookupMode(scrp, p, clockRanges, strategy);
- if (repeat && status == MODE_NOMODE)
- continue;
- if (status != MODE_OK)
- printModeRejectMessage(scrp->scrnIndex, p, status);
- if (status == MODE_ERROR) {
- ErrorF("xf86ValidateModes: "
- "unexpected result from xf86LookupMode()\n");
- return -1;
- }
- if (status != MODE_OK) {
- if (p->status == MODE_OK)
- p->status = status;
- continue;
- }
- p->type |= saveType;
- repeat = TRUE;
-
- newLinePitch = linePitch;
- newVirtX = virtX;
- newVirtY = virtY;
-
- /*
- * Don't let non-user defined modes increase the virtual size
- */
- if (!(p->type & M_T_USERDEF) && (numModes > 0)) {
- if (p->HDisplay > virtX) {
- p->status = MODE_VIRTUAL_X;
- goto lookupNext;
- }
- if (p->VDisplay > virtY) {
- p->status = MODE_VIRTUAL_Y;
- goto lookupNext;
- }
- }
- /*
- * Adjust virtual width and height if the mode is too large for the
- * current values and if they are not fixed.
- */
- if (virtualX <= 0 && p->HDisplay > newVirtX)
- newVirtX = _VIRTUALX(p->HDisplay);
- if (virtualY <= 0 && p->VDisplay > newVirtY) {
- if (maxHeight > 0 && p->VDisplay > maxHeight) {
- p->status = MODE_VIRTUAL_Y; /* ? */
- goto lookupNext;
- }
- newVirtY = p->VDisplay;
- }
-
- /*
- * If virtual resolution is to be increased, revalidate it.
- */
- if ((virtX != newVirtX) || (virtY != newVirtY)) {
- if (linePitches != NULL) {
- newLinePitch = -1;
- for (i = 0; linePitches[i] != 0; i++) {
- if ((linePitches[i] >= newVirtX) &&
- (linePitches[i] >= linePitch) &&
- (linePitches[i] ==
- scanLineWidth(newVirtX, newVirtY, linePitches[i],
- apertureSize, BankFormat, pitchInc))) {
- newLinePitch = linePitches[i];
- break;
- }
- }
- } else {
- if (linePitch < minPitch)
- linePitch = minPitch;
- newLinePitch = scanLineWidth(newVirtX, newVirtY, linePitch,
- apertureSize, BankFormat,
- pitchInc);
- }
- if ((newLinePitch < minPitch) || (newLinePitch > maxPitch)) {
- p->status = MODE_BAD_WIDTH;
- goto lookupNext;
- }
-
- /*
- * Check that the pixel area required by the new virtual height
- * and line pitch isn't too large.
- */
- if (!xf86CheckModeSize(scrp, newLinePitch, newVirtX, newVirtY)) {
- p->status = MODE_MEM_VIRT;
- goto lookupNext;
- }
- }
-
- if (scrp->ValidMode) {
- /*
- * Give the driver a final say, passing it the proposed virtual
- * geometry.
- */
- scrp->virtualX = newVirtX;
- scrp->virtualY = newVirtY;
- scrp->displayWidth = newLinePitch;
- p->status = (scrp->ValidMode)(scrp->scrnIndex, p, FALSE,
- MODECHECK_FINAL);
-
- if (p->status != MODE_OK) {
- goto lookupNext;
- }
- }
-
- /* Mode has passed all the tests */
- virtX = newVirtX;
- virtY = newVirtY;
- linePitch = newLinePitch;
- p->status = MODE_OK;
- numModes++;
- }
-
-#undef _VIRTUALX
-
- /*
- * If we estimated the virtual size above, we may have filtered away all
- * the modes that maximally match that size; scan again to find out and
- * fix up if so.
- */
- if (inferred_virtual) {
- int vx = 0, vy = 0;
- for (p = scrp->modes; p; p = p->next) {
- if (p->HDisplay > vx && p->VDisplay > vy) {
- vx = p->HDisplay;
- vy = p->VDisplay;
- }
- }
- if (vx < virtX || vy < virtY) {
- xf86DrvMsg(scrp->scrnIndex, X_WARNING,
- "Shrinking virtual size estimate from %dx%d to %dx%d\n",
- virtX, virtY, vx, vy);
- virtX = vx;
- virtY = vy;
- linePitch = scanLineWidth(vx, vy, minPitch, apertureSize,
- BankFormat, pitchInc);
- }
- }
-
- /* Update the ScrnInfoRec parameters */
-
- scrp->virtualX = virtX;
- scrp->virtualY = virtY;
- scrp->displayWidth = linePitch;
-
- if (numModes <= 0)
- return 0;
-
- /* Make the mode list into a circular list by joining up the ends */
- p = scrp->modes;
- while (p->next != NULL)
- p = p->next;
- /* p is now the last mode on the list */
- p->next = scrp->modes;
- scrp->modes->prev = p;
-
- if (minHeight > 0 && virtY < minHeight) {
- xf86DrvMsg(scrp->scrnIndex, X_ERROR,
- "Virtual height (%d) is too small for the hardware "
- "(min %d)\n", virtY, minHeight);
- return -1;
- }
-
- return numModes;
-}
-
-/*
- * xf86DeleteMode
- *
- * This function removes a mode from a list of modes.
- *
- * There are different types of mode lists:
- *
- * - singly linked linear lists, ending in NULL
- * - doubly linked linear lists, starting and ending in NULL
- * - doubly linked circular lists
- *
- */
-
-void
-xf86DeleteMode(DisplayModePtr *modeList, DisplayModePtr mode)
-{
- /* Catch the easy/insane cases */
- if (modeList == NULL || *modeList == NULL || mode == NULL)
- return;
-
- /* If the mode is at the start of the list, move the start of the list */
- if (*modeList == mode)
- *modeList = mode->next;
-
- /* If mode is the only one on the list, set the list to NULL */
- if ((mode == mode->prev) && (mode == mode->next)) {
- *modeList = NULL;
- } else {
- if ((mode->prev != NULL) && (mode->prev->next == mode))
- mode->prev->next = mode->next;
- if ((mode->next != NULL) && (mode->next->prev == mode))
- mode->next->prev = mode->prev;
- }
-
- xfree(mode->name);
- xfree(mode);
-}
-
-/*
- * xf86PruneDriverModes
- *
- * Remove modes from the driver's mode list which have been marked as
- * invalid.
- */
-
-void
-xf86PruneDriverModes(ScrnInfoPtr scrp)
-{
- DisplayModePtr first, p, n;
-
- p = scrp->modes;
- if (p == NULL)
- return;
-
- do {
- if (!(first = scrp->modes))
- return;
- n = p->next;
- if (p->status != MODE_OK) {
- xf86DeleteMode(&(scrp->modes), p);
- }
- p = n;
- } while (p != NULL && p != first);
-
- /* modePool is no longer needed, turf it */
- while (scrp->modePool) {
- /*
- * A modePool mode's prev field is used to hold a pointer to the
- * member of the scrp->modes list for which a match was considered.
- * Clear that pointer first, otherwise xf86DeleteMode might get
- * confused
- */
- scrp->modePool->prev = NULL;
- xf86DeleteMode(&scrp->modePool, scrp->modePool);
- }
-}
-
-
-/*
- * xf86SetCrtcForModes
- *
- * Goes through the screen's mode list, and initialises the Crtc
- * parameters for each mode. The initialisation includes adjustments
- * for interlaced and double scan modes.
- */
-void
-xf86SetCrtcForModes(ScrnInfoPtr scrp, int adjustFlags)
-{
- DisplayModePtr p;
-
- /*
- * Store adjustFlags for use with the VidMode extension. There is an
- * implicit assumption here that SetCrtcForModes is called once.
- */
- scrp->adjustFlags = adjustFlags;
-
- p = scrp->modes;
- if (p == NULL)
- return;
-
- do {
- xf86SetModeCrtc(p, adjustFlags);
- DebugF("%sMode %s: %d (%d) %d %d (%d) %d %d (%d) %d %d (%d) %d\n",
- (p->type & M_T_DEFAULT) ? "Default " : "",
- p->name, p->CrtcHDisplay, p->CrtcHBlankStart,
- p->CrtcHSyncStart, p->CrtcHSyncEnd, p->CrtcHBlankEnd,
- p->CrtcHTotal, p->CrtcVDisplay, p->CrtcVBlankStart,
- p->CrtcVSyncStart, p->CrtcVSyncEnd, p->CrtcVBlankEnd,
- p->CrtcVTotal);
- p = p->next;
- } while (p != NULL && p != scrp->modes);
-}
-
-void
-xf86PrintModes(ScrnInfoPtr scrp)
-{
- DisplayModePtr p;
- float hsync, refresh = 0;
- char *desc, *desc2, *prefix, *uprefix;
-
- if (scrp == NULL)
- return;
-
- xf86DrvMsg(scrp->scrnIndex, scrp->virtualFrom, "Virtual size is %dx%d "
- "(pitch %d)\n", scrp->virtualX, scrp->virtualY,
- scrp->displayWidth);
-
- p = scrp->modes;
- if (p == NULL)
- return;
-
- do {
- desc = desc2 = "";
- hsync = xf86ModeHSync(p);
- refresh = xf86ModeVRefresh(p);
- if (p->Flags & V_INTERLACE) {
- desc = " (I)";
- }
- if (p->Flags & V_DBLSCAN) {
- desc = " (D)";
- }
- if (p->VScan > 1) {
- desc2 = " (VScan)";
- }
- if (p->type & M_T_BUILTIN)
- prefix = "Built-in mode";
- else if (p->type & M_T_DEFAULT)
- prefix = "Default mode";
- else if (p->type & M_T_DRIVER)
- prefix = "Driver mode";
- else
- prefix = "Mode";
- if (p->type & M_T_USERDEF)
- uprefix = "*";
- else
- uprefix = " ";
- if (hsync == 0 || refresh == 0) {
- if (p->name)
- xf86DrvMsg(scrp->scrnIndex, X_CONFIG,
- "%s%s \"%s\"\n", uprefix, prefix, p->name);
- else
- xf86DrvMsg(scrp->scrnIndex, X_PROBED,
- "%s%s %dx%d (unnamed)\n",
- uprefix, prefix, p->HDisplay, p->VDisplay);
- } else if (p->Clock == p->SynthClock) {
- xf86DrvMsg(scrp->scrnIndex, X_CONFIG,
- "%s%s \"%s\": %.1f MHz, %.1f kHz, %.1f Hz%s%s\n",
- uprefix, prefix, p->name, p->Clock / 1000.0,
- hsync, refresh, desc, desc2);
- } else {
- xf86DrvMsg(scrp->scrnIndex, X_CONFIG,
- "%s%s \"%s\": %.1f MHz (scaled from %.1f MHz), "
- "%.1f kHz, %.1f Hz%s%s\n",
- uprefix, prefix, p->name, p->Clock / 1000.0,
- p->SynthClock / 1000.0, hsync, refresh, desc, desc2);
- }
- if (hsync != 0 && refresh != 0)
- xf86PrintModeline(scrp->scrnIndex,p);
- p = p->next;
- } while (p != NULL && p != scrp->modes);
-}
+/*
+ * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ * LCM() and scanLineWidth() are:
+ *
+ * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of Marc Aurele La France not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Marc Aurele La France makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as-is" without express or implied warranty.
+ *
+ * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Copyright 1990,91,92,93 by Thomas Roell, Germany.
+ * Copyright 1991,92,93 by SGCS (Snitily Graphics Consulting Services), USA.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation, and that the name of Thomas Roell nor
+ * SGCS be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ * Thomas Roell nor SGCS makes no representations about the suitability
+ * of this software for any purpose. It is provided "as is" without
+ * express or implied warranty.
+ *
+ * THOMAS ROELL AND SGCS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THOMAS ROELL OR SGCS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Authors: Dirk Hohndel <hohndel@XFree86.Org>
+ * David Dawes <dawes@XFree86.Org>
+ * Marc La France <tsi@XFree86.Org>
+ * ... and others
+ *
+ * This file includes helper functions for mode related things.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <X11/X.h>
+#include "xf86Modes.h"
+#include "os.h"
+#include "servermd.h"
+#include "globals.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "edid.h"
+
+static void
+printModeRejectMessage(int index, DisplayModePtr p, int status)
+{
+ char *type;
+
+ if (p->type & M_T_BUILTIN)
+ type = "built-in ";
+ else if (p->type & M_T_DEFAULT)
+ type = "default ";
+ else if (p->type & M_T_DRIVER)
+ type = "driver ";
+ else
+ type = "";
+
+ xf86DrvMsg(index, X_INFO, "Not using %smode \"%s\" (%s)\n", type, p->name,
+ xf86ModeStatusToString(status));
+}
+
+/*
+ * xf86GetNearestClock --
+ * Find closest clock to given frequency (in kHz). This assumes the
+ * number of clocks is greater than zero.
+ */
+int
+xf86GetNearestClock(ScrnInfoPtr scrp, int freq, Bool allowDiv2,
+ int DivFactor, int MulFactor, int *divider)
+{
+ int nearestClock = 0, nearestDiv = 1;
+ int minimumGap = abs(freq - scrp->clock[0]);
+ int i, j, k, gap;
+
+ if (allowDiv2)
+ k = 2;
+ else
+ k = 1;
+
+ /* Must set this here in case the best match is scrp->clock[0] */
+ if (divider != NULL)
+ *divider = 0;
+
+ for (i = 0; i < scrp->numClocks; i++) {
+ for (j = 1; j <= k; j++) {
+ gap = abs((freq * j) - ((scrp->clock[i] * DivFactor) / MulFactor));
+ if ((gap < minimumGap) ||
+ ((gap == minimumGap) && (j < nearestDiv))) {
+ minimumGap = gap;
+ nearestClock = i;
+ nearestDiv = j;
+ if (divider != NULL)
+ *divider = (j - 1) * V_CLKDIV2;
+ }
+ }
+ }
+ return nearestClock;
+}
+
+/*
+ * xf86ModeStatusToString
+ *
+ * Convert a ModeStatus value to a printable message
+ */
+
+const char *
+xf86ModeStatusToString(ModeStatus status)
+{
+ switch (status) {
+ case MODE_OK:
+ return "Mode OK";
+ case MODE_HSYNC:
+ return "hsync out of range";
+ case MODE_VSYNC:
+ return "vrefresh out of range";
+ case MODE_H_ILLEGAL:
+ return "illegal horizontal timings";
+ case MODE_V_ILLEGAL:
+ return "illegal vertical timings";
+ case MODE_BAD_WIDTH:
+ return "width requires unsupported line pitch";
+ case MODE_NOMODE:
+ return "no mode of this name";
+ case MODE_NO_INTERLACE:
+ return "interlace mode not supported";
+ case MODE_NO_DBLESCAN:
+ return "doublescan mode not supported";
+ case MODE_NO_VSCAN:
+ return "multiscan mode not supported";
+ case MODE_MEM:
+ return "insufficient memory for mode";
+ case MODE_VIRTUAL_X:
+ return "width too large for virtual size";
+ case MODE_VIRTUAL_Y:
+ return "height too large for virtual size";
+ case MODE_MEM_VIRT:
+ return "insufficient memory given virtual size";
+ case MODE_NOCLOCK:
+ return "no clock available for mode";
+ case MODE_CLOCK_HIGH:
+ return "mode clock too high";
+ case MODE_CLOCK_LOW:
+ return "mode clock too low";
+ case MODE_CLOCK_RANGE:
+ return "bad mode clock/interlace/doublescan";
+ case MODE_BAD_HVALUE:
+ return "horizontal timing out of range";
+ case MODE_BAD_VVALUE:
+ return "vertical timing out of range";
+ case MODE_BAD_VSCAN:
+ return "VScan value out of range";
+ case MODE_HSYNC_NARROW:
+ return "horizontal sync too narrow";
+ case MODE_HSYNC_WIDE:
+ return "horizontal sync too wide";
+ case MODE_HBLANK_NARROW:
+ return "horizontal blanking too narrow";
+ case MODE_HBLANK_WIDE:
+ return "horizontal blanking too wide";
+ case MODE_VSYNC_NARROW:
+ return "vertical sync too narrow";
+ case MODE_VSYNC_WIDE:
+ return "vertical sync too wide";
+ case MODE_VBLANK_NARROW:
+ return "vertical blanking too narrow";
+ case MODE_VBLANK_WIDE:
+ return "vertical blanking too wide";
+ case MODE_PANEL:
+ return "exceeds panel dimensions";
+ case MODE_INTERLACE_WIDTH:
+ return "width too large for interlaced mode";
+ case MODE_ONE_WIDTH:
+ return "all modes must have the same width";
+ case MODE_ONE_HEIGHT:
+ return "all modes must have the same height";
+ case MODE_ONE_SIZE:
+ return "all modes must have the same resolution";
+ case MODE_NO_REDUCED:
+ return "monitor doesn't support reduced blanking";
+ case MODE_BANDWIDTH:
+ return "mode requires too much memory bandwidth";
+ case MODE_BAD:
+ return "unknown reason";
+ case MODE_ERROR:
+ return "internal error";
+ default:
+ return "unknown";
+ }
+}
+
+/*
+ * xf86ShowClockRanges() -- Print the clock ranges allowed
+ * and the clock values scaled by ClockMulFactor and ClockDivFactor
+ */
+void
+xf86ShowClockRanges(ScrnInfoPtr scrp, ClockRangePtr clockRanges)
+{
+ ClockRangePtr cp;
+ int MulFactor = 1;
+ int DivFactor = 1;
+ int i, j;
+ int scaledClock;
+
+ for (cp = clockRanges; cp != NULL; cp = cp->next) {
+ DivFactor = max(1, cp->ClockDivFactor);
+ MulFactor = max(1, cp->ClockMulFactor);
+ if (scrp->progClock) {
+ if (cp->minClock) {
+ if (cp->maxClock) {
+ xf86DrvMsg(scrp->scrnIndex, X_INFO,
+ "Clock range: %6.2f to %6.2f MHz\n",
+ (double)cp->minClock / 1000.0,
+ (double)cp->maxClock / 1000.0);
+ } else {
+ xf86DrvMsg(scrp->scrnIndex, X_INFO,
+ "Minimum clock: %6.2f MHz\n",
+ (double)cp->minClock / 1000.0);
+ }
+ } else {
+ if (cp->maxClock) {
+ xf86DrvMsg(scrp->scrnIndex, X_INFO,
+ "Maximum clock: %6.2f MHz\n",
+ (double)cp->maxClock / 1000.0);
+ }
+ }
+ } else if (DivFactor > 1 || MulFactor > 1) {
+ j = 0;
+ for (i = 0; i < scrp->numClocks; i++) {
+ scaledClock = (scrp->clock[i] * DivFactor) / MulFactor;
+ if (scaledClock >= cp->minClock && scaledClock <= cp->maxClock) {
+ if ((j % 8) == 0) {
+ if (j > 0)
+ xf86ErrorF("\n");
+ xf86DrvMsg(scrp->scrnIndex, X_INFO, "scaled clocks:");
+ }
+ xf86ErrorF(" %6.2f", (double)scaledClock / 1000.0);
+ j++;
+ }
+ }
+ xf86ErrorF("\n");
+ }
+ }
+}
+
+static Bool
+modeInClockRange(ClockRangePtr cp, DisplayModePtr p)
+{
+ return ((p->Clock >= cp->minClock) &&
+ (p->Clock <= cp->maxClock) &&
+ (cp->interlaceAllowed || !(p->Flags & V_INTERLACE)) &&
+ (cp->doubleScanAllowed ||
+ ((p->VScan <= 1) && !(p->Flags & V_DBLSCAN))));
+}
+
+/*
+ * xf86FindClockRangeForMode() [... like the name says ...]
+ */
+static ClockRangePtr
+xf86FindClockRangeForMode(ClockRangePtr clockRanges, DisplayModePtr p)
+{
+ ClockRangePtr cp;
+
+ for (cp = clockRanges; ; cp = cp->next)
+ if (!cp || modeInClockRange(cp, p))
+ return cp;
+}
+
+
+/*
+ * xf86HandleBuiltinMode() - handles built-in modes
+ */
+static ModeStatus
+xf86HandleBuiltinMode(ScrnInfoPtr scrp,
+ DisplayModePtr p,
+ DisplayModePtr modep,
+ ClockRangePtr clockRanges,
+ Bool allowDiv2)
+{
+ ClockRangePtr cp;
+ int extraFlags = 0;
+ int MulFactor = 1;
+ int DivFactor = 1;
+ int clockIndex;
+
+ /* Reject previously rejected modes */
+ if (p->status != MODE_OK)
+ return p->status;
+
+ /* Reject previously considered modes */
+ if (p->prev)
+ return MODE_NOMODE;
+
+ if ((p->type & M_T_CLOCK_C) == M_T_CLOCK_C) {
+ /* Check clock is in range */
+ cp = xf86FindClockRangeForMode(clockRanges, p);
+ if (cp == NULL){
+ modep->type = p->type;
+ p->status = MODE_CLOCK_RANGE;
+ return MODE_CLOCK_RANGE;
+ }
+ DivFactor = cp->ClockDivFactor;
+ MulFactor = cp->ClockMulFactor;
+ if (!scrp->progClock) {
+ clockIndex = xf86GetNearestClock(scrp, p->Clock, allowDiv2,
+ cp->ClockDivFactor,
+ cp->ClockMulFactor, &extraFlags);
+ modep->Clock = (scrp->clock[clockIndex] * DivFactor)
+ / MulFactor;
+ modep->ClockIndex = clockIndex;
+ modep->SynthClock = scrp->clock[clockIndex];
+ if (extraFlags & V_CLKDIV2) {
+ modep->Clock /= 2;
+ modep->SynthClock /= 2;
+ }
+ } else {
+ modep->Clock = p->Clock;
+ modep->ClockIndex = -1;
+ modep->SynthClock = (modep->Clock * MulFactor)
+ / DivFactor;
+ }
+ modep->PrivFlags = cp->PrivFlags;
+ } else {
+ if(!scrp->progClock) {
+ modep->Clock = p->Clock;
+ modep->ClockIndex = p->ClockIndex;
+ modep->SynthClock = p->SynthClock;
+ } else {
+ modep->Clock = p->Clock;
+ modep->ClockIndex = -1;
+ modep->SynthClock = p->SynthClock;
+ }
+ modep->PrivFlags = p->PrivFlags;
+ }
+ modep->type = p->type;
+ modep->HDisplay = p->HDisplay;
+ modep->HSyncStart = p->HSyncStart;
+ modep->HSyncEnd = p->HSyncEnd;
+ modep->HTotal = p->HTotal;
+ modep->HSkew = p->HSkew;
+ modep->VDisplay = p->VDisplay;
+ modep->VSyncStart = p->VSyncStart;
+ modep->VSyncEnd = p->VSyncEnd;
+ modep->VTotal = p->VTotal;
+ modep->VScan = p->VScan;
+ modep->Flags = p->Flags | extraFlags;
+ modep->CrtcHDisplay = p->CrtcHDisplay;
+ modep->CrtcHBlankStart = p->CrtcHBlankStart;
+ modep->CrtcHSyncStart = p->CrtcHSyncStart;
+ modep->CrtcHSyncEnd = p->CrtcHSyncEnd;
+ modep->CrtcHBlankEnd = p->CrtcHBlankEnd;
+ modep->CrtcHTotal = p->CrtcHTotal;
+ modep->CrtcHSkew = p->CrtcHSkew;
+ modep->CrtcVDisplay = p->CrtcVDisplay;
+ modep->CrtcVBlankStart = p->CrtcVBlankStart;
+ modep->CrtcVSyncStart = p->CrtcVSyncStart;
+ modep->CrtcVSyncEnd = p->CrtcVSyncEnd;
+ modep->CrtcVBlankEnd = p->CrtcVBlankEnd;
+ modep->CrtcVTotal = p->CrtcVTotal;
+ modep->CrtcHAdjusted = p->CrtcHAdjusted;
+ modep->CrtcVAdjusted = p->CrtcVAdjusted;
+ modep->HSync = p->HSync;
+ modep->VRefresh = p->VRefresh;
+ modep->Private = p->Private;
+ modep->PrivSize = p->PrivSize;
+
+ p->prev = modep;
+
+ return MODE_OK;
+}
+
+/*
+ * xf86LookupMode
+ *
+ * This function returns a mode from the given list which matches the
+ * given name. When multiple modes with the same name are available,
+ * the method of picking the matching mode is determined by the
+ * strategy selected.
+ *
+ * This function takes the following parameters:
+ * scrp ScrnInfoPtr
+ * modep pointer to the returned mode, which must have the name
+ * field filled in.
+ * clockRanges a list of clock ranges. This is optional when all the
+ * modes are built-in modes.
+ * strategy how to decide which mode to use from multiple modes with
+ * the same name
+ *
+ * In addition, the following fields from the ScrnInfoRec are used:
+ * modePool the list of monitor modes compatible with the driver
+ * clocks a list of discrete clocks
+ * numClocks number of discrete clocks
+ * progClock clock is programmable
+ *
+ * If a mode was found, its values are filled in to the area pointed to
+ * by modep, If a mode was not found the return value indicates the
+ * reason.
+ */
+
+ModeStatus
+xf86LookupMode(ScrnInfoPtr scrp, DisplayModePtr modep,
+ ClockRangePtr clockRanges, LookupModeFlags strategy)
+{
+ DisplayModePtr p, bestMode = NULL;
+ ClockRangePtr cp;
+ int i, k, gap, minimumGap = CLOCK_TOLERANCE + 1;
+ double refresh, bestRefresh = 0.0;
+ Bool found = FALSE;
+ int extraFlags = 0;
+ int clockIndex = -1;
+ int MulFactor = 1;
+ int DivFactor = 1;
+ int ModePrivFlags = 0;
+ ModeStatus status = MODE_NOMODE;
+ Bool allowDiv2 = (strategy & LOOKUP_CLKDIV2) != 0;
+ int n;
+ const int types[] = {
+ M_T_BUILTIN | M_T_PREFERRED,
+ M_T_BUILTIN,
+ M_T_USERDEF | M_T_PREFERRED,
+ M_T_USERDEF,
+ M_T_DRIVER | M_T_PREFERRED,
+ M_T_DRIVER,
+ 0
+ };
+ const int ntypes = sizeof(types) / sizeof(int);
+
+ strategy &= ~(LOOKUP_CLKDIV2 | LOOKUP_OPTIONAL_TOLERANCES);
+
+ /* Some sanity checking */
+ if (scrp == NULL || scrp->modePool == NULL ||
+ (!scrp->progClock && scrp->numClocks == 0)) {
+ ErrorF("xf86LookupMode: called with invalid scrnInfoRec\n");
+ return MODE_ERROR;
+ }
+ if (modep == NULL || modep->name == NULL) {
+ ErrorF("xf86LookupMode: called with invalid modep\n");
+ return MODE_ERROR;
+ }
+ for (cp = clockRanges; cp != NULL; cp = cp->next) {
+ /* DivFactor and MulFactor must be > 0 */
+ cp->ClockDivFactor = max(1, cp->ClockDivFactor);
+ cp->ClockMulFactor = max(1, cp->ClockMulFactor);
+ }
+
+ /* Scan the mode pool for matching names */
+ for (n = 0; n < ntypes; n++) {
+ int type = types[n];
+ for (p = scrp->modePool; p != NULL; p = p->next) {
+
+ /* scan through the modes in the sort order above */
+ if ((p->type & type) != type)
+ continue;
+
+ if (strcmp(p->name, modep->name) == 0) {
+
+ /* Skip over previously rejected modes */
+ if (p->status != MODE_OK) {
+ if (!found)
+ status = p->status;
+ continue;
+ }
+
+ /* Skip over previously considered modes */
+ if (p->prev)
+ continue;
+
+ if (p->type & M_T_BUILTIN) {
+ return xf86HandleBuiltinMode(scrp, p,modep, clockRanges,
+ allowDiv2);
+ }
+
+ /* Check clock is in range */
+ cp = xf86FindClockRangeForMode(clockRanges, p);
+ if (cp == NULL) {
+ /*
+ * XXX Could do more here to provide a more detailed
+ * reason for not finding a mode.
+ */
+ p->status = MODE_CLOCK_RANGE;
+ if (!found)
+ status = MODE_CLOCK_RANGE;
+ continue;
+ }
+
+ /*
+ * If programmable clock and strategy is not
+ * LOOKUP_BEST_REFRESH, the required mode has been found,
+ * otherwise record the refresh and continue looking.
+ */
+ if (scrp->progClock) {
+ found = TRUE;
+ if (strategy != LOOKUP_BEST_REFRESH) {
+ bestMode = p;
+ DivFactor = cp->ClockDivFactor;
+ MulFactor = cp->ClockMulFactor;
+ ModePrivFlags = cp->PrivFlags;
+ break;
+ }
+ refresh = xf86ModeVRefresh(p);
+ if (p->Flags & V_INTERLACE)
+ refresh /= INTERLACE_REFRESH_WEIGHT;
+ if (refresh > bestRefresh) {
+ bestMode = p;
+ DivFactor = cp->ClockDivFactor;
+ MulFactor = cp->ClockMulFactor;
+ ModePrivFlags = cp->PrivFlags;
+ bestRefresh = refresh;
+ }
+ continue;
+ }
+
+ /*
+ * Clock is in range, so if it is not a programmable clock, find
+ * a matching clock.
+ */
+
+ i = xf86GetNearestClock(scrp, p->Clock, allowDiv2,
+ cp->ClockDivFactor, cp->ClockMulFactor, &k);
+ /*
+ * If the clock is too far from the requested clock, this
+ * mode is no good.
+ */
+ if (k & V_CLKDIV2)
+ gap = abs((p->Clock * 2) -
+ ((scrp->clock[i] * cp->ClockDivFactor) /
+ cp->ClockMulFactor));
+ else
+ gap = abs(p->Clock -
+ ((scrp->clock[i] * cp->ClockDivFactor) /
+ cp->ClockMulFactor));
+ if (gap > minimumGap) {
+ p->status = MODE_NOCLOCK;
+ if (!found)
+ status = MODE_NOCLOCK;
+ continue;
+ }
+ found = TRUE;
+
+ if (strategy == LOOKUP_BEST_REFRESH) {
+ refresh = xf86ModeVRefresh(p);
+ if (p->Flags & V_INTERLACE)
+ refresh /= INTERLACE_REFRESH_WEIGHT;
+ if (refresh > bestRefresh) {
+ bestMode = p;
+ DivFactor = cp->ClockDivFactor;
+ MulFactor = cp->ClockMulFactor;
+ ModePrivFlags = cp->PrivFlags;
+ extraFlags = k;
+ clockIndex = i;
+ bestRefresh = refresh;
+ }
+ continue;
+ }
+ if (strategy == LOOKUP_CLOSEST_CLOCK) {
+ if (gap < minimumGap) {
+ bestMode = p;
+ DivFactor = cp->ClockDivFactor;
+ MulFactor = cp->ClockMulFactor;
+ ModePrivFlags = cp->PrivFlags;
+ extraFlags = k;
+ clockIndex = i;
+ minimumGap = gap;
+ }
+ continue;
+ }
+ /*
+ * If strategy is neither LOOKUP_BEST_REFRESH or
+ * LOOKUP_CLOSEST_CLOCK the required mode has been found.
+ */
+ bestMode = p;
+ DivFactor = cp->ClockDivFactor;
+ MulFactor = cp->ClockMulFactor;
+ ModePrivFlags = cp->PrivFlags;
+ extraFlags = k;
+ clockIndex = i;
+ break;
+ }
+ }
+ if (found) break;
+ }
+ if (!found || bestMode == NULL)
+ return status;
+
+ /* Fill in the mode parameters */
+ if (scrp->progClock) {
+ modep->Clock = bestMode->Clock;
+ modep->ClockIndex = -1;
+ modep->SynthClock = (modep->Clock * MulFactor) / DivFactor;
+ } else {
+ modep->Clock = (scrp->clock[clockIndex] * DivFactor) /
+ MulFactor;
+ modep->ClockIndex = clockIndex;
+ modep->SynthClock = scrp->clock[clockIndex];
+ if (extraFlags & V_CLKDIV2) {
+ modep->Clock /= 2;
+ modep->SynthClock /= 2;
+ }
+ }
+ modep->type = bestMode->type;
+ modep->PrivFlags = ModePrivFlags;
+ modep->HDisplay = bestMode->HDisplay;
+ modep->HSyncStart = bestMode->HSyncStart;
+ modep->HSyncEnd = bestMode->HSyncEnd;
+ modep->HTotal = bestMode->HTotal;
+ modep->HSkew = bestMode->HSkew;
+ modep->VDisplay = bestMode->VDisplay;
+ modep->VSyncStart = bestMode->VSyncStart;
+ modep->VSyncEnd = bestMode->VSyncEnd;
+ modep->VTotal = bestMode->VTotal;
+ modep->VScan = bestMode->VScan;
+ modep->Flags = bestMode->Flags | extraFlags;
+ modep->CrtcHDisplay = bestMode->CrtcHDisplay;
+ modep->CrtcHBlankStart = bestMode->CrtcHBlankStart;
+ modep->CrtcHSyncStart = bestMode->CrtcHSyncStart;
+ modep->CrtcHSyncEnd = bestMode->CrtcHSyncEnd;
+ modep->CrtcHBlankEnd = bestMode->CrtcHBlankEnd;
+ modep->CrtcHTotal = bestMode->CrtcHTotal;
+ modep->CrtcHSkew = bestMode->CrtcHSkew;
+ modep->CrtcVDisplay = bestMode->CrtcVDisplay;
+ modep->CrtcVBlankStart = bestMode->CrtcVBlankStart;
+ modep->CrtcVSyncStart = bestMode->CrtcVSyncStart;
+ modep->CrtcVSyncEnd = bestMode->CrtcVSyncEnd;
+ modep->CrtcVBlankEnd = bestMode->CrtcVBlankEnd;
+ modep->CrtcVTotal = bestMode->CrtcVTotal;
+ modep->CrtcHAdjusted = bestMode->CrtcHAdjusted;
+ modep->CrtcVAdjusted = bestMode->CrtcVAdjusted;
+ modep->HSync = bestMode->HSync;
+ modep->VRefresh = bestMode->VRefresh;
+ modep->Private = bestMode->Private;
+ modep->PrivSize = bestMode->PrivSize;
+
+ bestMode->prev = modep;
+
+ return MODE_OK;
+}
+
+/*
+ * xf86CheckModeForMonitor
+ *
+ * This function takes a mode and monitor description, and determines
+ * if the mode is valid for the monitor.
+ */
+ModeStatus
+xf86CheckModeForMonitor(DisplayModePtr mode, MonPtr monitor)
+{
+ int i;
+
+ /* Sanity checks */
+ if (mode == NULL || monitor == NULL) {
+ ErrorF("xf86CheckModeForMonitor: called with invalid parameters\n");
+ return MODE_ERROR;
+ }
+
+ DebugF("xf86CheckModeForMonitor(%p %s, %p %s)\n",
+ mode, mode->name, monitor, monitor->id);
+
+ /* Some basic mode validity checks */
+ if (0 >= mode->HDisplay || mode->HDisplay > mode->HSyncStart ||
+ mode->HSyncStart >= mode->HSyncEnd || mode->HSyncEnd >= mode->HTotal)
+ return MODE_H_ILLEGAL;
+
+ if (0 >= mode->VDisplay || mode->VDisplay > mode->VSyncStart ||
+ mode->VSyncStart >= mode->VSyncEnd || mode->VSyncEnd >= mode->VTotal)
+ return MODE_V_ILLEGAL;
+
+ if (monitor->nHsync > 0) {
+ /* Check hsync against the allowed ranges */
+ float hsync = xf86ModeHSync(mode);
+ for (i = 0; i < monitor->nHsync; i++)
+ if ((hsync > monitor->hsync[i].lo * (1.0 - SYNC_TOLERANCE)) &&
+ (hsync < monitor->hsync[i].hi * (1.0 + SYNC_TOLERANCE)))
+ break;
+
+ /* Now see whether we ran out of sync ranges without finding a match */
+ if (i == monitor->nHsync)
+ return MODE_HSYNC;
+ }
+
+ if (monitor->nVrefresh > 0) {
+ /* Check vrefresh against the allowed ranges */
+ float vrefrsh = xf86ModeVRefresh(mode);
+ for (i = 0; i < monitor->nVrefresh; i++)
+ if ((vrefrsh > monitor->vrefresh[i].lo * (1.0 - SYNC_TOLERANCE)) &&
+ (vrefrsh < monitor->vrefresh[i].hi * (1.0 + SYNC_TOLERANCE)))
+ break;
+
+ /* Now see whether we ran out of refresh ranges without finding a match */
+ if (i == monitor->nVrefresh)
+ return MODE_VSYNC;
+ }
+
+ /* Force interlaced modes to have an odd VTotal */
+ if (mode->Flags & V_INTERLACE)
+ mode->CrtcVTotal = mode->VTotal |= 1;
+
+ /*
+ * This code stops cvt -r modes, and only cvt -r modes, from hitting 15y+
+ * old CRTs which might, when there is a lot of solar flare activity and
+ * when the celestial bodies are unfavourably aligned, implode trying to
+ * sync to it. It's called "Protecting the user from doing anything stupid".
+ * -- libv
+ */
+
+ if (xf86ModeIsReduced(mode)) {
+ if (!monitor->reducedblanking && !(mode->type & M_T_DRIVER))
+ return MODE_NO_REDUCED;
+ }
+
+ if ((monitor->maxPixClock) && (mode->Clock > monitor->maxPixClock))
+ return MODE_CLOCK_HIGH;
+
+ return MODE_OK;
+}
+
+/*
+ * xf86CheckModeSize
+ *
+ * An internal routine to check if a mode fits in video memory. This tries to
+ * avoid overflows that would otherwise occur when video memory size is greater
+ * than 256MB.
+ */
+static Bool
+xf86CheckModeSize(ScrnInfoPtr scrp, int w, int x, int y)
+{
+ int bpp = scrp->fbFormat.bitsPerPixel,
+ pad = scrp->fbFormat.scanlinePad;
+ int lineWidth, lastWidth;
+
+ if (scrp->depth == 4)
+ pad *= 4; /* 4 planes */
+
+ /* Sanity check */
+ if ((w < 0) || (x < 0) || (y <= 0))
+ return FALSE;
+
+ lineWidth = (((w * bpp) + pad - 1) / pad) * pad;
+ lastWidth = x * bpp;
+
+ /*
+ * At this point, we need to compare
+ *
+ * (lineWidth * (y - 1)) + lastWidth
+ *
+ * against
+ *
+ * scrp->videoRam * (1024 * 8)
+ *
+ * These are bit quantities. To avoid overflows, do the comparison in
+ * terms of BITMAP_SCANLINE_PAD units. This assumes BITMAP_SCANLINE_PAD
+ * is a power of 2. We currently use 32, which limits us to a video
+ * memory size of 8GB.
+ */
+
+ lineWidth = (lineWidth + (BITMAP_SCANLINE_PAD - 1)) / BITMAP_SCANLINE_PAD;
+ lastWidth = (lastWidth + (BITMAP_SCANLINE_PAD - 1)) / BITMAP_SCANLINE_PAD;
+
+ if ((lineWidth * (y - 1) + lastWidth) >
+ (scrp->videoRam * ((1024 * 8) / BITMAP_SCANLINE_PAD)))
+ return FALSE;
+
+ return TRUE;
+}
+
+/*
+ * xf86InitialCheckModeForDriver
+ *
+ * This function checks if a mode satisfies a driver's initial requirements:
+ * - mode size fits within the available pixel area (memory)
+ * - width lies within the range of supported line pitches
+ * - mode size fits within virtual size (if fixed)
+ * - horizontal timings are in range
+ *
+ * This function takes the following parameters:
+ * scrp ScrnInfoPtr
+ * mode mode to check
+ * maxPitch (optional) maximum line pitch
+ * virtualX (optional) virtual width requested
+ * virtualY (optional) virtual height requested
+ *
+ * In addition, the following fields from the ScrnInfoRec are used:
+ * monitor pointer to structure for monitor section
+ * fbFormat pixel format for the framebuffer
+ * videoRam video memory size (in kB)
+ * maxHValue maximum horizontal timing value
+ * maxVValue maximum vertical timing value
+ */
+
+ModeStatus
+xf86InitialCheckModeForDriver(ScrnInfoPtr scrp, DisplayModePtr mode,
+ ClockRangePtr clockRanges,
+ LookupModeFlags strategy,
+ int maxPitch, int virtualX, int virtualY)
+{
+ ClockRangePtr cp;
+ ModeStatus status;
+ Bool allowDiv2 = (strategy & LOOKUP_CLKDIV2) != 0;
+ int i, needDiv2;
+
+ /* Sanity checks */
+ if (!scrp || !mode || !clockRanges) {
+ ErrorF("xf86InitialCheckModeForDriver: "
+ "called with invalid parameters\n");
+ return MODE_ERROR;
+ }
+
+ DebugF("xf86InitialCheckModeForDriver(%p, %p %s, %p, 0x%x, %d, %d, %d)\n",
+ scrp, mode, mode->name , clockRanges, strategy, maxPitch, virtualX, virtualY);
+
+ /* Some basic mode validity checks */
+ if (0 >= mode->HDisplay || mode->HDisplay > mode->HSyncStart ||
+ mode->HSyncStart >= mode->HSyncEnd || mode->HSyncEnd >= mode->HTotal)
+ return MODE_H_ILLEGAL;
+
+ if (0 >= mode->VDisplay || mode->VDisplay > mode->VSyncStart ||
+ mode->VSyncStart >= mode->VSyncEnd || mode->VSyncEnd >= mode->VTotal)
+ return MODE_V_ILLEGAL;
+
+ if (!xf86CheckModeSize(scrp, mode->HDisplay, mode->HDisplay,
+ mode->VDisplay))
+ return MODE_MEM;
+
+ if (maxPitch > 0 && mode->HDisplay > maxPitch)
+ return MODE_BAD_WIDTH;
+
+ if (virtualX > 0 && mode->HDisplay > virtualX)
+ return MODE_VIRTUAL_X;
+
+ if (virtualY > 0 && mode->VDisplay > virtualY)
+ return MODE_VIRTUAL_Y;
+
+ if (scrp->maxHValue > 0 && mode->HTotal > scrp->maxHValue)
+ return MODE_BAD_HVALUE;
+
+ if (scrp->maxVValue > 0 && mode->VTotal > scrp->maxVValue)
+ return MODE_BAD_VVALUE;
+
+ /*
+ * The use of the DisplayModeRec's Crtc* and SynthClock elements below is
+ * provisional, in that they are later reused by the driver at mode-set
+ * time. Here, they are temporarily enlisted to contain the mode timings
+ * as seen by the CRT or panel (rather than the CRTC). The driver's
+ * ValidMode() is allowed to modify these so it can deal with such things
+ * as mode stretching and/or centering. The driver should >NOT< modify the
+ * user-supplied values as these are reported back when mode validation is
+ * said and done.
+ */
+ /*
+ * NOTE: We (ab)use the mode->Crtc* values here to store timing
+ * information for the calculation of Hsync and Vrefresh. Before
+ * these values are calculated the driver is given the opportunity
+ * to either set these HSync and VRefresh itself or modify the timing
+ * values.
+ * The difference to the final calculation is small but imortand:
+ * here we pass the flag INTERLACE_HALVE_V regardless if the driver
+ * sets it or not. This way our calculation of VRefresh has the same
+ * effect as if we do if (flags & V_INTERLACE) refresh *= 2.0
+ * This dual use of the mode->Crtc* values will certainly create
+ * confusion and is bad software design. However since it's part of
+ * the driver API it's hard to change.
+ */
+
+ if (scrp->ValidMode) {
+
+ xf86SetModeCrtc(mode, INTERLACE_HALVE_V);
+
+ cp = xf86FindClockRangeForMode(clockRanges, mode);
+ if (!cp)
+ return MODE_CLOCK_RANGE;
+
+ if (cp->ClockMulFactor < 1)
+ cp->ClockMulFactor = 1;
+ if (cp->ClockDivFactor < 1)
+ cp->ClockDivFactor = 1;
+
+ /*
+ * XXX The effect of clock dividers and multipliers on the monitor's
+ * pixel clock needs to be verified.
+ */
+ if (scrp->progClock) {
+ mode->SynthClock = mode->Clock;
+ } else {
+ i = xf86GetNearestClock(scrp, mode->Clock, allowDiv2,
+ cp->ClockDivFactor, cp->ClockMulFactor,
+ &needDiv2);
+ mode->SynthClock = (scrp->clock[i] * cp->ClockDivFactor) /
+ cp->ClockMulFactor;
+ if (needDiv2 & V_CLKDIV2)
+ mode->SynthClock /= 2;
+ }
+
+ status = (*scrp->ValidMode)(scrp->scrnIndex, mode, FALSE,
+ MODECHECK_INITIAL);
+ if (status != MODE_OK)
+ return status;
+
+ if (mode->HSync <= 0.0)
+ mode->HSync = (float)mode->SynthClock / (float)mode->CrtcHTotal;
+ if (mode->VRefresh <= 0.0)
+ mode->VRefresh = (mode->SynthClock * 1000.0)
+ / (mode->CrtcHTotal * mode->CrtcVTotal);
+ }
+
+ mode->HSync = xf86ModeHSync(mode);
+ mode->VRefresh = xf86ModeVRefresh(mode);
+
+ /* Assume it is OK */
+ return MODE_OK;
+}
+
+/*
+ * xf86CheckModeForDriver
+ *
+ * This function is for checking modes while the server is running (for
+ * use mainly by the VidMode extension).
+ *
+ * This function checks if a mode satisfies a driver's requirements:
+ * - width lies within the line pitch
+ * - mode size fits within virtual size
+ * - horizontal/vertical timings are in range
+ *
+ * This function takes the following parameters:
+ * scrp ScrnInfoPtr
+ * mode mode to check
+ * flags not (currently) used
+ *
+ * In addition, the following fields from the ScrnInfoRec are used:
+ * maxHValue maximum horizontal timing value
+ * maxVValue maximum vertical timing value
+ * virtualX virtual width
+ * virtualY virtual height
+ * clockRanges allowable clock ranges
+ */
+
+ModeStatus
+xf86CheckModeForDriver(ScrnInfoPtr scrp, DisplayModePtr mode, int flags)
+{
+ ClockRangePtr cp;
+ int i, k, gap, minimumGap = CLOCK_TOLERANCE + 1;
+ int extraFlags = 0;
+ int clockIndex = -1;
+ int MulFactor = 1;
+ int DivFactor = 1;
+ int ModePrivFlags = 0;
+ ModeStatus status = MODE_NOMODE;
+
+ /* Some sanity checking */
+ if (scrp == NULL || (!scrp->progClock && scrp->numClocks == 0)) {
+ ErrorF("xf86CheckModeForDriver: called with invalid scrnInfoRec\n");
+ return MODE_ERROR;
+ }
+ if (mode == NULL) {
+ ErrorF("xf86CheckModeForDriver: called with invalid modep\n");
+ return MODE_ERROR;
+ }
+
+ /* Check the mode size */
+ if (mode->HDisplay > scrp->virtualX)
+ return MODE_VIRTUAL_X;
+
+ if (mode->VDisplay > scrp->virtualY)
+ return MODE_VIRTUAL_Y;
+
+ if (scrp->maxHValue > 0 && mode->HTotal > scrp->maxHValue)
+ return MODE_BAD_HVALUE;
+
+ if (scrp->maxVValue > 0 && mode->VTotal > scrp->maxVValue)
+ return MODE_BAD_VVALUE;
+
+ for (cp = scrp->clockRanges; cp != NULL; cp = cp->next) {
+ /* DivFactor and MulFactor must be > 0 */
+ cp->ClockDivFactor = max(1, cp->ClockDivFactor);
+ cp->ClockMulFactor = max(1, cp->ClockMulFactor);
+ }
+
+ if (scrp->progClock) {
+ /* Check clock is in range */
+ for (cp = scrp->clockRanges; cp != NULL; cp = cp->next) {
+ if (modeInClockRange(cp, mode))
+ break;
+ }
+ if (cp == NULL) {
+ return MODE_CLOCK_RANGE;
+ }
+ /*
+ * If programmable clock the required mode has been found
+ */
+ DivFactor = cp->ClockDivFactor;
+ MulFactor = cp->ClockMulFactor;
+ ModePrivFlags = cp->PrivFlags;
+ } else {
+ status = MODE_CLOCK_RANGE;
+ /* Check clock is in range */
+ for (cp = scrp->clockRanges; cp != NULL; cp = cp->next) {
+ if (modeInClockRange(cp, mode)) {
+ /*
+ * Clock is in range, so if it is not a programmable clock,
+ * find a matching clock.
+ */
+
+ i = xf86GetNearestClock(scrp, mode->Clock, 0,
+ cp->ClockDivFactor, cp->ClockMulFactor, &k);
+ /*
+ * If the clock is too far from the requested clock, this
+ * mode is no good.
+ */
+ if (k & V_CLKDIV2)
+ gap = abs((mode->Clock * 2) -
+ ((scrp->clock[i] * cp->ClockDivFactor) /
+ cp->ClockMulFactor));
+ else
+ gap = abs(mode->Clock -
+ ((scrp->clock[i] * cp->ClockDivFactor) /
+ cp->ClockMulFactor));
+ if (gap > minimumGap) {
+ status = MODE_NOCLOCK;
+ continue;
+ }
+
+ DivFactor = cp->ClockDivFactor;
+ MulFactor = cp->ClockMulFactor;
+ ModePrivFlags = cp->PrivFlags;
+ extraFlags = k;
+ clockIndex = i;
+ break;
+ }
+ }
+ if (cp == NULL)
+ return status;
+ }
+
+ /* Fill in the mode parameters */
+ if (scrp->progClock) {
+ mode->ClockIndex = -1;
+ mode->SynthClock = (mode->Clock * MulFactor) / DivFactor;
+ } else {
+ mode->Clock = (scrp->clock[clockIndex] * DivFactor) / MulFactor;
+ mode->ClockIndex = clockIndex;
+ mode->SynthClock = scrp->clock[clockIndex];
+ if (extraFlags & V_CLKDIV2) {
+ mode->Clock /= 2;
+ mode->SynthClock /= 2;
+ }
+ }
+ mode->PrivFlags = ModePrivFlags;
+
+ return MODE_OK;
+}
+
+static int
+inferVirtualSize(ScrnInfoPtr scrp, DisplayModePtr modes, int *vx, int *vy)
+{
+ float aspect = 0.0;
+ MonPtr mon = scrp->monitor;
+ xf86MonPtr DDC;
+ int x = 0, y = 0;
+ DisplayModePtr mode;
+
+ if (!mon) return 0;
+ DDC = mon->DDC;
+
+ if (DDC && DDC->ver.revision >= 4) {
+ /* For 1.4, we might actually get native pixel format. How novel. */
+ if (PREFERRED_TIMING_MODE(DDC->features.msc)) {
+ for (mode = modes; mode; mode = mode->next) {
+ if (mode->type & (M_T_DRIVER | M_T_PREFERRED)) {
+ x = mode->HDisplay;
+ y = mode->VDisplay;
+ goto found;
+ }
+ }
+ }
+ /*
+ * Even if we don't, we might get aspect ratio from extra CVT info
+ * or from the monitor size fields. TODO.
+ */
+ }
+
+ /*
+ * Technically this triggers if either is zero. That wasn't legal
+ * before EDID 1.4, but right now we'll get that wrong. TODO.
+ */
+ if (!aspect) {
+ if (!mon->widthmm || !mon->heightmm)
+ aspect = 4.0/3.0;
+ else
+ aspect = (float)mon->widthmm / (float)mon->heightmm;
+ }
+
+ /* find the largest M_T_DRIVER mode with that aspect ratio */
+ for (mode = modes; mode; mode = mode->next) {
+ float mode_aspect, metaspect;
+ if (!(mode->type & (M_T_DRIVER|M_T_USERDEF)))
+ continue;
+ mode_aspect = (float)mode->HDisplay / (float)mode->VDisplay;
+ metaspect = aspect / mode_aspect;
+ /* 5% slop or so, since we only get size in centimeters */
+ if (fabs(1.0 - metaspect) < 0.05) {
+ if ((mode->HDisplay > x) && (mode->VDisplay > y)) {
+ x = mode->HDisplay;
+ y = mode->VDisplay;
+ }
+ }
+ }
+
+ if (!x || !y) {
+ xf86DrvMsg(scrp->scrnIndex, X_WARNING,
+ "Unable to estimate virtual size\n");
+ return 0;
+ }
+
+found:
+ *vx = x;
+ *vy = y;
+
+ xf86DrvMsg(scrp->scrnIndex, X_INFO,
+ "Estimated virtual size for aspect ratio %.4f is %dx%d\n",
+ aspect, *vx, *vy);
+
+ return 1;
+}
+
+/* Least common multiple */
+static unsigned int
+LCM(unsigned int x, unsigned int y)
+{
+ unsigned int m = x, n = y, o;
+
+ while ((o = m % n))
+ {
+ m = n;
+ n = o;
+ }
+
+ return (x / n) * y;
+}
+
+/*
+ * Given various screen attributes, determine the minimum scanline width such
+ * that each scanline is server and DDX padded and any pixels with imbedded
+ * bank boundaries are off-screen. This function returns -1 if such a width
+ * cannot exist.
+ */
+static int
+scanLineWidth(
+ unsigned int xsize, /* pixels */
+ unsigned int ysize, /* pixels */
+ unsigned int width, /* pixels */
+ unsigned long BankSize, /* char's */
+ PixmapFormatRec *pBankFormat,
+ unsigned int nWidthUnit /* bits */
+)
+{
+ unsigned long nBitsPerBank, nBitsPerScanline, nBitsPerScanlinePadUnit;
+ unsigned long minBitsPerScanline, maxBitsPerScanline;
+
+ /* Sanity checks */
+
+ if (!nWidthUnit || !pBankFormat)
+ return -1;
+
+ nBitsPerBank = BankSize * 8;
+ if (nBitsPerBank % pBankFormat->scanlinePad)
+ return -1;
+
+ if (xsize > width)
+ width = xsize;
+ nBitsPerScanlinePadUnit = LCM(pBankFormat->scanlinePad, nWidthUnit);
+ nBitsPerScanline =
+ (((width * pBankFormat->bitsPerPixel) + nBitsPerScanlinePadUnit - 1) /
+ nBitsPerScanlinePadUnit) * nBitsPerScanlinePadUnit;
+ width = nBitsPerScanline / pBankFormat->bitsPerPixel;
+
+ if (!xsize || !(nBitsPerBank % pBankFormat->bitsPerPixel))
+ return (int)width;
+
+ /*
+ * Scanlines will be server-pad aligned at this point. They will also be
+ * a multiple of nWidthUnit bits long. Ensure that pixels with imbedded
+ * bank boundaries are off-screen.
+ *
+ * It seems reasonable to limit total frame buffer size to 1/16 of the
+ * theoretical maximum address space size. On a machine with 32-bit
+ * addresses (to 8-bit quantities) this turns out to be 256MB. Not only
+ * does this provide a simple limiting condition for the loops below, but
+ * it also prevents unsigned long wraparounds.
+ */
+ if (!ysize)
+ return -1;
+
+ minBitsPerScanline = xsize * pBankFormat->bitsPerPixel;
+ if (minBitsPerScanline > nBitsPerBank)
+ return -1;
+
+ if (ysize == 1)
+ return (int)width;
+
+ maxBitsPerScanline =
+ (((unsigned long)(-1) >> 1) - minBitsPerScanline) / (ysize - 1);
+ while (nBitsPerScanline <= maxBitsPerScanline)
+ {
+ unsigned long BankBase, BankUnit;
+
+ BankUnit = ((nBitsPerBank + nBitsPerScanline - 1) / nBitsPerBank) *
+ nBitsPerBank;
+ if (!(BankUnit % nBitsPerScanline))
+ return (int)width;
+
+ for (BankBase = BankUnit; ; BankBase += nBitsPerBank)
+ {
+ unsigned long x, y;
+
+ y = BankBase / nBitsPerScanline;
+ if (y >= ysize)
+ return (int)width;
+
+ x = BankBase % nBitsPerScanline;
+ if (!(x % pBankFormat->bitsPerPixel))
+ continue;
+
+ if (x < minBitsPerScanline)
+ {
+ /*
+ * Skip ahead certain widths by dividing the excess scanline
+ * amongst the y's.
+ */
+ y *= nBitsPerScanlinePadUnit;
+ nBitsPerScanline +=
+ ((x + y - 1) / y) * nBitsPerScanlinePadUnit;
+ width = nBitsPerScanline / pBankFormat->bitsPerPixel;
+ break;
+ }
+
+ if (BankBase != BankUnit)
+ continue;
+
+ if (!(nBitsPerScanline % x))
+ return (int)width;
+
+ BankBase = ((nBitsPerScanline - minBitsPerScanline) /
+ (nBitsPerScanline - x)) * BankUnit;
+ }
+ }
+
+ return -1;
+}
+
+/*
+ * xf86ValidateModes
+ *
+ * This function takes a set of mode names, modes and limiting conditions,
+ * and selects a set of modes and parameters based on those conditions.
+ *
+ * This function takes the following parameters:
+ * scrp ScrnInfoPtr
+ * availModes the list of modes available for the monitor
+ * modeNames (optional) list of mode names that the screen is requesting
+ * clockRanges a list of clock ranges
+ * linePitches (optional) a list of line pitches
+ * minPitch (optional) minimum line pitch (in pixels)
+ * maxPitch (optional) maximum line pitch (in pixels)
+ * pitchInc (mandatory) pitch increment (in bits)
+ * minHeight (optional) minimum virtual height (in pixels)
+ * maxHeight (optional) maximum virtual height (in pixels)
+ * virtualX (optional) virtual width requested (in pixels)
+ * virtualY (optional) virtual height requested (in pixels)
+ * apertureSize size of video aperture (in bytes)
+ * strategy how to decide which mode to use from multiple modes with
+ * the same name
+ *
+ * In addition, the following fields from the ScrnInfoRec are used:
+ * clocks a list of discrete clocks
+ * numClocks number of discrete clocks
+ * progClock clock is programmable
+ * monitor pointer to structure for monitor section
+ * fbFormat format of the framebuffer
+ * videoRam video memory size
+ * maxHValue maximum horizontal timing value
+ * maxVValue maximum vertical timing value
+ * xInc horizontal timing increment (defaults to 8 pixels)
+ *
+ * The function fills in the following ScrnInfoRec fields:
+ * modePool A subset of the modes available to the monitor which
+ * are compatible with the driver.
+ * modes one mode entry for each of the requested modes, with the
+ * status field filled in to indicate if the mode has been
+ * accepted or not.
+ * virtualX the resulting virtual width
+ * virtualY the resulting virtual height
+ * displayWidth the resulting line pitch
+ *
+ * The function's return value is the number of matching modes found, or -1
+ * if an unrecoverable error was encountered.
+ */
+
+int
+xf86ValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes,
+ char **modeNames, ClockRangePtr clockRanges,
+ int *linePitches, int minPitch, int maxPitch, int pitchInc,
+ int minHeight, int maxHeight, int virtualX, int virtualY,
+ int apertureSize, LookupModeFlags strategy)
+{
+ DisplayModePtr p, q, r, new, last, *endp;
+ int i, numModes = 0;
+ ModeStatus status;
+ int linePitch = -1, virtX = 0, virtY = 0;
+ int newLinePitch, newVirtX, newVirtY;
+ int modeSize; /* in pixels */
+ Bool validateAllDefaultModes = FALSE;
+ Bool userModes = FALSE;
+ int saveType;
+ PixmapFormatRec *BankFormat;
+ ClockRangePtr cp;
+ ClockRangePtr storeClockRanges;
+ int numTimings = 0;
+ range hsync[MAX_HSYNC];
+ range vrefresh[MAX_VREFRESH];
+ Bool inferred_virtual = FALSE;
+
+ DebugF("xf86ValidateModes(%p, %p, %p, %p,\n\t\t %p, %d, %d, %d, %d, %d, %d, %d, %d, 0x%x)\n",
+ scrp, availModes, modeNames, clockRanges,
+ linePitches, minPitch, maxPitch, pitchInc,
+ minHeight, maxHeight, virtualX, virtualY,
+ apertureSize, strategy
+ );
+
+ /* Some sanity checking */
+ if (scrp == NULL || scrp->name == NULL || !scrp->monitor ||
+ (!scrp->progClock && scrp->numClocks == 0)) {
+ ErrorF("xf86ValidateModes: called with invalid scrnInfoRec\n");
+ return -1;
+ }
+ if (linePitches != NULL && linePitches[0] <= 0) {
+ ErrorF("xf86ValidateModes: called with invalid linePitches\n");
+ return -1;
+ }
+ if (pitchInc <= 0) {
+ ErrorF("xf86ValidateModes: called with invalid pitchInc\n");
+ return -1;
+ }
+ if ((virtualX > 0) != (virtualY > 0)) {
+ ErrorF("xf86ValidateModes: called with invalid virtual resolution\n");
+ return -1;
+ }
+
+ /*
+ * If requested by the driver, allow missing hsync and/or vrefresh ranges
+ * in the monitor section.
+ */
+ if (strategy & LOOKUP_OPTIONAL_TOLERANCES) {
+ strategy &= ~LOOKUP_OPTIONAL_TOLERANCES;
+ } else {
+ const char *type = "";
+
+ if (scrp->monitor->nHsync <= 0) {
+ if (numTimings > 0) {
+ scrp->monitor->nHsync = numTimings;
+ for (i = 0; i < numTimings; i++) {
+ scrp->monitor->hsync[i].lo = hsync[i].lo;
+ scrp->monitor->hsync[i].hi = hsync[i].hi;
+ }
+ } else {
+ scrp->monitor->hsync[0].lo = 31.5;
+ scrp->monitor->hsync[0].hi = 37.9;
+ scrp->monitor->nHsync = 1;
+ }
+ type = "default ";
+ }
+ for (i = 0; i < scrp->monitor->nHsync; i++) {
+ if (scrp->monitor->hsync[i].lo == scrp->monitor->hsync[i].hi)
+ xf86DrvMsg(scrp->scrnIndex, X_INFO,
+ "%s: Using %shsync value of %.2f kHz\n",
+ scrp->monitor->id, type,
+ scrp->monitor->hsync[i].lo);
+ else
+ xf86DrvMsg(scrp->scrnIndex, X_INFO,
+ "%s: Using %shsync range of %.2f-%.2f kHz\n",
+ scrp->monitor->id, type,
+ scrp->monitor->hsync[i].lo,
+ scrp->monitor->hsync[i].hi);
+ }
+
+ type = "";
+ if (scrp->monitor->nVrefresh <= 0) {
+ if (numTimings > 0) {
+ scrp->monitor->nVrefresh = numTimings;
+ for (i = 0; i < numTimings; i++) {
+ scrp->monitor->vrefresh[i].lo = vrefresh[i].lo;
+ scrp->monitor->vrefresh[i].hi = vrefresh[i].hi;
+ }
+ } else {
+ scrp->monitor->vrefresh[0].lo = 50;
+ scrp->monitor->vrefresh[0].hi = 70;
+ scrp->monitor->nVrefresh = 1;
+ }
+ type = "default ";
+ }
+ for (i = 0; i < scrp->monitor->nVrefresh; i++) {
+ if (scrp->monitor->vrefresh[i].lo == scrp->monitor->vrefresh[i].hi)
+ xf86DrvMsg(scrp->scrnIndex, X_INFO,
+ "%s: Using %svrefresh value of %.2f Hz\n",
+ scrp->monitor->id, type,
+ scrp->monitor->vrefresh[i].lo);
+ else
+ xf86DrvMsg(scrp->scrnIndex, X_INFO,
+ "%s: Using %svrefresh range of %.2f-%.2f Hz\n",
+ scrp->monitor->id, type,
+ scrp->monitor->vrefresh[i].lo,
+ scrp->monitor->vrefresh[i].hi);
+ }
+ if (scrp->monitor->maxPixClock) {
+ xf86DrvMsg(scrp->scrnIndex, X_INFO,
+ "%s: Using maximum pixel clock of %.2f MHz\n",
+ scrp->monitor->id,
+ (float)scrp->monitor->maxPixClock / 1000.0);
+ }
+ }
+
+ /*
+ * Store the clockRanges for later use by the VidMode extension.
+ */
+ storeClockRanges = scrp->clockRanges;
+ while (storeClockRanges != NULL) {
+ storeClockRanges = storeClockRanges->next;
+ }
+ for (cp = clockRanges; cp != NULL; cp = cp->next,
+ storeClockRanges = storeClockRanges->next) {
+ storeClockRanges = xnfalloc(sizeof(ClockRange));
+ if (scrp->clockRanges == NULL)
+ scrp->clockRanges = storeClockRanges;
+ memcpy(storeClockRanges, cp, sizeof(ClockRange));
+ }
+
+ /* Determine which pixmap format to pass to scanLineWidth() */
+ if (scrp->depth > 4)
+ BankFormat = &scrp->fbFormat;
+ else
+ BankFormat = xf86GetPixFormat(scrp, 1); /* >not< scrp->depth! */
+
+ if (scrp->xInc <= 0)
+ scrp->xInc = 8; /* Suitable for VGA and others */
+
+#define _VIRTUALX(x) ((((x) + scrp->xInc - 1) / scrp->xInc) * scrp->xInc)
+
+ /*
+ * Determine maxPitch if it wasn't given explicitly. Note linePitches
+ * always takes precedence if is non-NULL. In that case the minPitch and
+ * maxPitch values passed are ignored.
+ */
+ if (linePitches) {
+ minPitch = maxPitch = linePitches[0];
+ for (i = 1; linePitches[i] > 0; i++) {
+ if (linePitches[i] > maxPitch)
+ maxPitch = linePitches[i];
+ if (linePitches[i] < minPitch)
+ minPitch = linePitches[i];
+ }
+ }
+
+ /* Initial check of virtual size against other constraints */
+ scrp->virtualFrom = X_PROBED;
+ /*
+ * Initialise virtX and virtY if the values are fixed.
+ */
+ if (virtualY > 0) {
+ if (maxHeight > 0 && virtualY > maxHeight) {
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Virtual height (%d) is too large for the hardware "
+ "(max %d)\n", virtualY, maxHeight);
+ return -1;
+ }
+
+ if (minHeight > 0 && virtualY < minHeight) {
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Virtual height (%d) is too small for the hardware "
+ "(min %d)\n", virtualY, minHeight);
+ return -1;
+ }
+
+ virtualX = _VIRTUALX(virtualX);
+ if (linePitches != NULL) {
+ for (i = 0; linePitches[i] != 0; i++) {
+ if ((linePitches[i] >= virtualX) &&
+ (linePitches[i] ==
+ scanLineWidth(virtualX, virtualY, linePitches[i],
+ apertureSize, BankFormat, pitchInc))) {
+ linePitch = linePitches[i];
+ break;
+ }
+ }
+ } else {
+ linePitch = scanLineWidth(virtualX, virtualY, minPitch,
+ apertureSize, BankFormat, pitchInc);
+ }
+
+ if ((linePitch < minPitch) || (linePitch > maxPitch)) {
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Virtual width (%d) is too large for the hardware "
+ "(max %d)\n", virtualX, maxPitch);
+ return -1;
+ }
+
+ if (!xf86CheckModeSize(scrp, linePitch, virtualX, virtualY)) {
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Virtual size (%dx%d) (pitch %d) exceeds video memory\n",
+ virtualX, virtualY, linePitch);
+ return -1;
+ }
+
+ virtX = virtualX;
+ virtY = virtualY;
+ scrp->virtualFrom = X_CONFIG;
+ } else if (!modeNames || !*modeNames) {
+ /* No virtual size given in the config, try to infer */
+ /* XXX this doesn't take m{in,ax}Pitch into account; oh well */
+ inferred_virtual = inferVirtualSize(scrp, availModes, &virtX, &virtY);
+ if (inferred_virtual)
+ linePitch = scanLineWidth(virtX, virtY, minPitch, apertureSize,
+ BankFormat, pitchInc);
+ }
+
+ /* Print clock ranges and scaled clocks */
+ xf86ShowClockRanges(scrp, clockRanges);
+
+ /*
+ * If scrp->modePool hasn't been setup yet, set it up now. This allows the
+ * modes that the driver definitely can't use to be weeded out early. Note
+ * that a modePool mode's prev field is used to hold a pointer to the
+ * member of the scrp->modes list for which a match was considered.
+ */
+ if (scrp->modePool == NULL) {
+ q = NULL;
+ for (p = availModes; p != NULL; p = p->next) {
+ status = xf86InitialCheckModeForDriver(scrp, p, clockRanges,
+ strategy, maxPitch,
+ virtX, virtY);
+
+ if (status == MODE_OK) {
+ status = xf86CheckModeForMonitor(p, scrp->monitor);
+ }
+
+ if (status == MODE_OK) {
+ new = xnfalloc(sizeof(DisplayModeRec));
+ *new = *p;
+ new->next = NULL;
+ if (!q) {
+ scrp->modePool = new;
+ } else {
+ q->next = new;
+ }
+ new->prev = NULL;
+ q = new;
+ q->name = xnfstrdup(p->name);
+ q->status = MODE_OK;
+ } else {
+ printModeRejectMessage(scrp->scrnIndex, p, status);
+ }
+ }
+
+ if (scrp->modePool == NULL) {
+ xf86DrvMsg(scrp->scrnIndex, X_WARNING, "Mode pool is empty\n");
+ return 0;
+ }
+ } else {
+ for (p = scrp->modePool; p != NULL; p = p->next) {
+ p->prev = NULL;
+ p->status = MODE_OK;
+ }
+ }
+
+ /*
+ * Allocate one entry in scrp->modes for each named mode.
+ */
+ while (scrp->modes)
+ xf86DeleteMode(&scrp->modes, scrp->modes);
+ endp = &scrp->modes;
+ last = NULL;
+ if (modeNames != NULL) {
+ for (i = 0; modeNames[i] != NULL; i++) {
+ userModes = TRUE;
+ new = xnfcalloc(1, sizeof(DisplayModeRec));
+ new->prev = last;
+ new->type = M_T_USERDEF;
+ new->name = xnfalloc(strlen(modeNames[i]) + 1);
+ strcpy(new->name, modeNames[i]);
+ if (new->prev)
+ new->prev->next = new;
+ *endp = last = new;
+ endp = &new->next;
+ }
+ }
+
+ /* Lookup each mode */
+#ifdef RANDR
+ if (!xf86Info.disableRandR
+#ifdef PANORAMIX
+ && noPanoramiXExtension
+#endif
+ )
+ validateAllDefaultModes = TRUE;
+#endif
+
+ for (p = scrp->modes; ; p = p->next) {
+ Bool repeat;
+
+ /*
+ * If the supplied mode names don't produce a valid mode, scan through
+ * unconsidered modePool members until one survives validation. This
+ * is done in decreasing order by mode pixel area.
+ */
+
+ if (p == NULL) {
+ if ((numModes > 0) && !validateAllDefaultModes)
+ break;
+
+ validateAllDefaultModes = TRUE;
+ r = NULL;
+ modeSize = 0;
+ for (q = scrp->modePool; q != NULL; q = q->next) {
+ if ((q->prev == NULL) && (q->status == MODE_OK)) {
+ /*
+ * Deal with the case where this mode wasn't considered
+ * because of a builtin mode of the same name.
+ */
+ for (p = scrp->modes; p != NULL; p = p->next) {
+ if ((p->status != MODE_OK) &&
+ !strcmp(p->name, q->name))
+ break;
+ }
+
+ if (p != NULL)
+ q->prev = p;
+ else {
+ /*
+ * A quick check to not allow default modes with
+ * horizontal timing parameters that CRTs may have
+ * problems with.
+ */
+ if (!scrp->monitor->reducedblanking &&
+ (q->type & M_T_DEFAULT) &&
+ ((double)q->HTotal / (double)q->HDisplay) < 1.15)
+ continue;
+
+ if (modeSize < (q->HDisplay * q->VDisplay)) {
+ r = q;
+ modeSize = q->HDisplay * q->VDisplay;
+ }
+ }
+ }
+ }
+
+ if (r == NULL)
+ break;
+
+ p = xnfcalloc(1, sizeof(DisplayModeRec));
+ p->prev = last;
+ p->name = xnfalloc(strlen(r->name) + 1);
+ if (!userModes)
+ p->type = M_T_USERDEF;
+ strcpy(p->name, r->name);
+ if (p->prev)
+ p->prev->next = p;
+ *endp = last = p;
+ endp = &p->next;
+ }
+
+ repeat = FALSE;
+ lookupNext:
+ if (repeat && ((status = p->status) != MODE_OK))
+ printModeRejectMessage(scrp->scrnIndex, p, status);
+ saveType = p->type;
+ status = xf86LookupMode(scrp, p, clockRanges, strategy);
+ if (repeat && status == MODE_NOMODE)
+ continue;
+ if (status != MODE_OK)
+ printModeRejectMessage(scrp->scrnIndex, p, status);
+ if (status == MODE_ERROR) {
+ ErrorF("xf86ValidateModes: "
+ "unexpected result from xf86LookupMode()\n");
+ return -1;
+ }
+ if (status != MODE_OK) {
+ if (p->status == MODE_OK)
+ p->status = status;
+ continue;
+ }
+ p->type |= saveType;
+ repeat = TRUE;
+
+ newLinePitch = linePitch;
+ newVirtX = virtX;
+ newVirtY = virtY;
+
+ /*
+ * Don't let non-user defined modes increase the virtual size
+ */
+ if (!(p->type & M_T_USERDEF) && (numModes > 0)) {
+ if (p->HDisplay > virtX) {
+ p->status = MODE_VIRTUAL_X;
+ goto lookupNext;
+ }
+ if (p->VDisplay > virtY) {
+ p->status = MODE_VIRTUAL_Y;
+ goto lookupNext;
+ }
+ }
+ /*
+ * Adjust virtual width and height if the mode is too large for the
+ * current values and if they are not fixed.
+ */
+ if (virtualX <= 0 && p->HDisplay > newVirtX)
+ newVirtX = _VIRTUALX(p->HDisplay);
+ if (virtualY <= 0 && p->VDisplay > newVirtY) {
+ if (maxHeight > 0 && p->VDisplay > maxHeight) {
+ p->status = MODE_VIRTUAL_Y; /* ? */
+ goto lookupNext;
+ }
+ newVirtY = p->VDisplay;
+ }
+
+ /*
+ * If virtual resolution is to be increased, revalidate it.
+ */
+ if ((virtX != newVirtX) || (virtY != newVirtY)) {
+ if (linePitches != NULL) {
+ newLinePitch = -1;
+ for (i = 0; linePitches[i] != 0; i++) {
+ if ((linePitches[i] >= newVirtX) &&
+ (linePitches[i] >= linePitch) &&
+ (linePitches[i] ==
+ scanLineWidth(newVirtX, newVirtY, linePitches[i],
+ apertureSize, BankFormat, pitchInc))) {
+ newLinePitch = linePitches[i];
+ break;
+ }
+ }
+ } else {
+ if (linePitch < minPitch)
+ linePitch = minPitch;
+ newLinePitch = scanLineWidth(newVirtX, newVirtY, linePitch,
+ apertureSize, BankFormat,
+ pitchInc);
+ }
+ if ((newLinePitch < minPitch) || (newLinePitch > maxPitch)) {
+ p->status = MODE_BAD_WIDTH;
+ goto lookupNext;
+ }
+
+ /*
+ * Check that the pixel area required by the new virtual height
+ * and line pitch isn't too large.
+ */
+ if (!xf86CheckModeSize(scrp, newLinePitch, newVirtX, newVirtY)) {
+ p->status = MODE_MEM_VIRT;
+ goto lookupNext;
+ }
+ }
+
+ if (scrp->ValidMode) {
+ /*
+ * Give the driver a final say, passing it the proposed virtual
+ * geometry.
+ */
+ scrp->virtualX = newVirtX;
+ scrp->virtualY = newVirtY;
+ scrp->displayWidth = newLinePitch;
+ p->status = (scrp->ValidMode)(scrp->scrnIndex, p, FALSE,
+ MODECHECK_FINAL);
+
+ if (p->status != MODE_OK) {
+ goto lookupNext;
+ }
+ }
+
+ /* Mode has passed all the tests */
+ virtX = newVirtX;
+ virtY = newVirtY;
+ linePitch = newLinePitch;
+ p->status = MODE_OK;
+ numModes++;
+ }
+
+#undef _VIRTUALX
+
+ /*
+ * If we estimated the virtual size above, we may have filtered away all
+ * the modes that maximally match that size; scan again to find out and
+ * fix up if so.
+ */
+ if (inferred_virtual) {
+ int vx = 0, vy = 0;
+ for (p = scrp->modes; p; p = p->next) {
+ if (p->HDisplay > vx && p->VDisplay > vy) {
+ vx = p->HDisplay;
+ vy = p->VDisplay;
+ }
+ }
+ if (vx < virtX || vy < virtY) {
+ xf86DrvMsg(scrp->scrnIndex, X_WARNING,
+ "Shrinking virtual size estimate from %dx%d to %dx%d\n",
+ virtX, virtY, vx, vy);
+ virtX = vx;
+ virtY = vy;
+ linePitch = scanLineWidth(vx, vy, minPitch, apertureSize,
+ BankFormat, pitchInc);
+ }
+ }
+
+ /* Update the ScrnInfoRec parameters */
+
+ scrp->virtualX = virtX;
+ scrp->virtualY = virtY;
+ scrp->displayWidth = linePitch;
+
+ if (numModes <= 0)
+ return 0;
+
+ /* Make the mode list into a circular list by joining up the ends */
+ p = scrp->modes;
+ while (p->next != NULL)
+ p = p->next;
+ /* p is now the last mode on the list */
+ p->next = scrp->modes;
+ scrp->modes->prev = p;
+
+ if (minHeight > 0 && virtY < minHeight) {
+ xf86DrvMsg(scrp->scrnIndex, X_ERROR,
+ "Virtual height (%d) is too small for the hardware "
+ "(min %d)\n", virtY, minHeight);
+ return -1;
+ }
+
+ return numModes;
+}
+
+/*
+ * xf86DeleteMode
+ *
+ * This function removes a mode from a list of modes.
+ *
+ * There are different types of mode lists:
+ *
+ * - singly linked linear lists, ending in NULL
+ * - doubly linked linear lists, starting and ending in NULL
+ * - doubly linked circular lists
+ *
+ */
+
+void
+xf86DeleteMode(DisplayModePtr *modeList, DisplayModePtr mode)
+{
+ /* Catch the easy/insane cases */
+ if (modeList == NULL || *modeList == NULL || mode == NULL)
+ return;
+
+ /* If the mode is at the start of the list, move the start of the list */
+ if (*modeList == mode)
+ *modeList = mode->next;
+
+ /* If mode is the only one on the list, set the list to NULL */
+ if ((mode == mode->prev) && (mode == mode->next)) {
+ *modeList = NULL;
+ } else {
+ if ((mode->prev != NULL) && (mode->prev->next == mode))
+ mode->prev->next = mode->next;
+ if ((mode->next != NULL) && (mode->next->prev == mode))
+ mode->next->prev = mode->prev;
+ }
+
+ free(mode->name);
+ free(mode);
+}
+
+/*
+ * xf86PruneDriverModes
+ *
+ * Remove modes from the driver's mode list which have been marked as
+ * invalid.
+ */
+
+void
+xf86PruneDriverModes(ScrnInfoPtr scrp)
+{
+ DisplayModePtr first, p, n;
+
+ p = scrp->modes;
+ if (p == NULL)
+ return;
+
+ do {
+ if (!(first = scrp->modes))
+ return;
+ n = p->next;
+ if (p->status != MODE_OK) {
+ xf86DeleteMode(&(scrp->modes), p);
+ }
+ p = n;
+ } while (p != NULL && p != first);
+
+ /* modePool is no longer needed, turf it */
+ while (scrp->modePool) {
+ /*
+ * A modePool mode's prev field is used to hold a pointer to the
+ * member of the scrp->modes list for which a match was considered.
+ * Clear that pointer first, otherwise xf86DeleteMode might get
+ * confused
+ */
+ scrp->modePool->prev = NULL;
+ xf86DeleteMode(&scrp->modePool, scrp->modePool);
+ }
+}
+
+
+/*
+ * xf86SetCrtcForModes
+ *
+ * Goes through the screen's mode list, and initialises the Crtc
+ * parameters for each mode. The initialisation includes adjustments
+ * for interlaced and double scan modes.
+ */
+void
+xf86SetCrtcForModes(ScrnInfoPtr scrp, int adjustFlags)
+{
+ DisplayModePtr p;
+
+ /*
+ * Store adjustFlags for use with the VidMode extension. There is an
+ * implicit assumption here that SetCrtcForModes is called once.
+ */
+ scrp->adjustFlags = adjustFlags;
+
+ p = scrp->modes;
+ if (p == NULL)
+ return;
+
+ do {
+ xf86SetModeCrtc(p, adjustFlags);
+ DebugF("%sMode %s: %d (%d) %d %d (%d) %d %d (%d) %d %d (%d) %d\n",
+ (p->type & M_T_DEFAULT) ? "Default " : "",
+ p->name, p->CrtcHDisplay, p->CrtcHBlankStart,
+ p->CrtcHSyncStart, p->CrtcHSyncEnd, p->CrtcHBlankEnd,
+ p->CrtcHTotal, p->CrtcVDisplay, p->CrtcVBlankStart,
+ p->CrtcVSyncStart, p->CrtcVSyncEnd, p->CrtcVBlankEnd,
+ p->CrtcVTotal);
+ p = p->next;
+ } while (p != NULL && p != scrp->modes);
+}
+
+void
+xf86PrintModes(ScrnInfoPtr scrp)
+{
+ DisplayModePtr p;
+ float hsync, refresh = 0;
+ char *desc, *desc2, *prefix, *uprefix;
+
+ if (scrp == NULL)
+ return;
+
+ xf86DrvMsg(scrp->scrnIndex, scrp->virtualFrom, "Virtual size is %dx%d "
+ "(pitch %d)\n", scrp->virtualX, scrp->virtualY,
+ scrp->displayWidth);
+
+ p = scrp->modes;
+ if (p == NULL)
+ return;
+
+ do {
+ desc = desc2 = "";
+ hsync = xf86ModeHSync(p);
+ refresh = xf86ModeVRefresh(p);
+ if (p->Flags & V_INTERLACE) {
+ desc = " (I)";
+ }
+ if (p->Flags & V_DBLSCAN) {
+ desc = " (D)";
+ }
+ if (p->VScan > 1) {
+ desc2 = " (VScan)";
+ }
+ if (p->type & M_T_BUILTIN)
+ prefix = "Built-in mode";
+ else if (p->type & M_T_DEFAULT)
+ prefix = "Default mode";
+ else if (p->type & M_T_DRIVER)
+ prefix = "Driver mode";
+ else
+ prefix = "Mode";
+ if (p->type & M_T_USERDEF)
+ uprefix = "*";
+ else
+ uprefix = " ";
+ if (hsync == 0 || refresh == 0) {
+ if (p->name)
+ xf86DrvMsg(scrp->scrnIndex, X_CONFIG,
+ "%s%s \"%s\"\n", uprefix, prefix, p->name);
+ else
+ xf86DrvMsg(scrp->scrnIndex, X_PROBED,
+ "%s%s %dx%d (unnamed)\n",
+ uprefix, prefix, p->HDisplay, p->VDisplay);
+ } else if (p->Clock == p->SynthClock) {
+ xf86DrvMsg(scrp->scrnIndex, X_CONFIG,
+ "%s%s \"%s\": %.1f MHz, %.1f kHz, %.1f Hz%s%s\n",
+ uprefix, prefix, p->name, p->Clock / 1000.0,
+ hsync, refresh, desc, desc2);
+ } else {
+ xf86DrvMsg(scrp->scrnIndex, X_CONFIG,
+ "%s%s \"%s\": %.1f MHz (scaled from %.1f MHz), "
+ "%.1f kHz, %.1f Hz%s%s\n",
+ uprefix, prefix, p->name, p->Clock / 1000.0,
+ p->SynthClock / 1000.0, hsync, refresh, desc, desc2);
+ }
+ if (hsync != 0 && refresh != 0)
+ xf86PrintModeline(scrp->scrnIndex,p);
+ p = p->next;
+ } while (p != NULL && p != scrp->modes);
+}
diff --git a/xorg-server/hw/xfree86/common/xf86Option.c b/xorg-server/hw/xfree86/common/xf86Option.c
index a2868bf21..965ce4c7d 100644
--- a/xorg-server/hw/xfree86/common/xf86Option.c
+++ b/xorg-server/hw/xfree86/common/xf86Option.c
@@ -1,862 +1,862 @@
-/*
- * Copyright (c) 1998-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-/*
- * Author: David Dawes <dawes@xfree86.org>
- *
- * This file includes public option handling functions.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <stdlib.h>
-#include <ctype.h>
-#include <X11/X.h>
-#include "os.h"
-#include "xf86.h"
-#include "xf86Xinput.h"
-#include "xf86Optrec.h"
-#include "xf86Parser.h"
-
-static Bool ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p,
- Bool markUsed);
-
-/*
- * xf86CollectOptions collects the options from each of the config file
- * sections used by the screen and puts the combined list in pScrn->options.
- * This function requires that the following have been initialised:
- *
- * pScrn->confScreen
- * pScrn->Entities[i]->device
- * pScrn->display
- * pScrn->monitor
- *
- * The extraOpts parameter may optionally contain a list of additional options
- * to include.
- *
- * The order of precedence for options is:
- *
- * extraOpts, display, confScreen, monitor, device
- */
-
-void
-xf86CollectOptions(ScrnInfoPtr pScrn, pointer extraOpts)
-{
- XF86OptionPtr tmp;
- XF86OptionPtr extras = (XF86OptionPtr)extraOpts;
- GDevPtr device;
-
- int i;
-
- pScrn->options = NULL;
-
- for (i=pScrn->numEntities - 1; i >= 0; i--) {
- device = xf86GetDevFromEntity(pScrn->entityList[i],
- pScrn->entityInstanceList[i]);
- if (device && device->options) {
- tmp = xf86optionListDup(device->options);
- if (pScrn->options)
- xf86optionListMerge(pScrn->options,tmp);
- else
- pScrn->options = tmp;
- }
- }
- if (pScrn->monitor->options) {
- tmp = xf86optionListDup(pScrn->monitor->options);
- if (pScrn->options)
- pScrn->options = xf86optionListMerge(pScrn->options, tmp);
- else
- pScrn->options = tmp;
- }
- if (pScrn->confScreen->options) {
- tmp = xf86optionListDup(pScrn->confScreen->options);
- if (pScrn->options)
- pScrn->options = xf86optionListMerge(pScrn->options, tmp);
- else
- pScrn->options = tmp;
- }
- if (pScrn->display->options) {
- tmp = xf86optionListDup(pScrn->display->options);
- if (pScrn->options)
- pScrn->options = xf86optionListMerge(pScrn->options, tmp);
- else
- pScrn->options = tmp;
- }
- if (extras) {
- tmp = xf86optionListDup(extras);
- if (pScrn->options)
- pScrn->options = xf86optionListMerge(pScrn->options, tmp);
- else
- pScrn->options = tmp;
- }
-}
-
-/*
- * xf86CollectInputOptions collects the options for an InputDevice.
- * This function requires that the following has been initialised:
- *
- * pInfo->conf_idev
- *
- * The extraOpts parameter may optionally contain a list of additional options
- * to include.
- *
- * The order of precedence for options is:
- *
- * extraOpts, pInfo->conf_idev->extraOptions,
- * pInfo->conf_idev->commonOptions, defaultOpts
- */
-
-void
-xf86CollectInputOptions(InputInfoPtr pInfo, const char **defaultOpts,
- pointer extraOpts)
-{
- XF86OptionPtr tmp;
- XF86OptionPtr extras = (XF86OptionPtr)extraOpts;
-
- pInfo->options = NULL;
- if (defaultOpts) {
- pInfo->options = xf86OptionListCreate(defaultOpts, -1, 0);
- }
- if (pInfo->conf_idev && pInfo->conf_idev->commonOptions) {
- tmp = xf86optionListDup(pInfo->conf_idev->commonOptions);
- if (pInfo->options)
- pInfo->options = xf86optionListMerge(pInfo->options, tmp);
- else
- pInfo->options = tmp;
- }
- if (pInfo->conf_idev && pInfo->conf_idev->extraOptions) {
- tmp = xf86optionListDup(pInfo->conf_idev->extraOptions);
- if (pInfo->options)
- pInfo->options = xf86optionListMerge(pInfo->options, tmp);
- else
- pInfo->options = tmp;
- }
- if (extras) {
- tmp = xf86optionListDup(extras);
- if (pInfo->options)
- pInfo->options = xf86optionListMerge(pInfo->options, tmp);
- else
- pInfo->options = tmp;
- }
-}
-
-/* Created for new XInput stuff -- essentially extensions to the parser */
-
-static int
-LookupIntOption(pointer optlist, const char *name, int deflt, Bool markUsed)
-{
- OptionInfoRec o;
-
- o.name = name;
- o.type = OPTV_INTEGER;
- if (ParseOptionValue(-1, optlist, &o, markUsed))
- deflt = o.value.num;
- return deflt;
-}
-
-
-static double
-LookupRealOption(pointer optlist, const char *name, double deflt,
- Bool markUsed)
-{
- OptionInfoRec o;
-
- o.name = name;
- o.type = OPTV_REAL;
- if (ParseOptionValue(-1, optlist, &o, markUsed))
- deflt = o.value.realnum;
- return deflt;
-}
-
-
-static char *
-LookupStrOption(pointer optlist, const char *name, char *deflt, Bool markUsed)
-{
- OptionInfoRec o;
-
- o.name = name;
- o.type = OPTV_STRING;
- if (ParseOptionValue(-1, optlist, &o, markUsed))
- deflt = o.value.str;
- if (deflt)
- return xstrdup(deflt);
- else
- return NULL;
-}
-
-
-static int
-LookupBoolOption(pointer optlist, const char *name, int deflt, Bool markUsed)
-{
- OptionInfoRec o;
-
- o.name = name;
- o.type = OPTV_BOOLEAN;
- if (ParseOptionValue(-1, optlist, &o, markUsed))
- deflt = o.value.bool;
- return deflt;
-}
-
-/* These xf86Set* functions are intended for use by non-screen specific code */
-
-int
-xf86SetIntOption(pointer optlist, const char *name, int deflt)
-{
- return LookupIntOption(optlist, name, deflt, TRUE);
-}
-
-
-double
-xf86SetRealOption(pointer optlist, const char *name, double deflt)
-{
- return LookupRealOption(optlist, name, deflt, TRUE);
-}
-
-
-char *
-xf86SetStrOption(pointer optlist, const char *name, char *deflt)
-{
- return LookupStrOption(optlist, name, deflt, TRUE);
-}
-
-
-int
-xf86SetBoolOption(pointer optlist, const char *name, int deflt)
-{
- return LookupBoolOption(optlist, name, deflt, TRUE);
-}
-
-/*
- * These are like the Set*Option functions, but they don't mark the options
- * as used.
- */
-int
-xf86CheckIntOption(pointer optlist, const char *name, int deflt)
-{
- return LookupIntOption(optlist, name, deflt, FALSE);
-}
-
-
-double
-xf86CheckRealOption(pointer optlist, const char *name, double deflt)
-{
- return LookupRealOption(optlist, name, deflt, FALSE);
-}
-
-
-char *
-xf86CheckStrOption(pointer optlist, const char *name, char *deflt)
-{
- return LookupStrOption(optlist, name, deflt, FALSE);
-}
-
-
-int
-xf86CheckBoolOption(pointer optlist, const char *name, int deflt)
-{
- return LookupBoolOption(optlist, name, deflt, FALSE);
-}
-
-/*
- * addNewOption() has the required property of replacing the option value
- * if the option is already present.
- */
-pointer
-xf86ReplaceIntOption(pointer optlist, const char *name, const int val)
-{
- char tmp[16];
- sprintf(tmp,"%i",val);
- return xf86AddNewOption(optlist,name,tmp);
-}
-
-pointer
-xf86ReplaceRealOption(pointer optlist, const char *name, const double val)
-{
- char tmp[32];
- snprintf(tmp,32,"%f",val);
- return xf86AddNewOption(optlist,name,tmp);
-}
-
-pointer
-xf86ReplaceBoolOption(pointer optlist, const char *name, const Bool val)
-{
- return xf86AddNewOption(optlist,name,val?"True":"False");
-}
-
-pointer
-xf86ReplaceStrOption(pointer optlist, const char *name, const char* val)
-{
- return xf86AddNewOption(optlist,name,val);
-}
-
-pointer
-xf86AddNewOption(pointer head, const char *name, const char *val)
-{
- /* XXX These should actually be allocated in the parser library. */
- char *tmp = strdup(val);
- char *tmp_name = strdup(name);
-
- return xf86addNewOption(head, tmp_name, tmp);
-}
-
-
-pointer
-xf86NewOption(char *name, char *value)
-{
- return xf86newOption(name, value);
-}
-
-
-pointer
-xf86NextOption(pointer list)
-{
- return xf86nextOption(list);
-}
-
-pointer
-xf86OptionListCreate(const char **options, int count, int used)
-{
- return xf86optionListCreate(options, count, used);
-}
-
-pointer
-xf86OptionListMerge(pointer head, pointer tail)
-{
- return xf86optionListMerge(head, tail);
-}
-
-void
-xf86OptionListFree(pointer opt)
-{
- xf86optionListFree(opt);
-}
-
-char *
-xf86OptionName(pointer opt)
-{
- return xf86optionName(opt);
-}
-
-char *
-xf86OptionValue(pointer opt)
-{
- return xf86optionValue(opt);
-}
-
-void
-xf86OptionListReport(pointer parm)
-{
- XF86OptionPtr opts = parm;
-
- while(opts) {
- if (xf86optionValue(opts))
- xf86ErrorFVerb(5, "\tOption \"%s\" \"%s\"\n",
- xf86optionName(opts), xf86optionValue(opts));
- else
- xf86ErrorFVerb( 5, "\tOption \"%s\"\n", xf86optionName(opts));
- opts = xf86nextOption(opts);
- }
-}
-
-/* End of XInput-caused section */
-
-pointer
-xf86FindOption(pointer options, const char *name)
-{
- return xf86findOption(options, name);
-}
-
-
-char *
-xf86FindOptionValue(pointer options, const char *name)
-{
- return xf86findOptionValue(options, name);
-}
-
-
-void
-xf86MarkOptionUsed(pointer option)
-{
- if (option != NULL)
- ((XF86OptionPtr)option)->opt_used = TRUE;
-}
-
-
-void
-xf86MarkOptionUsedByName(pointer options, const char *name)
-{
- XF86OptionPtr opt;
-
- opt = xf86findOption(options, name);
- if (opt != NULL)
- opt->opt_used = TRUE;
-}
-
-Bool
-xf86CheckIfOptionUsed(pointer option)
-{
- if (option != NULL)
- return ((XF86OptionPtr)option)->opt_used;
- else
- return FALSE;
-}
-
-Bool
-xf86CheckIfOptionUsedByName(pointer options, const char *name)
-{
- XF86OptionPtr opt;
-
- opt = xf86findOption(options, name);
- if (opt != NULL)
- return opt->opt_used;
- else
- return FALSE;
-}
-
-void
-xf86ShowUnusedOptions(int scrnIndex, pointer options)
-{
- XF86OptionPtr opt = options;
-
- while (opt) {
- if (opt->opt_name && !opt->opt_used) {
- xf86DrvMsg(scrnIndex, X_WARNING, "Option \"%s\" is not used\n",
- opt->opt_name);
- }
- opt = opt->list.next;
- }
-}
-
-
-static Bool
-GetBoolValue(OptionInfoPtr p, const char *s)
-{
- return xf86getBoolValue(&p->value.bool, s);
-}
-
-static Bool
-ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p,
- Bool markUsed)
-{
- char *s, *end;
- Bool wasUsed = FALSE;
-
- if ((s = xf86findOptionValue(options, p->name)) != NULL) {
- if (markUsed) {
- wasUsed = xf86CheckIfOptionUsedByName(options, p->name);
- xf86MarkOptionUsedByName(options, p->name);
- }
- switch (p->type) {
- case OPTV_INTEGER:
- if (*s == '\0') {
- xf86DrvMsg(scrnIndex, X_WARNING,
- "Option \"%s\" requires an integer value\n",
- p->name);
- p->found = FALSE;
- } else {
- p->value.num = strtoul(s, &end, 0);
- if (*end == '\0') {
- p->found = TRUE;
- } else {
- xf86DrvMsg(scrnIndex, X_WARNING,
- "Option \"%s\" requires an integer value\n",
- p->name);
- p->found = FALSE;
- }
- }
- break;
- case OPTV_STRING:
- if (*s == '\0') {
- xf86DrvMsg(scrnIndex, X_WARNING,
- "Option \"%s\" requires an string value\n",
- p->name);
- p->found = FALSE;
- } else {
- p->value.str = s;
- p->found = TRUE;
- }
- break;
- case OPTV_ANYSTR:
- p->value.str = s;
- p->found = TRUE;
- break;
- case OPTV_REAL:
- if (*s == '\0') {
- xf86DrvMsg(scrnIndex, X_WARNING,
- "Option \"%s\" requires a floating point value\n",
- p->name);
- p->found = FALSE;
- } else {
- p->value.realnum = strtod(s, &end);
- if (*end == '\0') {
- p->found = TRUE;
- } else {
- xf86DrvMsg(scrnIndex, X_WARNING,
- "Option \"%s\" requires a floating point value\n",
- p->name);
- p->found = FALSE;
- }
- }
- break;
- case OPTV_BOOLEAN:
- if (GetBoolValue(p, s)) {
- p->found = TRUE;
- } else {
- xf86DrvMsg(scrnIndex, X_WARNING,
- "Option \"%s\" requires a boolean value\n", p->name);
- p->found = FALSE;
- }
- break;
- case OPTV_FREQ:
- if (*s == '\0') {
- xf86DrvMsg(scrnIndex, X_WARNING,
- "Option \"%s\" requires a frequency value\n",
- p->name);
- p->found = FALSE;
- } else {
- double freq = strtod(s, &end);
- int units = 0;
-
- if (end != s) {
- p->found = TRUE;
- if (!xf86NameCmp(end, "Hz"))
- units = 1;
- else if (!xf86NameCmp(end, "kHz") ||
- !xf86NameCmp(end, "k"))
- units = 1000;
- else if (!xf86NameCmp(end, "MHz") ||
- !xf86NameCmp(end, "M"))
- units = 1000000;
- else {
- xf86DrvMsg(scrnIndex, X_WARNING,
- "Option \"%s\" requires a frequency value\n",
- p->name);
- p->found = FALSE;
- }
- if (p->found)
- freq *= (double)units;
- } else {
- xf86DrvMsg(scrnIndex, X_WARNING,
- "Option \"%s\" requires a frequency value\n",
- p->name);
- p->found = FALSE;
- }
- if (p->found) {
- p->value.freq.freq = freq;
- p->value.freq.units = units;
- }
- }
- break;
- case OPTV_NONE:
- /* Should never get here */
- p->found = FALSE;
- break;
- }
- if (p->found && markUsed) {
- int verb = 2;
- if (wasUsed)
- verb = 4;
- xf86DrvMsgVerb(scrnIndex, X_CONFIG, verb, "Option \"%s\"", p->name);
- if (!(p->type == OPTV_BOOLEAN && *s == 0)) {
- xf86ErrorFVerb(verb, " \"%s\"", s);
- }
- xf86ErrorFVerb(verb, "\n");
- }
- } else if (p->type == OPTV_BOOLEAN) {
- /* Look for matches with options with or without a "No" prefix. */
- char *n, *newn;
- OptionInfoRec opt;
-
- n = xf86NormalizeName(p->name);
- if (!n) {
- p->found = FALSE;
- return FALSE;
- }
- if (strncmp(n, "no", 2) == 0) {
- newn = n + 2;
- } else {
- xfree(n);
- n = xalloc(strlen(p->name) + 2 + 1);
- if (!n) {
- p->found = FALSE;
- return FALSE;
- }
- strcpy(n, "No");
- strcat(n, p->name);
- newn = n;
- }
- if ((s = xf86findOptionValue(options, newn)) != NULL) {
- if (markUsed)
- xf86MarkOptionUsedByName(options, newn);
- if (GetBoolValue(&opt, s)) {
- p->value.bool = !opt.value.bool;
- p->found = TRUE;
- } else {
- xf86DrvMsg(scrnIndex, X_WARNING,
- "Option \"%s\" requires a boolean value\n", newn);
- p->found = FALSE;
- }
- } else {
- p->found = FALSE;
- }
- if (p->found && markUsed) {
- xf86DrvMsgVerb(scrnIndex, X_CONFIG, 2, "Option \"%s\"", newn);
- if (*s != 0) {
- xf86ErrorFVerb(2, " \"%s\"", s);
- }
- xf86ErrorFVerb(2, "\n");
- }
- xfree(n);
- } else {
- p->found = FALSE;
- }
- return p->found;
-}
-
-
-void
-xf86ProcessOptions(int scrnIndex, pointer options, OptionInfoPtr optinfo)
-{
- OptionInfoPtr p;
-
- for (p = optinfo; p->name != NULL; p++) {
- ParseOptionValue(scrnIndex, options, p, TRUE);
- }
-}
-
-
-OptionInfoPtr
-xf86TokenToOptinfo(const OptionInfoRec *table, int token)
-{
- const OptionInfoRec *p, *match = NULL, *set = NULL;
-
- if (!table) {
- ErrorF("xf86TokenToOptinfo: table is NULL\n");
- return NULL;
- }
-
- for (p = table; p->token >= 0; p++) {
- if (p->token == token) {
- match = p;
- if (p->found)
- set = p;
- }
- }
-
- if (set)
- return (OptionInfoPtr)set;
- else if (match)
- return (OptionInfoPtr)match;
- else
- return NULL;
-}
-
-
-const char *
-xf86TokenToOptName(const OptionInfoRec *table, int token)
-{
- const OptionInfoRec *p;
-
- p = xf86TokenToOptinfo(table, token);
- return p->name;
-}
-
-
-Bool
-xf86IsOptionSet(const OptionInfoRec *table, int token)
-{
- OptionInfoPtr p;
-
- p = xf86TokenToOptinfo(table, token);
- return (p && p->found);
-}
-
-
-char *
-xf86GetOptValString(const OptionInfoRec *table, int token)
-{
- OptionInfoPtr p;
-
- p = xf86TokenToOptinfo(table, token);
- if (p && p->found)
- return p->value.str;
- else
- return NULL;
-}
-
-
-Bool
-xf86GetOptValInteger(const OptionInfoRec *table, int token, int *value)
-{
- OptionInfoPtr p;
-
- p = xf86TokenToOptinfo(table, token);
- if (p && p->found) {
- *value = p->value.num;
- return TRUE;
- } else
- return FALSE;
-}
-
-
-Bool
-xf86GetOptValULong(const OptionInfoRec *table, int token, unsigned long *value)
-{
- OptionInfoPtr p;
-
- p = xf86TokenToOptinfo(table, token);
- if (p && p->found) {
- *value = p->value.num;
- return TRUE;
- } else
- return FALSE;
-}
-
-
-Bool
-xf86GetOptValReal(const OptionInfoRec *table, int token, double *value)
-{
- OptionInfoPtr p;
-
- p = xf86TokenToOptinfo(table, token);
- if (p && p->found) {
- *value = p->value.realnum;
- return TRUE;
- } else
- return FALSE;
-}
-
-
-Bool
-xf86GetOptValFreq(const OptionInfoRec *table, int token,
- OptFreqUnits expectedUnits, double *value)
-{
- OptionInfoPtr p;
-
- p = xf86TokenToOptinfo(table, token);
- if (p && p->found) {
- if (p->value.freq.units > 0) {
- /* Units give, so the scaling is known. */
- switch (expectedUnits) {
- case OPTUNITS_HZ:
- *value = p->value.freq.freq;
- break;
- case OPTUNITS_KHZ:
- *value = p->value.freq.freq / 1000.0;
- break;
- case OPTUNITS_MHZ:
- *value = p->value.freq.freq / 1000000.0;
- break;
- }
- } else {
- /* No units given, so try to guess the scaling. */
- switch (expectedUnits) {
- case OPTUNITS_HZ:
- *value = p->value.freq.freq;
- break;
- case OPTUNITS_KHZ:
- if (p->value.freq.freq > 1000.0)
- *value = p->value.freq.freq / 1000.0;
- else
- *value = p->value.freq.freq;
- break;
- case OPTUNITS_MHZ:
- if (p->value.freq.freq > 1000000.0)
- *value = p->value.freq.freq / 1000000.0;
- else if (p->value.freq.freq > 1000.0)
- *value = p->value.freq.freq / 1000.0;
- else
- *value = p->value.freq.freq;
- }
- }
- return TRUE;
- } else
- return FALSE;
-}
-
-
-Bool
-xf86GetOptValBool(const OptionInfoRec *table, int token, Bool *value)
-{
- OptionInfoPtr p;
-
- p = xf86TokenToOptinfo(table, token);
- if (p && p->found) {
- *value = p->value.bool;
- return TRUE;
- } else
- return FALSE;
-}
-
-
-Bool
-xf86ReturnOptValBool(const OptionInfoRec *table, int token, Bool def)
-{
- OptionInfoPtr p;
-
- p = xf86TokenToOptinfo(table, token);
- if (p && p->found) {
- return p->value.bool;
- } else
- return def;
-}
-
-
-int
-xf86NameCmp(const char *s1, const char *s2)
-{
- return xf86nameCompare(s1, s2);
-}
-
-char *
-xf86NormalizeName(const char *s)
-{
- char *ret, *q;
- const char *p;
-
- if (s == NULL)
- return NULL;
-
- ret = xalloc(strlen(s) + 1);
- for (p = s, q = ret; *p != 0; p++) {
- switch (*p) {
- case '_':
- case ' ':
- case '\t':
- continue;
- default:
- if (isupper(*p))
- *q++ = tolower(*p);
- else
- *q++ = *p;
- }
- }
- *q = '\0';
- return ret;
-}
+/*
+ * Copyright (c) 1998-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ * Author: David Dawes <dawes@xfree86.org>
+ *
+ * This file includes public option handling functions.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <X11/X.h>
+#include "os.h"
+#include "xf86.h"
+#include "xf86Xinput.h"
+#include "xf86Optrec.h"
+#include "xf86Parser.h"
+
+static Bool ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p,
+ Bool markUsed);
+
+/*
+ * xf86CollectOptions collects the options from each of the config file
+ * sections used by the screen and puts the combined list in pScrn->options.
+ * This function requires that the following have been initialised:
+ *
+ * pScrn->confScreen
+ * pScrn->Entities[i]->device
+ * pScrn->display
+ * pScrn->monitor
+ *
+ * The extraOpts parameter may optionally contain a list of additional options
+ * to include.
+ *
+ * The order of precedence for options is:
+ *
+ * extraOpts, display, confScreen, monitor, device
+ */
+
+void
+xf86CollectOptions(ScrnInfoPtr pScrn, pointer extraOpts)
+{
+ XF86OptionPtr tmp;
+ XF86OptionPtr extras = (XF86OptionPtr)extraOpts;
+ GDevPtr device;
+
+ int i;
+
+ pScrn->options = NULL;
+
+ for (i=pScrn->numEntities - 1; i >= 0; i--) {
+ device = xf86GetDevFromEntity(pScrn->entityList[i],
+ pScrn->entityInstanceList[i]);
+ if (device && device->options) {
+ tmp = xf86optionListDup(device->options);
+ if (pScrn->options)
+ xf86optionListMerge(pScrn->options,tmp);
+ else
+ pScrn->options = tmp;
+ }
+ }
+ if (pScrn->monitor->options) {
+ tmp = xf86optionListDup(pScrn->monitor->options);
+ if (pScrn->options)
+ pScrn->options = xf86optionListMerge(pScrn->options, tmp);
+ else
+ pScrn->options = tmp;
+ }
+ if (pScrn->confScreen->options) {
+ tmp = xf86optionListDup(pScrn->confScreen->options);
+ if (pScrn->options)
+ pScrn->options = xf86optionListMerge(pScrn->options, tmp);
+ else
+ pScrn->options = tmp;
+ }
+ if (pScrn->display->options) {
+ tmp = xf86optionListDup(pScrn->display->options);
+ if (pScrn->options)
+ pScrn->options = xf86optionListMerge(pScrn->options, tmp);
+ else
+ pScrn->options = tmp;
+ }
+ if (extras) {
+ tmp = xf86optionListDup(extras);
+ if (pScrn->options)
+ pScrn->options = xf86optionListMerge(pScrn->options, tmp);
+ else
+ pScrn->options = tmp;
+ }
+}
+
+/*
+ * xf86CollectInputOptions collects the options for an InputDevice.
+ * This function requires that the following has been initialised:
+ *
+ * pInfo->conf_idev
+ *
+ * The extraOpts parameter may optionally contain a list of additional options
+ * to include.
+ *
+ * The order of precedence for options is:
+ *
+ * extraOpts, pInfo->conf_idev->extraOptions,
+ * pInfo->conf_idev->commonOptions, defaultOpts
+ */
+
+void
+xf86CollectInputOptions(InputInfoPtr pInfo, const char **defaultOpts,
+ pointer extraOpts)
+{
+ XF86OptionPtr tmp;
+ XF86OptionPtr extras = (XF86OptionPtr)extraOpts;
+
+ pInfo->options = NULL;
+ if (defaultOpts) {
+ pInfo->options = xf86OptionListCreate(defaultOpts, -1, 0);
+ }
+ if (pInfo->conf_idev && pInfo->conf_idev->commonOptions) {
+ tmp = xf86optionListDup(pInfo->conf_idev->commonOptions);
+ if (pInfo->options)
+ pInfo->options = xf86optionListMerge(pInfo->options, tmp);
+ else
+ pInfo->options = tmp;
+ }
+ if (pInfo->conf_idev && pInfo->conf_idev->extraOptions) {
+ tmp = xf86optionListDup(pInfo->conf_idev->extraOptions);
+ if (pInfo->options)
+ pInfo->options = xf86optionListMerge(pInfo->options, tmp);
+ else
+ pInfo->options = tmp;
+ }
+ if (extras) {
+ tmp = xf86optionListDup(extras);
+ if (pInfo->options)
+ pInfo->options = xf86optionListMerge(pInfo->options, tmp);
+ else
+ pInfo->options = tmp;
+ }
+}
+
+/* Created for new XInput stuff -- essentially extensions to the parser */
+
+static int
+LookupIntOption(pointer optlist, const char *name, int deflt, Bool markUsed)
+{
+ OptionInfoRec o;
+
+ o.name = name;
+ o.type = OPTV_INTEGER;
+ if (ParseOptionValue(-1, optlist, &o, markUsed))
+ deflt = o.value.num;
+ return deflt;
+}
+
+
+static double
+LookupRealOption(pointer optlist, const char *name, double deflt,
+ Bool markUsed)
+{
+ OptionInfoRec o;
+
+ o.name = name;
+ o.type = OPTV_REAL;
+ if (ParseOptionValue(-1, optlist, &o, markUsed))
+ deflt = o.value.realnum;
+ return deflt;
+}
+
+
+static char *
+LookupStrOption(pointer optlist, const char *name, char *deflt, Bool markUsed)
+{
+ OptionInfoRec o;
+
+ o.name = name;
+ o.type = OPTV_STRING;
+ if (ParseOptionValue(-1, optlist, &o, markUsed))
+ deflt = o.value.str;
+ if (deflt)
+ return xstrdup(deflt);
+ else
+ return NULL;
+}
+
+
+static int
+LookupBoolOption(pointer optlist, const char *name, int deflt, Bool markUsed)
+{
+ OptionInfoRec o;
+
+ o.name = name;
+ o.type = OPTV_BOOLEAN;
+ if (ParseOptionValue(-1, optlist, &o, markUsed))
+ deflt = o.value.bool;
+ return deflt;
+}
+
+/* These xf86Set* functions are intended for use by non-screen specific code */
+
+int
+xf86SetIntOption(pointer optlist, const char *name, int deflt)
+{
+ return LookupIntOption(optlist, name, deflt, TRUE);
+}
+
+
+double
+xf86SetRealOption(pointer optlist, const char *name, double deflt)
+{
+ return LookupRealOption(optlist, name, deflt, TRUE);
+}
+
+
+char *
+xf86SetStrOption(pointer optlist, const char *name, char *deflt)
+{
+ return LookupStrOption(optlist, name, deflt, TRUE);
+}
+
+
+int
+xf86SetBoolOption(pointer optlist, const char *name, int deflt)
+{
+ return LookupBoolOption(optlist, name, deflt, TRUE);
+}
+
+/*
+ * These are like the Set*Option functions, but they don't mark the options
+ * as used.
+ */
+int
+xf86CheckIntOption(pointer optlist, const char *name, int deflt)
+{
+ return LookupIntOption(optlist, name, deflt, FALSE);
+}
+
+
+double
+xf86CheckRealOption(pointer optlist, const char *name, double deflt)
+{
+ return LookupRealOption(optlist, name, deflt, FALSE);
+}
+
+
+char *
+xf86CheckStrOption(pointer optlist, const char *name, char *deflt)
+{
+ return LookupStrOption(optlist, name, deflt, FALSE);
+}
+
+
+int
+xf86CheckBoolOption(pointer optlist, const char *name, int deflt)
+{
+ return LookupBoolOption(optlist, name, deflt, FALSE);
+}
+
+/*
+ * addNewOption() has the required property of replacing the option value
+ * if the option is already present.
+ */
+pointer
+xf86ReplaceIntOption(pointer optlist, const char *name, const int val)
+{
+ char tmp[16];
+ sprintf(tmp,"%i",val);
+ return xf86AddNewOption(optlist,name,tmp);
+}
+
+pointer
+xf86ReplaceRealOption(pointer optlist, const char *name, const double val)
+{
+ char tmp[32];
+ snprintf(tmp,32,"%f",val);
+ return xf86AddNewOption(optlist,name,tmp);
+}
+
+pointer
+xf86ReplaceBoolOption(pointer optlist, const char *name, const Bool val)
+{
+ return xf86AddNewOption(optlist,name,val?"True":"False");
+}
+
+pointer
+xf86ReplaceStrOption(pointer optlist, const char *name, const char* val)
+{
+ return xf86AddNewOption(optlist,name,val);
+}
+
+pointer
+xf86AddNewOption(pointer head, const char *name, const char *val)
+{
+ /* XXX These should actually be allocated in the parser library. */
+ char *tmp = strdup(val);
+ char *tmp_name = strdup(name);
+
+ return xf86addNewOption(head, tmp_name, tmp);
+}
+
+
+pointer
+xf86NewOption(char *name, char *value)
+{
+ return xf86newOption(name, value);
+}
+
+
+pointer
+xf86NextOption(pointer list)
+{
+ return xf86nextOption(list);
+}
+
+pointer
+xf86OptionListCreate(const char **options, int count, int used)
+{
+ return xf86optionListCreate(options, count, used);
+}
+
+pointer
+xf86OptionListMerge(pointer head, pointer tail)
+{
+ return xf86optionListMerge(head, tail);
+}
+
+void
+xf86OptionListFree(pointer opt)
+{
+ xf86optionListFree(opt);
+}
+
+char *
+xf86OptionName(pointer opt)
+{
+ return xf86optionName(opt);
+}
+
+char *
+xf86OptionValue(pointer opt)
+{
+ return xf86optionValue(opt);
+}
+
+void
+xf86OptionListReport(pointer parm)
+{
+ XF86OptionPtr opts = parm;
+
+ while(opts) {
+ if (xf86optionValue(opts))
+ xf86ErrorFVerb(5, "\tOption \"%s\" \"%s\"\n",
+ xf86optionName(opts), xf86optionValue(opts));
+ else
+ xf86ErrorFVerb( 5, "\tOption \"%s\"\n", xf86optionName(opts));
+ opts = xf86nextOption(opts);
+ }
+}
+
+/* End of XInput-caused section */
+
+pointer
+xf86FindOption(pointer options, const char *name)
+{
+ return xf86findOption(options, name);
+}
+
+
+char *
+xf86FindOptionValue(pointer options, const char *name)
+{
+ return xf86findOptionValue(options, name);
+}
+
+
+void
+xf86MarkOptionUsed(pointer option)
+{
+ if (option != NULL)
+ ((XF86OptionPtr)option)->opt_used = TRUE;
+}
+
+
+void
+xf86MarkOptionUsedByName(pointer options, const char *name)
+{
+ XF86OptionPtr opt;
+
+ opt = xf86findOption(options, name);
+ if (opt != NULL)
+ opt->opt_used = TRUE;
+}
+
+Bool
+xf86CheckIfOptionUsed(pointer option)
+{
+ if (option != NULL)
+ return ((XF86OptionPtr)option)->opt_used;
+ else
+ return FALSE;
+}
+
+Bool
+xf86CheckIfOptionUsedByName(pointer options, const char *name)
+{
+ XF86OptionPtr opt;
+
+ opt = xf86findOption(options, name);
+ if (opt != NULL)
+ return opt->opt_used;
+ else
+ return FALSE;
+}
+
+void
+xf86ShowUnusedOptions(int scrnIndex, pointer options)
+{
+ XF86OptionPtr opt = options;
+
+ while (opt) {
+ if (opt->opt_name && !opt->opt_used) {
+ xf86DrvMsg(scrnIndex, X_WARNING, "Option \"%s\" is not used\n",
+ opt->opt_name);
+ }
+ opt = opt->list.next;
+ }
+}
+
+
+static Bool
+GetBoolValue(OptionInfoPtr p, const char *s)
+{
+ return xf86getBoolValue(&p->value.bool, s);
+}
+
+static Bool
+ParseOptionValue(int scrnIndex, pointer options, OptionInfoPtr p,
+ Bool markUsed)
+{
+ char *s, *end;
+ Bool wasUsed = FALSE;
+
+ if ((s = xf86findOptionValue(options, p->name)) != NULL) {
+ if (markUsed) {
+ wasUsed = xf86CheckIfOptionUsedByName(options, p->name);
+ xf86MarkOptionUsedByName(options, p->name);
+ }
+ switch (p->type) {
+ case OPTV_INTEGER:
+ if (*s == '\0') {
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Option \"%s\" requires an integer value\n",
+ p->name);
+ p->found = FALSE;
+ } else {
+ p->value.num = strtoul(s, &end, 0);
+ if (*end == '\0') {
+ p->found = TRUE;
+ } else {
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Option \"%s\" requires an integer value\n",
+ p->name);
+ p->found = FALSE;
+ }
+ }
+ break;
+ case OPTV_STRING:
+ if (*s == '\0') {
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Option \"%s\" requires an string value\n",
+ p->name);
+ p->found = FALSE;
+ } else {
+ p->value.str = s;
+ p->found = TRUE;
+ }
+ break;
+ case OPTV_ANYSTR:
+ p->value.str = s;
+ p->found = TRUE;
+ break;
+ case OPTV_REAL:
+ if (*s == '\0') {
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Option \"%s\" requires a floating point value\n",
+ p->name);
+ p->found = FALSE;
+ } else {
+ p->value.realnum = strtod(s, &end);
+ if (*end == '\0') {
+ p->found = TRUE;
+ } else {
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Option \"%s\" requires a floating point value\n",
+ p->name);
+ p->found = FALSE;
+ }
+ }
+ break;
+ case OPTV_BOOLEAN:
+ if (GetBoolValue(p, s)) {
+ p->found = TRUE;
+ } else {
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Option \"%s\" requires a boolean value\n", p->name);
+ p->found = FALSE;
+ }
+ break;
+ case OPTV_FREQ:
+ if (*s == '\0') {
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Option \"%s\" requires a frequency value\n",
+ p->name);
+ p->found = FALSE;
+ } else {
+ double freq = strtod(s, &end);
+ int units = 0;
+
+ if (end != s) {
+ p->found = TRUE;
+ if (!xf86NameCmp(end, "Hz"))
+ units = 1;
+ else if (!xf86NameCmp(end, "kHz") ||
+ !xf86NameCmp(end, "k"))
+ units = 1000;
+ else if (!xf86NameCmp(end, "MHz") ||
+ !xf86NameCmp(end, "M"))
+ units = 1000000;
+ else {
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Option \"%s\" requires a frequency value\n",
+ p->name);
+ p->found = FALSE;
+ }
+ if (p->found)
+ freq *= (double)units;
+ } else {
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Option \"%s\" requires a frequency value\n",
+ p->name);
+ p->found = FALSE;
+ }
+ if (p->found) {
+ p->value.freq.freq = freq;
+ p->value.freq.units = units;
+ }
+ }
+ break;
+ case OPTV_NONE:
+ /* Should never get here */
+ p->found = FALSE;
+ break;
+ }
+ if (p->found && markUsed) {
+ int verb = 2;
+ if (wasUsed)
+ verb = 4;
+ xf86DrvMsgVerb(scrnIndex, X_CONFIG, verb, "Option \"%s\"", p->name);
+ if (!(p->type == OPTV_BOOLEAN && *s == 0)) {
+ xf86ErrorFVerb(verb, " \"%s\"", s);
+ }
+ xf86ErrorFVerb(verb, "\n");
+ }
+ } else if (p->type == OPTV_BOOLEAN) {
+ /* Look for matches with options with or without a "No" prefix. */
+ char *n, *newn;
+ OptionInfoRec opt;
+
+ n = xf86NormalizeName(p->name);
+ if (!n) {
+ p->found = FALSE;
+ return FALSE;
+ }
+ if (strncmp(n, "no", 2) == 0) {
+ newn = n + 2;
+ } else {
+ free(n);
+ n = malloc(strlen(p->name) + 2 + 1);
+ if (!n) {
+ p->found = FALSE;
+ return FALSE;
+ }
+ strcpy(n, "No");
+ strcat(n, p->name);
+ newn = n;
+ }
+ if ((s = xf86findOptionValue(options, newn)) != NULL) {
+ if (markUsed)
+ xf86MarkOptionUsedByName(options, newn);
+ if (GetBoolValue(&opt, s)) {
+ p->value.bool = !opt.value.bool;
+ p->found = TRUE;
+ } else {
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Option \"%s\" requires a boolean value\n", newn);
+ p->found = FALSE;
+ }
+ } else {
+ p->found = FALSE;
+ }
+ if (p->found && markUsed) {
+ xf86DrvMsgVerb(scrnIndex, X_CONFIG, 2, "Option \"%s\"", newn);
+ if (*s != 0) {
+ xf86ErrorFVerb(2, " \"%s\"", s);
+ }
+ xf86ErrorFVerb(2, "\n");
+ }
+ free(n);
+ } else {
+ p->found = FALSE;
+ }
+ return p->found;
+}
+
+
+void
+xf86ProcessOptions(int scrnIndex, pointer options, OptionInfoPtr optinfo)
+{
+ OptionInfoPtr p;
+
+ for (p = optinfo; p->name != NULL; p++) {
+ ParseOptionValue(scrnIndex, options, p, TRUE);
+ }
+}
+
+
+OptionInfoPtr
+xf86TokenToOptinfo(const OptionInfoRec *table, int token)
+{
+ const OptionInfoRec *p, *match = NULL, *set = NULL;
+
+ if (!table) {
+ ErrorF("xf86TokenToOptinfo: table is NULL\n");
+ return NULL;
+ }
+
+ for (p = table; p->token >= 0; p++) {
+ if (p->token == token) {
+ match = p;
+ if (p->found)
+ set = p;
+ }
+ }
+
+ if (set)
+ return (OptionInfoPtr)set;
+ else if (match)
+ return (OptionInfoPtr)match;
+ else
+ return NULL;
+}
+
+
+const char *
+xf86TokenToOptName(const OptionInfoRec *table, int token)
+{
+ const OptionInfoRec *p;
+
+ p = xf86TokenToOptinfo(table, token);
+ return p->name;
+}
+
+
+Bool
+xf86IsOptionSet(const OptionInfoRec *table, int token)
+{
+ OptionInfoPtr p;
+
+ p = xf86TokenToOptinfo(table, token);
+ return (p && p->found);
+}
+
+
+char *
+xf86GetOptValString(const OptionInfoRec *table, int token)
+{
+ OptionInfoPtr p;
+
+ p = xf86TokenToOptinfo(table, token);
+ if (p && p->found)
+ return p->value.str;
+ else
+ return NULL;
+}
+
+
+Bool
+xf86GetOptValInteger(const OptionInfoRec *table, int token, int *value)
+{
+ OptionInfoPtr p;
+
+ p = xf86TokenToOptinfo(table, token);
+ if (p && p->found) {
+ *value = p->value.num;
+ return TRUE;
+ } else
+ return FALSE;
+}
+
+
+Bool
+xf86GetOptValULong(const OptionInfoRec *table, int token, unsigned long *value)
+{
+ OptionInfoPtr p;
+
+ p = xf86TokenToOptinfo(table, token);
+ if (p && p->found) {
+ *value = p->value.num;
+ return TRUE;
+ } else
+ return FALSE;
+}
+
+
+Bool
+xf86GetOptValReal(const OptionInfoRec *table, int token, double *value)
+{
+ OptionInfoPtr p;
+
+ p = xf86TokenToOptinfo(table, token);
+ if (p && p->found) {
+ *value = p->value.realnum;
+ return TRUE;
+ } else
+ return FALSE;
+}
+
+
+Bool
+xf86GetOptValFreq(const OptionInfoRec *table, int token,
+ OptFreqUnits expectedUnits, double *value)
+{
+ OptionInfoPtr p;
+
+ p = xf86TokenToOptinfo(table, token);
+ if (p && p->found) {
+ if (p->value.freq.units > 0) {
+ /* Units give, so the scaling is known. */
+ switch (expectedUnits) {
+ case OPTUNITS_HZ:
+ *value = p->value.freq.freq;
+ break;
+ case OPTUNITS_KHZ:
+ *value = p->value.freq.freq / 1000.0;
+ break;
+ case OPTUNITS_MHZ:
+ *value = p->value.freq.freq / 1000000.0;
+ break;
+ }
+ } else {
+ /* No units given, so try to guess the scaling. */
+ switch (expectedUnits) {
+ case OPTUNITS_HZ:
+ *value = p->value.freq.freq;
+ break;
+ case OPTUNITS_KHZ:
+ if (p->value.freq.freq > 1000.0)
+ *value = p->value.freq.freq / 1000.0;
+ else
+ *value = p->value.freq.freq;
+ break;
+ case OPTUNITS_MHZ:
+ if (p->value.freq.freq > 1000000.0)
+ *value = p->value.freq.freq / 1000000.0;
+ else if (p->value.freq.freq > 1000.0)
+ *value = p->value.freq.freq / 1000.0;
+ else
+ *value = p->value.freq.freq;
+ }
+ }
+ return TRUE;
+ } else
+ return FALSE;
+}
+
+
+Bool
+xf86GetOptValBool(const OptionInfoRec *table, int token, Bool *value)
+{
+ OptionInfoPtr p;
+
+ p = xf86TokenToOptinfo(table, token);
+ if (p && p->found) {
+ *value = p->value.bool;
+ return TRUE;
+ } else
+ return FALSE;
+}
+
+
+Bool
+xf86ReturnOptValBool(const OptionInfoRec *table, int token, Bool def)
+{
+ OptionInfoPtr p;
+
+ p = xf86TokenToOptinfo(table, token);
+ if (p && p->found) {
+ return p->value.bool;
+ } else
+ return def;
+}
+
+
+int
+xf86NameCmp(const char *s1, const char *s2)
+{
+ return xf86nameCompare(s1, s2);
+}
+
+char *
+xf86NormalizeName(const char *s)
+{
+ char *ret, *q;
+ const char *p;
+
+ if (s == NULL)
+ return NULL;
+
+ ret = malloc(strlen(s) + 1);
+ for (p = s, q = ret; *p != 0; p++) {
+ switch (*p) {
+ case '_':
+ case ' ':
+ case '\t':
+ continue;
+ default:
+ if (isupper(*p))
+ *q++ = tolower(*p);
+ else
+ *q++ = *p;
+ }
+ }
+ *q = '\0';
+ return ret;
+}
diff --git a/xorg-server/hw/xfree86/common/xf86Privstr.h b/xorg-server/hw/xfree86/common/xf86Privstr.h
index b2095aab1..6138b6bec 100644
--- a/xorg-server/hw/xfree86/common/xf86Privstr.h
+++ b/xorg-server/hw/xfree86/common/xf86Privstr.h
@@ -1,173 +1,170 @@
-
-/*
- * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-/*
- * This file contains definitions of the private XFree86 data structures/types.
- * None of the data structures here should be used by video drivers.
- */
-
-#ifndef _XF86PRIVSTR_H
-#define _XF86PRIVSTR_H
-
-#include "xf86str.h"
-
-typedef enum {
- LogNone,
- LogFlush,
- LogSync
-} Log;
-
-typedef enum {
- XF86_GlxVisualsMinimal,
- XF86_GlxVisualsTypical,
- XF86_GlxVisualsAll,
-} XF86_GlxVisuals;
-
-/*
- * xf86InfoRec contains global parameters which the video drivers never
- * need to access. Global parameters which the video drivers do need
- * should be individual globals.
- */
-
-typedef struct {
- int consoleFd;
- int vtno;
- Bool vtSysreq;
-
- /* event handler part */
- int lastEventTime;
- Bool vtRequestsPending;
-#ifdef sun
- int vtPendingNum;
-#endif
- Bool dontVTSwitch;
- Bool dontZap;
- Bool dontZoom;
- Bool notrapSignals; /* don't exit cleanly - die at fault */
- Bool caughtSignal;
-
- /* graphics part */
- ScreenPtr currentScreen;
-#if defined(CSRG_BASED) || defined(__FreeBSD_kernel__)
- int screenFd; /* fd for memory mapped access to
- * vga card */
- int consType; /* Which console driver? */
-#endif
-
- /* Other things */
- Bool allowMouseOpenFail;
- Bool vidModeEnabled; /* VidMode extension enabled */
- Bool vidModeAllowNonLocal; /* allow non-local VidMode
- * connections */
- Bool miscModInDevEnabled; /* Allow input devices to be
- * changed */
- Bool miscModInDevAllowNonLocal;
- Bool useSIGIO; /* Use SIGIO for handling
- input device events */
- Pix24Flags pixmap24;
- MessageType pix24From;
-#ifdef SUPPORT_PC98
- Bool pc98;
-#endif
- Bool pmFlag;
- Log log;
- Bool kbdCustomKeycodes;
- Bool disableRandR;
- MessageType randRFrom;
- Bool aiglx;
- MessageType aiglxFrom;
- XF86_GlxVisuals glxVisuals;
- MessageType glxVisualsFrom;
-
- Bool useDefaultFontPath;
- MessageType useDefaultFontPathFrom;
- Bool ignoreABI;
-
- Bool allowEmptyInput; /* Allow the server to start with no input
- * devices. */
- Bool autoAddDevices; /* Whether to succeed NIDR, or ignore. */
- Bool autoEnableDevices; /* Whether to enable, or let the client
- * control. */
-
- Bool dri2;
- MessageType dri2From;
-} xf86InfoRec, *xf86InfoPtr;
-
-#ifdef DPMSExtension
-/* Private info for DPMS */
-typedef struct {
- CloseScreenProcPtr CloseScreen;
- Bool Enabled;
- int Flags;
-} DPMSRec, *DPMSPtr;
-#endif
-
-#ifdef XF86VIDMODE
-/* Private info for Video Mode Extentsion */
-typedef struct {
- DisplayModePtr First;
- DisplayModePtr Next;
- int Flags;
- CloseScreenProcPtr CloseScreen;
-} VidModeRec, *VidModePtr;
-#endif
-
-/* Information for root window properties. */
-typedef struct _RootWinProp {
- struct _RootWinProp * next;
- char * name;
- Atom type;
- short format;
- long size;
- pointer data;
-} RootWinProp, *RootWinPropPtr;
-
-/* private resource types */
-#define ResNoAvoid ResBios
-
-/* ISC's cc can't handle ~ of UL constants, so explicitly type cast them. */
-#define XLED1 ((unsigned long) 0x00000001)
-#define XLED2 ((unsigned long) 0x00000002)
-#define XLED3 ((unsigned long) 0x00000004)
-#define XLED4 ((unsigned long) 0x00000008)
-#define XCAPS ((unsigned long) 0x20000000)
-#define XNUM ((unsigned long) 0x40000000)
-#define XSCR ((unsigned long) 0x80000000)
-#define XCOMP ((unsigned long) 0x00008000)
-
-/* BSD console driver types (consType) */
-#if defined(CSRG_BASED) || defined(__FreeBSD_kernel__)
-#define PCCONS 0
-#define CODRV011 1
-#define CODRV01X 2
-#define SYSCONS 8
-#define PCVT 16
-#define WSCONS 32
-#endif
-
-#endif /* _XF86PRIVSTR_H */
+
+/*
+ * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ * This file contains definitions of the private XFree86 data structures/types.
+ * None of the data structures here should be used by video drivers.
+ */
+
+#ifndef _XF86PRIVSTR_H
+#define _XF86PRIVSTR_H
+
+#include "xf86str.h"
+
+typedef enum {
+ LogNone,
+ LogFlush,
+ LogSync
+} Log;
+
+typedef enum {
+ XF86_GlxVisualsMinimal,
+ XF86_GlxVisualsTypical,
+ XF86_GlxVisualsAll,
+} XF86_GlxVisuals;
+
+/*
+ * xf86InfoRec contains global parameters which the video drivers never
+ * need to access. Global parameters which the video drivers do need
+ * should be individual globals.
+ */
+
+typedef struct {
+ int consoleFd;
+ int vtno;
+ Bool vtSysreq;
+
+ /* event handler part */
+ int lastEventTime;
+ Bool vtRequestsPending;
+#ifdef sun
+ int vtPendingNum;
+#endif
+ Bool dontVTSwitch;
+ Bool dontZap;
+ Bool dontZoom;
+ Bool notrapSignals; /* don't exit cleanly - die at fault */
+ Bool caughtSignal;
+
+ /* graphics part */
+ ScreenPtr currentScreen;
+#if defined(CSRG_BASED) || defined(__FreeBSD_kernel__)
+ int screenFd; /* fd for memory mapped access to
+ * vga card */
+ int consType; /* Which console driver? */
+#endif
+
+ /* Other things */
+ Bool allowMouseOpenFail;
+ Bool vidModeEnabled; /* VidMode extension enabled */
+ Bool vidModeAllowNonLocal; /* allow non-local VidMode
+ * connections */
+ Bool miscModInDevEnabled; /* Allow input devices to be
+ * changed */
+ Bool miscModInDevAllowNonLocal;
+ Bool useSIGIO; /* Use SIGIO for handling
+ input device events */
+ Pix24Flags pixmap24;
+ MessageType pix24From;
+#ifdef SUPPORT_PC98
+ Bool pc98;
+#endif
+ Bool pmFlag;
+ Log log;
+ Bool kbdCustomKeycodes;
+ Bool disableRandR;
+ MessageType randRFrom;
+ Bool aiglx;
+ MessageType aiglxFrom;
+ XF86_GlxVisuals glxVisuals;
+ MessageType glxVisualsFrom;
+
+ Bool useDefaultFontPath;
+ MessageType useDefaultFontPathFrom;
+ Bool ignoreABI;
+
+ Bool allowEmptyInput; /* Allow the server to start with no input
+ * devices. */
+ Bool autoAddDevices; /* Whether to succeed NIDR, or ignore. */
+ Bool autoEnableDevices; /* Whether to enable, or let the client
+ * control. */
+
+ Bool dri2;
+ MessageType dri2From;
+} xf86InfoRec, *xf86InfoPtr;
+
+#ifdef DPMSExtension
+/* Private info for DPMS */
+typedef struct {
+ CloseScreenProcPtr CloseScreen;
+ Bool Enabled;
+ int Flags;
+} DPMSRec, *DPMSPtr;
+#endif
+
+#ifdef XF86VIDMODE
+/* Private info for Video Mode Extentsion */
+typedef struct {
+ DisplayModePtr First;
+ DisplayModePtr Next;
+ int Flags;
+ CloseScreenProcPtr CloseScreen;
+} VidModeRec, *VidModePtr;
+#endif
+
+/* Information for root window properties. */
+typedef struct _RootWinProp {
+ struct _RootWinProp * next;
+ char * name;
+ Atom type;
+ short format;
+ long size;
+ pointer data;
+} RootWinProp, *RootWinPropPtr;
+
+/* ISC's cc can't handle ~ of UL constants, so explicitly type cast them. */
+#define XLED1 ((unsigned long) 0x00000001)
+#define XLED2 ((unsigned long) 0x00000002)
+#define XLED3 ((unsigned long) 0x00000004)
+#define XLED4 ((unsigned long) 0x00000008)
+#define XCAPS ((unsigned long) 0x20000000)
+#define XNUM ((unsigned long) 0x40000000)
+#define XSCR ((unsigned long) 0x80000000)
+#define XCOMP ((unsigned long) 0x00008000)
+
+/* BSD console driver types (consType) */
+#if defined(CSRG_BASED) || defined(__FreeBSD_kernel__)
+#define PCCONS 0
+#define CODRV011 1
+#define CODRV01X 2
+#define SYSCONS 8
+#define PCVT 16
+#define WSCONS 32
+#endif
+
+#endif /* _XF86PRIVSTR_H */
diff --git a/xorg-server/hw/xfree86/common/xf86RandR.c b/xorg-server/hw/xfree86/common/xf86RandR.c
index 86c7bde79..1893974e2 100644
--- a/xorg-server/hw/xfree86/common/xf86RandR.c
+++ b/xorg-server/hw/xfree86/common/xf86RandR.c
@@ -1,459 +1,459 @@
-/*
- *
- * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <X11/X.h>
-#include "os.h"
-#include "globals.h"
-#include "xf86.h"
-#include "xf86str.h"
-#include "xf86Priv.h"
-#include "xf86DDC.h"
-#include "mipointer.h"
-#include <randrstr.h>
-#include "inputstr.h"
-
-typedef struct _xf86RandRInfo {
- CreateScreenResourcesProcPtr CreateScreenResources;
- CloseScreenProcPtr CloseScreen;
- int virtualX;
- int virtualY;
- int mmWidth;
- int mmHeight;
- Rotation rotation;
-} XF86RandRInfoRec, *XF86RandRInfoPtr;
-
-static int xf86RandRKeyIndex;
-static DevPrivateKey xf86RandRKey;
-
-#define XF86RANDRINFO(p) ((XF86RandRInfoPtr)dixLookupPrivate(&(p)->devPrivates, xf86RandRKey))
-
-static int
-xf86RandRModeRefresh (DisplayModePtr mode)
-{
- if (mode->VRefresh)
- return (int) (mode->VRefresh + 0.5);
- else if (mode->Clock == 0)
- return 0;
- else
- return (int) (mode->Clock * 1000.0 / mode->HTotal / mode->VTotal + 0.5);
-}
-
-static Bool
-xf86RandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
-{
- RRScreenSizePtr pSize;
- ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- DisplayModePtr mode;
- int refresh0 = 60;
- xorgRRModeMM RRModeMM;
-
- *rotations = RR_Rotate_0;
-
- for (mode = scrp->modes; mode != NULL ; mode = mode->next)
- {
- int refresh = xf86RandRModeRefresh (mode);
-
- if (mode == scrp->modes)
- refresh0 = refresh;
-
- RRModeMM.mode = mode;
- RRModeMM.virtX = randrp->virtualX;
- RRModeMM.virtY = randrp->virtualY;
- RRModeMM.mmWidth = randrp->mmWidth;
- RRModeMM.mmHeight = randrp->mmHeight;
-
- if(scrp->DriverFunc) {
- (*scrp->DriverFunc)(scrp, RR_GET_MODE_MM, &RRModeMM);
- }
-
- pSize = RRRegisterSize (pScreen,
- mode->HDisplay, mode->VDisplay,
- RRModeMM.mmWidth, RRModeMM.mmHeight);
- if (!pSize)
- return FALSE;
- RRRegisterRate (pScreen, pSize, refresh);
- if (mode == scrp->currentMode &&
- mode->HDisplay == scrp->virtualX && mode->VDisplay == scrp->virtualY)
- RRSetCurrentConfig (pScreen, randrp->rotation, refresh, pSize);
- if (mode->next == scrp->modes)
- break;
- }
- if (scrp->currentMode->HDisplay != randrp->virtualX ||
- scrp->currentMode->VDisplay != randrp->virtualY)
- {
- mode = scrp->modes;
-
- RRModeMM.mode = NULL;
- RRModeMM.virtX = randrp->virtualX;
- RRModeMM.virtY = randrp->virtualY;
- RRModeMM.mmWidth = randrp->mmWidth;
- RRModeMM.mmHeight = randrp->mmHeight;
-
- if(scrp->DriverFunc) {
- (*scrp->DriverFunc)(scrp, RR_GET_MODE_MM, &RRModeMM);
- }
-
- pSize = RRRegisterSize (pScreen,
- randrp->virtualX, randrp->virtualY,
- RRModeMM.mmWidth, RRModeMM.mmHeight);
- if (!pSize)
- return FALSE;
- RRRegisterRate (pScreen, pSize, refresh0);
- if (scrp->virtualX == randrp->virtualX &&
- scrp->virtualY == randrp->virtualY)
- {
- RRSetCurrentConfig (pScreen, randrp->rotation, refresh0, pSize);
- }
- }
-
- /* If there is driver support for randr, let it set our supported rotations */
- if(scrp->DriverFunc) {
- xorgRRRotation RRRotation;
-
- RRRotation.RRRotations = *rotations;
- if (!(*scrp->DriverFunc)(scrp, RR_GET_INFO, &RRRotation))
- return TRUE;
- *rotations = RRRotation.RRRotations;
- }
-
- return TRUE;
-}
-
-static Bool
-xf86RandRSetMode (ScreenPtr pScreen,
- DisplayModePtr mode,
- Bool useVirtual,
- int mmWidth,
- int mmHeight)
-{
- ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- int oldWidth = pScreen->width;
- int oldHeight = pScreen->height;
- int oldmmWidth = pScreen->mmWidth;
- int oldmmHeight = pScreen->mmHeight;
- int oldVirtualX = scrp->virtualX;
- int oldVirtualY = scrp->virtualY;
- WindowPtr pRoot = WindowTable[pScreen->myNum];
- Bool ret = TRUE;
-
- if (pRoot && scrp->vtSema)
- (*scrp->EnableDisableFBAccess) (pScreen->myNum, FALSE);
- if (useVirtual)
- {
- scrp->virtualX = randrp->virtualX;
- scrp->virtualY = randrp->virtualY;
- }
- else
- {
- scrp->virtualX = mode->HDisplay;
- scrp->virtualY = mode->VDisplay;
- }
-
- /*
- * The DIX forgets the physical dimensions we passed into RRRegisterSize, so
- * reconstruct them if possible.
- */
- if(scrp->DriverFunc) {
- xorgRRModeMM RRModeMM;
-
- RRModeMM.mode = mode;
- RRModeMM.virtX = scrp->virtualX;
- RRModeMM.virtY = scrp->virtualY;
- RRModeMM.mmWidth = mmWidth;
- RRModeMM.mmHeight = mmHeight;
-
- (*scrp->DriverFunc)(scrp, RR_GET_MODE_MM, &RRModeMM);
-
- mmWidth = RRModeMM.mmWidth;
- mmHeight = RRModeMM.mmHeight;
- }
- if(randrp->rotation & (RR_Rotate_90 | RR_Rotate_270))
- {
- /* If the screen is rotated 90 or 270 degrees, swap the sizes. */
- pScreen->width = scrp->virtualY;
- pScreen->height = scrp->virtualX;
- pScreen->mmWidth = mmHeight;
- pScreen->mmHeight = mmWidth;
- }
- else
- {
- pScreen->width = scrp->virtualX;
- pScreen->height = scrp->virtualY;
- pScreen->mmWidth = mmWidth;
- pScreen->mmHeight = mmHeight;
- }
- if (!xf86SwitchMode (pScreen, mode))
- {
- pScreen->width = oldWidth;
- pScreen->height = oldHeight;
- pScreen->mmWidth = oldmmWidth;
- pScreen->mmHeight = oldmmHeight;
- scrp->virtualX = oldVirtualX;
- scrp->virtualY = oldVirtualY;
- ret = FALSE;
- }
- /*
- * Make sure the layout is correct
- */
- xf86ReconfigureLayout();
-
- /*
- * Make sure the whole screen is visible
- */
- xf86SetViewport (pScreen, pScreen->width, pScreen->height);
- xf86SetViewport (pScreen, 0, 0);
- if (pRoot && scrp->vtSema)
- (*scrp->EnableDisableFBAccess) (pScreen->myNum, TRUE);
- return ret;
-}
-
-static Bool
-xf86RandRSetConfig (ScreenPtr pScreen,
- Rotation rotation,
- int rate,
- RRScreenSizePtr pSize)
-{
- ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- DisplayModePtr mode;
- int px, py;
- Bool useVirtual = FALSE;
- Rotation oldRotation = randrp->rotation;
-
- miPointerGetPosition(inputInfo.pointer, &px, &py);
- for (mode = scrp->modes; ; mode = mode->next)
- {
- if (mode->HDisplay == pSize->width &&
- mode->VDisplay == pSize->height &&
- (rate == 0 || xf86RandRModeRefresh (mode) == rate))
- break;
- if (mode->next == scrp->modes)
- {
- if (pSize->width == randrp->virtualX &&
- pSize->height == randrp->virtualY)
- {
- mode = scrp->modes;
- useVirtual = TRUE;
- break;
- }
- return FALSE;
- }
- }
-
- if (randrp->rotation != rotation) {
-
- /* Have the driver do its thing. */
- if (scrp->DriverFunc) {
- xorgRRRotation RRRotation;
- RRRotation.RRConfig.rotation = rotation;
- RRRotation.RRConfig.rate = rate;
- RRRotation.RRConfig.width = pSize->width;
- RRRotation.RRConfig.height = pSize->height;
-
- /*
- * Currently we need to rely on HW support for rotation.
- */
- if (!(*scrp->DriverFunc)(scrp, RR_SET_CONFIG, &RRRotation))
- return FALSE;
- } else
- return FALSE;
-
- randrp->rotation = rotation;
- }
-
- if (!xf86RandRSetMode (pScreen, mode, useVirtual, pSize->mmWidth, pSize->mmHeight)) {
- if(randrp->rotation != oldRotation) {
- /* Have the driver undo its thing. */
- if (scrp->DriverFunc) {
- xorgRRRotation RRRotation;
- RRRotation.RRConfig.rotation = oldRotation;
- RRRotation.RRConfig.rate = xf86RandRModeRefresh (scrp->currentMode);
- RRRotation.RRConfig.width = scrp->virtualX;
- RRRotation.RRConfig.height = scrp->virtualY;
- (*scrp->DriverFunc)(scrp, RR_SET_CONFIG, &RRRotation);
- }
-
- randrp->rotation = oldRotation;
- }
- return FALSE;
- }
- /*
- * Move the cursor back where it belongs; SwitchMode repositions it
- */
- if (pScreen == miPointerCurrentScreen ())
- {
- px = (px >= pScreen->width ? (pScreen->width - 1) : px);
- py = (py >= pScreen->height ? (pScreen->height - 1) : py);
-
- xf86SetViewport(pScreen, px, py);
-
- (*pScreen->SetCursorPosition) (inputInfo.pointer, pScreen, px, py, FALSE);
- }
-
- return TRUE;
-}
-
-/*
- * Wait until the screen is initialized before whacking the
- * sizes around; otherwise the screen pixmap will be allocated
- * at the current mode size rather than the maximum size
- */
-static Bool
-xf86RandRCreateScreenResources (ScreenPtr pScreen)
-{
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
-#if 0
- ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
- DisplayModePtr mode;
-#endif
-
- pScreen->CreateScreenResources = randrp->CreateScreenResources;
- if (!(*pScreen->CreateScreenResources) (pScreen))
- return FALSE;
-
-#if 0
- mode = scrp->currentMode;
- if (mode)
- xf86RandRSetMode (pScreen, mode, TRUE);
-#endif
-
- return TRUE;
-}
-
-/*
- * Reset size back to original
- */
-static Bool
-xf86RandRCloseScreen (int index, ScreenPtr pScreen)
-{
- ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
-
- scrp->virtualX = pScreen->width = randrp->virtualX;
- scrp->virtualY = pScreen->height = randrp->virtualY;
- scrp->currentMode = scrp->modes;
- pScreen->CloseScreen = randrp->CloseScreen;
- xfree (randrp);
- dixSetPrivate(&pScreen->devPrivates, xf86RandRKey, NULL);
- return (*pScreen->CloseScreen) (index, pScreen);
-}
-
-Rotation
-xf86GetRotation(ScreenPtr pScreen)
-{
- if (xf86RandRKey == NULL)
- return RR_Rotate_0;
-
- return XF86RANDRINFO(pScreen)->rotation;
-}
-
-/* Function to change RandR's idea of the virtual screen size */
-Bool
-xf86RandRSetNewVirtualAndDimensions(ScreenPtr pScreen,
- int newvirtX, int newvirtY, int newmmWidth, int newmmHeight,
- Bool resetMode)
-{
- XF86RandRInfoPtr randrp;
-
- if (xf86RandRKey == NULL)
- return FALSE;
-
- randrp = XF86RANDRINFO(pScreen);
- if (randrp == NULL)
- return FALSE;
-
- if (newvirtX > 0)
- randrp->virtualX = newvirtX;
-
- if (newvirtY > 0)
- randrp->virtualY = newvirtY;
-
- if (newmmWidth > 0)
- randrp->mmWidth = newmmWidth;
-
- if (newmmHeight > 0)
- randrp->mmHeight = newmmHeight;
-
- /* This is only for during server start */
- if (resetMode) {
- return (xf86RandRSetMode(pScreen,
- XF86SCRNINFO(pScreen)->currentMode,
- TRUE,
- pScreen->mmWidth, pScreen->mmHeight));
- }
-
- return TRUE;
-}
-
-Bool
-xf86RandRInit (ScreenPtr pScreen)
-{
- rrScrPrivPtr rp;
- XF86RandRInfoPtr randrp;
- ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
-
-#ifdef PANORAMIX
- /* XXX disable RandR when using Xinerama */
- if (!noPanoramiXExtension)
- return TRUE;
-#endif
-
- xf86RandRKey = &xf86RandRKeyIndex;
-
- randrp = xalloc (sizeof (XF86RandRInfoRec));
- if (!randrp)
- return FALSE;
-
- if (!RRScreenInit (pScreen))
- {
- xfree (randrp);
- return FALSE;
- }
- rp = rrGetScrPriv(pScreen);
- rp->rrGetInfo = xf86RandRGetInfo;
- rp->rrSetConfig = xf86RandRSetConfig;
-
- randrp->virtualX = scrp->virtualX;
- randrp->virtualY = scrp->virtualY;
- randrp->mmWidth = pScreen->mmWidth;
- randrp->mmHeight = pScreen->mmHeight;
-
- randrp->CreateScreenResources = pScreen->CreateScreenResources;
- pScreen->CreateScreenResources = xf86RandRCreateScreenResources;
-
- randrp->CloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = xf86RandRCloseScreen;
-
- randrp->rotation = RR_Rotate_0;
-
- dixSetPrivate(&pScreen->devPrivates, xf86RandRKey, randrp);
- return TRUE;
-}
-
-
+/*
+ *
+ * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <X11/X.h>
+#include "os.h"
+#include "globals.h"
+#include "xf86.h"
+#include "xf86str.h"
+#include "xf86Priv.h"
+#include "xf86DDC.h"
+#include "mipointer.h"
+#include <randrstr.h>
+#include "inputstr.h"
+
+typedef struct _xf86RandRInfo {
+ CreateScreenResourcesProcPtr CreateScreenResources;
+ CloseScreenProcPtr CloseScreen;
+ int virtualX;
+ int virtualY;
+ int mmWidth;
+ int mmHeight;
+ Rotation rotation;
+} XF86RandRInfoRec, *XF86RandRInfoPtr;
+
+static int xf86RandRKeyIndex;
+static DevPrivateKey xf86RandRKey;
+
+#define XF86RANDRINFO(p) ((XF86RandRInfoPtr)dixLookupPrivate(&(p)->devPrivates, xf86RandRKey))
+
+static int
+xf86RandRModeRefresh (DisplayModePtr mode)
+{
+ if (mode->VRefresh)
+ return (int) (mode->VRefresh + 0.5);
+ else if (mode->Clock == 0)
+ return 0;
+ else
+ return (int) (mode->Clock * 1000.0 / mode->HTotal / mode->VTotal + 0.5);
+}
+
+static Bool
+xf86RandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
+{
+ RRScreenSizePtr pSize;
+ ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ DisplayModePtr mode;
+ int refresh0 = 60;
+ xorgRRModeMM RRModeMM;
+
+ *rotations = RR_Rotate_0;
+
+ for (mode = scrp->modes; mode != NULL ; mode = mode->next)
+ {
+ int refresh = xf86RandRModeRefresh (mode);
+
+ if (mode == scrp->modes)
+ refresh0 = refresh;
+
+ RRModeMM.mode = mode;
+ RRModeMM.virtX = randrp->virtualX;
+ RRModeMM.virtY = randrp->virtualY;
+ RRModeMM.mmWidth = randrp->mmWidth;
+ RRModeMM.mmHeight = randrp->mmHeight;
+
+ if(scrp->DriverFunc) {
+ (*scrp->DriverFunc)(scrp, RR_GET_MODE_MM, &RRModeMM);
+ }
+
+ pSize = RRRegisterSize (pScreen,
+ mode->HDisplay, mode->VDisplay,
+ RRModeMM.mmWidth, RRModeMM.mmHeight);
+ if (!pSize)
+ return FALSE;
+ RRRegisterRate (pScreen, pSize, refresh);
+ if (mode == scrp->currentMode &&
+ mode->HDisplay == scrp->virtualX && mode->VDisplay == scrp->virtualY)
+ RRSetCurrentConfig (pScreen, randrp->rotation, refresh, pSize);
+ if (mode->next == scrp->modes)
+ break;
+ }
+ if (scrp->currentMode->HDisplay != randrp->virtualX ||
+ scrp->currentMode->VDisplay != randrp->virtualY)
+ {
+ mode = scrp->modes;
+
+ RRModeMM.mode = NULL;
+ RRModeMM.virtX = randrp->virtualX;
+ RRModeMM.virtY = randrp->virtualY;
+ RRModeMM.mmWidth = randrp->mmWidth;
+ RRModeMM.mmHeight = randrp->mmHeight;
+
+ if(scrp->DriverFunc) {
+ (*scrp->DriverFunc)(scrp, RR_GET_MODE_MM, &RRModeMM);
+ }
+
+ pSize = RRRegisterSize (pScreen,
+ randrp->virtualX, randrp->virtualY,
+ RRModeMM.mmWidth, RRModeMM.mmHeight);
+ if (!pSize)
+ return FALSE;
+ RRRegisterRate (pScreen, pSize, refresh0);
+ if (scrp->virtualX == randrp->virtualX &&
+ scrp->virtualY == randrp->virtualY)
+ {
+ RRSetCurrentConfig (pScreen, randrp->rotation, refresh0, pSize);
+ }
+ }
+
+ /* If there is driver support for randr, let it set our supported rotations */
+ if(scrp->DriverFunc) {
+ xorgRRRotation RRRotation;
+
+ RRRotation.RRRotations = *rotations;
+ if (!(*scrp->DriverFunc)(scrp, RR_GET_INFO, &RRRotation))
+ return TRUE;
+ *rotations = RRRotation.RRRotations;
+ }
+
+ return TRUE;
+}
+
+static Bool
+xf86RandRSetMode (ScreenPtr pScreen,
+ DisplayModePtr mode,
+ Bool useVirtual,
+ int mmWidth,
+ int mmHeight)
+{
+ ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ int oldWidth = pScreen->width;
+ int oldHeight = pScreen->height;
+ int oldmmWidth = pScreen->mmWidth;
+ int oldmmHeight = pScreen->mmHeight;
+ int oldVirtualX = scrp->virtualX;
+ int oldVirtualY = scrp->virtualY;
+ WindowPtr pRoot = WindowTable[pScreen->myNum];
+ Bool ret = TRUE;
+
+ if (pRoot && scrp->vtSema)
+ (*scrp->EnableDisableFBAccess) (pScreen->myNum, FALSE);
+ if (useVirtual)
+ {
+ scrp->virtualX = randrp->virtualX;
+ scrp->virtualY = randrp->virtualY;
+ }
+ else
+ {
+ scrp->virtualX = mode->HDisplay;
+ scrp->virtualY = mode->VDisplay;
+ }
+
+ /*
+ * The DIX forgets the physical dimensions we passed into RRRegisterSize, so
+ * reconstruct them if possible.
+ */
+ if(scrp->DriverFunc) {
+ xorgRRModeMM RRModeMM;
+
+ RRModeMM.mode = mode;
+ RRModeMM.virtX = scrp->virtualX;
+ RRModeMM.virtY = scrp->virtualY;
+ RRModeMM.mmWidth = mmWidth;
+ RRModeMM.mmHeight = mmHeight;
+
+ (*scrp->DriverFunc)(scrp, RR_GET_MODE_MM, &RRModeMM);
+
+ mmWidth = RRModeMM.mmWidth;
+ mmHeight = RRModeMM.mmHeight;
+ }
+ if(randrp->rotation & (RR_Rotate_90 | RR_Rotate_270))
+ {
+ /* If the screen is rotated 90 or 270 degrees, swap the sizes. */
+ pScreen->width = scrp->virtualY;
+ pScreen->height = scrp->virtualX;
+ pScreen->mmWidth = mmHeight;
+ pScreen->mmHeight = mmWidth;
+ }
+ else
+ {
+ pScreen->width = scrp->virtualX;
+ pScreen->height = scrp->virtualY;
+ pScreen->mmWidth = mmWidth;
+ pScreen->mmHeight = mmHeight;
+ }
+ if (!xf86SwitchMode (pScreen, mode))
+ {
+ pScreen->width = oldWidth;
+ pScreen->height = oldHeight;
+ pScreen->mmWidth = oldmmWidth;
+ pScreen->mmHeight = oldmmHeight;
+ scrp->virtualX = oldVirtualX;
+ scrp->virtualY = oldVirtualY;
+ ret = FALSE;
+ }
+ /*
+ * Make sure the layout is correct
+ */
+ xf86ReconfigureLayout();
+
+ /*
+ * Make sure the whole screen is visible
+ */
+ xf86SetViewport (pScreen, pScreen->width, pScreen->height);
+ xf86SetViewport (pScreen, 0, 0);
+ if (pRoot && scrp->vtSema)
+ (*scrp->EnableDisableFBAccess) (pScreen->myNum, TRUE);
+ return ret;
+}
+
+static Bool
+xf86RandRSetConfig (ScreenPtr pScreen,
+ Rotation rotation,
+ int rate,
+ RRScreenSizePtr pSize)
+{
+ ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ DisplayModePtr mode;
+ int px, py;
+ Bool useVirtual = FALSE;
+ Rotation oldRotation = randrp->rotation;
+
+ miPointerGetPosition(inputInfo.pointer, &px, &py);
+ for (mode = scrp->modes; ; mode = mode->next)
+ {
+ if (mode->HDisplay == pSize->width &&
+ mode->VDisplay == pSize->height &&
+ (rate == 0 || xf86RandRModeRefresh (mode) == rate))
+ break;
+ if (mode->next == scrp->modes)
+ {
+ if (pSize->width == randrp->virtualX &&
+ pSize->height == randrp->virtualY)
+ {
+ mode = scrp->modes;
+ useVirtual = TRUE;
+ break;
+ }
+ return FALSE;
+ }
+ }
+
+ if (randrp->rotation != rotation) {
+
+ /* Have the driver do its thing. */
+ if (scrp->DriverFunc) {
+ xorgRRRotation RRRotation;
+ RRRotation.RRConfig.rotation = rotation;
+ RRRotation.RRConfig.rate = rate;
+ RRRotation.RRConfig.width = pSize->width;
+ RRRotation.RRConfig.height = pSize->height;
+
+ /*
+ * Currently we need to rely on HW support for rotation.
+ */
+ if (!(*scrp->DriverFunc)(scrp, RR_SET_CONFIG, &RRRotation))
+ return FALSE;
+ } else
+ return FALSE;
+
+ randrp->rotation = rotation;
+ }
+
+ if (!xf86RandRSetMode (pScreen, mode, useVirtual, pSize->mmWidth, pSize->mmHeight)) {
+ if(randrp->rotation != oldRotation) {
+ /* Have the driver undo its thing. */
+ if (scrp->DriverFunc) {
+ xorgRRRotation RRRotation;
+ RRRotation.RRConfig.rotation = oldRotation;
+ RRRotation.RRConfig.rate = xf86RandRModeRefresh (scrp->currentMode);
+ RRRotation.RRConfig.width = scrp->virtualX;
+ RRRotation.RRConfig.height = scrp->virtualY;
+ (*scrp->DriverFunc)(scrp, RR_SET_CONFIG, &RRRotation);
+ }
+
+ randrp->rotation = oldRotation;
+ }
+ return FALSE;
+ }
+ /*
+ * Move the cursor back where it belongs; SwitchMode repositions it
+ */
+ if (pScreen == miPointerCurrentScreen ())
+ {
+ px = (px >= pScreen->width ? (pScreen->width - 1) : px);
+ py = (py >= pScreen->height ? (pScreen->height - 1) : py);
+
+ xf86SetViewport(pScreen, px, py);
+
+ (*pScreen->SetCursorPosition) (inputInfo.pointer, pScreen, px, py, FALSE);
+ }
+
+ return TRUE;
+}
+
+/*
+ * Wait until the screen is initialized before whacking the
+ * sizes around; otherwise the screen pixmap will be allocated
+ * at the current mode size rather than the maximum size
+ */
+static Bool
+xf86RandRCreateScreenResources (ScreenPtr pScreen)
+{
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+#if 0
+ ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
+ DisplayModePtr mode;
+#endif
+
+ pScreen->CreateScreenResources = randrp->CreateScreenResources;
+ if (!(*pScreen->CreateScreenResources) (pScreen))
+ return FALSE;
+
+#if 0
+ mode = scrp->currentMode;
+ if (mode)
+ xf86RandRSetMode (pScreen, mode, TRUE);
+#endif
+
+ return TRUE;
+}
+
+/*
+ * Reset size back to original
+ */
+static Bool
+xf86RandRCloseScreen (int index, ScreenPtr pScreen)
+{
+ ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+
+ scrp->virtualX = pScreen->width = randrp->virtualX;
+ scrp->virtualY = pScreen->height = randrp->virtualY;
+ scrp->currentMode = scrp->modes;
+ pScreen->CloseScreen = randrp->CloseScreen;
+ free(randrp);
+ dixSetPrivate(&pScreen->devPrivates, xf86RandRKey, NULL);
+ return (*pScreen->CloseScreen) (index, pScreen);
+}
+
+Rotation
+xf86GetRotation(ScreenPtr pScreen)
+{
+ if (xf86RandRKey == NULL)
+ return RR_Rotate_0;
+
+ return XF86RANDRINFO(pScreen)->rotation;
+}
+
+/* Function to change RandR's idea of the virtual screen size */
+Bool
+xf86RandRSetNewVirtualAndDimensions(ScreenPtr pScreen,
+ int newvirtX, int newvirtY, int newmmWidth, int newmmHeight,
+ Bool resetMode)
+{
+ XF86RandRInfoPtr randrp;
+
+ if (xf86RandRKey == NULL)
+ return FALSE;
+
+ randrp = XF86RANDRINFO(pScreen);
+ if (randrp == NULL)
+ return FALSE;
+
+ if (newvirtX > 0)
+ randrp->virtualX = newvirtX;
+
+ if (newvirtY > 0)
+ randrp->virtualY = newvirtY;
+
+ if (newmmWidth > 0)
+ randrp->mmWidth = newmmWidth;
+
+ if (newmmHeight > 0)
+ randrp->mmHeight = newmmHeight;
+
+ /* This is only for during server start */
+ if (resetMode) {
+ return (xf86RandRSetMode(pScreen,
+ XF86SCRNINFO(pScreen)->currentMode,
+ TRUE,
+ pScreen->mmWidth, pScreen->mmHeight));
+ }
+
+ return TRUE;
+}
+
+Bool
+xf86RandRInit (ScreenPtr pScreen)
+{
+ rrScrPrivPtr rp;
+ XF86RandRInfoPtr randrp;
+ ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
+
+#ifdef PANORAMIX
+ /* XXX disable RandR when using Xinerama */
+ if (!noPanoramiXExtension)
+ return TRUE;
+#endif
+
+ xf86RandRKey = &xf86RandRKeyIndex;
+
+ randrp = malloc(sizeof (XF86RandRInfoRec));
+ if (!randrp)
+ return FALSE;
+
+ if (!RRScreenInit (pScreen))
+ {
+ free(randrp);
+ return FALSE;
+ }
+ rp = rrGetScrPriv(pScreen);
+ rp->rrGetInfo = xf86RandRGetInfo;
+ rp->rrSetConfig = xf86RandRSetConfig;
+
+ randrp->virtualX = scrp->virtualX;
+ randrp->virtualY = scrp->virtualY;
+ randrp->mmWidth = pScreen->mmWidth;
+ randrp->mmHeight = pScreen->mmHeight;
+
+ randrp->CreateScreenResources = pScreen->CreateScreenResources;
+ pScreen->CreateScreenResources = xf86RandRCreateScreenResources;
+
+ randrp->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = xf86RandRCloseScreen;
+
+ randrp->rotation = RR_Rotate_0;
+
+ dixSetPrivate(&pScreen->devPrivates, xf86RandRKey, randrp);
+ return TRUE;
+}
+
+
diff --git a/xorg-server/hw/xfree86/common/xf86ShowOpts.c b/xorg-server/hw/xfree86/common/xf86ShowOpts.c
index 04a9a8b1c..77f156486 100644
--- a/xorg-server/hw/xfree86/common/xf86ShowOpts.c
+++ b/xorg-server/hw/xfree86/common/xf86ShowOpts.c
@@ -1,128 +1,128 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86ShopwOpts.c,v 3.80 2003/10/08 14:58:27 dawes Exp $ */
-/*
- * Copyright 2000-2002 by Alan Hourihane, Flint Mountain, North Wales.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Alan Hourihane not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Alan Hourihane makes no representations
- * about the suitability of this software for any purpose. It is provided
- * "as is" without express or implied warranty.
- *
- * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- * Author: Marcus Schaefer, ms@suse.de
- *
- */
-
-#include <ctype.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <X11/X.h>
-#include <X11/Xmd.h>
-#include "os.h"
-#ifdef XFree86LOADER
-#include "loaderProcs.h"
-#endif
-#include "xf86.h"
-#include "xf86Config.h"
-#include "xf86_OSlib.h"
-#include "xf86Priv.h"
-/* #include "xf86PciData.h" */
-#define IN_XSERVER
-#include "xf86Parser.h"
-#include "xf86tokens.h"
-#include "Configint.h"
-#include "xf86DDC.h"
-#if defined(__sparc__) && !defined(__OpenBSD__)
-#include "xf86Bus.h"
-#include "xf86Sbus.h"
-#endif
-#include "globals.h"
-
-static const char*
-optionTypeToSting(OptionValueType type)
-{
- switch (type) {
- case OPTV_NONE:
- return "";
- case OPTV_INTEGER:
- return "<int>";
- case OPTV_STRING:
- return "<str>";
- case OPTV_ANYSTR:
- return "<str>";
- case OPTV_REAL:
- return "<real>";
- case OPTV_BOOLEAN:
- return "<bool>";
- case OPTV_FREQ:
- return "<freq>";
- default:
- return "<undef>";
- }
-}
-
-void DoShowOptions (void) {
- int i = 0;
- char **vlist = 0;
- char *pSymbol = 0;
- XF86ModuleData *initData = 0;
- if (! (vlist = xf86DriverlistFromCompile())) {
- ErrorF("Missing output drivers\n");
- goto bail;
- }
- xf86LoadModules (vlist,0);
- xfree (vlist);
- for (i = 0; i < xf86NumDrivers; i++) {
- if (xf86DriverList[i]->AvailableOptions) {
- OptionInfoPtr pOption = (OptionInfoPtr)(*xf86DriverList[i]->AvailableOptions)(0,0);
- if (! pOption) {
- ErrorF ("(EE) Couldn't read option table for %s driver\n",
- xf86DriverList[i]->driverName
- );
- continue;
- }
- pSymbol = xalloc (
- strlen(xf86DriverList[i]->driverName) + strlen("ModuleData") + 1
- );
- strcpy (pSymbol, xf86DriverList[i]->driverName);
- strcat (pSymbol, "ModuleData");
- initData = LoaderSymbol (pSymbol);
- if (initData) {
- XF86ModuleVersionInfo *vers = initData->vers;
- OptionInfoPtr p;
- ErrorF ("Driver[%d]:%s[%s] {\n",
- i,xf86DriverList[i]->driverName,vers->vendor
- );
- for (p = pOption; p->name != NULL; p++) {
- const char *opttype = optionTypeToSting(p->type);
- char *optname = xalloc(strlen(p->name) + 2 + 1);
- if (!optname) {
- continue;
- }
- sprintf(optname, "%s", p->name);
- ErrorF ("\t%s:%s\n", optname,opttype);
- }
- ErrorF ("}\n");
- }
- }
- }
- bail:
- OsCleanup (TRUE);
- AbortDDX ();
- fflush (stderr);
- exit (0);
-}
+/* $XFree86: xc/programs/Xserver/hw/xfree86/common/xf86ShopwOpts.c,v 3.80 2003/10/08 14:58:27 dawes Exp $ */
+/*
+ * Copyright 2000-2002 by Alan Hourihane, Flint Mountain, North Wales.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Marcus Schaefer, ms@suse.de
+ *
+ */
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <X11/X.h>
+#include <X11/Xmd.h>
+#include "os.h"
+#ifdef XFree86LOADER
+#include "loaderProcs.h"
+#endif
+#include "xf86.h"
+#include "xf86Config.h"
+#include "xf86_OSlib.h"
+#include "xf86Priv.h"
+/* #include "xf86PciData.h" */
+#define IN_XSERVER
+#include "xf86Parser.h"
+#include "xf86tokens.h"
+#include "Configint.h"
+#include "xf86DDC.h"
+#if defined(__sparc__) && !defined(__OpenBSD__)
+#include "xf86Bus.h"
+#include "xf86Sbus.h"
+#endif
+#include "globals.h"
+
+static const char*
+optionTypeToSting(OptionValueType type)
+{
+ switch (type) {
+ case OPTV_NONE:
+ return "";
+ case OPTV_INTEGER:
+ return "<int>";
+ case OPTV_STRING:
+ return "<str>";
+ case OPTV_ANYSTR:
+ return "<str>";
+ case OPTV_REAL:
+ return "<real>";
+ case OPTV_BOOLEAN:
+ return "<bool>";
+ case OPTV_FREQ:
+ return "<freq>";
+ default:
+ return "<undef>";
+ }
+}
+
+void DoShowOptions (void) {
+ int i = 0;
+ char **vlist = 0;
+ char *pSymbol = 0;
+ XF86ModuleData *initData = 0;
+ if (! (vlist = xf86DriverlistFromCompile())) {
+ ErrorF("Missing output drivers\n");
+ goto bail;
+ }
+ xf86LoadModules (vlist,0);
+ free(vlist);
+ for (i = 0; i < xf86NumDrivers; i++) {
+ if (xf86DriverList[i]->AvailableOptions) {
+ OptionInfoPtr pOption = (OptionInfoPtr)(*xf86DriverList[i]->AvailableOptions)(0,0);
+ if (! pOption) {
+ ErrorF ("(EE) Couldn't read option table for %s driver\n",
+ xf86DriverList[i]->driverName
+ );
+ continue;
+ }
+ pSymbol = malloc(
+ strlen(xf86DriverList[i]->driverName) + strlen("ModuleData") + 1
+ );
+ strcpy (pSymbol, xf86DriverList[i]->driverName);
+ strcat (pSymbol, "ModuleData");
+ initData = LoaderSymbol (pSymbol);
+ if (initData) {
+ XF86ModuleVersionInfo *vers = initData->vers;
+ OptionInfoPtr p;
+ ErrorF ("Driver[%d]:%s[%s] {\n",
+ i,xf86DriverList[i]->driverName,vers->vendor
+ );
+ for (p = pOption; p->name != NULL; p++) {
+ const char *opttype = optionTypeToSting(p->type);
+ char *optname = malloc(strlen(p->name) + 2 + 1);
+ if (!optname) {
+ continue;
+ }
+ sprintf(optname, "%s", p->name);
+ ErrorF ("\t%s:%s\n", optname,opttype);
+ }
+ ErrorF ("}\n");
+ }
+ }
+ }
+ bail:
+ OsCleanup (TRUE);
+ AbortDDX ();
+ fflush (stderr);
+ exit (0);
+}
diff --git a/xorg-server/hw/xfree86/common/xf86VGAarbiter.c b/xorg-server/hw/xfree86/common/xf86VGAarbiter.c
index 52a8b9a60..ac44c5e67 100644
--- a/xorg-server/hw/xfree86/common/xf86VGAarbiter.c
+++ b/xorg-server/hw/xfree86/common/xf86VGAarbiter.c
@@ -1,1101 +1,1101 @@
-/*
- * This code was stolen from RAC and adapted to control the legacy vga
- * interface.
- *
- *
- * Copyright (c) 2007 Paulo R. Zanoni, Tiago Vignatti
- *
- * Permission is hereby granted, free of charge, to any person
- * obtaining a copy of this software and associated documentation
- * files (the "Software"), to deal in the Software without
- * restriction, including without limitation the rights to use,
- * copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following
- * conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-#include "xorg-config.h"
-
-#include "xf86VGAarbiter.h"
-
-#ifdef HAVE_PCI_DEVICE_VGAARB_INIT
-#include "xf86VGAarbiterPriv.h"
-#include "xf86Bus.h"
-#include "xf86Priv.h"
-#include "pciaccess.h"
-
-
-static GCFuncs VGAarbiterGCFuncs = {
- VGAarbiterValidateGC, VGAarbiterChangeGC, VGAarbiterCopyGC,
- VGAarbiterDestroyGC, VGAarbiterChangeClip, VGAarbiterDestroyClip,
- VGAarbiterCopyClip
-};
-
-static GCOps VGAarbiterGCOps = {
- VGAarbiterFillSpans, VGAarbiterSetSpans, VGAarbiterPutImage,
- VGAarbiterCopyArea, VGAarbiterCopyPlane, VGAarbiterPolyPoint,
- VGAarbiterPolylines, VGAarbiterPolySegment, VGAarbiterPolyRectangle,
- VGAarbiterPolyArc, VGAarbiterFillPolygon, VGAarbiterPolyFillRect,
- VGAarbiterPolyFillArc, VGAarbiterPolyText8, VGAarbiterPolyText16,
- VGAarbiterImageText8, VGAarbiterImageText16, VGAarbiterImageGlyphBlt,
- VGAarbiterPolyGlyphBlt, VGAarbiterPushPixels,
- {NULL} /* devPrivate */
-};
-
-static miPointerSpriteFuncRec VGAarbiterSpriteFuncs = {
- VGAarbiterSpriteRealizeCursor, VGAarbiterSpriteUnrealizeCursor,
- VGAarbiterSpriteSetCursor, VGAarbiterSpriteMoveCursor,
- VGAarbiterDeviceCursorInitialize, VGAarbiterDeviceCursorCleanup
-};
-
-static int VGAarbiterKeyIndex;
-static DevPrivateKey VGAarbiterScreenKey = &VGAarbiterKeyIndex;
-static int VGAarbiterGCIndex;
-static DevPrivateKey VGAarbiterGCKey = &VGAarbiterGCIndex;
-
-static int vga_no_arb = 0;
-void
-xf86VGAarbiterInit(void)
-{
- if (pci_device_vgaarb_init() != 0) {
- vga_no_arb = 1;
- xf86Msg(X_WARNING, "VGA arbiter: cannot open kernel arbiter, no multi-card support\n");
- }
-}
-
-void
-xf86VGAarbiterFini(void)
-{
- if (vga_no_arb)
- return;
- pci_device_vgaarb_fini();
-}
-
-void
-xf86VGAarbiterLock(ScrnInfoPtr pScrn)
-{
- if (vga_no_arb)
- return;
- pci_device_vgaarb_set_target(pScrn->vgaDev);
- pci_device_vgaarb_lock();
-}
-
-void
-xf86VGAarbiterUnlock(ScrnInfoPtr pScrn)
-{
- if (vga_no_arb)
- return;
- pci_device_vgaarb_unlock();
-}
-
-Bool xf86VGAarbiterAllowDRI(ScreenPtr pScreen)
-{
- int vga_count;
- int rsrc_decodes;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-
- if (vga_no_arb)
- return TRUE;
-
- pci_device_vgaarb_get_info(pScrn->vgaDev, &vga_count, &rsrc_decodes);
- if (vga_count > 1) {
- if (rsrc_decodes) {
- return FALSE;
- }
- }
- return TRUE;
-}
-
-void
-xf86VGAarbiterScrnInit(ScrnInfoPtr pScrn)
-{
- struct pci_device *dev;
- EntityPtr pEnt;
-
- if (vga_no_arb)
- return;
-
- pEnt = xf86Entities[pScrn->entityList[0]];
- if (pEnt->bus.type != BUS_PCI)
- return;
-
- dev = pEnt->bus.id.pci;
- pScrn->vgaDev = dev;
-}
-
-void
-xf86VGAarbiterDeviceDecodes(ScrnInfoPtr pScrn)
-{
- if (vga_no_arb)
- return;
- pci_device_vgaarb_decodes(VGA_ARB_RSRC_LEGACY_MEM | VGA_ARB_RSRC_LEGACY_IO);
-}
-
-Bool
-xf86VGAarbiterWrapFunctions(void)
-{
- ScrnInfoPtr pScrn;
- VGAarbiterScreenPtr pScreenPriv;
- miPointerScreenPtr PointPriv;
- PictureScreenPtr ps;
- ScreenPtr pScreen;
- int vga_count, i;
-
- if (vga_no_arb)
- return FALSE;
-
- /*
- * we need to wrap the arbiter if we have more than
- * one VGA card - hotplug cries.
- */
- pci_device_vgaarb_get_info(NULL, &vga_count, NULL);
- if (vga_count < 2 || !xf86Screens)
- return FALSE;
-
- xf86Msg(X_INFO,"Found %d VGA devices: arbiter wrapping enabled\n",
- vga_count);
-
- for (i = 0; i < xf86NumScreens; i++) {
- pScreen = xf86Screens[i]->pScreen;
- ps = GetPictureScreenIfSet(pScreen);
- pScrn = xf86Screens[pScreen->myNum];
- PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
-
- if (!dixRequestPrivate(VGAarbiterGCKey, sizeof(VGAarbiterGCRec)))
- return FALSE;
-
- if (!(pScreenPriv = xalloc(sizeof(VGAarbiterScreenRec))))
- return FALSE;
-
- dixSetPrivate(&pScreen->devPrivates, VGAarbiterScreenKey, pScreenPriv);
-
- WRAP_SCREEN(CloseScreen, VGAarbiterCloseScreen);
- WRAP_SCREEN(SaveScreen, VGAarbiterSaveScreen);
- WRAP_SCREEN(WakeupHandler, VGAarbiterWakeupHandler);
- WRAP_SCREEN(BlockHandler, VGAarbiterBlockHandler);
- WRAP_SCREEN(CreateGC, VGAarbiterCreateGC);
- WRAP_SCREEN(GetImage, VGAarbiterGetImage);
- WRAP_SCREEN(GetSpans, VGAarbiterGetSpans);
- WRAP_SCREEN(SourceValidate, VGAarbiterSourceValidate);
- WRAP_SCREEN(CopyWindow, VGAarbiterCopyWindow);
- WRAP_SCREEN(ClearToBackground, VGAarbiterClearToBackground);
- WRAP_SCREEN(CreatePixmap, VGAarbiterCreatePixmap);
- WRAP_SCREEN(StoreColors, VGAarbiterStoreColors);
- WRAP_SCREEN(DisplayCursor, VGAarbiterDisplayCursor);
- WRAP_SCREEN(RealizeCursor, VGAarbiterRealizeCursor);
- WRAP_SCREEN(UnrealizeCursor, VGAarbiterUnrealizeCursor);
- WRAP_SCREEN(RecolorCursor, VGAarbiterRecolorCursor);
- WRAP_SCREEN(SetCursorPosition, VGAarbiterSetCursorPosition);
- WRAP_PICT(Composite,VGAarbiterComposite);
- WRAP_PICT(Glyphs,VGAarbiterGlyphs);
- WRAP_PICT(CompositeRects,VGAarbiterCompositeRects);
- WRAP_SCREEN_INFO(AdjustFrame, VGAarbiterAdjustFrame);
- WRAP_SCREEN_INFO(SwitchMode, VGAarbiterSwitchMode);
- WRAP_SCREEN_INFO(EnterVT, VGAarbiterEnterVT);
- WRAP_SCREEN_INFO(LeaveVT, VGAarbiterLeaveVT);
- WRAP_SCREEN_INFO(FreeScreen, VGAarbiterFreeScreen);
- WRAP_SPRITE;
- }
-
- return TRUE;
-}
-
-/* Screen funcs */
-static Bool
-VGAarbiterCloseScreen (int i, ScreenPtr pScreen)
-{
- Bool val;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, VGAarbiterScreenKey);
- miPointerScreenPtr PointPriv = (miPointerScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, miPointerScreenKey);
- PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
-
- UNWRAP_SCREEN(CreateGC);
- UNWRAP_SCREEN(CloseScreen);
- UNWRAP_SCREEN(GetImage);
- UNWRAP_SCREEN(GetSpans);
- UNWRAP_SCREEN(SourceValidate);
- UNWRAP_SCREEN(CopyWindow);
- UNWRAP_SCREEN(ClearToBackground);
- UNWRAP_SCREEN(SaveScreen);
- UNWRAP_SCREEN(StoreColors);
- UNWRAP_SCREEN(DisplayCursor);
- UNWRAP_SCREEN(RealizeCursor);
- UNWRAP_SCREEN(UnrealizeCursor);
- UNWRAP_SCREEN(RecolorCursor);
- UNWRAP_SCREEN(SetCursorPosition);
- UNWRAP_PICT(Composite);
- UNWRAP_PICT(Glyphs);
- UNWRAP_PICT(CompositeRects);
- UNWRAP_SCREEN_INFO(AdjustFrame);
- UNWRAP_SCREEN_INFO(SwitchMode);
- UNWRAP_SCREEN_INFO(EnterVT);
- UNWRAP_SCREEN_INFO(LeaveVT);
- UNWRAP_SCREEN_INFO(FreeScreen);
- UNWRAP_SPRITE;
-
- xfree ((pointer) pScreenPriv);
- xf86VGAarbiterLock(xf86Screens[i]);
- val = (*pScreen->CloseScreen) (i, pScreen);
- xf86VGAarbiterUnlock(xf86Screens[i]);
- return val;
-}
-
-static void
-VGAarbiterBlockHandler(int i,
- pointer blockData, pointer pTimeout, pointer pReadmask)
-{
- ScreenPtr pScreen = screenInfo.screens[i];
- SCREEN_PROLOG(BlockHandler);
- VGAGet();
- pScreen->BlockHandler(i, blockData, pTimeout, pReadmask);
- VGAPut();
- SCREEN_EPILOG(BlockHandler, VGAarbiterBlockHandler);
-}
-
-static void
-VGAarbiterWakeupHandler(int i, pointer blockData, unsigned long result, pointer pReadmask)
-{
- ScreenPtr pScreen = screenInfo.screens[i];
- SCREEN_PROLOG(WakeupHandler);
- VGAGet();
- pScreen->WakeupHandler(i, blockData, result, pReadmask);
- VGAPut();
- SCREEN_EPILOG(WakeupHandler, VGAarbiterWakeupHandler);
-}
-
-static void
-VGAarbiterGetImage (
- DrawablePtr pDrawable,
- int sx, int sy, int w, int h,
- unsigned int format,
- unsigned long planemask,
- char *pdstLine
- )
-{
- ScreenPtr pScreen = pDrawable->pScreen;
- SCREEN_PROLOG(GetImage);
-// if (xf86Screens[pScreen->myNum]->vtSema) {
- VGAGet();
-// }
- (*pScreen->GetImage) (pDrawable, sx, sy, w, h,
- format, planemask, pdstLine);
- VGAPut();
- SCREEN_EPILOG (GetImage, VGAarbiterGetImage);
-}
-
-static void
-VGAarbiterGetSpans (
- DrawablePtr pDrawable,
- int wMax,
- DDXPointPtr ppt,
- int *pwidth,
- int nspans,
- char *pdstStart
- )
-{
- ScreenPtr pScreen = pDrawable->pScreen;
-
- SCREEN_PROLOG (GetSpans);
- VGAGet();
- (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
- VGAPut();
- SCREEN_EPILOG (GetSpans, VGAarbiterGetSpans);
-}
-
-static void
-VGAarbiterSourceValidate (
- DrawablePtr pDrawable,
- int x, int y, int width, int height )
-{
- ScreenPtr pScreen = pDrawable->pScreen;
- SCREEN_PROLOG (SourceValidate);
- VGAGet();
- if (pScreen->SourceValidate)
- (*pScreen->SourceValidate) (pDrawable, x, y, width, height);
- VGAPut();
- SCREEN_EPILOG (SourceValidate, VGAarbiterSourceValidate);
-}
-
-static void
-VGAarbiterCopyWindow(
- WindowPtr pWin,
- DDXPointRec ptOldOrg,
- RegionPtr prgnSrc )
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
-
- SCREEN_PROLOG (CopyWindow);
- VGAGet();
- (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
- VGAPut();
- SCREEN_EPILOG (CopyWindow, VGAarbiterCopyWindow);
-}
-
-static void
-VGAarbiterClearToBackground (
- WindowPtr pWin,
- int x, int y,
- int w, int h,
- Bool generateExposures )
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
-
- SCREEN_PROLOG ( ClearToBackground);
- VGAGet();
- (*pScreen->ClearToBackground) (pWin, x, y, w, h, generateExposures);
- VGAPut();
- SCREEN_EPILOG (ClearToBackground, VGAarbiterClearToBackground);
-}
-
-static PixmapPtr
-VGAarbiterCreatePixmap(ScreenPtr pScreen, int w, int h, int depth, unsigned usage_hint)
-{
- PixmapPtr pPix;
-
- SCREEN_PROLOG ( CreatePixmap);
- VGAGet();
- pPix = (*pScreen->CreatePixmap) (pScreen, w, h, depth, usage_hint);
- VGAPut();
- SCREEN_EPILOG (CreatePixmap, VGAarbiterCreatePixmap);
-
- return pPix;
-}
-
-static Bool
-VGAarbiterSaveScreen(ScreenPtr pScreen, Bool unblank)
-{
- Bool val;
-
- SCREEN_PROLOG (SaveScreen);
- VGAGet();
- val = (*pScreen->SaveScreen) (pScreen, unblank);
- VGAPut();
- SCREEN_EPILOG (SaveScreen, VGAarbiterSaveScreen);
-
- return val;
-}
-
-static void
-VGAarbiterStoreColors (
- ColormapPtr pmap,
- int ndef,
- xColorItem *pdefs)
-{
- ScreenPtr pScreen = pmap->pScreen;
-
- SCREEN_PROLOG (StoreColors);
- VGAGet();
- (*pScreen->StoreColors) (pmap,ndef,pdefs);
- VGAPut();
- SCREEN_EPILOG ( StoreColors, VGAarbiterStoreColors);
-}
-
-static void
-VGAarbiterRecolorCursor (
- DeviceIntPtr pDev,
- ScreenPtr pScreen,
- CursorPtr pCurs,
- Bool displayed
- )
-{
- SCREEN_PROLOG (RecolorCursor);
- VGAGet();
- (*pScreen->RecolorCursor) (pDev, pScreen, pCurs, displayed);
- VGAPut();
- SCREEN_EPILOG ( RecolorCursor, VGAarbiterRecolorCursor);
-}
-
-static Bool
-VGAarbiterRealizeCursor (
- DeviceIntPtr pDev,
- ScreenPtr pScreen,
- CursorPtr pCursor
- )
-{
- Bool val;
-
- SCREEN_PROLOG (RealizeCursor);
- VGAGet();
- val = (*pScreen->RealizeCursor) (pDev, pScreen,pCursor);
- VGAPut();
- SCREEN_EPILOG ( RealizeCursor, VGAarbiterRealizeCursor);
- return val;
-}
-
-static Bool
-VGAarbiterUnrealizeCursor (
- DeviceIntPtr pDev,
- ScreenPtr pScreen,
- CursorPtr pCursor
- )
-{
- Bool val;
-
- SCREEN_PROLOG (UnrealizeCursor);
- VGAGet();
- val = (*pScreen->UnrealizeCursor) (pDev, pScreen, pCursor);
- VGAPut();
- SCREEN_EPILOG ( UnrealizeCursor, VGAarbiterUnrealizeCursor);
- return val;
-}
-
-static Bool
-VGAarbiterDisplayCursor (
- DeviceIntPtr pDev,
- ScreenPtr pScreen,
- CursorPtr pCursor
- )
-{
- Bool val;
-
- SCREEN_PROLOG (DisplayCursor);
- VGAGet();
- val = (*pScreen->DisplayCursor) (pDev, pScreen, pCursor);
- VGAPut();
- SCREEN_EPILOG ( DisplayCursor, VGAarbiterDisplayCursor);
- return val;
-}
-
-static Bool
-VGAarbiterSetCursorPosition (
- DeviceIntPtr pDev,
- ScreenPtr pScreen,
- int x, int y,
- Bool generateEvent)
-{
- Bool val;
-
- SCREEN_PROLOG (SetCursorPosition);
- VGAGet();
- val = (*pScreen->SetCursorPosition) (pDev, pScreen, x, y, generateEvent);
- VGAPut();
- SCREEN_EPILOG ( SetCursorPosition, VGAarbiterSetCursorPosition);
- return val;
-}
-
-static void
-VGAarbiterAdjustFrame(int index, int x, int y, int flags)
-{
- ScreenPtr pScreen = screenInfo.screens[index];
- VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, VGAarbiterScreenKey);
-
- VGAGet();
- (*pScreenPriv->AdjustFrame)(index, x, y, flags);
- VGAPut();
-}
-
-static Bool
-VGAarbiterSwitchMode(int index, DisplayModePtr mode, int flags)
-{
- Bool val;
- ScreenPtr pScreen = screenInfo.screens[index];
- VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, VGAarbiterScreenKey);
-
- VGAGet();
- val = (*pScreenPriv->SwitchMode)(index, mode, flags);
- VGAPut();
- return val;
-}
-
-static Bool
-VGAarbiterEnterVT(int index, int flags)
-{
- Bool val;
- ScreenPtr pScreen = screenInfo.screens[index];
- VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, VGAarbiterScreenKey);
-
- VGAGet();
- val = (*pScreenPriv->EnterVT)(index, flags);
- VGAPut();
- return val;
-}
-
-static void
-VGAarbiterLeaveVT(int index, int flags)
-{
- ScreenPtr pScreen = screenInfo.screens[index];
- VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, VGAarbiterScreenKey);
-
- VGAGet();
- (*pScreenPriv->LeaveVT)(index, flags);
- VGAPut();
-}
-
-static void
-VGAarbiterFreeScreen(int index, int flags)
-{
- ScreenPtr pScreen = screenInfo.screens[index];
- VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, VGAarbiterScreenKey);
-
- VGAGet();
- (*pScreenPriv->FreeScreen)(index, flags);
- VGAPut();
-}
-
-static Bool
-VGAarbiterCreateGC(GCPtr pGC)
-{
- ScreenPtr pScreen = pGC->pScreen;
- VGAarbiterGCPtr pGCPriv = (VGAarbiterGCPtr)dixLookupPrivate(&pGC->devPrivates, VGAarbiterGCKey);
- Bool ret;
-
- SCREEN_PROLOG(CreateGC);
- VGAGet();
- ret = (*pScreen->CreateGC)(pGC);
- VGAPut();
- GC_WRAP(pGC);
- SCREEN_EPILOG(CreateGC,VGAarbiterCreateGC);
-
- return ret;
-}
-
-/* GC funcs */
-static void
-VGAarbiterValidateGC(
- GCPtr pGC,
- unsigned long changes,
- DrawablePtr pDraw )
-{
- GC_UNWRAP(pGC);
- (*pGC->funcs->ValidateGC)(pGC, changes, pDraw);
- GC_WRAP(pGC);
-}
-
-
-static void
-VGAarbiterDestroyGC(GCPtr pGC)
-{
- GC_UNWRAP (pGC);
- (*pGC->funcs->DestroyGC)(pGC);
- GC_WRAP (pGC);
-}
-
-static void
-VGAarbiterChangeGC (
- GCPtr pGC,
- unsigned long mask)
-{
- GC_UNWRAP (pGC);
- (*pGC->funcs->ChangeGC) (pGC, mask);
- GC_WRAP (pGC);
-}
-
-static void
-VGAarbiterCopyGC (
- GCPtr pGCSrc,
- unsigned long mask,
- GCPtr pGCDst)
-{
- GC_UNWRAP (pGCDst);
- (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
- GC_WRAP (pGCDst);
-}
-
-static void
-VGAarbiterChangeClip (
- GCPtr pGC,
- int type,
- pointer pvalue,
- int nrects )
-{
- GC_UNWRAP (pGC);
- (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
- GC_WRAP (pGC);
-}
-
-static void
-VGAarbiterCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
-{
- GC_UNWRAP (pgcDst);
- (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
- GC_WRAP (pgcDst);
-}
-
-static void
-VGAarbiterDestroyClip(GCPtr pGC)
-{
- GC_UNWRAP (pGC);
- (* pGC->funcs->DestroyClip)(pGC);
- GC_WRAP (pGC);
-}
-
-/* GC Ops */
-static void
-VGAarbiterFillSpans(
- DrawablePtr pDraw,
- GC *pGC,
- int nInit,
- DDXPointPtr pptInit,
- int *pwidthInit,
- int fSorted )
-{
- GC_UNWRAP(pGC);
- VGAGet_GC();
- (*pGC->ops->FillSpans)(pDraw, pGC, nInit, pptInit, pwidthInit, fSorted);
- VGAPut_GC();
- GC_WRAP(pGC);
-}
-
-static void
-VGAarbiterSetSpans(
- DrawablePtr pDraw,
- GCPtr pGC,
- char *pcharsrc,
- register DDXPointPtr ppt,
- int *pwidth,
- int nspans,
- int fSorted )
-{
- GC_UNWRAP(pGC);
- VGAGet_GC();
- (*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, ppt, pwidth, nspans, fSorted);
- VGAPut_GC();
- GC_WRAP(pGC);
-}
-
-static void
-VGAarbiterPutImage(
- DrawablePtr pDraw,
- GCPtr pGC,
- int depth,
- int x, int y, int w, int h,
- int leftPad,
- int format,
- char *pImage )
-{
- GC_UNWRAP(pGC);
- VGAGet_GC();
- (*pGC->ops->PutImage)(pDraw, pGC, depth, x, y, w, h,
- leftPad, format, pImage);
- VGAPut_GC();
- GC_WRAP(pGC);
-}
-
-static RegionPtr
-VGAarbiterCopyArea(
- DrawablePtr pSrc,
- DrawablePtr pDst,
- GC *pGC,
- int srcx, int srcy,
- int width, int height,
- int dstx, int dsty )
-{
- RegionPtr ret;
-
- GC_UNWRAP(pGC);
- VGAGet_GC();
- ret = (*pGC->ops->CopyArea)(pSrc, pDst,
- pGC, srcx, srcy, width, height, dstx, dsty);
- VGAPut_GC();
- GC_WRAP(pGC);
- return ret;
-}
-
-static RegionPtr
-VGAarbiterCopyPlane(
- DrawablePtr pSrc,
- DrawablePtr pDst,
- GCPtr pGC,
- int srcx, int srcy,
- int width, int height,
- int dstx, int dsty,
- unsigned long bitPlane )
-{
- RegionPtr ret;
-
- GC_UNWRAP(pGC);
- VGAGet_GC();
- ret = (*pGC->ops->CopyPlane)(pSrc, pDst, pGC, srcx, srcy,
- width, height, dstx, dsty, bitPlane);
- VGAPut_GC();
- GC_WRAP(pGC);
- return ret;
-}
-
-static void
-VGAarbiterPolyPoint(
- DrawablePtr pDraw,
- GCPtr pGC,
- int mode,
- int npt,
- xPoint *pptInit )
-{
- GC_UNWRAP(pGC);
- VGAGet_GC();
- (*pGC->ops->PolyPoint)(pDraw, pGC, mode, npt, pptInit);
- VGAPut_GC();
- GC_WRAP(pGC);
-}
-
-
-static void
-VGAarbiterPolylines(
- DrawablePtr pDraw,
- GCPtr pGC,
- int mode,
- int npt,
- DDXPointPtr pptInit )
-{
- GC_UNWRAP(pGC);
- VGAGet_GC();
- (*pGC->ops->Polylines)(pDraw, pGC, mode, npt, pptInit);
- VGAPut_GC();
- GC_WRAP(pGC);
-}
-
-static void
-VGAarbiterPolySegment(
- DrawablePtr pDraw,
- GCPtr pGC,
- int nseg,
- xSegment *pSeg )
-{
- GC_UNWRAP(pGC);
- VGAGet_GC();
- (*pGC->ops->PolySegment)(pDraw, pGC, nseg, pSeg);
- VGAPut_GC();
- GC_WRAP(pGC);
-}
-
-static void
-VGAarbiterPolyRectangle(
- DrawablePtr pDraw,
- GCPtr pGC,
- int nRectsInit,
- xRectangle *pRectsInit )
-{
- GC_UNWRAP(pGC);
- VGAGet_GC();
- (*pGC->ops->PolyRectangle)(pDraw, pGC, nRectsInit, pRectsInit);
- VGAPut_GC();
- GC_WRAP(pGC);
-}
-
-static void
-VGAarbiterPolyArc(
- DrawablePtr pDraw,
- GCPtr pGC,
- int narcs,
- xArc *parcs )
-{
- GC_UNWRAP(pGC);
- VGAGet_GC();
- (*pGC->ops->PolyArc)(pDraw, pGC, narcs, parcs);
- VGAPut_GC();
- GC_WRAP(pGC);
-}
-
-static void
-VGAarbiterFillPolygon(
- DrawablePtr pDraw,
- GCPtr pGC,
- int shape,
- int mode,
- int count,
- DDXPointPtr ptsIn )
-{
- GC_UNWRAP(pGC);
- VGAGet_GC();
- (*pGC->ops->FillPolygon)(pDraw, pGC, shape, mode, count, ptsIn);
- VGAPut_GC();
- GC_WRAP(pGC);
-}
-
-static void
-VGAarbiterPolyFillRect(
- DrawablePtr pDraw,
- GCPtr pGC,
- int nrectFill,
- xRectangle *prectInit)
-{
- GC_UNWRAP(pGC);
- VGAGet_GC();
- (*pGC->ops->PolyFillRect)(pDraw, pGC, nrectFill, prectInit);
- VGAPut_GC();
- GC_WRAP(pGC);
-}
-
-static void
-VGAarbiterPolyFillArc(
- DrawablePtr pDraw,
- GCPtr pGC,
- int narcs,
- xArc *parcs )
-{
- GC_UNWRAP(pGC);
- VGAGet_GC();
- (*pGC->ops->PolyFillArc)(pDraw, pGC, narcs, parcs);
- VGAPut_GC();
- GC_WRAP(pGC);
-}
-
-static int
-VGAarbiterPolyText8(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x,
- int y,
- int count,
- char *chars )
-{
- int ret;
-
- GC_UNWRAP(pGC);
- VGAGet_GC();
- ret = (*pGC->ops->PolyText8)(pDraw, pGC, x, y, count, chars);
- VGAPut_GC();
- GC_WRAP(pGC);
- return ret;
-}
-
-static int
-VGAarbiterPolyText16(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x,
- int y,
- int count,
- unsigned short *chars )
-{
- int ret;
-
- GC_UNWRAP(pGC);
- VGAGet_GC();
- ret = (*pGC->ops->PolyText16)(pDraw, pGC, x, y, count, chars);
- VGAPut_GC();
- GC_WRAP(pGC);
- return ret;
-}
-
-static void
-VGAarbiterImageText8(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x,
- int y,
- int count,
- char *chars )
-{
- GC_UNWRAP(pGC);
- VGAGet_GC();
- (*pGC->ops->ImageText8)(pDraw, pGC, x, y, count, chars);
- VGAPut_GC();
- GC_WRAP(pGC);
-}
-
-static void
-VGAarbiterImageText16(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x,
- int y,
- int count,
- unsigned short *chars )
-{
- GC_UNWRAP(pGC);
- VGAGet_GC();
- (*pGC->ops->ImageText16)(pDraw, pGC, x, y, count, chars);
- VGAPut_GC();
- GC_WRAP(pGC);
-}
-
-
-static void
-VGAarbiterImageGlyphBlt(
- DrawablePtr pDraw,
- GCPtr pGC,
- int xInit, int yInit,
- unsigned int nglyph,
- CharInfoPtr *ppci,
- pointer pglyphBase )
-{
- GC_UNWRAP(pGC);
- VGAGet_GC();
- (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, xInit, yInit,
- nglyph, ppci, pglyphBase);
- VGAPut_GC();
- GC_WRAP(pGC);
-}
-
-static void
-VGAarbiterPolyGlyphBlt(
- DrawablePtr pDraw,
- GCPtr pGC,
- int xInit, int yInit,
- unsigned int nglyph,
- CharInfoPtr *ppci,
- pointer pglyphBase )
-{
- GC_UNWRAP(pGC);
- VGAGet_GC();
- (*pGC->ops->PolyGlyphBlt)(pDraw, pGC, xInit, yInit,
- nglyph, ppci, pglyphBase);
- VGAPut_GC();
- GC_WRAP(pGC);
-}
-
-static void
-VGAarbiterPushPixels(
- GCPtr pGC,
- PixmapPtr pBitMap,
- DrawablePtr pDraw,
- int dx, int dy, int xOrg, int yOrg )
-{
- GC_UNWRAP(pGC);
- VGAGet_GC();
- (*pGC->ops->PushPixels)(pGC, pBitMap, pDraw, dx, dy, xOrg, yOrg);
- VGAPut_GC();
- GC_WRAP(pGC);
-}
-
-
-/* miSpriteFuncs */
-static Bool
-VGAarbiterSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCur)
-{
- Bool val;
- SPRITE_PROLOG;
- VGAGet();
- val = PointPriv->spriteFuncs->RealizeCursor(pDev, pScreen, pCur);
- VGAPut();
- SPRITE_EPILOG;
- return val;
-}
-
-static Bool
-VGAarbiterSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCur)
-{
- Bool val;
- SPRITE_PROLOG;
- VGAGet();
- val = PointPriv->spriteFuncs->UnrealizeCursor(pDev, pScreen, pCur);
- VGAPut();
- SPRITE_EPILOG;
- return val;
-}
-
-static void
-VGAarbiterSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCur, int x, int y)
-{
- SPRITE_PROLOG;
- VGAGet();
- PointPriv->spriteFuncs->SetCursor(pDev, pScreen, pCur, x, y);
- VGAPut();
- SPRITE_EPILOG;
-}
-
-static void
-VGAarbiterSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
-{
- SPRITE_PROLOG;
- VGAGet();
- PointPriv->spriteFuncs->MoveCursor(pDev, pScreen, x, y);
- VGAPut();
- SPRITE_EPILOG;
-}
-
-static Bool
-VGAarbiterDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
-{
- Bool val;
- SPRITE_PROLOG;
- VGAGet();
- val = PointPriv->spriteFuncs->DeviceCursorInitialize(pDev, pScreen);
- VGAPut();
- SPRITE_EPILOG;
- return val;
-}
-
-static void
-VGAarbiterDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
-{
- SPRITE_PROLOG;
- VGAGet();
- PointPriv->spriteFuncs->DeviceCursorCleanup(pDev, pScreen);
- VGAPut();
- SPRITE_EPILOG;
-}
-
-static void
-VGAarbiterComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask,
- PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask,
- INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width,
- CARD16 height)
-{
- ScreenPtr pScreen = pDst->pDrawable->pScreen;
- PictureScreenPtr ps = GetPictureScreen(pScreen);
-
- PICTURE_PROLOGUE(Composite);
-
- VGAGet();
- (*ps->Composite) (op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst,
- yDst, width, height);
- VGAPut();
- PICTURE_EPILOGUE(Composite, VGAarbiterComposite);
-}
-
-static void
-VGAarbiterGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
- PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlist,
- GlyphListPtr list, GlyphPtr *glyphs)
-{
- ScreenPtr pScreen = pDst->pDrawable->pScreen;
- PictureScreenPtr ps = GetPictureScreen(pScreen);
-
- PICTURE_PROLOGUE(Glyphs);
-
- VGAGet();
- (*ps->Glyphs)(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
- VGAPut();
- PICTURE_EPILOGUE (Glyphs, VGAarbiterGlyphs);
-}
-
-static void
-VGAarbiterCompositeRects(CARD8 op, PicturePtr pDst, xRenderColor *color, int nRect,
- xRectangle *rects)
-{
- ScreenPtr pScreen = pDst->pDrawable->pScreen;
- PictureScreenPtr ps = GetPictureScreen(pScreen);
-
- PICTURE_PROLOGUE(CompositeRects);
-
- VGAGet();
- (*ps->CompositeRects)(op, pDst, color, nRect, rects);
- VGAPut();
- PICTURE_EPILOGUE (CompositeRects, VGAarbiterCompositeRects);
-}
-#else
-/* dummy functions */
-void xf86VGAarbiterInit(void) {}
-void xf86VGAarbiterFini(void) {}
-
-void xf86VGAarbiterLock(ScrnInfoPtr pScrn) {}
-void xf86VGAarbiterUnlock(ScrnInfoPtr pScrn) {}
-Bool xf86VGAarbiterAllowDRI(ScreenPtr pScreen) { return TRUE; }
-void xf86VGAarbiterScrnInit(ScrnInfoPtr pScrn) {}
-void xf86VGAarbiterDeviceDecodes(ScrnInfoPtr pScrn) {}
-Bool xf86VGAarbiterWrapFunctions(void) { return FALSE; }
-
-#endif
+/*
+ * This code was stolen from RAC and adapted to control the legacy vga
+ * interface.
+ *
+ *
+ * Copyright (c) 2007 Paulo R. Zanoni, Tiago Vignatti
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "xorg-config.h"
+
+#include "xf86VGAarbiter.h"
+
+#ifdef HAVE_PCI_DEVICE_VGAARB_INIT
+#include "xf86VGAarbiterPriv.h"
+#include "xf86Bus.h"
+#include "xf86Priv.h"
+#include "pciaccess.h"
+
+
+static GCFuncs VGAarbiterGCFuncs = {
+ VGAarbiterValidateGC, VGAarbiterChangeGC, VGAarbiterCopyGC,
+ VGAarbiterDestroyGC, VGAarbiterChangeClip, VGAarbiterDestroyClip,
+ VGAarbiterCopyClip
+};
+
+static GCOps VGAarbiterGCOps = {
+ VGAarbiterFillSpans, VGAarbiterSetSpans, VGAarbiterPutImage,
+ VGAarbiterCopyArea, VGAarbiterCopyPlane, VGAarbiterPolyPoint,
+ VGAarbiterPolylines, VGAarbiterPolySegment, VGAarbiterPolyRectangle,
+ VGAarbiterPolyArc, VGAarbiterFillPolygon, VGAarbiterPolyFillRect,
+ VGAarbiterPolyFillArc, VGAarbiterPolyText8, VGAarbiterPolyText16,
+ VGAarbiterImageText8, VGAarbiterImageText16, VGAarbiterImageGlyphBlt,
+ VGAarbiterPolyGlyphBlt, VGAarbiterPushPixels,
+ {NULL} /* devPrivate */
+};
+
+static miPointerSpriteFuncRec VGAarbiterSpriteFuncs = {
+ VGAarbiterSpriteRealizeCursor, VGAarbiterSpriteUnrealizeCursor,
+ VGAarbiterSpriteSetCursor, VGAarbiterSpriteMoveCursor,
+ VGAarbiterDeviceCursorInitialize, VGAarbiterDeviceCursorCleanup
+};
+
+static int VGAarbiterKeyIndex;
+static DevPrivateKey VGAarbiterScreenKey = &VGAarbiterKeyIndex;
+static int VGAarbiterGCIndex;
+static DevPrivateKey VGAarbiterGCKey = &VGAarbiterGCIndex;
+
+static int vga_no_arb = 0;
+void
+xf86VGAarbiterInit(void)
+{
+ if (pci_device_vgaarb_init() != 0) {
+ vga_no_arb = 1;
+ xf86Msg(X_WARNING, "VGA arbiter: cannot open kernel arbiter, no multi-card support\n");
+ }
+}
+
+void
+xf86VGAarbiterFini(void)
+{
+ if (vga_no_arb)
+ return;
+ pci_device_vgaarb_fini();
+}
+
+void
+xf86VGAarbiterLock(ScrnInfoPtr pScrn)
+{
+ if (vga_no_arb)
+ return;
+ pci_device_vgaarb_set_target(pScrn->vgaDev);
+ pci_device_vgaarb_lock();
+}
+
+void
+xf86VGAarbiterUnlock(ScrnInfoPtr pScrn)
+{
+ if (vga_no_arb)
+ return;
+ pci_device_vgaarb_unlock();
+}
+
+Bool xf86VGAarbiterAllowDRI(ScreenPtr pScreen)
+{
+ int vga_count;
+ int rsrc_decodes;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+
+ if (vga_no_arb)
+ return TRUE;
+
+ pci_device_vgaarb_get_info(pScrn->vgaDev, &vga_count, &rsrc_decodes);
+ if (vga_count > 1) {
+ if (rsrc_decodes) {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+void
+xf86VGAarbiterScrnInit(ScrnInfoPtr pScrn)
+{
+ struct pci_device *dev;
+ EntityPtr pEnt;
+
+ if (vga_no_arb)
+ return;
+
+ pEnt = xf86Entities[pScrn->entityList[0]];
+ if (pEnt->bus.type != BUS_PCI)
+ return;
+
+ dev = pEnt->bus.id.pci;
+ pScrn->vgaDev = dev;
+}
+
+void
+xf86VGAarbiterDeviceDecodes(ScrnInfoPtr pScrn)
+{
+ if (vga_no_arb)
+ return;
+ pci_device_vgaarb_decodes(VGA_ARB_RSRC_LEGACY_MEM | VGA_ARB_RSRC_LEGACY_IO);
+}
+
+Bool
+xf86VGAarbiterWrapFunctions(void)
+{
+ ScrnInfoPtr pScrn;
+ VGAarbiterScreenPtr pScreenPriv;
+ miPointerScreenPtr PointPriv;
+ PictureScreenPtr ps;
+ ScreenPtr pScreen;
+ int vga_count, i;
+
+ if (vga_no_arb)
+ return FALSE;
+
+ /*
+ * we need to wrap the arbiter if we have more than
+ * one VGA card - hotplug cries.
+ */
+ pci_device_vgaarb_get_info(NULL, &vga_count, NULL);
+ if (vga_count < 2 || !xf86Screens)
+ return FALSE;
+
+ xf86Msg(X_INFO,"Found %d VGA devices: arbiter wrapping enabled\n",
+ vga_count);
+
+ for (i = 0; i < xf86NumScreens; i++) {
+ pScreen = xf86Screens[i]->pScreen;
+ ps = GetPictureScreenIfSet(pScreen);
+ pScrn = xf86Screens[pScreen->myNum];
+ PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
+
+ if (!dixRequestPrivate(VGAarbiterGCKey, sizeof(VGAarbiterGCRec)))
+ return FALSE;
+
+ if (!(pScreenPriv = malloc(sizeof(VGAarbiterScreenRec))))
+ return FALSE;
+
+ dixSetPrivate(&pScreen->devPrivates, VGAarbiterScreenKey, pScreenPriv);
+
+ WRAP_SCREEN(CloseScreen, VGAarbiterCloseScreen);
+ WRAP_SCREEN(SaveScreen, VGAarbiterSaveScreen);
+ WRAP_SCREEN(WakeupHandler, VGAarbiterWakeupHandler);
+ WRAP_SCREEN(BlockHandler, VGAarbiterBlockHandler);
+ WRAP_SCREEN(CreateGC, VGAarbiterCreateGC);
+ WRAP_SCREEN(GetImage, VGAarbiterGetImage);
+ WRAP_SCREEN(GetSpans, VGAarbiterGetSpans);
+ WRAP_SCREEN(SourceValidate, VGAarbiterSourceValidate);
+ WRAP_SCREEN(CopyWindow, VGAarbiterCopyWindow);
+ WRAP_SCREEN(ClearToBackground, VGAarbiterClearToBackground);
+ WRAP_SCREEN(CreatePixmap, VGAarbiterCreatePixmap);
+ WRAP_SCREEN(StoreColors, VGAarbiterStoreColors);
+ WRAP_SCREEN(DisplayCursor, VGAarbiterDisplayCursor);
+ WRAP_SCREEN(RealizeCursor, VGAarbiterRealizeCursor);
+ WRAP_SCREEN(UnrealizeCursor, VGAarbiterUnrealizeCursor);
+ WRAP_SCREEN(RecolorCursor, VGAarbiterRecolorCursor);
+ WRAP_SCREEN(SetCursorPosition, VGAarbiterSetCursorPosition);
+ WRAP_PICT(Composite,VGAarbiterComposite);
+ WRAP_PICT(Glyphs,VGAarbiterGlyphs);
+ WRAP_PICT(CompositeRects,VGAarbiterCompositeRects);
+ WRAP_SCREEN_INFO(AdjustFrame, VGAarbiterAdjustFrame);
+ WRAP_SCREEN_INFO(SwitchMode, VGAarbiterSwitchMode);
+ WRAP_SCREEN_INFO(EnterVT, VGAarbiterEnterVT);
+ WRAP_SCREEN_INFO(LeaveVT, VGAarbiterLeaveVT);
+ WRAP_SCREEN_INFO(FreeScreen, VGAarbiterFreeScreen);
+ WRAP_SPRITE;
+ }
+
+ return TRUE;
+}
+
+/* Screen funcs */
+static Bool
+VGAarbiterCloseScreen (int i, ScreenPtr pScreen)
+{
+ Bool val;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, VGAarbiterScreenKey);
+ miPointerScreenPtr PointPriv = (miPointerScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, miPointerScreenKey);
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+
+ UNWRAP_SCREEN(CreateGC);
+ UNWRAP_SCREEN(CloseScreen);
+ UNWRAP_SCREEN(GetImage);
+ UNWRAP_SCREEN(GetSpans);
+ UNWRAP_SCREEN(SourceValidate);
+ UNWRAP_SCREEN(CopyWindow);
+ UNWRAP_SCREEN(ClearToBackground);
+ UNWRAP_SCREEN(SaveScreen);
+ UNWRAP_SCREEN(StoreColors);
+ UNWRAP_SCREEN(DisplayCursor);
+ UNWRAP_SCREEN(RealizeCursor);
+ UNWRAP_SCREEN(UnrealizeCursor);
+ UNWRAP_SCREEN(RecolorCursor);
+ UNWRAP_SCREEN(SetCursorPosition);
+ UNWRAP_PICT(Composite);
+ UNWRAP_PICT(Glyphs);
+ UNWRAP_PICT(CompositeRects);
+ UNWRAP_SCREEN_INFO(AdjustFrame);
+ UNWRAP_SCREEN_INFO(SwitchMode);
+ UNWRAP_SCREEN_INFO(EnterVT);
+ UNWRAP_SCREEN_INFO(LeaveVT);
+ UNWRAP_SCREEN_INFO(FreeScreen);
+ UNWRAP_SPRITE;
+
+ free((pointer) pScreenPriv);
+ xf86VGAarbiterLock(xf86Screens[i]);
+ val = (*pScreen->CloseScreen) (i, pScreen);
+ xf86VGAarbiterUnlock(xf86Screens[i]);
+ return val;
+}
+
+static void
+VGAarbiterBlockHandler(int i,
+ pointer blockData, pointer pTimeout, pointer pReadmask)
+{
+ ScreenPtr pScreen = screenInfo.screens[i];
+ SCREEN_PROLOG(BlockHandler);
+ VGAGet();
+ pScreen->BlockHandler(i, blockData, pTimeout, pReadmask);
+ VGAPut();
+ SCREEN_EPILOG(BlockHandler, VGAarbiterBlockHandler);
+}
+
+static void
+VGAarbiterWakeupHandler(int i, pointer blockData, unsigned long result, pointer pReadmask)
+{
+ ScreenPtr pScreen = screenInfo.screens[i];
+ SCREEN_PROLOG(WakeupHandler);
+ VGAGet();
+ pScreen->WakeupHandler(i, blockData, result, pReadmask);
+ VGAPut();
+ SCREEN_EPILOG(WakeupHandler, VGAarbiterWakeupHandler);
+}
+
+static void
+VGAarbiterGetImage (
+ DrawablePtr pDrawable,
+ int sx, int sy, int w, int h,
+ unsigned int format,
+ unsigned long planemask,
+ char *pdstLine
+ )
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ SCREEN_PROLOG(GetImage);
+// if (xf86Screens[pScreen->myNum]->vtSema) {
+ VGAGet();
+// }
+ (*pScreen->GetImage) (pDrawable, sx, sy, w, h,
+ format, planemask, pdstLine);
+ VGAPut();
+ SCREEN_EPILOG (GetImage, VGAarbiterGetImage);
+}
+
+static void
+VGAarbiterGetSpans (
+ DrawablePtr pDrawable,
+ int wMax,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ char *pdstStart
+ )
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+
+ SCREEN_PROLOG (GetSpans);
+ VGAGet();
+ (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
+ VGAPut();
+ SCREEN_EPILOG (GetSpans, VGAarbiterGetSpans);
+}
+
+static void
+VGAarbiterSourceValidate (
+ DrawablePtr pDrawable,
+ int x, int y, int width, int height )
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ SCREEN_PROLOG (SourceValidate);
+ VGAGet();
+ if (pScreen->SourceValidate)
+ (*pScreen->SourceValidate) (pDrawable, x, y, width, height);
+ VGAPut();
+ SCREEN_EPILOG (SourceValidate, VGAarbiterSourceValidate);
+}
+
+static void
+VGAarbiterCopyWindow(
+ WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc )
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ SCREEN_PROLOG (CopyWindow);
+ VGAGet();
+ (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
+ VGAPut();
+ SCREEN_EPILOG (CopyWindow, VGAarbiterCopyWindow);
+}
+
+static void
+VGAarbiterClearToBackground (
+ WindowPtr pWin,
+ int x, int y,
+ int w, int h,
+ Bool generateExposures )
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ SCREEN_PROLOG ( ClearToBackground);
+ VGAGet();
+ (*pScreen->ClearToBackground) (pWin, x, y, w, h, generateExposures);
+ VGAPut();
+ SCREEN_EPILOG (ClearToBackground, VGAarbiterClearToBackground);
+}
+
+static PixmapPtr
+VGAarbiterCreatePixmap(ScreenPtr pScreen, int w, int h, int depth, unsigned usage_hint)
+{
+ PixmapPtr pPix;
+
+ SCREEN_PROLOG ( CreatePixmap);
+ VGAGet();
+ pPix = (*pScreen->CreatePixmap) (pScreen, w, h, depth, usage_hint);
+ VGAPut();
+ SCREEN_EPILOG (CreatePixmap, VGAarbiterCreatePixmap);
+
+ return pPix;
+}
+
+static Bool
+VGAarbiterSaveScreen(ScreenPtr pScreen, Bool unblank)
+{
+ Bool val;
+
+ SCREEN_PROLOG (SaveScreen);
+ VGAGet();
+ val = (*pScreen->SaveScreen) (pScreen, unblank);
+ VGAPut();
+ SCREEN_EPILOG (SaveScreen, VGAarbiterSaveScreen);
+
+ return val;
+}
+
+static void
+VGAarbiterStoreColors (
+ ColormapPtr pmap,
+ int ndef,
+ xColorItem *pdefs)
+{
+ ScreenPtr pScreen = pmap->pScreen;
+
+ SCREEN_PROLOG (StoreColors);
+ VGAGet();
+ (*pScreen->StoreColors) (pmap,ndef,pdefs);
+ VGAPut();
+ SCREEN_EPILOG ( StoreColors, VGAarbiterStoreColors);
+}
+
+static void
+VGAarbiterRecolorCursor (
+ DeviceIntPtr pDev,
+ ScreenPtr pScreen,
+ CursorPtr pCurs,
+ Bool displayed
+ )
+{
+ SCREEN_PROLOG (RecolorCursor);
+ VGAGet();
+ (*pScreen->RecolorCursor) (pDev, pScreen, pCurs, displayed);
+ VGAPut();
+ SCREEN_EPILOG ( RecolorCursor, VGAarbiterRecolorCursor);
+}
+
+static Bool
+VGAarbiterRealizeCursor (
+ DeviceIntPtr pDev,
+ ScreenPtr pScreen,
+ CursorPtr pCursor
+ )
+{
+ Bool val;
+
+ SCREEN_PROLOG (RealizeCursor);
+ VGAGet();
+ val = (*pScreen->RealizeCursor) (pDev, pScreen,pCursor);
+ VGAPut();
+ SCREEN_EPILOG ( RealizeCursor, VGAarbiterRealizeCursor);
+ return val;
+}
+
+static Bool
+VGAarbiterUnrealizeCursor (
+ DeviceIntPtr pDev,
+ ScreenPtr pScreen,
+ CursorPtr pCursor
+ )
+{
+ Bool val;
+
+ SCREEN_PROLOG (UnrealizeCursor);
+ VGAGet();
+ val = (*pScreen->UnrealizeCursor) (pDev, pScreen, pCursor);
+ VGAPut();
+ SCREEN_EPILOG ( UnrealizeCursor, VGAarbiterUnrealizeCursor);
+ return val;
+}
+
+static Bool
+VGAarbiterDisplayCursor (
+ DeviceIntPtr pDev,
+ ScreenPtr pScreen,
+ CursorPtr pCursor
+ )
+{
+ Bool val;
+
+ SCREEN_PROLOG (DisplayCursor);
+ VGAGet();
+ val = (*pScreen->DisplayCursor) (pDev, pScreen, pCursor);
+ VGAPut();
+ SCREEN_EPILOG ( DisplayCursor, VGAarbiterDisplayCursor);
+ return val;
+}
+
+static Bool
+VGAarbiterSetCursorPosition (
+ DeviceIntPtr pDev,
+ ScreenPtr pScreen,
+ int x, int y,
+ Bool generateEvent)
+{
+ Bool val;
+
+ SCREEN_PROLOG (SetCursorPosition);
+ VGAGet();
+ val = (*pScreen->SetCursorPosition) (pDev, pScreen, x, y, generateEvent);
+ VGAPut();
+ SCREEN_EPILOG ( SetCursorPosition, VGAarbiterSetCursorPosition);
+ return val;
+}
+
+static void
+VGAarbiterAdjustFrame(int index, int x, int y, int flags)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, VGAarbiterScreenKey);
+
+ VGAGet();
+ (*pScreenPriv->AdjustFrame)(index, x, y, flags);
+ VGAPut();
+}
+
+static Bool
+VGAarbiterSwitchMode(int index, DisplayModePtr mode, int flags)
+{
+ Bool val;
+ ScreenPtr pScreen = screenInfo.screens[index];
+ VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, VGAarbiterScreenKey);
+
+ VGAGet();
+ val = (*pScreenPriv->SwitchMode)(index, mode, flags);
+ VGAPut();
+ return val;
+}
+
+static Bool
+VGAarbiterEnterVT(int index, int flags)
+{
+ Bool val;
+ ScreenPtr pScreen = screenInfo.screens[index];
+ VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, VGAarbiterScreenKey);
+
+ VGAGet();
+ val = (*pScreenPriv->EnterVT)(index, flags);
+ VGAPut();
+ return val;
+}
+
+static void
+VGAarbiterLeaveVT(int index, int flags)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, VGAarbiterScreenKey);
+
+ VGAGet();
+ (*pScreenPriv->LeaveVT)(index, flags);
+ VGAPut();
+}
+
+static void
+VGAarbiterFreeScreen(int index, int flags)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, VGAarbiterScreenKey);
+
+ VGAGet();
+ (*pScreenPriv->FreeScreen)(index, flags);
+ VGAPut();
+}
+
+static Bool
+VGAarbiterCreateGC(GCPtr pGC)
+{
+ ScreenPtr pScreen = pGC->pScreen;
+ VGAarbiterGCPtr pGCPriv = (VGAarbiterGCPtr)dixLookupPrivate(&pGC->devPrivates, VGAarbiterGCKey);
+ Bool ret;
+
+ SCREEN_PROLOG(CreateGC);
+ VGAGet();
+ ret = (*pScreen->CreateGC)(pGC);
+ VGAPut();
+ GC_WRAP(pGC);
+ SCREEN_EPILOG(CreateGC,VGAarbiterCreateGC);
+
+ return ret;
+}
+
+/* GC funcs */
+static void
+VGAarbiterValidateGC(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw )
+{
+ GC_UNWRAP(pGC);
+ (*pGC->funcs->ValidateGC)(pGC, changes, pDraw);
+ GC_WRAP(pGC);
+}
+
+
+static void
+VGAarbiterDestroyGC(GCPtr pGC)
+{
+ GC_UNWRAP (pGC);
+ (*pGC->funcs->DestroyGC)(pGC);
+ GC_WRAP (pGC);
+}
+
+static void
+VGAarbiterChangeGC (
+ GCPtr pGC,
+ unsigned long mask)
+{
+ GC_UNWRAP (pGC);
+ (*pGC->funcs->ChangeGC) (pGC, mask);
+ GC_WRAP (pGC);
+}
+
+static void
+VGAarbiterCopyGC (
+ GCPtr pGCSrc,
+ unsigned long mask,
+ GCPtr pGCDst)
+{
+ GC_UNWRAP (pGCDst);
+ (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
+ GC_WRAP (pGCDst);
+}
+
+static void
+VGAarbiterChangeClip (
+ GCPtr pGC,
+ int type,
+ pointer pvalue,
+ int nrects )
+{
+ GC_UNWRAP (pGC);
+ (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
+ GC_WRAP (pGC);
+}
+
+static void
+VGAarbiterCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
+{
+ GC_UNWRAP (pgcDst);
+ (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
+ GC_WRAP (pgcDst);
+}
+
+static void
+VGAarbiterDestroyClip(GCPtr pGC)
+{
+ GC_UNWRAP (pGC);
+ (* pGC->funcs->DestroyClip)(pGC);
+ GC_WRAP (pGC);
+}
+
+/* GC Ops */
+static void
+VGAarbiterFillSpans(
+ DrawablePtr pDraw,
+ GC *pGC,
+ int nInit,
+ DDXPointPtr pptInit,
+ int *pwidthInit,
+ int fSorted )
+{
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ (*pGC->ops->FillSpans)(pDraw, pGC, nInit, pptInit, pwidthInit, fSorted);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+}
+
+static void
+VGAarbiterSetSpans(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ char *pcharsrc,
+ register DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ int fSorted )
+{
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ (*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, ppt, pwidth, nspans, fSorted);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+}
+
+static void
+VGAarbiterPutImage(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int depth,
+ int x, int y, int w, int h,
+ int leftPad,
+ int format,
+ char *pImage )
+{
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ (*pGC->ops->PutImage)(pDraw, pGC, depth, x, y, w, h,
+ leftPad, format, pImage);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+}
+
+static RegionPtr
+VGAarbiterCopyArea(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty )
+{
+ RegionPtr ret;
+
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ ret = (*pGC->ops->CopyArea)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+ return ret;
+}
+
+static RegionPtr
+VGAarbiterCopyPlane(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty,
+ unsigned long bitPlane )
+{
+ RegionPtr ret;
+
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ ret = (*pGC->ops->CopyPlane)(pSrc, pDst, pGC, srcx, srcy,
+ width, height, dstx, dsty, bitPlane);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+ return ret;
+}
+
+static void
+VGAarbiterPolyPoint(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ xPoint *pptInit )
+{
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ (*pGC->ops->PolyPoint)(pDraw, pGC, mode, npt, pptInit);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+}
+
+
+static void
+VGAarbiterPolylines(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pptInit )
+{
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ (*pGC->ops->Polylines)(pDraw, pGC, mode, npt, pptInit);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+}
+
+static void
+VGAarbiterPolySegment(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg )
+{
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ (*pGC->ops->PolySegment)(pDraw, pGC, nseg, pSeg);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+}
+
+static void
+VGAarbiterPolyRectangle(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nRectsInit,
+ xRectangle *pRectsInit )
+{
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ (*pGC->ops->PolyRectangle)(pDraw, pGC, nRectsInit, pRectsInit);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+}
+
+static void
+VGAarbiterPolyArc(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs )
+{
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ (*pGC->ops->PolyArc)(pDraw, pGC, narcs, parcs);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+}
+
+static void
+VGAarbiterFillPolygon(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn )
+{
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ (*pGC->ops->FillPolygon)(pDraw, pGC, shape, mode, count, ptsIn);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+}
+
+static void
+VGAarbiterPolyFillRect(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit)
+{
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ (*pGC->ops->PolyFillRect)(pDraw, pGC, nrectFill, prectInit);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+}
+
+static void
+VGAarbiterPolyFillArc(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs )
+{
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ (*pGC->ops->PolyFillArc)(pDraw, pGC, narcs, parcs);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+}
+
+static int
+VGAarbiterPolyText8(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars )
+{
+ int ret;
+
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ ret = (*pGC->ops->PolyText8)(pDraw, pGC, x, y, count, chars);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+ return ret;
+}
+
+static int
+VGAarbiterPolyText16(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars )
+{
+ int ret;
+
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ ret = (*pGC->ops->PolyText16)(pDraw, pGC, x, y, count, chars);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+ return ret;
+}
+
+static void
+VGAarbiterImageText8(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars )
+{
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ (*pGC->ops->ImageText8)(pDraw, pGC, x, y, count, chars);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+}
+
+static void
+VGAarbiterImageText16(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars )
+{
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ (*pGC->ops->ImageText16)(pDraw, pGC, x, y, count, chars);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+}
+
+
+static void
+VGAarbiterImageGlyphBlt(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase )
+{
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, xInit, yInit,
+ nglyph, ppci, pglyphBase);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+}
+
+static void
+VGAarbiterPolyGlyphBlt(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase )
+{
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ (*pGC->ops->PolyGlyphBlt)(pDraw, pGC, xInit, yInit,
+ nglyph, ppci, pglyphBase);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+}
+
+static void
+VGAarbiterPushPixels(
+ GCPtr pGC,
+ PixmapPtr pBitMap,
+ DrawablePtr pDraw,
+ int dx, int dy, int xOrg, int yOrg )
+{
+ GC_UNWRAP(pGC);
+ VGAGet_GC();
+ (*pGC->ops->PushPixels)(pGC, pBitMap, pDraw, dx, dy, xOrg, yOrg);
+ VGAPut_GC();
+ GC_WRAP(pGC);
+}
+
+
+/* miSpriteFuncs */
+static Bool
+VGAarbiterSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCur)
+{
+ Bool val;
+ SPRITE_PROLOG;
+ VGAGet();
+ val = PointPriv->spriteFuncs->RealizeCursor(pDev, pScreen, pCur);
+ VGAPut();
+ SPRITE_EPILOG;
+ return val;
+}
+
+static Bool
+VGAarbiterSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCur)
+{
+ Bool val;
+ SPRITE_PROLOG;
+ VGAGet();
+ val = PointPriv->spriteFuncs->UnrealizeCursor(pDev, pScreen, pCur);
+ VGAPut();
+ SPRITE_EPILOG;
+ return val;
+}
+
+static void
+VGAarbiterSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCur, int x, int y)
+{
+ SPRITE_PROLOG;
+ VGAGet();
+ PointPriv->spriteFuncs->SetCursor(pDev, pScreen, pCur, x, y);
+ VGAPut();
+ SPRITE_EPILOG;
+}
+
+static void
+VGAarbiterSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
+{
+ SPRITE_PROLOG;
+ VGAGet();
+ PointPriv->spriteFuncs->MoveCursor(pDev, pScreen, x, y);
+ VGAPut();
+ SPRITE_EPILOG;
+}
+
+static Bool
+VGAarbiterDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
+{
+ Bool val;
+ SPRITE_PROLOG;
+ VGAGet();
+ val = PointPriv->spriteFuncs->DeviceCursorInitialize(pDev, pScreen);
+ VGAPut();
+ SPRITE_EPILOG;
+ return val;
+}
+
+static void
+VGAarbiterDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
+{
+ SPRITE_PROLOG;
+ VGAGet();
+ PointPriv->spriteFuncs->DeviceCursorCleanup(pDev, pScreen);
+ VGAPut();
+ SPRITE_EPILOG;
+}
+
+static void
+VGAarbiterComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask,
+ PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask,
+ INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width,
+ CARD16 height)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+
+ PICTURE_PROLOGUE(Composite);
+
+ VGAGet();
+ (*ps->Composite) (op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst,
+ yDst, width, height);
+ VGAPut();
+ PICTURE_EPILOGUE(Composite, VGAarbiterComposite);
+}
+
+static void
+VGAarbiterGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+ PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlist,
+ GlyphListPtr list, GlyphPtr *glyphs)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+
+ PICTURE_PROLOGUE(Glyphs);
+
+ VGAGet();
+ (*ps->Glyphs)(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
+ VGAPut();
+ PICTURE_EPILOGUE (Glyphs, VGAarbiterGlyphs);
+}
+
+static void
+VGAarbiterCompositeRects(CARD8 op, PicturePtr pDst, xRenderColor *color, int nRect,
+ xRectangle *rects)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+
+ PICTURE_PROLOGUE(CompositeRects);
+
+ VGAGet();
+ (*ps->CompositeRects)(op, pDst, color, nRect, rects);
+ VGAPut();
+ PICTURE_EPILOGUE (CompositeRects, VGAarbiterCompositeRects);
+}
+#else
+/* dummy functions */
+void xf86VGAarbiterInit(void) {}
+void xf86VGAarbiterFini(void) {}
+
+void xf86VGAarbiterLock(ScrnInfoPtr pScrn) {}
+void xf86VGAarbiterUnlock(ScrnInfoPtr pScrn) {}
+Bool xf86VGAarbiterAllowDRI(ScreenPtr pScreen) { return TRUE; }
+void xf86VGAarbiterScrnInit(ScrnInfoPtr pScrn) {}
+void xf86VGAarbiterDeviceDecodes(ScrnInfoPtr pScrn) {}
+Bool xf86VGAarbiterWrapFunctions(void) { return FALSE; }
+
+#endif
diff --git a/xorg-server/hw/xfree86/common/xf86VidMode.c b/xorg-server/hw/xfree86/common/xf86VidMode.c
index 49b86e73a..08f27b8e4 100644
--- a/xorg-server/hw/xfree86/common/xf86VidMode.c
+++ b/xorg-server/hw/xfree86/common/xf86VidMode.c
@@ -1,667 +1,667 @@
-/*
- * Copyright (c) 1999-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-/*
- * This file contains the VidMode functions required by the extension.
- * These have been added to avoid the need for the higher level extension
- * code to access the private XFree86 data structures directly. Wherever
- * possible this code uses the functions in xf86Mode.c to do the work,
- * so that two version of code that do similar things don't have to be
- * maintained.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <X11/X.h>
-#include "os.h"
-#include "xf86.h"
-#include "xf86Priv.h"
-
-#ifdef XF86VIDMODE
-#include "vidmodeproc.h"
-#include "xf86cmap.h"
-
-static int VidModeKeyIndex;
-static DevPrivateKey VidModeKey;
-static int VidModeCount = 0;
-static Bool VidModeClose(int i, ScreenPtr pScreen);
-
-#define VMPTR(p) ((VidModePtr)dixLookupPrivate(&(p)->devPrivates, VidModeKey))
-
-#endif
-
-Bool
-VidModeExtensionInit(ScreenPtr pScreen)
-{
-#ifdef XF86VIDMODE
- VidModePtr pVidMode;
-
- if (!xf86GetVidModeEnabled()) {
- DebugF("!xf86GetVidModeEnabled()\n");
- return FALSE;
- }
-
- VidModeKey = &VidModeKeyIndex;
-
- if (!dixSetPrivate(&pScreen->devPrivates, VidModeKey,
- xcalloc(sizeof(VidModeRec), 1))) {
- DebugF("xcalloc failed\n");
- return FALSE;
- }
-
- pVidMode = VMPTR(pScreen);
- pVidMode->Flags = 0;
- pVidMode->Next = NULL;
- pVidMode->CloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = VidModeClose;
- VidModeCount++;
- return TRUE;
-#else
- DebugF("no vidmode extension\n");
- return FALSE;
-#endif
-}
-
-
-#ifdef XF86VIDMODE
-
-static Bool
-VidModeClose(int i, ScreenPtr pScreen)
-{
- VidModePtr pVidMode = VMPTR(pScreen);
-
- /* This shouldn't happen */
- if (!pVidMode)
- return FALSE;
-
- pScreen->CloseScreen = pVidMode->CloseScreen;
-
- if (--VidModeCount == 0) {
- xfree(dixLookupPrivate(&pScreen->devPrivates, VidModeKey));
- dixSetPrivate(&pScreen->devPrivates, VidModeKey, NULL);
- VidModeKey = NULL;
- }
- return pScreen->CloseScreen(i, pScreen);
-}
-
-Bool
-VidModeAvailable(int scrnIndex)
-{
- ScrnInfoPtr pScrn;
- VidModePtr pVidMode;
-
- if (VidModeKey == NULL) {
- DebugF("VidModeKey == NULL\n");
- return FALSE;
- }
-
- pScrn = xf86Screens[scrnIndex];
- if (pScrn == NULL) {
- DebugF("pScrn == NULL\n");
- return FALSE;
- }
-
- pVidMode = VMPTR(pScrn->pScreen);
- if (pVidMode)
- return TRUE;
- else {
- DebugF("pVidMode == NULL\n");
- return FALSE;
- }
-}
-
-Bool
-VidModeGetCurrentModeline(int scrnIndex, pointer *mode, int *dotClock)
-{
- ScrnInfoPtr pScrn;
-
- if (!VidModeAvailable(scrnIndex))
- return FALSE;
-
- pScrn = xf86Screens[scrnIndex];
-
- if (pScrn->currentMode) {
- *mode = (pointer)(pScrn->currentMode);
- *dotClock = pScrn->currentMode->Clock;
-
- return TRUE;
- }
- return FALSE;
-}
-
-int
-VidModeGetDotClock(int scrnIndex, int Clock)
-{
- ScrnInfoPtr pScrn;
-
- if (!VidModeAvailable(scrnIndex))
- return 0;
-
- pScrn = xf86Screens[scrnIndex];
- if ((pScrn->progClock) || (Clock >= MAXCLOCKS))
- return Clock;
- else
- return pScrn->clock[Clock];
-}
-
-int
-VidModeGetNumOfClocks(int scrnIndex, Bool *progClock)
-{
- ScrnInfoPtr pScrn;
-
- if (!VidModeAvailable(scrnIndex))
- return 0;
-
- pScrn = xf86Screens[scrnIndex];
- if (pScrn->progClock){
- *progClock = TRUE;
- return 0;
- } else {
- *progClock = FALSE;
- return pScrn->numClocks;
- }
-}
-
-Bool
-VidModeGetClocks(int scrnIndex, int *Clocks)
-{
- ScrnInfoPtr pScrn;
- int i;
-
- if (!VidModeAvailable(scrnIndex))
- return FALSE;
-
- pScrn = xf86Screens[scrnIndex];
-
- if (pScrn->progClock)
- return FALSE;
-
- for (i = 0; i < pScrn->numClocks; i++)
- *Clocks++ = pScrn->clock[i];
-
- return TRUE;
-}
-
-
-Bool
-VidModeGetFirstModeline(int scrnIndex, pointer *mode, int *dotClock)
-{
- ScrnInfoPtr pScrn;
- VidModePtr pVidMode;
-
- if (!VidModeAvailable(scrnIndex))
- return FALSE;
-
- pScrn = xf86Screens[scrnIndex];
- pVidMode = VMPTR(pScrn->pScreen);
- pVidMode->First = pScrn->modes;
- pVidMode->Next = pVidMode->First->next;
-
- if (pVidMode->First->status == MODE_OK) {
- *mode = (pointer)(pVidMode->First);
- *dotClock = VidModeGetDotClock(scrnIndex, pVidMode->First->Clock);
- return TRUE;
- }
-
- return VidModeGetNextModeline(scrnIndex, mode, dotClock);
-}
-
-Bool
-VidModeGetNextModeline(int scrnIndex, pointer *mode, int *dotClock)
-{
- ScrnInfoPtr pScrn;
- VidModePtr pVidMode;
- DisplayModePtr p;
-
- if (!VidModeAvailable(scrnIndex))
- return FALSE;
-
- pScrn = xf86Screens[scrnIndex];
- pVidMode = VMPTR(pScrn->pScreen);
-
- for (p = pVidMode->Next; p != NULL && p != pVidMode->First; p = p->next) {
- if (p->status == MODE_OK) {
- pVidMode->Next = p->next;
- *mode = (pointer)p;
- *dotClock = VidModeGetDotClock(scrnIndex, p->Clock);
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-Bool
-VidModeDeleteModeline(int scrnIndex, pointer mode)
-{
- ScrnInfoPtr pScrn;
-
- if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
- return FALSE;
-
- pScrn = xf86Screens[scrnIndex];
- xf86DeleteMode(&(pScrn->modes), (DisplayModePtr)mode);
- return TRUE;
-}
-
-Bool
-VidModeZoomViewport(int scrnIndex, int zoom)
-{
- ScrnInfoPtr pScrn;
-
- if (!VidModeAvailable(scrnIndex))
- return FALSE;
-
- pScrn = xf86Screens[scrnIndex];
- xf86ZoomViewport(pScrn->pScreen, zoom);
- return TRUE;
-}
-
-Bool
-VidModeSetViewPort(int scrnIndex, int x, int y)
-{
- ScrnInfoPtr pScrn;
-
- if (!VidModeAvailable(scrnIndex))
- return FALSE;
-
- pScrn = xf86Screens[scrnIndex];
- pScrn->frameX0 = min( max(x, 0),
- pScrn->virtualX - pScrn->currentMode->HDisplay );
- pScrn->frameX1 = pScrn->frameX0 + pScrn->currentMode->HDisplay - 1;
- pScrn->frameY0 = min( max(y, 0),
- pScrn->virtualY - pScrn->currentMode->VDisplay );
- pScrn->frameY1 = pScrn->frameY0 + pScrn->currentMode->VDisplay - 1;
- if (pScrn->AdjustFrame != NULL)
- (pScrn->AdjustFrame)(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
-
- return TRUE;
-}
-
-Bool
-VidModeGetViewPort(int scrnIndex, int *x, int *y)
-{
- ScrnInfoPtr pScrn;
-
- if (!VidModeAvailable(scrnIndex))
- return FALSE;
-
- pScrn = xf86Screens[scrnIndex];
- *x = pScrn->frameX0;
- *y = pScrn->frameY0;
- return TRUE;
-}
-
-Bool
-VidModeSwitchMode(int scrnIndex, pointer mode)
-{
- ScrnInfoPtr pScrn;
- DisplayModePtr pTmpMode;
- Bool retval;
-
- if (!VidModeAvailable(scrnIndex))
- return FALSE;
-
- pScrn = xf86Screens[scrnIndex];
- /* save in case we fail */
- pTmpMode = pScrn->currentMode;
- /* Force a mode switch */
- pScrn->currentMode = NULL;
- retval = xf86SwitchMode(pScrn->pScreen, mode);
- /* we failed: restore it */
- if (retval == FALSE)
- pScrn->currentMode = pTmpMode;
- return retval;
-}
-
-Bool
-VidModeLockZoom(int scrnIndex, Bool lock)
-{
- ScrnInfoPtr pScrn;
-
- if (!VidModeAvailable(scrnIndex))
- return FALSE;
-
- pScrn = xf86Screens[scrnIndex];
-
- if (xf86Info.dontZoom)
- return FALSE;
-
- xf86LockZoom(pScrn->pScreen, lock);
- return TRUE;
-}
-
-Bool
-VidModeGetMonitor(int scrnIndex, pointer *monitor)
-{
- ScrnInfoPtr pScrn;
-
- if (!VidModeAvailable(scrnIndex))
- return FALSE;
-
- pScrn = xf86Screens[scrnIndex];
- *monitor = (pointer)(pScrn->monitor);
-
- return TRUE;
-}
-
-ModeStatus
-VidModeCheckModeForMonitor(int scrnIndex, pointer mode)
-{
- ScrnInfoPtr pScrn;
-
- if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
- return MODE_ERROR;
-
- pScrn = xf86Screens[scrnIndex];
-
- return xf86CheckModeForMonitor((DisplayModePtr)mode, pScrn->monitor);
-}
-
-ModeStatus
-VidModeCheckModeForDriver(int scrnIndex, pointer mode)
-{
- ScrnInfoPtr pScrn;
-
- if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
- return MODE_ERROR;
-
- pScrn = xf86Screens[scrnIndex];
-
- return xf86CheckModeForDriver(pScrn, (DisplayModePtr)mode, 0);
-}
-
-void
-VidModeSetCrtcForMode(int scrnIndex, pointer mode)
-{
- ScrnInfoPtr pScrn;
- DisplayModePtr ScreenModes;
-
- if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
- return;
-
- /* Ugly hack so that the xf86Mode.c function can be used without change */
- pScrn = xf86Screens[scrnIndex];
- ScreenModes = pScrn->modes;
- pScrn->modes = (DisplayModePtr)mode;
-
- xf86SetCrtcForModes(pScrn, pScrn->adjustFlags);
- pScrn->modes = ScreenModes;
- return;
-}
-
-Bool
-VidModeAddModeline(int scrnIndex, pointer mode)
-{
- ScrnInfoPtr pScrn;
-
- if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
- return FALSE;
-
- pScrn = xf86Screens[scrnIndex];
-
- ((DisplayModePtr)mode)->name = strdup(""); /* freed by deletemode */
- ((DisplayModePtr)mode)->status = MODE_OK;
- ((DisplayModePtr)mode)->next = pScrn->modes->next;
- ((DisplayModePtr)mode)->prev = pScrn->modes;
- pScrn->modes->next = (DisplayModePtr)mode;
- if( ((DisplayModePtr)mode)->next != NULL )
- ((DisplayModePtr)mode)->next->prev = (DisplayModePtr)mode;
-
- return TRUE;
-}
-
-int
-VidModeGetNumOfModes(int scrnIndex)
-{
- pointer mode = NULL;
- int dotClock= 0, nummodes = 0;
-
- if (!VidModeGetFirstModeline(scrnIndex, &mode, &dotClock))
- return nummodes;
-
- do {
- nummodes++;
- if (!VidModeGetNextModeline(scrnIndex, &mode, &dotClock))
- return nummodes;
- } while (TRUE);
-}
-
-Bool
-VidModeSetGamma(int scrnIndex, float red, float green, float blue)
-{
- ScrnInfoPtr pScrn;
- Gamma gamma;
-
- if (!VidModeAvailable(scrnIndex))
- return FALSE;
-
- pScrn = xf86Screens[scrnIndex];
- gamma.red = red;
- gamma.green = green;
- gamma.blue = blue;
- if (xf86ChangeGamma(pScrn->pScreen, gamma) != Success)
- return FALSE;
- else
- return TRUE;
-}
-
-Bool
-VidModeGetGamma(int scrnIndex, float *red, float *green, float *blue)
-{
- ScrnInfoPtr pScrn;
-
- if (!VidModeAvailable(scrnIndex))
- return FALSE;
-
- pScrn = xf86Screens[scrnIndex];
- *red = pScrn->gamma.red;
- *green = pScrn->gamma.green;
- *blue = pScrn->gamma.blue;
- return TRUE;
-}
-
-Bool
-VidModeSetGammaRamp(int scrnIndex, int size, CARD16 *r, CARD16 *g, CARD16 *b)
-{
- ScrnInfoPtr pScrn;
-
- if (!VidModeAvailable(scrnIndex))
- return FALSE;
-
- pScrn = xf86Screens[scrnIndex];
- xf86ChangeGammaRamp(pScrn->pScreen, size, r, g, b);
- return TRUE;
-}
-
-Bool
-VidModeGetGammaRamp(int scrnIndex, int size, CARD16 *r, CARD16 *g, CARD16 *b)
-{
- ScrnInfoPtr pScrn;
-
- if (!VidModeAvailable(scrnIndex))
- return FALSE;
-
- pScrn = xf86Screens[scrnIndex];
- xf86GetGammaRamp(pScrn->pScreen, size, r, g, b);
- return TRUE;
-}
-
-int
-VidModeGetGammaRampSize(int scrnIndex)
-{
- if (!VidModeAvailable(scrnIndex))
- return 0;
-
- return xf86GetGammaRampSize(xf86Screens[scrnIndex]->pScreen);
-}
-
-pointer
-VidModeCreateMode(void)
-{
- DisplayModePtr mode;
-
- mode = xalloc(sizeof(DisplayModeRec));
- if (mode != NULL) {
- mode->name = "";
- mode->VScan = 1; /* divides refresh rate. default = 1 */
- mode->Private = NULL;
- mode->next = mode;
- mode->prev = mode;
- }
- return mode;
-}
-
-void
-VidModeCopyMode(pointer modefrom, pointer modeto)
-{
- memcpy(modeto, modefrom, sizeof(DisplayModeRec));
-}
-
-
-int
-VidModeGetModeValue(pointer mode, int valtyp)
-{
- int ret = 0;
-
- switch (valtyp) {
- case VIDMODE_H_DISPLAY:
- ret = ((DisplayModePtr) mode)->HDisplay;
- break;
- case VIDMODE_H_SYNCSTART:
- ret = ((DisplayModePtr)mode)->HSyncStart;
- break;
- case VIDMODE_H_SYNCEND:
- ret = ((DisplayModePtr)mode)->HSyncEnd;
- break;
- case VIDMODE_H_TOTAL:
- ret = ((DisplayModePtr)mode)->HTotal;
- break;
- case VIDMODE_H_SKEW:
- ret = ((DisplayModePtr)mode)->HSkew;
- break;
- case VIDMODE_V_DISPLAY:
- ret = ((DisplayModePtr)mode)->VDisplay;
- break;
- case VIDMODE_V_SYNCSTART:
- ret = ((DisplayModePtr)mode)->VSyncStart;
- break;
- case VIDMODE_V_SYNCEND:
- ret = ((DisplayModePtr)mode)->VSyncEnd;
- break;
- case VIDMODE_V_TOTAL:
- ret = ((DisplayModePtr)mode)->VTotal;
- break;
- case VIDMODE_FLAGS:
- ret = ((DisplayModePtr)mode)->Flags;
- break;
- case VIDMODE_CLOCK:
- ret = ((DisplayModePtr)mode)->Clock;
- break;
- }
- return ret;
-}
-
-void
-VidModeSetModeValue(pointer mode, int valtyp, int val)
-{
- switch (valtyp) {
- case VIDMODE_H_DISPLAY:
- ((DisplayModePtr)mode)->HDisplay = val;
- break;
- case VIDMODE_H_SYNCSTART:
- ((DisplayModePtr)mode)->HSyncStart = val;
- break;
- case VIDMODE_H_SYNCEND:
- ((DisplayModePtr)mode)->HSyncEnd = val;
- break;
- case VIDMODE_H_TOTAL:
- ((DisplayModePtr)mode)->HTotal = val;
- break;
- case VIDMODE_H_SKEW:
- ((DisplayModePtr)mode)->HSkew = val;
- break;
- case VIDMODE_V_DISPLAY:
- ((DisplayModePtr)mode)->VDisplay = val;
- break;
- case VIDMODE_V_SYNCSTART:
- ((DisplayModePtr)mode)->VSyncStart = val;
- break;
- case VIDMODE_V_SYNCEND:
- ((DisplayModePtr)mode)->VSyncEnd = val;
- break;
- case VIDMODE_V_TOTAL:
- ((DisplayModePtr)mode)->VTotal = val;
- break;
- case VIDMODE_FLAGS:
- ((DisplayModePtr)mode)->Flags = val;
- break;
- case VIDMODE_CLOCK:
- ((DisplayModePtr)mode)->Clock = val;
- break;
- }
- return;
-}
-
-vidMonitorValue
-VidModeGetMonitorValue(pointer monitor, int valtyp, int indx)
-{
- vidMonitorValue ret;
-
- switch (valtyp) {
- case VIDMODE_MON_VENDOR:
- ret.ptr = (((MonPtr)monitor)->vendor);
- break;
- case VIDMODE_MON_MODEL:
- ret.ptr = (((MonPtr)monitor)->model);
- break;
- case VIDMODE_MON_NHSYNC:
- ret.i = ((MonPtr)monitor)->nHsync;
- break;
- case VIDMODE_MON_NVREFRESH:
- ret.i = ((MonPtr)monitor)->nVrefresh;
- break;
- case VIDMODE_MON_HSYNC_LO:
- ret.f = (100.0 * ((MonPtr)monitor)->hsync[indx].lo);
- break;
- case VIDMODE_MON_HSYNC_HI:
- ret.f = (100.0 * ((MonPtr)monitor)->hsync[indx].hi);
- break;
- case VIDMODE_MON_VREFRESH_LO:
- ret.f = (100.0 * ((MonPtr)monitor)->vrefresh[indx].lo);
- break;
- case VIDMODE_MON_VREFRESH_HI:
- ret.f = (100.0 * ((MonPtr)monitor)->vrefresh[indx].hi);
- break;
- }
- return ret;
-}
-
-
-#endif /* XF86VIDMODE */
+/*
+ * Copyright (c) 1999-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ * This file contains the VidMode functions required by the extension.
+ * These have been added to avoid the need for the higher level extension
+ * code to access the private XFree86 data structures directly. Wherever
+ * possible this code uses the functions in xf86Mode.c to do the work,
+ * so that two version of code that do similar things don't have to be
+ * maintained.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <X11/X.h>
+#include "os.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+
+#ifdef XF86VIDMODE
+#include "vidmodeproc.h"
+#include "xf86cmap.h"
+
+static int VidModeKeyIndex;
+static DevPrivateKey VidModeKey;
+static int VidModeCount = 0;
+static Bool VidModeClose(int i, ScreenPtr pScreen);
+
+#define VMPTR(p) ((VidModePtr)dixLookupPrivate(&(p)->devPrivates, VidModeKey))
+
+#endif
+
+Bool
+VidModeExtensionInit(ScreenPtr pScreen)
+{
+#ifdef XF86VIDMODE
+ VidModePtr pVidMode;
+
+ if (!xf86GetVidModeEnabled()) {
+ DebugF("!xf86GetVidModeEnabled()\n");
+ return FALSE;
+ }
+
+ VidModeKey = &VidModeKeyIndex;
+
+ if (!dixSetPrivate(&pScreen->devPrivates, VidModeKey,
+ calloc(sizeof(VidModeRec), 1))) {
+ DebugF("xcalloc failed\n");
+ return FALSE;
+ }
+
+ pVidMode = VMPTR(pScreen);
+ pVidMode->Flags = 0;
+ pVidMode->Next = NULL;
+ pVidMode->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = VidModeClose;
+ VidModeCount++;
+ return TRUE;
+#else
+ DebugF("no vidmode extension\n");
+ return FALSE;
+#endif
+}
+
+
+#ifdef XF86VIDMODE
+
+static Bool
+VidModeClose(int i, ScreenPtr pScreen)
+{
+ VidModePtr pVidMode = VMPTR(pScreen);
+
+ /* This shouldn't happen */
+ if (!pVidMode)
+ return FALSE;
+
+ pScreen->CloseScreen = pVidMode->CloseScreen;
+
+ if (--VidModeCount == 0) {
+ free(dixLookupPrivate(&pScreen->devPrivates, VidModeKey));
+ dixSetPrivate(&pScreen->devPrivates, VidModeKey, NULL);
+ VidModeKey = NULL;
+ }
+ return pScreen->CloseScreen(i, pScreen);
+}
+
+Bool
+VidModeAvailable(int scrnIndex)
+{
+ ScrnInfoPtr pScrn;
+ VidModePtr pVidMode;
+
+ if (VidModeKey == NULL) {
+ DebugF("VidModeKey == NULL\n");
+ return FALSE;
+ }
+
+ pScrn = xf86Screens[scrnIndex];
+ if (pScrn == NULL) {
+ DebugF("pScrn == NULL\n");
+ return FALSE;
+ }
+
+ pVidMode = VMPTR(pScrn->pScreen);
+ if (pVidMode)
+ return TRUE;
+ else {
+ DebugF("pVidMode == NULL\n");
+ return FALSE;
+ }
+}
+
+Bool
+VidModeGetCurrentModeline(int scrnIndex, pointer *mode, int *dotClock)
+{
+ ScrnInfoPtr pScrn;
+
+ if (!VidModeAvailable(scrnIndex))
+ return FALSE;
+
+ pScrn = xf86Screens[scrnIndex];
+
+ if (pScrn->currentMode) {
+ *mode = (pointer)(pScrn->currentMode);
+ *dotClock = pScrn->currentMode->Clock;
+
+ return TRUE;
+ }
+ return FALSE;
+}
+
+int
+VidModeGetDotClock(int scrnIndex, int Clock)
+{
+ ScrnInfoPtr pScrn;
+
+ if (!VidModeAvailable(scrnIndex))
+ return 0;
+
+ pScrn = xf86Screens[scrnIndex];
+ if ((pScrn->progClock) || (Clock >= MAXCLOCKS))
+ return Clock;
+ else
+ return pScrn->clock[Clock];
+}
+
+int
+VidModeGetNumOfClocks(int scrnIndex, Bool *progClock)
+{
+ ScrnInfoPtr pScrn;
+
+ if (!VidModeAvailable(scrnIndex))
+ return 0;
+
+ pScrn = xf86Screens[scrnIndex];
+ if (pScrn->progClock){
+ *progClock = TRUE;
+ return 0;
+ } else {
+ *progClock = FALSE;
+ return pScrn->numClocks;
+ }
+}
+
+Bool
+VidModeGetClocks(int scrnIndex, int *Clocks)
+{
+ ScrnInfoPtr pScrn;
+ int i;
+
+ if (!VidModeAvailable(scrnIndex))
+ return FALSE;
+
+ pScrn = xf86Screens[scrnIndex];
+
+ if (pScrn->progClock)
+ return FALSE;
+
+ for (i = 0; i < pScrn->numClocks; i++)
+ *Clocks++ = pScrn->clock[i];
+
+ return TRUE;
+}
+
+
+Bool
+VidModeGetFirstModeline(int scrnIndex, pointer *mode, int *dotClock)
+{
+ ScrnInfoPtr pScrn;
+ VidModePtr pVidMode;
+
+ if (!VidModeAvailable(scrnIndex))
+ return FALSE;
+
+ pScrn = xf86Screens[scrnIndex];
+ pVidMode = VMPTR(pScrn->pScreen);
+ pVidMode->First = pScrn->modes;
+ pVidMode->Next = pVidMode->First->next;
+
+ if (pVidMode->First->status == MODE_OK) {
+ *mode = (pointer)(pVidMode->First);
+ *dotClock = VidModeGetDotClock(scrnIndex, pVidMode->First->Clock);
+ return TRUE;
+ }
+
+ return VidModeGetNextModeline(scrnIndex, mode, dotClock);
+}
+
+Bool
+VidModeGetNextModeline(int scrnIndex, pointer *mode, int *dotClock)
+{
+ ScrnInfoPtr pScrn;
+ VidModePtr pVidMode;
+ DisplayModePtr p;
+
+ if (!VidModeAvailable(scrnIndex))
+ return FALSE;
+
+ pScrn = xf86Screens[scrnIndex];
+ pVidMode = VMPTR(pScrn->pScreen);
+
+ for (p = pVidMode->Next; p != NULL && p != pVidMode->First; p = p->next) {
+ if (p->status == MODE_OK) {
+ pVidMode->Next = p->next;
+ *mode = (pointer)p;
+ *dotClock = VidModeGetDotClock(scrnIndex, p->Clock);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+Bool
+VidModeDeleteModeline(int scrnIndex, pointer mode)
+{
+ ScrnInfoPtr pScrn;
+
+ if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
+ return FALSE;
+
+ pScrn = xf86Screens[scrnIndex];
+ xf86DeleteMode(&(pScrn->modes), (DisplayModePtr)mode);
+ return TRUE;
+}
+
+Bool
+VidModeZoomViewport(int scrnIndex, int zoom)
+{
+ ScrnInfoPtr pScrn;
+
+ if (!VidModeAvailable(scrnIndex))
+ return FALSE;
+
+ pScrn = xf86Screens[scrnIndex];
+ xf86ZoomViewport(pScrn->pScreen, zoom);
+ return TRUE;
+}
+
+Bool
+VidModeSetViewPort(int scrnIndex, int x, int y)
+{
+ ScrnInfoPtr pScrn;
+
+ if (!VidModeAvailable(scrnIndex))
+ return FALSE;
+
+ pScrn = xf86Screens[scrnIndex];
+ pScrn->frameX0 = min( max(x, 0),
+ pScrn->virtualX - pScrn->currentMode->HDisplay );
+ pScrn->frameX1 = pScrn->frameX0 + pScrn->currentMode->HDisplay - 1;
+ pScrn->frameY0 = min( max(y, 0),
+ pScrn->virtualY - pScrn->currentMode->VDisplay );
+ pScrn->frameY1 = pScrn->frameY0 + pScrn->currentMode->VDisplay - 1;
+ if (pScrn->AdjustFrame != NULL)
+ (pScrn->AdjustFrame)(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+
+ return TRUE;
+}
+
+Bool
+VidModeGetViewPort(int scrnIndex, int *x, int *y)
+{
+ ScrnInfoPtr pScrn;
+
+ if (!VidModeAvailable(scrnIndex))
+ return FALSE;
+
+ pScrn = xf86Screens[scrnIndex];
+ *x = pScrn->frameX0;
+ *y = pScrn->frameY0;
+ return TRUE;
+}
+
+Bool
+VidModeSwitchMode(int scrnIndex, pointer mode)
+{
+ ScrnInfoPtr pScrn;
+ DisplayModePtr pTmpMode;
+ Bool retval;
+
+ if (!VidModeAvailable(scrnIndex))
+ return FALSE;
+
+ pScrn = xf86Screens[scrnIndex];
+ /* save in case we fail */
+ pTmpMode = pScrn->currentMode;
+ /* Force a mode switch */
+ pScrn->currentMode = NULL;
+ retval = xf86SwitchMode(pScrn->pScreen, mode);
+ /* we failed: restore it */
+ if (retval == FALSE)
+ pScrn->currentMode = pTmpMode;
+ return retval;
+}
+
+Bool
+VidModeLockZoom(int scrnIndex, Bool lock)
+{
+ ScrnInfoPtr pScrn;
+
+ if (!VidModeAvailable(scrnIndex))
+ return FALSE;
+
+ pScrn = xf86Screens[scrnIndex];
+
+ if (xf86Info.dontZoom)
+ return FALSE;
+
+ xf86LockZoom(pScrn->pScreen, lock);
+ return TRUE;
+}
+
+Bool
+VidModeGetMonitor(int scrnIndex, pointer *monitor)
+{
+ ScrnInfoPtr pScrn;
+
+ if (!VidModeAvailable(scrnIndex))
+ return FALSE;
+
+ pScrn = xf86Screens[scrnIndex];
+ *monitor = (pointer)(pScrn->monitor);
+
+ return TRUE;
+}
+
+ModeStatus
+VidModeCheckModeForMonitor(int scrnIndex, pointer mode)
+{
+ ScrnInfoPtr pScrn;
+
+ if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
+ return MODE_ERROR;
+
+ pScrn = xf86Screens[scrnIndex];
+
+ return xf86CheckModeForMonitor((DisplayModePtr)mode, pScrn->monitor);
+}
+
+ModeStatus
+VidModeCheckModeForDriver(int scrnIndex, pointer mode)
+{
+ ScrnInfoPtr pScrn;
+
+ if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
+ return MODE_ERROR;
+
+ pScrn = xf86Screens[scrnIndex];
+
+ return xf86CheckModeForDriver(pScrn, (DisplayModePtr)mode, 0);
+}
+
+void
+VidModeSetCrtcForMode(int scrnIndex, pointer mode)
+{
+ ScrnInfoPtr pScrn;
+ DisplayModePtr ScreenModes;
+
+ if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
+ return;
+
+ /* Ugly hack so that the xf86Mode.c function can be used without change */
+ pScrn = xf86Screens[scrnIndex];
+ ScreenModes = pScrn->modes;
+ pScrn->modes = (DisplayModePtr)mode;
+
+ xf86SetCrtcForModes(pScrn, pScrn->adjustFlags);
+ pScrn->modes = ScreenModes;
+ return;
+}
+
+Bool
+VidModeAddModeline(int scrnIndex, pointer mode)
+{
+ ScrnInfoPtr pScrn;
+
+ if ((mode == NULL) || (!VidModeAvailable(scrnIndex)))
+ return FALSE;
+
+ pScrn = xf86Screens[scrnIndex];
+
+ ((DisplayModePtr)mode)->name = strdup(""); /* freed by deletemode */
+ ((DisplayModePtr)mode)->status = MODE_OK;
+ ((DisplayModePtr)mode)->next = pScrn->modes->next;
+ ((DisplayModePtr)mode)->prev = pScrn->modes;
+ pScrn->modes->next = (DisplayModePtr)mode;
+ if( ((DisplayModePtr)mode)->next != NULL )
+ ((DisplayModePtr)mode)->next->prev = (DisplayModePtr)mode;
+
+ return TRUE;
+}
+
+int
+VidModeGetNumOfModes(int scrnIndex)
+{
+ pointer mode = NULL;
+ int dotClock= 0, nummodes = 0;
+
+ if (!VidModeGetFirstModeline(scrnIndex, &mode, &dotClock))
+ return nummodes;
+
+ do {
+ nummodes++;
+ if (!VidModeGetNextModeline(scrnIndex, &mode, &dotClock))
+ return nummodes;
+ } while (TRUE);
+}
+
+Bool
+VidModeSetGamma(int scrnIndex, float red, float green, float blue)
+{
+ ScrnInfoPtr pScrn;
+ Gamma gamma;
+
+ if (!VidModeAvailable(scrnIndex))
+ return FALSE;
+
+ pScrn = xf86Screens[scrnIndex];
+ gamma.red = red;
+ gamma.green = green;
+ gamma.blue = blue;
+ if (xf86ChangeGamma(pScrn->pScreen, gamma) != Success)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+Bool
+VidModeGetGamma(int scrnIndex, float *red, float *green, float *blue)
+{
+ ScrnInfoPtr pScrn;
+
+ if (!VidModeAvailable(scrnIndex))
+ return FALSE;
+
+ pScrn = xf86Screens[scrnIndex];
+ *red = pScrn->gamma.red;
+ *green = pScrn->gamma.green;
+ *blue = pScrn->gamma.blue;
+ return TRUE;
+}
+
+Bool
+VidModeSetGammaRamp(int scrnIndex, int size, CARD16 *r, CARD16 *g, CARD16 *b)
+{
+ ScrnInfoPtr pScrn;
+
+ if (!VidModeAvailable(scrnIndex))
+ return FALSE;
+
+ pScrn = xf86Screens[scrnIndex];
+ xf86ChangeGammaRamp(pScrn->pScreen, size, r, g, b);
+ return TRUE;
+}
+
+Bool
+VidModeGetGammaRamp(int scrnIndex, int size, CARD16 *r, CARD16 *g, CARD16 *b)
+{
+ ScrnInfoPtr pScrn;
+
+ if (!VidModeAvailable(scrnIndex))
+ return FALSE;
+
+ pScrn = xf86Screens[scrnIndex];
+ xf86GetGammaRamp(pScrn->pScreen, size, r, g, b);
+ return TRUE;
+}
+
+int
+VidModeGetGammaRampSize(int scrnIndex)
+{
+ if (!VidModeAvailable(scrnIndex))
+ return 0;
+
+ return xf86GetGammaRampSize(xf86Screens[scrnIndex]->pScreen);
+}
+
+pointer
+VidModeCreateMode(void)
+{
+ DisplayModePtr mode;
+
+ mode = malloc(sizeof(DisplayModeRec));
+ if (mode != NULL) {
+ mode->name = "";
+ mode->VScan = 1; /* divides refresh rate. default = 1 */
+ mode->Private = NULL;
+ mode->next = mode;
+ mode->prev = mode;
+ }
+ return mode;
+}
+
+void
+VidModeCopyMode(pointer modefrom, pointer modeto)
+{
+ memcpy(modeto, modefrom, sizeof(DisplayModeRec));
+}
+
+
+int
+VidModeGetModeValue(pointer mode, int valtyp)
+{
+ int ret = 0;
+
+ switch (valtyp) {
+ case VIDMODE_H_DISPLAY:
+ ret = ((DisplayModePtr) mode)->HDisplay;
+ break;
+ case VIDMODE_H_SYNCSTART:
+ ret = ((DisplayModePtr)mode)->HSyncStart;
+ break;
+ case VIDMODE_H_SYNCEND:
+ ret = ((DisplayModePtr)mode)->HSyncEnd;
+ break;
+ case VIDMODE_H_TOTAL:
+ ret = ((DisplayModePtr)mode)->HTotal;
+ break;
+ case VIDMODE_H_SKEW:
+ ret = ((DisplayModePtr)mode)->HSkew;
+ break;
+ case VIDMODE_V_DISPLAY:
+ ret = ((DisplayModePtr)mode)->VDisplay;
+ break;
+ case VIDMODE_V_SYNCSTART:
+ ret = ((DisplayModePtr)mode)->VSyncStart;
+ break;
+ case VIDMODE_V_SYNCEND:
+ ret = ((DisplayModePtr)mode)->VSyncEnd;
+ break;
+ case VIDMODE_V_TOTAL:
+ ret = ((DisplayModePtr)mode)->VTotal;
+ break;
+ case VIDMODE_FLAGS:
+ ret = ((DisplayModePtr)mode)->Flags;
+ break;
+ case VIDMODE_CLOCK:
+ ret = ((DisplayModePtr)mode)->Clock;
+ break;
+ }
+ return ret;
+}
+
+void
+VidModeSetModeValue(pointer mode, int valtyp, int val)
+{
+ switch (valtyp) {
+ case VIDMODE_H_DISPLAY:
+ ((DisplayModePtr)mode)->HDisplay = val;
+ break;
+ case VIDMODE_H_SYNCSTART:
+ ((DisplayModePtr)mode)->HSyncStart = val;
+ break;
+ case VIDMODE_H_SYNCEND:
+ ((DisplayModePtr)mode)->HSyncEnd = val;
+ break;
+ case VIDMODE_H_TOTAL:
+ ((DisplayModePtr)mode)->HTotal = val;
+ break;
+ case VIDMODE_H_SKEW:
+ ((DisplayModePtr)mode)->HSkew = val;
+ break;
+ case VIDMODE_V_DISPLAY:
+ ((DisplayModePtr)mode)->VDisplay = val;
+ break;
+ case VIDMODE_V_SYNCSTART:
+ ((DisplayModePtr)mode)->VSyncStart = val;
+ break;
+ case VIDMODE_V_SYNCEND:
+ ((DisplayModePtr)mode)->VSyncEnd = val;
+ break;
+ case VIDMODE_V_TOTAL:
+ ((DisplayModePtr)mode)->VTotal = val;
+ break;
+ case VIDMODE_FLAGS:
+ ((DisplayModePtr)mode)->Flags = val;
+ break;
+ case VIDMODE_CLOCK:
+ ((DisplayModePtr)mode)->Clock = val;
+ break;
+ }
+ return;
+}
+
+vidMonitorValue
+VidModeGetMonitorValue(pointer monitor, int valtyp, int indx)
+{
+ vidMonitorValue ret;
+
+ switch (valtyp) {
+ case VIDMODE_MON_VENDOR:
+ ret.ptr = (((MonPtr)monitor)->vendor);
+ break;
+ case VIDMODE_MON_MODEL:
+ ret.ptr = (((MonPtr)monitor)->model);
+ break;
+ case VIDMODE_MON_NHSYNC:
+ ret.i = ((MonPtr)monitor)->nHsync;
+ break;
+ case VIDMODE_MON_NVREFRESH:
+ ret.i = ((MonPtr)monitor)->nVrefresh;
+ break;
+ case VIDMODE_MON_HSYNC_LO:
+ ret.f = (100.0 * ((MonPtr)monitor)->hsync[indx].lo);
+ break;
+ case VIDMODE_MON_HSYNC_HI:
+ ret.f = (100.0 * ((MonPtr)monitor)->hsync[indx].hi);
+ break;
+ case VIDMODE_MON_VREFRESH_LO:
+ ret.f = (100.0 * ((MonPtr)monitor)->vrefresh[indx].lo);
+ break;
+ case VIDMODE_MON_VREFRESH_HI:
+ ret.f = (100.0 * ((MonPtr)monitor)->vrefresh[indx].hi);
+ break;
+ }
+ return ret;
+}
+
+
+#endif /* XF86VIDMODE */
diff --git a/xorg-server/hw/xfree86/common/xf86Xinput.c b/xorg-server/hw/xfree86/common/xf86Xinput.c
index a1a5527f4..f1096f1a5 100644
--- a/xorg-server/hw/xfree86/common/xf86Xinput.c
+++ b/xorg-server/hw/xfree86/common/xf86Xinput.c
@@ -1,1284 +1,1284 @@
-/*
- * Copyright 1995-1999 by Frederic Lepied, France. <Lepied@XFree86.org>
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Frederic Lepied not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Frederic Lepied makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * FREDERIC LEPIED DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL FREDERIC LEPIED BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- */
-/*
- * Copyright (c) 2000-2002 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <X11/Xfuncproto.h>
-#include <X11/Xmd.h>
-#include <X11/extensions/XI.h>
-#include <X11/extensions/XIproto.h>
-#include <X11/Xatom.h>
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86Config.h"
-#include "xf86Xinput.h"
-#include "XIstubs.h"
-#include "xf86Optrec.h"
-#include "xf86Parser.h"
-#include "mipointer.h"
-#include "xf86InPriv.h"
-#include "compiler.h"
-#include "extinit.h"
-
-#ifdef DPMSExtension
-#include <X11/extensions/dpmsconst.h>
-#include "dpmsproc.h"
-#endif
-
-#include "exevents.h" /* AddInputDevice */
-#include "exglobals.h"
-#include "eventstr.h"
-
-#include <string.h> /* InputClassMatches */
-#ifdef HAVE_FNMATCH_H
-#include <fnmatch.h>
-#endif
-
-#include "extnsionst.h"
-
-#include "windowstr.h" /* screenIsSaved */
-
-#include <stdarg.h>
-#include <stdint.h> /* for int64_t */
-
-#include <X11/Xpoll.h>
-
-#include "mi.h"
-
-#include <ptrveloc.h> /* dix pointer acceleration */
-#include <xserver-properties.h>
-
-#ifdef XFreeXDGA
-#include "dgaproc.h"
-#endif
-
-#include "xkbsrv.h"
-
-#include "os.h"
-
-EventListPtr xf86Events = NULL;
-
-/**
- * Eval config and modify DeviceVelocityRec accordingly
- */
-static void
-ProcessVelocityConfiguration(DeviceIntPtr pDev, char* devname, pointer list,
- DeviceVelocityPtr s)
-{
- int tempi;
- float tempf;
- Atom float_prop = XIGetKnownProperty(XATOM_FLOAT);
- Atom prop;
-
- if(!s)
- return;
-
- /* common settings (available via device properties) */
- tempf = xf86SetRealOption(list, "ConstantDeceleration", 1.0);
- if (tempf > 1.0) {
- xf86Msg(X_CONFIG, "%s: (accel) constant deceleration by %.1f\n",
- devname, tempf);
- prop = XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION);
- XIChangeDeviceProperty(pDev, prop, float_prop, 32,
- PropModeReplace, 1, &tempf, FALSE);
- }
-
- tempf = xf86SetRealOption(list, "AdaptiveDeceleration", 1.0);
- if (tempf > 1.0) {
- xf86Msg(X_CONFIG, "%s: (accel) adaptive deceleration by %.1f\n",
- devname, tempf);
- prop = XIGetKnownProperty(ACCEL_PROP_ADAPTIVE_DECELERATION);
- XIChangeDeviceProperty(pDev, prop, float_prop, 32,
- PropModeReplace, 1, &tempf, FALSE);
- }
-
- /* select profile by number */
- tempi = xf86SetIntOption(list, "AccelerationProfile",
- s->statistics.profile_number);
-
- prop = XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER);
- if (XIChangeDeviceProperty(pDev, prop, XA_INTEGER, 32,
- PropModeReplace, 1, &tempi, FALSE) == Success) {
- xf86Msg(X_CONFIG, "%s: (accel) acceleration profile %i\n", devname,
- tempi);
- } else {
- xf86Msg(X_CONFIG, "%s: (accel) acceleration profile %i is unknown\n",
- devname, tempi);
- }
-
- /* set scaling */
- tempf = xf86SetRealOption(list, "ExpectedRate", 0);
- prop = XIGetKnownProperty(ACCEL_PROP_VELOCITY_SCALING);
- if (tempf > 0) {
- tempf = 1000.0 / tempf;
- XIChangeDeviceProperty(pDev, prop, float_prop, 32,
- PropModeReplace, 1, &tempf, FALSE);
- } else {
- tempf = xf86SetRealOption(list, "VelocityScale", s->corr_mul);
- XIChangeDeviceProperty(pDev, prop, float_prop, 32,
- PropModeReplace, 1, &tempf, FALSE);
- }
-
- tempi = xf86SetIntOption(list, "VelocityTrackerCount", -1);
- if (tempi > 1)
- InitTrackers(s, tempi);
-
- s->initial_range = xf86SetIntOption(list, "VelocityInitialRange",
- s->initial_range);
-
- s->max_diff = xf86SetRealOption(list, "VelocityAbsDiff", s->max_diff);
-
- tempf = xf86SetRealOption(list, "VelocityRelDiff", -1);
- if (tempf >= 0) {
- xf86Msg(X_CONFIG, "%s: (accel) max rel. velocity difference: %.1f%%\n",
- devname, tempf*100.0);
- s->max_rel_diff = tempf;
- }
-
- /* Configure softening. If const deceleration is used, this is expected
- * to provide better subpixel information so we enable
- * softening by default only if ConstantDeceleration is not used
- */
- s->use_softening = xf86SetBoolOption(list, "Softening",
- s->const_acceleration == 1.0);
-
- s->average_accel = xf86SetBoolOption(list, "AccelerationProfileAveraging",
- s->average_accel);
-
- s->reset_time = xf86SetIntOption(list, "VelocityReset", s->reset_time);
-}
-
-static void
-ApplyAccelerationSettings(DeviceIntPtr dev){
- int scheme, i;
- DeviceVelocityPtr pVel;
- LocalDevicePtr local = (LocalDevicePtr)dev->public.devicePrivate;
- char* schemeStr;
-
- if (dev->valuator && dev->ptrfeed) {
- schemeStr = xf86SetStrOption(local->options, "AccelerationScheme", "");
-
- scheme = dev->valuator->accelScheme.number;
-
- if (!xf86NameCmp(schemeStr, "predictable"))
- scheme = PtrAccelPredictable;
-
- if (!xf86NameCmp(schemeStr, "lightweight"))
- scheme = PtrAccelLightweight;
-
- if (!xf86NameCmp(schemeStr, "none"))
- scheme = PtrAccelNoOp;
-
- /* reinit scheme if needed */
- if (dev->valuator->accelScheme.number != scheme) {
- if (dev->valuator->accelScheme.AccelCleanupProc) {
- dev->valuator->accelScheme.AccelCleanupProc(dev);
- }
-
- if (InitPointerAccelerationScheme(dev, scheme)) {
- xf86Msg(X_CONFIG, "%s: (accel) selected scheme %s/%i\n",
- local->name, schemeStr, scheme);
- } else {
- xf86Msg(X_CONFIG, "%s: (accel) could not init scheme %s\n",
- local->name, schemeStr);
- scheme = dev->valuator->accelScheme.number;
- }
- } else {
- xf86Msg(X_CONFIG, "%s: (accel) keeping acceleration scheme %i\n",
- local->name, scheme);
- }
-
- xfree(schemeStr);
-
- /* process special configuration */
- switch (scheme) {
- case PtrAccelPredictable:
- pVel = GetDevicePredictableAccelData(dev);
- ProcessVelocityConfiguration (dev, local->name, local->options,
- pVel);
- break;
- }
-
- i = xf86SetIntOption(local->options, "AccelerationNumerator",
- dev->ptrfeed->ctrl.num);
- if (i >= 0)
- dev->ptrfeed->ctrl.num = i;
-
- i = xf86SetIntOption(local->options, "AccelerationDenominator",
- dev->ptrfeed->ctrl.den);
- if (i > 0)
- dev->ptrfeed->ctrl.den = i;
-
- i = xf86SetIntOption(local->options, "AccelerationThreshold",
- dev->ptrfeed->ctrl.threshold);
- if (i >= 0)
- dev->ptrfeed->ctrl.threshold = i;
-
- /* mostly a no-op anyway */
- (*dev->ptrfeed->CtrlProc)(dev, &dev->ptrfeed->ctrl);
-
- xf86Msg(X_CONFIG, "%s: (accel) acceleration factor: %.3f\n",
- local->name, ((float)dev->ptrfeed->ctrl.num)/
- ((float)dev->ptrfeed->ctrl.den));
- xf86Msg(X_CONFIG, "%s: (accel) acceleration threshold: %i\n",
- local->name, dev->ptrfeed->ctrl.threshold);
- }
-}
-
-static Bool
-xf86SendDragEvents(DeviceIntPtr device)
-{
- LocalDevicePtr local = (LocalDevicePtr) device->public.devicePrivate;
-
- if (device->button && device->button->buttonsDown > 0)
- return (local->flags & XI86_SEND_DRAG_EVENTS);
- else
- return (TRUE);
-}
-
-/***********************************************************************
- *
- * xf86ProcessCommonOptions --
- *
- * Process global options.
- *
- ***********************************************************************
- */
-void
-xf86ProcessCommonOptions(LocalDevicePtr local,
- pointer list)
-{
- if (!xf86SetBoolOption(list, "AlwaysCore", 1) ||
- !xf86SetBoolOption(list, "SendCoreEvents", 1) ||
- !xf86SetBoolOption(list, "CorePointer", 1) ||
- !xf86SetBoolOption(list, "CoreKeyboard", 1)) {
- xf86Msg(X_CONFIG, "%s: doesn't report core events\n", local->name);
- } else {
- local->flags |= XI86_ALWAYS_CORE;
- xf86Msg(X_CONFIG, "%s: always reports core events\n", local->name);
- }
-
- if (xf86SetBoolOption(list, "SendDragEvents", 1)) {
- local->flags |= XI86_SEND_DRAG_EVENTS;
- } else {
- xf86Msg(X_CONFIG, "%s: doesn't report drag events\n", local->name);
- }
-
- /* Backwards compatibility. */
- local->history_size = GetMotionHistorySize();
-}
-
-/***********************************************************************
- *
- * xf86ActivateDevice --
- *
- * Initialize an input device.
- *
- * Returns TRUE on success, or FALSE otherwise.
- ***********************************************************************
- */
-int
-xf86ActivateDevice(LocalDevicePtr local)
-{
- DeviceIntPtr dev;
-
- if (local->flags & XI86_CONFIGURED) {
- dev = AddInputDevice(serverClient, local->device_control, TRUE);
-
- if (dev == NULL)
- {
- xf86Msg(X_ERROR, "Too many input devices. Ignoring %s\n",
- local->name);
- local->dev = NULL;
- return FALSE;
- }
-
- local->atom = MakeAtom(local->type_name,
- strlen(local->type_name),
- TRUE);
- AssignTypeAndName(dev, local->atom, local->name);
- dev->public.devicePrivate = (pointer) local;
- local->dev = dev;
-
- dev->coreEvents = local->flags & XI86_ALWAYS_CORE;
- dev->type = SLAVE;
- dev->spriteInfo->spriteOwner = FALSE;
-
- dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
- dev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
-
- RegisterOtherDevice(dev);
- XkbSetExtension(dev, ProcessKeyboardEvent);
-
- if (serverGeneration == 1)
- xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s)\n",
- local->name, local->type_name);
- }
-
- return TRUE;
-}
-
-
-/***********************************************************************
- *
- * Caller: ProcXOpenDevice
- *
- * This is the implementation-dependent routine to open an input device.
- * Some implementations open all input devices when the server is first
- * initialized, and never close them. Other implementations open only
- * the X pointer and keyboard devices during server initialization,
- * and only open other input devices when some client makes an
- * XOpenDevice request. This entry point is for the latter type of
- * implementation.
- *
- * If the physical device is not already open, do it here. In this case,
- * you need to keep track of the fact that one or more clients has the
- * device open, and physically close it when the last client that has
- * it open does an XCloseDevice.
- *
- * The default implementation is to do nothing (assume all input devices
- * are opened during X server initialization and kept open).
- *
- ***********************************************************************
- */
-
-void
-OpenInputDevice(DeviceIntPtr dev,
- ClientPtr client,
- int *status)
-{
- if (!dev->inited)
- ActivateDevice(dev, TRUE);
-
- *status = Success;
-}
-
-void
-CloseInputDevice(DeviceIntPtr dev,
- ClientPtr client)
-{
-}
-
-/****************************************************************************
- *
- * Caller: ProcXSetDeviceMode
- *
- * Change the mode of an extension device.
- * This function is used to change the mode of a device from reporting
- * relative motion to reporting absolute positional information, and
- * vice versa.
- * The default implementation below is that no such devices are supported.
- *
- ***********************************************************************
- */
-
-int
-SetDeviceMode (ClientPtr client, DeviceIntPtr dev, int mode)
-{
- LocalDevicePtr local = (LocalDevicePtr)dev->public.devicePrivate;
-
- if (local->switch_mode) {
- return (*local->switch_mode)(client, dev, mode);
- }
- else
- return BadMatch;
-}
-
-
-/***********************************************************************
- *
- * Caller: ProcXSetDeviceValuators
- *
- * Set the value of valuators on an extension input device.
- * This function is used to set the initial value of valuators on
- * those input devices that are capable of reporting either relative
- * motion or an absolute position, and allow an initial position to be set.
- * The default implementation below is that no such devices are supported.
- *
- ***********************************************************************
- */
-
-int
-SetDeviceValuators (ClientPtr client, DeviceIntPtr dev, int *valuators,
- int first_valuator, int num_valuators)
-{
- LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
-
- if (local->set_device_valuators)
- return (*local->set_device_valuators)(local, valuators, first_valuator,
- num_valuators);
-
- return BadMatch;
-}
-
-
-/***********************************************************************
- *
- * Caller: ProcXChangeDeviceControl
- *
- * Change the specified device controls on an extension input device.
- *
- ***********************************************************************
- */
-
-int
-ChangeDeviceControl (ClientPtr client, DeviceIntPtr dev, xDeviceCtl *control)
-{
- LocalDevicePtr local = (LocalDevicePtr)dev->public.devicePrivate;
-
- if (!local->control_proc) {
- switch (control->control) {
- case DEVICE_CORE:
- return BadMatch;
- case DEVICE_RESOLUTION:
- case DEVICE_ABS_CALIB:
- case DEVICE_ABS_AREA:
- case DEVICE_ENABLE:
- return Success;
- default:
- return BadMatch;
- }
- }
- else {
- return (*local->control_proc)(local, control);
- }
-}
-
-void
-AddOtherInputDevices(void)
-{
-}
-
-/*
- * Classes without any Match statements match all devices. Otherwise, all
- * statements must match.
- */
-static Bool
-InputClassMatches(XF86ConfInputClassPtr iclass, InputAttributes *attrs)
-{
- char **cur;
- Bool match;
-
- if (iclass->match_product) {
- if (!attrs->product)
- return FALSE;
- /* see if any of the values match */
- for (cur = iclass->match_product, match = FALSE; *cur; cur++)
- if (strstr(attrs->product, *cur)) {
- match = TRUE;
- break;
- }
- if (!match)
- return FALSE;
- }
- if (iclass->match_vendor) {
- if (!attrs->vendor)
- return FALSE;
- /* see if any of the values match */
- for (cur = iclass->match_vendor, match = FALSE; *cur; cur++)
- if (strstr(attrs->vendor, *cur)) {
- match = TRUE;
- break;
- }
- if (!match)
- return FALSE;
- }
- if (iclass->match_device) {
- if (!attrs->device)
- return FALSE;
- /* see if any of the values match */
- for (cur = iclass->match_device, match = FALSE; *cur; cur++)
-#ifdef HAVE_FNMATCH_H
- if (fnmatch(*cur, attrs->device, FNM_PATHNAME) == 0) {
-#else
- if (strstr(attrs->device, *cur)) {
-#endif
- match = TRUE;
- break;
- }
- if (!match)
- return FALSE;
- }
- if (iclass->match_tag) {
- if (!attrs->tags)
- return FALSE;
-
- for (cur = iclass->match_tag, match = FALSE; *cur && !match; cur++) {
- const char *tag;
- for(tag = *attrs->tags; *tag; tag++) {
- if (!strcmp(tag, *cur)) {
- match = TRUE;
- break;
- }
- }
- }
-
- if (!match)
- return FALSE;
- }
-
- if (iclass->is_keyboard.set &&
- iclass->is_keyboard.val != !!(attrs->flags & ATTR_KEYBOARD))
- return FALSE;
- if (iclass->is_pointer.set &&
- iclass->is_pointer.val != !!(attrs->flags & ATTR_POINTER))
- return FALSE;
- if (iclass->is_joystick.set &&
- iclass->is_joystick.val != !!(attrs->flags & ATTR_JOYSTICK))
- return FALSE;
- if (iclass->is_tablet.set &&
- iclass->is_tablet.val != !!(attrs->flags & ATTR_TABLET))
- return FALSE;
- if (iclass->is_touchpad.set &&
- iclass->is_touchpad.val != !!(attrs->flags & ATTR_TOUCHPAD))
- return FALSE;
- if (iclass->is_touchscreen.set &&
- iclass->is_touchscreen.val != !!(attrs->flags & ATTR_TOUCHSCREEN))
- return FALSE;
- return TRUE;
-}
-
-/*
- * Merge in any InputClass configurations. Options in each InputClass
- * section have more priority than the original device configuration as
- * well as any previous InputClass sections.
- */
-static int
-MergeInputClasses(IDevPtr idev, InputAttributes *attrs)
-{
- XF86ConfInputClassPtr cl;
- XF86OptionPtr classopts, mergedopts = NULL;
- char *classdriver = NULL;
-
- for (cl = xf86configptr->conf_inputclass_lst; cl; cl = cl->list.next) {
- if (!InputClassMatches(cl, attrs))
- continue;
-
- /* Collect class options and merge over previous classes */
- xf86Msg(X_CONFIG, "%s: Applying InputClass \"%s\"\n",
- idev->identifier, cl->identifier);
- if (cl->driver)
- classdriver = cl->driver;
- classopts = xf86optionListDup(cl->option_lst);
- mergedopts = xf86optionListMerge(mergedopts, classopts);
- }
-
- /* Apply options to device with InputClass settings preferred. */
- if (classdriver) {
- xfree(idev->driver);
- idev->driver = xstrdup(classdriver);
- if (!idev->driver) {
- xf86Msg(X_ERROR, "Failed to allocate memory while merging "
- "InputClass configuration");
- return BadAlloc;
- }
- mergedopts = xf86ReplaceStrOption(mergedopts, "driver", idev->driver);
- }
- idev->commonOptions = xf86optionListMerge(idev->commonOptions, mergedopts);
-
- return Success;
-}
-
-/*
- * Iterate the list of classes and look for Option "Ignore". Return the
- * value of the last matching class and holler when returning TRUE.
- */
-static Bool
-IgnoreInputClass(IDevPtr idev, InputAttributes *attrs)
-{
- XF86ConfInputClassPtr cl;
- Bool ignore = FALSE;
- const char *ignore_class;
-
- for (cl = xf86configptr->conf_inputclass_lst; cl; cl = cl->list.next) {
- if (!InputClassMatches(cl, attrs))
- continue;
- if (xf86findOption(cl->option_lst, "Ignore")) {
- ignore = xf86CheckBoolOption(cl->option_lst, "Ignore", FALSE);
- ignore_class = cl->identifier;
- }
- }
-
- if (ignore)
- xf86Msg(X_CONFIG, "%s: Ignoring device from InputClass \"%s\"\n",
- idev->identifier, ignore_class);
- return ignore;
-}
-
-/**
- * Create a new input device, activate and enable it.
- *
- * Possible return codes:
- * BadName .. a bad driver name was supplied.
- * BadImplementation ... The driver does not have a PreInit function. This
- * is a driver bug.
- * BadMatch .. device initialization failed.
- * BadAlloc .. too many input devices
- *
- * @param idev The device, already set up with identifier, driver, and the
- * options.
- * @param pdev Pointer to the new device, if Success was reported.
- * @param enable Enable the device after activating it.
- *
- * @return Success or an error code
- */
-_X_INTERNAL int
-xf86NewInputDevice(IDevPtr idev, DeviceIntPtr *pdev, BOOL enable)
-{
- InputDriverPtr drv = NULL;
- InputInfoPtr pInfo = NULL;
- DeviceIntPtr dev = NULL;
- int rval;
-
- /* Memory leak for every attached device if we don't
- * test if the module is already loaded first */
- drv = xf86LookupInputDriver(idev->driver);
- if (!drv)
- if (xf86LoadOneModule(idev->driver, NULL))
- drv = xf86LookupInputDriver(idev->driver);
- if (!drv) {
- xf86Msg(X_ERROR, "No input driver matching `%s'\n", idev->driver);
- rval = BadName;
- goto unwind;
- }
-
- if (!drv->PreInit) {
- xf86Msg(X_ERROR,
- "Input driver `%s' has no PreInit function (ignoring)\n",
- drv->driverName);
- rval = BadImplementation;
- goto unwind;
- }
-
- pInfo = drv->PreInit(drv, idev, 0);
-
- if (!pInfo) {
- xf86Msg(X_ERROR, "PreInit returned NULL for \"%s\"\n", idev->identifier);
- rval = BadMatch;
- goto unwind;
- }
- else if (!(pInfo->flags & XI86_CONFIGURED)) {
- xf86Msg(X_ERROR, "PreInit failed for input device \"%s\"\n",
- idev->identifier);
- rval = BadMatch;
- goto unwind;
- }
-
- if (!xf86ActivateDevice(pInfo))
- {
- rval = BadAlloc;
- goto unwind;
- }
-
- dev = pInfo->dev;
- rval = ActivateDevice(dev, TRUE);
- if (rval != Success)
- {
- xf86Msg(X_ERROR, "Couldn't init device \"%s\"\n", idev->identifier);
- RemoveDevice(dev, TRUE);
- goto unwind;
- }
-
- /* Enable it if it's properly initialised and we're currently in the VT */
- if (enable && dev->inited && dev->startup && xf86Screens[0]->vtSema)
- {
- EnableDevice(dev, TRUE);
- if (!dev->enabled)
- {
- xf86Msg(X_ERROR, "Couldn't init device \"%s\"\n", idev->identifier);
- rval = BadMatch;
- goto unwind;
- }
- /* send enter/leave event, update sprite window */
- CheckMotion(NULL, dev);
- }
-
- *pdev = dev;
- return Success;
-
-unwind:
- if(pInfo) {
- if(drv->UnInit)
- drv->UnInit(drv, pInfo, 0);
- else
- xf86DeleteInput(pInfo, 0);
- }
- return rval;
-}
-
-int
-NewInputDeviceRequest (InputOption *options, InputAttributes *attrs,
- DeviceIntPtr *pdev)
-{
- IDevRec *idev = NULL;
- InputOption *option = NULL;
- int rval = Success;
- int is_auto = 0;
-
- idev = xcalloc(sizeof(*idev), 1);
- if (!idev)
- return BadAlloc;
-
- for (option = options; option; option = option->next) {
- if (strcasecmp(option->key, "driver") == 0) {
- if (idev->driver) {
- rval = BadRequest;
- goto unwind;
- }
- idev->driver = xstrdup(option->value);
- if (!idev->driver) {
- rval = BadAlloc;
- goto unwind;
- }
- }
-
- if (strcasecmp(option->key, "name") == 0 ||
- strcasecmp(option->key, "identifier") == 0) {
- if (idev->identifier) {
- rval = BadRequest;
- goto unwind;
- }
- idev->identifier = xstrdup(option->value);
- if (!idev->identifier) {
- rval = BadAlloc;
- goto unwind;
- }
- }
-
- if (strcmp(option->key, "_source") == 0 &&
- (strcmp(option->value, "server/hal") == 0 ||
- strcmp(option->value, "server/udev") == 0)) {
- is_auto = 1;
- if (!xf86Info.autoAddDevices) {
- rval = BadMatch;
- goto unwind;
- }
- }
- }
-
- for (option = options; option; option = option->next) {
- /* Steal option key/value strings from the provided list.
- * We need those strings, the InputOption list doesn't. */
- idev->commonOptions = xf86addNewOption(idev->commonOptions,
- option->key, option->value);
- option->key = NULL;
- option->value = NULL;
- }
-
- /* Apply InputClass settings */
- if (attrs) {
- if (IgnoreInputClass(idev, attrs)) {
- rval = BadIDChoice;
- goto unwind;
- }
-
- rval = MergeInputClasses(idev, attrs);
- if (rval != Success)
- goto unwind;
- }
-
- if (!idev->driver || !idev->identifier) {
- xf86Msg(X_INFO, "No input driver/identifier specified (ignoring)\n");
- rval = BadRequest;
- goto unwind;
- }
-
- if (!idev->identifier) {
- xf86Msg(X_ERROR, "No device identifier specified (ignoring)\n");
- return BadMatch;
- }
-
- rval = xf86NewInputDevice(idev, pdev,
- (!is_auto || (is_auto && xf86Info.autoEnableDevices)));
- if (rval == Success)
- return Success;
-
-unwind:
- if (is_auto && !xf86Info.autoAddDevices)
- xf86Msg(X_INFO, "AutoAddDevices is off - not adding device.\n");
- if(idev->driver)
- xfree(idev->driver);
- if(idev->identifier)
- xfree(idev->identifier);
- xf86optionListFree(idev->commonOptions);
- xfree(idev);
- return rval;
-}
-
-void
-DeleteInputDeviceRequest(DeviceIntPtr pDev)
-{
- LocalDevicePtr pInfo = (LocalDevicePtr) pDev->public.devicePrivate;
- InputDriverPtr drv = NULL;
- IDevRec *idev = NULL;
- IDevPtr *it;
- Bool isMaster = IsMaster(pDev);
-
- if (pInfo) /* need to get these before RemoveDevice */
- {
- drv = pInfo->drv;
- idev = pInfo->conf_idev;
- }
-
- OsBlockSignals();
- RemoveDevice(pDev, TRUE);
-
- if (!isMaster && pInfo != NULL)
- {
- if(drv->UnInit)
- drv->UnInit(drv, pInfo, 0);
- else
- xf86DeleteInput(pInfo, 0);
-
- /* devices added through HAL aren't in the config layout */
- it = xf86ConfigLayout.inputs;
- while(*it && *it != idev)
- it++;
-
- if (!(*it)) /* end of list, not in the layout */
- {
- xfree(idev->driver);
- xfree(idev->identifier);
- xf86optionListFree(idev->commonOptions);
- xfree(idev);
- }
- }
- OsReleaseSignals();
-}
-
-/*
- * convenient functions to post events
- */
-
-void
-xf86PostMotionEvent(DeviceIntPtr device,
- int is_absolute,
- int first_valuator,
- int num_valuators,
- ...)
-{
- va_list var;
- int i = 0;
- static int valuators[MAX_VALUATORS];
-
- XI_VERIFY_VALUATORS(num_valuators);
-
- va_start(var, num_valuators);
- for (i = 0; i < num_valuators; i++)
- valuators[i] = va_arg(var, int);
- va_end(var);
-
- xf86PostMotionEventP(device, is_absolute, first_valuator, num_valuators, valuators);
-}
-
-void
-xf86PostMotionEventP(DeviceIntPtr device,
- int is_absolute,
- int first_valuator,
- int num_valuators,
- int *valuators)
-{
- int i = 0, nevents = 0;
- Bool drag = xf86SendDragEvents(device);
- DeviceEvent *event;
- int flags = 0;
-
-#if XFreeXDGA
- int index;
- int dx = 0, dy = 0;
-#endif
-
- XI_VERIFY_VALUATORS(num_valuators);
-
- if (is_absolute)
- flags = POINTER_ABSOLUTE;
- else
- flags = POINTER_RELATIVE | POINTER_ACCELERATE;
-
-#if XFreeXDGA
- /* The evdev driver may not always send all axes across. */
- if (num_valuators >= 1 && first_valuator <= 1) {
- if (miPointerGetScreen(device)) {
- index = miPointerGetScreen(device)->myNum;
- if (first_valuator == 0)
- {
- dx = valuators[0];
- if (is_absolute)
- dx -= device->last.valuators[0];
- }
-
- if (first_valuator == 1 || num_valuators >= 2)
- {
- dy = valuators[1 - first_valuator];
- if (is_absolute)
- dy -= device->last.valuators[1];
- }
-
- if (DGAStealMotionEvent(device, index, dx, dy))
- return;
- }
- }
-#endif
-
- nevents = GetPointerEvents(xf86Events, device, MotionNotify, 0,
- flags, first_valuator, num_valuators,
- valuators);
-
- for (i = 0; i < nevents; i++) {
- event = (DeviceEvent*)((xf86Events + i)->event);
- /* Don't post core motion events for devices not registered to send
- * drag events. */
- if (event->header == ET_Internal &&
- (event->type != ET_Motion || drag)) {
- mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
- }
- }
-}
-
-void
-xf86PostProximityEvent(DeviceIntPtr device,
- int is_in,
- int first_valuator,
- int num_valuators,
- ...)
-{
- va_list var;
- int i;
- int valuators[MAX_VALUATORS];
-
- XI_VERIFY_VALUATORS(num_valuators);
-
- va_start(var, num_valuators);
- for (i = 0; i < num_valuators; i++)
- valuators[i] = va_arg(var, int);
- va_end(var);
-
- xf86PostProximityEventP(device, is_in, first_valuator, num_valuators,
- valuators);
-
-}
-
-void
-xf86PostProximityEventP(DeviceIntPtr device,
- int is_in,
- int first_valuator,
- int num_valuators,
- int *valuators)
-{
- int i, nevents;
-
- XI_VERIFY_VALUATORS(num_valuators);
-
- nevents = GetProximityEvents(xf86Events, device,
- is_in ? ProximityIn : ProximityOut,
- first_valuator, num_valuators, valuators);
- for (i = 0; i < nevents; i++)
- mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
-
-}
-
-void
-xf86PostButtonEvent(DeviceIntPtr device,
- int is_absolute,
- int button,
- int is_down,
- int first_valuator,
- int num_valuators,
- ...)
-{
- va_list var;
- int valuators[MAX_VALUATORS];
- int i = 0;
-
- XI_VERIFY_VALUATORS(num_valuators);
-
- va_start(var, num_valuators);
- for (i = 0; i < num_valuators; i++)
- valuators[i] = va_arg(var, int);
- va_end(var);
-
- xf86PostButtonEventP(device, is_absolute, button, is_down, first_valuator,
- num_valuators, valuators);
-
-}
-
-void
-xf86PostButtonEventP(DeviceIntPtr device,
- int is_absolute,
- int button,
- int is_down,
- int first_valuator,
- int num_valuators,
- int *valuators)
-{
- int i = 0, nevents = 0;
- int flags = 0;
-
-#if XFreeXDGA
- int index;
-#endif
-
- XI_VERIFY_VALUATORS(num_valuators);
-
- if (is_absolute)
- flags = POINTER_ABSOLUTE;
- else
- flags = POINTER_RELATIVE | POINTER_ACCELERATE;
-
-#if XFreeXDGA
- if (miPointerGetScreen(device)) {
- index = miPointerGetScreen(device)->myNum;
- if (DGAStealButtonEvent(device, index, button, is_down))
- return;
- }
-#endif
-
- nevents = GetPointerEvents(xf86Events, device,
- is_down ? ButtonPress : ButtonRelease, button,
- flags, first_valuator, num_valuators, valuators);
-
- for (i = 0; i < nevents; i++)
- mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
-
-}
-
-void
-xf86PostKeyEvent(DeviceIntPtr device,
- unsigned int key_code,
- int is_down,
- int is_absolute,
- int first_valuator,
- int num_valuators,
- ...)
-{
- va_list var;
- int i = 0;
- static int valuators[MAX_VALUATORS];
-
- XI_VERIFY_VALUATORS(num_valuators);
-
- va_start(var, num_valuators);
- for (i = 0; i < num_valuators; i++)
- valuators[i] = va_arg(var, int);
- va_end(var);
-
- xf86PostKeyEventP(device, key_code, is_down, is_absolute, first_valuator,
- num_valuators, valuators);
-
-}
-
-void
-xf86PostKeyEventP(DeviceIntPtr device,
- unsigned int key_code,
- int is_down,
- int is_absolute,
- int first_valuator,
- int num_valuators,
- int *valuators)
-{
- int i = 0, nevents = 0;
-
- XI_VERIFY_VALUATORS(num_valuators);
-
- if (is_absolute) {
- nevents = GetKeyboardValuatorEvents(xf86Events, device,
- is_down ? KeyPress : KeyRelease,
- key_code, first_valuator,
- num_valuators, valuators);
- }
- else {
- nevents = GetKeyboardEvents(xf86Events, device,
- is_down ? KeyPress : KeyRelease,
- key_code);
- }
-
- for (i = 0; i < nevents; i++)
- mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
-}
-
-void
-xf86PostKeyboardEvent(DeviceIntPtr device,
- unsigned int key_code,
- int is_down)
-{
- xf86PostKeyEventP(device, key_code, is_down, 0, 0, 0, NULL);
-}
-
-LocalDevicePtr
-xf86FirstLocalDevice(void)
-{
- return xf86InputDevs;
-}
-
-/*
- * Cx - raw data from touch screen
- * Sxhigh - scaled highest dimension
- * (remember, this is of rows - 1 because of 0 origin)
- * Sxlow - scaled lowest dimension
- * Rxhigh - highest raw value from touch screen calibration
- * Rxlow - lowest raw value from touch screen calibration
- *
- * This function is the same for X or Y coordinates.
- * You may have to reverse the high and low values to compensate for
- * different orgins on the touch screen vs X.
- */
-
-int
-xf86ScaleAxis(int Cx,
- int Sxhigh,
- int Sxlow,
- int Rxhigh,
- int Rxlow )
-{
- int X;
- int64_t dSx = Sxhigh - Sxlow;
- int64_t dRx = Rxhigh - Rxlow;
-
- if (dRx) {
- X = (int)(((dSx * (Cx - Rxlow)) / dRx) + Sxlow);
- }
- else {
- X = 0;
- ErrorF ("Divide by Zero in xf86ScaleAxis");
- }
-
- if (X > Sxhigh)
- X = Sxhigh;
- if (X < Sxlow)
- X = Sxlow;
-
- return (X);
-}
-
-/*
- * This function checks the given screen against the current screen and
- * makes changes if appropriate. It should be called from an XInput driver's
- * ReadInput function before any events are posted, if the device is screen
- * specific like a touch screen.
- */
-void
-xf86XInputSetScreen(LocalDevicePtr local,
- int screen_number,
- int x,
- int y)
-{
- if (miPointerGetScreen(local->dev) !=
- screenInfo.screens[screen_number]) {
- miPointerSetScreen(local->dev, screen_number, x, y);
- }
-}
-
-
-void
-xf86InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int maxval,
- int resolution, int min_res, int max_res)
-{
- if (!dev || !dev->valuator)
- return;
-
- InitValuatorAxisStruct(dev, axnum, label, minval, maxval, resolution, min_res,
- max_res);
-}
-
-/*
- * Set the valuator values to be in synch with dix/event.c
- * DefineInitialRootWindow().
- */
-void
-xf86InitValuatorDefaults(DeviceIntPtr dev, int axnum)
-{
- if (axnum == 0) {
- dev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2;
- dev->last.valuators[0] = dev->valuator->axisVal[0];
- }
- else if (axnum == 1) {
- dev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2;
- dev->last.valuators[1] = dev->valuator->axisVal[1];
- }
-
- if(axnum == 0) /* to prevent double invocation */
- ApplyAccelerationSettings(dev);
-}
-
-
-/**
- * Deactivate a device. Call this function from the driver if you receive a
- * read error or something else that spoils your day.
- * Device will be moved to the off_devices list, but it will still be there
- * until you really clean up after it.
- * Notifies the client about an inactive device.
- *
- * @param panic True if device is unrecoverable and needs to be removed.
- */
-void
-xf86DisableDevice(DeviceIntPtr dev, Bool panic)
-{
- if(!panic)
- {
- DisableDevice(dev, TRUE);
- } else
- {
- SendDevicePresenceEvent(dev->id, DeviceUnrecoverable);
- DeleteInputDeviceRequest(dev);
- }
-}
-
-/**
- * Reactivate a device. Call this function from the driver if you just found
- * out that the read error wasn't quite that bad after all.
- * Device will be re-activated, and an event sent to the client.
- */
-void
-xf86EnableDevice(DeviceIntPtr dev)
-{
- EnableDevice(dev, TRUE);
-}
-
-/* end of xf86Xinput.c */
+/*
+ * Copyright 1995-1999 by Frederic Lepied, France. <Lepied@XFree86.org>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Frederic Lepied not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Frederic Lepied makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * FREDERIC LEPIED DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL FREDERIC LEPIED BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+/*
+ * Copyright (c) 2000-2002 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <X11/Xfuncproto.h>
+#include <X11/Xmd.h>
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XIproto.h>
+#include <X11/Xatom.h>
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86Config.h"
+#include "xf86Xinput.h"
+#include "XIstubs.h"
+#include "xf86Optrec.h"
+#include "xf86Parser.h"
+#include "mipointer.h"
+#include "xf86InPriv.h"
+#include "compiler.h"
+#include "extinit.h"
+
+#ifdef DPMSExtension
+#include <X11/extensions/dpmsconst.h>
+#include "dpmsproc.h"
+#endif
+
+#include "exevents.h" /* AddInputDevice */
+#include "exglobals.h"
+#include "eventstr.h"
+
+#include <string.h> /* InputClassMatches */
+#ifdef HAVE_FNMATCH_H
+#include <fnmatch.h>
+#endif
+
+#include "extnsionst.h"
+
+#include "windowstr.h" /* screenIsSaved */
+
+#include <stdarg.h>
+#include <stdint.h> /* for int64_t */
+
+#include <X11/Xpoll.h>
+
+#include "mi.h"
+
+#include <ptrveloc.h> /* dix pointer acceleration */
+#include <xserver-properties.h>
+
+#ifdef XFreeXDGA
+#include "dgaproc.h"
+#endif
+
+#include "xkbsrv.h"
+
+#include "os.h"
+
+EventListPtr xf86Events = NULL;
+
+/**
+ * Eval config and modify DeviceVelocityRec accordingly
+ */
+static void
+ProcessVelocityConfiguration(DeviceIntPtr pDev, char* devname, pointer list,
+ DeviceVelocityPtr s)
+{
+ int tempi;
+ float tempf;
+ Atom float_prop = XIGetKnownProperty(XATOM_FLOAT);
+ Atom prop;
+
+ if(!s)
+ return;
+
+ /* common settings (available via device properties) */
+ tempf = xf86SetRealOption(list, "ConstantDeceleration", 1.0);
+ if (tempf > 1.0) {
+ xf86Msg(X_CONFIG, "%s: (accel) constant deceleration by %.1f\n",
+ devname, tempf);
+ prop = XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION);
+ XIChangeDeviceProperty(pDev, prop, float_prop, 32,
+ PropModeReplace, 1, &tempf, FALSE);
+ }
+
+ tempf = xf86SetRealOption(list, "AdaptiveDeceleration", 1.0);
+ if (tempf > 1.0) {
+ xf86Msg(X_CONFIG, "%s: (accel) adaptive deceleration by %.1f\n",
+ devname, tempf);
+ prop = XIGetKnownProperty(ACCEL_PROP_ADAPTIVE_DECELERATION);
+ XIChangeDeviceProperty(pDev, prop, float_prop, 32,
+ PropModeReplace, 1, &tempf, FALSE);
+ }
+
+ /* select profile by number */
+ tempi = xf86SetIntOption(list, "AccelerationProfile",
+ s->statistics.profile_number);
+
+ prop = XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER);
+ if (XIChangeDeviceProperty(pDev, prop, XA_INTEGER, 32,
+ PropModeReplace, 1, &tempi, FALSE) == Success) {
+ xf86Msg(X_CONFIG, "%s: (accel) acceleration profile %i\n", devname,
+ tempi);
+ } else {
+ xf86Msg(X_CONFIG, "%s: (accel) acceleration profile %i is unknown\n",
+ devname, tempi);
+ }
+
+ /* set scaling */
+ tempf = xf86SetRealOption(list, "ExpectedRate", 0);
+ prop = XIGetKnownProperty(ACCEL_PROP_VELOCITY_SCALING);
+ if (tempf > 0) {
+ tempf = 1000.0 / tempf;
+ XIChangeDeviceProperty(pDev, prop, float_prop, 32,
+ PropModeReplace, 1, &tempf, FALSE);
+ } else {
+ tempf = xf86SetRealOption(list, "VelocityScale", s->corr_mul);
+ XIChangeDeviceProperty(pDev, prop, float_prop, 32,
+ PropModeReplace, 1, &tempf, FALSE);
+ }
+
+ tempi = xf86SetIntOption(list, "VelocityTrackerCount", -1);
+ if (tempi > 1)
+ InitTrackers(s, tempi);
+
+ s->initial_range = xf86SetIntOption(list, "VelocityInitialRange",
+ s->initial_range);
+
+ s->max_diff = xf86SetRealOption(list, "VelocityAbsDiff", s->max_diff);
+
+ tempf = xf86SetRealOption(list, "VelocityRelDiff", -1);
+ if (tempf >= 0) {
+ xf86Msg(X_CONFIG, "%s: (accel) max rel. velocity difference: %.1f%%\n",
+ devname, tempf*100.0);
+ s->max_rel_diff = tempf;
+ }
+
+ /* Configure softening. If const deceleration is used, this is expected
+ * to provide better subpixel information so we enable
+ * softening by default only if ConstantDeceleration is not used
+ */
+ s->use_softening = xf86SetBoolOption(list, "Softening",
+ s->const_acceleration == 1.0);
+
+ s->average_accel = xf86SetBoolOption(list, "AccelerationProfileAveraging",
+ s->average_accel);
+
+ s->reset_time = xf86SetIntOption(list, "VelocityReset", s->reset_time);
+}
+
+static void
+ApplyAccelerationSettings(DeviceIntPtr dev){
+ int scheme, i;
+ DeviceVelocityPtr pVel;
+ LocalDevicePtr local = (LocalDevicePtr)dev->public.devicePrivate;
+ char* schemeStr;
+
+ if (dev->valuator && dev->ptrfeed) {
+ schemeStr = xf86SetStrOption(local->options, "AccelerationScheme", "");
+
+ scheme = dev->valuator->accelScheme.number;
+
+ if (!xf86NameCmp(schemeStr, "predictable"))
+ scheme = PtrAccelPredictable;
+
+ if (!xf86NameCmp(schemeStr, "lightweight"))
+ scheme = PtrAccelLightweight;
+
+ if (!xf86NameCmp(schemeStr, "none"))
+ scheme = PtrAccelNoOp;
+
+ /* reinit scheme if needed */
+ if (dev->valuator->accelScheme.number != scheme) {
+ if (dev->valuator->accelScheme.AccelCleanupProc) {
+ dev->valuator->accelScheme.AccelCleanupProc(dev);
+ }
+
+ if (InitPointerAccelerationScheme(dev, scheme)) {
+ xf86Msg(X_CONFIG, "%s: (accel) selected scheme %s/%i\n",
+ local->name, schemeStr, scheme);
+ } else {
+ xf86Msg(X_CONFIG, "%s: (accel) could not init scheme %s\n",
+ local->name, schemeStr);
+ scheme = dev->valuator->accelScheme.number;
+ }
+ } else {
+ xf86Msg(X_CONFIG, "%s: (accel) keeping acceleration scheme %i\n",
+ local->name, scheme);
+ }
+
+ free(schemeStr);
+
+ /* process special configuration */
+ switch (scheme) {
+ case PtrAccelPredictable:
+ pVel = GetDevicePredictableAccelData(dev);
+ ProcessVelocityConfiguration (dev, local->name, local->options,
+ pVel);
+ break;
+ }
+
+ i = xf86SetIntOption(local->options, "AccelerationNumerator",
+ dev->ptrfeed->ctrl.num);
+ if (i >= 0)
+ dev->ptrfeed->ctrl.num = i;
+
+ i = xf86SetIntOption(local->options, "AccelerationDenominator",
+ dev->ptrfeed->ctrl.den);
+ if (i > 0)
+ dev->ptrfeed->ctrl.den = i;
+
+ i = xf86SetIntOption(local->options, "AccelerationThreshold",
+ dev->ptrfeed->ctrl.threshold);
+ if (i >= 0)
+ dev->ptrfeed->ctrl.threshold = i;
+
+ /* mostly a no-op anyway */
+ (*dev->ptrfeed->CtrlProc)(dev, &dev->ptrfeed->ctrl);
+
+ xf86Msg(X_CONFIG, "%s: (accel) acceleration factor: %.3f\n",
+ local->name, ((float)dev->ptrfeed->ctrl.num)/
+ ((float)dev->ptrfeed->ctrl.den));
+ xf86Msg(X_CONFIG, "%s: (accel) acceleration threshold: %i\n",
+ local->name, dev->ptrfeed->ctrl.threshold);
+ }
+}
+
+static Bool
+xf86SendDragEvents(DeviceIntPtr device)
+{
+ LocalDevicePtr local = (LocalDevicePtr) device->public.devicePrivate;
+
+ if (device->button && device->button->buttonsDown > 0)
+ return (local->flags & XI86_SEND_DRAG_EVENTS);
+ else
+ return (TRUE);
+}
+
+/***********************************************************************
+ *
+ * xf86ProcessCommonOptions --
+ *
+ * Process global options.
+ *
+ ***********************************************************************
+ */
+void
+xf86ProcessCommonOptions(LocalDevicePtr local,
+ pointer list)
+{
+ if (!xf86SetBoolOption(list, "AlwaysCore", 1) ||
+ !xf86SetBoolOption(list, "SendCoreEvents", 1) ||
+ !xf86SetBoolOption(list, "CorePointer", 1) ||
+ !xf86SetBoolOption(list, "CoreKeyboard", 1)) {
+ xf86Msg(X_CONFIG, "%s: doesn't report core events\n", local->name);
+ } else {
+ local->flags |= XI86_ALWAYS_CORE;
+ xf86Msg(X_CONFIG, "%s: always reports core events\n", local->name);
+ }
+
+ if (xf86SetBoolOption(list, "SendDragEvents", 1)) {
+ local->flags |= XI86_SEND_DRAG_EVENTS;
+ } else {
+ xf86Msg(X_CONFIG, "%s: doesn't report drag events\n", local->name);
+ }
+
+ /* Backwards compatibility. */
+ local->history_size = GetMotionHistorySize();
+}
+
+/***********************************************************************
+ *
+ * xf86ActivateDevice --
+ *
+ * Initialize an input device.
+ *
+ * Returns TRUE on success, or FALSE otherwise.
+ ***********************************************************************
+ */
+int
+xf86ActivateDevice(LocalDevicePtr local)
+{
+ DeviceIntPtr dev;
+
+ if (local->flags & XI86_CONFIGURED) {
+ dev = AddInputDevice(serverClient, local->device_control, TRUE);
+
+ if (dev == NULL)
+ {
+ xf86Msg(X_ERROR, "Too many input devices. Ignoring %s\n",
+ local->name);
+ local->dev = NULL;
+ return FALSE;
+ }
+
+ local->atom = MakeAtom(local->type_name,
+ strlen(local->type_name),
+ TRUE);
+ AssignTypeAndName(dev, local->atom, local->name);
+ dev->public.devicePrivate = (pointer) local;
+ local->dev = dev;
+
+ dev->coreEvents = local->flags & XI86_ALWAYS_CORE;
+ dev->type = SLAVE;
+ dev->spriteInfo->spriteOwner = FALSE;
+
+ dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
+ dev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
+
+ RegisterOtherDevice(dev);
+ XkbSetExtension(dev, ProcessKeyboardEvent);
+
+ if (serverGeneration == 1)
+ xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s)\n",
+ local->name, local->type_name);
+ }
+
+ return TRUE;
+}
+
+
+/***********************************************************************
+ *
+ * Caller: ProcXOpenDevice
+ *
+ * This is the implementation-dependent routine to open an input device.
+ * Some implementations open all input devices when the server is first
+ * initialized, and never close them. Other implementations open only
+ * the X pointer and keyboard devices during server initialization,
+ * and only open other input devices when some client makes an
+ * XOpenDevice request. This entry point is for the latter type of
+ * implementation.
+ *
+ * If the physical device is not already open, do it here. In this case,
+ * you need to keep track of the fact that one or more clients has the
+ * device open, and physically close it when the last client that has
+ * it open does an XCloseDevice.
+ *
+ * The default implementation is to do nothing (assume all input devices
+ * are opened during X server initialization and kept open).
+ *
+ ***********************************************************************
+ */
+
+void
+OpenInputDevice(DeviceIntPtr dev,
+ ClientPtr client,
+ int *status)
+{
+ if (!dev->inited)
+ ActivateDevice(dev, TRUE);
+
+ *status = Success;
+}
+
+void
+CloseInputDevice(DeviceIntPtr dev,
+ ClientPtr client)
+{
+}
+
+/****************************************************************************
+ *
+ * Caller: ProcXSetDeviceMode
+ *
+ * Change the mode of an extension device.
+ * This function is used to change the mode of a device from reporting
+ * relative motion to reporting absolute positional information, and
+ * vice versa.
+ * The default implementation below is that no such devices are supported.
+ *
+ ***********************************************************************
+ */
+
+int
+SetDeviceMode (ClientPtr client, DeviceIntPtr dev, int mode)
+{
+ LocalDevicePtr local = (LocalDevicePtr)dev->public.devicePrivate;
+
+ if (local->switch_mode) {
+ return (*local->switch_mode)(client, dev, mode);
+ }
+ else
+ return BadMatch;
+}
+
+
+/***********************************************************************
+ *
+ * Caller: ProcXSetDeviceValuators
+ *
+ * Set the value of valuators on an extension input device.
+ * This function is used to set the initial value of valuators on
+ * those input devices that are capable of reporting either relative
+ * motion or an absolute position, and allow an initial position to be set.
+ * The default implementation below is that no such devices are supported.
+ *
+ ***********************************************************************
+ */
+
+int
+SetDeviceValuators (ClientPtr client, DeviceIntPtr dev, int *valuators,
+ int first_valuator, int num_valuators)
+{
+ LocalDevicePtr local = (LocalDevicePtr) dev->public.devicePrivate;
+
+ if (local->set_device_valuators)
+ return (*local->set_device_valuators)(local, valuators, first_valuator,
+ num_valuators);
+
+ return BadMatch;
+}
+
+
+/***********************************************************************
+ *
+ * Caller: ProcXChangeDeviceControl
+ *
+ * Change the specified device controls on an extension input device.
+ *
+ ***********************************************************************
+ */
+
+int
+ChangeDeviceControl (ClientPtr client, DeviceIntPtr dev, xDeviceCtl *control)
+{
+ LocalDevicePtr local = (LocalDevicePtr)dev->public.devicePrivate;
+
+ if (!local->control_proc) {
+ switch (control->control) {
+ case DEVICE_CORE:
+ return BadMatch;
+ case DEVICE_RESOLUTION:
+ case DEVICE_ABS_CALIB:
+ case DEVICE_ABS_AREA:
+ case DEVICE_ENABLE:
+ return Success;
+ default:
+ return BadMatch;
+ }
+ }
+ else {
+ return (*local->control_proc)(local, control);
+ }
+}
+
+void
+AddOtherInputDevices(void)
+{
+}
+
+/*
+ * Classes without any Match statements match all devices. Otherwise, all
+ * statements must match.
+ */
+static Bool
+InputClassMatches(XF86ConfInputClassPtr iclass, InputAttributes *attrs)
+{
+ char **cur;
+ Bool match;
+
+ if (iclass->match_product) {
+ if (!attrs->product)
+ return FALSE;
+ /* see if any of the values match */
+ for (cur = iclass->match_product, match = FALSE; *cur; cur++)
+ if (strstr(attrs->product, *cur)) {
+ match = TRUE;
+ break;
+ }
+ if (!match)
+ return FALSE;
+ }
+ if (iclass->match_vendor) {
+ if (!attrs->vendor)
+ return FALSE;
+ /* see if any of the values match */
+ for (cur = iclass->match_vendor, match = FALSE; *cur; cur++)
+ if (strstr(attrs->vendor, *cur)) {
+ match = TRUE;
+ break;
+ }
+ if (!match)
+ return FALSE;
+ }
+ if (iclass->match_device) {
+ if (!attrs->device)
+ return FALSE;
+ /* see if any of the values match */
+ for (cur = iclass->match_device, match = FALSE; *cur; cur++)
+#ifdef HAVE_FNMATCH_H
+ if (fnmatch(*cur, attrs->device, FNM_PATHNAME) == 0) {
+#else
+ if (strstr(attrs->device, *cur)) {
+#endif
+ match = TRUE;
+ break;
+ }
+ if (!match)
+ return FALSE;
+ }
+ if (iclass->match_tag) {
+ if (!attrs->tags)
+ return FALSE;
+
+ for (cur = iclass->match_tag, match = FALSE; *cur && !match; cur++) {
+ const char *tag;
+ for(tag = *attrs->tags; *tag; tag++) {
+ if (!strcmp(tag, *cur)) {
+ match = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (!match)
+ return FALSE;
+ }
+
+ if (iclass->is_keyboard.set &&
+ iclass->is_keyboard.val != !!(attrs->flags & ATTR_KEYBOARD))
+ return FALSE;
+ if (iclass->is_pointer.set &&
+ iclass->is_pointer.val != !!(attrs->flags & ATTR_POINTER))
+ return FALSE;
+ if (iclass->is_joystick.set &&
+ iclass->is_joystick.val != !!(attrs->flags & ATTR_JOYSTICK))
+ return FALSE;
+ if (iclass->is_tablet.set &&
+ iclass->is_tablet.val != !!(attrs->flags & ATTR_TABLET))
+ return FALSE;
+ if (iclass->is_touchpad.set &&
+ iclass->is_touchpad.val != !!(attrs->flags & ATTR_TOUCHPAD))
+ return FALSE;
+ if (iclass->is_touchscreen.set &&
+ iclass->is_touchscreen.val != !!(attrs->flags & ATTR_TOUCHSCREEN))
+ return FALSE;
+ return TRUE;
+}
+
+/*
+ * Merge in any InputClass configurations. Options in each InputClass
+ * section have more priority than the original device configuration as
+ * well as any previous InputClass sections.
+ */
+static int
+MergeInputClasses(IDevPtr idev, InputAttributes *attrs)
+{
+ XF86ConfInputClassPtr cl;
+ XF86OptionPtr classopts, mergedopts = NULL;
+ char *classdriver = NULL;
+
+ for (cl = xf86configptr->conf_inputclass_lst; cl; cl = cl->list.next) {
+ if (!InputClassMatches(cl, attrs))
+ continue;
+
+ /* Collect class options and merge over previous classes */
+ xf86Msg(X_CONFIG, "%s: Applying InputClass \"%s\"\n",
+ idev->identifier, cl->identifier);
+ if (cl->driver)
+ classdriver = cl->driver;
+ classopts = xf86optionListDup(cl->option_lst);
+ mergedopts = xf86optionListMerge(mergedopts, classopts);
+ }
+
+ /* Apply options to device with InputClass settings preferred. */
+ if (classdriver) {
+ free(idev->driver);
+ idev->driver = xstrdup(classdriver);
+ if (!idev->driver) {
+ xf86Msg(X_ERROR, "Failed to allocate memory while merging "
+ "InputClass configuration");
+ return BadAlloc;
+ }
+ mergedopts = xf86ReplaceStrOption(mergedopts, "driver", idev->driver);
+ }
+ idev->commonOptions = xf86optionListMerge(idev->commonOptions, mergedopts);
+
+ return Success;
+}
+
+/*
+ * Iterate the list of classes and look for Option "Ignore". Return the
+ * value of the last matching class and holler when returning TRUE.
+ */
+static Bool
+IgnoreInputClass(IDevPtr idev, InputAttributes *attrs)
+{
+ XF86ConfInputClassPtr cl;
+ Bool ignore = FALSE;
+ const char *ignore_class;
+
+ for (cl = xf86configptr->conf_inputclass_lst; cl; cl = cl->list.next) {
+ if (!InputClassMatches(cl, attrs))
+ continue;
+ if (xf86findOption(cl->option_lst, "Ignore")) {
+ ignore = xf86CheckBoolOption(cl->option_lst, "Ignore", FALSE);
+ ignore_class = cl->identifier;
+ }
+ }
+
+ if (ignore)
+ xf86Msg(X_CONFIG, "%s: Ignoring device from InputClass \"%s\"\n",
+ idev->identifier, ignore_class);
+ return ignore;
+}
+
+/**
+ * Create a new input device, activate and enable it.
+ *
+ * Possible return codes:
+ * BadName .. a bad driver name was supplied.
+ * BadImplementation ... The driver does not have a PreInit function. This
+ * is a driver bug.
+ * BadMatch .. device initialization failed.
+ * BadAlloc .. too many input devices
+ *
+ * @param idev The device, already set up with identifier, driver, and the
+ * options.
+ * @param pdev Pointer to the new device, if Success was reported.
+ * @param enable Enable the device after activating it.
+ *
+ * @return Success or an error code
+ */
+_X_INTERNAL int
+xf86NewInputDevice(IDevPtr idev, DeviceIntPtr *pdev, BOOL enable)
+{
+ InputDriverPtr drv = NULL;
+ InputInfoPtr pInfo = NULL;
+ DeviceIntPtr dev = NULL;
+ int rval;
+
+ /* Memory leak for every attached device if we don't
+ * test if the module is already loaded first */
+ drv = xf86LookupInputDriver(idev->driver);
+ if (!drv)
+ if (xf86LoadOneModule(idev->driver, NULL))
+ drv = xf86LookupInputDriver(idev->driver);
+ if (!drv) {
+ xf86Msg(X_ERROR, "No input driver matching `%s'\n", idev->driver);
+ rval = BadName;
+ goto unwind;
+ }
+
+ if (!drv->PreInit) {
+ xf86Msg(X_ERROR,
+ "Input driver `%s' has no PreInit function (ignoring)\n",
+ drv->driverName);
+ rval = BadImplementation;
+ goto unwind;
+ }
+
+ pInfo = drv->PreInit(drv, idev, 0);
+
+ if (!pInfo) {
+ xf86Msg(X_ERROR, "PreInit returned NULL for \"%s\"\n", idev->identifier);
+ rval = BadMatch;
+ goto unwind;
+ }
+ else if (!(pInfo->flags & XI86_CONFIGURED)) {
+ xf86Msg(X_ERROR, "PreInit failed for input device \"%s\"\n",
+ idev->identifier);
+ rval = BadMatch;
+ goto unwind;
+ }
+
+ if (!xf86ActivateDevice(pInfo))
+ {
+ rval = BadAlloc;
+ goto unwind;
+ }
+
+ dev = pInfo->dev;
+ rval = ActivateDevice(dev, TRUE);
+ if (rval != Success)
+ {
+ xf86Msg(X_ERROR, "Couldn't init device \"%s\"\n", idev->identifier);
+ RemoveDevice(dev, TRUE);
+ goto unwind;
+ }
+
+ /* Enable it if it's properly initialised and we're currently in the VT */
+ if (enable && dev->inited && dev->startup && xf86Screens[0]->vtSema)
+ {
+ EnableDevice(dev, TRUE);
+ if (!dev->enabled)
+ {
+ xf86Msg(X_ERROR, "Couldn't init device \"%s\"\n", idev->identifier);
+ rval = BadMatch;
+ goto unwind;
+ }
+ /* send enter/leave event, update sprite window */
+ CheckMotion(NULL, dev);
+ }
+
+ *pdev = dev;
+ return Success;
+
+unwind:
+ if(pInfo) {
+ if(drv->UnInit)
+ drv->UnInit(drv, pInfo, 0);
+ else
+ xf86DeleteInput(pInfo, 0);
+ }
+ return rval;
+}
+
+int
+NewInputDeviceRequest (InputOption *options, InputAttributes *attrs,
+ DeviceIntPtr *pdev)
+{
+ IDevRec *idev = NULL;
+ InputOption *option = NULL;
+ int rval = Success;
+ int is_auto = 0;
+
+ idev = calloc(sizeof(*idev), 1);
+ if (!idev)
+ return BadAlloc;
+
+ for (option = options; option; option = option->next) {
+ if (strcasecmp(option->key, "driver") == 0) {
+ if (idev->driver) {
+ rval = BadRequest;
+ goto unwind;
+ }
+ idev->driver = xstrdup(option->value);
+ if (!idev->driver) {
+ rval = BadAlloc;
+ goto unwind;
+ }
+ }
+
+ if (strcasecmp(option->key, "name") == 0 ||
+ strcasecmp(option->key, "identifier") == 0) {
+ if (idev->identifier) {
+ rval = BadRequest;
+ goto unwind;
+ }
+ idev->identifier = xstrdup(option->value);
+ if (!idev->identifier) {
+ rval = BadAlloc;
+ goto unwind;
+ }
+ }
+
+ if (strcmp(option->key, "_source") == 0 &&
+ (strcmp(option->value, "server/hal") == 0 ||
+ strcmp(option->value, "server/udev") == 0)) {
+ is_auto = 1;
+ if (!xf86Info.autoAddDevices) {
+ rval = BadMatch;
+ goto unwind;
+ }
+ }
+ }
+
+ for (option = options; option; option = option->next) {
+ /* Steal option key/value strings from the provided list.
+ * We need those strings, the InputOption list doesn't. */
+ idev->commonOptions = xf86addNewOption(idev->commonOptions,
+ option->key, option->value);
+ option->key = NULL;
+ option->value = NULL;
+ }
+
+ /* Apply InputClass settings */
+ if (attrs) {
+ if (IgnoreInputClass(idev, attrs)) {
+ rval = BadIDChoice;
+ goto unwind;
+ }
+
+ rval = MergeInputClasses(idev, attrs);
+ if (rval != Success)
+ goto unwind;
+ }
+
+ if (!idev->driver || !idev->identifier) {
+ xf86Msg(X_INFO, "No input driver/identifier specified (ignoring)\n");
+ rval = BadRequest;
+ goto unwind;
+ }
+
+ if (!idev->identifier) {
+ xf86Msg(X_ERROR, "No device identifier specified (ignoring)\n");
+ return BadMatch;
+ }
+
+ rval = xf86NewInputDevice(idev, pdev,
+ (!is_auto || (is_auto && xf86Info.autoEnableDevices)));
+ if (rval == Success)
+ return Success;
+
+unwind:
+ if (is_auto && !xf86Info.autoAddDevices)
+ xf86Msg(X_INFO, "AutoAddDevices is off - not adding device.\n");
+ if(idev->driver)
+ free(idev->driver);
+ if(idev->identifier)
+ free(idev->identifier);
+ xf86optionListFree(idev->commonOptions);
+ free(idev);
+ return rval;
+}
+
+void
+DeleteInputDeviceRequest(DeviceIntPtr pDev)
+{
+ LocalDevicePtr pInfo = (LocalDevicePtr) pDev->public.devicePrivate;
+ InputDriverPtr drv = NULL;
+ IDevRec *idev = NULL;
+ IDevPtr *it;
+ Bool isMaster = IsMaster(pDev);
+
+ if (pInfo) /* need to get these before RemoveDevice */
+ {
+ drv = pInfo->drv;
+ idev = pInfo->conf_idev;
+ }
+
+ OsBlockSignals();
+ RemoveDevice(pDev, TRUE);
+
+ if (!isMaster && pInfo != NULL)
+ {
+ if(drv->UnInit)
+ drv->UnInit(drv, pInfo, 0);
+ else
+ xf86DeleteInput(pInfo, 0);
+
+ /* devices added through HAL aren't in the config layout */
+ it = xf86ConfigLayout.inputs;
+ while(*it && *it != idev)
+ it++;
+
+ if (!(*it)) /* end of list, not in the layout */
+ {
+ free(idev->driver);
+ free(idev->identifier);
+ xf86optionListFree(idev->commonOptions);
+ free(idev);
+ }
+ }
+ OsReleaseSignals();
+}
+
+/*
+ * convenient functions to post events
+ */
+
+void
+xf86PostMotionEvent(DeviceIntPtr device,
+ int is_absolute,
+ int first_valuator,
+ int num_valuators,
+ ...)
+{
+ va_list var;
+ int i = 0;
+ static int valuators[MAX_VALUATORS];
+
+ XI_VERIFY_VALUATORS(num_valuators);
+
+ va_start(var, num_valuators);
+ for (i = 0; i < num_valuators; i++)
+ valuators[i] = va_arg(var, int);
+ va_end(var);
+
+ xf86PostMotionEventP(device, is_absolute, first_valuator, num_valuators, valuators);
+}
+
+void
+xf86PostMotionEventP(DeviceIntPtr device,
+ int is_absolute,
+ int first_valuator,
+ int num_valuators,
+ int *valuators)
+{
+ int i = 0, nevents = 0;
+ Bool drag = xf86SendDragEvents(device);
+ DeviceEvent *event;
+ int flags = 0;
+
+#if XFreeXDGA
+ int index;
+ int dx = 0, dy = 0;
+#endif
+
+ XI_VERIFY_VALUATORS(num_valuators);
+
+ if (is_absolute)
+ flags = POINTER_ABSOLUTE;
+ else
+ flags = POINTER_RELATIVE | POINTER_ACCELERATE;
+
+#if XFreeXDGA
+ /* The evdev driver may not always send all axes across. */
+ if (num_valuators >= 1 && first_valuator <= 1) {
+ if (miPointerGetScreen(device)) {
+ index = miPointerGetScreen(device)->myNum;
+ if (first_valuator == 0)
+ {
+ dx = valuators[0];
+ if (is_absolute)
+ dx -= device->last.valuators[0];
+ }
+
+ if (first_valuator == 1 || num_valuators >= 2)
+ {
+ dy = valuators[1 - first_valuator];
+ if (is_absolute)
+ dy -= device->last.valuators[1];
+ }
+
+ if (DGAStealMotionEvent(device, index, dx, dy))
+ return;
+ }
+ }
+#endif
+
+ nevents = GetPointerEvents(xf86Events, device, MotionNotify, 0,
+ flags, first_valuator, num_valuators,
+ valuators);
+
+ for (i = 0; i < nevents; i++) {
+ event = (DeviceEvent*)((xf86Events + i)->event);
+ /* Don't post core motion events for devices not registered to send
+ * drag events. */
+ if (event->header == ET_Internal &&
+ (event->type != ET_Motion || drag)) {
+ mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
+ }
+ }
+}
+
+void
+xf86PostProximityEvent(DeviceIntPtr device,
+ int is_in,
+ int first_valuator,
+ int num_valuators,
+ ...)
+{
+ va_list var;
+ int i;
+ int valuators[MAX_VALUATORS];
+
+ XI_VERIFY_VALUATORS(num_valuators);
+
+ va_start(var, num_valuators);
+ for (i = 0; i < num_valuators; i++)
+ valuators[i] = va_arg(var, int);
+ va_end(var);
+
+ xf86PostProximityEventP(device, is_in, first_valuator, num_valuators,
+ valuators);
+
+}
+
+void
+xf86PostProximityEventP(DeviceIntPtr device,
+ int is_in,
+ int first_valuator,
+ int num_valuators,
+ int *valuators)
+{
+ int i, nevents;
+
+ XI_VERIFY_VALUATORS(num_valuators);
+
+ nevents = GetProximityEvents(xf86Events, device,
+ is_in ? ProximityIn : ProximityOut,
+ first_valuator, num_valuators, valuators);
+ for (i = 0; i < nevents; i++)
+ mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
+
+}
+
+void
+xf86PostButtonEvent(DeviceIntPtr device,
+ int is_absolute,
+ int button,
+ int is_down,
+ int first_valuator,
+ int num_valuators,
+ ...)
+{
+ va_list var;
+ int valuators[MAX_VALUATORS];
+ int i = 0;
+
+ XI_VERIFY_VALUATORS(num_valuators);
+
+ va_start(var, num_valuators);
+ for (i = 0; i < num_valuators; i++)
+ valuators[i] = va_arg(var, int);
+ va_end(var);
+
+ xf86PostButtonEventP(device, is_absolute, button, is_down, first_valuator,
+ num_valuators, valuators);
+
+}
+
+void
+xf86PostButtonEventP(DeviceIntPtr device,
+ int is_absolute,
+ int button,
+ int is_down,
+ int first_valuator,
+ int num_valuators,
+ int *valuators)
+{
+ int i = 0, nevents = 0;
+ int flags = 0;
+
+#if XFreeXDGA
+ int index;
+#endif
+
+ XI_VERIFY_VALUATORS(num_valuators);
+
+ if (is_absolute)
+ flags = POINTER_ABSOLUTE;
+ else
+ flags = POINTER_RELATIVE | POINTER_ACCELERATE;
+
+#if XFreeXDGA
+ if (miPointerGetScreen(device)) {
+ index = miPointerGetScreen(device)->myNum;
+ if (DGAStealButtonEvent(device, index, button, is_down))
+ return;
+ }
+#endif
+
+ nevents = GetPointerEvents(xf86Events, device,
+ is_down ? ButtonPress : ButtonRelease, button,
+ flags, first_valuator, num_valuators, valuators);
+
+ for (i = 0; i < nevents; i++)
+ mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
+
+}
+
+void
+xf86PostKeyEvent(DeviceIntPtr device,
+ unsigned int key_code,
+ int is_down,
+ int is_absolute,
+ int first_valuator,
+ int num_valuators,
+ ...)
+{
+ va_list var;
+ int i = 0;
+ static int valuators[MAX_VALUATORS];
+
+ XI_VERIFY_VALUATORS(num_valuators);
+
+ va_start(var, num_valuators);
+ for (i = 0; i < num_valuators; i++)
+ valuators[i] = va_arg(var, int);
+ va_end(var);
+
+ xf86PostKeyEventP(device, key_code, is_down, is_absolute, first_valuator,
+ num_valuators, valuators);
+
+}
+
+void
+xf86PostKeyEventP(DeviceIntPtr device,
+ unsigned int key_code,
+ int is_down,
+ int is_absolute,
+ int first_valuator,
+ int num_valuators,
+ int *valuators)
+{
+ int i = 0, nevents = 0;
+
+ XI_VERIFY_VALUATORS(num_valuators);
+
+ if (is_absolute) {
+ nevents = GetKeyboardValuatorEvents(xf86Events, device,
+ is_down ? KeyPress : KeyRelease,
+ key_code, first_valuator,
+ num_valuators, valuators);
+ }
+ else {
+ nevents = GetKeyboardEvents(xf86Events, device,
+ is_down ? KeyPress : KeyRelease,
+ key_code);
+ }
+
+ for (i = 0; i < nevents; i++)
+ mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
+}
+
+void
+xf86PostKeyboardEvent(DeviceIntPtr device,
+ unsigned int key_code,
+ int is_down)
+{
+ xf86PostKeyEventP(device, key_code, is_down, 0, 0, 0, NULL);
+}
+
+LocalDevicePtr
+xf86FirstLocalDevice(void)
+{
+ return xf86InputDevs;
+}
+
+/*
+ * Cx - raw data from touch screen
+ * Sxhigh - scaled highest dimension
+ * (remember, this is of rows - 1 because of 0 origin)
+ * Sxlow - scaled lowest dimension
+ * Rxhigh - highest raw value from touch screen calibration
+ * Rxlow - lowest raw value from touch screen calibration
+ *
+ * This function is the same for X or Y coordinates.
+ * You may have to reverse the high and low values to compensate for
+ * different orgins on the touch screen vs X.
+ */
+
+int
+xf86ScaleAxis(int Cx,
+ int Sxhigh,
+ int Sxlow,
+ int Rxhigh,
+ int Rxlow )
+{
+ int X;
+ int64_t dSx = Sxhigh - Sxlow;
+ int64_t dRx = Rxhigh - Rxlow;
+
+ if (dRx) {
+ X = (int)(((dSx * (Cx - Rxlow)) / dRx) + Sxlow);
+ }
+ else {
+ X = 0;
+ ErrorF ("Divide by Zero in xf86ScaleAxis");
+ }
+
+ if (X > Sxhigh)
+ X = Sxhigh;
+ if (X < Sxlow)
+ X = Sxlow;
+
+ return (X);
+}
+
+/*
+ * This function checks the given screen against the current screen and
+ * makes changes if appropriate. It should be called from an XInput driver's
+ * ReadInput function before any events are posted, if the device is screen
+ * specific like a touch screen.
+ */
+void
+xf86XInputSetScreen(LocalDevicePtr local,
+ int screen_number,
+ int x,
+ int y)
+{
+ if (miPointerGetScreen(local->dev) !=
+ screenInfo.screens[screen_number]) {
+ miPointerSetScreen(local->dev, screen_number, x, y);
+ }
+}
+
+
+void
+xf86InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int maxval,
+ int resolution, int min_res, int max_res)
+{
+ if (!dev || !dev->valuator)
+ return;
+
+ InitValuatorAxisStruct(dev, axnum, label, minval, maxval, resolution, min_res,
+ max_res);
+}
+
+/*
+ * Set the valuator values to be in synch with dix/event.c
+ * DefineInitialRootWindow().
+ */
+void
+xf86InitValuatorDefaults(DeviceIntPtr dev, int axnum)
+{
+ if (axnum == 0) {
+ dev->valuator->axisVal[0] = screenInfo.screens[0]->width / 2;
+ dev->last.valuators[0] = dev->valuator->axisVal[0];
+ }
+ else if (axnum == 1) {
+ dev->valuator->axisVal[1] = screenInfo.screens[0]->height / 2;
+ dev->last.valuators[1] = dev->valuator->axisVal[1];
+ }
+
+ if(axnum == 0) /* to prevent double invocation */
+ ApplyAccelerationSettings(dev);
+}
+
+
+/**
+ * Deactivate a device. Call this function from the driver if you receive a
+ * read error or something else that spoils your day.
+ * Device will be moved to the off_devices list, but it will still be there
+ * until you really clean up after it.
+ * Notifies the client about an inactive device.
+ *
+ * @param panic True if device is unrecoverable and needs to be removed.
+ */
+void
+xf86DisableDevice(DeviceIntPtr dev, Bool panic)
+{
+ if(!panic)
+ {
+ DisableDevice(dev, TRUE);
+ } else
+ {
+ SendDevicePresenceEvent(dev->id, DeviceUnrecoverable);
+ DeleteInputDeviceRequest(dev);
+ }
+}
+
+/**
+ * Reactivate a device. Call this function from the driver if you just found
+ * out that the read error wasn't quite that bad after all.
+ * Device will be re-activated, and an event sent to the client.
+ */
+void
+xf86EnableDevice(DeviceIntPtr dev)
+{
+ EnableDevice(dev, TRUE);
+}
+
+/* end of xf86Xinput.c */
diff --git a/xorg-server/hw/xfree86/common/xf86cmap.c b/xorg-server/hw/xfree86/common/xf86cmap.c
index e266ffb6d..fa0ebc8eb 100644
--- a/xorg-server/hw/xfree86/common/xf86cmap.c
+++ b/xorg-server/hw/xfree86/common/xf86cmap.c
@@ -1,1166 +1,1166 @@
-/*
- * Copyright (c) 1998-2001 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#if defined(_XOPEN_SOURCE) || defined(sun) && defined(__SVR4)
-#include <math.h>
-#else
-#define _XOPEN_SOURCE /* to get prototype for pow on some systems */
-#include <math.h>
-#undef _XOPEN_SOURCE
-#endif
-
-#include <X11/X.h>
-#include "misc.h"
-#include <X11/Xproto.h>
-#include "colormapst.h"
-#include "scrnintstr.h"
-
-#include "resource.h"
-
-#include "xf86.h"
-#include "xf86_OSproc.h"
-#include "xf86str.h"
-#include "micmap.h"
-#include "xf86Crtc.h"
-
-#ifdef XFreeXDGA
-#include <X11/extensions/xf86dgaproto.h>
-#include "dgaproc.h"
-#endif
-
-#include "xf86cmap.h"
-
-#define SCREEN_PROLOGUE(pScreen, field) ((pScreen)->field = \
- ((CMapScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates, CMapScreenKey))->field)
-#define SCREEN_EPILOGUE(pScreen, field, wrapper)\
- ((pScreen)->field = wrapper)
-
-#define LOAD_PALETTE(pmap) \
- ((pmap == GetInstalledmiColormap(pmap->pScreen)) && \
- ((pScreenPriv->flags & CMAP_LOAD_EVEN_IF_OFFSCREEN) || \
- xf86Screens[pmap->pScreen->myNum]->vtSema || pScreenPriv->isDGAmode))
-
-
-typedef struct _CMapLink {
- ColormapPtr cmap;
- struct _CMapLink *next;
-} CMapLink, *CMapLinkPtr;
-
-typedef struct {
- ScrnInfoPtr pScrn;
- CloseScreenProcPtr CloseScreen;
- CreateColormapProcPtr CreateColormap;
- DestroyColormapProcPtr DestroyColormap;
- InstallColormapProcPtr InstallColormap;
- StoreColorsProcPtr StoreColors;
- Bool (*EnterVT)(int, int);
- Bool (*SwitchMode)(int, DisplayModePtr, int);
- int (*SetDGAMode)(int, int, DGADevicePtr);
- xf86ChangeGammaProc *ChangeGamma;
- int maxColors;
- int sigRGBbits;
- int gammaElements;
- LOCO *gamma;
- int *PreAllocIndices;
- CMapLinkPtr maps;
- unsigned int flags;
- Bool isDGAmode;
-} CMapScreenRec, *CMapScreenPtr;
-
-typedef struct {
- int numColors;
- LOCO *colors;
- Bool recalculate;
- int overscan;
-} CMapColormapRec, *CMapColormapPtr;
-
-static int CMapScreenKeyIndex;
-static DevPrivateKey CMapScreenKey;
-static int CMapColormapKeyIndex;
-static DevPrivateKey CMapColormapKey = &CMapColormapKeyIndex;
-
-static void CMapInstallColormap(ColormapPtr);
-static void CMapStoreColors(ColormapPtr, int, xColorItem *);
-static Bool CMapCloseScreen (int, ScreenPtr);
-static Bool CMapCreateColormap (ColormapPtr);
-static void CMapDestroyColormap (ColormapPtr);
-
-static Bool CMapEnterVT(int, int);
-static Bool CMapSwitchMode(int, DisplayModePtr, int);
-#ifdef XFreeXDGA
-static int CMapSetDGAMode(int, int, DGADevicePtr);
-#endif
-static int CMapChangeGamma(int, Gamma);
-
-static void ComputeGamma(CMapScreenPtr);
-static Bool CMapAllocateColormapPrivate(ColormapPtr);
-static void CMapRefreshColors(ColormapPtr, int, int*);
-static void CMapSetOverscan(ColormapPtr, int, int *);
-static void CMapReinstallMap(ColormapPtr);
-static void CMapUnwrapScreen(ScreenPtr pScreen);
-
-
-
-Bool xf86HandleColormaps(
- ScreenPtr pScreen,
- int maxColors,
- int sigRGBbits,
- xf86LoadPaletteProc *loadPalette,
- xf86SetOverscanProc *setOverscan,
- unsigned int flags
-){
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- ColormapPtr pDefMap = NULL;
- CMapScreenPtr pScreenPriv;
- LOCO *gamma;
- int *indices;
- int elements;
-
- /* If we support a better colormap system, then pretend we succeeded. */
- if (xf86_crtc_supports_gamma(pScrn))
- return TRUE;
-
- if(!maxColors || !sigRGBbits || !loadPalette)
- return FALSE;
-
- CMapScreenKey = &CMapScreenKeyIndex;
-
- elements = 1 << sigRGBbits;
-
- if(!(gamma = xalloc(elements * sizeof(LOCO))))
- return FALSE;
-
- if(!(indices = xalloc(maxColors * sizeof(int)))) {
- xfree(gamma);
- return FALSE;
- }
-
- if(!(pScreenPriv = xalloc(sizeof(CMapScreenRec)))) {
- xfree(gamma);
- xfree(indices);
- return FALSE;
- }
-
- dixSetPrivate(&pScreen->devPrivates, CMapScreenKey, pScreenPriv);
-
- pScreenPriv->CloseScreen = pScreen->CloseScreen;
- pScreenPriv->CreateColormap = pScreen->CreateColormap;
- pScreenPriv->DestroyColormap = pScreen->DestroyColormap;
- pScreenPriv->InstallColormap = pScreen->InstallColormap;
- pScreenPriv->StoreColors = pScreen->StoreColors;
- pScreen->CloseScreen = CMapCloseScreen;
- pScreen->CreateColormap = CMapCreateColormap;
- pScreen->DestroyColormap = CMapDestroyColormap;
- pScreen->InstallColormap = CMapInstallColormap;
- pScreen->StoreColors = CMapStoreColors;
-
- pScreenPriv->pScrn = pScrn;
- pScrn->LoadPalette = loadPalette;
- pScrn->SetOverscan = setOverscan;
- pScreenPriv->maxColors = maxColors;
- pScreenPriv->sigRGBbits = sigRGBbits;
- pScreenPriv->gammaElements = elements;
- pScreenPriv->gamma = gamma;
- pScreenPriv->PreAllocIndices = indices;
- pScreenPriv->maps = NULL;
- pScreenPriv->flags = flags;
- pScreenPriv->isDGAmode = FALSE;
-
- pScreenPriv->EnterVT = pScrn->EnterVT;
- pScreenPriv->SwitchMode = pScrn->SwitchMode;
- pScreenPriv->SetDGAMode = pScrn->SetDGAMode;
- pScreenPriv->ChangeGamma = pScrn->ChangeGamma;
-
- if (!(flags & CMAP_LOAD_EVEN_IF_OFFSCREEN)) {
- pScrn->EnterVT = CMapEnterVT;
- if ((flags & CMAP_RELOAD_ON_MODE_SWITCH) && pScrn->SwitchMode)
- pScrn->SwitchMode = CMapSwitchMode;
- }
-#ifdef XFreeXDGA
- pScrn->SetDGAMode = CMapSetDGAMode;
-#endif
- pScrn->ChangeGamma = CMapChangeGamma;
-
- ComputeGamma(pScreenPriv);
-
- /* get the default map */
- dixLookupResourceByType((pointer *)&pDefMap, pScreen->defColormap,
- RT_COLORMAP, serverClient, DixInstallAccess);
-
- if(!CMapAllocateColormapPrivate(pDefMap)) {
- CMapUnwrapScreen(pScreen);
- return FALSE;
- }
-
- /* Force the initial map to be loaded */
- SetInstalledmiColormap(pScreen, NULL);
- CMapInstallColormap(pDefMap);
- return TRUE;
-}
-
-
-/**** Screen functions ****/
-
-
-static Bool
-CMapCloseScreen (int i, ScreenPtr pScreen)
-{
- CMapUnwrapScreen(pScreen);
-
- return (*pScreen->CloseScreen) (i, pScreen);
-}
-
-static Bool
-CMapColormapUseMax(VisualPtr pVisual, CMapScreenPtr pScreenPriv)
-{
- if (pVisual->nplanes > 16)
- return TRUE;
- return ((1 << pVisual->nplanes) > pScreenPriv->maxColors);
-}
-
-static Bool
-CMapAllocateColormapPrivate(ColormapPtr pmap)
-{
- CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
- &pmap->pScreen->devPrivates, CMapScreenKey);
- CMapColormapPtr pColPriv;
- CMapLinkPtr pLink;
- int numColors;
- LOCO *colors;
-
- if (CMapColormapUseMax(pmap->pVisual, pScreenPriv))
- numColors = pmap->pVisual->ColormapEntries;
- else
- numColors = 1 << pmap->pVisual->nplanes;
-
- if(!(colors = xalloc(numColors * sizeof(LOCO))))
- return FALSE;
-
- if(!(pColPriv = xalloc(sizeof(CMapColormapRec)))) {
- xfree(colors);
- return FALSE;
- }
-
- dixSetPrivate(&pmap->devPrivates, CMapColormapKey, pColPriv);
-
- pColPriv->numColors = numColors;
- pColPriv->colors = colors;
- pColPriv->recalculate = TRUE;
- pColPriv->overscan = -1;
-
- /* add map to list */
- pLink = xalloc(sizeof(CMapLink));
- if(pLink) {
- pLink->cmap = pmap;
- pLink->next = pScreenPriv->maps;
- pScreenPriv->maps = pLink;
- }
-
- return TRUE;
-}
-
-static Bool
-CMapCreateColormap (ColormapPtr pmap)
-{
- ScreenPtr pScreen = pmap->pScreen;
- CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, CMapScreenKey);
- Bool ret = FALSE;
-
- pScreen->CreateColormap = pScreenPriv->CreateColormap;
- if((*pScreen->CreateColormap)(pmap)) {
- if(CMapAllocateColormapPrivate(pmap))
- ret = TRUE;
- }
- pScreen->CreateColormap = CMapCreateColormap;
-
- return ret;
-}
-
-static void
-CMapDestroyColormap (ColormapPtr cmap)
-{
- ScreenPtr pScreen = cmap->pScreen;
- CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, CMapScreenKey);
- CMapColormapPtr pColPriv = (CMapColormapPtr)dixLookupPrivate(
- &cmap->devPrivates, CMapColormapKey);
- CMapLinkPtr prevLink = NULL, pLink = pScreenPriv->maps;
-
- if(pColPriv) {
- if(pColPriv->colors) xfree(pColPriv->colors);
- xfree(pColPriv);
- }
-
- /* remove map from list */
- while(pLink) {
- if(pLink->cmap == cmap) {
- if(prevLink)
- prevLink->next = pLink->next;
- else
- pScreenPriv->maps = pLink->next;
- xfree(pLink);
- break;
- }
- prevLink = pLink;
- pLink = pLink->next;
- }
-
- if(pScreenPriv->DestroyColormap) {
- pScreen->DestroyColormap = pScreenPriv->DestroyColormap;
- (*pScreen->DestroyColormap)(cmap);
- pScreen->DestroyColormap = CMapDestroyColormap;
- }
-}
-
-
-
-static void
-CMapStoreColors(
- ColormapPtr pmap,
- int ndef,
- xColorItem *pdefs
-){
- ScreenPtr pScreen = pmap->pScreen;
- VisualPtr pVisual = pmap->pVisual;
- CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, CMapScreenKey);
- int *indices = pScreenPriv->PreAllocIndices;
- int num = ndef;
-
- /* At the moment this isn't necessary since there's nobody below us */
- pScreen->StoreColors = pScreenPriv->StoreColors;
- (*pScreen->StoreColors)(pmap, ndef, pdefs);
- pScreen->StoreColors = CMapStoreColors;
-
- /* should never get here for these */
- if( (pVisual->class == TrueColor) ||
- (pVisual->class == StaticColor) ||
- (pVisual->class == StaticGray))
- return;
-
- if(pVisual->class == DirectColor) {
- CMapColormapPtr pColPriv = (CMapColormapPtr)dixLookupPrivate(
- &pmap->devPrivates, CMapColormapKey);
- int i;
-
- if (CMapColormapUseMax(pVisual, pScreenPriv)) {
- int index;
-
- num = 0;
- while(ndef--) {
- if(pdefs[ndef].flags & DoRed) {
- index = (pdefs[ndef].pixel & pVisual->redMask) >>
- pVisual->offsetRed;
- i = num;
- while(i--)
- if(indices[i] == index) break;
- if(i == -1)
- indices[num++] = index;
- }
- if(pdefs[ndef].flags & DoGreen) {
- index = (pdefs[ndef].pixel & pVisual->greenMask) >>
- pVisual->offsetGreen;
- i = num;
- while(i--)
- if(indices[i] == index) break;
- if(i == -1)
- indices[num++] = index;
- }
- if(pdefs[ndef].flags & DoBlue) {
- index = (pdefs[ndef].pixel & pVisual->blueMask) >>
- pVisual->offsetBlue;
- i = num;
- while(i--)
- if(indices[i] == index) break;
- if(i == -1)
- indices[num++] = index;
- }
- }
-
- } else {
- /* not really as overkill as it seems */
- num = pColPriv->numColors;
- for(i = 0; i < pColPriv->numColors; i++)
- indices[i] = i;
- }
- } else {
- while(ndef--)
- indices[ndef] = pdefs[ndef].pixel;
- }
-
- CMapRefreshColors(pmap, num, indices);
-}
-
-
-static void
-CMapInstallColormap(ColormapPtr pmap)
-{
- ScreenPtr pScreen = pmap->pScreen;
- CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, CMapScreenKey);
-
- if (pmap == GetInstalledmiColormap(pmap->pScreen))
- return;
-
- pScreen->InstallColormap = pScreenPriv->InstallColormap;
- (*pScreen->InstallColormap)(pmap);
- pScreen->InstallColormap = CMapInstallColormap;
-
- /* Important. We let the lower layers, namely DGA,
- overwrite the choice of Colormap to install */
- if (GetInstalledmiColormap(pmap->pScreen))
- pmap = GetInstalledmiColormap(pmap->pScreen);
-
- if (!(pScreenPriv->flags & CMAP_PALETTED_TRUECOLOR) &&
- (pmap->pVisual->class == TrueColor) &&
- CMapColormapUseMax(pmap->pVisual, pScreenPriv))
- return;
-
- if(LOAD_PALETTE(pmap))
- CMapReinstallMap(pmap);
-}
-
-
-/**** ScrnInfoRec functions ****/
-
-static Bool
-CMapEnterVT(int index, int flags)
-{
- ScreenPtr pScreen = screenInfo.screens[index];
- CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, CMapScreenKey);
-
- if((*pScreenPriv->EnterVT)(index, flags)) {
- if(GetInstalledmiColormap(pScreen))
- CMapReinstallMap(GetInstalledmiColormap(pScreen));
- return TRUE;
- }
- return FALSE;
-}
-
-
-static Bool
-CMapSwitchMode(int index, DisplayModePtr mode, int flags)
-{
- ScreenPtr pScreen = screenInfo.screens[index];
- CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, CMapScreenKey);
-
- if((*pScreenPriv->SwitchMode)(index, mode, flags)) {
- if(GetInstalledmiColormap(pScreen))
- CMapReinstallMap(GetInstalledmiColormap(pScreen));
- return TRUE;
- }
- return FALSE;
-}
-
-#ifdef XFreeXDGA
-static int
-CMapSetDGAMode(int index, int num, DGADevicePtr dev)
-{
- ScreenPtr pScreen = screenInfo.screens[index];
- CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, CMapScreenKey);
- int ret;
-
- ret = (*pScreenPriv->SetDGAMode)(index, num, dev);
-
- pScreenPriv->isDGAmode = DGAActive(index);
-
- if(!pScreenPriv->isDGAmode && GetInstalledmiColormap(pScreen)
- && xf86Screens[pScreen->myNum]->vtSema)
- CMapReinstallMap(GetInstalledmiColormap(pScreen));
-
- return ret;
-}
-#endif
-
-
-/**** Utilities ****/
-
-static void
-CMapReinstallMap(ColormapPtr pmap)
-{
- CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
- &pmap->pScreen->devPrivates, CMapScreenKey);
- CMapColormapPtr cmapPriv = (CMapColormapPtr)dixLookupPrivate(
- &pmap->devPrivates, CMapColormapKey);
- ScrnInfoPtr pScrn = xf86Screens[pmap->pScreen->myNum];
- int i = cmapPriv->numColors;
- int *indices = pScreenPriv->PreAllocIndices;
-
- while(i--)
- indices[i] = i;
-
- if(cmapPriv->recalculate)
- CMapRefreshColors(pmap, cmapPriv->numColors, indices);
- else {
- (*pScrn->LoadPalette)(pScrn, cmapPriv->numColors,
- indices, cmapPriv->colors, pmap->pVisual);
- if (pScrn->SetOverscan) {
-#ifdef DEBUGOVERSCAN
- ErrorF("SetOverscan() called from CMapReinstallMap\n");
-#endif
- pScrn->SetOverscan(pScrn, cmapPriv->overscan);
- }
- }
-
- cmapPriv->recalculate = FALSE;
-}
-
-
-static void
-CMapRefreshColors(ColormapPtr pmap, int defs, int* indices)
-{
- CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
- &pmap->pScreen->devPrivates, CMapScreenKey);
- CMapColormapPtr pColPriv = (CMapColormapPtr)dixLookupPrivate(
- &pmap->devPrivates, CMapColormapKey);
- VisualPtr pVisual = pmap->pVisual;
- ScrnInfoPtr pScrn = xf86Screens[pmap->pScreen->myNum];
- int numColors, i;
- LOCO *gamma, *colors;
- EntryPtr entry;
- int reds, greens, blues, maxValue, index, shift;
-
- numColors = pColPriv->numColors;
- shift = 16 - pScreenPriv->sigRGBbits;
- maxValue = (1 << pScreenPriv->sigRGBbits) - 1;
- gamma = pScreenPriv->gamma;
- colors = pColPriv->colors;
-
- reds = pVisual->redMask >> pVisual->offsetRed;
- greens = pVisual->greenMask >> pVisual->offsetGreen;
- blues = pVisual->blueMask >> pVisual->offsetBlue;
-
- switch(pVisual->class) {
- case StaticGray:
- for(i = 0; i < numColors; i++) {
- index = (i+1) * maxValue / numColors;
- colors[i].red = gamma[index].red;
- colors[i].green = gamma[index].green;
- colors[i].blue = gamma[index].blue;
- }
- break;
- case TrueColor:
- if (CMapColormapUseMax(pVisual, pScreenPriv)) {
- for(i = 0; i <= reds; i++)
- colors[i].red = gamma[i * maxValue / reds].red;
- for(i = 0; i <= greens; i++)
- colors[i].green = gamma[i * maxValue / greens].green;
- for(i = 0; i <= blues; i++)
- colors[i].blue = gamma[i * maxValue / blues].blue;
- break;
- }
- for(i = 0; i < numColors; i++) {
- colors[i].red = gamma[((i >> pVisual->offsetRed) & reds) *
- maxValue / reds].red;
- colors[i].green = gamma[((i >> pVisual->offsetGreen) & greens) *
- maxValue / greens].green;
- colors[i].blue = gamma[((i >> pVisual->offsetBlue) & blues) *
- maxValue / blues].blue;
- }
- break;
- case StaticColor:
- case PseudoColor:
- case GrayScale:
- for(i = 0; i < defs; i++) {
- index = indices[i];
- entry = (EntryPtr)&pmap->red[index];
-
- if(entry->fShared) {
- colors[index].red =
- gamma[entry->co.shco.red->color >> shift].red;
- colors[index].green =
- gamma[entry->co.shco.green->color >> shift].green;
- colors[index].blue =
- gamma[entry->co.shco.blue->color >> shift].blue;
- } else {
- colors[index].red =
- gamma[entry->co.local.red >> shift].red;
- colors[index].green =
- gamma[entry->co.local.green >> shift].green;
- colors[index].blue =
- gamma[entry->co.local.blue >> shift].blue;
- }
- }
- break;
- case DirectColor:
- if (CMapColormapUseMax(pVisual, pScreenPriv)) {
- for(i = 0; i < defs; i++) {
- index = indices[i];
- if(index <= reds)
- colors[index].red =
- gamma[pmap->red[index].co.local.red >> shift].red;
- if(index <= greens)
- colors[index].green =
- gamma[pmap->green[index].co.local.green >> shift].green;
- if(index <= blues)
- colors[index].blue =
- gamma[pmap->blue[index].co.local.blue >> shift].blue;
-
- }
- break;
- }
- for(i = 0; i < defs; i++) {
- index = indices[i];
-
- colors[index].red = gamma[pmap->red[
- (index >> pVisual->offsetRed) & reds
- ].co.local.red >> shift].red;
- colors[index].green = gamma[pmap->green[
- (index >> pVisual->offsetGreen) & greens
- ].co.local.green >> shift].green;
- colors[index].blue = gamma[pmap->blue[
- (index >> pVisual->offsetBlue) & blues
- ].co.local.blue >> shift].blue;
- }
- break;
- }
-
-
- if(LOAD_PALETTE(pmap))
- (*pScrn->LoadPalette)(pScreenPriv->pScrn, defs, indices,
- colors, pmap->pVisual);
-
- if (pScrn->SetOverscan)
- CMapSetOverscan(pmap, defs, indices);
-
-}
-
-static Bool
-CMapCompareColors(LOCO *color1, LOCO *color2)
-{
- /* return TRUE if the color1 is "closer" to black than color2 */
-#ifdef DEBUGOVERSCAN
- ErrorF("#%02x%02x%02x vs #%02x%02x%02x (%d vs %d)\n",
- color1->red, color1->green, color1->blue,
- color2->red, color2->green, color2->blue,
- color1->red + color1->green + color1->blue,
- color2->red + color2->green + color2->blue);
-#endif
- return (color1->red + color1->green + color1->blue <
- color2->red + color2->green + color2->blue);
-}
-
-static void
-CMapSetOverscan(ColormapPtr pmap, int defs, int *indices)
-{
- CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
- &pmap->pScreen->devPrivates, CMapScreenKey);
- CMapColormapPtr pColPriv = (CMapColormapPtr)dixLookupPrivate(
- &pmap->devPrivates, CMapColormapKey);
- ScrnInfoPtr pScrn = xf86Screens[pmap->pScreen->myNum];
- VisualPtr pVisual = pmap->pVisual;
- int i;
- LOCO *colors;
- int index;
- Bool newOverscan = FALSE;
- int overscan, tmpOverscan;
-
- colors = pColPriv->colors;
- overscan = pColPriv->overscan;
-
- /*
- * Search for a new overscan index in the following cases:
- *
- * - The index hasn't yet been initialised.  In this case search
- * for an index that is black or a close match to black.
- *
- * - The colour of the old index is changed. In this case search
- * all indices for a black or close match to black.
- *
- * - The colour of the old index wasn't black. In this case only
- * search the indices that were changed for a better match to black.
- */
-
- switch (pVisual->class) {
- case StaticGray:
- case TrueColor:
- /* Should only come here once. Initialise the overscan index to 0 */
- overscan = 0;
- newOverscan = TRUE;
- break;
- case StaticColor:
- /*
- * Only come here once, but search for the overscan in the same way
- * as for the other cases.
- */
- case DirectColor:
- case PseudoColor:
- case GrayScale:
- if (overscan < 0 || overscan > pScreenPriv->maxColors - 1) {
- /* Uninitialised */
- newOverscan = TRUE;
- } else {
- /* Check if the overscan was changed */
- for (i = 0; i < defs; i++) {
- index = indices[i];
- if (index == overscan) {
- newOverscan = TRUE;
- break;
- }
- }
- }
- if (newOverscan) {
- /* The overscan is either uninitialised or it has been changed */
-
- if (overscan < 0 || overscan > pScreenPriv->maxColors - 1)
- tmpOverscan = pScreenPriv->maxColors - 1;
- else
- tmpOverscan = overscan;
-
- /* search all entries for a close match to black */
- for (i = pScreenPriv->maxColors - 1; i >= 0; i--) {
- if (colors[i].red == 0 && colors[i].green == 0 &&
- colors[i].blue == 0) {
- overscan = i;
-#ifdef DEBUGOVERSCAN
- ErrorF("Black found at index 0x%02x\n", i);
-#endif
- break;
- } else {
-#ifdef DEBUGOVERSCAN
- ErrorF("0x%02x: ", i);
-#endif
- if (CMapCompareColors(&colors[i], &colors[tmpOverscan])) {
- tmpOverscan = i;
-#ifdef DEBUGOVERSCAN
- ErrorF("possible \"Black\" at index 0x%02x\n", i);
-#endif
- }
- }
- }
- if (i < 0)
- overscan = tmpOverscan;
- } else {
- /* Check of the old overscan wasn't black */
- if (colors[overscan].red != 0 || colors[overscan].green != 0 ||
- colors[overscan].blue != 0) {
- int oldOverscan = tmpOverscan = overscan;
- /* See of there is now a better match */
- for (i = 0; i < defs; i++) {
- index = indices[i];
- if (colors[index].red == 0 && colors[index].green == 0 &&
- colors[index].blue == 0) {
- overscan = index;
-#ifdef DEBUGOVERSCAN
- ErrorF("Black found at index 0x%02x\n", index);
-#endif
- break;
- } else {
-#ifdef DEBUGOVERSCAN
- ErrorF("0x%02x: ", index);
-#endif
- if (CMapCompareColors(&colors[index],
- &colors[tmpOverscan])) {
- tmpOverscan = index;
-#ifdef DEBUGOVERSCAN
- ErrorF("possible \"Black\" at index 0x%02x\n",
- index);
-#endif
- }
- }
- }
- if (i == defs)
- overscan = tmpOverscan;
- if (overscan != oldOverscan)
- newOverscan = TRUE;
- }
- }
- break;
- }
- if (newOverscan) {
- pColPriv->overscan = overscan;
- if (LOAD_PALETTE(pmap)) {
-#ifdef DEBUGOVERSCAN
- ErrorF("SetOverscan() called from CmapSetOverscan\n");
-#endif
- pScrn->SetOverscan(pScreenPriv->pScrn, overscan);
- }
- }
-}
-
-static void
-CMapUnwrapScreen(ScreenPtr pScreen)
-{
- CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, CMapScreenKey);
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-
- pScreen->CloseScreen = pScreenPriv->CloseScreen;
- pScreen->CreateColormap = pScreenPriv->CreateColormap;
- pScreen->DestroyColormap = pScreenPriv->DestroyColormap;
- pScreen->InstallColormap = pScreenPriv->InstallColormap;
- pScreen->StoreColors = pScreenPriv->StoreColors;
-
- pScrn->EnterVT = pScreenPriv->EnterVT;
- pScrn->SwitchMode = pScreenPriv->SwitchMode;
- pScrn->SetDGAMode = pScreenPriv->SetDGAMode;
- pScrn->ChangeGamma = pScreenPriv->ChangeGamma;
-
- xfree(pScreenPriv->gamma);
- xfree(pScreenPriv->PreAllocIndices);
- xfree(pScreenPriv);
-}
-
-
-static void
-ComputeGamma(CMapScreenPtr priv)
-{
- int elements = priv->gammaElements - 1;
- double RedGamma, GreenGamma, BlueGamma;
- int i;
-
-#ifndef DONT_CHECK_GAMMA
- /* This check is to catch drivers that are not initialising pScrn->gamma */
- if (priv->pScrn->gamma.red < GAMMA_MIN ||
- priv->pScrn->gamma.red > GAMMA_MAX ||
- priv->pScrn->gamma.green < GAMMA_MIN ||
- priv->pScrn->gamma.green > GAMMA_MAX ||
- priv->pScrn->gamma.blue < GAMMA_MIN ||
- priv->pScrn->gamma.blue > GAMMA_MAX) {
-
- xf86DrvMsgVerb(priv->pScrn->scrnIndex, X_WARNING, 0,
- "The %s driver didn't call xf86SetGamma() to initialise\n"
- "\tthe gamma values.\n", priv->pScrn->driverName);
- xf86DrvMsgVerb(priv->pScrn->scrnIndex, X_WARNING, 0,
- "PLEASE FIX THE `%s' DRIVER!\n", priv->pScrn->driverName);
- priv->pScrn->gamma.red = 1.0;
- priv->pScrn->gamma.green = 1.0;
- priv->pScrn->gamma.blue = 1.0;
- }
-#endif
-
- RedGamma = 1.0 / (double)priv->pScrn->gamma.red;
- GreenGamma = 1.0 / (double)priv->pScrn->gamma.green;
- BlueGamma = 1.0 / (double)priv->pScrn->gamma.blue;
-
- for(i = 0; i <= elements; i++) {
- if(RedGamma == 1.0)
- priv->gamma[i].red = i;
- else
- priv->gamma[i].red = (CARD16)(pow((double)i/(double)elements,
- RedGamma) * (double)elements + 0.5);
-
- if(GreenGamma == 1.0)
- priv->gamma[i].green = i;
- else
- priv->gamma[i].green = (CARD16)(pow((double)i/(double)elements,
- GreenGamma) * (double)elements + 0.5);
-
- if(BlueGamma == 1.0)
- priv->gamma[i].blue = i;
- else
- priv->gamma[i].blue = (CARD16)(pow((double)i/(double)elements,
- BlueGamma) * (double)elements + 0.5);
- }
-}
-
-
-int
-CMapChangeGamma(
- int index,
- Gamma gamma
-){
- int ret = Success;
- ScrnInfoPtr pScrn = xf86Screens[index];
- ScreenPtr pScreen = pScrn->pScreen;
- CMapColormapPtr pColPriv;
- CMapScreenPtr pScreenPriv;
- CMapLinkPtr pLink;
-
- /* Is this sufficient checking ? */
- if(CMapScreenKey == NULL)
- return BadImplementation;
-
- pScreenPriv = (CMapScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
- CMapScreenKey);
- if(!pScreenPriv)
- return BadImplementation;
-
- if (gamma.red < GAMMA_MIN || gamma.red > GAMMA_MAX ||
- gamma.green < GAMMA_MIN || gamma.green > GAMMA_MAX ||
- gamma.blue < GAMMA_MIN || gamma.blue > GAMMA_MAX)
- return BadValue;
-
- pScrn->gamma.red = gamma.red;
- pScrn->gamma.green = gamma.green;
- pScrn->gamma.blue = gamma.blue;
-
- ComputeGamma(pScreenPriv);
-
- /* mark all colormaps on this screen */
- pLink = pScreenPriv->maps;
- while(pLink) {
- pColPriv = (CMapColormapPtr)dixLookupPrivate(&pLink->cmap->devPrivates,
- CMapColormapKey);
- pColPriv->recalculate = TRUE;
- pLink = pLink->next;
- }
-
- if(GetInstalledmiColormap(pScreen) &&
- ((pScreenPriv->flags & CMAP_LOAD_EVEN_IF_OFFSCREEN) ||
- pScrn->vtSema || pScreenPriv->isDGAmode)) {
- ColormapPtr pMap = GetInstalledmiColormap(pScreen);
-
- if (!(pScreenPriv->flags & CMAP_PALETTED_TRUECOLOR) &&
- (pMap->pVisual->class == TrueColor) &&
- CMapColormapUseMax(pMap->pVisual, pScreenPriv)) {
-
- /* if the current map doesn't have a palette look
- for another map to change the gamma on. */
-
- pLink = pScreenPriv->maps;
- while(pLink) {
- if(pLink->cmap->pVisual->class == PseudoColor)
- break;
- pLink = pLink->next;
- }
-
- if(pLink) {
- /* need to trick CMapRefreshColors() into thinking
- this is the currently installed map */
- SetInstalledmiColormap(pScreen, pLink->cmap);
- CMapReinstallMap(pLink->cmap);
- SetInstalledmiColormap(pScreen, pMap);
- }
- } else
- CMapReinstallMap(pMap);
- }
-
- pScrn->ChangeGamma = pScreenPriv->ChangeGamma;
- if (pScrn->ChangeGamma)
- ret = pScrn->ChangeGamma(index, gamma);
- pScrn->ChangeGamma = CMapChangeGamma;
-
- return ret;
-}
-
-
-static void
-ComputeGammaRamp (
- CMapScreenPtr priv,
- unsigned short *red,
- unsigned short *green,
- unsigned short *blue
-){
- int elements = priv->gammaElements;
- LOCO *entry = priv->gamma;
- int shift = 16 - priv->sigRGBbits;
-
- while(elements--) {
- entry->red = *(red++) >> shift;
- entry->green = *(green++) >> shift;
- entry->blue = *(blue++) >> shift;
- entry++;
- }
-}
-
-int
-xf86ChangeGammaRamp(
- ScreenPtr pScreen,
- int size,
- unsigned short *red,
- unsigned short *green,
- unsigned short *blue
-){
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- CMapColormapPtr pColPriv;
- CMapScreenPtr pScreenPriv;
- CMapLinkPtr pLink;
-
- if (xf86_crtc_supports_gamma(pScrn)) {
- RRCrtcPtr crtc = xf86CompatRRCrtc(pScrn);
-
- if (crtc) {
- if (crtc->gammaSize != size)
- return BadValue;
-
- RRCrtcGammaSet(crtc, red, green, blue);
-
- return Success;
- }
- }
-
- if(CMapScreenKey == NULL)
- return BadImplementation;
-
- pScreenPriv = (CMapScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
- CMapScreenKey);
- if(!pScreenPriv)
- return BadImplementation;
-
- if(pScreenPriv->gammaElements != size)
- return BadValue;
-
- ComputeGammaRamp(pScreenPriv, red, green, blue);
-
- /* mark all colormaps on this screen */
- pLink = pScreenPriv->maps;
- while(pLink) {
- pColPriv = (CMapColormapPtr)dixLookupPrivate(&pLink->cmap->devPrivates,
- CMapColormapKey);
- pColPriv->recalculate = TRUE;
- pLink = pLink->next;
- }
-
- if(GetInstalledmiColormap(pScreen) &&
- ((pScreenPriv->flags & CMAP_LOAD_EVEN_IF_OFFSCREEN) ||
- pScrn->vtSema || pScreenPriv->isDGAmode)) {
- ColormapPtr pMap = GetInstalledmiColormap(pScreen);
-
- if (!(pScreenPriv->flags & CMAP_PALETTED_TRUECOLOR) &&
- (pMap->pVisual->class == TrueColor) &&
- CMapColormapUseMax(pMap->pVisual, pScreenPriv)) {
-
- /* if the current map doesn't have a palette look
- for another map to change the gamma on. */
-
- pLink = pScreenPriv->maps;
- while(pLink) {
- if(pLink->cmap->pVisual->class == PseudoColor)
- break;
- pLink = pLink->next;
- }
-
- if(pLink) {
- /* need to trick CMapRefreshColors() into thinking
- this is the currently installed map */
- SetInstalledmiColormap(pScreen, pLink->cmap);
- CMapReinstallMap(pLink->cmap);
- SetInstalledmiColormap(pScreen, pMap);
- }
- } else
- CMapReinstallMap(pMap);
- }
-
- return Success;
-}
-
-int
-xf86GetGammaRampSize(ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- CMapScreenPtr pScreenPriv;
-
- if (xf86_crtc_supports_gamma(pScrn)) {
- RRCrtcPtr crtc = xf86CompatRRCrtc(pScrn);
-
- if (crtc)
- return crtc->gammaSize;
- }
-
- if(CMapScreenKey == NULL) return 0;
-
- pScreenPriv = (CMapScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
- CMapScreenKey);
- if(!pScreenPriv) return 0;
-
- return pScreenPriv->gammaElements;
-}
-
-int
-xf86GetGammaRamp(
- ScreenPtr pScreen,
- int size,
- unsigned short *red,
- unsigned short *green,
- unsigned short *blue
-){
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- CMapScreenPtr pScreenPriv;
- LOCO *entry;
- int shift, sigbits;
-
- if (xf86_crtc_supports_gamma(pScrn)) {
- RRCrtcPtr crtc = xf86CompatRRCrtc(pScrn);
-
- if (crtc) {
- if (crtc->gammaSize < size)
- return BadValue;
-
- if (!RRCrtcGammaGet(crtc))
- return BadImplementation;
-
- memcpy(red, crtc->gammaRed, size * sizeof(*red));
- memcpy(green, crtc->gammaGreen, size * sizeof(*green));
- memcpy(blue, crtc->gammaBlue, size * sizeof(*blue));
-
- return Success;
- }
- }
-
- if(CMapScreenKey == NULL)
- return BadImplementation;
-
- pScreenPriv = (CMapScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
- CMapScreenKey);
- if(!pScreenPriv)
- return BadImplementation;
-
- if(size > pScreenPriv->gammaElements)
- return BadValue;
-
- entry = pScreenPriv->gamma;
- sigbits = pScreenPriv->sigRGBbits;
-
- while(size--) {
- *red = entry->red << (16 - sigbits);
- *green = entry->green << (16 - sigbits);
- *blue = entry->blue << (16 - sigbits);
- shift = sigbits;
- while(shift < 16) {
- *red |= *red >> shift;
- *green |= *green >> shift;
- *blue |= *blue >> shift;
- shift += sigbits;
- }
- red++; green++; blue++;
- entry++;
- }
-
- return Success;
-}
-
-int
-xf86ChangeGamma(
- ScreenPtr pScreen,
- Gamma gamma
-){
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-
- if(pScrn->ChangeGamma)
- return (*pScrn->ChangeGamma)(pScreen->myNum, gamma);
-
- return BadImplementation;
-}
+/*
+ * Copyright (c) 1998-2001 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#if defined(_XOPEN_SOURCE) || defined(sun) && defined(__SVR4)
+#include <math.h>
+#else
+#define _XOPEN_SOURCE /* to get prototype for pow on some systems */
+#include <math.h>
+#undef _XOPEN_SOURCE
+#endif
+
+#include <X11/X.h>
+#include "misc.h"
+#include <X11/Xproto.h>
+#include "colormapst.h"
+#include "scrnintstr.h"
+
+#include "resource.h"
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86str.h"
+#include "micmap.h"
+#include "xf86Crtc.h"
+
+#ifdef XFreeXDGA
+#include <X11/extensions/xf86dgaproto.h>
+#include "dgaproc.h"
+#endif
+
+#include "xf86cmap.h"
+
+#define SCREEN_PROLOGUE(pScreen, field) ((pScreen)->field = \
+ ((CMapScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates, CMapScreenKey))->field)
+#define SCREEN_EPILOGUE(pScreen, field, wrapper)\
+ ((pScreen)->field = wrapper)
+
+#define LOAD_PALETTE(pmap) \
+ ((pmap == GetInstalledmiColormap(pmap->pScreen)) && \
+ ((pScreenPriv->flags & CMAP_LOAD_EVEN_IF_OFFSCREEN) || \
+ xf86Screens[pmap->pScreen->myNum]->vtSema || pScreenPriv->isDGAmode))
+
+
+typedef struct _CMapLink {
+ ColormapPtr cmap;
+ struct _CMapLink *next;
+} CMapLink, *CMapLinkPtr;
+
+typedef struct {
+ ScrnInfoPtr pScrn;
+ CloseScreenProcPtr CloseScreen;
+ CreateColormapProcPtr CreateColormap;
+ DestroyColormapProcPtr DestroyColormap;
+ InstallColormapProcPtr InstallColormap;
+ StoreColorsProcPtr StoreColors;
+ Bool (*EnterVT)(int, int);
+ Bool (*SwitchMode)(int, DisplayModePtr, int);
+ int (*SetDGAMode)(int, int, DGADevicePtr);
+ xf86ChangeGammaProc *ChangeGamma;
+ int maxColors;
+ int sigRGBbits;
+ int gammaElements;
+ LOCO *gamma;
+ int *PreAllocIndices;
+ CMapLinkPtr maps;
+ unsigned int flags;
+ Bool isDGAmode;
+} CMapScreenRec, *CMapScreenPtr;
+
+typedef struct {
+ int numColors;
+ LOCO *colors;
+ Bool recalculate;
+ int overscan;
+} CMapColormapRec, *CMapColormapPtr;
+
+static int CMapScreenKeyIndex;
+static DevPrivateKey CMapScreenKey;
+static int CMapColormapKeyIndex;
+static DevPrivateKey CMapColormapKey = &CMapColormapKeyIndex;
+
+static void CMapInstallColormap(ColormapPtr);
+static void CMapStoreColors(ColormapPtr, int, xColorItem *);
+static Bool CMapCloseScreen (int, ScreenPtr);
+static Bool CMapCreateColormap (ColormapPtr);
+static void CMapDestroyColormap (ColormapPtr);
+
+static Bool CMapEnterVT(int, int);
+static Bool CMapSwitchMode(int, DisplayModePtr, int);
+#ifdef XFreeXDGA
+static int CMapSetDGAMode(int, int, DGADevicePtr);
+#endif
+static int CMapChangeGamma(int, Gamma);
+
+static void ComputeGamma(CMapScreenPtr);
+static Bool CMapAllocateColormapPrivate(ColormapPtr);
+static void CMapRefreshColors(ColormapPtr, int, int*);
+static void CMapSetOverscan(ColormapPtr, int, int *);
+static void CMapReinstallMap(ColormapPtr);
+static void CMapUnwrapScreen(ScreenPtr pScreen);
+
+
+
+Bool xf86HandleColormaps(
+ ScreenPtr pScreen,
+ int maxColors,
+ int sigRGBbits,
+ xf86LoadPaletteProc *loadPalette,
+ xf86SetOverscanProc *setOverscan,
+ unsigned int flags
+){
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ ColormapPtr pDefMap = NULL;
+ CMapScreenPtr pScreenPriv;
+ LOCO *gamma;
+ int *indices;
+ int elements;
+
+ /* If we support a better colormap system, then pretend we succeeded. */
+ if (xf86_crtc_supports_gamma(pScrn))
+ return TRUE;
+
+ if(!maxColors || !sigRGBbits || !loadPalette)
+ return FALSE;
+
+ CMapScreenKey = &CMapScreenKeyIndex;
+
+ elements = 1 << sigRGBbits;
+
+ if(!(gamma = malloc(elements * sizeof(LOCO))))
+ return FALSE;
+
+ if(!(indices = malloc(maxColors * sizeof(int)))) {
+ free(gamma);
+ return FALSE;
+ }
+
+ if(!(pScreenPriv = malloc(sizeof(CMapScreenRec)))) {
+ free(gamma);
+ free(indices);
+ return FALSE;
+ }
+
+ dixSetPrivate(&pScreen->devPrivates, CMapScreenKey, pScreenPriv);
+
+ pScreenPriv->CloseScreen = pScreen->CloseScreen;
+ pScreenPriv->CreateColormap = pScreen->CreateColormap;
+ pScreenPriv->DestroyColormap = pScreen->DestroyColormap;
+ pScreenPriv->InstallColormap = pScreen->InstallColormap;
+ pScreenPriv->StoreColors = pScreen->StoreColors;
+ pScreen->CloseScreen = CMapCloseScreen;
+ pScreen->CreateColormap = CMapCreateColormap;
+ pScreen->DestroyColormap = CMapDestroyColormap;
+ pScreen->InstallColormap = CMapInstallColormap;
+ pScreen->StoreColors = CMapStoreColors;
+
+ pScreenPriv->pScrn = pScrn;
+ pScrn->LoadPalette = loadPalette;
+ pScrn->SetOverscan = setOverscan;
+ pScreenPriv->maxColors = maxColors;
+ pScreenPriv->sigRGBbits = sigRGBbits;
+ pScreenPriv->gammaElements = elements;
+ pScreenPriv->gamma = gamma;
+ pScreenPriv->PreAllocIndices = indices;
+ pScreenPriv->maps = NULL;
+ pScreenPriv->flags = flags;
+ pScreenPriv->isDGAmode = FALSE;
+
+ pScreenPriv->EnterVT = pScrn->EnterVT;
+ pScreenPriv->SwitchMode = pScrn->SwitchMode;
+ pScreenPriv->SetDGAMode = pScrn->SetDGAMode;
+ pScreenPriv->ChangeGamma = pScrn->ChangeGamma;
+
+ if (!(flags & CMAP_LOAD_EVEN_IF_OFFSCREEN)) {
+ pScrn->EnterVT = CMapEnterVT;
+ if ((flags & CMAP_RELOAD_ON_MODE_SWITCH) && pScrn->SwitchMode)
+ pScrn->SwitchMode = CMapSwitchMode;
+ }
+#ifdef XFreeXDGA
+ pScrn->SetDGAMode = CMapSetDGAMode;
+#endif
+ pScrn->ChangeGamma = CMapChangeGamma;
+
+ ComputeGamma(pScreenPriv);
+
+ /* get the default map */
+ dixLookupResourceByType((pointer *)&pDefMap, pScreen->defColormap,
+ RT_COLORMAP, serverClient, DixInstallAccess);
+
+ if(!CMapAllocateColormapPrivate(pDefMap)) {
+ CMapUnwrapScreen(pScreen);
+ return FALSE;
+ }
+
+ /* Force the initial map to be loaded */
+ SetInstalledmiColormap(pScreen, NULL);
+ CMapInstallColormap(pDefMap);
+ return TRUE;
+}
+
+
+/**** Screen functions ****/
+
+
+static Bool
+CMapCloseScreen (int i, ScreenPtr pScreen)
+{
+ CMapUnwrapScreen(pScreen);
+
+ return (*pScreen->CloseScreen) (i, pScreen);
+}
+
+static Bool
+CMapColormapUseMax(VisualPtr pVisual, CMapScreenPtr pScreenPriv)
+{
+ if (pVisual->nplanes > 16)
+ return TRUE;
+ return ((1 << pVisual->nplanes) > pScreenPriv->maxColors);
+}
+
+static Bool
+CMapAllocateColormapPrivate(ColormapPtr pmap)
+{
+ CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
+ &pmap->pScreen->devPrivates, CMapScreenKey);
+ CMapColormapPtr pColPriv;
+ CMapLinkPtr pLink;
+ int numColors;
+ LOCO *colors;
+
+ if (CMapColormapUseMax(pmap->pVisual, pScreenPriv))
+ numColors = pmap->pVisual->ColormapEntries;
+ else
+ numColors = 1 << pmap->pVisual->nplanes;
+
+ if(!(colors = malloc(numColors * sizeof(LOCO))))
+ return FALSE;
+
+ if(!(pColPriv = malloc(sizeof(CMapColormapRec)))) {
+ free(colors);
+ return FALSE;
+ }
+
+ dixSetPrivate(&pmap->devPrivates, CMapColormapKey, pColPriv);
+
+ pColPriv->numColors = numColors;
+ pColPriv->colors = colors;
+ pColPriv->recalculate = TRUE;
+ pColPriv->overscan = -1;
+
+ /* add map to list */
+ pLink = malloc(sizeof(CMapLink));
+ if(pLink) {
+ pLink->cmap = pmap;
+ pLink->next = pScreenPriv->maps;
+ pScreenPriv->maps = pLink;
+ }
+
+ return TRUE;
+}
+
+static Bool
+CMapCreateColormap (ColormapPtr pmap)
+{
+ ScreenPtr pScreen = pmap->pScreen;
+ CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, CMapScreenKey);
+ Bool ret = FALSE;
+
+ pScreen->CreateColormap = pScreenPriv->CreateColormap;
+ if((*pScreen->CreateColormap)(pmap)) {
+ if(CMapAllocateColormapPrivate(pmap))
+ ret = TRUE;
+ }
+ pScreen->CreateColormap = CMapCreateColormap;
+
+ return ret;
+}
+
+static void
+CMapDestroyColormap (ColormapPtr cmap)
+{
+ ScreenPtr pScreen = cmap->pScreen;
+ CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, CMapScreenKey);
+ CMapColormapPtr pColPriv = (CMapColormapPtr)dixLookupPrivate(
+ &cmap->devPrivates, CMapColormapKey);
+ CMapLinkPtr prevLink = NULL, pLink = pScreenPriv->maps;
+
+ if(pColPriv) {
+ if(pColPriv->colors) free(pColPriv->colors);
+ free(pColPriv);
+ }
+
+ /* remove map from list */
+ while(pLink) {
+ if(pLink->cmap == cmap) {
+ if(prevLink)
+ prevLink->next = pLink->next;
+ else
+ pScreenPriv->maps = pLink->next;
+ free(pLink);
+ break;
+ }
+ prevLink = pLink;
+ pLink = pLink->next;
+ }
+
+ if(pScreenPriv->DestroyColormap) {
+ pScreen->DestroyColormap = pScreenPriv->DestroyColormap;
+ (*pScreen->DestroyColormap)(cmap);
+ pScreen->DestroyColormap = CMapDestroyColormap;
+ }
+}
+
+
+
+static void
+CMapStoreColors(
+ ColormapPtr pmap,
+ int ndef,
+ xColorItem *pdefs
+){
+ ScreenPtr pScreen = pmap->pScreen;
+ VisualPtr pVisual = pmap->pVisual;
+ CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, CMapScreenKey);
+ int *indices = pScreenPriv->PreAllocIndices;
+ int num = ndef;
+
+ /* At the moment this isn't necessary since there's nobody below us */
+ pScreen->StoreColors = pScreenPriv->StoreColors;
+ (*pScreen->StoreColors)(pmap, ndef, pdefs);
+ pScreen->StoreColors = CMapStoreColors;
+
+ /* should never get here for these */
+ if( (pVisual->class == TrueColor) ||
+ (pVisual->class == StaticColor) ||
+ (pVisual->class == StaticGray))
+ return;
+
+ if(pVisual->class == DirectColor) {
+ CMapColormapPtr pColPriv = (CMapColormapPtr)dixLookupPrivate(
+ &pmap->devPrivates, CMapColormapKey);
+ int i;
+
+ if (CMapColormapUseMax(pVisual, pScreenPriv)) {
+ int index;
+
+ num = 0;
+ while(ndef--) {
+ if(pdefs[ndef].flags & DoRed) {
+ index = (pdefs[ndef].pixel & pVisual->redMask) >>
+ pVisual->offsetRed;
+ i = num;
+ while(i--)
+ if(indices[i] == index) break;
+ if(i == -1)
+ indices[num++] = index;
+ }
+ if(pdefs[ndef].flags & DoGreen) {
+ index = (pdefs[ndef].pixel & pVisual->greenMask) >>
+ pVisual->offsetGreen;
+ i = num;
+ while(i--)
+ if(indices[i] == index) break;
+ if(i == -1)
+ indices[num++] = index;
+ }
+ if(pdefs[ndef].flags & DoBlue) {
+ index = (pdefs[ndef].pixel & pVisual->blueMask) >>
+ pVisual->offsetBlue;
+ i = num;
+ while(i--)
+ if(indices[i] == index) break;
+ if(i == -1)
+ indices[num++] = index;
+ }
+ }
+
+ } else {
+ /* not really as overkill as it seems */
+ num = pColPriv->numColors;
+ for(i = 0; i < pColPriv->numColors; i++)
+ indices[i] = i;
+ }
+ } else {
+ while(ndef--)
+ indices[ndef] = pdefs[ndef].pixel;
+ }
+
+ CMapRefreshColors(pmap, num, indices);
+}
+
+
+static void
+CMapInstallColormap(ColormapPtr pmap)
+{
+ ScreenPtr pScreen = pmap->pScreen;
+ CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, CMapScreenKey);
+
+ if (pmap == GetInstalledmiColormap(pmap->pScreen))
+ return;
+
+ pScreen->InstallColormap = pScreenPriv->InstallColormap;
+ (*pScreen->InstallColormap)(pmap);
+ pScreen->InstallColormap = CMapInstallColormap;
+
+ /* Important. We let the lower layers, namely DGA,
+ overwrite the choice of Colormap to install */
+ if (GetInstalledmiColormap(pmap->pScreen))
+ pmap = GetInstalledmiColormap(pmap->pScreen);
+
+ if (!(pScreenPriv->flags & CMAP_PALETTED_TRUECOLOR) &&
+ (pmap->pVisual->class == TrueColor) &&
+ CMapColormapUseMax(pmap->pVisual, pScreenPriv))
+ return;
+
+ if(LOAD_PALETTE(pmap))
+ CMapReinstallMap(pmap);
+}
+
+
+/**** ScrnInfoRec functions ****/
+
+static Bool
+CMapEnterVT(int index, int flags)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, CMapScreenKey);
+
+ if((*pScreenPriv->EnterVT)(index, flags)) {
+ if(GetInstalledmiColormap(pScreen))
+ CMapReinstallMap(GetInstalledmiColormap(pScreen));
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+static Bool
+CMapSwitchMode(int index, DisplayModePtr mode, int flags)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, CMapScreenKey);
+
+ if((*pScreenPriv->SwitchMode)(index, mode, flags)) {
+ if(GetInstalledmiColormap(pScreen))
+ CMapReinstallMap(GetInstalledmiColormap(pScreen));
+ return TRUE;
+ }
+ return FALSE;
+}
+
+#ifdef XFreeXDGA
+static int
+CMapSetDGAMode(int index, int num, DGADevicePtr dev)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, CMapScreenKey);
+ int ret;
+
+ ret = (*pScreenPriv->SetDGAMode)(index, num, dev);
+
+ pScreenPriv->isDGAmode = DGAActive(index);
+
+ if(!pScreenPriv->isDGAmode && GetInstalledmiColormap(pScreen)
+ && xf86Screens[pScreen->myNum]->vtSema)
+ CMapReinstallMap(GetInstalledmiColormap(pScreen));
+
+ return ret;
+}
+#endif
+
+
+/**** Utilities ****/
+
+static void
+CMapReinstallMap(ColormapPtr pmap)
+{
+ CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
+ &pmap->pScreen->devPrivates, CMapScreenKey);
+ CMapColormapPtr cmapPriv = (CMapColormapPtr)dixLookupPrivate(
+ &pmap->devPrivates, CMapColormapKey);
+ ScrnInfoPtr pScrn = xf86Screens[pmap->pScreen->myNum];
+ int i = cmapPriv->numColors;
+ int *indices = pScreenPriv->PreAllocIndices;
+
+ while(i--)
+ indices[i] = i;
+
+ if(cmapPriv->recalculate)
+ CMapRefreshColors(pmap, cmapPriv->numColors, indices);
+ else {
+ (*pScrn->LoadPalette)(pScrn, cmapPriv->numColors,
+ indices, cmapPriv->colors, pmap->pVisual);
+ if (pScrn->SetOverscan) {
+#ifdef DEBUGOVERSCAN
+ ErrorF("SetOverscan() called from CMapReinstallMap\n");
+#endif
+ pScrn->SetOverscan(pScrn, cmapPriv->overscan);
+ }
+ }
+
+ cmapPriv->recalculate = FALSE;
+}
+
+
+static void
+CMapRefreshColors(ColormapPtr pmap, int defs, int* indices)
+{
+ CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
+ &pmap->pScreen->devPrivates, CMapScreenKey);
+ CMapColormapPtr pColPriv = (CMapColormapPtr)dixLookupPrivate(
+ &pmap->devPrivates, CMapColormapKey);
+ VisualPtr pVisual = pmap->pVisual;
+ ScrnInfoPtr pScrn = xf86Screens[pmap->pScreen->myNum];
+ int numColors, i;
+ LOCO *gamma, *colors;
+ EntryPtr entry;
+ int reds, greens, blues, maxValue, index, shift;
+
+ numColors = pColPriv->numColors;
+ shift = 16 - pScreenPriv->sigRGBbits;
+ maxValue = (1 << pScreenPriv->sigRGBbits) - 1;
+ gamma = pScreenPriv->gamma;
+ colors = pColPriv->colors;
+
+ reds = pVisual->redMask >> pVisual->offsetRed;
+ greens = pVisual->greenMask >> pVisual->offsetGreen;
+ blues = pVisual->blueMask >> pVisual->offsetBlue;
+
+ switch(pVisual->class) {
+ case StaticGray:
+ for(i = 0; i < numColors; i++) {
+ index = (i+1) * maxValue / numColors;
+ colors[i].red = gamma[index].red;
+ colors[i].green = gamma[index].green;
+ colors[i].blue = gamma[index].blue;
+ }
+ break;
+ case TrueColor:
+ if (CMapColormapUseMax(pVisual, pScreenPriv)) {
+ for(i = 0; i <= reds; i++)
+ colors[i].red = gamma[i * maxValue / reds].red;
+ for(i = 0; i <= greens; i++)
+ colors[i].green = gamma[i * maxValue / greens].green;
+ for(i = 0; i <= blues; i++)
+ colors[i].blue = gamma[i * maxValue / blues].blue;
+ break;
+ }
+ for(i = 0; i < numColors; i++) {
+ colors[i].red = gamma[((i >> pVisual->offsetRed) & reds) *
+ maxValue / reds].red;
+ colors[i].green = gamma[((i >> pVisual->offsetGreen) & greens) *
+ maxValue / greens].green;
+ colors[i].blue = gamma[((i >> pVisual->offsetBlue) & blues) *
+ maxValue / blues].blue;
+ }
+ break;
+ case StaticColor:
+ case PseudoColor:
+ case GrayScale:
+ for(i = 0; i < defs; i++) {
+ index = indices[i];
+ entry = (EntryPtr)&pmap->red[index];
+
+ if(entry->fShared) {
+ colors[index].red =
+ gamma[entry->co.shco.red->color >> shift].red;
+ colors[index].green =
+ gamma[entry->co.shco.green->color >> shift].green;
+ colors[index].blue =
+ gamma[entry->co.shco.blue->color >> shift].blue;
+ } else {
+ colors[index].red =
+ gamma[entry->co.local.red >> shift].red;
+ colors[index].green =
+ gamma[entry->co.local.green >> shift].green;
+ colors[index].blue =
+ gamma[entry->co.local.blue >> shift].blue;
+ }
+ }
+ break;
+ case DirectColor:
+ if (CMapColormapUseMax(pVisual, pScreenPriv)) {
+ for(i = 0; i < defs; i++) {
+ index = indices[i];
+ if(index <= reds)
+ colors[index].red =
+ gamma[pmap->red[index].co.local.red >> shift].red;
+ if(index <= greens)
+ colors[index].green =
+ gamma[pmap->green[index].co.local.green >> shift].green;
+ if(index <= blues)
+ colors[index].blue =
+ gamma[pmap->blue[index].co.local.blue >> shift].blue;
+
+ }
+ break;
+ }
+ for(i = 0; i < defs; i++) {
+ index = indices[i];
+
+ colors[index].red = gamma[pmap->red[
+ (index >> pVisual->offsetRed) & reds
+ ].co.local.red >> shift].red;
+ colors[index].green = gamma[pmap->green[
+ (index >> pVisual->offsetGreen) & greens
+ ].co.local.green >> shift].green;
+ colors[index].blue = gamma[pmap->blue[
+ (index >> pVisual->offsetBlue) & blues
+ ].co.local.blue >> shift].blue;
+ }
+ break;
+ }
+
+
+ if(LOAD_PALETTE(pmap))
+ (*pScrn->LoadPalette)(pScreenPriv->pScrn, defs, indices,
+ colors, pmap->pVisual);
+
+ if (pScrn->SetOverscan)
+ CMapSetOverscan(pmap, defs, indices);
+
+}
+
+static Bool
+CMapCompareColors(LOCO *color1, LOCO *color2)
+{
+ /* return TRUE if the color1 is "closer" to black than color2 */
+#ifdef DEBUGOVERSCAN
+ ErrorF("#%02x%02x%02x vs #%02x%02x%02x (%d vs %d)\n",
+ color1->red, color1->green, color1->blue,
+ color2->red, color2->green, color2->blue,
+ color1->red + color1->green + color1->blue,
+ color2->red + color2->green + color2->blue);
+#endif
+ return (color1->red + color1->green + color1->blue <
+ color2->red + color2->green + color2->blue);
+}
+
+static void
+CMapSetOverscan(ColormapPtr pmap, int defs, int *indices)
+{
+ CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
+ &pmap->pScreen->devPrivates, CMapScreenKey);
+ CMapColormapPtr pColPriv = (CMapColormapPtr)dixLookupPrivate(
+ &pmap->devPrivates, CMapColormapKey);
+ ScrnInfoPtr pScrn = xf86Screens[pmap->pScreen->myNum];
+ VisualPtr pVisual = pmap->pVisual;
+ int i;
+ LOCO *colors;
+ int index;
+ Bool newOverscan = FALSE;
+ int overscan, tmpOverscan;
+
+ colors = pColPriv->colors;
+ overscan = pColPriv->overscan;
+
+ /*
+ * Search for a new overscan index in the following cases:
+ *
+ * - The index hasn't yet been initialised.  In this case search
+ * for an index that is black or a close match to black.
+ *
+ * - The colour of the old index is changed. In this case search
+ * all indices for a black or close match to black.
+ *
+ * - The colour of the old index wasn't black. In this case only
+ * search the indices that were changed for a better match to black.
+ */
+
+ switch (pVisual->class) {
+ case StaticGray:
+ case TrueColor:
+ /* Should only come here once. Initialise the overscan index to 0 */
+ overscan = 0;
+ newOverscan = TRUE;
+ break;
+ case StaticColor:
+ /*
+ * Only come here once, but search for the overscan in the same way
+ * as for the other cases.
+ */
+ case DirectColor:
+ case PseudoColor:
+ case GrayScale:
+ if (overscan < 0 || overscan > pScreenPriv->maxColors - 1) {
+ /* Uninitialised */
+ newOverscan = TRUE;
+ } else {
+ /* Check if the overscan was changed */
+ for (i = 0; i < defs; i++) {
+ index = indices[i];
+ if (index == overscan) {
+ newOverscan = TRUE;
+ break;
+ }
+ }
+ }
+ if (newOverscan) {
+ /* The overscan is either uninitialised or it has been changed */
+
+ if (overscan < 0 || overscan > pScreenPriv->maxColors - 1)
+ tmpOverscan = pScreenPriv->maxColors - 1;
+ else
+ tmpOverscan = overscan;
+
+ /* search all entries for a close match to black */
+ for (i = pScreenPriv->maxColors - 1; i >= 0; i--) {
+ if (colors[i].red == 0 && colors[i].green == 0 &&
+ colors[i].blue == 0) {
+ overscan = i;
+#ifdef DEBUGOVERSCAN
+ ErrorF("Black found at index 0x%02x\n", i);
+#endif
+ break;
+ } else {
+#ifdef DEBUGOVERSCAN
+ ErrorF("0x%02x: ", i);
+#endif
+ if (CMapCompareColors(&colors[i], &colors[tmpOverscan])) {
+ tmpOverscan = i;
+#ifdef DEBUGOVERSCAN
+ ErrorF("possible \"Black\" at index 0x%02x\n", i);
+#endif
+ }
+ }
+ }
+ if (i < 0)
+ overscan = tmpOverscan;
+ } else {
+ /* Check of the old overscan wasn't black */
+ if (colors[overscan].red != 0 || colors[overscan].green != 0 ||
+ colors[overscan].blue != 0) {
+ int oldOverscan = tmpOverscan = overscan;
+ /* See of there is now a better match */
+ for (i = 0; i < defs; i++) {
+ index = indices[i];
+ if (colors[index].red == 0 && colors[index].green == 0 &&
+ colors[index].blue == 0) {
+ overscan = index;
+#ifdef DEBUGOVERSCAN
+ ErrorF("Black found at index 0x%02x\n", index);
+#endif
+ break;
+ } else {
+#ifdef DEBUGOVERSCAN
+ ErrorF("0x%02x: ", index);
+#endif
+ if (CMapCompareColors(&colors[index],
+ &colors[tmpOverscan])) {
+ tmpOverscan = index;
+#ifdef DEBUGOVERSCAN
+ ErrorF("possible \"Black\" at index 0x%02x\n",
+ index);
+#endif
+ }
+ }
+ }
+ if (i == defs)
+ overscan = tmpOverscan;
+ if (overscan != oldOverscan)
+ newOverscan = TRUE;
+ }
+ }
+ break;
+ }
+ if (newOverscan) {
+ pColPriv->overscan = overscan;
+ if (LOAD_PALETTE(pmap)) {
+#ifdef DEBUGOVERSCAN
+ ErrorF("SetOverscan() called from CmapSetOverscan\n");
+#endif
+ pScrn->SetOverscan(pScreenPriv->pScrn, overscan);
+ }
+ }
+}
+
+static void
+CMapUnwrapScreen(ScreenPtr pScreen)
+{
+ CMapScreenPtr pScreenPriv = (CMapScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, CMapScreenKey);
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+
+ pScreen->CloseScreen = pScreenPriv->CloseScreen;
+ pScreen->CreateColormap = pScreenPriv->CreateColormap;
+ pScreen->DestroyColormap = pScreenPriv->DestroyColormap;
+ pScreen->InstallColormap = pScreenPriv->InstallColormap;
+ pScreen->StoreColors = pScreenPriv->StoreColors;
+
+ pScrn->EnterVT = pScreenPriv->EnterVT;
+ pScrn->SwitchMode = pScreenPriv->SwitchMode;
+ pScrn->SetDGAMode = pScreenPriv->SetDGAMode;
+ pScrn->ChangeGamma = pScreenPriv->ChangeGamma;
+
+ free(pScreenPriv->gamma);
+ free(pScreenPriv->PreAllocIndices);
+ free(pScreenPriv);
+}
+
+
+static void
+ComputeGamma(CMapScreenPtr priv)
+{
+ int elements = priv->gammaElements - 1;
+ double RedGamma, GreenGamma, BlueGamma;
+ int i;
+
+#ifndef DONT_CHECK_GAMMA
+ /* This check is to catch drivers that are not initialising pScrn->gamma */
+ if (priv->pScrn->gamma.red < GAMMA_MIN ||
+ priv->pScrn->gamma.red > GAMMA_MAX ||
+ priv->pScrn->gamma.green < GAMMA_MIN ||
+ priv->pScrn->gamma.green > GAMMA_MAX ||
+ priv->pScrn->gamma.blue < GAMMA_MIN ||
+ priv->pScrn->gamma.blue > GAMMA_MAX) {
+
+ xf86DrvMsgVerb(priv->pScrn->scrnIndex, X_WARNING, 0,
+ "The %s driver didn't call xf86SetGamma() to initialise\n"
+ "\tthe gamma values.\n", priv->pScrn->driverName);
+ xf86DrvMsgVerb(priv->pScrn->scrnIndex, X_WARNING, 0,
+ "PLEASE FIX THE `%s' DRIVER!\n", priv->pScrn->driverName);
+ priv->pScrn->gamma.red = 1.0;
+ priv->pScrn->gamma.green = 1.0;
+ priv->pScrn->gamma.blue = 1.0;
+ }
+#endif
+
+ RedGamma = 1.0 / (double)priv->pScrn->gamma.red;
+ GreenGamma = 1.0 / (double)priv->pScrn->gamma.green;
+ BlueGamma = 1.0 / (double)priv->pScrn->gamma.blue;
+
+ for(i = 0; i <= elements; i++) {
+ if(RedGamma == 1.0)
+ priv->gamma[i].red = i;
+ else
+ priv->gamma[i].red = (CARD16)(pow((double)i/(double)elements,
+ RedGamma) * (double)elements + 0.5);
+
+ if(GreenGamma == 1.0)
+ priv->gamma[i].green = i;
+ else
+ priv->gamma[i].green = (CARD16)(pow((double)i/(double)elements,
+ GreenGamma) * (double)elements + 0.5);
+
+ if(BlueGamma == 1.0)
+ priv->gamma[i].blue = i;
+ else
+ priv->gamma[i].blue = (CARD16)(pow((double)i/(double)elements,
+ BlueGamma) * (double)elements + 0.5);
+ }
+}
+
+
+int
+CMapChangeGamma(
+ int index,
+ Gamma gamma
+){
+ int ret = Success;
+ ScrnInfoPtr pScrn = xf86Screens[index];
+ ScreenPtr pScreen = pScrn->pScreen;
+ CMapColormapPtr pColPriv;
+ CMapScreenPtr pScreenPriv;
+ CMapLinkPtr pLink;
+
+ /* Is this sufficient checking ? */
+ if(CMapScreenKey == NULL)
+ return BadImplementation;
+
+ pScreenPriv = (CMapScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
+ CMapScreenKey);
+ if(!pScreenPriv)
+ return BadImplementation;
+
+ if (gamma.red < GAMMA_MIN || gamma.red > GAMMA_MAX ||
+ gamma.green < GAMMA_MIN || gamma.green > GAMMA_MAX ||
+ gamma.blue < GAMMA_MIN || gamma.blue > GAMMA_MAX)
+ return BadValue;
+
+ pScrn->gamma.red = gamma.red;
+ pScrn->gamma.green = gamma.green;
+ pScrn->gamma.blue = gamma.blue;
+
+ ComputeGamma(pScreenPriv);
+
+ /* mark all colormaps on this screen */
+ pLink = pScreenPriv->maps;
+ while(pLink) {
+ pColPriv = (CMapColormapPtr)dixLookupPrivate(&pLink->cmap->devPrivates,
+ CMapColormapKey);
+ pColPriv->recalculate = TRUE;
+ pLink = pLink->next;
+ }
+
+ if(GetInstalledmiColormap(pScreen) &&
+ ((pScreenPriv->flags & CMAP_LOAD_EVEN_IF_OFFSCREEN) ||
+ pScrn->vtSema || pScreenPriv->isDGAmode)) {
+ ColormapPtr pMap = GetInstalledmiColormap(pScreen);
+
+ if (!(pScreenPriv->flags & CMAP_PALETTED_TRUECOLOR) &&
+ (pMap->pVisual->class == TrueColor) &&
+ CMapColormapUseMax(pMap->pVisual, pScreenPriv)) {
+
+ /* if the current map doesn't have a palette look
+ for another map to change the gamma on. */
+
+ pLink = pScreenPriv->maps;
+ while(pLink) {
+ if(pLink->cmap->pVisual->class == PseudoColor)
+ break;
+ pLink = pLink->next;
+ }
+
+ if(pLink) {
+ /* need to trick CMapRefreshColors() into thinking
+ this is the currently installed map */
+ SetInstalledmiColormap(pScreen, pLink->cmap);
+ CMapReinstallMap(pLink->cmap);
+ SetInstalledmiColormap(pScreen, pMap);
+ }
+ } else
+ CMapReinstallMap(pMap);
+ }
+
+ pScrn->ChangeGamma = pScreenPriv->ChangeGamma;
+ if (pScrn->ChangeGamma)
+ ret = pScrn->ChangeGamma(index, gamma);
+ pScrn->ChangeGamma = CMapChangeGamma;
+
+ return ret;
+}
+
+
+static void
+ComputeGammaRamp (
+ CMapScreenPtr priv,
+ unsigned short *red,
+ unsigned short *green,
+ unsigned short *blue
+){
+ int elements = priv->gammaElements;
+ LOCO *entry = priv->gamma;
+ int shift = 16 - priv->sigRGBbits;
+
+ while(elements--) {
+ entry->red = *(red++) >> shift;
+ entry->green = *(green++) >> shift;
+ entry->blue = *(blue++) >> shift;
+ entry++;
+ }
+}
+
+int
+xf86ChangeGammaRamp(
+ ScreenPtr pScreen,
+ int size,
+ unsigned short *red,
+ unsigned short *green,
+ unsigned short *blue
+){
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ CMapColormapPtr pColPriv;
+ CMapScreenPtr pScreenPriv;
+ CMapLinkPtr pLink;
+
+ if (xf86_crtc_supports_gamma(pScrn)) {
+ RRCrtcPtr crtc = xf86CompatRRCrtc(pScrn);
+
+ if (crtc) {
+ if (crtc->gammaSize != size)
+ return BadValue;
+
+ RRCrtcGammaSet(crtc, red, green, blue);
+
+ return Success;
+ }
+ }
+
+ if(CMapScreenKey == NULL)
+ return BadImplementation;
+
+ pScreenPriv = (CMapScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
+ CMapScreenKey);
+ if(!pScreenPriv)
+ return BadImplementation;
+
+ if(pScreenPriv->gammaElements != size)
+ return BadValue;
+
+ ComputeGammaRamp(pScreenPriv, red, green, blue);
+
+ /* mark all colormaps on this screen */
+ pLink = pScreenPriv->maps;
+ while(pLink) {
+ pColPriv = (CMapColormapPtr)dixLookupPrivate(&pLink->cmap->devPrivates,
+ CMapColormapKey);
+ pColPriv->recalculate = TRUE;
+ pLink = pLink->next;
+ }
+
+ if(GetInstalledmiColormap(pScreen) &&
+ ((pScreenPriv->flags & CMAP_LOAD_EVEN_IF_OFFSCREEN) ||
+ pScrn->vtSema || pScreenPriv->isDGAmode)) {
+ ColormapPtr pMap = GetInstalledmiColormap(pScreen);
+
+ if (!(pScreenPriv->flags & CMAP_PALETTED_TRUECOLOR) &&
+ (pMap->pVisual->class == TrueColor) &&
+ CMapColormapUseMax(pMap->pVisual, pScreenPriv)) {
+
+ /* if the current map doesn't have a palette look
+ for another map to change the gamma on. */
+
+ pLink = pScreenPriv->maps;
+ while(pLink) {
+ if(pLink->cmap->pVisual->class == PseudoColor)
+ break;
+ pLink = pLink->next;
+ }
+
+ if(pLink) {
+ /* need to trick CMapRefreshColors() into thinking
+ this is the currently installed map */
+ SetInstalledmiColormap(pScreen, pLink->cmap);
+ CMapReinstallMap(pLink->cmap);
+ SetInstalledmiColormap(pScreen, pMap);
+ }
+ } else
+ CMapReinstallMap(pMap);
+ }
+
+ return Success;
+}
+
+int
+xf86GetGammaRampSize(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ CMapScreenPtr pScreenPriv;
+
+ if (xf86_crtc_supports_gamma(pScrn)) {
+ RRCrtcPtr crtc = xf86CompatRRCrtc(pScrn);
+
+ if (crtc)
+ return crtc->gammaSize;
+ }
+
+ if(CMapScreenKey == NULL) return 0;
+
+ pScreenPriv = (CMapScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
+ CMapScreenKey);
+ if(!pScreenPriv) return 0;
+
+ return pScreenPriv->gammaElements;
+}
+
+int
+xf86GetGammaRamp(
+ ScreenPtr pScreen,
+ int size,
+ unsigned short *red,
+ unsigned short *green,
+ unsigned short *blue
+){
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ CMapScreenPtr pScreenPriv;
+ LOCO *entry;
+ int shift, sigbits;
+
+ if (xf86_crtc_supports_gamma(pScrn)) {
+ RRCrtcPtr crtc = xf86CompatRRCrtc(pScrn);
+
+ if (crtc) {
+ if (crtc->gammaSize < size)
+ return BadValue;
+
+ if (!RRCrtcGammaGet(crtc))
+ return BadImplementation;
+
+ memcpy(red, crtc->gammaRed, size * sizeof(*red));
+ memcpy(green, crtc->gammaGreen, size * sizeof(*green));
+ memcpy(blue, crtc->gammaBlue, size * sizeof(*blue));
+
+ return Success;
+ }
+ }
+
+ if(CMapScreenKey == NULL)
+ return BadImplementation;
+
+ pScreenPriv = (CMapScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
+ CMapScreenKey);
+ if(!pScreenPriv)
+ return BadImplementation;
+
+ if(size > pScreenPriv->gammaElements)
+ return BadValue;
+
+ entry = pScreenPriv->gamma;
+ sigbits = pScreenPriv->sigRGBbits;
+
+ while(size--) {
+ *red = entry->red << (16 - sigbits);
+ *green = entry->green << (16 - sigbits);
+ *blue = entry->blue << (16 - sigbits);
+ shift = sigbits;
+ while(shift < 16) {
+ *red |= *red >> shift;
+ *green |= *green >> shift;
+ *blue |= *blue >> shift;
+ shift += sigbits;
+ }
+ red++; green++; blue++;
+ entry++;
+ }
+
+ return Success;
+}
+
+int
+xf86ChangeGamma(
+ ScreenPtr pScreen,
+ Gamma gamma
+){
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+
+ if(pScrn->ChangeGamma)
+ return (*pScrn->ChangeGamma)(pScreen->myNum, gamma);
+
+ return BadImplementation;
+}
diff --git a/xorg-server/hw/xfree86/common/xf86fbman.c b/xorg-server/hw/xfree86/common/xf86fbman.c
index 5b8871723..1ca27015f 100644
--- a/xorg-server/hw/xfree86/common/xf86fbman.c
+++ b/xorg-server/hw/xfree86/common/xf86fbman.c
@@ -1,1438 +1,1438 @@
-
-/*
- * Copyright (c) 1998-2001 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "misc.h"
-#include "xf86.h"
-
-#include <X11/X.h>
-#include "scrnintstr.h"
-#include "regionstr.h"
-#include "xf86fbman.h"
-
-/*
-#define DEBUG
-*/
-
-static int xf86FBManagerKeyIndex;
-static DevPrivateKey xf86FBManagerKey;
-
-Bool xf86RegisterOffscreenManager(
- ScreenPtr pScreen,
- FBManagerFuncsPtr funcs
-){
-
- xf86FBManagerKey = &xf86FBManagerKeyIndex;
- dixSetPrivate(&pScreen->devPrivates, xf86FBManagerKey, funcs);
-
- return TRUE;
-}
-
-
-Bool
-xf86FBManagerRunning(ScreenPtr pScreen)
-{
- if(xf86FBManagerKey == NULL)
- return FALSE;
- if(!dixLookupPrivate(&pScreen->devPrivates, xf86FBManagerKey))
- return FALSE;
-
- return TRUE;
-}
-
-Bool
-xf86RegisterFreeBoxCallback(
- ScreenPtr pScreen,
- FreeBoxCallbackProcPtr FreeBoxCallback,
- pointer devPriv
-){
- FBManagerFuncsPtr funcs;
-
- if(xf86FBManagerKey == NULL)
- return FALSE;
- if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBManagerKey)))
- return FALSE;
-
- return (*funcs->RegisterFreeBoxCallback)(pScreen, FreeBoxCallback, devPriv);
-}
-
-
-FBAreaPtr
-xf86AllocateOffscreenArea(
- ScreenPtr pScreen,
- int w, int h,
- int gran,
- MoveAreaCallbackProcPtr moveCB,
- RemoveAreaCallbackProcPtr removeCB,
- pointer privData
-){
- FBManagerFuncsPtr funcs;
-
- if(xf86FBManagerKey == NULL)
- return NULL;
- if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBManagerKey)))
- return NULL;
-
- return (*funcs->AllocateOffscreenArea)(
- pScreen, w, h, gran, moveCB, removeCB, privData);
-}
-
-
-FBLinearPtr
-xf86AllocateOffscreenLinear(
- ScreenPtr pScreen,
- int length,
- int gran,
- MoveLinearCallbackProcPtr moveCB,
- RemoveLinearCallbackProcPtr removeCB,
- pointer privData
-){
- FBManagerFuncsPtr funcs;
-
- if(xf86FBManagerKey == NULL)
- return NULL;
- if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBManagerKey)))
- return NULL;
-
- return (*funcs->AllocateOffscreenLinear)(
- pScreen, length, gran, moveCB, removeCB, privData);
-}
-
-
-void
-xf86FreeOffscreenArea(FBAreaPtr area)
-{
- FBManagerFuncsPtr funcs;
-
- if(!area) return;
-
- if(xf86FBManagerKey == NULL)
- return;
- if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(
- &area->pScreen->devPrivates, xf86FBManagerKey)))
- return;
-
- (*funcs->FreeOffscreenArea)(area);
-
- return;
-}
-
-
-void
-xf86FreeOffscreenLinear(FBLinearPtr linear)
-{
- FBManagerFuncsPtr funcs;
-
- if(!linear) return;
-
- if(xf86FBManagerKey == NULL)
- return;
- if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(
- &linear->pScreen->devPrivates, xf86FBManagerKey)))
- return;
-
- (*funcs->FreeOffscreenLinear)(linear);
-
- return;
-}
-
-
-Bool
-xf86ResizeOffscreenArea(
- FBAreaPtr resize,
- int w, int h
-){
- FBManagerFuncsPtr funcs;
-
- if(!resize) return FALSE;
-
- if(xf86FBManagerKey == NULL)
- return FALSE;
- if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(
- &resize->pScreen->devPrivates, xf86FBManagerKey)))
- return FALSE;
-
- return (*funcs->ResizeOffscreenArea)(resize, w, h);
-}
-
-Bool
-xf86ResizeOffscreenLinear(
- FBLinearPtr resize,
- int size
-){
- FBManagerFuncsPtr funcs;
-
- if(!resize) return FALSE;
-
- if(xf86FBManagerKey == NULL)
- return FALSE;
- if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(
- &resize->pScreen->devPrivates, xf86FBManagerKey)))
- return FALSE;
-
- return (*funcs->ResizeOffscreenLinear)(resize, size);
-}
-
-
-Bool
-xf86QueryLargestOffscreenArea(
- ScreenPtr pScreen,
- int *w, int *h,
- int gran,
- int preferences,
- int severity
-){
- FBManagerFuncsPtr funcs;
-
- *w = 0;
- *h = 0;
-
- if(xf86FBManagerKey == NULL)
- return FALSE;
- if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBManagerKey)))
- return FALSE;
-
- return (*funcs->QueryLargestOffscreenArea)(
- pScreen, w, h, gran, preferences, severity);
-}
-
-Bool
-xf86QueryLargestOffscreenLinear(
- ScreenPtr pScreen,
- int *size,
- int gran,
- int severity
-){
- FBManagerFuncsPtr funcs;
-
- *size = 0;
-
- if(xf86FBManagerKey == NULL)
- return FALSE;
- if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBManagerKey)))
- return FALSE;
-
- return (*funcs->QueryLargestOffscreenLinear)(
- pScreen, size, gran, severity);
-}
-
-
-Bool
-xf86PurgeUnlockedOffscreenAreas(ScreenPtr pScreen)
-{
- FBManagerFuncsPtr funcs;
-
- if(xf86FBManagerKey == NULL)
- return FALSE;
- if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBManagerKey)))
- return FALSE;
-
- return (*funcs->PurgeOffscreenAreas)(pScreen);
-}
-
-/************************************************************\
-
- Below is a specific implementation of an offscreen manager.
-
-\************************************************************/
-
-static int xf86FBScreenKeyIndex;
-static DevPrivateKey xf86FBScreenKey = &xf86FBScreenKeyIndex;
-
-typedef struct _FBLink {
- FBArea area;
- struct _FBLink *next;
-} FBLink, *FBLinkPtr;
-
-typedef struct _FBLinearLink {
- FBLinear linear;
- int free; /* need to add free here as FBLinear is publicly accessible */
- FBAreaPtr area; /* only used if allocation came from XY area */
- struct _FBLinearLink *next;
-} FBLinearLink, *FBLinearLinkPtr;
-
-
-typedef struct {
- ScreenPtr pScreen;
- RegionPtr InitialBoxes;
- RegionPtr FreeBoxes;
- FBLinkPtr UsedAreas;
- int NumUsedAreas;
- FBLinearLinkPtr LinearAreas;
- CloseScreenProcPtr CloseScreen;
- int NumCallbacks;
- FreeBoxCallbackProcPtr *FreeBoxesUpdateCallback;
- DevUnion *devPrivates;
-} FBManager, *FBManagerPtr;
-
-
-static void
-SendCallFreeBoxCallbacks(FBManagerPtr offman)
-{
- int i = offman->NumCallbacks;
-
- while(i--) {
- (*offman->FreeBoxesUpdateCallback[i])(
- offman->pScreen, offman->FreeBoxes, offman->devPrivates[i].ptr);
- }
-}
-
-static Bool
-localRegisterFreeBoxCallback(
- ScreenPtr pScreen,
- FreeBoxCallbackProcPtr FreeBoxCallback,
- pointer devPriv
-){
- FBManagerPtr offman;
- FreeBoxCallbackProcPtr *newCallbacks;
- DevUnion *newPrivates;
-
- offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBScreenKey);
- newCallbacks = xrealloc( offman->FreeBoxesUpdateCallback,
- sizeof(FreeBoxCallbackProcPtr) * (offman->NumCallbacks + 1));
-
- newPrivates = xrealloc(offman->devPrivates,
- sizeof(DevUnion) * (offman->NumCallbacks + 1));
-
- if(!newCallbacks || !newPrivates)
- return FALSE;
-
- offman->FreeBoxesUpdateCallback = newCallbacks;
- offman->devPrivates = newPrivates;
-
- offman->FreeBoxesUpdateCallback[offman->NumCallbacks] = FreeBoxCallback;
- offman->devPrivates[offman->NumCallbacks].ptr = devPriv;
- offman->NumCallbacks++;
-
- SendCallFreeBoxCallbacks(offman);
-
- return TRUE;
-}
-
-
-static FBAreaPtr
-AllocateArea(
- FBManagerPtr offman,
- int w, int h,
- int granularity,
- MoveAreaCallbackProcPtr moveCB,
- RemoveAreaCallbackProcPtr removeCB,
- pointer privData
-){
- ScreenPtr pScreen = offman->pScreen;
- FBLinkPtr link = NULL;
- FBAreaPtr area = NULL;
- RegionRec NewReg;
- int i, x = 0, num;
- BoxPtr boxp;
-
- if(granularity <= 1) granularity = 0;
-
- boxp = REGION_RECTS(offman->FreeBoxes);
- num = REGION_NUM_RECTS(offman->FreeBoxes);
-
- /* look through the free boxes */
- for(i = 0; i < num; i++, boxp++) {
- x = boxp->x1;
- if (granularity > 1)
- x = ((x + granularity - 1) / granularity) * granularity;
-
- if(((boxp->y2 - boxp->y1) < h) || ((boxp->x2 - x) < w))
- continue;
-
- link = xalloc(sizeof(FBLink));
- if(!link) return NULL;
-
- area = &(link->area);
- link->next = offman->UsedAreas;
- offman->UsedAreas = link;
- offman->NumUsedAreas++;
- break;
- }
-
- /* try to boot a removeable one out if we are not expendable ourselves */
- if(!area && !removeCB) {
- link = offman->UsedAreas;
-
- while(link) {
- if(!link->area.RemoveAreaCallback) {
- link = link->next;
- continue;
- }
-
- boxp = &(link->area.box);
- x = boxp->x1;
- if (granularity > 1)
- x = ((x + granularity - 1) / granularity) * granularity;
-
- if(((boxp->y2 - boxp->y1) < h) || ((boxp->x2 - x) < w)) {
- link = link->next;
- continue;
- }
-
- /* bye, bye */
- (*link->area.RemoveAreaCallback)(&link->area);
- REGION_INIT(pScreen, &NewReg, &(link->area.box), 1);
- REGION_UNION(pScreen, offman->FreeBoxes, offman->FreeBoxes, &NewReg);
- REGION_UNINIT(pScreen, &NewReg);
-
- area = &(link->area);
- break;
- }
- }
-
- if(area) {
- area->pScreen = pScreen;
- area->granularity = granularity;
- area->box.x1 = x;
- area->box.x2 = x + w;
- area->box.y1 = boxp->y1;
- area->box.y2 = boxp->y1 + h;
- area->MoveAreaCallback = moveCB;
- area->RemoveAreaCallback = removeCB;
- area->devPrivate.ptr = privData;
-
- REGION_INIT(pScreen, &NewReg, &(area->box), 1);
- REGION_SUBTRACT(pScreen, offman->FreeBoxes, offman->FreeBoxes, &NewReg);
- REGION_UNINIT(pScreen, &NewReg);
- }
-
- return area;
-}
-
-static FBAreaPtr
-localAllocateOffscreenArea(
- ScreenPtr pScreen,
- int w, int h,
- int gran,
- MoveAreaCallbackProcPtr moveCB,
- RemoveAreaCallbackProcPtr removeCB,
- pointer privData
-){
- FBManagerPtr offman;
- FBAreaPtr area = NULL;
-
- offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBScreenKey);
- if((area = AllocateArea(offman, w, h, gran, moveCB, removeCB, privData)))
- SendCallFreeBoxCallbacks(offman);
-
- return area;
-}
-
-
-static void
-localFreeOffscreenArea(FBAreaPtr area)
-{
- FBManagerPtr offman;
- FBLinkPtr pLink, pLinkPrev = NULL;
- RegionRec FreedRegion;
- ScreenPtr pScreen;
-
- pScreen = area->pScreen;
- offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBScreenKey);
- pLink = offman->UsedAreas;
- if(!pLink) return;
-
- while(&(pLink->area) != area) {
- pLinkPrev = pLink;
- pLink = pLink->next;
- if(!pLink) return;
- }
-
- /* put the area back into the pool */
- REGION_INIT(pScreen, &FreedRegion, &(pLink->area.box), 1);
- REGION_UNION(pScreen, offman->FreeBoxes, offman->FreeBoxes, &FreedRegion);
- REGION_UNINIT(pScreen, &FreedRegion);
-
- if(pLinkPrev)
- pLinkPrev->next = pLink->next;
- else offman->UsedAreas = pLink->next;
-
- xfree(pLink);
- offman->NumUsedAreas--;
-
- SendCallFreeBoxCallbacks(offman);
-}
-
-
-
-static Bool
-localResizeOffscreenArea(
- FBAreaPtr resize,
- int w, int h
-){
- FBManagerPtr offman;
- ScreenPtr pScreen;
- BoxRec OrigArea;
- RegionRec FreedReg;
- FBAreaPtr area = NULL;
- FBLinkPtr pLink, newLink, pLinkPrev = NULL;
-
- pScreen = resize->pScreen;
- offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBScreenKey);
- /* find this link */
- if(!(pLink = offman->UsedAreas))
- return FALSE;
-
- while(&(pLink->area) != resize) {
- pLinkPrev = pLink;
- pLink = pLink->next;
- if(!pLink) return FALSE;
- }
-
- OrigArea.x1 = resize->box.x1;
- OrigArea.x2 = resize->box.x2;
- OrigArea.y1 = resize->box.y1;
- OrigArea.y2 = resize->box.y2;
-
- /* if it's smaller, this is easy */
-
- if((w <= (resize->box.x2 - resize->box.x1)) &&
- (h <= (resize->box.y2 - resize->box.y1))) {
- RegionRec NewReg;
-
- resize->box.x2 = resize->box.x1 + w;
- resize->box.y2 = resize->box.y1 + h;
-
- if((resize->box.y2 == OrigArea.y2) &&
- (resize->box.x2 == OrigArea.x2))
- return TRUE;
-
- REGION_INIT(pScreen, &FreedReg, &OrigArea, 1);
- REGION_INIT(pScreen, &NewReg, &(resize->box), 1);
- REGION_SUBTRACT(pScreen, &FreedReg, &FreedReg, &NewReg);
- REGION_UNION(pScreen, offman->FreeBoxes, offman->FreeBoxes, &FreedReg);
- REGION_UNINIT(pScreen, &FreedReg);
- REGION_UNINIT(pScreen, &NewReg);
-
- SendCallFreeBoxCallbacks(offman);
-
- return TRUE;
- }
-
-
- /* otherwise we remove the old region */
-
- REGION_INIT(pScreen, &FreedReg, &OrigArea, 1);
- REGION_UNION(pScreen, offman->FreeBoxes, offman->FreeBoxes, &FreedReg);
-
- /* remove the old link */
- if(pLinkPrev)
- pLinkPrev->next = pLink->next;
- else offman->UsedAreas = pLink->next;
-
- /* and try to add a new one */
-
- if((area = AllocateArea(offman, w, h, resize->granularity,
- resize->MoveAreaCallback, resize->RemoveAreaCallback,
- resize->devPrivate.ptr))) {
-
- /* copy data over to our link and replace the new with old */
- memcpy(resize, area, sizeof(FBArea));
-
- pLinkPrev = NULL;
- newLink = offman->UsedAreas;
-
- while(&(newLink->area) != area) {
- pLinkPrev = newLink;
- newLink = newLink->next;
- }
-
- if(pLinkPrev)
- pLinkPrev->next = newLink->next;
- else offman->UsedAreas = newLink->next;
-
- pLink->next = offman->UsedAreas;
- offman->UsedAreas = pLink;
-
- xfree(newLink);
-
- /* AllocateArea added one but we really only exchanged one */
- offman->NumUsedAreas--;
- } else {
- /* reinstate the old region */
- REGION_SUBTRACT(pScreen, offman->FreeBoxes, offman->FreeBoxes, &FreedReg);
- REGION_UNINIT(pScreen, &FreedReg);
-
- pLink->next = offman->UsedAreas;
- offman->UsedAreas = pLink;
- return FALSE;
- }
-
-
- REGION_UNINIT(pScreen, &FreedReg);
-
- SendCallFreeBoxCallbacks(offman);
-
- return TRUE;
-}
-
-static Bool
-localQueryLargestOffscreenArea(
- ScreenPtr pScreen,
- int *width, int *height,
- int granularity,
- int preferences,
- int severity
-){
- FBManagerPtr offman;
- RegionPtr newRegion = NULL;
- BoxPtr pbox;
- int nbox;
- int x, w, h, area, oldArea;
-
- *width = *height = oldArea = 0;
-
- if(granularity <= 1) granularity = 0;
-
- if((preferences < 0) || (preferences > 3))
- return FALSE;
-
- offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBScreenKey);
- if(severity < 0) severity = 0;
- if(severity > 2) severity = 2;
-
- switch(severity) {
- case 2:
- if(offman->NumUsedAreas) {
- FBLinkPtr pLink;
- RegionRec tmpRegion;
- newRegion = REGION_CREATE(pScreen, NULL, 1);
- REGION_COPY(pScreen, newRegion, offman->InitialBoxes);
- pLink = offman->UsedAreas;
-
- while(pLink) {
- if(!pLink->area.RemoveAreaCallback) {
- REGION_INIT(pScreen, &tmpRegion, &(pLink->area.box), 1);
- REGION_SUBTRACT(pScreen, newRegion, newRegion, &tmpRegion);
- REGION_UNINIT(pScreen, &tmpRegion);
- }
- pLink = pLink->next;
- }
-
- nbox = REGION_NUM_RECTS(newRegion);
- pbox = REGION_RECTS(newRegion);
- break;
- }
- case 1:
- if(offman->NumUsedAreas) {
- FBLinkPtr pLink;
- RegionRec tmpRegion;
- newRegion = REGION_CREATE(pScreen, NULL, 1);
- REGION_COPY(pScreen, newRegion, offman->FreeBoxes);
- pLink = offman->UsedAreas;
-
- while(pLink) {
- if(pLink->area.RemoveAreaCallback) {
- REGION_INIT(pScreen, &tmpRegion, &(pLink->area.box), 1);
- REGION_APPEND(pScreen, newRegion, &tmpRegion);
- REGION_UNINIT(pScreen, &tmpRegion);
- }
- pLink = pLink->next;
- }
-
- nbox = REGION_NUM_RECTS(newRegion);
- pbox = REGION_RECTS(newRegion);
- break;
- }
- default:
- nbox = REGION_NUM_RECTS(offman->FreeBoxes);
- pbox = REGION_RECTS(offman->FreeBoxes);
- break;
- }
-
- while(nbox--) {
- x = pbox->x1;
- if (granularity > 1)
- x = ((x + granularity - 1) / granularity) * granularity;
-
- w = pbox->x2 - x;
- h = pbox->y2 - pbox->y1;
- area = w * h;
-
- if(w > 0) {
- Bool gotIt = FALSE;
- switch(preferences) {
- case FAVOR_AREA_THEN_WIDTH:
- if((area > oldArea) || ((area == oldArea) && (w > *width)))
- gotIt = TRUE;
- break;
- case FAVOR_AREA_THEN_HEIGHT:
- if((area > oldArea) || ((area == oldArea) && (h > *height)))
- gotIt = TRUE;
- break;
- case FAVOR_WIDTH_THEN_AREA:
- if((w > *width) || ((w == *width) && (area > oldArea)))
- gotIt = TRUE;
- break;
- case FAVOR_HEIGHT_THEN_AREA:
- if((h > *height) || ((h == *height) && (area > oldArea)))
- gotIt = TRUE;
- break;
- }
- if(gotIt) {
- *width = w;
- *height = h;
- oldArea = area;
- }
- }
- pbox++;
- }
-
- if(newRegion)
- REGION_DESTROY(pScreen, newRegion);
-
- return TRUE;
-}
-
-static Bool
-localPurgeUnlockedOffscreenAreas(ScreenPtr pScreen)
-{
- FBManagerPtr offman;
- FBLinkPtr pLink, tmp, pPrev = NULL;
- RegionRec FreedRegion;
- Bool anyUsed = FALSE;
-
- offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBScreenKey);
- pLink = offman->UsedAreas;
- if(!pLink) return TRUE;
-
- while(pLink) {
- if(pLink->area.RemoveAreaCallback) {
- (*pLink->area.RemoveAreaCallback)(&pLink->area);
-
- REGION_INIT(pScreen, &FreedRegion, &(pLink->area.box), 1);
- REGION_APPEND(pScreen, offman->FreeBoxes, &FreedRegion);
- REGION_UNINIT(pScreen, &FreedRegion);
-
- if(pPrev)
- pPrev->next = pLink->next;
- else offman->UsedAreas = pLink->next;
-
- tmp = pLink;
- pLink = pLink->next;
- xfree(tmp);
- offman->NumUsedAreas--;
- anyUsed = TRUE;
- } else {
- pPrev = pLink;
- pLink = pLink->next;
- }
- }
-
- if(anyUsed) {
- REGION_VALIDATE(pScreen, offman->FreeBoxes, &anyUsed);
- SendCallFreeBoxCallbacks(offman);
- }
-
- return TRUE;
-}
-
-static void
-LinearMoveCBWrapper(FBAreaPtr from, FBAreaPtr to)
-{
- /* this will never get called */
-}
-
-static void
-LinearRemoveCBWrapper(FBAreaPtr area)
-{
- FBManagerPtr offman;
- FBLinearLinkPtr pLink, pLinkPrev = NULL;
- ScreenPtr pScreen = area->pScreen;
-
- offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBScreenKey);
- pLink = offman->LinearAreas;
- if(!pLink) return;
-
- while(pLink->area != area) {
- pLinkPrev = pLink;
- pLink = pLink->next;
- if(!pLink) return;
- }
-
- /* give the user the callback it is expecting */
- (*pLink->linear.RemoveLinearCallback)(&(pLink->linear));
-
- if(pLinkPrev)
- pLinkPrev->next = pLink->next;
- else offman->LinearAreas = pLink->next;
-
- xfree(pLink);
-}
-
-static void
-DumpDebug(FBLinearLinkPtr pLink)
-{
-#ifdef DEBUG
- if (!pLink) ErrorF("MMmm, PLINK IS NULL!\n");
-
- while (pLink) {
- ErrorF(" Offset:%08x, Size:%08x, %s,%s\n",
- pLink->linear.offset,
- pLink->linear.size,
- pLink->free ? "Free" : "Used",
- pLink->area ? "Area" : "Linear");
-
- pLink = pLink->next;
- }
-#endif
-}
-
-static FBLinearPtr
-AllocateLinear(
- FBManagerPtr offman,
- int size,
- int granularity,
- pointer privData
-){
- ScreenPtr pScreen = offman->pScreen;
- FBLinearLinkPtr linear = NULL;
- FBLinearLinkPtr newlink = NULL;
- int offset, end;
-
- if(size <= 0) return NULL;
-
- if (!offman->LinearAreas) return NULL;
-
- linear = offman->LinearAreas;
- while (linear) {
- /* Make sure we get a free area that's not an XY fallback case */
- if (!linear->area && linear->free) {
- offset = linear->linear.offset;
- if (granularity > 1)
- offset = ((offset + granularity - 1) / granularity) * granularity;
- end = offset+size;
- if (end <= (linear->linear.offset + linear->linear.size))
- break;
- }
- linear = linear->next;
- }
- if (!linear)
- return NULL;
-
- /* break left */
- if (offset > linear->linear.offset) {
- newlink = xalloc(sizeof(FBLinearLink));
- if (!newlink)
- return NULL;
- newlink->area = NULL;
- newlink->linear.offset = offset;
- newlink->linear.size = linear->linear.size - (offset - linear->linear.offset);
- newlink->free = 1;
- newlink->next = linear->next;
- linear->linear.size -= newlink->linear.size;
- linear->next = newlink;
- linear = newlink;
- }
-
- /* break right */
- if (size < linear->linear.size) {
- newlink = xalloc(sizeof(FBLinearLink));
- if (!newlink)
- return NULL;
- newlink->area = NULL;
- newlink->linear.offset = offset + size;
- newlink->linear.size = linear->linear.size - size;
- newlink->free = 1;
- newlink->next = linear->next;
- linear->linear.size = size;
- linear->next = newlink;
- }
-
- /* p = middle block */
- linear->linear.granularity = granularity;
- linear->free = 0;
- linear->linear.pScreen = pScreen;
- linear->linear.MoveLinearCallback = NULL;
- linear->linear.RemoveLinearCallback = NULL;
- linear->linear.devPrivate.ptr = NULL;
-
- DumpDebug(offman->LinearAreas);
-
- return &(linear->linear);
-}
-
-static FBLinearPtr
-localAllocateOffscreenLinear(
- ScreenPtr pScreen,
- int length,
- int gran,
- MoveLinearCallbackProcPtr moveCB,
- RemoveLinearCallbackProcPtr removeCB,
- pointer privData
-){
- FBManagerPtr offman;
- FBLinearLinkPtr link;
- FBAreaPtr area;
- FBLinearPtr linear = NULL;
- BoxPtr extents;
- int w, h, pitch;
-
- offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBScreenKey);
-
- /* Try to allocate from linear memory first...... */
- DebugF("ALLOCATING LINEAR\n");
- if ((linear = AllocateLinear(offman, length, gran, privData)))
- return linear;
-
- DebugF("NOPE, ALLOCATING AREA\n");
-
- if(!(link = xalloc(sizeof(FBLinearLink))))
- return NULL;
-
- /* No linear available, so try and pinch some from the XY areas */
- extents = REGION_EXTENTS(pScreen, offman->InitialBoxes);
- pitch = extents->x2 - extents->x1;
-
- if (gran > 1) {
- if (gran > pitch) {
- /* we can't match the specified alignment with XY allocations */
- xfree(link);
- return NULL;
- }
-
- if (pitch % gran) {
- /* pitch and granularity aren't a perfect match, let's allocate
- * a bit more so we can align later on
- */
- length += gran - 1;
- }
- }
-
- if(length < pitch) { /* special case */
- w = length;
- h = 1;
- } else {
- w = pitch;
- h = (length + pitch - 1) / pitch;
- }
-
- if((area = localAllocateOffscreenArea(pScreen, w, h, gran,
- moveCB ? LinearMoveCBWrapper : NULL,
- removeCB ? LinearRemoveCBWrapper : NULL,
- privData)))
- {
- link->area = area;
- link->free = 0;
- link->next = offman->LinearAreas;
- offman->LinearAreas = link;
- linear = &(link->linear);
- linear->pScreen = pScreen;
- linear->size = h * w;
- linear->offset = (pitch * area->box.y1) + area->box.x1;
- if (gran > 1)
- linear->offset = ((linear->offset + gran - 1) / gran) * gran;
- linear->granularity = gran;
- linear->MoveLinearCallback = moveCB;
- linear->RemoveLinearCallback = removeCB;
- linear->devPrivate.ptr = privData;
- } else
- xfree(link);
-
- DumpDebug(offman->LinearAreas);
-
- return linear;
-}
-
-
-static void
-localFreeOffscreenLinear(FBLinearPtr linear)
-{
- FBManagerPtr offman;
- FBLinearLinkPtr pLink, pLinkPrev = NULL;
- ScreenPtr pScreen = linear->pScreen;
-
- offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBScreenKey);
- pLink = offman->LinearAreas;
- if(!pLink) return;
-
- while(&(pLink->linear) != linear) {
- pLinkPrev = pLink;
- pLink = pLink->next;
- if(!pLink) return;
- }
-
- if(pLink->area) { /* really an XY area */
- DebugF("FREEING AREA\n");
- localFreeOffscreenArea(pLink->area);
- if(pLinkPrev)
- pLinkPrev->next = pLink->next;
- else offman->LinearAreas = pLink->next;
- xfree(pLink);
- DumpDebug(offman->LinearAreas);
- return;
- }
-
- pLink->free = 1;
-
- if (pLink->next && pLink->next->free) {
- FBLinearLinkPtr p = pLink->next;
- pLink->linear.size += p->linear.size;
- pLink->next = p->next;
- free(p);
- }
-
- if(pLinkPrev) {
- if (pLinkPrev->next && pLinkPrev->next->free && !pLinkPrev->area) {
- FBLinearLinkPtr p = pLinkPrev->next;
- pLinkPrev->linear.size += p->linear.size;
- pLinkPrev->next = p->next;
- free(p);
- }
- }
-
- DebugF("FREEING LINEAR\n");
- DumpDebug(offman->LinearAreas);
-}
-
-
-static Bool
-localResizeOffscreenLinear(FBLinearPtr resize, int length)
-{
- FBManagerPtr offman;
- FBLinearLinkPtr pLink;
- ScreenPtr pScreen = resize->pScreen;
-
- offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBScreenKey);
- pLink = offman->LinearAreas;
- if(!pLink) return FALSE;
-
- while(&(pLink->linear) != resize) {
- pLink = pLink->next;
- if(!pLink) return FALSE;
- }
-
- /* This could actually be alot smarter and try to move allocations
- from XY to linear when available. For now if it was XY, we keep
- it XY */
-
- if(pLink->area) { /* really an XY area */
- BoxPtr extents;
- int pitch, w, h;
-
- extents = REGION_EXTENTS(pScreen, offman->InitialBoxes);
- pitch = extents->x2 - extents->x1;
-
- if(length < pitch) { /* special case */
- w = length;
- h = 1;
- } else {
- w = pitch;
- h = (length + pitch - 1) / pitch;
- }
-
- if(localResizeOffscreenArea(pLink->area, w, h)) {
- resize->size = h * w;
- resize->offset = (pitch * pLink->area->box.y1) + pLink->area->box.x1;
- return TRUE;
- }
- } else {
- /* TODO!!!! resize the linear area */
- }
-
- return FALSE;
-}
-
-
-static Bool
-localQueryLargestOffscreenLinear(
- ScreenPtr pScreen,
- int *size,
- int gran,
- int priority
-)
-{
- FBManagerPtr offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBScreenKey);
- FBLinearLinkPtr pLink;
- FBLinearLinkPtr pLinkRet;
-
- *size = 0;
-
- pLink = offman->LinearAreas;
-
- if (pLink && !pLink->area) {
- pLinkRet = pLink;
- while (pLink) {
- if (pLink->free) {
- if (pLink->linear.size > pLinkRet->linear.size)
- pLinkRet = pLink;
- }
- pLink = pLink->next;
- }
-
- if (pLinkRet->free) {
- *size = pLinkRet->linear.size;
- return TRUE;
- }
- } else {
- int w, h;
-
- if(localQueryLargestOffscreenArea(pScreen, &w, &h, gran,
- FAVOR_WIDTH_THEN_AREA, priority))
- {
- FBManagerPtr offman;
- BoxPtr extents;
-
- offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBScreenKey);
- extents = REGION_EXTENTS(pScreen, offman->InitialBoxes);
- if((extents->x2 - extents->x1) == w)
- *size = w * h;
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-
-
-static FBManagerFuncs xf86FBManFuncs = {
- localAllocateOffscreenArea,
- localFreeOffscreenArea,
- localResizeOffscreenArea,
- localQueryLargestOffscreenArea,
- localRegisterFreeBoxCallback,
- localAllocateOffscreenLinear,
- localFreeOffscreenLinear,
- localResizeOffscreenLinear,
- localQueryLargestOffscreenLinear,
- localPurgeUnlockedOffscreenAreas
- };
-
-
-static Bool
-xf86FBCloseScreen (int i, ScreenPtr pScreen)
-{
- FBLinkPtr pLink, tmp;
- FBLinearLinkPtr pLinearLink, tmp2;
- FBManagerPtr offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBScreenKey);
-
- pScreen->CloseScreen = offman->CloseScreen;
-
- pLink = offman->UsedAreas;
- while(pLink) {
- tmp = pLink;
- pLink = pLink->next;
- xfree(tmp);
- }
-
- pLinearLink = offman->LinearAreas;
- while(pLinearLink) {
- tmp2 = pLinearLink;
- pLinearLink = pLinearLink->next;
- xfree(tmp2);
- }
-
- REGION_DESTROY(pScreen, offman->InitialBoxes);
- REGION_DESTROY(pScreen, offman->FreeBoxes);
-
- xfree(offman->FreeBoxesUpdateCallback);
- xfree(offman->devPrivates);
- xfree(offman);
- dixSetPrivate(&pScreen->devPrivates, xf86FBScreenKey, NULL);
-
- return (*pScreen->CloseScreen) (i, pScreen);
-}
-
-Bool
-xf86InitFBManager(
- ScreenPtr pScreen,
- BoxPtr FullBox
-){
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- RegionRec ScreenRegion;
- RegionRec FullRegion;
- BoxRec ScreenBox;
- Bool ret;
-
- ScreenBox.x1 = 0;
- ScreenBox.y1 = 0;
- ScreenBox.x2 = pScrn->virtualX;
- ScreenBox.y2 = pScrn->virtualY;
-
- if((FullBox->x1 > ScreenBox.x1) || (FullBox->y1 > ScreenBox.y1) ||
- (FullBox->x2 < ScreenBox.x2) || (FullBox->y2 < ScreenBox.y2)) {
- return FALSE;
- }
-
- if (FullBox->y2 < FullBox->y1) return FALSE;
- if (FullBox->x2 < FullBox->x1) return FALSE;
-
- REGION_INIT(pScreen, &ScreenRegion, &ScreenBox, 1);
- REGION_INIT(pScreen, &FullRegion, FullBox, 1);
-
- REGION_SUBTRACT(pScreen, &FullRegion, &FullRegion, &ScreenRegion);
-
- ret = xf86InitFBManagerRegion(pScreen, &FullRegion);
-
- REGION_UNINIT(pScreen, &ScreenRegion);
- REGION_UNINIT(pScreen, &FullRegion);
-
- return ret;
-}
-
-Bool
-xf86InitFBManagerArea(
- ScreenPtr pScreen,
- int PixelArea,
- int Verbosity
-)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xRectangle Rect[3];
- RegionPtr pRegion, pScreenRegion;
- int nRect;
- Bool ret = FALSE;
-
- if (PixelArea < (pScrn->displayWidth * pScrn->virtualY))
- return FALSE;
-
- Rect[0].x = Rect[0].y = 0;
- Rect[0].width = pScrn->displayWidth;
- Rect[0].height = PixelArea / pScrn->displayWidth;
- nRect = 1;
-
- /* Add a possible partial scanline */
- if ((Rect[1].height = Rect[1].width = PixelArea % pScrn->displayWidth)) {
- Rect[1].x = 0;
- Rect[1].y = Rect[0].height;
- Rect[1].height = 1;
- nRect++;
- }
-
- /* Factor out virtual resolution */
- pRegion = RECTS_TO_REGION(pScreen, nRect, Rect, 0);
- if (pRegion) {
- if (!REGION_NAR(pRegion)) {
- Rect[2].x = Rect[2].y = 0;
- Rect[2].width = pScrn->virtualX;
- Rect[2].height = pScrn->virtualY;
-
- pScreenRegion = RECTS_TO_REGION(pScreen, 1, &Rect[2], 0);
- if (pScreenRegion) {
- if (!REGION_NAR(pScreenRegion)) {
- REGION_SUBTRACT(pScreen, pRegion, pRegion, pScreenRegion);
-
- ret = xf86InitFBManagerRegion(pScreen, pRegion);
-
- if (ret && xf86GetVerbosity() >= Verbosity) {
- int scrnIndex = pScrn->scrnIndex;
-
- xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
- "Largest offscreen areas (with overlaps):\n");
-
- if (Rect[2].width < Rect[0].width) {
- xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
- "\t%d x %d rectangle at %d,0\n",
- Rect[0].width - Rect[2].width,
- Rect[0].height,
- Rect[2].width);
- }
- if (Rect[2].width < Rect[1].width) {
- xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
- "\t%d x %d rectangle at %d,0\n",
- Rect[1].width - Rect[2].width,
- Rect[0].height + Rect[1].height,
- Rect[2].width);
- }
- if (Rect[2].height < Rect[0].height) {
- xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
- "\t%d x %d rectangle at 0,%d\n",
- Rect[0].width,
- Rect[0].height - Rect[2].height,
- Rect[2].height);
- }
- if (Rect[1].height) {
- xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
- "\t%d x %d rectangle at 0,%d\n",
- Rect[1].width,
- Rect[0].height - Rect[2].height +
- Rect[1].height,
- Rect[2].height);
- }
- }
- }
-
- REGION_DESTROY(pScreen, pScreenRegion);
- }
- }
-
- REGION_DESTROY(pScreen, pRegion);
- }
-
- return ret;
-}
-
-Bool
-xf86InitFBManagerRegion(
- ScreenPtr pScreen,
- RegionPtr FullRegion
-){
- FBManagerPtr offman;
-
- if(REGION_NIL(FullRegion))
- return FALSE;
-
- if(!xf86RegisterOffscreenManager(pScreen, &xf86FBManFuncs))
- return FALSE;
-
- offman = xalloc(sizeof(FBManager));
- if(!offman) return FALSE;
-
- dixSetPrivate(&pScreen->devPrivates, xf86FBScreenKey, offman);
-
- offman->CloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = xf86FBCloseScreen;
-
- offman->InitialBoxes = REGION_CREATE(pScreen, NULL, 1);
- offman->FreeBoxes = REGION_CREATE(pScreen, NULL, 1);
-
- REGION_COPY(pScreen, offman->InitialBoxes, FullRegion);
- REGION_COPY(pScreen, offman->FreeBoxes, FullRegion);
-
- offman->pScreen = pScreen;
- offman->UsedAreas = NULL;
- offman->LinearAreas = NULL;
- offman->NumUsedAreas = 0;
- offman->NumCallbacks = 0;
- offman->FreeBoxesUpdateCallback = NULL;
- offman->devPrivates = NULL;
-
- return TRUE;
-}
-
-Bool
-xf86InitFBManagerLinear(
- ScreenPtr pScreen,
- int offset,
- int size
-){
- FBManagerPtr offman;
- FBLinearLinkPtr link;
- FBLinearPtr linear;
-
- if (size <= 0)
- return FALSE;
-
- /* we expect people to have called the Area setup first for pixmap cache */
- if (!dixLookupPrivate(&pScreen->devPrivates, xf86FBScreenKey))
- return FALSE;
-
- offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBScreenKey);
- offman->LinearAreas = xalloc(sizeof(FBLinearLink));
- if (!offman->LinearAreas)
- return FALSE;
-
- link = offman->LinearAreas;
- link->area = NULL;
- link->next = NULL;
- link->free = 1;
- linear = &(link->linear);
- linear->pScreen = pScreen;
- linear->size = size;
- linear->offset = offset;
- linear->granularity = 0;
- linear->MoveLinearCallback = NULL;
- linear->RemoveLinearCallback = NULL;
- linear->devPrivate.ptr = NULL;
-
- return TRUE;
-}
-
-
-/* This is an implementation specific function and should
- disappear after the next release. People should use the
- real linear functions instead */
-
-FBAreaPtr
-xf86AllocateLinearOffscreenArea (
- ScreenPtr pScreen,
- int length,
- int gran,
- MoveAreaCallbackProcPtr moveCB,
- RemoveAreaCallbackProcPtr removeCB,
- pointer privData
-){
- FBManagerFuncsPtr funcs;
- FBManagerPtr offman;
- BoxPtr extents;
- int w, h;
-
- if(xf86FBManagerKey == NULL)
- return NULL;
- if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBManagerKey)))
- return NULL;
-
- offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
- xf86FBScreenKey);
- extents = REGION_EXTENTS(pScreen, offman->InitialBoxes);
- w = extents->x2 - extents->x1;
-
- if (gran > 1) {
- if (gran > w)
- return NULL;
-
- if (w % gran)
- length += gran - 1;
- }
-
- if(length <= w) { /* special case */
- h = 1;
- w = length;
- } else {
- h = (length + w - 1) / w;
- }
-
- return (*funcs->AllocateOffscreenArea)(
- pScreen, w, h, gran, moveCB, removeCB, privData);
-}
+
+/*
+ * Copyright (c) 1998-2001 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "misc.h"
+#include "xf86.h"
+
+#include <X11/X.h>
+#include "scrnintstr.h"
+#include "regionstr.h"
+#include "xf86fbman.h"
+
+/*
+#define DEBUG
+*/
+
+static int xf86FBManagerKeyIndex;
+static DevPrivateKey xf86FBManagerKey;
+
+Bool xf86RegisterOffscreenManager(
+ ScreenPtr pScreen,
+ FBManagerFuncsPtr funcs
+){
+
+ xf86FBManagerKey = &xf86FBManagerKeyIndex;
+ dixSetPrivate(&pScreen->devPrivates, xf86FBManagerKey, funcs);
+
+ return TRUE;
+}
+
+
+Bool
+xf86FBManagerRunning(ScreenPtr pScreen)
+{
+ if(xf86FBManagerKey == NULL)
+ return FALSE;
+ if(!dixLookupPrivate(&pScreen->devPrivates, xf86FBManagerKey))
+ return FALSE;
+
+ return TRUE;
+}
+
+Bool
+xf86RegisterFreeBoxCallback(
+ ScreenPtr pScreen,
+ FreeBoxCallbackProcPtr FreeBoxCallback,
+ pointer devPriv
+){
+ FBManagerFuncsPtr funcs;
+
+ if(xf86FBManagerKey == NULL)
+ return FALSE;
+ if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBManagerKey)))
+ return FALSE;
+
+ return (*funcs->RegisterFreeBoxCallback)(pScreen, FreeBoxCallback, devPriv);
+}
+
+
+FBAreaPtr
+xf86AllocateOffscreenArea(
+ ScreenPtr pScreen,
+ int w, int h,
+ int gran,
+ MoveAreaCallbackProcPtr moveCB,
+ RemoveAreaCallbackProcPtr removeCB,
+ pointer privData
+){
+ FBManagerFuncsPtr funcs;
+
+ if(xf86FBManagerKey == NULL)
+ return NULL;
+ if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBManagerKey)))
+ return NULL;
+
+ return (*funcs->AllocateOffscreenArea)(
+ pScreen, w, h, gran, moveCB, removeCB, privData);
+}
+
+
+FBLinearPtr
+xf86AllocateOffscreenLinear(
+ ScreenPtr pScreen,
+ int length,
+ int gran,
+ MoveLinearCallbackProcPtr moveCB,
+ RemoveLinearCallbackProcPtr removeCB,
+ pointer privData
+){
+ FBManagerFuncsPtr funcs;
+
+ if(xf86FBManagerKey == NULL)
+ return NULL;
+ if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBManagerKey)))
+ return NULL;
+
+ return (*funcs->AllocateOffscreenLinear)(
+ pScreen, length, gran, moveCB, removeCB, privData);
+}
+
+
+void
+xf86FreeOffscreenArea(FBAreaPtr area)
+{
+ FBManagerFuncsPtr funcs;
+
+ if(!area) return;
+
+ if(xf86FBManagerKey == NULL)
+ return;
+ if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(
+ &area->pScreen->devPrivates, xf86FBManagerKey)))
+ return;
+
+ (*funcs->FreeOffscreenArea)(area);
+
+ return;
+}
+
+
+void
+xf86FreeOffscreenLinear(FBLinearPtr linear)
+{
+ FBManagerFuncsPtr funcs;
+
+ if(!linear) return;
+
+ if(xf86FBManagerKey == NULL)
+ return;
+ if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(
+ &linear->pScreen->devPrivates, xf86FBManagerKey)))
+ return;
+
+ (*funcs->FreeOffscreenLinear)(linear);
+
+ return;
+}
+
+
+Bool
+xf86ResizeOffscreenArea(
+ FBAreaPtr resize,
+ int w, int h
+){
+ FBManagerFuncsPtr funcs;
+
+ if(!resize) return FALSE;
+
+ if(xf86FBManagerKey == NULL)
+ return FALSE;
+ if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(
+ &resize->pScreen->devPrivates, xf86FBManagerKey)))
+ return FALSE;
+
+ return (*funcs->ResizeOffscreenArea)(resize, w, h);
+}
+
+Bool
+xf86ResizeOffscreenLinear(
+ FBLinearPtr resize,
+ int size
+){
+ FBManagerFuncsPtr funcs;
+
+ if(!resize) return FALSE;
+
+ if(xf86FBManagerKey == NULL)
+ return FALSE;
+ if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(
+ &resize->pScreen->devPrivates, xf86FBManagerKey)))
+ return FALSE;
+
+ return (*funcs->ResizeOffscreenLinear)(resize, size);
+}
+
+
+Bool
+xf86QueryLargestOffscreenArea(
+ ScreenPtr pScreen,
+ int *w, int *h,
+ int gran,
+ int preferences,
+ int severity
+){
+ FBManagerFuncsPtr funcs;
+
+ *w = 0;
+ *h = 0;
+
+ if(xf86FBManagerKey == NULL)
+ return FALSE;
+ if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBManagerKey)))
+ return FALSE;
+
+ return (*funcs->QueryLargestOffscreenArea)(
+ pScreen, w, h, gran, preferences, severity);
+}
+
+Bool
+xf86QueryLargestOffscreenLinear(
+ ScreenPtr pScreen,
+ int *size,
+ int gran,
+ int severity
+){
+ FBManagerFuncsPtr funcs;
+
+ *size = 0;
+
+ if(xf86FBManagerKey == NULL)
+ return FALSE;
+ if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBManagerKey)))
+ return FALSE;
+
+ return (*funcs->QueryLargestOffscreenLinear)(
+ pScreen, size, gran, severity);
+}
+
+
+Bool
+xf86PurgeUnlockedOffscreenAreas(ScreenPtr pScreen)
+{
+ FBManagerFuncsPtr funcs;
+
+ if(xf86FBManagerKey == NULL)
+ return FALSE;
+ if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBManagerKey)))
+ return FALSE;
+
+ return (*funcs->PurgeOffscreenAreas)(pScreen);
+}
+
+/************************************************************\
+
+ Below is a specific implementation of an offscreen manager.
+
+\************************************************************/
+
+static int xf86FBScreenKeyIndex;
+static DevPrivateKey xf86FBScreenKey = &xf86FBScreenKeyIndex;
+
+typedef struct _FBLink {
+ FBArea area;
+ struct _FBLink *next;
+} FBLink, *FBLinkPtr;
+
+typedef struct _FBLinearLink {
+ FBLinear linear;
+ int free; /* need to add free here as FBLinear is publicly accessible */
+ FBAreaPtr area; /* only used if allocation came from XY area */
+ struct _FBLinearLink *next;
+} FBLinearLink, *FBLinearLinkPtr;
+
+
+typedef struct {
+ ScreenPtr pScreen;
+ RegionPtr InitialBoxes;
+ RegionPtr FreeBoxes;
+ FBLinkPtr UsedAreas;
+ int NumUsedAreas;
+ FBLinearLinkPtr LinearAreas;
+ CloseScreenProcPtr CloseScreen;
+ int NumCallbacks;
+ FreeBoxCallbackProcPtr *FreeBoxesUpdateCallback;
+ DevUnion *devPrivates;
+} FBManager, *FBManagerPtr;
+
+
+static void
+SendCallFreeBoxCallbacks(FBManagerPtr offman)
+{
+ int i = offman->NumCallbacks;
+
+ while(i--) {
+ (*offman->FreeBoxesUpdateCallback[i])(
+ offman->pScreen, offman->FreeBoxes, offman->devPrivates[i].ptr);
+ }
+}
+
+static Bool
+localRegisterFreeBoxCallback(
+ ScreenPtr pScreen,
+ FreeBoxCallbackProcPtr FreeBoxCallback,
+ pointer devPriv
+){
+ FBManagerPtr offman;
+ FreeBoxCallbackProcPtr *newCallbacks;
+ DevUnion *newPrivates;
+
+ offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBScreenKey);
+ newCallbacks = realloc( offman->FreeBoxesUpdateCallback,
+ sizeof(FreeBoxCallbackProcPtr) * (offman->NumCallbacks + 1));
+
+ newPrivates = realloc(offman->devPrivates,
+ sizeof(DevUnion) * (offman->NumCallbacks + 1));
+
+ if(!newCallbacks || !newPrivates)
+ return FALSE;
+
+ offman->FreeBoxesUpdateCallback = newCallbacks;
+ offman->devPrivates = newPrivates;
+
+ offman->FreeBoxesUpdateCallback[offman->NumCallbacks] = FreeBoxCallback;
+ offman->devPrivates[offman->NumCallbacks].ptr = devPriv;
+ offman->NumCallbacks++;
+
+ SendCallFreeBoxCallbacks(offman);
+
+ return TRUE;
+}
+
+
+static FBAreaPtr
+AllocateArea(
+ FBManagerPtr offman,
+ int w, int h,
+ int granularity,
+ MoveAreaCallbackProcPtr moveCB,
+ RemoveAreaCallbackProcPtr removeCB,
+ pointer privData
+){
+ ScreenPtr pScreen = offman->pScreen;
+ FBLinkPtr link = NULL;
+ FBAreaPtr area = NULL;
+ RegionRec NewReg;
+ int i, x = 0, num;
+ BoxPtr boxp;
+
+ if(granularity <= 1) granularity = 0;
+
+ boxp = REGION_RECTS(offman->FreeBoxes);
+ num = REGION_NUM_RECTS(offman->FreeBoxes);
+
+ /* look through the free boxes */
+ for(i = 0; i < num; i++, boxp++) {
+ x = boxp->x1;
+ if (granularity > 1)
+ x = ((x + granularity - 1) / granularity) * granularity;
+
+ if(((boxp->y2 - boxp->y1) < h) || ((boxp->x2 - x) < w))
+ continue;
+
+ link = malloc(sizeof(FBLink));
+ if(!link) return NULL;
+
+ area = &(link->area);
+ link->next = offman->UsedAreas;
+ offman->UsedAreas = link;
+ offman->NumUsedAreas++;
+ break;
+ }
+
+ /* try to boot a removeable one out if we are not expendable ourselves */
+ if(!area && !removeCB) {
+ link = offman->UsedAreas;
+
+ while(link) {
+ if(!link->area.RemoveAreaCallback) {
+ link = link->next;
+ continue;
+ }
+
+ boxp = &(link->area.box);
+ x = boxp->x1;
+ if (granularity > 1)
+ x = ((x + granularity - 1) / granularity) * granularity;
+
+ if(((boxp->y2 - boxp->y1) < h) || ((boxp->x2 - x) < w)) {
+ link = link->next;
+ continue;
+ }
+
+ /* bye, bye */
+ (*link->area.RemoveAreaCallback)(&link->area);
+ REGION_INIT(pScreen, &NewReg, &(link->area.box), 1);
+ REGION_UNION(pScreen, offman->FreeBoxes, offman->FreeBoxes, &NewReg);
+ REGION_UNINIT(pScreen, &NewReg);
+
+ area = &(link->area);
+ break;
+ }
+ }
+
+ if(area) {
+ area->pScreen = pScreen;
+ area->granularity = granularity;
+ area->box.x1 = x;
+ area->box.x2 = x + w;
+ area->box.y1 = boxp->y1;
+ area->box.y2 = boxp->y1 + h;
+ area->MoveAreaCallback = moveCB;
+ area->RemoveAreaCallback = removeCB;
+ area->devPrivate.ptr = privData;
+
+ REGION_INIT(pScreen, &NewReg, &(area->box), 1);
+ REGION_SUBTRACT(pScreen, offman->FreeBoxes, offman->FreeBoxes, &NewReg);
+ REGION_UNINIT(pScreen, &NewReg);
+ }
+
+ return area;
+}
+
+static FBAreaPtr
+localAllocateOffscreenArea(
+ ScreenPtr pScreen,
+ int w, int h,
+ int gran,
+ MoveAreaCallbackProcPtr moveCB,
+ RemoveAreaCallbackProcPtr removeCB,
+ pointer privData
+){
+ FBManagerPtr offman;
+ FBAreaPtr area = NULL;
+
+ offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBScreenKey);
+ if((area = AllocateArea(offman, w, h, gran, moveCB, removeCB, privData)))
+ SendCallFreeBoxCallbacks(offman);
+
+ return area;
+}
+
+
+static void
+localFreeOffscreenArea(FBAreaPtr area)
+{
+ FBManagerPtr offman;
+ FBLinkPtr pLink, pLinkPrev = NULL;
+ RegionRec FreedRegion;
+ ScreenPtr pScreen;
+
+ pScreen = area->pScreen;
+ offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBScreenKey);
+ pLink = offman->UsedAreas;
+ if(!pLink) return;
+
+ while(&(pLink->area) != area) {
+ pLinkPrev = pLink;
+ pLink = pLink->next;
+ if(!pLink) return;
+ }
+
+ /* put the area back into the pool */
+ REGION_INIT(pScreen, &FreedRegion, &(pLink->area.box), 1);
+ REGION_UNION(pScreen, offman->FreeBoxes, offman->FreeBoxes, &FreedRegion);
+ REGION_UNINIT(pScreen, &FreedRegion);
+
+ if(pLinkPrev)
+ pLinkPrev->next = pLink->next;
+ else offman->UsedAreas = pLink->next;
+
+ free(pLink);
+ offman->NumUsedAreas--;
+
+ SendCallFreeBoxCallbacks(offman);
+}
+
+
+
+static Bool
+localResizeOffscreenArea(
+ FBAreaPtr resize,
+ int w, int h
+){
+ FBManagerPtr offman;
+ ScreenPtr pScreen;
+ BoxRec OrigArea;
+ RegionRec FreedReg;
+ FBAreaPtr area = NULL;
+ FBLinkPtr pLink, newLink, pLinkPrev = NULL;
+
+ pScreen = resize->pScreen;
+ offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBScreenKey);
+ /* find this link */
+ if(!(pLink = offman->UsedAreas))
+ return FALSE;
+
+ while(&(pLink->area) != resize) {
+ pLinkPrev = pLink;
+ pLink = pLink->next;
+ if(!pLink) return FALSE;
+ }
+
+ OrigArea.x1 = resize->box.x1;
+ OrigArea.x2 = resize->box.x2;
+ OrigArea.y1 = resize->box.y1;
+ OrigArea.y2 = resize->box.y2;
+
+ /* if it's smaller, this is easy */
+
+ if((w <= (resize->box.x2 - resize->box.x1)) &&
+ (h <= (resize->box.y2 - resize->box.y1))) {
+ RegionRec NewReg;
+
+ resize->box.x2 = resize->box.x1 + w;
+ resize->box.y2 = resize->box.y1 + h;
+
+ if((resize->box.y2 == OrigArea.y2) &&
+ (resize->box.x2 == OrigArea.x2))
+ return TRUE;
+
+ REGION_INIT(pScreen, &FreedReg, &OrigArea, 1);
+ REGION_INIT(pScreen, &NewReg, &(resize->box), 1);
+ REGION_SUBTRACT(pScreen, &FreedReg, &FreedReg, &NewReg);
+ REGION_UNION(pScreen, offman->FreeBoxes, offman->FreeBoxes, &FreedReg);
+ REGION_UNINIT(pScreen, &FreedReg);
+ REGION_UNINIT(pScreen, &NewReg);
+
+ SendCallFreeBoxCallbacks(offman);
+
+ return TRUE;
+ }
+
+
+ /* otherwise we remove the old region */
+
+ REGION_INIT(pScreen, &FreedReg, &OrigArea, 1);
+ REGION_UNION(pScreen, offman->FreeBoxes, offman->FreeBoxes, &FreedReg);
+
+ /* remove the old link */
+ if(pLinkPrev)
+ pLinkPrev->next = pLink->next;
+ else offman->UsedAreas = pLink->next;
+
+ /* and try to add a new one */
+
+ if((area = AllocateArea(offman, w, h, resize->granularity,
+ resize->MoveAreaCallback, resize->RemoveAreaCallback,
+ resize->devPrivate.ptr))) {
+
+ /* copy data over to our link and replace the new with old */
+ memcpy(resize, area, sizeof(FBArea));
+
+ pLinkPrev = NULL;
+ newLink = offman->UsedAreas;
+
+ while(&(newLink->area) != area) {
+ pLinkPrev = newLink;
+ newLink = newLink->next;
+ }
+
+ if(pLinkPrev)
+ pLinkPrev->next = newLink->next;
+ else offman->UsedAreas = newLink->next;
+
+ pLink->next = offman->UsedAreas;
+ offman->UsedAreas = pLink;
+
+ free(newLink);
+
+ /* AllocateArea added one but we really only exchanged one */
+ offman->NumUsedAreas--;
+ } else {
+ /* reinstate the old region */
+ REGION_SUBTRACT(pScreen, offman->FreeBoxes, offman->FreeBoxes, &FreedReg);
+ REGION_UNINIT(pScreen, &FreedReg);
+
+ pLink->next = offman->UsedAreas;
+ offman->UsedAreas = pLink;
+ return FALSE;
+ }
+
+
+ REGION_UNINIT(pScreen, &FreedReg);
+
+ SendCallFreeBoxCallbacks(offman);
+
+ return TRUE;
+}
+
+static Bool
+localQueryLargestOffscreenArea(
+ ScreenPtr pScreen,
+ int *width, int *height,
+ int granularity,
+ int preferences,
+ int severity
+){
+ FBManagerPtr offman;
+ RegionPtr newRegion = NULL;
+ BoxPtr pbox;
+ int nbox;
+ int x, w, h, area, oldArea;
+
+ *width = *height = oldArea = 0;
+
+ if(granularity <= 1) granularity = 0;
+
+ if((preferences < 0) || (preferences > 3))
+ return FALSE;
+
+ offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBScreenKey);
+ if(severity < 0) severity = 0;
+ if(severity > 2) severity = 2;
+
+ switch(severity) {
+ case 2:
+ if(offman->NumUsedAreas) {
+ FBLinkPtr pLink;
+ RegionRec tmpRegion;
+ newRegion = REGION_CREATE(pScreen, NULL, 1);
+ REGION_COPY(pScreen, newRegion, offman->InitialBoxes);
+ pLink = offman->UsedAreas;
+
+ while(pLink) {
+ if(!pLink->area.RemoveAreaCallback) {
+ REGION_INIT(pScreen, &tmpRegion, &(pLink->area.box), 1);
+ REGION_SUBTRACT(pScreen, newRegion, newRegion, &tmpRegion);
+ REGION_UNINIT(pScreen, &tmpRegion);
+ }
+ pLink = pLink->next;
+ }
+
+ nbox = REGION_NUM_RECTS(newRegion);
+ pbox = REGION_RECTS(newRegion);
+ break;
+ }
+ case 1:
+ if(offman->NumUsedAreas) {
+ FBLinkPtr pLink;
+ RegionRec tmpRegion;
+ newRegion = REGION_CREATE(pScreen, NULL, 1);
+ REGION_COPY(pScreen, newRegion, offman->FreeBoxes);
+ pLink = offman->UsedAreas;
+
+ while(pLink) {
+ if(pLink->area.RemoveAreaCallback) {
+ REGION_INIT(pScreen, &tmpRegion, &(pLink->area.box), 1);
+ REGION_APPEND(pScreen, newRegion, &tmpRegion);
+ REGION_UNINIT(pScreen, &tmpRegion);
+ }
+ pLink = pLink->next;
+ }
+
+ nbox = REGION_NUM_RECTS(newRegion);
+ pbox = REGION_RECTS(newRegion);
+ break;
+ }
+ default:
+ nbox = REGION_NUM_RECTS(offman->FreeBoxes);
+ pbox = REGION_RECTS(offman->FreeBoxes);
+ break;
+ }
+
+ while(nbox--) {
+ x = pbox->x1;
+ if (granularity > 1)
+ x = ((x + granularity - 1) / granularity) * granularity;
+
+ w = pbox->x2 - x;
+ h = pbox->y2 - pbox->y1;
+ area = w * h;
+
+ if(w > 0) {
+ Bool gotIt = FALSE;
+ switch(preferences) {
+ case FAVOR_AREA_THEN_WIDTH:
+ if((area > oldArea) || ((area == oldArea) && (w > *width)))
+ gotIt = TRUE;
+ break;
+ case FAVOR_AREA_THEN_HEIGHT:
+ if((area > oldArea) || ((area == oldArea) && (h > *height)))
+ gotIt = TRUE;
+ break;
+ case FAVOR_WIDTH_THEN_AREA:
+ if((w > *width) || ((w == *width) && (area > oldArea)))
+ gotIt = TRUE;
+ break;
+ case FAVOR_HEIGHT_THEN_AREA:
+ if((h > *height) || ((h == *height) && (area > oldArea)))
+ gotIt = TRUE;
+ break;
+ }
+ if(gotIt) {
+ *width = w;
+ *height = h;
+ oldArea = area;
+ }
+ }
+ pbox++;
+ }
+
+ if(newRegion)
+ REGION_DESTROY(pScreen, newRegion);
+
+ return TRUE;
+}
+
+static Bool
+localPurgeUnlockedOffscreenAreas(ScreenPtr pScreen)
+{
+ FBManagerPtr offman;
+ FBLinkPtr pLink, tmp, pPrev = NULL;
+ RegionRec FreedRegion;
+ Bool anyUsed = FALSE;
+
+ offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBScreenKey);
+ pLink = offman->UsedAreas;
+ if(!pLink) return TRUE;
+
+ while(pLink) {
+ if(pLink->area.RemoveAreaCallback) {
+ (*pLink->area.RemoveAreaCallback)(&pLink->area);
+
+ REGION_INIT(pScreen, &FreedRegion, &(pLink->area.box), 1);
+ REGION_APPEND(pScreen, offman->FreeBoxes, &FreedRegion);
+ REGION_UNINIT(pScreen, &FreedRegion);
+
+ if(pPrev)
+ pPrev->next = pLink->next;
+ else offman->UsedAreas = pLink->next;
+
+ tmp = pLink;
+ pLink = pLink->next;
+ free(tmp);
+ offman->NumUsedAreas--;
+ anyUsed = TRUE;
+ } else {
+ pPrev = pLink;
+ pLink = pLink->next;
+ }
+ }
+
+ if(anyUsed) {
+ REGION_VALIDATE(pScreen, offman->FreeBoxes, &anyUsed);
+ SendCallFreeBoxCallbacks(offman);
+ }
+
+ return TRUE;
+}
+
+static void
+LinearMoveCBWrapper(FBAreaPtr from, FBAreaPtr to)
+{
+ /* this will never get called */
+}
+
+static void
+LinearRemoveCBWrapper(FBAreaPtr area)
+{
+ FBManagerPtr offman;
+ FBLinearLinkPtr pLink, pLinkPrev = NULL;
+ ScreenPtr pScreen = area->pScreen;
+
+ offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBScreenKey);
+ pLink = offman->LinearAreas;
+ if(!pLink) return;
+
+ while(pLink->area != area) {
+ pLinkPrev = pLink;
+ pLink = pLink->next;
+ if(!pLink) return;
+ }
+
+ /* give the user the callback it is expecting */
+ (*pLink->linear.RemoveLinearCallback)(&(pLink->linear));
+
+ if(pLinkPrev)
+ pLinkPrev->next = pLink->next;
+ else offman->LinearAreas = pLink->next;
+
+ free(pLink);
+}
+
+static void
+DumpDebug(FBLinearLinkPtr pLink)
+{
+#ifdef DEBUG
+ if (!pLink) ErrorF("MMmm, PLINK IS NULL!\n");
+
+ while (pLink) {
+ ErrorF(" Offset:%08x, Size:%08x, %s,%s\n",
+ pLink->linear.offset,
+ pLink->linear.size,
+ pLink->free ? "Free" : "Used",
+ pLink->area ? "Area" : "Linear");
+
+ pLink = pLink->next;
+ }
+#endif
+}
+
+static FBLinearPtr
+AllocateLinear(
+ FBManagerPtr offman,
+ int size,
+ int granularity,
+ pointer privData
+){
+ ScreenPtr pScreen = offman->pScreen;
+ FBLinearLinkPtr linear = NULL;
+ FBLinearLinkPtr newlink = NULL;
+ int offset, end;
+
+ if(size <= 0) return NULL;
+
+ if (!offman->LinearAreas) return NULL;
+
+ linear = offman->LinearAreas;
+ while (linear) {
+ /* Make sure we get a free area that's not an XY fallback case */
+ if (!linear->area && linear->free) {
+ offset = linear->linear.offset;
+ if (granularity > 1)
+ offset = ((offset + granularity - 1) / granularity) * granularity;
+ end = offset+size;
+ if (end <= (linear->linear.offset + linear->linear.size))
+ break;
+ }
+ linear = linear->next;
+ }
+ if (!linear)
+ return NULL;
+
+ /* break left */
+ if (offset > linear->linear.offset) {
+ newlink = malloc(sizeof(FBLinearLink));
+ if (!newlink)
+ return NULL;
+ newlink->area = NULL;
+ newlink->linear.offset = offset;
+ newlink->linear.size = linear->linear.size - (offset - linear->linear.offset);
+ newlink->free = 1;
+ newlink->next = linear->next;
+ linear->linear.size -= newlink->linear.size;
+ linear->next = newlink;
+ linear = newlink;
+ }
+
+ /* break right */
+ if (size < linear->linear.size) {
+ newlink = malloc(sizeof(FBLinearLink));
+ if (!newlink)
+ return NULL;
+ newlink->area = NULL;
+ newlink->linear.offset = offset + size;
+ newlink->linear.size = linear->linear.size - size;
+ newlink->free = 1;
+ newlink->next = linear->next;
+ linear->linear.size = size;
+ linear->next = newlink;
+ }
+
+ /* p = middle block */
+ linear->linear.granularity = granularity;
+ linear->free = 0;
+ linear->linear.pScreen = pScreen;
+ linear->linear.MoveLinearCallback = NULL;
+ linear->linear.RemoveLinearCallback = NULL;
+ linear->linear.devPrivate.ptr = NULL;
+
+ DumpDebug(offman->LinearAreas);
+
+ return &(linear->linear);
+}
+
+static FBLinearPtr
+localAllocateOffscreenLinear(
+ ScreenPtr pScreen,
+ int length,
+ int gran,
+ MoveLinearCallbackProcPtr moveCB,
+ RemoveLinearCallbackProcPtr removeCB,
+ pointer privData
+){
+ FBManagerPtr offman;
+ FBLinearLinkPtr link;
+ FBAreaPtr area;
+ FBLinearPtr linear = NULL;
+ BoxPtr extents;
+ int w, h, pitch;
+
+ offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBScreenKey);
+
+ /* Try to allocate from linear memory first...... */
+ DebugF("ALLOCATING LINEAR\n");
+ if ((linear = AllocateLinear(offman, length, gran, privData)))
+ return linear;
+
+ DebugF("NOPE, ALLOCATING AREA\n");
+
+ if(!(link = malloc(sizeof(FBLinearLink))))
+ return NULL;
+
+ /* No linear available, so try and pinch some from the XY areas */
+ extents = REGION_EXTENTS(pScreen, offman->InitialBoxes);
+ pitch = extents->x2 - extents->x1;
+
+ if (gran > 1) {
+ if (gran > pitch) {
+ /* we can't match the specified alignment with XY allocations */
+ free(link);
+ return NULL;
+ }
+
+ if (pitch % gran) {
+ /* pitch and granularity aren't a perfect match, let's allocate
+ * a bit more so we can align later on
+ */
+ length += gran - 1;
+ }
+ }
+
+ if(length < pitch) { /* special case */
+ w = length;
+ h = 1;
+ } else {
+ w = pitch;
+ h = (length + pitch - 1) / pitch;
+ }
+
+ if((area = localAllocateOffscreenArea(pScreen, w, h, gran,
+ moveCB ? LinearMoveCBWrapper : NULL,
+ removeCB ? LinearRemoveCBWrapper : NULL,
+ privData)))
+ {
+ link->area = area;
+ link->free = 0;
+ link->next = offman->LinearAreas;
+ offman->LinearAreas = link;
+ linear = &(link->linear);
+ linear->pScreen = pScreen;
+ linear->size = h * w;
+ linear->offset = (pitch * area->box.y1) + area->box.x1;
+ if (gran > 1)
+ linear->offset = ((linear->offset + gran - 1) / gran) * gran;
+ linear->granularity = gran;
+ linear->MoveLinearCallback = moveCB;
+ linear->RemoveLinearCallback = removeCB;
+ linear->devPrivate.ptr = privData;
+ } else
+ free(link);
+
+ DumpDebug(offman->LinearAreas);
+
+ return linear;
+}
+
+
+static void
+localFreeOffscreenLinear(FBLinearPtr linear)
+{
+ FBManagerPtr offman;
+ FBLinearLinkPtr pLink, pLinkPrev = NULL;
+ ScreenPtr pScreen = linear->pScreen;
+
+ offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBScreenKey);
+ pLink = offman->LinearAreas;
+ if(!pLink) return;
+
+ while(&(pLink->linear) != linear) {
+ pLinkPrev = pLink;
+ pLink = pLink->next;
+ if(!pLink) return;
+ }
+
+ if(pLink->area) { /* really an XY area */
+ DebugF("FREEING AREA\n");
+ localFreeOffscreenArea(pLink->area);
+ if(pLinkPrev)
+ pLinkPrev->next = pLink->next;
+ else offman->LinearAreas = pLink->next;
+ free(pLink);
+ DumpDebug(offman->LinearAreas);
+ return;
+ }
+
+ pLink->free = 1;
+
+ if (pLink->next && pLink->next->free) {
+ FBLinearLinkPtr p = pLink->next;
+ pLink->linear.size += p->linear.size;
+ pLink->next = p->next;
+ free(p);
+ }
+
+ if(pLinkPrev) {
+ if (pLinkPrev->next && pLinkPrev->next->free && !pLinkPrev->area) {
+ FBLinearLinkPtr p = pLinkPrev->next;
+ pLinkPrev->linear.size += p->linear.size;
+ pLinkPrev->next = p->next;
+ free(p);
+ }
+ }
+
+ DebugF("FREEING LINEAR\n");
+ DumpDebug(offman->LinearAreas);
+}
+
+
+static Bool
+localResizeOffscreenLinear(FBLinearPtr resize, int length)
+{
+ FBManagerPtr offman;
+ FBLinearLinkPtr pLink;
+ ScreenPtr pScreen = resize->pScreen;
+
+ offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBScreenKey);
+ pLink = offman->LinearAreas;
+ if(!pLink) return FALSE;
+
+ while(&(pLink->linear) != resize) {
+ pLink = pLink->next;
+ if(!pLink) return FALSE;
+ }
+
+ /* This could actually be alot smarter and try to move allocations
+ from XY to linear when available. For now if it was XY, we keep
+ it XY */
+
+ if(pLink->area) { /* really an XY area */
+ BoxPtr extents;
+ int pitch, w, h;
+
+ extents = REGION_EXTENTS(pScreen, offman->InitialBoxes);
+ pitch = extents->x2 - extents->x1;
+
+ if(length < pitch) { /* special case */
+ w = length;
+ h = 1;
+ } else {
+ w = pitch;
+ h = (length + pitch - 1) / pitch;
+ }
+
+ if(localResizeOffscreenArea(pLink->area, w, h)) {
+ resize->size = h * w;
+ resize->offset = (pitch * pLink->area->box.y1) + pLink->area->box.x1;
+ return TRUE;
+ }
+ } else {
+ /* TODO!!!! resize the linear area */
+ }
+
+ return FALSE;
+}
+
+
+static Bool
+localQueryLargestOffscreenLinear(
+ ScreenPtr pScreen,
+ int *size,
+ int gran,
+ int priority
+)
+{
+ FBManagerPtr offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBScreenKey);
+ FBLinearLinkPtr pLink;
+ FBLinearLinkPtr pLinkRet;
+
+ *size = 0;
+
+ pLink = offman->LinearAreas;
+
+ if (pLink && !pLink->area) {
+ pLinkRet = pLink;
+ while (pLink) {
+ if (pLink->free) {
+ if (pLink->linear.size > pLinkRet->linear.size)
+ pLinkRet = pLink;
+ }
+ pLink = pLink->next;
+ }
+
+ if (pLinkRet->free) {
+ *size = pLinkRet->linear.size;
+ return TRUE;
+ }
+ } else {
+ int w, h;
+
+ if(localQueryLargestOffscreenArea(pScreen, &w, &h, gran,
+ FAVOR_WIDTH_THEN_AREA, priority))
+ {
+ FBManagerPtr offman;
+ BoxPtr extents;
+
+ offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBScreenKey);
+ extents = REGION_EXTENTS(pScreen, offman->InitialBoxes);
+ if((extents->x2 - extents->x1) == w)
+ *size = w * h;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+
+static FBManagerFuncs xf86FBManFuncs = {
+ localAllocateOffscreenArea,
+ localFreeOffscreenArea,
+ localResizeOffscreenArea,
+ localQueryLargestOffscreenArea,
+ localRegisterFreeBoxCallback,
+ localAllocateOffscreenLinear,
+ localFreeOffscreenLinear,
+ localResizeOffscreenLinear,
+ localQueryLargestOffscreenLinear,
+ localPurgeUnlockedOffscreenAreas
+ };
+
+
+static Bool
+xf86FBCloseScreen (int i, ScreenPtr pScreen)
+{
+ FBLinkPtr pLink, tmp;
+ FBLinearLinkPtr pLinearLink, tmp2;
+ FBManagerPtr offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBScreenKey);
+
+ pScreen->CloseScreen = offman->CloseScreen;
+
+ pLink = offman->UsedAreas;
+ while(pLink) {
+ tmp = pLink;
+ pLink = pLink->next;
+ free(tmp);
+ }
+
+ pLinearLink = offman->LinearAreas;
+ while(pLinearLink) {
+ tmp2 = pLinearLink;
+ pLinearLink = pLinearLink->next;
+ free(tmp2);
+ }
+
+ REGION_DESTROY(pScreen, offman->InitialBoxes);
+ REGION_DESTROY(pScreen, offman->FreeBoxes);
+
+ free(offman->FreeBoxesUpdateCallback);
+ free(offman->devPrivates);
+ free(offman);
+ dixSetPrivate(&pScreen->devPrivates, xf86FBScreenKey, NULL);
+
+ return (*pScreen->CloseScreen) (i, pScreen);
+}
+
+Bool
+xf86InitFBManager(
+ ScreenPtr pScreen,
+ BoxPtr FullBox
+){
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ RegionRec ScreenRegion;
+ RegionRec FullRegion;
+ BoxRec ScreenBox;
+ Bool ret;
+
+ ScreenBox.x1 = 0;
+ ScreenBox.y1 = 0;
+ ScreenBox.x2 = pScrn->virtualX;
+ ScreenBox.y2 = pScrn->virtualY;
+
+ if((FullBox->x1 > ScreenBox.x1) || (FullBox->y1 > ScreenBox.y1) ||
+ (FullBox->x2 < ScreenBox.x2) || (FullBox->y2 < ScreenBox.y2)) {
+ return FALSE;
+ }
+
+ if (FullBox->y2 < FullBox->y1) return FALSE;
+ if (FullBox->x2 < FullBox->x1) return FALSE;
+
+ REGION_INIT(pScreen, &ScreenRegion, &ScreenBox, 1);
+ REGION_INIT(pScreen, &FullRegion, FullBox, 1);
+
+ REGION_SUBTRACT(pScreen, &FullRegion, &FullRegion, &ScreenRegion);
+
+ ret = xf86InitFBManagerRegion(pScreen, &FullRegion);
+
+ REGION_UNINIT(pScreen, &ScreenRegion);
+ REGION_UNINIT(pScreen, &FullRegion);
+
+ return ret;
+}
+
+Bool
+xf86InitFBManagerArea(
+ ScreenPtr pScreen,
+ int PixelArea,
+ int Verbosity
+)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ xRectangle Rect[3];
+ RegionPtr pRegion, pScreenRegion;
+ int nRect;
+ Bool ret = FALSE;
+
+ if (PixelArea < (pScrn->displayWidth * pScrn->virtualY))
+ return FALSE;
+
+ Rect[0].x = Rect[0].y = 0;
+ Rect[0].width = pScrn->displayWidth;
+ Rect[0].height = PixelArea / pScrn->displayWidth;
+ nRect = 1;
+
+ /* Add a possible partial scanline */
+ if ((Rect[1].height = Rect[1].width = PixelArea % pScrn->displayWidth)) {
+ Rect[1].x = 0;
+ Rect[1].y = Rect[0].height;
+ Rect[1].height = 1;
+ nRect++;
+ }
+
+ /* Factor out virtual resolution */
+ pRegion = RECTS_TO_REGION(pScreen, nRect, Rect, 0);
+ if (pRegion) {
+ if (!REGION_NAR(pRegion)) {
+ Rect[2].x = Rect[2].y = 0;
+ Rect[2].width = pScrn->virtualX;
+ Rect[2].height = pScrn->virtualY;
+
+ pScreenRegion = RECTS_TO_REGION(pScreen, 1, &Rect[2], 0);
+ if (pScreenRegion) {
+ if (!REGION_NAR(pScreenRegion)) {
+ REGION_SUBTRACT(pScreen, pRegion, pRegion, pScreenRegion);
+
+ ret = xf86InitFBManagerRegion(pScreen, pRegion);
+
+ if (ret && xf86GetVerbosity() >= Verbosity) {
+ int scrnIndex = pScrn->scrnIndex;
+
+ xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
+ "Largest offscreen areas (with overlaps):\n");
+
+ if (Rect[2].width < Rect[0].width) {
+ xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
+ "\t%d x %d rectangle at %d,0\n",
+ Rect[0].width - Rect[2].width,
+ Rect[0].height,
+ Rect[2].width);
+ }
+ if (Rect[2].width < Rect[1].width) {
+ xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
+ "\t%d x %d rectangle at %d,0\n",
+ Rect[1].width - Rect[2].width,
+ Rect[0].height + Rect[1].height,
+ Rect[2].width);
+ }
+ if (Rect[2].height < Rect[0].height) {
+ xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
+ "\t%d x %d rectangle at 0,%d\n",
+ Rect[0].width,
+ Rect[0].height - Rect[2].height,
+ Rect[2].height);
+ }
+ if (Rect[1].height) {
+ xf86DrvMsgVerb(scrnIndex, X_INFO, Verbosity,
+ "\t%d x %d rectangle at 0,%d\n",
+ Rect[1].width,
+ Rect[0].height - Rect[2].height +
+ Rect[1].height,
+ Rect[2].height);
+ }
+ }
+ }
+
+ REGION_DESTROY(pScreen, pScreenRegion);
+ }
+ }
+
+ REGION_DESTROY(pScreen, pRegion);
+ }
+
+ return ret;
+}
+
+Bool
+xf86InitFBManagerRegion(
+ ScreenPtr pScreen,
+ RegionPtr FullRegion
+){
+ FBManagerPtr offman;
+
+ if(REGION_NIL(FullRegion))
+ return FALSE;
+
+ if(!xf86RegisterOffscreenManager(pScreen, &xf86FBManFuncs))
+ return FALSE;
+
+ offman = malloc(sizeof(FBManager));
+ if(!offman) return FALSE;
+
+ dixSetPrivate(&pScreen->devPrivates, xf86FBScreenKey, offman);
+
+ offman->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = xf86FBCloseScreen;
+
+ offman->InitialBoxes = REGION_CREATE(pScreen, NULL, 1);
+ offman->FreeBoxes = REGION_CREATE(pScreen, NULL, 1);
+
+ REGION_COPY(pScreen, offman->InitialBoxes, FullRegion);
+ REGION_COPY(pScreen, offman->FreeBoxes, FullRegion);
+
+ offman->pScreen = pScreen;
+ offman->UsedAreas = NULL;
+ offman->LinearAreas = NULL;
+ offman->NumUsedAreas = 0;
+ offman->NumCallbacks = 0;
+ offman->FreeBoxesUpdateCallback = NULL;
+ offman->devPrivates = NULL;
+
+ return TRUE;
+}
+
+Bool
+xf86InitFBManagerLinear(
+ ScreenPtr pScreen,
+ int offset,
+ int size
+){
+ FBManagerPtr offman;
+ FBLinearLinkPtr link;
+ FBLinearPtr linear;
+
+ if (size <= 0)
+ return FALSE;
+
+ /* we expect people to have called the Area setup first for pixmap cache */
+ if (!dixLookupPrivate(&pScreen->devPrivates, xf86FBScreenKey))
+ return FALSE;
+
+ offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBScreenKey);
+ offman->LinearAreas = malloc(sizeof(FBLinearLink));
+ if (!offman->LinearAreas)
+ return FALSE;
+
+ link = offman->LinearAreas;
+ link->area = NULL;
+ link->next = NULL;
+ link->free = 1;
+ linear = &(link->linear);
+ linear->pScreen = pScreen;
+ linear->size = size;
+ linear->offset = offset;
+ linear->granularity = 0;
+ linear->MoveLinearCallback = NULL;
+ linear->RemoveLinearCallback = NULL;
+ linear->devPrivate.ptr = NULL;
+
+ return TRUE;
+}
+
+
+/* This is an implementation specific function and should
+ disappear after the next release. People should use the
+ real linear functions instead */
+
+FBAreaPtr
+xf86AllocateLinearOffscreenArea (
+ ScreenPtr pScreen,
+ int length,
+ int gran,
+ MoveAreaCallbackProcPtr moveCB,
+ RemoveAreaCallbackProcPtr removeCB,
+ pointer privData
+){
+ FBManagerFuncsPtr funcs;
+ FBManagerPtr offman;
+ BoxPtr extents;
+ int w, h;
+
+ if(xf86FBManagerKey == NULL)
+ return NULL;
+ if(!(funcs = (FBManagerFuncsPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBManagerKey)))
+ return NULL;
+
+ offman = (FBManagerPtr)dixLookupPrivate(&pScreen->devPrivates,
+ xf86FBScreenKey);
+ extents = REGION_EXTENTS(pScreen, offman->InitialBoxes);
+ w = extents->x2 - extents->x1;
+
+ if (gran > 1) {
+ if (gran > w)
+ return NULL;
+
+ if (w % gran)
+ length += gran - 1;
+ }
+
+ if(length <= w) { /* special case */
+ h = 1;
+ w = length;
+ } else {
+ h = (length + w - 1) / w;
+ }
+
+ return (*funcs->AllocateOffscreenArea)(
+ pScreen, w, h, gran, moveCB, removeCB, privData);
+}
diff --git a/xorg-server/hw/xfree86/common/xf86pciBus.c b/xorg-server/hw/xfree86/common/xf86pciBus.c
index ac018e739..b3164730c 100644
--- a/xorg-server/hw/xfree86/common/xf86pciBus.c
+++ b/xorg-server/hw/xfree86/common/xf86pciBus.c
@@ -1,423 +1,423 @@
-/*
- * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-/*
- * This file contains the interfaces to the bus-specific code
- */
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <ctype.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <X11/X.h>
-#include <pciaccess.h>
-#include "os.h"
-#include "Pci.h"
-#include "xf86.h"
-#include "xf86Priv.h"
-
-/* Bus-specific headers */
-#include "xf86Bus.h"
-
-#define XF86_OS_PRIVS
-#include "xf86_OSproc.h"
-
-
-/* Bus-specific globals */
-Bool pciSlotClaimed = FALSE;
-
-#define PCIINFOCLASSES(c) \
- ( (((c) & 0x00ff0000) == (PCI_CLASS_PREHISTORIC << 16)) \
- || (((c) & 0x00ff0000) == (PCI_CLASS_DISPLAY << 16)) \
- || ((((c) & 0x00ffff00) \
- == ((PCI_CLASS_MULTIMEDIA << 16) | (PCI_SUBCLASS_MULTIMEDIA_VIDEO << 8)))) \
- || ((((c) & 0x00ffff00) \
- == ((PCI_CLASS_PROCESSOR << 16) | (PCI_SUBCLASS_PROCESSOR_COPROC << 8)))) )
-
-/*
- * PCI classes that have messages printed always. The others are only
- * have a message printed when the vendor/dev IDs are recognised.
- */
-#define PCIALWAYSPRINTCLASSES(c) \
- ( (((c) & 0x00ffff00) \
- == ((PCI_CLASS_PREHISTORIC << 16) | (PCI_SUBCLASS_PREHISTORIC_VGA << 8))) \
- || (((c) & 0x00ff0000) == (PCI_CLASS_DISPLAY << 16)) \
- || ((((c) & 0x00ffff00) \
- == ((PCI_CLASS_MULTIMEDIA << 16) | (PCI_SUBCLASS_MULTIMEDIA_VIDEO << 8)))) )
-
-#define IS_VGA(c) \
- (((c) & 0x00ffff00) \
- == ((PCI_CLASS_DISPLAY << 16) | (PCI_SUBCLASS_DISPLAY_VGA << 8)))
-
-void
-xf86FormatPciBusNumber(int busnum, char *buffer)
-{
- /* 'buffer' should be at least 8 characters long */
- if (busnum < 256)
- sprintf(buffer, "%d", busnum);
- else
- sprintf(buffer, "%d@%d", busnum & 0x00ff, busnum >> 8);
-}
-
-/*
- * xf86Bus.c interface
- */
-
-void
-xf86PciProbe(void)
-{
- int i = 0, k;
- int num = 0;
- struct pci_device *info;
- struct pci_device_iterator *iter;
- struct pci_device ** xf86PciVideoInfo = NULL;
-
-
- if (!xf86scanpci()) {
- xf86PciVideoInfo = NULL;
- return;
- }
-
- iter = pci_slot_match_iterator_create(& xf86IsolateDevice);
- while ((info = pci_device_next(iter)) != NULL) {
- if (PCIINFOCLASSES(info->device_class)) {
- num++;
- xf86PciVideoInfo = xnfrealloc(xf86PciVideoInfo,
- (sizeof(struct pci_device *)
- * (num + 1)));
- xf86PciVideoInfo[num] = NULL;
- xf86PciVideoInfo[num - 1] = info;
-
- pci_device_probe(info);
-#ifdef HAVE_PCI_DEVICE_IS_BOOT_VGA
- if (pci_device_is_boot_vga(info)) {
- primaryBus.type = BUS_PCI;
- primaryBus.id.pci = info;
- }
-#endif
- info->user_data = 0;
- }
- }
- free(iter);
-
- /* If we haven't found a primary device try a different heuristic */
- if (primaryBus.type == BUS_NONE && num) {
- for (i = 0; i < num; i++) {
- uint16_t command;
-
- info = xf86PciVideoInfo[i];
- pci_device_cfg_read_u16(info, & command, 4);
-
- if ((command & PCI_CMD_MEM_ENABLE)
- && ((num == 1) || IS_VGA(info->device_class))) {
- if (primaryBus.type == BUS_NONE) {
- primaryBus.type = BUS_PCI;
- primaryBus.id.pci = info;
- } else {
- xf86Msg(X_NOTICE,
- "More than one possible primary device found\n");
- primaryBus.type ^= (BusType)(-1);
- }
- }
- }
- }
-
- /* Print a summary of the video devices found */
- for (k = 0; k < num; k++) {
- const char *vendorname = NULL, *chipname = NULL;
- const char *prim = " ";
- Bool memdone = FALSE, iodone = FALSE;
-
-
- info = xf86PciVideoInfo[k];
-
- vendorname = pci_device_get_vendor_name( info );
- chipname = pci_device_get_device_name( info );
-
- if ((!vendorname || !chipname) &&
- !PCIALWAYSPRINTCLASSES(info->device_class))
- continue;
-
- if (xf86IsPrimaryPci(info))
- prim = "*";
-
- xf86Msg(X_PROBED, "PCI:%s(%u:%u:%u:%u) %04x:%04x:%04x:%04x ", prim,
- info->domain, info->bus, info->dev, info->func,
- info->vendor_id, info->device_id,
- info->subvendor_id, info->subdevice_id);
-
- if (vendorname)
- xf86ErrorF("%s ", vendorname);
-
- if (chipname)
- xf86ErrorF("%s ", chipname);
-
- xf86ErrorF("rev %d", info->revision);
-
- for (i = 0; i < 6; i++) {
- struct pci_mem_region * r = & info->regions[i];
-
- if ( r->size && ! r->is_IO ) {
- if (!memdone) {
- xf86ErrorF(", Mem @ ");
- memdone = TRUE;
- } else
- xf86ErrorF(", ");
- xf86ErrorF("0x%08lx/%ld", (long)r->base_addr, (long)r->size);
- }
- }
-
- for (i = 0; i < 6; i++) {
- struct pci_mem_region * r = & info->regions[i];
-
- if ( r->size && r->is_IO ) {
- if (!iodone) {
- xf86ErrorF(", I/O @ ");
- iodone = TRUE;
- } else
- xf86ErrorF(", ");
- xf86ErrorF("0x%08lx/%ld", (long)r->base_addr, (long)r->size);
- }
- }
-
- if ( info->rom_size ) {
- xf86ErrorF(", BIOS @ 0x\?\?\?\?\?\?\?\?/%ld", (long)info->rom_size);
- }
-
- xf86ErrorF("\n");
- }
- xfree(xf86PciVideoInfo);
-}
-
-/*
- * If the slot requested is already in use, return -1.
- * Otherwise, claim the slot for the screen requesting it.
- */
-
-int
-xf86ClaimPciSlot(struct pci_device * d, DriverPtr drvp,
- int chipset, GDevPtr dev, Bool active)
-{
- EntityPtr p = NULL;
- int num;
-
- if (xf86CheckPciSlot(d)) {
- num = xf86AllocateEntity();
- p = xf86Entities[num];
- p->driver = drvp;
- p->chipset = chipset;
- p->bus.type = BUS_PCI;
- p->bus.id.pci = d;
- p->active = active;
- p->inUse = FALSE;
- if (dev)
- xf86AddDevToEntity(num, dev);
- pciSlotClaimed = TRUE;
-
- if (active) {
- /* Map in this domain's I/O space */
- p->domainIO = xf86MapLegacyIO(d);
- }
-
- return num;
- } else
- return -1;
-}
-
-/*
- * Unclaim PCI slot, e.g. if probing failed, so that a different driver can claim.
- */
-void
-xf86UnclaimPciSlot(struct pci_device *d)
-{
- int i;
-
- for (i = 0; i < xf86NumEntities; i++) {
- const EntityPtr p = xf86Entities[i];
-
- if ((p->bus.type == BUS_PCI) && (p->bus.id.pci == d)) {
- /* Probably the slot should be deallocated? */
- p->bus.type = BUS_NONE;
- return;
- }
- }
-}
-
-/*
- * Parse a BUS ID string, and return the PCI bus parameters if it was
- * in the correct format for a PCI bus id.
- */
-
-Bool
-xf86ParsePciBusString(const char *busID, int *bus, int *device, int *func)
-{
- /*
- * The format is assumed to be "bus[@domain]:device[:func]", where domain,
- * bus, device and func are decimal integers. domain and func may be
- * omitted and assumed to be zero, although doing this isn't encouraged.
- */
-
- char *p, *s, *d;
- const char *id;
- int i;
-
- if (StringToBusType(busID, &id) != BUS_PCI)
- return FALSE;
-
- s = xstrdup(id);
- p = strtok(s, ":");
- if (p == NULL || *p == 0) {
- xfree(s);
- return FALSE;
- }
- d = strpbrk(p, "@");
- if (d != NULL) {
- *(d++) = 0;
- for (i = 0; d[i] != 0; i++) {
- if (!isdigit(d[i])) {
- xfree(s);
- return FALSE;
- }
- }
- }
- for (i = 0; p[i] != 0; i++) {
- if (!isdigit(p[i])) {
- xfree(s);
- return FALSE;
- }
- }
- *bus = atoi(p);
- if (d != NULL && *d != 0)
- *bus += atoi(d) << 8;
- p = strtok(NULL, ":");
- if (p == NULL || *p == 0) {
- xfree(s);
- return FALSE;
- }
- for (i = 0; p[i] != 0; i++) {
- if (!isdigit(p[i])) {
- xfree(s);
- return FALSE;
- }
- }
- *device = atoi(p);
- *func = 0;
- p = strtok(NULL, ":");
- if (p == NULL || *p == 0) {
- xfree(s);
- return TRUE;
- }
- for (i = 0; p[i] != 0; i++) {
- if (!isdigit(p[i])) {
- xfree(s);
- return FALSE;
- }
- }
- *func = atoi(p);
- xfree(s);
- return TRUE;
-}
-
-/*
- * Compare a BUS ID string with a PCI bus id. Return TRUE if they match.
- */
-
-Bool
-xf86ComparePciBusString(const char *busID, int bus, int device, int func)
-{
- int ibus, idevice, ifunc;
-
- if (xf86ParsePciBusString(busID, &ibus, &idevice, &ifunc)) {
- return bus == ibus && device == idevice && func == ifunc;
- } else {
- return FALSE;
- }
-}
-
-/*
- * xf86IsPrimaryPci() -- return TRUE if primary device
- * is PCI and bus, dev and func numbers match.
- */
-
-Bool
-xf86IsPrimaryPci(struct pci_device *pPci)
-{
- return ((primaryBus.type == BUS_PCI) && (pPci == primaryBus.id.pci));
-}
-
-/*
- * xf86GetPciInfoForEntity() -- Get the pciVideoRec of entity.
- */
-struct pci_device *
-xf86GetPciInfoForEntity(int entityIndex)
-{
- EntityPtr p;
-
- if (entityIndex >= xf86NumEntities)
- return NULL;
-
- p = xf86Entities[entityIndex];
- return (p->bus.type == BUS_PCI) ? p->bus.id.pci : NULL;
-}
-
-/*
- * xf86CheckPciMemBase() checks that the memory base value matches one of the
- * PCI base address register values for the given PCI device.
- */
-Bool
-xf86CheckPciMemBase( struct pci_device * pPci, memType base )
-{
- int i;
-
- for (i = 0; i < 6; i++)
- if (base == pPci->regions[i].base_addr)
- return TRUE;
- return FALSE;
-}
-
-/*
- * Check if the slot requested is free. If it is already in use, return FALSE.
- */
-
-Bool
-xf86CheckPciSlot(const struct pci_device *d)
-{
- int i;
-
- for (i = 0; i < xf86NumEntities; i++) {
- const EntityPtr p = xf86Entities[i];
-
- if ((p->bus.type == BUS_PCI) && (p->bus.id.pci == d)) {
- return FALSE;
- }
- }
- return TRUE;
-}
-
-
+/*
+ * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+/*
+ * This file contains the interfaces to the bus-specific code
+ */
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <X11/X.h>
+#include <pciaccess.h>
+#include "os.h"
+#include "Pci.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+
+/* Bus-specific headers */
+#include "xf86Bus.h"
+
+#define XF86_OS_PRIVS
+#include "xf86_OSproc.h"
+
+
+/* Bus-specific globals */
+Bool pciSlotClaimed = FALSE;
+
+#define PCIINFOCLASSES(c) \
+ ( (((c) & 0x00ff0000) == (PCI_CLASS_PREHISTORIC << 16)) \
+ || (((c) & 0x00ff0000) == (PCI_CLASS_DISPLAY << 16)) \
+ || ((((c) & 0x00ffff00) \
+ == ((PCI_CLASS_MULTIMEDIA << 16) | (PCI_SUBCLASS_MULTIMEDIA_VIDEO << 8)))) \
+ || ((((c) & 0x00ffff00) \
+ == ((PCI_CLASS_PROCESSOR << 16) | (PCI_SUBCLASS_PROCESSOR_COPROC << 8)))) )
+
+/*
+ * PCI classes that have messages printed always. The others are only
+ * have a message printed when the vendor/dev IDs are recognised.
+ */
+#define PCIALWAYSPRINTCLASSES(c) \
+ ( (((c) & 0x00ffff00) \
+ == ((PCI_CLASS_PREHISTORIC << 16) | (PCI_SUBCLASS_PREHISTORIC_VGA << 8))) \
+ || (((c) & 0x00ff0000) == (PCI_CLASS_DISPLAY << 16)) \
+ || ((((c) & 0x00ffff00) \
+ == ((PCI_CLASS_MULTIMEDIA << 16) | (PCI_SUBCLASS_MULTIMEDIA_VIDEO << 8)))) )
+
+#define IS_VGA(c) \
+ (((c) & 0x00ffff00) \
+ == ((PCI_CLASS_DISPLAY << 16) | (PCI_SUBCLASS_DISPLAY_VGA << 8)))
+
+void
+xf86FormatPciBusNumber(int busnum, char *buffer)
+{
+ /* 'buffer' should be at least 8 characters long */
+ if (busnum < 256)
+ sprintf(buffer, "%d", busnum);
+ else
+ sprintf(buffer, "%d@%d", busnum & 0x00ff, busnum >> 8);
+}
+
+/*
+ * xf86Bus.c interface
+ */
+
+void
+xf86PciProbe(void)
+{
+ int i = 0, k;
+ int num = 0;
+ struct pci_device *info;
+ struct pci_device_iterator *iter;
+ struct pci_device ** xf86PciVideoInfo = NULL;
+
+
+ if (!xf86scanpci()) {
+ xf86PciVideoInfo = NULL;
+ return;
+ }
+
+ iter = pci_slot_match_iterator_create(& xf86IsolateDevice);
+ while ((info = pci_device_next(iter)) != NULL) {
+ if (PCIINFOCLASSES(info->device_class)) {
+ num++;
+ xf86PciVideoInfo = xnfrealloc(xf86PciVideoInfo,
+ (sizeof(struct pci_device *)
+ * (num + 1)));
+ xf86PciVideoInfo[num] = NULL;
+ xf86PciVideoInfo[num - 1] = info;
+
+ pci_device_probe(info);
+#ifdef HAVE_PCI_DEVICE_IS_BOOT_VGA
+ if (pci_device_is_boot_vga(info)) {
+ primaryBus.type = BUS_PCI;
+ primaryBus.id.pci = info;
+ }
+#endif
+ info->user_data = 0;
+ }
+ }
+ free(iter);
+
+ /* If we haven't found a primary device try a different heuristic */
+ if (primaryBus.type == BUS_NONE && num) {
+ for (i = 0; i < num; i++) {
+ uint16_t command;
+
+ info = xf86PciVideoInfo[i];
+ pci_device_cfg_read_u16(info, & command, 4);
+
+ if ((command & PCI_CMD_MEM_ENABLE)
+ && ((num == 1) || IS_VGA(info->device_class))) {
+ if (primaryBus.type == BUS_NONE) {
+ primaryBus.type = BUS_PCI;
+ primaryBus.id.pci = info;
+ } else {
+ xf86Msg(X_NOTICE,
+ "More than one possible primary device found\n");
+ primaryBus.type ^= (BusType)(-1);
+ }
+ }
+ }
+ }
+
+ /* Print a summary of the video devices found */
+ for (k = 0; k < num; k++) {
+ const char *vendorname = NULL, *chipname = NULL;
+ const char *prim = " ";
+ Bool memdone = FALSE, iodone = FALSE;
+
+
+ info = xf86PciVideoInfo[k];
+
+ vendorname = pci_device_get_vendor_name( info );
+ chipname = pci_device_get_device_name( info );
+
+ if ((!vendorname || !chipname) &&
+ !PCIALWAYSPRINTCLASSES(info->device_class))
+ continue;
+
+ if (xf86IsPrimaryPci(info))
+ prim = "*";
+
+ xf86Msg(X_PROBED, "PCI:%s(%u:%u:%u:%u) %04x:%04x:%04x:%04x ", prim,
+ info->domain, info->bus, info->dev, info->func,
+ info->vendor_id, info->device_id,
+ info->subvendor_id, info->subdevice_id);
+
+ if (vendorname)
+ xf86ErrorF("%s ", vendorname);
+
+ if (chipname)
+ xf86ErrorF("%s ", chipname);
+
+ xf86ErrorF("rev %d", info->revision);
+
+ for (i = 0; i < 6; i++) {
+ struct pci_mem_region * r = & info->regions[i];
+
+ if ( r->size && ! r->is_IO ) {
+ if (!memdone) {
+ xf86ErrorF(", Mem @ ");
+ memdone = TRUE;
+ } else
+ xf86ErrorF(", ");
+ xf86ErrorF("0x%08lx/%ld", (long)r->base_addr, (long)r->size);
+ }
+ }
+
+ for (i = 0; i < 6; i++) {
+ struct pci_mem_region * r = & info->regions[i];
+
+ if ( r->size && r->is_IO ) {
+ if (!iodone) {
+ xf86ErrorF(", I/O @ ");
+ iodone = TRUE;
+ } else
+ xf86ErrorF(", ");
+ xf86ErrorF("0x%08lx/%ld", (long)r->base_addr, (long)r->size);
+ }
+ }
+
+ if ( info->rom_size ) {
+ xf86ErrorF(", BIOS @ 0x\?\?\?\?\?\?\?\?/%ld", (long)info->rom_size);
+ }
+
+ xf86ErrorF("\n");
+ }
+ free(xf86PciVideoInfo);
+}
+
+/*
+ * If the slot requested is already in use, return -1.
+ * Otherwise, claim the slot for the screen requesting it.
+ */
+
+int
+xf86ClaimPciSlot(struct pci_device * d, DriverPtr drvp,
+ int chipset, GDevPtr dev, Bool active)
+{
+ EntityPtr p = NULL;
+ int num;
+
+ if (xf86CheckPciSlot(d)) {
+ num = xf86AllocateEntity();
+ p = xf86Entities[num];
+ p->driver = drvp;
+ p->chipset = chipset;
+ p->bus.type = BUS_PCI;
+ p->bus.id.pci = d;
+ p->active = active;
+ p->inUse = FALSE;
+ if (dev)
+ xf86AddDevToEntity(num, dev);
+ pciSlotClaimed = TRUE;
+
+ if (active) {
+ /* Map in this domain's I/O space */
+ p->domainIO = xf86MapLegacyIO(d);
+ }
+
+ return num;
+ } else
+ return -1;
+}
+
+/*
+ * Unclaim PCI slot, e.g. if probing failed, so that a different driver can claim.
+ */
+void
+xf86UnclaimPciSlot(struct pci_device *d)
+{
+ int i;
+
+ for (i = 0; i < xf86NumEntities; i++) {
+ const EntityPtr p = xf86Entities[i];
+
+ if ((p->bus.type == BUS_PCI) && (p->bus.id.pci == d)) {
+ /* Probably the slot should be deallocated? */
+ p->bus.type = BUS_NONE;
+ return;
+ }
+ }
+}
+
+/*
+ * Parse a BUS ID string, and return the PCI bus parameters if it was
+ * in the correct format for a PCI bus id.
+ */
+
+Bool
+xf86ParsePciBusString(const char *busID, int *bus, int *device, int *func)
+{
+ /*
+ * The format is assumed to be "bus[@domain]:device[:func]", where domain,
+ * bus, device and func are decimal integers. domain and func may be
+ * omitted and assumed to be zero, although doing this isn't encouraged.
+ */
+
+ char *p, *s, *d;
+ const char *id;
+ int i;
+
+ if (StringToBusType(busID, &id) != BUS_PCI)
+ return FALSE;
+
+ s = xstrdup(id);
+ p = strtok(s, ":");
+ if (p == NULL || *p == 0) {
+ free(s);
+ return FALSE;
+ }
+ d = strpbrk(p, "@");
+ if (d != NULL) {
+ *(d++) = 0;
+ for (i = 0; d[i] != 0; i++) {
+ if (!isdigit(d[i])) {
+ free(s);
+ return FALSE;
+ }
+ }
+ }
+ for (i = 0; p[i] != 0; i++) {
+ if (!isdigit(p[i])) {
+ free(s);
+ return FALSE;
+ }
+ }
+ *bus = atoi(p);
+ if (d != NULL && *d != 0)
+ *bus += atoi(d) << 8;
+ p = strtok(NULL, ":");
+ if (p == NULL || *p == 0) {
+ free(s);
+ return FALSE;
+ }
+ for (i = 0; p[i] != 0; i++) {
+ if (!isdigit(p[i])) {
+ free(s);
+ return FALSE;
+ }
+ }
+ *device = atoi(p);
+ *func = 0;
+ p = strtok(NULL, ":");
+ if (p == NULL || *p == 0) {
+ free(s);
+ return TRUE;
+ }
+ for (i = 0; p[i] != 0; i++) {
+ if (!isdigit(p[i])) {
+ free(s);
+ return FALSE;
+ }
+ }
+ *func = atoi(p);
+ free(s);
+ return TRUE;
+}
+
+/*
+ * Compare a BUS ID string with a PCI bus id. Return TRUE if they match.
+ */
+
+Bool
+xf86ComparePciBusString(const char *busID, int bus, int device, int func)
+{
+ int ibus, idevice, ifunc;
+
+ if (xf86ParsePciBusString(busID, &ibus, &idevice, &ifunc)) {
+ return bus == ibus && device == idevice && func == ifunc;
+ } else {
+ return FALSE;
+ }
+}
+
+/*
+ * xf86IsPrimaryPci() -- return TRUE if primary device
+ * is PCI and bus, dev and func numbers match.
+ */
+
+Bool
+xf86IsPrimaryPci(struct pci_device *pPci)
+{
+ return ((primaryBus.type == BUS_PCI) && (pPci == primaryBus.id.pci));
+}
+
+/*
+ * xf86GetPciInfoForEntity() -- Get the pciVideoRec of entity.
+ */
+struct pci_device *
+xf86GetPciInfoForEntity(int entityIndex)
+{
+ EntityPtr p;
+
+ if (entityIndex >= xf86NumEntities)
+ return NULL;
+
+ p = xf86Entities[entityIndex];
+ return (p->bus.type == BUS_PCI) ? p->bus.id.pci : NULL;
+}
+
+/*
+ * xf86CheckPciMemBase() checks that the memory base value matches one of the
+ * PCI base address register values for the given PCI device.
+ */
+Bool
+xf86CheckPciMemBase( struct pci_device * pPci, memType base )
+{
+ int i;
+
+ for (i = 0; i < 6; i++)
+ if (base == pPci->regions[i].base_addr)
+ return TRUE;
+ return FALSE;
+}
+
+/*
+ * Check if the slot requested is free. If it is already in use, return FALSE.
+ */
+
+Bool
+xf86CheckPciSlot(const struct pci_device *d)
+{
+ int i;
+
+ for (i = 0; i < xf86NumEntities; i++) {
+ const EntityPtr p = xf86Entities[i];
+
+ if ((p->bus.type == BUS_PCI) && (p->bus.id.pci == d)) {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+
diff --git a/xorg-server/hw/xfree86/common/xf86sbusBus.c b/xorg-server/hw/xfree86/common/xf86sbusBus.c
index 7b23233aa..8df3a6c7a 100644
--- a/xorg-server/hw/xfree86/common/xf86sbusBus.c
+++ b/xorg-server/hw/xfree86/common/xf86sbusBus.c
@@ -1,688 +1,688 @@
-/*
- * SBUS bus-specific code.
- *
- * Copyright (C) 2000 Jakub Jelinek (jakub@redhat.com)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * JAKUB JELINEK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <ctype.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <X11/X.h>
-#include "os.h"
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86_OSlib.h"
-#include "xf86cmap.h"
-
-#include "xf86Bus.h"
-
-#include "xf86sbusBus.h"
-#include "xf86Sbus.h"
-
-Bool sbusSlotClaimed = FALSE;
-
-static int xf86nSbusInfo;
-
-static void
-CheckSbusDevice(const char *device, int fbNum)
-{
- int fd, i;
- struct fbgattr fbattr;
- sbusDevicePtr psdp;
-
- fd = open(device, O_RDONLY, 0);
- if (fd < 0)
- return;
- memset(&fbattr, 0, sizeof(fbattr));
- if (ioctl(fd, FBIOGATTR, &fbattr) < 0) {
- if (ioctl(fd, FBIOGTYPE, &fbattr.fbtype) < 0) {
- close(fd);
- return;
- }
- }
- close(fd);
- for (i = 0; sbusDeviceTable[i].devId; i++)
- if (sbusDeviceTable[i].fbType == fbattr.fbtype.fb_type)
- break;
- if (! sbusDeviceTable[i].devId)
- return;
- xf86SbusInfo = xnfrealloc(xf86SbusInfo, sizeof(psdp) * (++xf86nSbusInfo + 1));
- xf86SbusInfo[xf86nSbusInfo] = NULL;
- xf86SbusInfo[xf86nSbusInfo - 1] = psdp = xnfcalloc(sizeof (sbusDevice), 1);
- psdp->devId = sbusDeviceTable[i].devId;
- psdp->fbNum = fbNum;
- psdp->device = xnfstrdup(device);
- psdp->width = fbattr.fbtype.fb_width;
- psdp->height = fbattr.fbtype.fb_height;
- psdp->fd = -1;
-}
-
-void
-xf86SbusProbe(void)
-{
- int i, useProm = 0;
- char fbDevName[32];
- sbusDevicePtr psdp, *psdpp;
-
- xf86SbusInfo = xalloc(sizeof(psdp));
- *xf86SbusInfo = NULL;
- for (i = 0; i < 32; i++) {
- sprintf(fbDevName, "/dev/fb%d", i);
- CheckSbusDevice(fbDevName, i);
- }
- if (sparcPromInit() >= 0) {
- useProm = 1;
- sparcPromAssignNodes();
- }
- for (psdpp = xf86SbusInfo; (psdp = *psdpp); psdpp++) {
- for (i = 0; sbusDeviceTable[i].devId; i++)
- if (sbusDeviceTable[i].devId == psdp->devId)
- psdp->descr = sbusDeviceTable[i].descr;
- /*
- * If we can use PROM information and found the PROM node for this
- * device, we can tell more about the card.
- */
- if (useProm && psdp->node.node) {
- char *prop, *promPath;
- int len, chiprev, vmsize;
-
- switch (psdp->devId) {
- case SBUS_DEVICE_MGX:
- prop = sparcPromGetProperty(&psdp->node, "fb_size", &len);
- if (prop && len == 4 && *(int *)prop == 0x400000)
- psdp->descr = "Quantum 3D MGXplus with 4M VRAM";
- break;
- case SBUS_DEVICE_CG6:
- chiprev = 0;
- vmsize = 0;
- prop = sparcPromGetProperty(&psdp->node, "chiprev", &len);
- if (prop && len == 4)
- chiprev = *(int *)prop;
- prop = sparcPromGetProperty(&psdp->node, "vmsize", &len);
- if (prop && len == 4)
- vmsize = *(int *)prop;
- switch (chiprev) {
- case 1:
- case 2:
- case 3:
- case 4:
- psdp->descr = "Sun Double width GX"; break;
- case 5:
- case 6:
- case 7:
- case 8:
- case 9:
- psdp->descr = "Sun Single width GX"; break;
- case 11:
- switch (vmsize) {
- case 2:
- psdp->descr = "Sun Turbo GX with 1M VSIMM"; break;
- case 4:
- psdp->descr = "Sun Turbo GX Plus"; break;
- default:
- psdp->descr = "Sun Turbo GX"; break;
- }
- }
- break;
- case SBUS_DEVICE_CG14:
- prop = sparcPromGetProperty(&psdp->node, "reg", &len);
- vmsize = 0;
- if (prop && !(len % 12) && len > 0)
- vmsize = *(int *)(prop + len - 4);
- switch (vmsize) {
- case 0x400000:
- psdp->descr = "Sun SX with 4M VSIMM"; break;
- case 0x800000:
- psdp->descr = "Sun SX with 8M VSIMM"; break;
- }
- break;
- case SBUS_DEVICE_LEO:
- prop = sparcPromGetProperty(&psdp->node, "model", &len);
- if (prop && len > 0 && !strstr(prop, "501-2503"))
- psdp->descr = "Sun Turbo ZX";
- break;
- case SBUS_DEVICE_TCX:
- if (sparcPromGetBool(&psdp->node, "tcx-8-bit"))
- psdp->descr = "Sun TCX (8bit)";
- else
- psdp->descr = "Sun TCX (S24)";
- break;
- case SBUS_DEVICE_FFB:
- prop = sparcPromGetProperty(&psdp->node, "name", &len);
- chiprev = 0;
- prop = sparcPromGetProperty(&psdp->node, "board_type", &len);
- if (prop && len == 4)
- chiprev = *(int *)prop;
- if (strstr (prop, "afb")) {
- if (chiprev == 3)
- psdp->descr = "Sun|Elite3D-M6 Horizontal";
- } else {
- switch (chiprev) {
- case 0x08:
- psdp->descr = "Sun FFB 67MHz Creator"; break;
- case 0x0b:
- psdp->descr = "Sun FFB 67MHz Creator 3D"; break;
- case 0x1b:
- psdp->descr = "Sun FFB 75MHz Creator 3D"; break;
- case 0x20:
- case 0x28:
- psdp->descr = "Sun FFB2 Vertical Creator"; break;
- case 0x23:
- case 0x2b:
- psdp->descr = "Sun FFB2 Vertical Creator 3D"; break;
- case 0x30:
- psdp->descr = "Sun FFB2+ Vertical Creator"; break;
- case 0x33:
- psdp->descr = "Sun FFB2+ Vertical Creator 3D"; break;
- case 0x40:
- case 0x48:
- psdp->descr = "Sun FFB2 Horizontal Creator"; break;
- case 0x43:
- case 0x4b:
- psdp->descr = "Sun FFB2 Horizontal Creator 3D"; break;
- }
- }
- break;
- }
-
- xf86Msg(X_PROBED, "SBUS:(0x%08x) %s", psdp->node.node, psdp->descr);
- promPath = sparcPromNode2Pathname (&psdp->node);
- if (promPath) {
- xf86ErrorF(" at %s", promPath);
- xfree(promPath);
- }
- } else
- xf86Msg(X_PROBED, "SBUS: %s", psdp->descr);
- xf86ErrorF("\n");
- }
- if (useProm)
- sparcPromClose();
-}
-
-/*
- * Parse a BUS ID string, and return the SBUS bus parameters if it was
- * in the correct format for a SBUS bus id.
- */
-
-Bool
-xf86ParseSbusBusString(const char *busID, int *fbNum)
-{
- /*
- * The format is assumed to be one of:
- * "fbN", e.g. "fb1", which means the device corresponding to /dev/fbN
- * "nameN", e.g. "cgsix0", which means Nth instance of card NAME
- * "/prompath", e.g. "/sbus@0,10001000/cgsix@3,0" which is PROM pathname
- * to the device.
- */
-
- const char *id;
- int i, len;
-
- if (StringToBusType(busID, &id) != BUS_SBUS)
- return FALSE;
-
- if (*id != '/') {
- if (!strncmp (id, "fb", 2)) {
- if (!isdigit(id[2]))
- return FALSE;
- *fbNum = atoi(id + 2);
- return TRUE;
- } else {
- sbusDevicePtr *psdpp;
- int devId;
-
- for (i = 0, len = 0; sbusDeviceTable[i].devId; i++) {
- len = strlen(sbusDeviceTable[i].promName);
- if (!strncmp (sbusDeviceTable[i].promName, id, len)
- && isdigit(id[len]))
- break;
- }
- devId = sbusDeviceTable[i].devId;
- if (!devId) return FALSE;
- i = atoi(id + len);
- for (psdpp = xf86SbusInfo; *psdpp; ++psdpp) {
- if ((*psdpp)->devId != devId)
- continue;
- if (!i) {
- *fbNum = (*psdpp)->fbNum;
- return TRUE;
- }
- i--;
- }
- }
- return FALSE;
- }
-
- if (sparcPromInit() >= 0) {
- i = sparcPromPathname2Node(id);
- sparcPromClose();
- if (i) {
- sbusDevicePtr *psdpp;
- for (psdpp = xf86SbusInfo; *psdpp; ++psdpp) {
- if ((*psdpp)->node.node == i) {
- *fbNum = (*psdpp)->fbNum;
- return TRUE;
- }
- }
- }
- }
- return FALSE;
-}
-
-/*
- * Compare a BUS ID string with a SBUS bus id. Return TRUE if they match.
- */
-
-Bool
-xf86CompareSbusBusString(const char *busID, int fbNum)
-{
- int iFbNum;
-
- if (xf86ParseSbusBusString(busID, &iFbNum)) {
- return fbNum == iFbNum;
- } else {
- return FALSE;
- }
-}
-
-/*
- * Check if the slot requested is free. If it is already in use, return FALSE.
- */
-
-Bool
-xf86CheckSbusSlot(int fbNum)
-{
- int i;
- EntityPtr p;
-
- for (i = 0; i < xf86NumEntities; i++) {
- p = xf86Entities[i];
- /* Check if this SBUS slot is taken */
- if (p->bus.type == BUS_SBUS && p->bus.id.sbus.fbNum == fbNum)
- return FALSE;
- }
-
- return TRUE;
-}
-
-/*
- * If the slot requested is already in use, return -1.
- * Otherwise, claim the slot for the screen requesting it.
- */
-
-int
-xf86ClaimSbusSlot(sbusDevicePtr psdp, DriverPtr drvp,
- GDevPtr dev, Bool active)
-{
- EntityPtr p = NULL;
-
- int num;
-
- if (xf86CheckSbusSlot(psdp->fbNum)) {
- num = xf86AllocateEntity();
- p = xf86Entities[num];
- p->driver = drvp;
- p->chipset = -1;
- p->bus.type = BUS_SBUS;
- xf86AddDevToEntity(num, dev);
- p->bus.id.sbus.fbNum = psdp->fbNum;
- p->active = active;
- p->inUse = FALSE;
- sbusSlotClaimed = TRUE;
- return num;
- } else
- return -1;
-}
-
-int
-xf86MatchSbusInstances(const char *driverName, int sbusDevId,
- GDevPtr *devList, int numDevs, DriverPtr drvp,
- int **foundEntities)
-{
- int i,j;
- sbusDevicePtr psdp, *psdpp;
- int numClaimedInstances = 0;
- int allocatedInstances = 0;
- int numFound = 0;
- GDevPtr devBus = NULL;
- GDevPtr dev = NULL;
- int *retEntities = NULL;
- int useProm = 0;
-
- struct Inst {
- sbusDevicePtr sbus;
- GDevPtr dev;
- Bool claimed; /* BusID matches with a device section */
- } *instances = NULL;
-
- *foundEntities = NULL;
- for (psdpp = xf86SbusInfo, psdp = *psdpp; psdp; psdp = *++psdpp) {
- if (psdp->devId != sbusDevId)
- continue;
- if (psdp->fd == -2)
- continue;
- ++allocatedInstances;
- instances = xnfrealloc(instances,
- allocatedInstances * sizeof(struct Inst));
- instances[allocatedInstances - 1].sbus = psdp;
- instances[allocatedInstances - 1].dev = NULL;
- instances[allocatedInstances - 1].claimed = FALSE;
- numFound++;
- }
-
- /*
- * This may be debatable, but if no SBUS devices with a matching vendor
- * type is found, return zero now. It is probably not desirable to
- * allow the config file to override this.
- */
- if (allocatedInstances <= 0) {
- xfree(instances);
- return 0;
- }
-
- if (sparcPromInit() >= 0)
- useProm = 1;
-
- if (xf86DoConfigure && xf86DoConfigurePass1) {
- GDevPtr pGDev;
- int actualcards = 0;
- for (i = 0; i < allocatedInstances; i++) {
- actualcards++;
- pGDev = xf86AddBusDeviceToConfigure(drvp->driverName, BUS_SBUS,
- instances[i].sbus, -1);
- if (pGDev) {
- /*
- * XF86Match???Instances() treat chipID and chipRev as
- * overrides, so clobber them here.
- */
- pGDev->chipID = pGDev->chipRev = -1;
- }
- }
- xfree(instances);
- if (useProm)
- sparcPromClose();
- return actualcards;
- }
-
- DebugF("%s instances found: %d\n", driverName, allocatedInstances);
-
- for (i = 0; i < allocatedInstances; i++) {
- char *promPath = NULL;
-
- psdp = instances[i].sbus;
- devBus = NULL;
- dev = NULL;
- if (useProm && psdp->node.node)
- promPath = sparcPromNode2Pathname(&psdp->node);
-
- for (j = 0; j < numDevs; j++) {
- if (devList[j]->busID && *devList[j]->busID) {
- if (xf86CompareSbusBusString(devList[j]->busID, psdp->fbNum)) {
- if (devBus)
- xf86MsgVerb(X_WARNING,0,
- "%s: More than one matching Device section for "
- "instance (BusID: %s) found: %s\n",
- driverName,devList[j]->identifier,
- devList[j]->busID);
- else
- devBus = devList[j];
- }
- } else {
- if (!dev && !devBus) {
- if (promPath)
- xf86Msg(X_PROBED, "Assigning device section with no busID to SBUS:%s\n",
- promPath);
- else
- xf86Msg(X_PROBED, "Assigning device section with no busID to SBUS:fb%d\n",
- psdp->fbNum);
- dev = devList[j];
- } else
- xf86MsgVerb(X_WARNING, 0,
- "%s: More than one matching Device section "
- "found: %s\n", driverName, devList[j]->identifier);
- }
- }
- if (devBus) dev = devBus; /* busID preferred */
- if (!dev && psdp->fd != -2) {
- if (promPath) {
- xf86MsgVerb(X_WARNING, 0, "%s: No matching Device section "
- "for instance (BusID SBUS:%s) found\n",
- driverName, promPath);
- } else
- xf86MsgVerb(X_WARNING, 0, "%s: No matching Device section "
- "for instance (BusID SBUS:fb%d) found\n",
- driverName, psdp->fbNum);
- } else if (dev) {
- numClaimedInstances++;
- instances[i].claimed = TRUE;
- instances[i].dev = dev;
- }
- if (promPath)
- xfree(promPath);
- }
-
- DebugF("%s instances found: %d\n", driverName, numClaimedInstances);
-
- /*
- * Of the claimed instances, check that another driver hasn't already
- * claimed its slot.
- */
- numFound = 0;
- for (i = 0; i < allocatedInstances && numClaimedInstances > 0; i++) {
- if (!instances[i].claimed)
- continue;
- psdp = instances[i].sbus;
- if (!xf86CheckSbusSlot(psdp->fbNum))
- continue;
-
- DebugF("%s: card at fb%d %08x is claimed by a Device section\n",
- driverName, psdp->fbNum, psdp->node.node);
-
- /* Allocate an entry in the lists to be returned */
- numFound++;
- retEntities = xnfrealloc(retEntities, numFound * sizeof(int));
- retEntities[numFound - 1]
- = xf86ClaimSbusSlot(psdp, drvp, instances[i].dev,instances[i].dev->active ?
- TRUE : FALSE);
- }
- xfree(instances);
- if (numFound > 0) {
- *foundEntities = retEntities;
- }
-
- if (useProm)
- sparcPromClose();
-
- return numFound;
-}
-
-/*
- * xf86GetSbusInfoForEntity() -- Get the sbusDevicePtr of entity.
- */
-sbusDevicePtr
-xf86GetSbusInfoForEntity(int entityIndex)
-{
- sbusDevicePtr *psdpp;
- EntityPtr p = xf86Entities[entityIndex];
-
- if (entityIndex >= xf86NumEntities
- || p->bus.type != BUS_SBUS) return NULL;
-
- for (psdpp = xf86SbusInfo; *psdpp != NULL; psdpp++) {
- if (p->bus.id.sbus.fbNum == (*psdpp)->fbNum)
- return (*psdpp);
- }
- return NULL;
-}
-
-int
-xf86GetEntityForSbusInfo(sbusDevicePtr psdp)
-{
- int i;
-
- for (i = 0; i < xf86NumEntities; i++) {
- EntityPtr p = xf86Entities[i];
- if (p->bus.type != BUS_SBUS) continue;
-
- if (p->bus.id.sbus.fbNum == psdp->fbNum)
- return i;
- }
- return -1;
-}
-
-void
-xf86SbusUseBuiltinMode(ScrnInfoPtr pScrn, sbusDevicePtr psdp)
-{
- DisplayModePtr mode;
-
- mode = xnfcalloc(sizeof(DisplayModeRec), 1);
- mode->name = "current";
- mode->next = mode;
- mode->prev = mode;
- mode->type = M_T_BUILTIN;
- mode->Clock = 100000000;
- mode->HDisplay = psdp->width;
- mode->HSyncStart = psdp->width;
- mode->HSyncEnd = psdp->width;
- mode->HTotal = psdp->width;
- mode->VDisplay = psdp->height;
- mode->VSyncStart = psdp->height;
- mode->VSyncEnd = psdp->height;
- mode->VTotal = psdp->height;
- mode->SynthClock = mode->Clock;
- mode->CrtcHDisplay = mode->HDisplay;
- mode->CrtcHSyncStart = mode->HSyncStart;
- mode->CrtcHSyncEnd = mode->HSyncEnd;
- mode->CrtcHTotal = mode->HTotal;
- mode->CrtcVDisplay = mode->VDisplay;
- mode->CrtcVSyncStart = mode->VSyncStart;
- mode->CrtcVSyncEnd = mode->VSyncEnd;
- mode->CrtcVTotal = mode->VTotal;
- mode->CrtcHAdjusted = FALSE;
- mode->CrtcVAdjusted = FALSE;
- pScrn->modes = mode;
- pScrn->virtualX = psdp->width;
- pScrn->virtualY = psdp->height;
-}
-
-static sbusPaletteKeyIndex;
-static DevPrivateKey sbusPaletteKey = &sbusPaletteKeyIndex;
-typedef struct _sbusCmap {
- sbusDevicePtr psdp;
- CloseScreenProcPtr CloseScreen;
- Bool origCmapValid;
- unsigned char origRed[16];
- unsigned char origGreen[16];
- unsigned char origBlue[16];
-} sbusCmapRec, *sbusCmapPtr;
-
-#define SBUSCMAPPTR(pScreen) ((sbusCmapPtr) \
- dixLookupPrivate(&(pScreen)->devPrivates, sbusPaletteKey))
-
-static void
-xf86SbusCmapLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
- LOCO *colors, VisualPtr pVisual)
-{
- int i, index;
- sbusCmapPtr cmap;
- struct fbcmap fbcmap;
- unsigned char *data = xalloc(numColors*3);
-
- cmap = SBUSCMAPPTR(pScrn->pScreen);
- if (!cmap) return;
- fbcmap.count = 0;
- fbcmap.index = indices[0];
- fbcmap.red = data;
- fbcmap.green = data + numColors;
- fbcmap.blue = fbcmap.green + numColors;
- for (i = 0; i < numColors; i++) {
- index = indices[i];
- if (fbcmap.count && index != fbcmap.index + fbcmap.count) {
- ioctl (cmap->psdp->fd, FBIOPUTCMAP, &fbcmap);
- fbcmap.count = 0;
- fbcmap.index = index;
- }
- fbcmap.red[fbcmap.count] = colors[index].red;
- fbcmap.green[fbcmap.count] = colors[index].green;
- fbcmap.blue[fbcmap.count++] = colors[index].blue;
- }
- ioctl (cmap->psdp->fd, FBIOPUTCMAP, &fbcmap);
- xfree(data);
-}
-
-static Bool
-xf86SbusCmapCloseScreen(int i, ScreenPtr pScreen)
-{
- sbusCmapPtr cmap;
- struct fbcmap fbcmap;
-
- cmap = SBUSCMAPPTR(pScreen);
- if (cmap->origCmapValid) {
- fbcmap.index = 0;
- fbcmap.count = 16;
- fbcmap.red = cmap->origRed;
- fbcmap.green = cmap->origGreen;
- fbcmap.blue = cmap->origBlue;
- ioctl (cmap->psdp->fd, FBIOPUTCMAP, &fbcmap);
- }
- pScreen->CloseScreen = cmap->CloseScreen;
- xfree (cmap);
- return (*pScreen->CloseScreen) (i, pScreen);
-}
-
-Bool
-xf86SbusHandleColormaps(ScreenPtr pScreen, sbusDevicePtr psdp)
-{
- sbusCmapPtr cmap;
- struct fbcmap fbcmap;
- unsigned char data[2];
-
- cmap = xnfcalloc(1, sizeof(sbusCmapRec));
- dixSetPrivate(&pScreen->devPrivates, sbusPaletteKey, cmap);
- cmap->psdp = psdp;
- fbcmap.index = 0;
- fbcmap.count = 16;
- fbcmap.red = cmap->origRed;
- fbcmap.green = cmap->origGreen;
- fbcmap.blue = cmap->origBlue;
- if (ioctl (psdp->fd, FBIOGETCMAP, &fbcmap) >= 0)
- cmap->origCmapValid = TRUE;
- fbcmap.index = 0;
- fbcmap.count = 2;
- fbcmap.red = data;
- fbcmap.green = data;
- fbcmap.blue = data;
- if (pScreen->whitePixel == 0) {
- data[0] = 255;
- data[1] = 0;
- } else {
- data[0] = 0;
- data[1] = 255;
- }
- ioctl (psdp->fd, FBIOPUTCMAP, &fbcmap);
- cmap->CloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = xf86SbusCmapCloseScreen;
- return xf86HandleColormaps(pScreen, 256, 8,
- xf86SbusCmapLoadPalette, NULL, 0);
-}
+/*
+ * SBUS bus-specific code.
+ *
+ * Copyright (C) 2000 Jakub Jelinek (jakub@redhat.com)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * JAKUB JELINEK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <ctype.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <X11/X.h>
+#include "os.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "xf86cmap.h"
+
+#include "xf86Bus.h"
+
+#include "xf86sbusBus.h"
+#include "xf86Sbus.h"
+
+Bool sbusSlotClaimed = FALSE;
+
+static int xf86nSbusInfo;
+
+static void
+CheckSbusDevice(const char *device, int fbNum)
+{
+ int fd, i;
+ struct fbgattr fbattr;
+ sbusDevicePtr psdp;
+
+ fd = open(device, O_RDONLY, 0);
+ if (fd < 0)
+ return;
+ memset(&fbattr, 0, sizeof(fbattr));
+ if (ioctl(fd, FBIOGATTR, &fbattr) < 0) {
+ if (ioctl(fd, FBIOGTYPE, &fbattr.fbtype) < 0) {
+ close(fd);
+ return;
+ }
+ }
+ close(fd);
+ for (i = 0; sbusDeviceTable[i].devId; i++)
+ if (sbusDeviceTable[i].fbType == fbattr.fbtype.fb_type)
+ break;
+ if (! sbusDeviceTable[i].devId)
+ return;
+ xf86SbusInfo = xnfrealloc(xf86SbusInfo, sizeof(psdp) * (++xf86nSbusInfo + 1));
+ xf86SbusInfo[xf86nSbusInfo] = NULL;
+ xf86SbusInfo[xf86nSbusInfo - 1] = psdp = xnfcalloc(sizeof (sbusDevice), 1);
+ psdp->devId = sbusDeviceTable[i].devId;
+ psdp->fbNum = fbNum;
+ psdp->device = xnfstrdup(device);
+ psdp->width = fbattr.fbtype.fb_width;
+ psdp->height = fbattr.fbtype.fb_height;
+ psdp->fd = -1;
+}
+
+void
+xf86SbusProbe(void)
+{
+ int i, useProm = 0;
+ char fbDevName[32];
+ sbusDevicePtr psdp, *psdpp;
+
+ xf86SbusInfo = malloc(sizeof(psdp));
+ *xf86SbusInfo = NULL;
+ for (i = 0; i < 32; i++) {
+ sprintf(fbDevName, "/dev/fb%d", i);
+ CheckSbusDevice(fbDevName, i);
+ }
+ if (sparcPromInit() >= 0) {
+ useProm = 1;
+ sparcPromAssignNodes();
+ }
+ for (psdpp = xf86SbusInfo; (psdp = *psdpp); psdpp++) {
+ for (i = 0; sbusDeviceTable[i].devId; i++)
+ if (sbusDeviceTable[i].devId == psdp->devId)
+ psdp->descr = sbusDeviceTable[i].descr;
+ /*
+ * If we can use PROM information and found the PROM node for this
+ * device, we can tell more about the card.
+ */
+ if (useProm && psdp->node.node) {
+ char *prop, *promPath;
+ int len, chiprev, vmsize;
+
+ switch (psdp->devId) {
+ case SBUS_DEVICE_MGX:
+ prop = sparcPromGetProperty(&psdp->node, "fb_size", &len);
+ if (prop && len == 4 && *(int *)prop == 0x400000)
+ psdp->descr = "Quantum 3D MGXplus with 4M VRAM";
+ break;
+ case SBUS_DEVICE_CG6:
+ chiprev = 0;
+ vmsize = 0;
+ prop = sparcPromGetProperty(&psdp->node, "chiprev", &len);
+ if (prop && len == 4)
+ chiprev = *(int *)prop;
+ prop = sparcPromGetProperty(&psdp->node, "vmsize", &len);
+ if (prop && len == 4)
+ vmsize = *(int *)prop;
+ switch (chiprev) {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ psdp->descr = "Sun Double width GX"; break;
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 9:
+ psdp->descr = "Sun Single width GX"; break;
+ case 11:
+ switch (vmsize) {
+ case 2:
+ psdp->descr = "Sun Turbo GX with 1M VSIMM"; break;
+ case 4:
+ psdp->descr = "Sun Turbo GX Plus"; break;
+ default:
+ psdp->descr = "Sun Turbo GX"; break;
+ }
+ }
+ break;
+ case SBUS_DEVICE_CG14:
+ prop = sparcPromGetProperty(&psdp->node, "reg", &len);
+ vmsize = 0;
+ if (prop && !(len % 12) && len > 0)
+ vmsize = *(int *)(prop + len - 4);
+ switch (vmsize) {
+ case 0x400000:
+ psdp->descr = "Sun SX with 4M VSIMM"; break;
+ case 0x800000:
+ psdp->descr = "Sun SX with 8M VSIMM"; break;
+ }
+ break;
+ case SBUS_DEVICE_LEO:
+ prop = sparcPromGetProperty(&psdp->node, "model", &len);
+ if (prop && len > 0 && !strstr(prop, "501-2503"))
+ psdp->descr = "Sun Turbo ZX";
+ break;
+ case SBUS_DEVICE_TCX:
+ if (sparcPromGetBool(&psdp->node, "tcx-8-bit"))
+ psdp->descr = "Sun TCX (8bit)";
+ else
+ psdp->descr = "Sun TCX (S24)";
+ break;
+ case SBUS_DEVICE_FFB:
+ prop = sparcPromGetProperty(&psdp->node, "name", &len);
+ chiprev = 0;
+ prop = sparcPromGetProperty(&psdp->node, "board_type", &len);
+ if (prop && len == 4)
+ chiprev = *(int *)prop;
+ if (strstr (prop, "afb")) {
+ if (chiprev == 3)
+ psdp->descr = "Sun|Elite3D-M6 Horizontal";
+ } else {
+ switch (chiprev) {
+ case 0x08:
+ psdp->descr = "Sun FFB 67MHz Creator"; break;
+ case 0x0b:
+ psdp->descr = "Sun FFB 67MHz Creator 3D"; break;
+ case 0x1b:
+ psdp->descr = "Sun FFB 75MHz Creator 3D"; break;
+ case 0x20:
+ case 0x28:
+ psdp->descr = "Sun FFB2 Vertical Creator"; break;
+ case 0x23:
+ case 0x2b:
+ psdp->descr = "Sun FFB2 Vertical Creator 3D"; break;
+ case 0x30:
+ psdp->descr = "Sun FFB2+ Vertical Creator"; break;
+ case 0x33:
+ psdp->descr = "Sun FFB2+ Vertical Creator 3D"; break;
+ case 0x40:
+ case 0x48:
+ psdp->descr = "Sun FFB2 Horizontal Creator"; break;
+ case 0x43:
+ case 0x4b:
+ psdp->descr = "Sun FFB2 Horizontal Creator 3D"; break;
+ }
+ }
+ break;
+ }
+
+ xf86Msg(X_PROBED, "SBUS:(0x%08x) %s", psdp->node.node, psdp->descr);
+ promPath = sparcPromNode2Pathname (&psdp->node);
+ if (promPath) {
+ xf86ErrorF(" at %s", promPath);
+ free(promPath);
+ }
+ } else
+ xf86Msg(X_PROBED, "SBUS: %s", psdp->descr);
+ xf86ErrorF("\n");
+ }
+ if (useProm)
+ sparcPromClose();
+}
+
+/*
+ * Parse a BUS ID string, and return the SBUS bus parameters if it was
+ * in the correct format for a SBUS bus id.
+ */
+
+Bool
+xf86ParseSbusBusString(const char *busID, int *fbNum)
+{
+ /*
+ * The format is assumed to be one of:
+ * "fbN", e.g. "fb1", which means the device corresponding to /dev/fbN
+ * "nameN", e.g. "cgsix0", which means Nth instance of card NAME
+ * "/prompath", e.g. "/sbus@0,10001000/cgsix@3,0" which is PROM pathname
+ * to the device.
+ */
+
+ const char *id;
+ int i, len;
+
+ if (StringToBusType(busID, &id) != BUS_SBUS)
+ return FALSE;
+
+ if (*id != '/') {
+ if (!strncmp (id, "fb", 2)) {
+ if (!isdigit(id[2]))
+ return FALSE;
+ *fbNum = atoi(id + 2);
+ return TRUE;
+ } else {
+ sbusDevicePtr *psdpp;
+ int devId;
+
+ for (i = 0, len = 0; sbusDeviceTable[i].devId; i++) {
+ len = strlen(sbusDeviceTable[i].promName);
+ if (!strncmp (sbusDeviceTable[i].promName, id, len)
+ && isdigit(id[len]))
+ break;
+ }
+ devId = sbusDeviceTable[i].devId;
+ if (!devId) return FALSE;
+ i = atoi(id + len);
+ for (psdpp = xf86SbusInfo; *psdpp; ++psdpp) {
+ if ((*psdpp)->devId != devId)
+ continue;
+ if (!i) {
+ *fbNum = (*psdpp)->fbNum;
+ return TRUE;
+ }
+ i--;
+ }
+ }
+ return FALSE;
+ }
+
+ if (sparcPromInit() >= 0) {
+ i = sparcPromPathname2Node(id);
+ sparcPromClose();
+ if (i) {
+ sbusDevicePtr *psdpp;
+ for (psdpp = xf86SbusInfo; *psdpp; ++psdpp) {
+ if ((*psdpp)->node.node == i) {
+ *fbNum = (*psdpp)->fbNum;
+ return TRUE;
+ }
+ }
+ }
+ }
+ return FALSE;
+}
+
+/*
+ * Compare a BUS ID string with a SBUS bus id. Return TRUE if they match.
+ */
+
+Bool
+xf86CompareSbusBusString(const char *busID, int fbNum)
+{
+ int iFbNum;
+
+ if (xf86ParseSbusBusString(busID, &iFbNum)) {
+ return fbNum == iFbNum;
+ } else {
+ return FALSE;
+ }
+}
+
+/*
+ * Check if the slot requested is free. If it is already in use, return FALSE.
+ */
+
+Bool
+xf86CheckSbusSlot(int fbNum)
+{
+ int i;
+ EntityPtr p;
+
+ for (i = 0; i < xf86NumEntities; i++) {
+ p = xf86Entities[i];
+ /* Check if this SBUS slot is taken */
+ if (p->bus.type == BUS_SBUS && p->bus.id.sbus.fbNum == fbNum)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*
+ * If the slot requested is already in use, return -1.
+ * Otherwise, claim the slot for the screen requesting it.
+ */
+
+int
+xf86ClaimSbusSlot(sbusDevicePtr psdp, DriverPtr drvp,
+ GDevPtr dev, Bool active)
+{
+ EntityPtr p = NULL;
+
+ int num;
+
+ if (xf86CheckSbusSlot(psdp->fbNum)) {
+ num = xf86AllocateEntity();
+ p = xf86Entities[num];
+ p->driver = drvp;
+ p->chipset = -1;
+ p->bus.type = BUS_SBUS;
+ xf86AddDevToEntity(num, dev);
+ p->bus.id.sbus.fbNum = psdp->fbNum;
+ p->active = active;
+ p->inUse = FALSE;
+ sbusSlotClaimed = TRUE;
+ return num;
+ } else
+ return -1;
+}
+
+int
+xf86MatchSbusInstances(const char *driverName, int sbusDevId,
+ GDevPtr *devList, int numDevs, DriverPtr drvp,
+ int **foundEntities)
+{
+ int i,j;
+ sbusDevicePtr psdp, *psdpp;
+ int numClaimedInstances = 0;
+ int allocatedInstances = 0;
+ int numFound = 0;
+ GDevPtr devBus = NULL;
+ GDevPtr dev = NULL;
+ int *retEntities = NULL;
+ int useProm = 0;
+
+ struct Inst {
+ sbusDevicePtr sbus;
+ GDevPtr dev;
+ Bool claimed; /* BusID matches with a device section */
+ } *instances = NULL;
+
+ *foundEntities = NULL;
+ for (psdpp = xf86SbusInfo, psdp = *psdpp; psdp; psdp = *++psdpp) {
+ if (psdp->devId != sbusDevId)
+ continue;
+ if (psdp->fd == -2)
+ continue;
+ ++allocatedInstances;
+ instances = xnfrealloc(instances,
+ allocatedInstances * sizeof(struct Inst));
+ instances[allocatedInstances - 1].sbus = psdp;
+ instances[allocatedInstances - 1].dev = NULL;
+ instances[allocatedInstances - 1].claimed = FALSE;
+ numFound++;
+ }
+
+ /*
+ * This may be debatable, but if no SBUS devices with a matching vendor
+ * type is found, return zero now. It is probably not desirable to
+ * allow the config file to override this.
+ */
+ if (allocatedInstances <= 0) {
+ free(instances);
+ return 0;
+ }
+
+ if (sparcPromInit() >= 0)
+ useProm = 1;
+
+ if (xf86DoConfigure && xf86DoConfigurePass1) {
+ GDevPtr pGDev;
+ int actualcards = 0;
+ for (i = 0; i < allocatedInstances; i++) {
+ actualcards++;
+ pGDev = xf86AddBusDeviceToConfigure(drvp->driverName, BUS_SBUS,
+ instances[i].sbus, -1);
+ if (pGDev) {
+ /*
+ * XF86Match???Instances() treat chipID and chipRev as
+ * overrides, so clobber them here.
+ */
+ pGDev->chipID = pGDev->chipRev = -1;
+ }
+ }
+ free(instances);
+ if (useProm)
+ sparcPromClose();
+ return actualcards;
+ }
+
+ DebugF("%s instances found: %d\n", driverName, allocatedInstances);
+
+ for (i = 0; i < allocatedInstances; i++) {
+ char *promPath = NULL;
+
+ psdp = instances[i].sbus;
+ devBus = NULL;
+ dev = NULL;
+ if (useProm && psdp->node.node)
+ promPath = sparcPromNode2Pathname(&psdp->node);
+
+ for (j = 0; j < numDevs; j++) {
+ if (devList[j]->busID && *devList[j]->busID) {
+ if (xf86CompareSbusBusString(devList[j]->busID, psdp->fbNum)) {
+ if (devBus)
+ xf86MsgVerb(X_WARNING,0,
+ "%s: More than one matching Device section for "
+ "instance (BusID: %s) found: %s\n",
+ driverName,devList[j]->identifier,
+ devList[j]->busID);
+ else
+ devBus = devList[j];
+ }
+ } else {
+ if (!dev && !devBus) {
+ if (promPath)
+ xf86Msg(X_PROBED, "Assigning device section with no busID to SBUS:%s\n",
+ promPath);
+ else
+ xf86Msg(X_PROBED, "Assigning device section with no busID to SBUS:fb%d\n",
+ psdp->fbNum);
+ dev = devList[j];
+ } else
+ xf86MsgVerb(X_WARNING, 0,
+ "%s: More than one matching Device section "
+ "found: %s\n", driverName, devList[j]->identifier);
+ }
+ }
+ if (devBus) dev = devBus; /* busID preferred */
+ if (!dev && psdp->fd != -2) {
+ if (promPath) {
+ xf86MsgVerb(X_WARNING, 0, "%s: No matching Device section "
+ "for instance (BusID SBUS:%s) found\n",
+ driverName, promPath);
+ } else
+ xf86MsgVerb(X_WARNING, 0, "%s: No matching Device section "
+ "for instance (BusID SBUS:fb%d) found\n",
+ driverName, psdp->fbNum);
+ } else if (dev) {
+ numClaimedInstances++;
+ instances[i].claimed = TRUE;
+ instances[i].dev = dev;
+ }
+ if (promPath)
+ free(promPath);
+ }
+
+ DebugF("%s instances found: %d\n", driverName, numClaimedInstances);
+
+ /*
+ * Of the claimed instances, check that another driver hasn't already
+ * claimed its slot.
+ */
+ numFound = 0;
+ for (i = 0; i < allocatedInstances && numClaimedInstances > 0; i++) {
+ if (!instances[i].claimed)
+ continue;
+ psdp = instances[i].sbus;
+ if (!xf86CheckSbusSlot(psdp->fbNum))
+ continue;
+
+ DebugF("%s: card at fb%d %08x is claimed by a Device section\n",
+ driverName, psdp->fbNum, psdp->node.node);
+
+ /* Allocate an entry in the lists to be returned */
+ numFound++;
+ retEntities = xnfrealloc(retEntities, numFound * sizeof(int));
+ retEntities[numFound - 1]
+ = xf86ClaimSbusSlot(psdp, drvp, instances[i].dev,instances[i].dev->active ?
+ TRUE : FALSE);
+ }
+ free(instances);
+ if (numFound > 0) {
+ *foundEntities = retEntities;
+ }
+
+ if (useProm)
+ sparcPromClose();
+
+ return numFound;
+}
+
+/*
+ * xf86GetSbusInfoForEntity() -- Get the sbusDevicePtr of entity.
+ */
+sbusDevicePtr
+xf86GetSbusInfoForEntity(int entityIndex)
+{
+ sbusDevicePtr *psdpp;
+ EntityPtr p = xf86Entities[entityIndex];
+
+ if (entityIndex >= xf86NumEntities
+ || p->bus.type != BUS_SBUS) return NULL;
+
+ for (psdpp = xf86SbusInfo; *psdpp != NULL; psdpp++) {
+ if (p->bus.id.sbus.fbNum == (*psdpp)->fbNum)
+ return (*psdpp);
+ }
+ return NULL;
+}
+
+int
+xf86GetEntityForSbusInfo(sbusDevicePtr psdp)
+{
+ int i;
+
+ for (i = 0; i < xf86NumEntities; i++) {
+ EntityPtr p = xf86Entities[i];
+ if (p->bus.type != BUS_SBUS) continue;
+
+ if (p->bus.id.sbus.fbNum == psdp->fbNum)
+ return i;
+ }
+ return -1;
+}
+
+void
+xf86SbusUseBuiltinMode(ScrnInfoPtr pScrn, sbusDevicePtr psdp)
+{
+ DisplayModePtr mode;
+
+ mode = xnfcalloc(sizeof(DisplayModeRec), 1);
+ mode->name = "current";
+ mode->next = mode;
+ mode->prev = mode;
+ mode->type = M_T_BUILTIN;
+ mode->Clock = 100000000;
+ mode->HDisplay = psdp->width;
+ mode->HSyncStart = psdp->width;
+ mode->HSyncEnd = psdp->width;
+ mode->HTotal = psdp->width;
+ mode->VDisplay = psdp->height;
+ mode->VSyncStart = psdp->height;
+ mode->VSyncEnd = psdp->height;
+ mode->VTotal = psdp->height;
+ mode->SynthClock = mode->Clock;
+ mode->CrtcHDisplay = mode->HDisplay;
+ mode->CrtcHSyncStart = mode->HSyncStart;
+ mode->CrtcHSyncEnd = mode->HSyncEnd;
+ mode->CrtcHTotal = mode->HTotal;
+ mode->CrtcVDisplay = mode->VDisplay;
+ mode->CrtcVSyncStart = mode->VSyncStart;
+ mode->CrtcVSyncEnd = mode->VSyncEnd;
+ mode->CrtcVTotal = mode->VTotal;
+ mode->CrtcHAdjusted = FALSE;
+ mode->CrtcVAdjusted = FALSE;
+ pScrn->modes = mode;
+ pScrn->virtualX = psdp->width;
+ pScrn->virtualY = psdp->height;
+}
+
+static sbusPaletteKeyIndex;
+static DevPrivateKey sbusPaletteKey = &sbusPaletteKeyIndex;
+typedef struct _sbusCmap {
+ sbusDevicePtr psdp;
+ CloseScreenProcPtr CloseScreen;
+ Bool origCmapValid;
+ unsigned char origRed[16];
+ unsigned char origGreen[16];
+ unsigned char origBlue[16];
+} sbusCmapRec, *sbusCmapPtr;
+
+#define SBUSCMAPPTR(pScreen) ((sbusCmapPtr) \
+ dixLookupPrivate(&(pScreen)->devPrivates, sbusPaletteKey))
+
+static void
+xf86SbusCmapLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
+ LOCO *colors, VisualPtr pVisual)
+{
+ int i, index;
+ sbusCmapPtr cmap;
+ struct fbcmap fbcmap;
+ unsigned char *data = malloc(numColors*3);
+
+ cmap = SBUSCMAPPTR(pScrn->pScreen);
+ if (!cmap) return;
+ fbcmap.count = 0;
+ fbcmap.index = indices[0];
+ fbcmap.red = data;
+ fbcmap.green = data + numColors;
+ fbcmap.blue = fbcmap.green + numColors;
+ for (i = 0; i < numColors; i++) {
+ index = indices[i];
+ if (fbcmap.count && index != fbcmap.index + fbcmap.count) {
+ ioctl (cmap->psdp->fd, FBIOPUTCMAP, &fbcmap);
+ fbcmap.count = 0;
+ fbcmap.index = index;
+ }
+ fbcmap.red[fbcmap.count] = colors[index].red;
+ fbcmap.green[fbcmap.count] = colors[index].green;
+ fbcmap.blue[fbcmap.count++] = colors[index].blue;
+ }
+ ioctl (cmap->psdp->fd, FBIOPUTCMAP, &fbcmap);
+ free(data);
+}
+
+static Bool
+xf86SbusCmapCloseScreen(int i, ScreenPtr pScreen)
+{
+ sbusCmapPtr cmap;
+ struct fbcmap fbcmap;
+
+ cmap = SBUSCMAPPTR(pScreen);
+ if (cmap->origCmapValid) {
+ fbcmap.index = 0;
+ fbcmap.count = 16;
+ fbcmap.red = cmap->origRed;
+ fbcmap.green = cmap->origGreen;
+ fbcmap.blue = cmap->origBlue;
+ ioctl (cmap->psdp->fd, FBIOPUTCMAP, &fbcmap);
+ }
+ pScreen->CloseScreen = cmap->CloseScreen;
+ free(cmap);
+ return (*pScreen->CloseScreen) (i, pScreen);
+}
+
+Bool
+xf86SbusHandleColormaps(ScreenPtr pScreen, sbusDevicePtr psdp)
+{
+ sbusCmapPtr cmap;
+ struct fbcmap fbcmap;
+ unsigned char data[2];
+
+ cmap = xnfcalloc(1, sizeof(sbusCmapRec));
+ dixSetPrivate(&pScreen->devPrivates, sbusPaletteKey, cmap);
+ cmap->psdp = psdp;
+ fbcmap.index = 0;
+ fbcmap.count = 16;
+ fbcmap.red = cmap->origRed;
+ fbcmap.green = cmap->origGreen;
+ fbcmap.blue = cmap->origBlue;
+ if (ioctl (psdp->fd, FBIOGETCMAP, &fbcmap) >= 0)
+ cmap->origCmapValid = TRUE;
+ fbcmap.index = 0;
+ fbcmap.count = 2;
+ fbcmap.red = data;
+ fbcmap.green = data;
+ fbcmap.blue = data;
+ if (pScreen->whitePixel == 0) {
+ data[0] = 255;
+ data[1] = 0;
+ } else {
+ data[0] = 0;
+ data[1] = 255;
+ }
+ ioctl (psdp->fd, FBIOPUTCMAP, &fbcmap);
+ cmap->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = xf86SbusCmapCloseScreen;
+ return xf86HandleColormaps(pScreen, 256, 8,
+ xf86SbusCmapLoadPalette, NULL, 0);
+}
diff --git a/xorg-server/hw/xfree86/common/xf86xv.c b/xorg-server/hw/xfree86/common/xf86xv.c
index 2cc2f6093..e35b8d667 100644
--- a/xorg-server/hw/xfree86/common/xf86xv.c
+++ b/xorg-server/hw/xfree86/common/xf86xv.c
@@ -1,2101 +1,2102 @@
-/*
- * XFree86 Xv DDX written by Mark Vojkovich (markv@valinux.com)
- */
-/*
- * Copyright (c) 1998-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "misc.h"
-#include "xf86.h"
-#include "xf86_OSproc.h"
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "scrnintstr.h"
-#include "regionstr.h"
-#include "windowstr.h"
-#include "pixmapstr.h"
-#include "mivalidate.h"
-#include "validate.h"
-#include "resource.h"
-#include "gcstruct.h"
-#include "dixstruct.h"
-
-#include <X11/extensions/Xv.h>
-#include <X11/extensions/Xvproto.h>
-#include "xvdix.h"
-#include "xvmodproc.h"
-
-#include "xf86xvpriv.h"
-
-
-/* XvScreenRec fields */
-
-static Bool xf86XVCloseScreen(int, ScreenPtr);
-static int xf86XVQueryAdaptors(ScreenPtr, XvAdaptorPtr *, int *);
-
-/* XvAdaptorRec fields */
-
-static int xf86XVAllocatePort(unsigned long, XvPortPtr, XvPortPtr*);
-static int xf86XVFreePort(XvPortPtr);
-static int xf86XVPutVideo(ClientPtr, DrawablePtr,XvPortPtr, GCPtr,
- INT16, INT16, CARD16, CARD16,
- INT16, INT16, CARD16, CARD16);
-static int xf86XVPutStill(ClientPtr, DrawablePtr,XvPortPtr, GCPtr,
- INT16, INT16, CARD16, CARD16,
- INT16, INT16, CARD16, CARD16);
-static int xf86XVGetVideo(ClientPtr, DrawablePtr,XvPortPtr, GCPtr,
- INT16, INT16, CARD16, CARD16,
- INT16, INT16, CARD16, CARD16);
-static int xf86XVGetStill(ClientPtr, DrawablePtr,XvPortPtr, GCPtr,
- INT16, INT16, CARD16, CARD16,
- INT16, INT16, CARD16, CARD16);
-static int xf86XVStopVideo(ClientPtr, XvPortPtr, DrawablePtr);
-static int xf86XVSetPortAttribute(ClientPtr, XvPortPtr, Atom, INT32);
-static int xf86XVGetPortAttribute(ClientPtr, XvPortPtr, Atom, INT32*);
-static int xf86XVQueryBestSize(ClientPtr, XvPortPtr, CARD8,
- CARD16, CARD16,CARD16, CARD16,
- unsigned int*, unsigned int*);
-static int xf86XVPutImage(ClientPtr, DrawablePtr, XvPortPtr, GCPtr,
- INT16, INT16, CARD16, CARD16,
- INT16, INT16, CARD16, CARD16,
- XvImagePtr, unsigned char*, Bool,
- CARD16, CARD16);
-static int xf86XVQueryImageAttributes(ClientPtr, XvPortPtr, XvImagePtr,
- CARD16*, CARD16*, int*, int*);
-
-
-/* ScreenRec fields */
-
-static Bool xf86XVDestroyWindow(WindowPtr pWin);
-static void xf86XVWindowExposures(WindowPtr pWin, RegionPtr r1, RegionPtr r2);
-static void xf86XVClipNotify(WindowPtr pWin, int dx, int dy);
-
-/* ScrnInfoRec functions */
-
-static Bool xf86XVEnterVT(int, int);
-static void xf86XVLeaveVT(int, int);
-static void xf86XVAdjustFrame(int index, int x, int y, int flags);
-
-/* misc */
-
-static Bool xf86XVInitAdaptors(ScreenPtr, XF86VideoAdaptorPtr*, int);
-
-
-static int XF86XVWindowKeyIndex;
-static DevPrivateKey XF86XVWindowKey = &XF86XVWindowKeyIndex;
-static int XF86XvScreenKeyIndex;
-DevPrivateKey XF86XvScreenKey = &XF86XvScreenKeyIndex;
-static unsigned long PortResource = 0;
-
-DevPrivateKey (*XvGetScreenKeyProc)(void) = NULL;
-unsigned long (*XvGetRTPortProc)(void) = NULL;
-int (*XvScreenInitProc)(ScreenPtr) = NULL;
-
-#define GET_XV_SCREEN(pScreen) \
- ((XvScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates, XF86XvScreenKey))
-
-#define GET_XF86XV_SCREEN(pScreen) \
- ((XF86XVScreenPtr)(GET_XV_SCREEN(pScreen)->devPriv.ptr))
-
-#define GET_XF86XV_WINDOW(pWin) \
- ((XF86XVWindowPtr)dixLookupPrivate(&(pWin)->devPrivates, XF86XVWindowKey))
-
-static xf86XVInitGenericAdaptorPtr *GenDrivers = NULL;
-static int NumGenDrivers = 0;
-
-int
-xf86XVRegisterGenericAdaptorDriver(
- xf86XVInitGenericAdaptorPtr InitFunc
-){
- xf86XVInitGenericAdaptorPtr *newdrivers;
-
- newdrivers = xrealloc(GenDrivers, sizeof(xf86XVInitGenericAdaptorPtr) *
- (1 + NumGenDrivers));
- if (!newdrivers)
- return 0;
- GenDrivers = newdrivers;
-
- GenDrivers[NumGenDrivers++] = InitFunc;
-
- return 1;
-}
-
-int
-xf86XVListGenericAdaptors(
- ScrnInfoPtr pScrn,
- XF86VideoAdaptorPtr **adaptors
-){
- int i,j,n,num;
- XF86VideoAdaptorPtr *DrivAdap,*new;
-
- num = 0;
- *adaptors = NULL;
- /*
- * The v4l driver registers itself first, but can use surfaces registered
- * by other drivers. So, call the v4l driver last.
- */
- for (i = NumGenDrivers; --i >= 0; ) {
- DrivAdap = NULL;
- n = (*GenDrivers[i])(pScrn, &DrivAdap);
- if (0 == n)
- continue;
- new = xrealloc(*adaptors, sizeof(XF86VideoAdaptorPtr) * (num+n));
- if (NULL == new)
- continue;
- *adaptors = new;
- for (j = 0; j < n; j++, num++)
- (*adaptors)[num] = DrivAdap[j];
- }
- return num;
-}
-
-
-/**************** Offscreen surface stuff *******************/
-
-typedef struct {
- XF86OffscreenImagePtr images;
- int num;
-} OffscreenImageRec;
-
-static int OffscreenPrivateKeyIndex;
-static DevPrivateKey OffscreenPrivateKey = &OffscreenPrivateKeyIndex;
-#define GetOffscreenImage(pScreen) ((OffscreenImageRec *) dixLookupPrivate(&(pScreen)->devPrivates, OffscreenPrivateKey))
-
-Bool
-xf86XVRegisterOffscreenImages(
- ScreenPtr pScreen,
- XF86OffscreenImagePtr images,
- int num
-){
- OffscreenImageRec *OffscreenImage;
- /* This function may be called before xf86XVScreenInit, so there's
- * no better place than this to call dixRequestPrivate to ensure we
- * have space reserved. After the first call it is a no-op. */
- if(!dixRequestPrivate(OffscreenPrivateKey, sizeof(OffscreenImageRec)) ||
- !(OffscreenImage = GetOffscreenImage(pScreen)))
- /* Every X.org driver assumes this function always succeeds, so
- * just die on allocation failure. */
- FatalError("Could not allocate private storage for XV offscreen images.\n");
-
- OffscreenImage->num = num;
- OffscreenImage->images = images;
- return TRUE;
-}
-
-XF86OffscreenImagePtr
-xf86XVQueryOffscreenImages(
- ScreenPtr pScreen,
- int *num
-){
- OffscreenImageRec *OffscreenImage = GetOffscreenImage(pScreen);
- *num = OffscreenImage->num;
- return OffscreenImage->images;
-}
-
-
-XF86VideoAdaptorPtr
-xf86XVAllocateVideoAdaptorRec(ScrnInfoPtr pScrn)
-{
- return xcalloc(1, sizeof(XF86VideoAdaptorRec));
-}
-
-void
-xf86XVFreeVideoAdaptorRec(XF86VideoAdaptorPtr ptr)
-{
- xfree(ptr);
-}
-
-
-Bool
-xf86XVScreenInit(
- ScreenPtr pScreen,
- XF86VideoAdaptorPtr *adaptors,
- int num
-){
- ScrnInfoPtr pScrn;
- XF86XVScreenPtr ScreenPriv;
- XvScreenPtr pxvs;
-
- if(num <= 0 ||
- !XvGetScreenKeyProc || !XvGetRTPortProc || !XvScreenInitProc)
- return FALSE;
-
- if(Success != (*XvScreenInitProc)(pScreen)) return FALSE;
-
- XF86XvScreenKey = (*XvGetScreenKeyProc)();
- PortResource = (*XvGetRTPortProc)();
-
- pxvs = GET_XV_SCREEN(pScreen);
-
- /* Anyone initializing the Xv layer must provide these two.
- The Xv di layer calls them without even checking if they exist! */
-
- pxvs->ddCloseScreen = xf86XVCloseScreen;
- pxvs->ddQueryAdaptors = xf86XVQueryAdaptors;
-
- /* The Xv di layer provides us with a private hook so that we don't
- have to allocate our own screen private. They also provide
- a CloseScreen hook so that we don't have to wrap it. I'm not
- sure that I appreciate that. */
-
- ScreenPriv = xalloc(sizeof(XF86XVScreenRec));
- pxvs->devPriv.ptr = (pointer)ScreenPriv;
-
- if(!ScreenPriv) return FALSE;
-
- pScrn = xf86Screens[pScreen->myNum];
-
- ScreenPriv->videoGC = NULL; /* for the helper */
-
- ScreenPriv->DestroyWindow = pScreen->DestroyWindow;
- ScreenPriv->WindowExposures = pScreen->WindowExposures;
- ScreenPriv->ClipNotify = pScreen->ClipNotify;
- ScreenPriv->EnterVT = pScrn->EnterVT;
- ScreenPriv->LeaveVT = pScrn->LeaveVT;
- ScreenPriv->AdjustFrame = pScrn->AdjustFrame;
-
- pScreen->DestroyWindow = xf86XVDestroyWindow;
- pScreen->WindowExposures = xf86XVWindowExposures;
- pScreen->ClipNotify = xf86XVClipNotify;
- pScrn->EnterVT = xf86XVEnterVT;
- pScrn->LeaveVT = xf86XVLeaveVT;
- if(pScrn->AdjustFrame)
- pScrn->AdjustFrame = xf86XVAdjustFrame;
-
- if(!xf86XVInitAdaptors(pScreen, adaptors, num))
- return FALSE;
-
- return TRUE;
-}
-
-static void
-xf86XVFreeAdaptor(XvAdaptorPtr pAdaptor)
-{
- int i;
-
- xfree(pAdaptor->name);
-
- if(pAdaptor->pEncodings) {
- XvEncodingPtr pEncode = pAdaptor->pEncodings;
-
- for(i = 0; i < pAdaptor->nEncodings; i++, pEncode++)
- xfree(pEncode->name);
- xfree(pAdaptor->pEncodings);
- }
-
- xfree(pAdaptor->pFormats);
-
- if(pAdaptor->pPorts) {
- XvPortPtr pPort = pAdaptor->pPorts;
- XvPortRecPrivatePtr pPriv;
-
- for(i = 0; i < pAdaptor->nPorts; i++, pPort++) {
- pPriv = (XvPortRecPrivatePtr)pPort->devPriv.ptr;
- if(pPriv) {
- if(pPriv->clientClip)
- REGION_DESTROY(pAdaptor->pScreen, pPriv->clientClip);
- if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
- REGION_DESTROY(pAdaptor->pScreen, pPriv->pCompositeClip);
- xfree(pPriv);
- }
- }
- xfree(pAdaptor->pPorts);
- }
-
- if(pAdaptor->nAttributes) {
- XvAttributePtr pAttribute = pAdaptor->pAttributes;
-
- for(i = 0; i < pAdaptor->nAttributes; i++, pAttribute++)
- xfree(pAttribute->name);
- xfree(pAdaptor->pAttributes);
- }
-
- xfree(pAdaptor->pImages);
- xfree(pAdaptor->devPriv.ptr);
-}
-
-static Bool
-xf86XVInitAdaptors(
- ScreenPtr pScreen,
- XF86VideoAdaptorPtr *infoPtr,
- int number
-) {
- XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- XF86VideoAdaptorPtr adaptorPtr;
- XvAdaptorPtr pAdaptor, pa;
- XvAdaptorRecPrivatePtr adaptorPriv;
- int na, numAdaptor;
- XvPortRecPrivatePtr portPriv;
- XvPortPtr pPort, pp;
- int numPort;
- XF86AttributePtr attributePtr;
- XvAttributePtr pAttribute, pat;
- XF86VideoFormatPtr formatPtr;
- XvFormatPtr pFormat, pf;
- int numFormat, totFormat;
- XF86VideoEncodingPtr encodingPtr;
- XvEncodingPtr pEncode, pe;
- XF86ImagePtr imagePtr;
- XvImagePtr pImage, pi;
- int numVisuals;
- VisualPtr pVisual;
- int i;
-
- pxvs->nAdaptors = 0;
- pxvs->pAdaptors = NULL;
-
- if(!(pAdaptor = xcalloc(number, sizeof(XvAdaptorRec))))
- return FALSE;
-
- for(pa = pAdaptor, na = 0, numAdaptor = 0; na < number; na++, adaptorPtr++) {
- adaptorPtr = infoPtr[na];
-
- if(!adaptorPtr->StopVideo || !adaptorPtr->SetPortAttribute ||
- !adaptorPtr->GetPortAttribute || !adaptorPtr->QueryBestSize)
- continue;
-
- /* client libs expect at least one encoding */
- if(!adaptorPtr->nEncodings || !adaptorPtr->pEncodings)
- continue;
-
- pa->type = adaptorPtr->type;
-
- if(!adaptorPtr->PutVideo && !adaptorPtr->GetVideo)
- pa->type &= ~XvVideoMask;
-
- if(!adaptorPtr->PutStill && !adaptorPtr->GetStill)
- pa->type &= ~XvStillMask;
-
- if(!adaptorPtr->PutImage || !adaptorPtr->QueryImageAttributes)
- pa->type &= ~XvImageMask;
-
- if(!adaptorPtr->PutVideo && !adaptorPtr->PutImage &&
- !adaptorPtr->PutStill)
- pa->type &= ~XvInputMask;
-
- if(!adaptorPtr->GetVideo && !adaptorPtr->GetStill)
- pa->type &= ~XvOutputMask;
-
- if(!(adaptorPtr->type & (XvPixmapMask | XvWindowMask)))
- continue;
- if(!(adaptorPtr->type & (XvImageMask | XvVideoMask | XvStillMask)))
- continue;
-
- pa->pScreen = pScreen;
- pa->ddAllocatePort = xf86XVAllocatePort;
- pa->ddFreePort = xf86XVFreePort;
- pa->ddPutVideo = xf86XVPutVideo;
- pa->ddPutStill = xf86XVPutStill;
- pa->ddGetVideo = xf86XVGetVideo;
- pa->ddGetStill = xf86XVGetStill;
- pa->ddStopVideo = xf86XVStopVideo;
- pa->ddPutImage = xf86XVPutImage;
- pa->ddSetPortAttribute = xf86XVSetPortAttribute;
- pa->ddGetPortAttribute = xf86XVGetPortAttribute;
- pa->ddQueryBestSize = xf86XVQueryBestSize;
- pa->ddQueryImageAttributes = xf86XVQueryImageAttributes;
- if((pa->name = xalloc(strlen(adaptorPtr->name) + 1)))
- strcpy(pa->name, adaptorPtr->name);
-
- if(adaptorPtr->nEncodings &&
- (pEncode = xcalloc(adaptorPtr->nEncodings, sizeof(XvEncodingRec)))) {
-
- for(pe = pEncode, encodingPtr = adaptorPtr->pEncodings, i = 0;
- i < adaptorPtr->nEncodings; pe++, i++, encodingPtr++)
- {
- pe->id = encodingPtr->id;
- pe->pScreen = pScreen;
- if((pe->name = xalloc(strlen(encodingPtr->name) + 1)))
- strcpy(pe->name, encodingPtr->name);
- pe->width = encodingPtr->width;
- pe->height = encodingPtr->height;
- pe->rate.numerator = encodingPtr->rate.numerator;
- pe->rate.denominator = encodingPtr->rate.denominator;
- }
- pa->nEncodings = adaptorPtr->nEncodings;
- pa->pEncodings = pEncode;
- }
-
- if(adaptorPtr->nImages &&
- (pImage = xcalloc(adaptorPtr->nImages, sizeof(XvImageRec)))) {
-
- for(i = 0, pi = pImage, imagePtr = adaptorPtr->pImages;
- i < adaptorPtr->nImages; i++, pi++, imagePtr++)
- {
- pi->id = imagePtr->id;
- pi->type = imagePtr->type;
- pi->byte_order = imagePtr->byte_order;
- memcpy(pi->guid, imagePtr->guid, 16);
- pi->bits_per_pixel = imagePtr->bits_per_pixel;
- pi->format = imagePtr->format;
- pi->num_planes = imagePtr->num_planes;
- pi->depth = imagePtr->depth;
- pi->red_mask = imagePtr->red_mask;
- pi->green_mask = imagePtr->green_mask;
- pi->blue_mask = imagePtr->blue_mask;
- pi->y_sample_bits = imagePtr->y_sample_bits;
- pi->u_sample_bits = imagePtr->u_sample_bits;
- pi->v_sample_bits = imagePtr->v_sample_bits;
- pi->horz_y_period = imagePtr->horz_y_period;
- pi->horz_u_period = imagePtr->horz_u_period;
- pi->horz_v_period = imagePtr->horz_v_period;
- pi->vert_y_period = imagePtr->vert_y_period;
- pi->vert_u_period = imagePtr->vert_u_period;
- pi->vert_v_period = imagePtr->vert_v_period;
- memcpy(pi->component_order, imagePtr->component_order, 32);
- pi->scanline_order = imagePtr->scanline_order;
- }
- pa->nImages = adaptorPtr->nImages;
- pa->pImages = pImage;
- }
-
- if(adaptorPtr->nAttributes &&
- (pAttribute = xcalloc(adaptorPtr->nAttributes, sizeof(XvAttributeRec))))
- {
- for(pat = pAttribute, attributePtr = adaptorPtr->pAttributes, i = 0;
- i < adaptorPtr->nAttributes; pat++, i++, attributePtr++)
- {
- pat->flags = attributePtr->flags;
- pat->min_value = attributePtr->min_value;
- pat->max_value = attributePtr->max_value;
- if((pat->name = xalloc(strlen(attributePtr->name) + 1)))
- strcpy(pat->name, attributePtr->name);
- }
- pa->nAttributes = adaptorPtr->nAttributes;
- pa->pAttributes = pAttribute;
- }
-
-
- totFormat = adaptorPtr->nFormats;
-
- if(!(pFormat = xcalloc(totFormat, sizeof(XvFormatRec)))) {
- xf86XVFreeAdaptor(pa);
- continue;
- }
- for(pf = pFormat, i = 0, numFormat = 0, formatPtr = adaptorPtr->pFormats;
- i < adaptorPtr->nFormats; i++, formatPtr++)
- {
- numVisuals = pScreen->numVisuals;
- pVisual = pScreen->visuals;
-
- while(numVisuals--) {
- if((pVisual->class == formatPtr->class) &&
- (pVisual->nplanes == formatPtr->depth)) {
-
- if(numFormat >= totFormat) {
- void *moreSpace;
- totFormat *= 2;
- moreSpace = xrealloc(pFormat,
- totFormat * sizeof(XvFormatRec));
- if(!moreSpace) break;
- pFormat = moreSpace;
- pf = pFormat + numFormat;
- }
-
- pf->visual = pVisual->vid;
- pf->depth = formatPtr->depth;
-
- pf++;
- numFormat++;
- }
- pVisual++;
- }
- }
- pa->nFormats = numFormat;
- pa->pFormats = pFormat;
- if(!numFormat) {
- xf86XVFreeAdaptor(pa);
- continue;
- }
-
- if(!(adaptorPriv = xcalloc(1, sizeof(XvAdaptorRecPrivate)))) {
- xf86XVFreeAdaptor(pa);
- continue;
- }
-
- adaptorPriv->flags = adaptorPtr->flags;
- adaptorPriv->PutVideo = adaptorPtr->PutVideo;
- adaptorPriv->PutStill = adaptorPtr->PutStill;
- adaptorPriv->GetVideo = adaptorPtr->GetVideo;
- adaptorPriv->GetStill = adaptorPtr->GetStill;
- adaptorPriv->StopVideo = adaptorPtr->StopVideo;
- adaptorPriv->SetPortAttribute = adaptorPtr->SetPortAttribute;
- adaptorPriv->GetPortAttribute = adaptorPtr->GetPortAttribute;
- adaptorPriv->QueryBestSize = adaptorPtr->QueryBestSize;
- adaptorPriv->QueryImageAttributes = adaptorPtr->QueryImageAttributes;
- adaptorPriv->PutImage = adaptorPtr->PutImage;
- adaptorPriv->ReputImage = adaptorPtr->ReputImage;
-
- pa->devPriv.ptr = (pointer)adaptorPriv;
-
- if(!(pPort = xcalloc(adaptorPtr->nPorts, sizeof(XvPortRec)))) {
- xf86XVFreeAdaptor(pa);
- continue;
- }
- for(pp = pPort, i = 0, numPort = 0;
- i < adaptorPtr->nPorts; i++) {
-
- if(!(pp->id = FakeClientID(0)))
- continue;
-
- if(!(portPriv = xcalloc(1, sizeof(XvPortRecPrivate))))
- continue;
-
- if(!AddResource(pp->id, PortResource, pp)) {
- xfree(portPriv);
- continue;
- }
-
- pp->pAdaptor = pa;
- pp->pNotify = (XvPortNotifyPtr)NULL;
- pp->pDraw = (DrawablePtr)NULL;
- pp->client = (ClientPtr)NULL;
- pp->grab.client = (ClientPtr)NULL;
- pp->time = currentTime;
- pp->devPriv.ptr = portPriv;
-
- portPriv->pScrn = pScrn;
- portPriv->AdaptorRec = adaptorPriv;
- portPriv->DevPriv.ptr = adaptorPtr->pPortPrivates[i].ptr;
-
- pp++;
- numPort++;
- }
- pa->nPorts = numPort;
- pa->pPorts = pPort;
- if(!numPort) {
- xf86XVFreeAdaptor(pa);
- continue;
- }
-
- pa->base_id = pPort->id;
-
- pa++;
- numAdaptor++;
- }
-
- if(numAdaptor) {
- pxvs->nAdaptors = numAdaptor;
- pxvs->pAdaptors = pAdaptor;
- } else {
- xfree(pAdaptor);
- return FALSE;
- }
-
- return TRUE;
-}
-
-/* Video should be clipped to the intersection of the window cliplist
- and the client cliplist specified in the GC for which the video was
- initialized. When we need to reclip a window, the GC that started
- the video may not even be around anymore. That's why we save the
- client clip from the GC when the video is initialized. We then
- use xf86XVUpdateCompositeClip to calculate the new composite clip
- when we need it. This is different from what DEC did. They saved
- the GC and used it's clip list when they needed to reclip the window,
- even if the client clip was different from the one the video was
- initialized with. If the original GC was destroyed, they had to stop
- the video. I like the new method better (MArk).
-
- This function only works for windows. Will need to rewrite when
- (if) we support pixmap rendering.
-*/
-
-static void
-xf86XVUpdateCompositeClip(XvPortRecPrivatePtr portPriv)
-{
- RegionPtr pregWin, pCompositeClip;
- WindowPtr pWin;
- ScreenPtr pScreen;
- Bool freeCompClip = FALSE;
-
- if(portPriv->pCompositeClip)
- return;
-
- pWin = (WindowPtr)portPriv->pDraw;
- pScreen = pWin->drawable.pScreen;
-
- /* get window clip list */
- if(portPriv->subWindowMode == IncludeInferiors) {
- pregWin = NotClippedByChildren(pWin);
- freeCompClip = TRUE;
- } else
- pregWin = &pWin->clipList;
-
- if(!portPriv->clientClip) {
- portPriv->pCompositeClip = pregWin;
- portPriv->FreeCompositeClip = freeCompClip;
- return;
- }
-
- pCompositeClip = REGION_CREATE(pScreen, NullBox, 1);
- REGION_COPY(pScreen, pCompositeClip, portPriv->clientClip);
- REGION_TRANSLATE(pScreen, pCompositeClip,
- portPriv->pDraw->x + portPriv->clipOrg.x,
- portPriv->pDraw->y + portPriv->clipOrg.y);
- REGION_INTERSECT(pScreen, pCompositeClip, pregWin, pCompositeClip);
-
- portPriv->pCompositeClip = pCompositeClip;
- portPriv->FreeCompositeClip = TRUE;
-
- if(freeCompClip) {
- REGION_DESTROY(pScreen, pregWin);
- }
-}
-
-/* Save the current clientClip and update the CompositeClip whenever
- we have a fresh GC */
-
-static void
-xf86XVCopyClip(
- XvPortRecPrivatePtr portPriv,
- GCPtr pGC
-){
- /* copy the new clip if it exists */
- if((pGC->clientClipType == CT_REGION) && pGC->clientClip) {
- if(!portPriv->clientClip)
- portPriv->clientClip = REGION_CREATE(pScreen, NullBox, 1);
- /* Note: this is in window coordinates */
- REGION_COPY(pScreen, portPriv->clientClip, pGC->clientClip);
- } else if(portPriv->clientClip) { /* free the old clientClip */
- REGION_DESTROY(pScreen, portPriv->clientClip);
- portPriv->clientClip = NULL;
- }
-
- /* get rid of the old clip list */
- if(portPriv->pCompositeClip && portPriv->FreeCompositeClip) {
- REGION_DESTROY(pScreen, portPriv->pCompositeClip);
- }
-
- portPriv->clipOrg = pGC->clipOrg;
- portPriv->pCompositeClip = pGC->pCompositeClip;
- portPriv->FreeCompositeClip = FALSE;
- portPriv->subWindowMode = pGC->subWindowMode;
-}
-
-static int
-xf86XVRegetVideo(XvPortRecPrivatePtr portPriv)
-{
- RegionRec WinRegion;
- RegionRec ClipRegion;
- BoxRec WinBox;
- ScreenPtr pScreen;
- int ret = Success;
- Bool clippedAway = FALSE;
-
- pScreen = portPriv->pDraw->pScreen;
- xf86XVUpdateCompositeClip(portPriv);
-
- /* translate the video region to the screen */
- WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
- WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
- WinBox.x2 = WinBox.x1 + portPriv->drw_w;
- WinBox.y2 = WinBox.y1 + portPriv->drw_h;
-
- /* clip to the window composite clip */
- REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
- REGION_NULL(pScreen, &ClipRegion);
- REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, portPriv->pCompositeClip);
-
- /* that's all if it's totally obscured */
- if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
- clippedAway = TRUE;
- goto CLIP_VIDEO_BAILOUT;
- }
-
- if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
- REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
- }
-
- ret = (*portPriv->AdaptorRec->GetVideo)(portPriv->pScrn,
- portPriv->vid_x, portPriv->vid_y,
- WinBox.x1, WinBox.y1,
- portPriv->vid_w, portPriv->vid_h,
- portPriv->drw_w, portPriv->drw_h,
- &ClipRegion, portPriv->DevPriv.ptr,
- portPriv->pDraw);
-
- if(ret == Success)
- portPriv->isOn = XV_ON;
-
-CLIP_VIDEO_BAILOUT:
-
- if((clippedAway || (ret != Success)) && portPriv->isOn == XV_ON) {
- (*portPriv->AdaptorRec->StopVideo)(
- portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
- portPriv->isOn = XV_PENDING;
- }
-
- /* This clip was copied and only good for one shot */
- if(!portPriv->FreeCompositeClip)
- portPriv->pCompositeClip = NULL;
-
- REGION_UNINIT(pScreen, &WinRegion);
- REGION_UNINIT(pScreen, &ClipRegion);
-
- return ret;
-}
-
-
-static int
-xf86XVReputVideo(XvPortRecPrivatePtr portPriv)
-{
- RegionRec WinRegion;
- RegionRec ClipRegion;
- BoxRec WinBox;
- ScreenPtr pScreen;
- int ret = Success;
- Bool clippedAway = FALSE;
-
- pScreen = portPriv->pDraw->pScreen;
-
- xf86XVUpdateCompositeClip(portPriv);
-
- /* translate the video region to the screen */
- WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
- WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
- WinBox.x2 = WinBox.x1 + portPriv->drw_w;
- WinBox.y2 = WinBox.y1 + portPriv->drw_h;
-
- /* clip to the window composite clip */
- REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
- REGION_NULL(pScreen, &ClipRegion);
- REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, portPriv->pCompositeClip);
-
- /* clip and translate to the viewport */
- if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
- RegionRec VPReg;
- BoxRec VPBox;
-
- VPBox.x1 = portPriv->pScrn->frameX0;
- VPBox.y1 = portPriv->pScrn->frameY0;
- VPBox.x2 = portPriv->pScrn->frameX1 + 1;
- VPBox.y2 = portPriv->pScrn->frameY1 + 1;
-
- REGION_INIT(pScreen, &VPReg, &VPBox, 1);
- REGION_INTERSECT(pScreen, &ClipRegion, &ClipRegion, &VPReg);
- REGION_UNINIT(pScreen, &VPReg);
- }
-
- /* that's all if it's totally obscured */
- if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
- clippedAway = TRUE;
- goto CLIP_VIDEO_BAILOUT;
- }
-
- /* bailout if we have to clip but the hardware doesn't support it */
- if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) {
- BoxPtr clipBox = REGION_RECTS(&ClipRegion);
- if( (REGION_NUM_RECTS(&ClipRegion) != 1) ||
- (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) ||
- (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2))
- {
- clippedAway = TRUE;
- goto CLIP_VIDEO_BAILOUT;
- }
- }
-
- if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
- REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
- }
-
- ret = (*portPriv->AdaptorRec->PutVideo)(portPriv->pScrn,
- portPriv->vid_x, portPriv->vid_y,
- WinBox.x1, WinBox.y1,
- portPriv->vid_w, portPriv->vid_h,
- portPriv->drw_w, portPriv->drw_h,
- &ClipRegion, portPriv->DevPriv.ptr,
- portPriv->pDraw);
-
- if(ret == Success) portPriv->isOn = XV_ON;
-
-CLIP_VIDEO_BAILOUT:
-
- if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
- (*portPriv->AdaptorRec->StopVideo)(
- portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
- portPriv->isOn = XV_PENDING;
- }
-
- /* This clip was copied and only good for one shot */
- if(!portPriv->FreeCompositeClip)
- portPriv->pCompositeClip = NULL;
-
- REGION_UNINIT(pScreen, &WinRegion);
- REGION_UNINIT(pScreen, &ClipRegion);
-
- return ret;
-}
-
-static int
-xf86XVReputImage(XvPortRecPrivatePtr portPriv)
-{
- RegionRec WinRegion;
- RegionRec ClipRegion;
- BoxRec WinBox;
- ScreenPtr pScreen;
- int ret = Success;
- Bool clippedAway = FALSE;
-
- pScreen = portPriv->pDraw->pScreen;
-
- xf86XVUpdateCompositeClip(portPriv);
-
- /* translate the video region to the screen */
- WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
- WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
- WinBox.x2 = WinBox.x1 + portPriv->drw_w;
- WinBox.y2 = WinBox.y1 + portPriv->drw_h;
-
- /* clip to the window composite clip */
- REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
- REGION_NULL(pScreen, &ClipRegion);
- REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, portPriv->pCompositeClip);
-
- /* clip and translate to the viewport */
- if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
- RegionRec VPReg;
- BoxRec VPBox;
-
- VPBox.x1 = portPriv->pScrn->frameX0;
- VPBox.y1 = portPriv->pScrn->frameY0;
- VPBox.x2 = portPriv->pScrn->frameX1 + 1;
- VPBox.y2 = portPriv->pScrn->frameY1 + 1;
-
- REGION_INIT(pScreen, &VPReg, &VPBox, 1);
- REGION_INTERSECT(pScreen, &ClipRegion, &ClipRegion, &VPReg);
- REGION_UNINIT(pScreen, &VPReg);
- }
-
- /* that's all if it's totally obscured */
- if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
- clippedAway = TRUE;
- goto CLIP_VIDEO_BAILOUT;
- }
-
- /* bailout if we have to clip but the hardware doesn't support it */
- if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) {
- BoxPtr clipBox = REGION_RECTS(&ClipRegion);
- if( (REGION_NUM_RECTS(&ClipRegion) != 1) ||
- (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) ||
- (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2))
- {
- clippedAway = TRUE;
- goto CLIP_VIDEO_BAILOUT;
- }
- }
-
- if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
- REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
- }
-
- ret = (*portPriv->AdaptorRec->ReputImage)(portPriv->pScrn,
- WinBox.x1, WinBox.y1,
- &ClipRegion, portPriv->DevPriv.ptr,
- portPriv->pDraw);
-
- portPriv->isOn = (ret == Success) ? XV_ON : XV_OFF;
-
-CLIP_VIDEO_BAILOUT:
-
- if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
- (*portPriv->AdaptorRec->StopVideo)(
- portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
- portPriv->isOn = XV_PENDING;
- }
-
- /* This clip was copied and only good for one shot */
- if(!portPriv->FreeCompositeClip)
- portPriv->pCompositeClip = NULL;
-
- REGION_UNINIT(pScreen, &WinRegion);
- REGION_UNINIT(pScreen, &ClipRegion);
-
- return ret;
-}
-
-
-static int
-xf86XVReputAllVideo(WindowPtr pWin, pointer data)
-{
- XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin);
-
- while(WinPriv) {
- if(WinPriv->PortRec->type == XvInputMask)
- xf86XVReputVideo(WinPriv->PortRec);
- else
- xf86XVRegetVideo(WinPriv->PortRec);
- WinPriv = WinPriv->next;
- }
-
- return WT_WALKCHILDREN;
-}
-
-static int
-xf86XVEnlistPortInWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv)
-{
- XF86XVWindowPtr winPriv, PrivRoot;
-
- winPriv = PrivRoot = GET_XF86XV_WINDOW(pWin);
-
- /* Enlist our port in the window private */
- while(winPriv) {
- if(winPriv->PortRec == portPriv) /* we're already listed */
- break;
- winPriv = winPriv->next;
- }
-
- if(!winPriv) {
- winPriv = xcalloc(1, sizeof(XF86XVWindowRec));
- if(!winPriv) return BadAlloc;
- winPriv->PortRec = portPriv;
- winPriv->next = PrivRoot;
- dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey, winPriv);
- }
-
- portPriv->pDraw = (DrawablePtr)pWin;
-
- return Success;
-}
-
-
-static void
-xf86XVRemovePortFromWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv)
-{
- XF86XVWindowPtr winPriv, prevPriv = NULL;
-
- winPriv = GET_XF86XV_WINDOW(pWin);
-
- while(winPriv) {
- if(winPriv->PortRec == portPriv) {
- if(prevPriv)
- prevPriv->next = winPriv->next;
- else
- dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey,
- winPriv->next);
- xfree(winPriv);
- break;
- }
- prevPriv = winPriv;
- winPriv = winPriv->next;
- }
- portPriv->pDraw = NULL;
-}
-
-/**** ScreenRec fields ****/
-
-static Bool
-xf86XVDestroyWindow(WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
- XF86XVWindowPtr tmp, WinPriv = GET_XF86XV_WINDOW(pWin);
- int ret;
-
- while(WinPriv) {
- XvPortRecPrivatePtr pPriv = WinPriv->PortRec;
-
- if(pPriv->isOn > XV_OFF) {
- (*pPriv->AdaptorRec->StopVideo)(
- pPriv->pScrn, pPriv->DevPriv.ptr, TRUE);
- pPriv->isOn = XV_OFF;
- }
-
- pPriv->pDraw = NULL;
- tmp = WinPriv;
- if(WinPriv->pGC) {
- FreeGC(WinPriv->pGC, 0);
- }
- WinPriv = WinPriv->next;
- xfree(tmp);
- }
-
- dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey, NULL);
-
- pScreen->DestroyWindow = ScreenPriv->DestroyWindow;
- ret = (*pScreen->DestroyWindow)(pWin);
- pScreen->DestroyWindow = xf86XVDestroyWindow;
-
- return ret;
-}
-
-
-static void
-xf86XVWindowExposures(WindowPtr pWin, RegionPtr reg1, RegionPtr reg2)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
- XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin);
- XF86XVWindowPtr pPrev;
- XvPortRecPrivatePtr pPriv;
- Bool AreasExposed;
-
- AreasExposed = (WinPriv && reg1 && REGION_NOTEMPTY(pScreen, reg1));
-
- pScreen->WindowExposures = ScreenPriv->WindowExposures;
- (*pScreen->WindowExposures)(pWin, reg1, reg2);
- pScreen->WindowExposures = xf86XVWindowExposures;
-
- /* filter out XClearWindow/Area */
- if (!pWin->valdata) return;
-
- pPrev = NULL;
-
- while(WinPriv) {
- pPriv = WinPriv->PortRec;
-
- /* Reput anyone with a reput function */
-
- switch(pPriv->type) {
- case XvInputMask:
- xf86XVReputVideo(pPriv);
- break;
- case XvOutputMask:
- xf86XVRegetVideo(pPriv);
- break;
- default: /* overlaid still/image*/
- if (pPriv->AdaptorRec->ReputImage)
- xf86XVReputImage(pPriv);
- else if(AreasExposed) {
- XF86XVWindowPtr tmp;
-
- if (pPriv->isOn == XV_ON) {
- (*pPriv->AdaptorRec->StopVideo)(
- pPriv->pScrn, pPriv->DevPriv.ptr, FALSE);
- pPriv->isOn = XV_PENDING;
- }
- pPriv->pDraw = NULL;
-
- if(!pPrev)
- dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey,
- WinPriv->next);
- else
- pPrev->next = WinPriv->next;
- tmp = WinPriv;
- WinPriv = WinPriv->next;
- xfree(tmp);
- continue;
- }
- break;
- }
- pPrev = WinPriv;
- WinPriv = WinPriv->next;
- }
-}
-
-
-static void
-xf86XVClipNotify(WindowPtr pWin, int dx, int dy)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
- XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin);
- XF86XVWindowPtr tmp, pPrev = NULL;
- XvPortRecPrivatePtr pPriv;
- Bool visible = (pWin->visibility == VisibilityUnobscured) ||
- (pWin->visibility == VisibilityPartiallyObscured);
-
- while(WinPriv) {
- pPriv = WinPriv->PortRec;
-
- if(!pPriv) goto next;
-
- if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
- REGION_DESTROY(pScreen, pPriv->pCompositeClip);
-
- pPriv->pCompositeClip = NULL;
-
- if (pPriv->AdaptorRec->ClipNotify)
- (*pPriv->AdaptorRec->ClipNotify)(pPriv->pScrn, pPriv->DevPriv.ptr,
- pWin, dx, dy);
-
- /* Stop everything except images, but stop them too if the
- window isn't visible. But we only remove the images. */
-
- if(pPriv->type || !visible) {
- if(pPriv->isOn == XV_ON) {
- (*pPriv->AdaptorRec->StopVideo)(
- pPriv->pScrn, pPriv->DevPriv.ptr, FALSE);
- pPriv->isOn = XV_PENDING;
- }
-
- if(!pPriv->type) { /* overlaid still/image */
- pPriv->pDraw = NULL;
-
- if(!pPrev)
- dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey,
- WinPriv->next);
- else
- pPrev->next = WinPriv->next;
- tmp = WinPriv;
- WinPriv = WinPriv->next;
- xfree(tmp);
- continue;
- }
- }
-
-next:
- pPrev = WinPriv;
- WinPriv = WinPriv->next;
- }
-
- if(ScreenPriv->ClipNotify) {
- pScreen->ClipNotify = ScreenPriv->ClipNotify;
- (*pScreen->ClipNotify)(pWin, dx, dy);
- pScreen->ClipNotify = xf86XVClipNotify;
- }
-}
-
-
-
-/**** Required XvScreenRec fields ****/
-
-static Bool
-xf86XVCloseScreen(int i, ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
- XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
- XvAdaptorPtr pa;
- int c;
-
- if(!ScreenPriv) return TRUE;
-
- if(ScreenPriv->videoGC) {
- FreeGC(ScreenPriv->videoGC, 0);
- ScreenPriv->videoGC = NULL;
- }
-
- pScreen->DestroyWindow = ScreenPriv->DestroyWindow;
- pScreen->WindowExposures = ScreenPriv->WindowExposures;
- pScreen->ClipNotify = ScreenPriv->ClipNotify;
-
- pScrn->EnterVT = ScreenPriv->EnterVT;
- pScrn->LeaveVT = ScreenPriv->LeaveVT;
- pScrn->AdjustFrame = ScreenPriv->AdjustFrame;
-
- for(c = 0, pa = pxvs->pAdaptors; c < pxvs->nAdaptors; c++, pa++) {
- xf86XVFreeAdaptor(pa);
- }
-
- xfree(pxvs->pAdaptors);
- xfree(ScreenPriv);
- return TRUE;
-}
-
-
-static int
-xf86XVQueryAdaptors(
- ScreenPtr pScreen,
- XvAdaptorPtr *p_pAdaptors,
- int *p_nAdaptors
-){
- XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
-
- *p_nAdaptors = pxvs->nAdaptors;
- *p_pAdaptors = pxvs->pAdaptors;
-
- return (Success);
-}
-
-
-/**** ScrnInfoRec fields ****/
-
-static Bool
-xf86XVEnterVT(int index, int flags)
-{
- ScreenPtr pScreen = screenInfo.screens[index];
- XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
- Bool ret;
-
- ret = (*ScreenPriv->EnterVT)(index, flags);
-
- if(ret) WalkTree(pScreen, xf86XVReputAllVideo, 0);
-
- return ret;
-}
-
-static void
-xf86XVLeaveVT(int index, int flags)
-{
- ScreenPtr pScreen = screenInfo.screens[index];
- XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
- XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
- XvAdaptorPtr pAdaptor;
- XvPortPtr pPort;
- XvPortRecPrivatePtr pPriv;
- int i, j;
-
- for(i = 0; i < pxvs->nAdaptors; i++) {
- pAdaptor = &pxvs->pAdaptors[i];
- for(j = 0; j < pAdaptor->nPorts; j++) {
- pPort = &pAdaptor->pPorts[j];
- pPriv = (XvPortRecPrivatePtr)pPort->devPriv.ptr;
- if(pPriv->isOn > XV_OFF) {
-
- (*pPriv->AdaptorRec->StopVideo)(
- pPriv->pScrn, pPriv->DevPriv.ptr, TRUE);
- pPriv->isOn = XV_OFF;
-
- if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
- REGION_DESTROY(pScreen, pPriv->pCompositeClip);
-
- pPriv->pCompositeClip = NULL;
-
- if(!pPriv->type && pPriv->pDraw) { /* still */
- xf86XVRemovePortFromWindow((WindowPtr)pPriv->pDraw, pPriv);
- }
- }
- }
- }
-
- (*ScreenPriv->LeaveVT)(index, flags);
-}
-
-static void
-xf86XVAdjustFrame(int index, int x, int y, int flags)
-{
- ScrnInfoPtr pScrn = xf86Screens[index];
- ScreenPtr pScreen = pScrn->pScreen;
- XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
- XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
- WindowPtr pWin;
- XvAdaptorPtr pa;
- int c, i;
-
- if(ScreenPriv->AdjustFrame) {
- pScrn->AdjustFrame = ScreenPriv->AdjustFrame;
- (*pScrn->AdjustFrame)(index, x, y, flags);
- pScrn->AdjustFrame = xf86XVAdjustFrame;
- }
-
- for(c = pxvs->nAdaptors, pa = pxvs->pAdaptors; c > 0; c--, pa++) {
- XvPortPtr pPort = pa->pPorts;
- XvPortRecPrivatePtr pPriv;
-
- for(i = pa->nPorts; i > 0; i--, pPort++) {
- pPriv = (XvPortRecPrivatePtr)pPort->devPriv.ptr;
-
- if(!pPriv->type && (pPriv->isOn != XV_OFF)) { /* overlaid still/image */
-
- if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
- REGION_DESTROY(pScreen, pPriv->pCompositeClip);
-
- pPriv->pCompositeClip = NULL;
-
- pWin = (WindowPtr)pPriv->pDraw;
-
- if ((pPriv->AdaptorRec->ReputImage) &&
- ((pWin->visibility == VisibilityUnobscured) ||
- (pWin->visibility == VisibilityPartiallyObscured)))
- {
- xf86XVReputImage(pPriv);
- } else if (pPriv->isOn == XV_ON) {
- (*pPriv->AdaptorRec->StopVideo)(
- pPriv->pScrn, pPriv->DevPriv.ptr, FALSE);
- xf86XVRemovePortFromWindow(pWin, pPriv);
- pPriv->isOn = XV_PENDING;
- continue;
- }
- }
- }
- }
-}
-
-
-/**** XvAdaptorRec fields ****/
-
-static int
-xf86XVAllocatePort(
- unsigned long port,
- XvPortPtr pPort,
- XvPortPtr *ppPort
-){
- *ppPort = pPort;
- return Success;
-}
-
-
-
-static int
-xf86XVFreePort(XvPortPtr pPort)
-{
- return Success;
-}
-
-
-static int
-xf86XVPutVideo(
- ClientPtr client,
- DrawablePtr pDraw,
- XvPortPtr pPort,
- GCPtr pGC,
- INT16 vid_x, INT16 vid_y,
- CARD16 vid_w, CARD16 vid_h,
- INT16 drw_x, INT16 drw_y,
- CARD16 drw_w, CARD16 drw_h
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
- int result;
-
- /* No dumping video to pixmaps... For now anyhow */
- if(pDraw->type != DRAWABLE_WINDOW) {
- pPort->pDraw = (DrawablePtr)NULL;
- return BadAlloc;
- }
-
- /* If we are changing windows, unregister our port in the old window */
- if(portPriv->pDraw && (portPriv->pDraw != pDraw))
- xf86XVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
-
- /* Register our port with the new window */
- result = xf86XVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
- if(result != Success) return result;
-
- portPriv->type = XvInputMask;
-
- /* save a copy of these parameters */
- portPriv->vid_x = vid_x; portPriv->vid_y = vid_y;
- portPriv->vid_w = vid_w; portPriv->vid_h = vid_h;
- portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
- portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
-
- /* make sure we have the most recent copy of the clientClip */
- xf86XVCopyClip(portPriv, pGC);
-
- /* To indicate to the DI layer that we were successful */
- pPort->pDraw = pDraw;
-
- if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
-
- return(xf86XVReputVideo(portPriv));
-}
-
-static int
-xf86XVPutStill(
- ClientPtr client,
- DrawablePtr pDraw,
- XvPortPtr pPort,
- GCPtr pGC,
- INT16 vid_x, INT16 vid_y,
- CARD16 vid_w, CARD16 vid_h,
- INT16 drw_x, INT16 drw_y,
- CARD16 drw_w, CARD16 drw_h
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
- ScreenPtr pScreen;
- RegionRec WinRegion;
- RegionRec ClipRegion;
- BoxRec WinBox;
- int ret = Success;
- Bool clippedAway = FALSE;
-
- if (pDraw->type != DRAWABLE_WINDOW)
- return BadAlloc;
-
- if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
-
- pScreen = pDraw->pScreen;
-
- WinBox.x1 = pDraw->x + drw_x;
- WinBox.y1 = pDraw->y + drw_y;
- WinBox.x2 = WinBox.x1 + drw_w;
- WinBox.y2 = WinBox.y1 + drw_h;
-
- REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
- REGION_NULL(pScreen, &ClipRegion);
- REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, pGC->pCompositeClip);
-
- if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
- RegionRec VPReg;
- BoxRec VPBox;
-
- VPBox.x1 = portPriv->pScrn->frameX0;
- VPBox.y1 = portPriv->pScrn->frameY0;
- VPBox.x2 = portPriv->pScrn->frameX1 + 1;
- VPBox.y2 = portPriv->pScrn->frameY1 + 1;
-
- REGION_INIT(pScreen, &VPReg, &VPBox, 1);
- REGION_INTERSECT(pScreen, &ClipRegion, &ClipRegion, &VPReg);
- REGION_UNINIT(pScreen, &VPReg);
- }
-
- if(portPriv->pDraw) {
- xf86XVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
- }
-
- if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
- clippedAway = TRUE;
- goto PUT_STILL_BAILOUT;
- }
-
- if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) {
- BoxPtr clipBox = REGION_RECTS(&ClipRegion);
- if( (REGION_NUM_RECTS(&ClipRegion) != 1) ||
- (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) ||
- (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2))
- {
- clippedAway = TRUE;
- goto PUT_STILL_BAILOUT;
- }
- }
-
- if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
- REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
- }
-
- ret = (*portPriv->AdaptorRec->PutStill)(portPriv->pScrn,
- vid_x, vid_y, WinBox.x1, WinBox.y1,
- vid_w, vid_h, drw_w, drw_h,
- &ClipRegion, portPriv->DevPriv.ptr,
- pDraw);
-
- if((ret == Success) &&
- (portPriv->AdaptorRec->flags & VIDEO_OVERLAID_STILLS)) {
-
- xf86XVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
- portPriv->isOn = XV_ON;
- portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
- portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
- portPriv->type = 0; /* no mask means it's transient and should
- not be reput once it's removed */
- pPort->pDraw = pDraw; /* make sure we can get stop requests */
- }
-
-PUT_STILL_BAILOUT:
-
- if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
- (*portPriv->AdaptorRec->StopVideo)(
- portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
- portPriv->isOn = XV_PENDING;
- }
-
- REGION_UNINIT(pScreen, &WinRegion);
- REGION_UNINIT(pScreen, &ClipRegion);
-
- return ret;
-}
-
-static int
-xf86XVGetVideo(
- ClientPtr client,
- DrawablePtr pDraw,
- XvPortPtr pPort,
- GCPtr pGC,
- INT16 vid_x, INT16 vid_y,
- CARD16 vid_w, CARD16 vid_h,
- INT16 drw_x, INT16 drw_y,
- CARD16 drw_w, CARD16 drw_h
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
- int result;
-
- /* No pixmaps... For now anyhow */
- if(pDraw->type != DRAWABLE_WINDOW) {
- pPort->pDraw = (DrawablePtr)NULL;
- return BadAlloc;
- }
-
- /* If we are changing windows, unregister our port in the old window */
- if(portPriv->pDraw && (portPriv->pDraw != pDraw))
- xf86XVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
-
- /* Register our port with the new window */
- result = xf86XVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
- if(result != Success) return result;
-
- portPriv->type = XvOutputMask;
-
- /* save a copy of these parameters */
- portPriv->vid_x = vid_x; portPriv->vid_y = vid_y;
- portPriv->vid_w = vid_w; portPriv->vid_h = vid_h;
- portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
- portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
-
- /* make sure we have the most recent copy of the clientClip */
- xf86XVCopyClip(portPriv, pGC);
-
- /* To indicate to the DI layer that we were successful */
- pPort->pDraw = pDraw;
-
- if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
-
- return(xf86XVRegetVideo(portPriv));
-}
-
-static int
-xf86XVGetStill(
- ClientPtr client,
- DrawablePtr pDraw,
- XvPortPtr pPort,
- GCPtr pGC,
- INT16 vid_x, INT16 vid_y,
- CARD16 vid_w, CARD16 vid_h,
- INT16 drw_x, INT16 drw_y,
- CARD16 drw_w, CARD16 drw_h
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
- ScreenPtr pScreen;
- RegionRec WinRegion;
- RegionRec ClipRegion;
- BoxRec WinBox;
- int ret = Success;
- Bool clippedAway = FALSE;
-
- if (pDraw->type != DRAWABLE_WINDOW)
- return BadAlloc;
-
- if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
-
- pScreen = pDraw->pScreen;
-
- WinBox.x1 = pDraw->x + drw_x;
- WinBox.y1 = pDraw->y + drw_y;
- WinBox.x2 = WinBox.x1 + drw_w;
- WinBox.y2 = WinBox.y1 + drw_h;
-
- REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
- REGION_NULL(pScreen, &ClipRegion);
- REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, pGC->pCompositeClip);
-
- if(portPriv->pDraw) {
- xf86XVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
- }
-
- if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
- clippedAway = TRUE;
- goto GET_STILL_BAILOUT;
- }
-
- if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
- REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
- }
-
- ret = (*portPriv->AdaptorRec->GetStill)(portPriv->pScrn,
- vid_x, vid_y, WinBox.x1, WinBox.y1,
- vid_w, vid_h, drw_w, drw_h,
- &ClipRegion, portPriv->DevPriv.ptr,
- pDraw);
-
-GET_STILL_BAILOUT:
-
- if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
- (*portPriv->AdaptorRec->StopVideo)(
- portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
- portPriv->isOn = XV_PENDING;
- }
-
- REGION_UNINIT(pScreen, &WinRegion);
- REGION_UNINIT(pScreen, &ClipRegion);
-
- return ret;
-}
-
-
-
-static int
-xf86XVStopVideo(
- ClientPtr client,
- XvPortPtr pPort,
- DrawablePtr pDraw
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
-
- if(pDraw->type != DRAWABLE_WINDOW)
- return BadAlloc;
-
- xf86XVRemovePortFromWindow((WindowPtr)pDraw, portPriv);
-
- if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
-
- /* Must free resources. */
-
- if(portPriv->isOn > XV_OFF) {
- (*portPriv->AdaptorRec->StopVideo)(
- portPriv->pScrn, portPriv->DevPriv.ptr, TRUE);
- portPriv->isOn = XV_OFF;
- }
-
- return Success;
-}
-
-static int
-xf86XVSetPortAttribute(
- ClientPtr client,
- XvPortPtr pPort,
- Atom attribute,
- INT32 value
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
-
- return((*portPriv->AdaptorRec->SetPortAttribute)(portPriv->pScrn,
- attribute, value, portPriv->DevPriv.ptr));
-}
-
-
-static int
-xf86XVGetPortAttribute(
- ClientPtr client,
- XvPortPtr pPort,
- Atom attribute,
- INT32 *p_value
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
-
- return((*portPriv->AdaptorRec->GetPortAttribute)(portPriv->pScrn,
- attribute, p_value, portPriv->DevPriv.ptr));
-}
-
-
-
-static int
-xf86XVQueryBestSize(
- ClientPtr client,
- XvPortPtr pPort,
- CARD8 motion,
- CARD16 vid_w, CARD16 vid_h,
- CARD16 drw_w, CARD16 drw_h,
- unsigned int *p_w, unsigned int *p_h
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
-
- (*portPriv->AdaptorRec->QueryBestSize)(portPriv->pScrn,
- (Bool)motion, vid_w, vid_h, drw_w, drw_h,
- p_w, p_h, portPriv->DevPriv.ptr);
-
- return Success;
-}
-
-
-static int
-xf86XVPutImage(
- ClientPtr client,
- DrawablePtr pDraw,
- XvPortPtr pPort,
- GCPtr pGC,
- INT16 src_x, INT16 src_y,
- CARD16 src_w, CARD16 src_h,
- INT16 drw_x, INT16 drw_y,
- CARD16 drw_w, CARD16 drw_h,
- XvImagePtr format,
- unsigned char* data,
- Bool sync,
- CARD16 width, CARD16 height
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
- ScreenPtr pScreen;
- RegionRec WinRegion;
- RegionRec ClipRegion;
- BoxRec WinBox;
- int ret = Success;
- Bool clippedAway = FALSE;
-
- if (pDraw->type != DRAWABLE_WINDOW)
- return BadAlloc;
-
- if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
-
- pScreen = pDraw->pScreen;
-
- WinBox.x1 = pDraw->x + drw_x;
- WinBox.y1 = pDraw->y + drw_y;
- WinBox.x2 = WinBox.x1 + drw_w;
- WinBox.y2 = WinBox.y1 + drw_h;
-
- REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
- REGION_NULL(pScreen, &ClipRegion);
- REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, pGC->pCompositeClip);
-
- if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
- RegionRec VPReg;
- BoxRec VPBox;
-
- VPBox.x1 = portPriv->pScrn->frameX0;
- VPBox.y1 = portPriv->pScrn->frameY0;
- VPBox.x2 = portPriv->pScrn->frameX1 + 1;
- VPBox.y2 = portPriv->pScrn->frameY1 + 1;
-
- REGION_INIT(pScreen, &VPReg, &VPBox, 1);
- REGION_INTERSECT(pScreen, &ClipRegion, &ClipRegion, &VPReg);
- REGION_UNINIT(pScreen, &VPReg);
- }
-
- /* If we are changing windows, unregister our port in the old window */
- if(portPriv->pDraw && (portPriv->pDraw != pDraw))
- xf86XVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
-
- /* Register our port with the new window */
- ret = xf86XVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
- if(ret != Success) goto PUT_IMAGE_BAILOUT;
-
- if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
- clippedAway = TRUE;
- goto PUT_IMAGE_BAILOUT;
- }
-
- if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) {
- BoxPtr clipBox = REGION_RECTS(&ClipRegion);
- if( (REGION_NUM_RECTS(&ClipRegion) != 1) ||
- (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) ||
- (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2))
- {
- clippedAway = TRUE;
- goto PUT_IMAGE_BAILOUT;
- }
- }
-
- if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
- REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
- }
-
- ret = (*portPriv->AdaptorRec->PutImage)(portPriv->pScrn,
- src_x, src_y, WinBox.x1, WinBox.y1,
- src_w, src_h, drw_w, drw_h, format->id, data, width, height,
- sync, &ClipRegion, portPriv->DevPriv.ptr,
- pDraw);
-
- if((ret == Success) &&
- (portPriv->AdaptorRec->flags & VIDEO_OVERLAID_IMAGES)) {
-
- portPriv->isOn = XV_ON;
- portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
- portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
- portPriv->type = 0; /* no mask means it's transient and should
- not be reput once it's removed */
- pPort->pDraw = pDraw; /* make sure we can get stop requests */
- }
-
-PUT_IMAGE_BAILOUT:
-
- if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
- (*portPriv->AdaptorRec->StopVideo)(
- portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
- portPriv->isOn = XV_PENDING;
- }
-
- REGION_UNINIT(pScreen, &WinRegion);
- REGION_UNINIT(pScreen, &ClipRegion);
-
- return ret;
-}
-
-
-static int
-xf86XVQueryImageAttributes(
- ClientPtr client,
- XvPortPtr pPort,
- XvImagePtr format,
- CARD16 *width,
- CARD16 *height,
- int *pitches,
- int *offsets
-){
- XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
-
- return (*portPriv->AdaptorRec->QueryImageAttributes)(portPriv->pScrn,
- format->id, width, height, pitches, offsets);
-}
-
-
-void
-xf86XVFillKeyHelperDrawable (DrawablePtr pDraw, CARD32 key, RegionPtr clipboxes)
-{
- ScreenPtr pScreen = pDraw->pScreen;
- WindowPtr pWin = (WindowPtr)pDraw;
- XF86XVWindowPtr pPriv = GET_XF86XV_WINDOW(pWin);
- GCPtr pGC = NULL;
- XID pval[2];
- BoxPtr pbox = REGION_RECTS(clipboxes);
- int i, nbox = REGION_NUM_RECTS(clipboxes);
- xRectangle *rects;
-
- if(!xf86Screens[pScreen->myNum]->vtSema) return;
-
- if(pPriv)
- pGC = pPriv->pGC;
-
- if(!pGC) {
- int status;
- pval[0] = key;
- pval[1] = IncludeInferiors;
- pGC = CreateGC(pDraw, GCForeground | GCSubwindowMode, pval, &status,
- (XID)0, serverClient);
- if(!pGC) return;
- ValidateGC(pDraw, pGC);
- if (pPriv) pPriv->pGC = pGC;
- } else if (key != pGC->fgPixel){
- pval[0] = key;
- ChangeGC(pGC, GCForeground, pval);
- ValidateGC(pDraw, pGC);
- }
-
- REGION_TRANSLATE(pDraw->pScreen, clipboxes, -pDraw->x, -pDraw->y);
-
- rects = xalloc(nbox * sizeof(xRectangle));
-
- for(i = 0; i < nbox; i++, pbox++) {
- rects[i].x = pbox->x1;
- rects[i].y = pbox->y1;
- rects[i].width = pbox->x2 - pbox->x1;
- rects[i].height = pbox->y2 - pbox->y1;
- }
-
- (*pGC->ops->PolyFillRect)(pDraw, pGC, nbox, rects);
-
- if (!pPriv) FreeGC(pGC, 0);
-
- xfree(rects);
-}
-
-void
-xf86XVFillKeyHelper (ScreenPtr pScreen, CARD32 key, RegionPtr clipboxes)
-{
- DrawablePtr root = &WindowTable[pScreen->myNum]->drawable;
- XID pval[2];
- BoxPtr pbox = REGION_RECTS(clipboxes);
- int i, nbox = REGION_NUM_RECTS(clipboxes);
- xRectangle *rects;
- GCPtr gc;
-
- if(!xf86Screens[pScreen->myNum]->vtSema) return;
-
- gc = GetScratchGC(root->depth, pScreen);
- pval[0] = key;
- pval[1] = IncludeInferiors;
- (void) ChangeGC(gc, GCForeground|GCSubwindowMode, pval);
- ValidateGC(root, gc);
-
- rects = xalloc (nbox * sizeof(xRectangle));
-
- for(i = 0; i < nbox; i++, pbox++)
- {
- rects[i].x = pbox->x1;
- rects[i].y = pbox->y1;
- rects[i].width = pbox->x2 - pbox->x1;
- rects[i].height = pbox->y2 - pbox->y1;
- }
-
- (*gc->ops->PolyFillRect)(root, gc, nbox, rects);
-
- xfree (rects);
- FreeScratchGC (gc);
-}
-
-/* xf86XVClipVideoHelper -
-
- Takes the dst box in standard X BoxRec form (top and left
- edges inclusive, bottom and right exclusive). The new dst
- box is returned. The source boundaries are given (x1, y1
- inclusive, x2, y2 exclusive) and returned are the new source
- boundaries in 16.16 fixed point.
-*/
-
-#define DummyScreen screenInfo.screens[0]
-
-Bool
-xf86XVClipVideoHelper(
- BoxPtr dst,
- INT32 *xa,
- INT32 *xb,
- INT32 *ya,
- INT32 *yb,
- RegionPtr reg,
- INT32 width,
- INT32 height
-){
- double xsw, xdw, ysw, ydw;
- INT32 delta;
- BoxPtr extents = REGION_EXTENTS(DummyScreen, reg);
- int diff;
-
- xsw = (*xb - *xa) << 16;
- xdw = dst->x2 - dst->x1;
- ysw = (*yb - *ya) << 16;
- ydw = dst->y2 - dst->y1;
-
- *xa <<= 16; *xb <<= 16;
- *ya <<= 16; *yb <<= 16;
-
- diff = extents->x1 - dst->x1;
- if (diff > 0) {
- dst->x1 = extents->x1;
- *xa += (diff * xsw) / xdw;
- }
- diff = dst->x2 - extents->x2;
- if (diff > 0) {
- dst->x2 = extents->x2;
- *xb -= (diff * xsw) / xdw;
- }
- diff = extents->y1 - dst->y1;
- if (diff > 0) {
- dst->y1 = extents->y1;
- *ya += (diff * ysw) / ydw;
- }
- diff = dst->y2 - extents->y2;
- if (diff > 0) {
- dst->y2 = extents->y2;
- *yb -= (diff * ysw) / ydw;
- }
-
- if (*xa < 0) {
- diff = (((-*xa) * xdw) + xsw - 1) / xsw;
- dst->x1 += diff;
- *xa += (diff * xsw) / xdw;
- }
- delta = *xb - (width << 16);
- if (delta > 0) {
- diff = ((delta * xdw) + xsw - 1) / xsw;
- dst->x2 -= diff;
- *xb -= (diff * xsw) / xdw;
- }
- if (*xa >= *xb) return FALSE;
-
- if (*ya < 0) {
- diff = (((-*ya) * ydw) + ysw - 1) / ysw;
- dst->y1 += diff;
- *ya += (diff * ysw) / ydw;
- }
- delta = *yb - (height << 16);
- if (delta > 0) {
- diff = ((delta * ydw) + ysw - 1) / ysw;
- dst->y2 -= diff;
- *yb -= (diff * ysw) / ydw;
- }
- if (*ya >= *yb) return FALSE;
-
- if ((dst->x1 > extents->x1) || (dst->x2 < extents->x2) ||
- (dst->y1 > extents->y1) || (dst->y2 < extents->y2))
- {
- RegionRec clipReg;
- REGION_INIT(DummyScreen, &clipReg, dst, 1);
- REGION_INTERSECT(DummyScreen, reg, reg, &clipReg);
- REGION_UNINIT(DummyScreen, &clipReg);
- }
- return TRUE;
-}
-
-void
-xf86XVCopyYUV12ToPacked(
- const void *srcy,
- const void *srcv,
- const void *srcu,
- void *dst,
- int srcPitchy,
- int srcPitchuv,
- int dstPitch,
- int h,
- int w
-){
- CARD32 *Dst;
- const CARD8 *Y, *U, *V;
- int i, j;
-
- w >>= 1;
-
- for (j = 0; j < h; j++) {
- Dst = dst;
- Y = srcy; V = srcv; U = srcu;
- i = w;
- while (i >= 4) {
-#if X_BYTE_ORDER == X_LITTLE_ENDIAN
- Dst[0] = Y[0] | (Y[1] << 16) | (U[0] << 8) | (V[0] << 24);
- Dst[1] = Y[2] | (Y[3] << 16) | (U[1] << 8) | (V[1] << 24);
- Dst[2] = Y[4] | (Y[5] << 16) | (U[2] << 8) | (V[2] << 24);
- Dst[3] = Y[6] | (Y[7] << 16) | (U[3] << 8) | (V[3] << 24);
-#else
- /* This assumes a little-endian framebuffer */
- Dst[0] = (Y[0] << 24) | (Y[1] << 8) | (U[0] << 16) | V[0];
- Dst[1] = (Y[2] << 24) | (Y[3] << 8) | (U[1] << 16) | V[1];
- Dst[2] = (Y[4] << 24) | (Y[5] << 8) | (U[2] << 16) | V[2];
- Dst[3] = (Y[6] << 24) | (Y[7] << 8) | (U[3] << 16) | V[3];
-#endif
- Dst += 4; Y += 8; V += 4; U += 4;
- i -= 4;
- }
-
- while (i--) {
-#if X_BYTE_ORDER == X_LITTLE_ENDIAN
- Dst[0] = Y[0] | (Y[1] << 16) | (U[0] << 8) | (V[0] << 24);
-#else
- /* This assumes a little-endian framebuffer */
- Dst[0] = (Y[0] << 24) | (Y[1] << 8) | (U[0] << 16) | V[0];
-#endif
- Dst++; Y += 2; V++; U++;
- }
-
- dst = (CARD8 *)dst + dstPitch;
- srcy = (const CARD8 *)srcy + srcPitchy;
- if (j & 1) {
- srcu = (const CARD8 *)srcu + srcPitchuv;
- srcv = (const CARD8 *)srcv + srcPitchuv;
- }
- }
-}
-
-void
-xf86XVCopyPacked(
- const void *src,
- void *dst,
- int srcPitch,
- int dstPitch,
- int h,
- int w
-){
- const CARD32 *Src;
- CARD32 *Dst;
- int i;
-
- w >>= 1;
- while (--h >= 0) {
- do {
- Dst = dst; Src = src;
- i = w;
- while (i >= 4) {
- Dst[0] = Src[0];
- Dst[1] = Src[1];
- Dst[2] = Src[2];
- Dst[3] = Src[3];
- Dst += 4; Src += 4; i -= 4;
- }
- if (!i) break;
- Dst[0] = Src[0];
- if (i == 1) break;
- Dst[1] = Src[1];
- if (i == 2) break;
- Dst[2] = Src[2];
- } while (0);
-
- src = (const CARD8 *)src + srcPitch;
- dst = (CARD8 *)dst + dstPitch;
- }
-}
+/*
+ * XFree86 Xv DDX written by Mark Vojkovich (markv@valinux.com)
+ */
+/*
+ * Copyright (c) 1998-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "scrnintstr.h"
+#include "regionstr.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "mivalidate.h"
+#include "validate.h"
+#include "resource.h"
+#include "gcstruct.h"
+#include "dixstruct.h"
+
+#include <X11/extensions/Xv.h>
+#include <X11/extensions/Xvproto.h>
+#include "xvdix.h"
+#include "xvmodproc.h"
+
+#include "xf86xvpriv.h"
+
+
+/* XvScreenRec fields */
+
+static Bool xf86XVCloseScreen(int, ScreenPtr);
+static int xf86XVQueryAdaptors(ScreenPtr, XvAdaptorPtr *, int *);
+
+/* XvAdaptorRec fields */
+
+static int xf86XVAllocatePort(unsigned long, XvPortPtr, XvPortPtr*);
+static int xf86XVFreePort(XvPortPtr);
+static int xf86XVPutVideo(ClientPtr, DrawablePtr,XvPortPtr, GCPtr,
+ INT16, INT16, CARD16, CARD16,
+ INT16, INT16, CARD16, CARD16);
+static int xf86XVPutStill(ClientPtr, DrawablePtr,XvPortPtr, GCPtr,
+ INT16, INT16, CARD16, CARD16,
+ INT16, INT16, CARD16, CARD16);
+static int xf86XVGetVideo(ClientPtr, DrawablePtr,XvPortPtr, GCPtr,
+ INT16, INT16, CARD16, CARD16,
+ INT16, INT16, CARD16, CARD16);
+static int xf86XVGetStill(ClientPtr, DrawablePtr,XvPortPtr, GCPtr,
+ INT16, INT16, CARD16, CARD16,
+ INT16, INT16, CARD16, CARD16);
+static int xf86XVStopVideo(ClientPtr, XvPortPtr, DrawablePtr);
+static int xf86XVSetPortAttribute(ClientPtr, XvPortPtr, Atom, INT32);
+static int xf86XVGetPortAttribute(ClientPtr, XvPortPtr, Atom, INT32*);
+static int xf86XVQueryBestSize(ClientPtr, XvPortPtr, CARD8,
+ CARD16, CARD16,CARD16, CARD16,
+ unsigned int*, unsigned int*);
+static int xf86XVPutImage(ClientPtr, DrawablePtr, XvPortPtr, GCPtr,
+ INT16, INT16, CARD16, CARD16,
+ INT16, INT16, CARD16, CARD16,
+ XvImagePtr, unsigned char*, Bool,
+ CARD16, CARD16);
+static int xf86XVQueryImageAttributes(ClientPtr, XvPortPtr, XvImagePtr,
+ CARD16*, CARD16*, int*, int*);
+
+
+/* ScreenRec fields */
+
+static Bool xf86XVDestroyWindow(WindowPtr pWin);
+static void xf86XVWindowExposures(WindowPtr pWin, RegionPtr r1, RegionPtr r2);
+static void xf86XVClipNotify(WindowPtr pWin, int dx, int dy);
+
+/* ScrnInfoRec functions */
+
+static Bool xf86XVEnterVT(int, int);
+static void xf86XVLeaveVT(int, int);
+static void xf86XVAdjustFrame(int index, int x, int y, int flags);
+
+/* misc */
+
+static Bool xf86XVInitAdaptors(ScreenPtr, XF86VideoAdaptorPtr*, int);
+
+
+static int XF86XVWindowKeyIndex;
+static DevPrivateKey XF86XVWindowKey = &XF86XVWindowKeyIndex;
+static int XF86XvScreenKeyIndex;
+DevPrivateKey XF86XvScreenKey = &XF86XvScreenKeyIndex;
+static unsigned long PortResource = 0;
+
+DevPrivateKey (*XvGetScreenKeyProc)(void) = NULL;
+unsigned long (*XvGetRTPortProc)(void) = NULL;
+int (*XvScreenInitProc)(ScreenPtr) = NULL;
+
+#define GET_XV_SCREEN(pScreen) \
+ ((XvScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates, XF86XvScreenKey))
+
+#define GET_XF86XV_SCREEN(pScreen) \
+ ((XF86XVScreenPtr)(GET_XV_SCREEN(pScreen)->devPriv.ptr))
+
+#define GET_XF86XV_WINDOW(pWin) \
+ ((XF86XVWindowPtr)dixLookupPrivate(&(pWin)->devPrivates, XF86XVWindowKey))
+
+static xf86XVInitGenericAdaptorPtr *GenDrivers = NULL;
+static int NumGenDrivers = 0;
+
+int
+xf86XVRegisterGenericAdaptorDriver(
+ xf86XVInitGenericAdaptorPtr InitFunc
+){
+ xf86XVInitGenericAdaptorPtr *newdrivers;
+
+ newdrivers = realloc(GenDrivers, sizeof(xf86XVInitGenericAdaptorPtr) *
+ (1 + NumGenDrivers));
+ if (!newdrivers)
+ return 0;
+ GenDrivers = newdrivers;
+
+ GenDrivers[NumGenDrivers++] = InitFunc;
+
+ return 1;
+}
+
+int
+xf86XVListGenericAdaptors(
+ ScrnInfoPtr pScrn,
+ XF86VideoAdaptorPtr **adaptors
+){
+ int i,j,n,num;
+ XF86VideoAdaptorPtr *DrivAdap,*new;
+
+ num = 0;
+ *adaptors = NULL;
+ /*
+ * The v4l driver registers itself first, but can use surfaces registered
+ * by other drivers. So, call the v4l driver last.
+ */
+ for (i = NumGenDrivers; --i >= 0; ) {
+ DrivAdap = NULL;
+ n = (*GenDrivers[i])(pScrn, &DrivAdap);
+ if (0 == n)
+ continue;
+ new = realloc(*adaptors, sizeof(XF86VideoAdaptorPtr) * (num+n));
+ if (NULL == new)
+ continue;
+ *adaptors = new;
+ for (j = 0; j < n; j++, num++)
+ (*adaptors)[num] = DrivAdap[j];
+ }
+ return num;
+}
+
+
+/**************** Offscreen surface stuff *******************/
+
+typedef struct {
+ XF86OffscreenImagePtr images;
+ int num;
+} OffscreenImageRec;
+
+static int OffscreenPrivateKeyIndex;
+static DevPrivateKey OffscreenPrivateKey = &OffscreenPrivateKeyIndex;
+#define GetOffscreenImage(pScreen) ((OffscreenImageRec *) dixLookupPrivate(&(pScreen)->devPrivates, OffscreenPrivateKey))
+
+Bool
+xf86XVRegisterOffscreenImages(
+ ScreenPtr pScreen,
+ XF86OffscreenImagePtr images,
+ int num
+){
+ OffscreenImageRec *OffscreenImage;
+ /* This function may be called before xf86XVScreenInit, so there's
+ * no better place than this to call dixRequestPrivate to ensure we
+ * have space reserved. After the first call it is a no-op. */
+ if(!dixRequestPrivate(OffscreenPrivateKey, sizeof(OffscreenImageRec)) ||
+ !(OffscreenImage = GetOffscreenImage(pScreen)))
+ /* Every X.org driver assumes this function always succeeds, so
+ * just die on allocation failure. */
+ FatalError("Could not allocate private storage for XV offscreen images.\n");
+
+ OffscreenImage->num = num;
+ OffscreenImage->images = images;
+ return TRUE;
+}
+
+XF86OffscreenImagePtr
+xf86XVQueryOffscreenImages(
+ ScreenPtr pScreen,
+ int *num
+){
+ OffscreenImageRec *OffscreenImage = GetOffscreenImage(pScreen);
+ *num = OffscreenImage->num;
+ return OffscreenImage->images;
+}
+
+
+XF86VideoAdaptorPtr
+xf86XVAllocateVideoAdaptorRec(ScrnInfoPtr pScrn)
+{
+ return calloc(1, sizeof(XF86VideoAdaptorRec));
+}
+
+void
+xf86XVFreeVideoAdaptorRec(XF86VideoAdaptorPtr ptr)
+{
+ free(ptr);
+}
+
+
+Bool
+xf86XVScreenInit(
+ ScreenPtr pScreen,
+ XF86VideoAdaptorPtr *adaptors,
+ int num
+){
+ ScrnInfoPtr pScrn;
+ XF86XVScreenPtr ScreenPriv;
+ XvScreenPtr pxvs;
+
+ if(num <= 0 ||
+ !XvGetScreenKeyProc || !XvGetRTPortProc || !XvScreenInitProc)
+ return FALSE;
+
+ if(Success != (*XvScreenInitProc)(pScreen)) return FALSE;
+
+ XF86XvScreenKey = (*XvGetScreenKeyProc)();
+ PortResource = (*XvGetRTPortProc)();
+
+ pxvs = GET_XV_SCREEN(pScreen);
+
+ /* Anyone initializing the Xv layer must provide these two.
+ The Xv di layer calls them without even checking if they exist! */
+
+ pxvs->ddCloseScreen = xf86XVCloseScreen;
+ pxvs->ddQueryAdaptors = xf86XVQueryAdaptors;
+
+ /* The Xv di layer provides us with a private hook so that we don't
+ have to allocate our own screen private. They also provide
+ a CloseScreen hook so that we don't have to wrap it. I'm not
+ sure that I appreciate that. */
+
+ ScreenPriv = malloc(sizeof(XF86XVScreenRec));
+ pxvs->devPriv.ptr = (pointer)ScreenPriv;
+
+ if(!ScreenPriv) return FALSE;
+
+ pScrn = xf86Screens[pScreen->myNum];
+
+ ScreenPriv->videoGC = NULL; /* for the helper */
+
+ ScreenPriv->DestroyWindow = pScreen->DestroyWindow;
+ ScreenPriv->WindowExposures = pScreen->WindowExposures;
+ ScreenPriv->ClipNotify = pScreen->ClipNotify;
+ ScreenPriv->EnterVT = pScrn->EnterVT;
+ ScreenPriv->LeaveVT = pScrn->LeaveVT;
+ ScreenPriv->AdjustFrame = pScrn->AdjustFrame;
+
+ pScreen->DestroyWindow = xf86XVDestroyWindow;
+ pScreen->WindowExposures = xf86XVWindowExposures;
+ pScreen->ClipNotify = xf86XVClipNotify;
+ pScrn->EnterVT = xf86XVEnterVT;
+ pScrn->LeaveVT = xf86XVLeaveVT;
+ if(pScrn->AdjustFrame)
+ pScrn->AdjustFrame = xf86XVAdjustFrame;
+
+ if(!xf86XVInitAdaptors(pScreen, adaptors, num))
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+xf86XVFreeAdaptor(XvAdaptorPtr pAdaptor)
+{
+ int i;
+
+ free(pAdaptor->name);
+
+ if(pAdaptor->pEncodings) {
+ XvEncodingPtr pEncode = pAdaptor->pEncodings;
+
+ for(i = 0; i < pAdaptor->nEncodings; i++, pEncode++)
+ free(pEncode->name);
+ free(pAdaptor->pEncodings);
+ }
+
+ free(pAdaptor->pFormats);
+
+ if(pAdaptor->pPorts) {
+ XvPortPtr pPort = pAdaptor->pPorts;
+ XvPortRecPrivatePtr pPriv;
+
+ for(i = 0; i < pAdaptor->nPorts; i++, pPort++) {
+ pPriv = (XvPortRecPrivatePtr)pPort->devPriv.ptr;
+ if(pPriv) {
+ if(pPriv->clientClip)
+ REGION_DESTROY(pAdaptor->pScreen, pPriv->clientClip);
+ if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
+ REGION_DESTROY(pAdaptor->pScreen, pPriv->pCompositeClip);
+ free(pPriv);
+ }
+ }
+ free(pAdaptor->pPorts);
+ }
+
+ if(pAdaptor->nAttributes) {
+ XvAttributePtr pAttribute = pAdaptor->pAttributes;
+
+ for(i = 0; i < pAdaptor->nAttributes; i++, pAttribute++)
+ free(pAttribute->name);
+ free(pAdaptor->pAttributes);
+ }
+
+ free(pAdaptor->pImages);
+ free(pAdaptor->devPriv.ptr);
+}
+
+static Bool
+xf86XVInitAdaptors(
+ ScreenPtr pScreen,
+ XF86VideoAdaptorPtr *infoPtr,
+ int number
+) {
+ XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XF86VideoAdaptorPtr adaptorPtr;
+ XvAdaptorPtr pAdaptor, pa;
+ XvAdaptorRecPrivatePtr adaptorPriv;
+ int na, numAdaptor;
+ XvPortRecPrivatePtr portPriv;
+ XvPortPtr pPort, pp;
+ int numPort;
+ XF86AttributePtr attributePtr;
+ XvAttributePtr pAttribute, pat;
+ XF86VideoFormatPtr formatPtr;
+ XvFormatPtr pFormat, pf;
+ int numFormat, totFormat;
+ XF86VideoEncodingPtr encodingPtr;
+ XvEncodingPtr pEncode, pe;
+ XF86ImagePtr imagePtr;
+ XvImagePtr pImage, pi;
+ int numVisuals;
+ VisualPtr pVisual;
+ int i;
+
+ pxvs->nAdaptors = 0;
+ pxvs->pAdaptors = NULL;
+
+ if(!(pAdaptor = calloc(number, sizeof(XvAdaptorRec))))
+ return FALSE;
+
+ for(pa = pAdaptor, na = 0, numAdaptor = 0; na < number; na++, adaptorPtr++) {
+ adaptorPtr = infoPtr[na];
+
+ if(!adaptorPtr->StopVideo || !adaptorPtr->SetPortAttribute ||
+ !adaptorPtr->GetPortAttribute || !adaptorPtr->QueryBestSize)
+ continue;
+
+ /* client libs expect at least one encoding */
+ if(!adaptorPtr->nEncodings || !adaptorPtr->pEncodings)
+ continue;
+
+ pa->type = adaptorPtr->type;
+
+ if(!adaptorPtr->PutVideo && !adaptorPtr->GetVideo)
+ pa->type &= ~XvVideoMask;
+
+ if(!adaptorPtr->PutStill && !adaptorPtr->GetStill)
+ pa->type &= ~XvStillMask;
+
+ if(!adaptorPtr->PutImage || !adaptorPtr->QueryImageAttributes)
+ pa->type &= ~XvImageMask;
+
+ if(!adaptorPtr->PutVideo && !adaptorPtr->PutImage &&
+ !adaptorPtr->PutStill)
+ pa->type &= ~XvInputMask;
+
+ if(!adaptorPtr->GetVideo && !adaptorPtr->GetStill)
+ pa->type &= ~XvOutputMask;
+
+ if(!(adaptorPtr->type & (XvPixmapMask | XvWindowMask)))
+ continue;
+ if(!(adaptorPtr->type & (XvImageMask | XvVideoMask | XvStillMask)))
+ continue;
+
+ pa->pScreen = pScreen;
+ pa->ddAllocatePort = xf86XVAllocatePort;
+ pa->ddFreePort = xf86XVFreePort;
+ pa->ddPutVideo = xf86XVPutVideo;
+ pa->ddPutStill = xf86XVPutStill;
+ pa->ddGetVideo = xf86XVGetVideo;
+ pa->ddGetStill = xf86XVGetStill;
+ pa->ddStopVideo = xf86XVStopVideo;
+ pa->ddPutImage = xf86XVPutImage;
+ pa->ddSetPortAttribute = xf86XVSetPortAttribute;
+ pa->ddGetPortAttribute = xf86XVGetPortAttribute;
+ pa->ddQueryBestSize = xf86XVQueryBestSize;
+ pa->ddQueryImageAttributes = xf86XVQueryImageAttributes;
+ if((pa->name = malloc(strlen(adaptorPtr->name) + 1)))
+ strcpy(pa->name, adaptorPtr->name);
+
+ if(adaptorPtr->nEncodings &&
+ (pEncode = calloc(adaptorPtr->nEncodings, sizeof(XvEncodingRec)))) {
+
+ for(pe = pEncode, encodingPtr = adaptorPtr->pEncodings, i = 0;
+ i < adaptorPtr->nEncodings; pe++, i++, encodingPtr++)
+ {
+ pe->id = encodingPtr->id;
+ pe->pScreen = pScreen;
+ if((pe->name = malloc(strlen(encodingPtr->name) + 1)))
+ strcpy(pe->name, encodingPtr->name);
+ pe->width = encodingPtr->width;
+ pe->height = encodingPtr->height;
+ pe->rate.numerator = encodingPtr->rate.numerator;
+ pe->rate.denominator = encodingPtr->rate.denominator;
+ }
+ pa->nEncodings = adaptorPtr->nEncodings;
+ pa->pEncodings = pEncode;
+ }
+
+ if(adaptorPtr->nImages &&
+ (pImage = calloc(adaptorPtr->nImages, sizeof(XvImageRec)))) {
+
+ for(i = 0, pi = pImage, imagePtr = adaptorPtr->pImages;
+ i < adaptorPtr->nImages; i++, pi++, imagePtr++)
+ {
+ pi->id = imagePtr->id;
+ pi->type = imagePtr->type;
+ pi->byte_order = imagePtr->byte_order;
+ memcpy(pi->guid, imagePtr->guid, 16);
+ pi->bits_per_pixel = imagePtr->bits_per_pixel;
+ pi->format = imagePtr->format;
+ pi->num_planes = imagePtr->num_planes;
+ pi->depth = imagePtr->depth;
+ pi->red_mask = imagePtr->red_mask;
+ pi->green_mask = imagePtr->green_mask;
+ pi->blue_mask = imagePtr->blue_mask;
+ pi->y_sample_bits = imagePtr->y_sample_bits;
+ pi->u_sample_bits = imagePtr->u_sample_bits;
+ pi->v_sample_bits = imagePtr->v_sample_bits;
+ pi->horz_y_period = imagePtr->horz_y_period;
+ pi->horz_u_period = imagePtr->horz_u_period;
+ pi->horz_v_period = imagePtr->horz_v_period;
+ pi->vert_y_period = imagePtr->vert_y_period;
+ pi->vert_u_period = imagePtr->vert_u_period;
+ pi->vert_v_period = imagePtr->vert_v_period;
+ memcpy(pi->component_order, imagePtr->component_order, 32);
+ pi->scanline_order = imagePtr->scanline_order;
+ }
+ pa->nImages = adaptorPtr->nImages;
+ pa->pImages = pImage;
+ }
+
+ if(adaptorPtr->nAttributes &&
+ (pAttribute = calloc(adaptorPtr->nAttributes, sizeof(XvAttributeRec))))
+ {
+ for(pat = pAttribute, attributePtr = adaptorPtr->pAttributes, i = 0;
+ i < adaptorPtr->nAttributes; pat++, i++, attributePtr++)
+ {
+ pat->flags = attributePtr->flags;
+ pat->min_value = attributePtr->min_value;
+ pat->max_value = attributePtr->max_value;
+ if((pat->name = malloc(strlen(attributePtr->name) + 1)))
+ strcpy(pat->name, attributePtr->name);
+ }
+ pa->nAttributes = adaptorPtr->nAttributes;
+ pa->pAttributes = pAttribute;
+ }
+
+
+ totFormat = adaptorPtr->nFormats;
+
+ if(!(pFormat = calloc(totFormat, sizeof(XvFormatRec)))) {
+ xf86XVFreeAdaptor(pa);
+ continue;
+ }
+ for(pf = pFormat, i = 0, numFormat = 0, formatPtr = adaptorPtr->pFormats;
+ i < adaptorPtr->nFormats; i++, formatPtr++)
+ {
+ numVisuals = pScreen->numVisuals;
+ pVisual = pScreen->visuals;
+
+ while(numVisuals--) {
+ if((pVisual->class == formatPtr->class) &&
+ (pVisual->nplanes == formatPtr->depth)) {
+
+ if(numFormat >= totFormat) {
+ void *moreSpace;
+ totFormat *= 2;
+ moreSpace = realloc(pFormat,
+ totFormat * sizeof(XvFormatRec));
+ if(!moreSpace) break;
+ pFormat = moreSpace;
+ pf = pFormat + numFormat;
+ }
+
+ pf->visual = pVisual->vid;
+ pf->depth = formatPtr->depth;
+
+ pf++;
+ numFormat++;
+ }
+ pVisual++;
+ }
+ }
+ pa->nFormats = numFormat;
+ pa->pFormats = pFormat;
+ if(!numFormat) {
+ xf86XVFreeAdaptor(pa);
+ continue;
+ }
+
+ if(!(adaptorPriv = calloc(1, sizeof(XvAdaptorRecPrivate)))) {
+ xf86XVFreeAdaptor(pa);
+ continue;
+ }
+
+ adaptorPriv->flags = adaptorPtr->flags;
+ adaptorPriv->PutVideo = adaptorPtr->PutVideo;
+ adaptorPriv->PutStill = adaptorPtr->PutStill;
+ adaptorPriv->GetVideo = adaptorPtr->GetVideo;
+ adaptorPriv->GetStill = adaptorPtr->GetStill;
+ adaptorPriv->StopVideo = adaptorPtr->StopVideo;
+ adaptorPriv->SetPortAttribute = adaptorPtr->SetPortAttribute;
+ adaptorPriv->GetPortAttribute = adaptorPtr->GetPortAttribute;
+ adaptorPriv->QueryBestSize = adaptorPtr->QueryBestSize;
+ adaptorPriv->QueryImageAttributes = adaptorPtr->QueryImageAttributes;
+ adaptorPriv->PutImage = adaptorPtr->PutImage;
+ adaptorPriv->ReputImage = adaptorPtr->ReputImage;
+
+ pa->devPriv.ptr = (pointer)adaptorPriv;
+
+ if(!(pPort = calloc(adaptorPtr->nPorts, sizeof(XvPortRec)))) {
+ xf86XVFreeAdaptor(pa);
+ continue;
+ }
+ for(pp = pPort, i = 0, numPort = 0;
+ i < adaptorPtr->nPorts; i++) {
+
+ if(!(pp->id = FakeClientID(0)))
+ continue;
+
+ if(!(portPriv = calloc(1, sizeof(XvPortRecPrivate))))
+ continue;
+
+ if(!AddResource(pp->id, PortResource, pp)) {
+ free(portPriv);
+ continue;
+ }
+
+ pp->pAdaptor = pa;
+ pp->pNotify = (XvPortNotifyPtr)NULL;
+ pp->pDraw = (DrawablePtr)NULL;
+ pp->client = (ClientPtr)NULL;
+ pp->grab.client = (ClientPtr)NULL;
+ pp->time = currentTime;
+ pp->devPriv.ptr = portPriv;
+
+ portPriv->pScrn = pScrn;
+ portPriv->AdaptorRec = adaptorPriv;
+ portPriv->DevPriv.ptr = adaptorPtr->pPortPrivates[i].ptr;
+
+ pp++;
+ numPort++;
+ }
+ pa->nPorts = numPort;
+ pa->pPorts = pPort;
+ if(!numPort) {
+ xf86XVFreeAdaptor(pa);
+ continue;
+ }
+
+ pa->base_id = pPort->id;
+
+ pa++;
+ numAdaptor++;
+ }
+
+ if(numAdaptor) {
+ pxvs->nAdaptors = numAdaptor;
+ pxvs->pAdaptors = pAdaptor;
+ } else {
+ free(pAdaptor);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Video should be clipped to the intersection of the window cliplist
+ and the client cliplist specified in the GC for which the video was
+ initialized. When we need to reclip a window, the GC that started
+ the video may not even be around anymore. That's why we save the
+ client clip from the GC when the video is initialized. We then
+ use xf86XVUpdateCompositeClip to calculate the new composite clip
+ when we need it. This is different from what DEC did. They saved
+ the GC and used it's clip list when they needed to reclip the window,
+ even if the client clip was different from the one the video was
+ initialized with. If the original GC was destroyed, they had to stop
+ the video. I like the new method better (MArk).
+
+ This function only works for windows. Will need to rewrite when
+ (if) we support pixmap rendering.
+*/
+
+static void
+xf86XVUpdateCompositeClip(XvPortRecPrivatePtr portPriv)
+{
+ RegionPtr pregWin, pCompositeClip;
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ Bool freeCompClip = FALSE;
+
+ if(portPriv->pCompositeClip)
+ return;
+
+ pWin = (WindowPtr)portPriv->pDraw;
+ pScreen = pWin->drawable.pScreen;
+
+ /* get window clip list */
+ if(portPriv->subWindowMode == IncludeInferiors) {
+ pregWin = NotClippedByChildren(pWin);
+ freeCompClip = TRUE;
+ } else
+ pregWin = &pWin->clipList;
+
+ if(!portPriv->clientClip) {
+ portPriv->pCompositeClip = pregWin;
+ portPriv->FreeCompositeClip = freeCompClip;
+ return;
+ }
+
+ pCompositeClip = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_COPY(pScreen, pCompositeClip, portPriv->clientClip);
+ REGION_TRANSLATE(pScreen, pCompositeClip,
+ portPriv->pDraw->x + portPriv->clipOrg.x,
+ portPriv->pDraw->y + portPriv->clipOrg.y);
+ REGION_INTERSECT(pScreen, pCompositeClip, pregWin, pCompositeClip);
+
+ portPriv->pCompositeClip = pCompositeClip;
+ portPriv->FreeCompositeClip = TRUE;
+
+ if(freeCompClip) {
+ REGION_DESTROY(pScreen, pregWin);
+ }
+}
+
+/* Save the current clientClip and update the CompositeClip whenever
+ we have a fresh GC */
+
+static void
+xf86XVCopyClip(
+ XvPortRecPrivatePtr portPriv,
+ GCPtr pGC
+){
+ /* copy the new clip if it exists */
+ if((pGC->clientClipType == CT_REGION) && pGC->clientClip) {
+ if(!portPriv->clientClip)
+ portPriv->clientClip = REGION_CREATE(pScreen, NullBox, 1);
+ /* Note: this is in window coordinates */
+ REGION_COPY(pScreen, portPriv->clientClip, pGC->clientClip);
+ } else if(portPriv->clientClip) { /* free the old clientClip */
+ REGION_DESTROY(pScreen, portPriv->clientClip);
+ portPriv->clientClip = NULL;
+ }
+
+ /* get rid of the old clip list */
+ if(portPriv->pCompositeClip && portPriv->FreeCompositeClip) {
+ REGION_DESTROY(pScreen, portPriv->pCompositeClip);
+ }
+
+ portPriv->clipOrg = pGC->clipOrg;
+ portPriv->pCompositeClip = pGC->pCompositeClip;
+ portPriv->FreeCompositeClip = FALSE;
+ portPriv->subWindowMode = pGC->subWindowMode;
+}
+
+static int
+xf86XVRegetVideo(XvPortRecPrivatePtr portPriv)
+{
+ RegionRec WinRegion;
+ RegionRec ClipRegion;
+ BoxRec WinBox;
+ ScreenPtr pScreen;
+ int ret = Success;
+ Bool clippedAway = FALSE;
+
+ pScreen = portPriv->pDraw->pScreen;
+ xf86XVUpdateCompositeClip(portPriv);
+
+ /* translate the video region to the screen */
+ WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
+ WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
+ WinBox.x2 = WinBox.x1 + portPriv->drw_w;
+ WinBox.y2 = WinBox.y1 + portPriv->drw_h;
+
+ /* clip to the window composite clip */
+ REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
+ REGION_NULL(pScreen, &ClipRegion);
+ REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, portPriv->pCompositeClip);
+
+ /* that's all if it's totally obscured */
+ if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
+ clippedAway = TRUE;
+ goto CLIP_VIDEO_BAILOUT;
+ }
+
+ if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
+ REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
+ }
+
+ ret = (*portPriv->AdaptorRec->GetVideo)(portPriv->pScrn,
+ portPriv->vid_x, portPriv->vid_y,
+ WinBox.x1, WinBox.y1,
+ portPriv->vid_w, portPriv->vid_h,
+ portPriv->drw_w, portPriv->drw_h,
+ &ClipRegion, portPriv->DevPriv.ptr,
+ portPriv->pDraw);
+
+ if(ret == Success)
+ portPriv->isOn = XV_ON;
+
+CLIP_VIDEO_BAILOUT:
+
+ if((clippedAway || (ret != Success)) && portPriv->isOn == XV_ON) {
+ (*portPriv->AdaptorRec->StopVideo)(
+ portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
+ portPriv->isOn = XV_PENDING;
+ }
+
+ /* This clip was copied and only good for one shot */
+ if(!portPriv->FreeCompositeClip)
+ portPriv->pCompositeClip = NULL;
+
+ REGION_UNINIT(pScreen, &WinRegion);
+ REGION_UNINIT(pScreen, &ClipRegion);
+
+ return ret;
+}
+
+
+static int
+xf86XVReputVideo(XvPortRecPrivatePtr portPriv)
+{
+ RegionRec WinRegion;
+ RegionRec ClipRegion;
+ BoxRec WinBox;
+ ScreenPtr pScreen;
+ int ret = Success;
+ Bool clippedAway = FALSE;
+
+ pScreen = portPriv->pDraw->pScreen;
+
+ xf86XVUpdateCompositeClip(portPriv);
+
+ /* translate the video region to the screen */
+ WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
+ WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
+ WinBox.x2 = WinBox.x1 + portPriv->drw_w;
+ WinBox.y2 = WinBox.y1 + portPriv->drw_h;
+
+ /* clip to the window composite clip */
+ REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
+ REGION_NULL(pScreen, &ClipRegion);
+ REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, portPriv->pCompositeClip);
+
+ /* clip and translate to the viewport */
+ if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
+ RegionRec VPReg;
+ BoxRec VPBox;
+
+ VPBox.x1 = portPriv->pScrn->frameX0;
+ VPBox.y1 = portPriv->pScrn->frameY0;
+ VPBox.x2 = portPriv->pScrn->frameX1 + 1;
+ VPBox.y2 = portPriv->pScrn->frameY1 + 1;
+
+ REGION_INIT(pScreen, &VPReg, &VPBox, 1);
+ REGION_INTERSECT(pScreen, &ClipRegion, &ClipRegion, &VPReg);
+ REGION_UNINIT(pScreen, &VPReg);
+ }
+
+ /* that's all if it's totally obscured */
+ if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
+ clippedAway = TRUE;
+ goto CLIP_VIDEO_BAILOUT;
+ }
+
+ /* bailout if we have to clip but the hardware doesn't support it */
+ if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) {
+ BoxPtr clipBox = REGION_RECTS(&ClipRegion);
+ if( (REGION_NUM_RECTS(&ClipRegion) != 1) ||
+ (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) ||
+ (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2))
+ {
+ clippedAway = TRUE;
+ goto CLIP_VIDEO_BAILOUT;
+ }
+ }
+
+ if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
+ REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
+ }
+
+ ret = (*portPriv->AdaptorRec->PutVideo)(portPriv->pScrn,
+ portPriv->vid_x, portPriv->vid_y,
+ WinBox.x1, WinBox.y1,
+ portPriv->vid_w, portPriv->vid_h,
+ portPriv->drw_w, portPriv->drw_h,
+ &ClipRegion, portPriv->DevPriv.ptr,
+ portPriv->pDraw);
+
+ if(ret == Success) portPriv->isOn = XV_ON;
+
+CLIP_VIDEO_BAILOUT:
+
+ if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
+ (*portPriv->AdaptorRec->StopVideo)(
+ portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
+ portPriv->isOn = XV_PENDING;
+ }
+
+ /* This clip was copied and only good for one shot */
+ if(!portPriv->FreeCompositeClip)
+ portPriv->pCompositeClip = NULL;
+
+ REGION_UNINIT(pScreen, &WinRegion);
+ REGION_UNINIT(pScreen, &ClipRegion);
+
+ return ret;
+}
+
+static int
+xf86XVReputImage(XvPortRecPrivatePtr portPriv)
+{
+ RegionRec WinRegion;
+ RegionRec ClipRegion;
+ BoxRec WinBox;
+ ScreenPtr pScreen;
+ int ret = Success;
+ Bool clippedAway = FALSE;
+
+ pScreen = portPriv->pDraw->pScreen;
+
+ xf86XVUpdateCompositeClip(portPriv);
+
+ /* translate the video region to the screen */
+ WinBox.x1 = portPriv->pDraw->x + portPriv->drw_x;
+ WinBox.y1 = portPriv->pDraw->y + portPriv->drw_y;
+ WinBox.x2 = WinBox.x1 + portPriv->drw_w;
+ WinBox.y2 = WinBox.y1 + portPriv->drw_h;
+
+ /* clip to the window composite clip */
+ REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
+ REGION_NULL(pScreen, &ClipRegion);
+ REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, portPriv->pCompositeClip);
+
+ /* clip and translate to the viewport */
+ if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
+ RegionRec VPReg;
+ BoxRec VPBox;
+
+ VPBox.x1 = portPriv->pScrn->frameX0;
+ VPBox.y1 = portPriv->pScrn->frameY0;
+ VPBox.x2 = portPriv->pScrn->frameX1 + 1;
+ VPBox.y2 = portPriv->pScrn->frameY1 + 1;
+
+ REGION_INIT(pScreen, &VPReg, &VPBox, 1);
+ REGION_INTERSECT(pScreen, &ClipRegion, &ClipRegion, &VPReg);
+ REGION_UNINIT(pScreen, &VPReg);
+ }
+
+ /* that's all if it's totally obscured */
+ if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
+ clippedAway = TRUE;
+ goto CLIP_VIDEO_BAILOUT;
+ }
+
+ /* bailout if we have to clip but the hardware doesn't support it */
+ if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) {
+ BoxPtr clipBox = REGION_RECTS(&ClipRegion);
+ if( (REGION_NUM_RECTS(&ClipRegion) != 1) ||
+ (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) ||
+ (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2))
+ {
+ clippedAway = TRUE;
+ goto CLIP_VIDEO_BAILOUT;
+ }
+ }
+
+ if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
+ REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
+ }
+
+ ret = (*portPriv->AdaptorRec->ReputImage)(portPriv->pScrn,
+ WinBox.x1, WinBox.y1,
+ &ClipRegion, portPriv->DevPriv.ptr,
+ portPriv->pDraw);
+
+ portPriv->isOn = (ret == Success) ? XV_ON : XV_OFF;
+
+CLIP_VIDEO_BAILOUT:
+
+ if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
+ (*portPriv->AdaptorRec->StopVideo)(
+ portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
+ portPriv->isOn = XV_PENDING;
+ }
+
+ /* This clip was copied and only good for one shot */
+ if(!portPriv->FreeCompositeClip)
+ portPriv->pCompositeClip = NULL;
+
+ REGION_UNINIT(pScreen, &WinRegion);
+ REGION_UNINIT(pScreen, &ClipRegion);
+
+ return ret;
+}
+
+
+static int
+xf86XVReputAllVideo(WindowPtr pWin, pointer data)
+{
+ XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin);
+
+ while(WinPriv) {
+ if(WinPriv->PortRec->type == XvInputMask)
+ xf86XVReputVideo(WinPriv->PortRec);
+ else
+ xf86XVRegetVideo(WinPriv->PortRec);
+ WinPriv = WinPriv->next;
+ }
+
+ return WT_WALKCHILDREN;
+}
+
+static int
+xf86XVEnlistPortInWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv)
+{
+ XF86XVWindowPtr winPriv, PrivRoot;
+
+ winPriv = PrivRoot = GET_XF86XV_WINDOW(pWin);
+
+ /* Enlist our port in the window private */
+ while(winPriv) {
+ if(winPriv->PortRec == portPriv) /* we're already listed */
+ break;
+ winPriv = winPriv->next;
+ }
+
+ if(!winPriv) {
+ winPriv = calloc(1, sizeof(XF86XVWindowRec));
+ if(!winPriv) return BadAlloc;
+ winPriv->PortRec = portPriv;
+ winPriv->next = PrivRoot;
+ dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey, winPriv);
+ }
+
+ portPriv->pDraw = (DrawablePtr)pWin;
+
+ return Success;
+}
+
+
+static void
+xf86XVRemovePortFromWindow(WindowPtr pWin, XvPortRecPrivatePtr portPriv)
+{
+ XF86XVWindowPtr winPriv, prevPriv = NULL;
+
+ winPriv = GET_XF86XV_WINDOW(pWin);
+
+ while(winPriv) {
+ if(winPriv->PortRec == portPriv) {
+ if(prevPriv)
+ prevPriv->next = winPriv->next;
+ else
+ dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey,
+ winPriv->next);
+ free(winPriv);
+ break;
+ }
+ prevPriv = winPriv;
+ winPriv = winPriv->next;
+ }
+ portPriv->pDraw = NULL;
+}
+
+/**** ScreenRec fields ****/
+
+static Bool
+xf86XVDestroyWindow(WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
+ XF86XVWindowPtr tmp, WinPriv = GET_XF86XV_WINDOW(pWin);
+ int ret;
+
+ while(WinPriv) {
+ XvPortRecPrivatePtr pPriv = WinPriv->PortRec;
+
+ if(pPriv->isOn > XV_OFF) {
+ (*pPriv->AdaptorRec->StopVideo)(
+ pPriv->pScrn, pPriv->DevPriv.ptr, TRUE);
+ pPriv->isOn = XV_OFF;
+ }
+
+ pPriv->pDraw = NULL;
+ tmp = WinPriv;
+ if(WinPriv->pGC) {
+ FreeGC(WinPriv->pGC, 0);
+ }
+ WinPriv = WinPriv->next;
+ free(tmp);
+ }
+
+ dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey, NULL);
+
+ pScreen->DestroyWindow = ScreenPriv->DestroyWindow;
+ ret = (*pScreen->DestroyWindow)(pWin);
+ pScreen->DestroyWindow = xf86XVDestroyWindow;
+
+ return ret;
+}
+
+
+static void
+xf86XVWindowExposures(WindowPtr pWin, RegionPtr reg1, RegionPtr reg2)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
+ XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin);
+ XF86XVWindowPtr pPrev;
+ XvPortRecPrivatePtr pPriv;
+ Bool AreasExposed;
+
+ AreasExposed = (WinPriv && reg1 && REGION_NOTEMPTY(pScreen, reg1));
+
+ pScreen->WindowExposures = ScreenPriv->WindowExposures;
+ (*pScreen->WindowExposures)(pWin, reg1, reg2);
+ pScreen->WindowExposures = xf86XVWindowExposures;
+
+ /* filter out XClearWindow/Area */
+ if (!pWin->valdata) return;
+
+ pPrev = NULL;
+
+ while(WinPriv) {
+ pPriv = WinPriv->PortRec;
+
+ /* Reput anyone with a reput function */
+
+ switch(pPriv->type) {
+ case XvInputMask:
+ xf86XVReputVideo(pPriv);
+ break;
+ case XvOutputMask:
+ xf86XVRegetVideo(pPriv);
+ break;
+ default: /* overlaid still/image*/
+ if (pPriv->AdaptorRec->ReputImage)
+ xf86XVReputImage(pPriv);
+ else if(AreasExposed) {
+ XF86XVWindowPtr tmp;
+
+ if (pPriv->isOn == XV_ON) {
+ (*pPriv->AdaptorRec->StopVideo)(
+ pPriv->pScrn, pPriv->DevPriv.ptr, FALSE);
+ pPriv->isOn = XV_PENDING;
+ }
+ pPriv->pDraw = NULL;
+
+ if(!pPrev)
+ dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey,
+ WinPriv->next);
+ else
+ pPrev->next = WinPriv->next;
+ tmp = WinPriv;
+ WinPriv = WinPriv->next;
+ free(tmp);
+ continue;
+ }
+ break;
+ }
+ pPrev = WinPriv;
+ WinPriv = WinPriv->next;
+ }
+}
+
+
+static void
+xf86XVClipNotify(WindowPtr pWin, int dx, int dy)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
+ XF86XVWindowPtr WinPriv = GET_XF86XV_WINDOW(pWin);
+ XF86XVWindowPtr tmp, pPrev = NULL;
+ XvPortRecPrivatePtr pPriv;
+ Bool visible = (pWin->visibility == VisibilityUnobscured) ||
+ (pWin->visibility == VisibilityPartiallyObscured);
+
+ while(WinPriv) {
+ pPriv = WinPriv->PortRec;
+
+ if(!pPriv) goto next;
+
+ if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
+ REGION_DESTROY(pScreen, pPriv->pCompositeClip);
+
+ pPriv->pCompositeClip = NULL;
+
+ if (pPriv->AdaptorRec->ClipNotify)
+ (*pPriv->AdaptorRec->ClipNotify)(pPriv->pScrn, pPriv->DevPriv.ptr,
+ pWin, dx, dy);
+
+ /* Stop everything except images, but stop them too if the
+ window isn't visible. But we only remove the images. */
+
+ if(pPriv->type || !visible) {
+ if(pPriv->isOn == XV_ON) {
+ (*pPriv->AdaptorRec->StopVideo)(
+ pPriv->pScrn, pPriv->DevPriv.ptr, FALSE);
+ pPriv->isOn = XV_PENDING;
+ }
+
+ if(!pPriv->type) { /* overlaid still/image */
+ pPriv->pDraw = NULL;
+
+ if(!pPrev)
+ dixSetPrivate(&pWin->devPrivates, XF86XVWindowKey,
+ WinPriv->next);
+ else
+ pPrev->next = WinPriv->next;
+ tmp = WinPriv;
+ WinPriv = WinPriv->next;
+ free(tmp);
+ continue;
+ }
+ }
+
+next:
+ pPrev = WinPriv;
+ WinPriv = WinPriv->next;
+ }
+
+ if(ScreenPriv->ClipNotify) {
+ pScreen->ClipNotify = ScreenPriv->ClipNotify;
+ (*pScreen->ClipNotify)(pWin, dx, dy);
+ pScreen->ClipNotify = xf86XVClipNotify;
+ }
+}
+
+
+
+/**** Required XvScreenRec fields ****/
+
+static Bool
+xf86XVCloseScreen(int i, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
+ XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
+ XvAdaptorPtr pa;
+ int c;
+
+ if(!ScreenPriv) return TRUE;
+
+ if(ScreenPriv->videoGC) {
+ FreeGC(ScreenPriv->videoGC, 0);
+ ScreenPriv->videoGC = NULL;
+ }
+
+ pScreen->DestroyWindow = ScreenPriv->DestroyWindow;
+ pScreen->WindowExposures = ScreenPriv->WindowExposures;
+ pScreen->ClipNotify = ScreenPriv->ClipNotify;
+
+ pScrn->EnterVT = ScreenPriv->EnterVT;
+ pScrn->LeaveVT = ScreenPriv->LeaveVT;
+ pScrn->AdjustFrame = ScreenPriv->AdjustFrame;
+
+ for(c = 0, pa = pxvs->pAdaptors; c < pxvs->nAdaptors; c++, pa++) {
+ xf86XVFreeAdaptor(pa);
+ }
+
+ free(pxvs->pAdaptors);
+ free(ScreenPriv);
+ return TRUE;
+}
+
+
+static int
+xf86XVQueryAdaptors(
+ ScreenPtr pScreen,
+ XvAdaptorPtr *p_pAdaptors,
+ int *p_nAdaptors
+){
+ XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
+
+ *p_nAdaptors = pxvs->nAdaptors;
+ *p_pAdaptors = pxvs->pAdaptors;
+
+ return (Success);
+}
+
+
+/**** ScrnInfoRec fields ****/
+
+static Bool
+xf86XVEnterVT(int index, int flags)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
+ Bool ret;
+
+ ret = (*ScreenPriv->EnterVT)(index, flags);
+
+ if(ret) WalkTree(pScreen, xf86XVReputAllVideo, 0);
+
+ return ret;
+}
+
+static void
+xf86XVLeaveVT(int index, int flags)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
+ XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
+ XvAdaptorPtr pAdaptor;
+ XvPortPtr pPort;
+ XvPortRecPrivatePtr pPriv;
+ int i, j;
+
+ for(i = 0; i < pxvs->nAdaptors; i++) {
+ pAdaptor = &pxvs->pAdaptors[i];
+ for(j = 0; j < pAdaptor->nPorts; j++) {
+ pPort = &pAdaptor->pPorts[j];
+ pPriv = (XvPortRecPrivatePtr)pPort->devPriv.ptr;
+ if(pPriv->isOn > XV_OFF) {
+
+ (*pPriv->AdaptorRec->StopVideo)(
+ pPriv->pScrn, pPriv->DevPriv.ptr, TRUE);
+ pPriv->isOn = XV_OFF;
+
+ if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
+ REGION_DESTROY(pScreen, pPriv->pCompositeClip);
+
+ pPriv->pCompositeClip = NULL;
+
+ if(!pPriv->type && pPriv->pDraw) { /* still */
+ xf86XVRemovePortFromWindow((WindowPtr)pPriv->pDraw, pPriv);
+ }
+ }
+ }
+ }
+
+ (*ScreenPriv->LeaveVT)(index, flags);
+}
+
+static void
+xf86XVAdjustFrame(int index, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[index];
+ ScreenPtr pScreen = pScrn->pScreen;
+ XvScreenPtr pxvs = GET_XV_SCREEN(pScreen);
+ XF86XVScreenPtr ScreenPriv = GET_XF86XV_SCREEN(pScreen);
+ WindowPtr pWin;
+ XvAdaptorPtr pa;
+ int c, i;
+
+ if(ScreenPriv->AdjustFrame) {
+ pScrn->AdjustFrame = ScreenPriv->AdjustFrame;
+ (*pScrn->AdjustFrame)(index, x, y, flags);
+ pScrn->AdjustFrame = xf86XVAdjustFrame;
+ }
+
+ for(c = pxvs->nAdaptors, pa = pxvs->pAdaptors; c > 0; c--, pa++) {
+ XvPortPtr pPort = pa->pPorts;
+ XvPortRecPrivatePtr pPriv;
+
+ for(i = pa->nPorts; i > 0; i--, pPort++) {
+ pPriv = (XvPortRecPrivatePtr)pPort->devPriv.ptr;
+
+ if(!pPriv->type && (pPriv->isOn != XV_OFF)) { /* overlaid still/image */
+
+ if(pPriv->pCompositeClip && pPriv->FreeCompositeClip)
+ REGION_DESTROY(pScreen, pPriv->pCompositeClip);
+
+ pPriv->pCompositeClip = NULL;
+
+ pWin = (WindowPtr)pPriv->pDraw;
+
+ if ((pPriv->AdaptorRec->ReputImage) &&
+ ((pWin->visibility == VisibilityUnobscured) ||
+ (pWin->visibility == VisibilityPartiallyObscured)))
+ {
+ xf86XVReputImage(pPriv);
+ } else if (pPriv->isOn == XV_ON) {
+ (*pPriv->AdaptorRec->StopVideo)(
+ pPriv->pScrn, pPriv->DevPriv.ptr, FALSE);
+ xf86XVRemovePortFromWindow(pWin, pPriv);
+ pPriv->isOn = XV_PENDING;
+ continue;
+ }
+ }
+ }
+ }
+}
+
+
+/**** XvAdaptorRec fields ****/
+
+static int
+xf86XVAllocatePort(
+ unsigned long port,
+ XvPortPtr pPort,
+ XvPortPtr *ppPort
+){
+ *ppPort = pPort;
+ return Success;
+}
+
+
+
+static int
+xf86XVFreePort(XvPortPtr pPort)
+{
+ return Success;
+}
+
+
+static int
+xf86XVPutVideo(
+ ClientPtr client,
+ DrawablePtr pDraw,
+ XvPortPtr pPort,
+ GCPtr pGC,
+ INT16 vid_x, INT16 vid_y,
+ CARD16 vid_w, CARD16 vid_h,
+ INT16 drw_x, INT16 drw_y,
+ CARD16 drw_w, CARD16 drw_h
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+ int result;
+
+ /* No dumping video to pixmaps... For now anyhow */
+ if(pDraw->type != DRAWABLE_WINDOW) {
+ pPort->pDraw = (DrawablePtr)NULL;
+ return BadAlloc;
+ }
+
+ /* If we are changing windows, unregister our port in the old window */
+ if(portPriv->pDraw && (portPriv->pDraw != pDraw))
+ xf86XVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
+
+ /* Register our port with the new window */
+ result = xf86XVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
+ if(result != Success) return result;
+
+ portPriv->type = XvInputMask;
+
+ /* save a copy of these parameters */
+ portPriv->vid_x = vid_x; portPriv->vid_y = vid_y;
+ portPriv->vid_w = vid_w; portPriv->vid_h = vid_h;
+ portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
+ portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
+
+ /* make sure we have the most recent copy of the clientClip */
+ xf86XVCopyClip(portPriv, pGC);
+
+ /* To indicate to the DI layer that we were successful */
+ pPort->pDraw = pDraw;
+
+ if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
+
+ return(xf86XVReputVideo(portPriv));
+}
+
+static int
+xf86XVPutStill(
+ ClientPtr client,
+ DrawablePtr pDraw,
+ XvPortPtr pPort,
+ GCPtr pGC,
+ INT16 vid_x, INT16 vid_y,
+ CARD16 vid_w, CARD16 vid_h,
+ INT16 drw_x, INT16 drw_y,
+ CARD16 drw_w, CARD16 drw_h
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+ ScreenPtr pScreen;
+ RegionRec WinRegion;
+ RegionRec ClipRegion;
+ BoxRec WinBox;
+ int ret = Success;
+ Bool clippedAway = FALSE;
+
+ if (pDraw->type != DRAWABLE_WINDOW)
+ return BadAlloc;
+
+ if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
+
+ pScreen = pDraw->pScreen;
+
+ WinBox.x1 = pDraw->x + drw_x;
+ WinBox.y1 = pDraw->y + drw_y;
+ WinBox.x2 = WinBox.x1 + drw_w;
+ WinBox.y2 = WinBox.y1 + drw_h;
+
+ REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
+ REGION_NULL(pScreen, &ClipRegion);
+ REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, pGC->pCompositeClip);
+
+ if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
+ RegionRec VPReg;
+ BoxRec VPBox;
+
+ VPBox.x1 = portPriv->pScrn->frameX0;
+ VPBox.y1 = portPriv->pScrn->frameY0;
+ VPBox.x2 = portPriv->pScrn->frameX1 + 1;
+ VPBox.y2 = portPriv->pScrn->frameY1 + 1;
+
+ REGION_INIT(pScreen, &VPReg, &VPBox, 1);
+ REGION_INTERSECT(pScreen, &ClipRegion, &ClipRegion, &VPReg);
+ REGION_UNINIT(pScreen, &VPReg);
+ }
+
+ if(portPriv->pDraw) {
+ xf86XVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
+ }
+
+ if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
+ clippedAway = TRUE;
+ goto PUT_STILL_BAILOUT;
+ }
+
+ if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) {
+ BoxPtr clipBox = REGION_RECTS(&ClipRegion);
+ if( (REGION_NUM_RECTS(&ClipRegion) != 1) ||
+ (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) ||
+ (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2))
+ {
+ clippedAway = TRUE;
+ goto PUT_STILL_BAILOUT;
+ }
+ }
+
+ if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
+ REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
+ }
+
+ ret = (*portPriv->AdaptorRec->PutStill)(portPriv->pScrn,
+ vid_x, vid_y, WinBox.x1, WinBox.y1,
+ vid_w, vid_h, drw_w, drw_h,
+ &ClipRegion, portPriv->DevPriv.ptr,
+ pDraw);
+
+ if((ret == Success) &&
+ (portPriv->AdaptorRec->flags & VIDEO_OVERLAID_STILLS)) {
+
+ xf86XVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
+ portPriv->isOn = XV_ON;
+ portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
+ portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
+ portPriv->type = 0; /* no mask means it's transient and should
+ not be reput once it's removed */
+ pPort->pDraw = pDraw; /* make sure we can get stop requests */
+ }
+
+PUT_STILL_BAILOUT:
+
+ if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
+ (*portPriv->AdaptorRec->StopVideo)(
+ portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
+ portPriv->isOn = XV_PENDING;
+ }
+
+ REGION_UNINIT(pScreen, &WinRegion);
+ REGION_UNINIT(pScreen, &ClipRegion);
+
+ return ret;
+}
+
+static int
+xf86XVGetVideo(
+ ClientPtr client,
+ DrawablePtr pDraw,
+ XvPortPtr pPort,
+ GCPtr pGC,
+ INT16 vid_x, INT16 vid_y,
+ CARD16 vid_w, CARD16 vid_h,
+ INT16 drw_x, INT16 drw_y,
+ CARD16 drw_w, CARD16 drw_h
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+ int result;
+
+ /* No pixmaps... For now anyhow */
+ if(pDraw->type != DRAWABLE_WINDOW) {
+ pPort->pDraw = (DrawablePtr)NULL;
+ return BadAlloc;
+ }
+
+ /* If we are changing windows, unregister our port in the old window */
+ if(portPriv->pDraw && (portPriv->pDraw != pDraw))
+ xf86XVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
+
+ /* Register our port with the new window */
+ result = xf86XVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
+ if(result != Success) return result;
+
+ portPriv->type = XvOutputMask;
+
+ /* save a copy of these parameters */
+ portPriv->vid_x = vid_x; portPriv->vid_y = vid_y;
+ portPriv->vid_w = vid_w; portPriv->vid_h = vid_h;
+ portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
+ portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
+
+ /* make sure we have the most recent copy of the clientClip */
+ xf86XVCopyClip(portPriv, pGC);
+
+ /* To indicate to the DI layer that we were successful */
+ pPort->pDraw = pDraw;
+
+ if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
+
+ return(xf86XVRegetVideo(portPriv));
+}
+
+static int
+xf86XVGetStill(
+ ClientPtr client,
+ DrawablePtr pDraw,
+ XvPortPtr pPort,
+ GCPtr pGC,
+ INT16 vid_x, INT16 vid_y,
+ CARD16 vid_w, CARD16 vid_h,
+ INT16 drw_x, INT16 drw_y,
+ CARD16 drw_w, CARD16 drw_h
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+ ScreenPtr pScreen;
+ RegionRec WinRegion;
+ RegionRec ClipRegion;
+ BoxRec WinBox;
+ int ret = Success;
+ Bool clippedAway = FALSE;
+
+ if (pDraw->type != DRAWABLE_WINDOW)
+ return BadAlloc;
+
+ if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
+
+ pScreen = pDraw->pScreen;
+
+ WinBox.x1 = pDraw->x + drw_x;
+ WinBox.y1 = pDraw->y + drw_y;
+ WinBox.x2 = WinBox.x1 + drw_w;
+ WinBox.y2 = WinBox.y1 + drw_h;
+
+ REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
+ REGION_NULL(pScreen, &ClipRegion);
+ REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, pGC->pCompositeClip);
+
+ if(portPriv->pDraw) {
+ xf86XVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
+ }
+
+ if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
+ clippedAway = TRUE;
+ goto GET_STILL_BAILOUT;
+ }
+
+ if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
+ REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
+ }
+
+ ret = (*portPriv->AdaptorRec->GetStill)(portPriv->pScrn,
+ vid_x, vid_y, WinBox.x1, WinBox.y1,
+ vid_w, vid_h, drw_w, drw_h,
+ &ClipRegion, portPriv->DevPriv.ptr,
+ pDraw);
+
+GET_STILL_BAILOUT:
+
+ if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
+ (*portPriv->AdaptorRec->StopVideo)(
+ portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
+ portPriv->isOn = XV_PENDING;
+ }
+
+ REGION_UNINIT(pScreen, &WinRegion);
+ REGION_UNINIT(pScreen, &ClipRegion);
+
+ return ret;
+}
+
+
+
+static int
+xf86XVStopVideo(
+ ClientPtr client,
+ XvPortPtr pPort,
+ DrawablePtr pDraw
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+
+ if(pDraw->type != DRAWABLE_WINDOW)
+ return BadAlloc;
+
+ xf86XVRemovePortFromWindow((WindowPtr)pDraw, portPriv);
+
+ if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
+
+ /* Must free resources. */
+
+ if(portPriv->isOn > XV_OFF) {
+ (*portPriv->AdaptorRec->StopVideo)(
+ portPriv->pScrn, portPriv->DevPriv.ptr, TRUE);
+ portPriv->isOn = XV_OFF;
+ }
+
+ return Success;
+}
+
+static int
+xf86XVSetPortAttribute(
+ ClientPtr client,
+ XvPortPtr pPort,
+ Atom attribute,
+ INT32 value
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+
+ return((*portPriv->AdaptorRec->SetPortAttribute)(portPriv->pScrn,
+ attribute, value, portPriv->DevPriv.ptr));
+}
+
+
+static int
+xf86XVGetPortAttribute(
+ ClientPtr client,
+ XvPortPtr pPort,
+ Atom attribute,
+ INT32 *p_value
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+
+ return((*portPriv->AdaptorRec->GetPortAttribute)(portPriv->pScrn,
+ attribute, p_value, portPriv->DevPriv.ptr));
+}
+
+
+
+static int
+xf86XVQueryBestSize(
+ ClientPtr client,
+ XvPortPtr pPort,
+ CARD8 motion,
+ CARD16 vid_w, CARD16 vid_h,
+ CARD16 drw_w, CARD16 drw_h,
+ unsigned int *p_w, unsigned int *p_h
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+
+ (*portPriv->AdaptorRec->QueryBestSize)(portPriv->pScrn,
+ (Bool)motion, vid_w, vid_h, drw_w, drw_h,
+ p_w, p_h, portPriv->DevPriv.ptr);
+
+ return Success;
+}
+
+
+static int
+xf86XVPutImage(
+ ClientPtr client,
+ DrawablePtr pDraw,
+ XvPortPtr pPort,
+ GCPtr pGC,
+ INT16 src_x, INT16 src_y,
+ CARD16 src_w, CARD16 src_h,
+ INT16 drw_x, INT16 drw_y,
+ CARD16 drw_w, CARD16 drw_h,
+ XvImagePtr format,
+ unsigned char* data,
+ Bool sync,
+ CARD16 width, CARD16 height
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+ ScreenPtr pScreen;
+ RegionRec WinRegion;
+ RegionRec ClipRegion;
+ BoxRec WinBox;
+ int ret = Success;
+ Bool clippedAway = FALSE;
+
+ if (pDraw->type != DRAWABLE_WINDOW)
+ return BadAlloc;
+
+ if(!portPriv->pScrn->vtSema) return Success; /* Success ? */
+
+ pScreen = pDraw->pScreen;
+
+ WinBox.x1 = pDraw->x + drw_x;
+ WinBox.y1 = pDraw->y + drw_y;
+ WinBox.x2 = WinBox.x1 + drw_w;
+ WinBox.y2 = WinBox.y1 + drw_h;
+
+ REGION_INIT(pScreen, &WinRegion, &WinBox, 1);
+ REGION_NULL(pScreen, &ClipRegion);
+ REGION_INTERSECT(pScreen, &ClipRegion, &WinRegion, pGC->pCompositeClip);
+
+ if(portPriv->AdaptorRec->flags & VIDEO_CLIP_TO_VIEWPORT) {
+ RegionRec VPReg;
+ BoxRec VPBox;
+
+ VPBox.x1 = portPriv->pScrn->frameX0;
+ VPBox.y1 = portPriv->pScrn->frameY0;
+ VPBox.x2 = portPriv->pScrn->frameX1 + 1;
+ VPBox.y2 = portPriv->pScrn->frameY1 + 1;
+
+ REGION_INIT(pScreen, &VPReg, &VPBox, 1);
+ REGION_INTERSECT(pScreen, &ClipRegion, &ClipRegion, &VPReg);
+ REGION_UNINIT(pScreen, &VPReg);
+ }
+
+ /* If we are changing windows, unregister our port in the old window */
+ if(portPriv->pDraw && (portPriv->pDraw != pDraw))
+ xf86XVRemovePortFromWindow((WindowPtr)(portPriv->pDraw), portPriv);
+
+ /* Register our port with the new window */
+ ret = xf86XVEnlistPortInWindow((WindowPtr)pDraw, portPriv);
+ if(ret != Success) goto PUT_IMAGE_BAILOUT;
+
+ if(!REGION_NOTEMPTY(pScreen, &ClipRegion)) {
+ clippedAway = TRUE;
+ goto PUT_IMAGE_BAILOUT;
+ }
+
+ if(portPriv->AdaptorRec->flags & VIDEO_NO_CLIPPING) {
+ BoxPtr clipBox = REGION_RECTS(&ClipRegion);
+ if( (REGION_NUM_RECTS(&ClipRegion) != 1) ||
+ (clipBox->x1 != WinBox.x1) || (clipBox->x2 != WinBox.x2) ||
+ (clipBox->y1 != WinBox.y1) || (clipBox->y2 != WinBox.y2))
+ {
+ clippedAway = TRUE;
+ goto PUT_IMAGE_BAILOUT;
+ }
+ }
+
+ if(portPriv->AdaptorRec->flags & VIDEO_INVERT_CLIPLIST) {
+ REGION_SUBTRACT(pScreen, &ClipRegion, &WinRegion, &ClipRegion);
+ }
+
+ ret = (*portPriv->AdaptorRec->PutImage)(portPriv->pScrn,
+ src_x, src_y, WinBox.x1, WinBox.y1,
+ src_w, src_h, drw_w, drw_h, format->id, data, width, height,
+ sync, &ClipRegion, portPriv->DevPriv.ptr,
+ pDraw);
+
+ if((ret == Success) &&
+ (portPriv->AdaptorRec->flags & VIDEO_OVERLAID_IMAGES)) {
+
+ portPriv->isOn = XV_ON;
+ portPriv->drw_x = drw_x; portPriv->drw_y = drw_y;
+ portPriv->drw_w = drw_w; portPriv->drw_h = drw_h;
+ portPriv->type = 0; /* no mask means it's transient and should
+ not be reput once it's removed */
+ pPort->pDraw = pDraw; /* make sure we can get stop requests */
+ }
+
+PUT_IMAGE_BAILOUT:
+
+ if((clippedAway || (ret != Success)) && (portPriv->isOn == XV_ON)) {
+ (*portPriv->AdaptorRec->StopVideo)(
+ portPriv->pScrn, portPriv->DevPriv.ptr, FALSE);
+ portPriv->isOn = XV_PENDING;
+ }
+
+ REGION_UNINIT(pScreen, &WinRegion);
+ REGION_UNINIT(pScreen, &ClipRegion);
+
+ return ret;
+}
+
+
+static int
+xf86XVQueryImageAttributes(
+ ClientPtr client,
+ XvPortPtr pPort,
+ XvImagePtr format,
+ CARD16 *width,
+ CARD16 *height,
+ int *pitches,
+ int *offsets
+){
+ XvPortRecPrivatePtr portPriv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+
+ return (*portPriv->AdaptorRec->QueryImageAttributes)(portPriv->pScrn,
+ format->id, width, height, pitches, offsets);
+}
+
+
+void
+xf86XVFillKeyHelperDrawable (DrawablePtr pDraw, CARD32 key, RegionPtr clipboxes)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ WindowPtr pWin = (WindowPtr)pDraw;
+ XF86XVWindowPtr pPriv = GET_XF86XV_WINDOW(pWin);
+ GCPtr pGC = NULL;
+ BoxPtr pbox = REGION_RECTS(clipboxes);
+ int i, nbox = REGION_NUM_RECTS(clipboxes);
+ xRectangle *rects;
+
+ if(!xf86Screens[pScreen->myNum]->vtSema) return;
+
+ if(pPriv)
+ pGC = pPriv->pGC;
+
+ if(!pGC) {
+ int status;
+ XID pval[2];
+ pval[0] = key;
+ pval[1] = IncludeInferiors;
+ pGC = CreateGC(pDraw, GCForeground | GCSubwindowMode, pval, &status,
+ (XID)0, serverClient);
+ if(!pGC) return;
+ ValidateGC(pDraw, pGC);
+ if (pPriv) pPriv->pGC = pGC;
+ } else if (key != pGC->fgPixel){
+ ChangeGCVal val;
+ val.val = key;
+ ChangeGC(NullClient, pGC, GCForeground, &val);
+ ValidateGC(pDraw, pGC);
+ }
+
+ REGION_TRANSLATE(pDraw->pScreen, clipboxes, -pDraw->x, -pDraw->y);
+
+ rects = malloc(nbox * sizeof(xRectangle));
+
+ for(i = 0; i < nbox; i++, pbox++) {
+ rects[i].x = pbox->x1;
+ rects[i].y = pbox->y1;
+ rects[i].width = pbox->x2 - pbox->x1;
+ rects[i].height = pbox->y2 - pbox->y1;
+ }
+
+ (*pGC->ops->PolyFillRect)(pDraw, pGC, nbox, rects);
+
+ if (!pPriv) FreeGC(pGC, 0);
+
+ free(rects);
+}
+
+void
+xf86XVFillKeyHelper (ScreenPtr pScreen, CARD32 key, RegionPtr clipboxes)
+{
+ DrawablePtr root = &WindowTable[pScreen->myNum]->drawable;
+ ChangeGCVal pval[2];
+ BoxPtr pbox = REGION_RECTS(clipboxes);
+ int i, nbox = REGION_NUM_RECTS(clipboxes);
+ xRectangle *rects;
+ GCPtr gc;
+
+ if(!xf86Screens[pScreen->myNum]->vtSema) return;
+
+ gc = GetScratchGC(root->depth, pScreen);
+ pval[0].val = key;
+ pval[1].val = IncludeInferiors;
+ (void) ChangeGC(NullClient, gc, GCForeground|GCSubwindowMode, pval);
+ ValidateGC(root, gc);
+
+ rects = malloc(nbox * sizeof(xRectangle));
+
+ for(i = 0; i < nbox; i++, pbox++)
+ {
+ rects[i].x = pbox->x1;
+ rects[i].y = pbox->y1;
+ rects[i].width = pbox->x2 - pbox->x1;
+ rects[i].height = pbox->y2 - pbox->y1;
+ }
+
+ (*gc->ops->PolyFillRect)(root, gc, nbox, rects);
+
+ free(rects);
+ FreeScratchGC (gc);
+}
+
+/* xf86XVClipVideoHelper -
+
+ Takes the dst box in standard X BoxRec form (top and left
+ edges inclusive, bottom and right exclusive). The new dst
+ box is returned. The source boundaries are given (x1, y1
+ inclusive, x2, y2 exclusive) and returned are the new source
+ boundaries in 16.16 fixed point.
+*/
+
+#define DummyScreen screenInfo.screens[0]
+
+Bool
+xf86XVClipVideoHelper(
+ BoxPtr dst,
+ INT32 *xa,
+ INT32 *xb,
+ INT32 *ya,
+ INT32 *yb,
+ RegionPtr reg,
+ INT32 width,
+ INT32 height
+){
+ double xsw, xdw, ysw, ydw;
+ INT32 delta;
+ BoxPtr extents = REGION_EXTENTS(DummyScreen, reg);
+ int diff;
+
+ xsw = (*xb - *xa) << 16;
+ xdw = dst->x2 - dst->x1;
+ ysw = (*yb - *ya) << 16;
+ ydw = dst->y2 - dst->y1;
+
+ *xa <<= 16; *xb <<= 16;
+ *ya <<= 16; *yb <<= 16;
+
+ diff = extents->x1 - dst->x1;
+ if (diff > 0) {
+ dst->x1 = extents->x1;
+ *xa += (diff * xsw) / xdw;
+ }
+ diff = dst->x2 - extents->x2;
+ if (diff > 0) {
+ dst->x2 = extents->x2;
+ *xb -= (diff * xsw) / xdw;
+ }
+ diff = extents->y1 - dst->y1;
+ if (diff > 0) {
+ dst->y1 = extents->y1;
+ *ya += (diff * ysw) / ydw;
+ }
+ diff = dst->y2 - extents->y2;
+ if (diff > 0) {
+ dst->y2 = extents->y2;
+ *yb -= (diff * ysw) / ydw;
+ }
+
+ if (*xa < 0) {
+ diff = (((-*xa) * xdw) + xsw - 1) / xsw;
+ dst->x1 += diff;
+ *xa += (diff * xsw) / xdw;
+ }
+ delta = *xb - (width << 16);
+ if (delta > 0) {
+ diff = ((delta * xdw) + xsw - 1) / xsw;
+ dst->x2 -= diff;
+ *xb -= (diff * xsw) / xdw;
+ }
+ if (*xa >= *xb) return FALSE;
+
+ if (*ya < 0) {
+ diff = (((-*ya) * ydw) + ysw - 1) / ysw;
+ dst->y1 += diff;
+ *ya += (diff * ysw) / ydw;
+ }
+ delta = *yb - (height << 16);
+ if (delta > 0) {
+ diff = ((delta * ydw) + ysw - 1) / ysw;
+ dst->y2 -= diff;
+ *yb -= (diff * ysw) / ydw;
+ }
+ if (*ya >= *yb) return FALSE;
+
+ if ((dst->x1 > extents->x1) || (dst->x2 < extents->x2) ||
+ (dst->y1 > extents->y1) || (dst->y2 < extents->y2))
+ {
+ RegionRec clipReg;
+ REGION_INIT(DummyScreen, &clipReg, dst, 1);
+ REGION_INTERSECT(DummyScreen, reg, reg, &clipReg);
+ REGION_UNINIT(DummyScreen, &clipReg);
+ }
+ return TRUE;
+}
+
+void
+xf86XVCopyYUV12ToPacked(
+ const void *srcy,
+ const void *srcv,
+ const void *srcu,
+ void *dst,
+ int srcPitchy,
+ int srcPitchuv,
+ int dstPitch,
+ int h,
+ int w
+){
+ CARD32 *Dst;
+ const CARD8 *Y, *U, *V;
+ int i, j;
+
+ w >>= 1;
+
+ for (j = 0; j < h; j++) {
+ Dst = dst;
+ Y = srcy; V = srcv; U = srcu;
+ i = w;
+ while (i >= 4) {
+#if X_BYTE_ORDER == X_LITTLE_ENDIAN
+ Dst[0] = Y[0] | (Y[1] << 16) | (U[0] << 8) | (V[0] << 24);
+ Dst[1] = Y[2] | (Y[3] << 16) | (U[1] << 8) | (V[1] << 24);
+ Dst[2] = Y[4] | (Y[5] << 16) | (U[2] << 8) | (V[2] << 24);
+ Dst[3] = Y[6] | (Y[7] << 16) | (U[3] << 8) | (V[3] << 24);
+#else
+ /* This assumes a little-endian framebuffer */
+ Dst[0] = (Y[0] << 24) | (Y[1] << 8) | (U[0] << 16) | V[0];
+ Dst[1] = (Y[2] << 24) | (Y[3] << 8) | (U[1] << 16) | V[1];
+ Dst[2] = (Y[4] << 24) | (Y[5] << 8) | (U[2] << 16) | V[2];
+ Dst[3] = (Y[6] << 24) | (Y[7] << 8) | (U[3] << 16) | V[3];
+#endif
+ Dst += 4; Y += 8; V += 4; U += 4;
+ i -= 4;
+ }
+
+ while (i--) {
+#if X_BYTE_ORDER == X_LITTLE_ENDIAN
+ Dst[0] = Y[0] | (Y[1] << 16) | (U[0] << 8) | (V[0] << 24);
+#else
+ /* This assumes a little-endian framebuffer */
+ Dst[0] = (Y[0] << 24) | (Y[1] << 8) | (U[0] << 16) | V[0];
+#endif
+ Dst++; Y += 2; V++; U++;
+ }
+
+ dst = (CARD8 *)dst + dstPitch;
+ srcy = (const CARD8 *)srcy + srcPitchy;
+ if (j & 1) {
+ srcu = (const CARD8 *)srcu + srcPitchuv;
+ srcv = (const CARD8 *)srcv + srcPitchuv;
+ }
+ }
+}
+
+void
+xf86XVCopyPacked(
+ const void *src,
+ void *dst,
+ int srcPitch,
+ int dstPitch,
+ int h,
+ int w
+){
+ const CARD32 *Src;
+ CARD32 *Dst;
+ int i;
+
+ w >>= 1;
+ while (--h >= 0) {
+ do {
+ Dst = dst; Src = src;
+ i = w;
+ while (i >= 4) {
+ Dst[0] = Src[0];
+ Dst[1] = Src[1];
+ Dst[2] = Src[2];
+ Dst[3] = Src[3];
+ Dst += 4; Src += 4; i -= 4;
+ }
+ if (!i) break;
+ Dst[0] = Src[0];
+ if (i == 1) break;
+ Dst[1] = Src[1];
+ if (i == 2) break;
+ Dst[2] = Src[2];
+ } while (0);
+
+ src = (const CARD8 *)src + srcPitch;
+ dst = (CARD8 *)dst + dstPitch;
+ }
+}
diff --git a/xorg-server/hw/xfree86/common/xf86xvmc.c b/xorg-server/hw/xfree86/common/xf86xvmc.c
index 39d33da08..9cf36f526 100644
--- a/xorg-server/hw/xfree86/common/xf86xvmc.c
+++ b/xorg-server/hw/xfree86/common/xf86xvmc.c
@@ -1,229 +1,229 @@
-
-/*
- * Copyright (c) 2001-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "misc.h"
-#include "xf86.h"
-#include "xf86_OSproc.h"
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "scrnintstr.h"
-#include "resource.h"
-#include "dixstruct.h"
-
-#include "xvmodproc.h"
-
-#include "xf86xvpriv.h"
-#include "xf86xvmc.h"
-
-XvMCScreenInitProcPtr XvMCScreenInitProc = NULL;
-
-
-typedef struct {
- CloseScreenProcPtr CloseScreen;
- int num_adaptors;
- XF86MCAdaptorPtr *adaptors;
- XvMCAdaptorPtr dixinfo;
-} xf86XvMCScreenRec, *xf86XvMCScreenPtr;
-
-static int XF86XvMCScreenKeyIndex;
-static DevPrivateKey XF86XvMCScreenKey = &XF86XvMCScreenKeyIndex;
-
-#define XF86XVMC_GET_PRIVATE(pScreen) (xf86XvMCScreenPtr) \
- dixLookupPrivate(&(pScreen)->devPrivates, XF86XvMCScreenKey)
-
-
-static int
-xf86XvMCCreateContext (
- XvPortPtr pPort,
- XvMCContextPtr pContext,
- int *num_priv,
- CARD32 **priv
-)
-{
- xf86XvMCScreenPtr pScreenPriv = XF86XVMC_GET_PRIVATE(pContext->pScreen);
- ScrnInfoPtr pScrn = xf86Screens[pContext->pScreen->myNum];
-
- pContext->port_priv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
-
- return (*pScreenPriv->adaptors[pContext->adapt_num]->CreateContext)(
- pScrn, pContext, num_priv, priv);
-}
-
-static void
-xf86XvMCDestroyContext ( XvMCContextPtr pContext)
-{
- xf86XvMCScreenPtr pScreenPriv = XF86XVMC_GET_PRIVATE(pContext->pScreen);
- ScrnInfoPtr pScrn = xf86Screens[pContext->pScreen->myNum];
-
- (*pScreenPriv->adaptors[pContext->adapt_num]->DestroyContext)(
- pScrn, pContext);
-}
-
-static int
-xf86XvMCCreateSurface (
- XvMCSurfacePtr pSurface,
- int *num_priv,
- CARD32 **priv
-)
-{
- XvMCContextPtr pContext = pSurface->context;
- xf86XvMCScreenPtr pScreenPriv = XF86XVMC_GET_PRIVATE(pContext->pScreen);
- ScrnInfoPtr pScrn = xf86Screens[pContext->pScreen->myNum];
-
- return (*pScreenPriv->adaptors[pContext->adapt_num]->CreateSurface)(
- pScrn, pSurface, num_priv, priv);
-}
-
-static void
-xf86XvMCDestroySurface (XvMCSurfacePtr pSurface)
-{
- XvMCContextPtr pContext = pSurface->context;
- xf86XvMCScreenPtr pScreenPriv = XF86XVMC_GET_PRIVATE(pContext->pScreen);
- ScrnInfoPtr pScrn = xf86Screens[pContext->pScreen->myNum];
-
- (*pScreenPriv->adaptors[pContext->adapt_num]->DestroySurface)(
- pScrn, pSurface);
-}
-
-static int
-xf86XvMCCreateSubpicture (
- XvMCSubpicturePtr pSubpicture,
- int *num_priv,
- CARD32 **priv
-)
-{
- XvMCContextPtr pContext = pSubpicture->context;
- xf86XvMCScreenPtr pScreenPriv = XF86XVMC_GET_PRIVATE(pContext->pScreen);
- ScrnInfoPtr pScrn = xf86Screens[pContext->pScreen->myNum];
-
- return (*pScreenPriv->adaptors[pContext->adapt_num]->CreateSubpicture)(
- pScrn, pSubpicture, num_priv, priv);
-}
-
-static void
-xf86XvMCDestroySubpicture (XvMCSubpicturePtr pSubpicture)
-{
- XvMCContextPtr pContext = pSubpicture->context;
- xf86XvMCScreenPtr pScreenPriv = XF86XVMC_GET_PRIVATE(pContext->pScreen);
- ScrnInfoPtr pScrn = xf86Screens[pContext->pScreen->myNum];
-
- (*pScreenPriv->adaptors[pContext->adapt_num]->DestroySubpicture)(
- pScrn, pSubpicture);
-}
-
-
-static Bool
-xf86XvMCCloseScreen (int i, ScreenPtr pScreen)
-{
- xf86XvMCScreenPtr pScreenPriv = XF86XVMC_GET_PRIVATE(pScreen);
-
- pScreen->CloseScreen = pScreenPriv->CloseScreen;
-
- xfree(pScreenPriv->dixinfo);
- xfree(pScreenPriv);
-
- return (*pScreen->CloseScreen)(i, pScreen);
-}
-
-Bool xf86XvMCScreenInit(
- ScreenPtr pScreen,
- int num_adaptors,
- XF86MCAdaptorPtr *adaptors
-)
-{
- XvMCAdaptorPtr pAdapt;
- xf86XvMCScreenPtr pScreenPriv;
- XvScreenPtr pxvs = (XvScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
- XF86XvScreenKey);
- int i, j;
-
- if(!XvMCScreenInitProc) return FALSE;
-
- if(!(pAdapt = xalloc(sizeof(XvMCAdaptorRec) * num_adaptors)))
- return FALSE;
-
- if(!(pScreenPriv = xalloc(sizeof(xf86XvMCScreenRec)))) {
- xfree(pAdapt);
- return FALSE;
- }
-
- dixSetPrivate(&pScreen->devPrivates, XF86XvMCScreenKey, pScreenPriv);
-
- pScreenPriv->CloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = xf86XvMCCloseScreen;
-
- pScreenPriv->num_adaptors = num_adaptors;
- pScreenPriv->adaptors = adaptors;
- pScreenPriv->dixinfo = pAdapt;
-
- for(i = 0; i < num_adaptors; i++) {
- pAdapt[i].xv_adaptor = NULL;
- for(j = 0; j < pxvs->nAdaptors; j++) {
- if(!strcmp((*adaptors)->name, pxvs->pAdaptors[j].name)) {
- pAdapt[i].xv_adaptor = &(pxvs->pAdaptors[j]);
- break;
- }
- }
- if(!pAdapt[i].xv_adaptor) {
- /* no adaptor by that name */
- xfree(pAdapt);
- return FALSE;
- }
- pAdapt[i].num_surfaces = (*adaptors)->num_surfaces;
- pAdapt[i].surfaces = (XvMCSurfaceInfoPtr*)((*adaptors)->surfaces);
- pAdapt[i].num_subpictures = (*adaptors)->num_subpictures;
- pAdapt[i].subpictures = (XvImagePtr*)((*adaptors)->subpictures);
- pAdapt[i].CreateContext = xf86XvMCCreateContext;
- pAdapt[i].DestroyContext = xf86XvMCDestroyContext;
- pAdapt[i].CreateSurface = xf86XvMCCreateSurface;
- pAdapt[i].DestroySurface = xf86XvMCDestroySurface;
- pAdapt[i].CreateSubpicture = xf86XvMCCreateSubpicture;
- pAdapt[i].DestroySubpicture = xf86XvMCDestroySubpicture;
- adaptors++;
- }
-
- if(Success != (*XvMCScreenInitProc)(pScreen, num_adaptors, pAdapt))
- return FALSE;
-
- return TRUE;
-}
-
-XF86MCAdaptorPtr xf86XvMCCreateAdaptorRec (void)
-{
- return xcalloc(1, sizeof(XF86MCAdaptorRec));
-}
-
-void xf86XvMCDestroyAdaptorRec(XF86MCAdaptorPtr adaptor)
-{
- xfree(adaptor);
-}
+
+/*
+ * Copyright (c) 2001-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "scrnintstr.h"
+#include "resource.h"
+#include "dixstruct.h"
+
+#include "xvmodproc.h"
+
+#include "xf86xvpriv.h"
+#include "xf86xvmc.h"
+
+XvMCScreenInitProcPtr XvMCScreenInitProc = NULL;
+
+
+typedef struct {
+ CloseScreenProcPtr CloseScreen;
+ int num_adaptors;
+ XF86MCAdaptorPtr *adaptors;
+ XvMCAdaptorPtr dixinfo;
+} xf86XvMCScreenRec, *xf86XvMCScreenPtr;
+
+static int XF86XvMCScreenKeyIndex;
+static DevPrivateKey XF86XvMCScreenKey = &XF86XvMCScreenKeyIndex;
+
+#define XF86XVMC_GET_PRIVATE(pScreen) (xf86XvMCScreenPtr) \
+ dixLookupPrivate(&(pScreen)->devPrivates, XF86XvMCScreenKey)
+
+
+static int
+xf86XvMCCreateContext (
+ XvPortPtr pPort,
+ XvMCContextPtr pContext,
+ int *num_priv,
+ CARD32 **priv
+)
+{
+ xf86XvMCScreenPtr pScreenPriv = XF86XVMC_GET_PRIVATE(pContext->pScreen);
+ ScrnInfoPtr pScrn = xf86Screens[pContext->pScreen->myNum];
+
+ pContext->port_priv = (XvPortRecPrivatePtr)(pPort->devPriv.ptr);
+
+ return (*pScreenPriv->adaptors[pContext->adapt_num]->CreateContext)(
+ pScrn, pContext, num_priv, priv);
+}
+
+static void
+xf86XvMCDestroyContext ( XvMCContextPtr pContext)
+{
+ xf86XvMCScreenPtr pScreenPriv = XF86XVMC_GET_PRIVATE(pContext->pScreen);
+ ScrnInfoPtr pScrn = xf86Screens[pContext->pScreen->myNum];
+
+ (*pScreenPriv->adaptors[pContext->adapt_num]->DestroyContext)(
+ pScrn, pContext);
+}
+
+static int
+xf86XvMCCreateSurface (
+ XvMCSurfacePtr pSurface,
+ int *num_priv,
+ CARD32 **priv
+)
+{
+ XvMCContextPtr pContext = pSurface->context;
+ xf86XvMCScreenPtr pScreenPriv = XF86XVMC_GET_PRIVATE(pContext->pScreen);
+ ScrnInfoPtr pScrn = xf86Screens[pContext->pScreen->myNum];
+
+ return (*pScreenPriv->adaptors[pContext->adapt_num]->CreateSurface)(
+ pScrn, pSurface, num_priv, priv);
+}
+
+static void
+xf86XvMCDestroySurface (XvMCSurfacePtr pSurface)
+{
+ XvMCContextPtr pContext = pSurface->context;
+ xf86XvMCScreenPtr pScreenPriv = XF86XVMC_GET_PRIVATE(pContext->pScreen);
+ ScrnInfoPtr pScrn = xf86Screens[pContext->pScreen->myNum];
+
+ (*pScreenPriv->adaptors[pContext->adapt_num]->DestroySurface)(
+ pScrn, pSurface);
+}
+
+static int
+xf86XvMCCreateSubpicture (
+ XvMCSubpicturePtr pSubpicture,
+ int *num_priv,
+ CARD32 **priv
+)
+{
+ XvMCContextPtr pContext = pSubpicture->context;
+ xf86XvMCScreenPtr pScreenPriv = XF86XVMC_GET_PRIVATE(pContext->pScreen);
+ ScrnInfoPtr pScrn = xf86Screens[pContext->pScreen->myNum];
+
+ return (*pScreenPriv->adaptors[pContext->adapt_num]->CreateSubpicture)(
+ pScrn, pSubpicture, num_priv, priv);
+}
+
+static void
+xf86XvMCDestroySubpicture (XvMCSubpicturePtr pSubpicture)
+{
+ XvMCContextPtr pContext = pSubpicture->context;
+ xf86XvMCScreenPtr pScreenPriv = XF86XVMC_GET_PRIVATE(pContext->pScreen);
+ ScrnInfoPtr pScrn = xf86Screens[pContext->pScreen->myNum];
+
+ (*pScreenPriv->adaptors[pContext->adapt_num]->DestroySubpicture)(
+ pScrn, pSubpicture);
+}
+
+
+static Bool
+xf86XvMCCloseScreen (int i, ScreenPtr pScreen)
+{
+ xf86XvMCScreenPtr pScreenPriv = XF86XVMC_GET_PRIVATE(pScreen);
+
+ pScreen->CloseScreen = pScreenPriv->CloseScreen;
+
+ free(pScreenPriv->dixinfo);
+ free(pScreenPriv);
+
+ return (*pScreen->CloseScreen)(i, pScreen);
+}
+
+Bool xf86XvMCScreenInit(
+ ScreenPtr pScreen,
+ int num_adaptors,
+ XF86MCAdaptorPtr *adaptors
+)
+{
+ XvMCAdaptorPtr pAdapt;
+ xf86XvMCScreenPtr pScreenPriv;
+ XvScreenPtr pxvs = (XvScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
+ XF86XvScreenKey);
+ int i, j;
+
+ if(!XvMCScreenInitProc) return FALSE;
+
+ if(!(pAdapt = malloc(sizeof(XvMCAdaptorRec) * num_adaptors)))
+ return FALSE;
+
+ if(!(pScreenPriv = malloc(sizeof(xf86XvMCScreenRec)))) {
+ free(pAdapt);
+ return FALSE;
+ }
+
+ dixSetPrivate(&pScreen->devPrivates, XF86XvMCScreenKey, pScreenPriv);
+
+ pScreenPriv->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = xf86XvMCCloseScreen;
+
+ pScreenPriv->num_adaptors = num_adaptors;
+ pScreenPriv->adaptors = adaptors;
+ pScreenPriv->dixinfo = pAdapt;
+
+ for(i = 0; i < num_adaptors; i++) {
+ pAdapt[i].xv_adaptor = NULL;
+ for(j = 0; j < pxvs->nAdaptors; j++) {
+ if(!strcmp((*adaptors)->name, pxvs->pAdaptors[j].name)) {
+ pAdapt[i].xv_adaptor = &(pxvs->pAdaptors[j]);
+ break;
+ }
+ }
+ if(!pAdapt[i].xv_adaptor) {
+ /* no adaptor by that name */
+ free(pAdapt);
+ return FALSE;
+ }
+ pAdapt[i].num_surfaces = (*adaptors)->num_surfaces;
+ pAdapt[i].surfaces = (XvMCSurfaceInfoPtr*)((*adaptors)->surfaces);
+ pAdapt[i].num_subpictures = (*adaptors)->num_subpictures;
+ pAdapt[i].subpictures = (XvImagePtr*)((*adaptors)->subpictures);
+ pAdapt[i].CreateContext = xf86XvMCCreateContext;
+ pAdapt[i].DestroyContext = xf86XvMCDestroyContext;
+ pAdapt[i].CreateSurface = xf86XvMCCreateSurface;
+ pAdapt[i].DestroySurface = xf86XvMCDestroySurface;
+ pAdapt[i].CreateSubpicture = xf86XvMCCreateSubpicture;
+ pAdapt[i].DestroySubpicture = xf86XvMCDestroySubpicture;
+ adaptors++;
+ }
+
+ if(Success != (*XvMCScreenInitProc)(pScreen, num_adaptors, pAdapt))
+ return FALSE;
+
+ return TRUE;
+}
+
+XF86MCAdaptorPtr xf86XvMCCreateAdaptorRec (void)
+{
+ return calloc(1, sizeof(XF86MCAdaptorRec));
+}
+
+void xf86XvMCDestroyAdaptorRec(XF86MCAdaptorPtr adaptor)
+{
+ free(adaptor);
+}
diff --git a/xorg-server/hw/xfree86/common/xisb.c b/xorg-server/hw/xfree86/common/xisb.c
index 1cb9e4854..f08327fb3 100644
--- a/xorg-server/hw/xfree86/common/xisb.c
+++ b/xorg-server/hw/xfree86/common/xisb.c
@@ -1,174 +1,174 @@
-/*
- * Copyright (c) 1997 Metro Link Incorporated
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
- * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Except as contained in this notice, the name of the Metro Link shall not be
- * used in advertising or otherwise to promote the sale, use or other dealings
- * in this Software without prior written authorization from Metro Link.
- *
- */
-
-/*
- X Input Serial Buffer routines for use in any XInput driver that accesses
- a serial device.
-*/
-
-
-/*****************************************************************************
- * Standard Headers
- ****************************************************************************/
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <misc.h>
-#include <xf86.h>
-#include <xf86_OSproc.h>
-#include <xf86_OSlib.h>
-#include <xf86Xinput.h>
-#include "xisb.h"
-
-/*****************************************************************************
- * Local Headers
- ****************************************************************************/
-
-/*****************************************************************************
- * Variables without includable headers
- ****************************************************************************/
-
-/*****************************************************************************
- * Local Variables
- ****************************************************************************/
-
-/*****************************************************************************
- * Function Definitions
- ****************************************************************************/
-
-XISBuffer *
-XisbNew (int fd, ssize_t size)
-{
- XISBuffer *b;
-
- b = xalloc (sizeof (XISBuffer));
- if (!b)
- return (NULL);
- b->buf = xalloc ((sizeof (unsigned char) * size));
- if (!b->buf)
- {
- xfree (b);
- return (NULL);
- }
-
- b->fd = fd;
- b->trace = 0;
- b->block_duration = 0;
- b->current = 1; /* force it to be past the end to trigger initial read */
- b->end = 0;
- b->buffer_size = size;
- return (b);
-}
-
-void
-XisbFree (XISBuffer *b)
-{
- xfree (b->buf);
- xfree (b);
-}
-
-int
-XisbRead (XISBuffer *b)
-{
- int ret;
-
- if (b->current >= b->end)
- {
- if (b->block_duration >= 0)
- {
- if (xf86WaitForInput (b->fd, b->block_duration) < 1)
- return (-1);
- }
- else
- {
- /*
- * automatically clear it so if XisbRead is called in a loop
- * the next call will make sure there is data with select and
- * thus prevent a blocking read
- */
- b->block_duration = 0;
- }
-
- ret = xf86ReadSerial (b->fd, b->buf, b->buffer_size);
- switch (ret)
- {
- case 0:
- return (-1); /* timeout */
- case -1:
- return (-2); /* error */
- default:
- b->end = ret;
- b->current = 0;
- break;
- }
- }
- if (b->trace)
- ErrorF ("read 0x%02x (%c)\n", b->buf[b->current],
- isprint(b->buf[b->current])?b->buf[b->current]:'.');
-
- return (b->buf[b->current++]);
-}
-
-/* the only purpose of this function is to provide output tracing */
-ssize_t
-XisbWrite (XISBuffer *b, unsigned char *msg, ssize_t len)
-{
- if (b->trace)
- {
- int i = 0;
- for (i = 0; i < len; i++)
- ErrorF ("\t\twrote 0x%02x (%c)\n", msg[i], msg[i]);
- }
- return (xf86WriteSerial (b->fd, msg, len));
-}
-
-/* turn tracing of this buffer on (1) or off (0) */
-void
-XisbTrace (XISBuffer *b, int trace)
-{
- b->trace = trace;
-}
-
-/*
- * specify a block_duration of -1 when you know the buffer's fd is ready to
- * read. After a read, it is automatically set to 0 so that the next read
- * will use check to select for data and prevent a block.
- * It is the caller's responsibility to set the block_duration to -1 if it
- * knows that there is data to read (because the main select loop triggered
- * the read) and want's to avoid the unnecessary overhead of the select call
- *
- * a zero or positive block duration will cause the select to block for the
- * give duration in usecs.
- */
-
-void
-XisbBlockDuration (XISBuffer *b, int block_duration)
-{
- b->block_duration = block_duration;
-}
+/*
+ * Copyright (c) 1997 Metro Link Incorporated
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the Metro Link shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Metro Link.
+ *
+ */
+
+/*
+ X Input Serial Buffer routines for use in any XInput driver that accesses
+ a serial device.
+*/
+
+
+/*****************************************************************************
+ * Standard Headers
+ ****************************************************************************/
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <misc.h>
+#include <xf86.h>
+#include <xf86_OSproc.h>
+#include <xf86_OSlib.h>
+#include <xf86Xinput.h>
+#include "xisb.h"
+
+/*****************************************************************************
+ * Local Headers
+ ****************************************************************************/
+
+/*****************************************************************************
+ * Variables without includable headers
+ ****************************************************************************/
+
+/*****************************************************************************
+ * Local Variables
+ ****************************************************************************/
+
+/*****************************************************************************
+ * Function Definitions
+ ****************************************************************************/
+
+XISBuffer *
+XisbNew (int fd, ssize_t size)
+{
+ XISBuffer *b;
+
+ b = malloc(sizeof (XISBuffer));
+ if (!b)
+ return (NULL);
+ b->buf = malloc((sizeof (unsigned char) * size));
+ if (!b->buf)
+ {
+ free(b);
+ return (NULL);
+ }
+
+ b->fd = fd;
+ b->trace = 0;
+ b->block_duration = 0;
+ b->current = 1; /* force it to be past the end to trigger initial read */
+ b->end = 0;
+ b->buffer_size = size;
+ return (b);
+}
+
+void
+XisbFree (XISBuffer *b)
+{
+ free(b->buf);
+ free(b);
+}
+
+int
+XisbRead (XISBuffer *b)
+{
+ int ret;
+
+ if (b->current >= b->end)
+ {
+ if (b->block_duration >= 0)
+ {
+ if (xf86WaitForInput (b->fd, b->block_duration) < 1)
+ return (-1);
+ }
+ else
+ {
+ /*
+ * automatically clear it so if XisbRead is called in a loop
+ * the next call will make sure there is data with select and
+ * thus prevent a blocking read
+ */
+ b->block_duration = 0;
+ }
+
+ ret = xf86ReadSerial (b->fd, b->buf, b->buffer_size);
+ switch (ret)
+ {
+ case 0:
+ return (-1); /* timeout */
+ case -1:
+ return (-2); /* error */
+ default:
+ b->end = ret;
+ b->current = 0;
+ break;
+ }
+ }
+ if (b->trace)
+ ErrorF ("read 0x%02x (%c)\n", b->buf[b->current],
+ isprint(b->buf[b->current])?b->buf[b->current]:'.');
+
+ return (b->buf[b->current++]);
+}
+
+/* the only purpose of this function is to provide output tracing */
+ssize_t
+XisbWrite (XISBuffer *b, unsigned char *msg, ssize_t len)
+{
+ if (b->trace)
+ {
+ int i = 0;
+ for (i = 0; i < len; i++)
+ ErrorF ("\t\twrote 0x%02x (%c)\n", msg[i], msg[i]);
+ }
+ return (xf86WriteSerial (b->fd, msg, len));
+}
+
+/* turn tracing of this buffer on (1) or off (0) */
+void
+XisbTrace (XISBuffer *b, int trace)
+{
+ b->trace = trace;
+}
+
+/*
+ * specify a block_duration of -1 when you know the buffer's fd is ready to
+ * read. After a read, it is automatically set to 0 so that the next read
+ * will use check to select for data and prevent a block.
+ * It is the caller's responsibility to set the block_duration to -1 if it
+ * knows that there is data to read (because the main select loop triggered
+ * the read) and want's to avoid the unnecessary overhead of the select call
+ *
+ * a zero or positive block duration will cause the select to block for the
+ * give duration in usecs.
+ */
+
+void
+XisbBlockDuration (XISBuffer *b, int block_duration)
+{
+ b->block_duration = block_duration;
+}
diff --git a/xorg-server/hw/xfree86/ddc/ddc.c b/xorg-server/hw/xfree86/ddc/ddc.c
index 6fad9fbbc..ec6465818 100644
--- a/xorg-server/hw/xfree86/ddc/ddc.c
+++ b/xorg-server/hw/xfree86/ddc/ddc.c
@@ -1,507 +1,507 @@
-/* xf86DDC.c
- *
- * Copyright 1998,1999 by Egbert Eich <Egbert.Eich@Physik.TU-Darmstadt.DE>
- */
-
-/*
- * A note on terminology. DDC1 is the original dumb serial protocol, and
- * can only do up to 128 bytes of EDID. DDC2 is I2C-encapsulated and
- * introduces extension blocks. EDID is the old display identification
- * block, DisplayID is the new one.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "misc.h"
-#include "xf86.h"
-#include "xf86_OSproc.h"
-#include "xf86DDC.h"
-#include <string.h>
-
-#define RETRIES 4
-
-typedef enum {
- DDCOPT_NODDC1,
- DDCOPT_NODDC2,
- DDCOPT_NODDC
-} DDCOpts;
-
-static const OptionInfoRec DDCOptions[] = {
- { DDCOPT_NODDC1, "NoDDC1", OPTV_BOOLEAN, {0}, FALSE },
- { DDCOPT_NODDC2, "NoDDC2", OPTV_BOOLEAN, {0}, FALSE },
- { DDCOPT_NODDC, "NoDDC", OPTV_BOOLEAN, {0}, FALSE },
- { -1, NULL, OPTV_NONE, {0}, FALSE },
-};
-
-/* DDC1 */
-
-static int
-find_start(unsigned int *ptr)
-{
- unsigned int comp[9], test[9];
- int i,j;
-
- for (i=0;i<9;i++){
- comp[i] = *(ptr++);
- test[i] = 1;
- }
- for (i=0;i<127;i++){
- for (j=0;j<9;j++){
- test[j] = test[j] & !(comp[j] ^ *(ptr++));
- }
- }
- for (i=0;i<9;i++)
- if (test[i]) return (i+1);
- return (-1);
-}
-
-static unsigned char *
-find_header(unsigned char *block)
-{
- unsigned char *ptr, *head_ptr, *end;
- unsigned char header[]={0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00};
-
- ptr = block;
- end = block + EDID1_LEN;
- while (ptr<end) {
- int i;
- head_ptr = ptr;
- for (i=0;i<8;i++){
- if (header[i] != *(head_ptr++)) break;
- if (head_ptr == end) head_ptr = block;
- }
- if (i==8) break;
- ptr++;
- }
- if (ptr == end) return (NULL);
- return (ptr);
-}
-
-static unsigned char *
-resort(unsigned char *s_block)
-{
- unsigned char *d_new, *d_ptr, *d_end, *s_ptr, *s_end;
- unsigned char tmp;
-
- s_end = s_block + EDID1_LEN;
- d_new = xalloc(EDID1_LEN);
- if (!d_new) return NULL;
- d_end = d_new + EDID1_LEN;
-
- s_ptr = find_header(s_block);
- if (!s_ptr) return NULL;
- for (d_ptr=d_new;d_ptr<d_end;d_ptr++){
- tmp = *(s_ptr++);
- *d_ptr = tmp;
- if (s_ptr == s_end) s_ptr = s_block;
- }
- xfree(s_block);
- return (d_new);
-}
-
-static int
-DDC_checksum(unsigned char *block, int len)
-{
- int i, result = 0;
- int not_null = 0;
-
- for (i=0;i<len;i++) {
- not_null |= block[i];
- result += block[i];
- }
-
-#ifdef DEBUG
- if (result & 0xFF) ErrorF("DDC checksum not correct\n");
- if (!not_null) ErrorF("DDC read all Null\n");
-#endif
-
- /* catch the trivial case where all bytes are 0 */
- if (!not_null) return 1;
-
- return (result&0xFF);
-}
-
-static unsigned char *
-GetEDID_DDC1(unsigned int *s_ptr)
-{
- unsigned char *d_block, *d_pos;
- unsigned int *s_pos, *s_end;
- int s_start;
- int i,j;
- s_start = find_start(s_ptr);
- if (s_start==-1) return NULL;
- s_end = s_ptr + NUM;
- s_pos = s_ptr + s_start;
- d_block=xalloc(EDID1_LEN);
- if (!d_block) return NULL;
- d_pos = d_block;
- for (i=0;i<EDID1_LEN;i++) {
- for (j=0;j<8;j++) {
- *d_pos <<= 1;
- if (*s_pos) {
- *d_pos |= 0x01;
- }
- s_pos++; if (s_pos == s_end) s_pos=s_ptr;
- };
- s_pos++; if (s_pos == s_end) s_pos=s_ptr;
- d_pos++;
- }
- xfree(s_ptr);
- if (d_block && DDC_checksum(d_block,EDID1_LEN)) return NULL;
- return (resort(d_block));
-}
-
-/* fetch entire EDID record; DDC bit needs to be masked */
-static unsigned int *
-FetchEDID_DDC1(register ScrnInfoPtr pScrn,
- register unsigned int (*read_DDC)(ScrnInfoPtr))
-{
- int count = NUM;
- unsigned int *ptr, *xp;
-
- ptr=xp=xalloc(sizeof(int)*NUM);
-
- if (!ptr) return NULL;
- do {
- /* wait for next retrace */
- *xp = read_DDC(pScrn);
- xp++;
- } while(--count);
- return (ptr);
-}
-
-/* test if DDC1 return 0 if not */
-static Bool
-TestDDC1(ScrnInfoPtr pScrn, unsigned int (*read_DDC)(ScrnInfoPtr))
-{
- int old, count;
-
- old = read_DDC(pScrn);
- count = HEADER * BITS_PER_BYTE;
- do {
- /* wait for next retrace */
- if (old != read_DDC(pScrn)) break;
- } while(count--);
- return (count);
-}
-
-/*
- * read EDID record , pass it to callback function to interpret.
- * callback function will store it for further use by calling
- * function; it will also decide if we need to reread it
- */
-static unsigned char *
-EDIDRead_DDC1(ScrnInfoPtr pScrn, DDC1SetSpeedProc DDCSpeed,
- unsigned int (*read_DDC)(ScrnInfoPtr))
-{
- unsigned char *EDID_block = NULL;
- int count = RETRIES;
-
- if (!read_DDC) {
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
- "chipset doesn't support DDC1\n");
- return NULL;
- };
-
- if (TestDDC1(pScrn,read_DDC)==-1) {
- xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "No DDC signal\n");
- return NULL;
- };
-
- if (DDCSpeed) DDCSpeed(pScrn,DDC_FAST);
- do {
- EDID_block = GetEDID_DDC1(FetchEDID_DDC1(pScrn,read_DDC));
- count --;
- } while (!EDID_block && count);
- if (DDCSpeed) DDCSpeed(pScrn,DDC_SLOW);
-
- return EDID_block;
-}
-
-/**
- * Attempts to probe the monitor for EDID information, if NoDDC and NoDDC1 are
- * unset. EDID information blocks are interpreted and the results returned in
- * an xf86MonPtr.
- *
- * This function does not affect the list of modes used by drivers -- it is up
- * to the driver to decide policy on what to do with EDID information.
- *
- * @return pointer to a new xf86MonPtr containing the EDID information.
- * @return NULL if no monitor attached or failure to interpret the EDID.
- */
-xf86MonPtr
-xf86DoEDID_DDC1(
- int scrnIndex, DDC1SetSpeedProc DDC1SetSpeed,
- unsigned int (*DDC1Read)(ScrnInfoPtr)
-)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- unsigned char *EDID_block = NULL;
- xf86MonPtr tmp = NULL;
- int sigio;
- /* Default DDC and DDC1 to enabled. */
- Bool noddc = FALSE, noddc1 = FALSE;
- OptionInfoPtr options;
-
- options = xnfalloc(sizeof(DDCOptions));
- (void)memcpy(options, DDCOptions, sizeof(DDCOptions));
- xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
-
- xf86GetOptValBool(options, DDCOPT_NODDC, &noddc);
- xf86GetOptValBool(options, DDCOPT_NODDC1, &noddc1);
- xfree(options);
-
- if (noddc || noddc1)
- return NULL;
-
- sigio = xf86BlockSIGIO();
- EDID_block = EDIDRead_DDC1(pScrn,DDC1SetSpeed,DDC1Read);
- xf86UnblockSIGIO(sigio);
-
- if (EDID_block){
- tmp = xf86InterpretEDID(scrnIndex,EDID_block);
- }
-#ifdef DEBUG
- else ErrorF("No EDID block returned\n");
- if (!tmp)
- ErrorF("Cannot interpret EDID block\n");
-#endif
- return tmp;
-}
-
-/* DDC2 */
-
-static I2CDevPtr
-DDC2MakeDevice(I2CBusPtr pBus, int address, char *name)
-{
- I2CDevPtr dev = NULL;
-
- if (!(dev = xf86I2CFindDev(pBus, address))) {
- dev = xf86CreateI2CDevRec();
- dev->DevName = name;
- dev->SlaveAddr = address;
- dev->ByteTimeout = 2200; /* VESA DDC spec 3 p. 43 (+10 %) */
- dev->StartTimeout = 550;
- dev->BitTimeout = 40;
- dev->AcknTimeout = 40;
-
- dev->pI2CBus = pBus;
- if (!xf86I2CDevInit(dev)) {
- xf86DrvMsg(pBus->scrnIndex, X_PROBED, "No DDC2 device\n");
- return NULL;
- }
- }
-
- return dev;
-}
-
-static I2CDevPtr
-DDC2Init(int scrnIndex, I2CBusPtr pBus)
-{
- I2CDevPtr dev = NULL;
-
- /*
- * Slow down the bus so that older monitors don't
- * miss things.
- */
- pBus->RiseFallTime = 20;
-
- dev = DDC2MakeDevice(pBus, 0x00A0, "ddc2");
- if (xf86I2CProbeAddress(pBus, 0x0060))
- DDC2MakeDevice(pBus, 0x0060, "E-EDID segment register");
- if (xf86I2CProbeAddress(pBus, 0x0062))
- DDC2MakeDevice(pBus, 0x0062, "EDID EEPROM interface");
- if (xf86I2CProbeAddress(pBus, 0x006E))
- DDC2MakeDevice(pBus, 0x006E, "DDC control interface");
-
- return dev;
-}
-
-/* Mmmm, smell the hacks */
-static void
-EEDIDStop(I2CDevPtr d)
-{
-}
-
-/* block is the EDID block number. a segment is two blocks. */
-static Bool
-DDC2Read(I2CDevPtr dev, int block, unsigned char *R_Buffer)
-{
- unsigned char W_Buffer[1];
- int i, segment;
- I2CDevPtr seg;
- void (*stop)(I2CDevPtr);
-
- for (i = 0; i < RETRIES; i++) {
- /* Stop bits reset the segment pointer to 0, so be careful here. */
- segment = block >> 1;
- if (segment) {
- Bool b;
-
- if (!(seg = xf86I2CFindDev(dev->pI2CBus, 0x0060)))
- return FALSE;
-
- W_Buffer[0] = segment;
-
- stop = dev->pI2CBus->I2CStop;
- dev->pI2CBus->I2CStop = EEDIDStop;
-
- b = xf86I2CWriteRead(seg, W_Buffer, 1, NULL, 0);
-
- dev->pI2CBus->I2CStop = stop;
- if (!b) {
- dev->pI2CBus->I2CStop(dev);
- continue;
- }
- }
-
- W_Buffer[0] = (block & 0x01) * EDID1_LEN;
-
- if (xf86I2CWriteRead(dev, W_Buffer, 1, R_Buffer, EDID1_LEN)) {
- if (!DDC_checksum(R_Buffer, EDID1_LEN))
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-/**
- * Attempts to probe the monitor for EDID information, if NoDDC and NoDDC2 are
- * unset. EDID information blocks are interpreted and the results returned in
- * an xf86MonPtr. Unlike xf86DoEDID_DDC[12](), this function will return
- * the complete EDID data, including all extension blocks, if the 'complete'
- * parameter is TRUE;
- *
- * This function does not affect the list of modes used by drivers -- it is up
- * to the driver to decide policy on what to do with EDID information.
- *
- * @return pointer to a new xf86MonPtr containing the EDID information.
- * @return NULL if no monitor attached or failure to interpret the EDID.
- */
-xf86MonPtr
-xf86DoEEDID(int scrnIndex, I2CBusPtr pBus, Bool complete)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- unsigned char *EDID_block = NULL;
- xf86MonPtr tmp = NULL;
- I2CDevPtr dev = NULL;
- /* Default DDC and DDC2 to enabled. */
- Bool noddc = FALSE, noddc2 = FALSE;
- OptionInfoPtr options;
-
- options = xalloc(sizeof(DDCOptions));
- if (!options)
- return NULL;
- memcpy(options, DDCOptions, sizeof(DDCOptions));
- xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
-
- xf86GetOptValBool(options, DDCOPT_NODDC, &noddc);
- xf86GetOptValBool(options, DDCOPT_NODDC2, &noddc2);
- xfree(options);
-
- if (noddc || noddc2)
- return NULL;
-
- if (!(dev = DDC2Init(scrnIndex, pBus)))
- return NULL;
-
- EDID_block = xcalloc(1, EDID1_LEN);
- if (!EDID_block)
- return NULL;
-
- if (DDC2Read(dev, 0, EDID_block)) {
- int i, n = EDID_block[0x7e];
-
- if (complete && n) {
- EDID_block = xrealloc(EDID_block, EDID1_LEN * (1+n));
-
- for (i = 0; i < n; i++)
- DDC2Read(dev, i+1, EDID_block + (EDID1_LEN * (1+i)));
- }
-
- tmp = xf86InterpretEEDID(scrnIndex, EDID_block);
- }
-
- if (tmp && complete)
- tmp->flags |= MONITOR_EDID_COMPLETE_RAWDATA;
-
- return tmp;
-}
-
-/**
- * Attempts to probe the monitor for EDID information, if NoDDC and NoDDC2 are
- * unset. EDID information blocks are interpreted and the results returned in
- * an xf86MonPtr.
- *
- * This function does not affect the list of modes used by drivers -- it is up
- * to the driver to decide policy on what to do with EDID information.
- *
- * @return pointer to a new xf86MonPtr containing the EDID information.
- * @return NULL if no monitor attached or failure to interpret the EDID.
- */
-xf86MonPtr
-xf86DoEDID_DDC2(int scrnIndex, I2CBusPtr pBus)
-{
- return xf86DoEEDID(scrnIndex, pBus, FALSE);
-}
-
-/* XXX write me */
-static void *
-DDC2ReadDisplayID(void)
-{
- return FALSE;
-}
-
-/**
- * Attempts to probe the monitor for DisplayID information, if NoDDC and
- * NoDDC2 are unset. DisplayID blocks are interpreted and the results
- * returned in an xf86MonPtr.
- *
- * This function does not affect the list of modes used by drivers -- it is up
- * to the driver to decide policy on what to do with DisplayID information.
- *
- * @return pointer to a new xf86MonPtr containing the DisplayID information.
- * @return NULL if no monitor attached or failure to interpret the DisplayID.
- */
-xf86MonPtr
-xf86DoDisplayID(int scrnIndex, I2CBusPtr pBus)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- unsigned char *did = NULL;
- xf86MonPtr tmp = NULL;
- I2CDevPtr dev = NULL;
- /* Default DDC and DDC2 to enabled. */
- Bool noddc = FALSE, noddc2 = FALSE;
- OptionInfoPtr options;
-
- options = xalloc(sizeof(DDCOptions));
- if (!options)
- return NULL;
- memcpy(options, DDCOptions, sizeof(DDCOptions));
- xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
-
- xf86GetOptValBool(options, DDCOPT_NODDC, &noddc);
- xf86GetOptValBool(options, DDCOPT_NODDC2, &noddc2);
- xfree(options);
-
- if (noddc || noddc2)
- return NULL;
-
- if (!(dev = DDC2Init(scrnIndex, pBus)))
- return NULL;
-
- if ((did = DDC2ReadDisplayID())) {
- tmp = xcalloc(1, sizeof(*tmp));
- if (!tmp)
- return NULL;
-
- tmp->scrnIndex = scrnIndex;
- tmp->flags |= MONITOR_DISPLAYID;
- tmp->rawData = did;
- }
-
- return tmp;
-}
+/* xf86DDC.c
+ *
+ * Copyright 1998,1999 by Egbert Eich <Egbert.Eich@Physik.TU-Darmstadt.DE>
+ */
+
+/*
+ * A note on terminology. DDC1 is the original dumb serial protocol, and
+ * can only do up to 128 bytes of EDID. DDC2 is I2C-encapsulated and
+ * introduces extension blocks. EDID is the old display identification
+ * block, DisplayID is the new one.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86DDC.h"
+#include <string.h>
+
+#define RETRIES 4
+
+typedef enum {
+ DDCOPT_NODDC1,
+ DDCOPT_NODDC2,
+ DDCOPT_NODDC
+} DDCOpts;
+
+static const OptionInfoRec DDCOptions[] = {
+ { DDCOPT_NODDC1, "NoDDC1", OPTV_BOOLEAN, {0}, FALSE },
+ { DDCOPT_NODDC2, "NoDDC2", OPTV_BOOLEAN, {0}, FALSE },
+ { DDCOPT_NODDC, "NoDDC", OPTV_BOOLEAN, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE },
+};
+
+/* DDC1 */
+
+static int
+find_start(unsigned int *ptr)
+{
+ unsigned int comp[9], test[9];
+ int i,j;
+
+ for (i=0;i<9;i++){
+ comp[i] = *(ptr++);
+ test[i] = 1;
+ }
+ for (i=0;i<127;i++){
+ for (j=0;j<9;j++){
+ test[j] = test[j] & !(comp[j] ^ *(ptr++));
+ }
+ }
+ for (i=0;i<9;i++)
+ if (test[i]) return (i+1);
+ return (-1);
+}
+
+static unsigned char *
+find_header(unsigned char *block)
+{
+ unsigned char *ptr, *head_ptr, *end;
+ unsigned char header[]={0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00};
+
+ ptr = block;
+ end = block + EDID1_LEN;
+ while (ptr<end) {
+ int i;
+ head_ptr = ptr;
+ for (i=0;i<8;i++){
+ if (header[i] != *(head_ptr++)) break;
+ if (head_ptr == end) head_ptr = block;
+ }
+ if (i==8) break;
+ ptr++;
+ }
+ if (ptr == end) return (NULL);
+ return (ptr);
+}
+
+static unsigned char *
+resort(unsigned char *s_block)
+{
+ unsigned char *d_new, *d_ptr, *d_end, *s_ptr, *s_end;
+ unsigned char tmp;
+
+ s_end = s_block + EDID1_LEN;
+ d_new = malloc(EDID1_LEN);
+ if (!d_new) return NULL;
+ d_end = d_new + EDID1_LEN;
+
+ s_ptr = find_header(s_block);
+ if (!s_ptr) return NULL;
+ for (d_ptr=d_new;d_ptr<d_end;d_ptr++){
+ tmp = *(s_ptr++);
+ *d_ptr = tmp;
+ if (s_ptr == s_end) s_ptr = s_block;
+ }
+ free(s_block);
+ return (d_new);
+}
+
+static int
+DDC_checksum(unsigned char *block, int len)
+{
+ int i, result = 0;
+ int not_null = 0;
+
+ for (i=0;i<len;i++) {
+ not_null |= block[i];
+ result += block[i];
+ }
+
+#ifdef DEBUG
+ if (result & 0xFF) ErrorF("DDC checksum not correct\n");
+ if (!not_null) ErrorF("DDC read all Null\n");
+#endif
+
+ /* catch the trivial case where all bytes are 0 */
+ if (!not_null) return 1;
+
+ return (result&0xFF);
+}
+
+static unsigned char *
+GetEDID_DDC1(unsigned int *s_ptr)
+{
+ unsigned char *d_block, *d_pos;
+ unsigned int *s_pos, *s_end;
+ int s_start;
+ int i,j;
+ s_start = find_start(s_ptr);
+ if (s_start==-1) return NULL;
+ s_end = s_ptr + NUM;
+ s_pos = s_ptr + s_start;
+ d_block=malloc(EDID1_LEN);
+ if (!d_block) return NULL;
+ d_pos = d_block;
+ for (i=0;i<EDID1_LEN;i++) {
+ for (j=0;j<8;j++) {
+ *d_pos <<= 1;
+ if (*s_pos) {
+ *d_pos |= 0x01;
+ }
+ s_pos++; if (s_pos == s_end) s_pos=s_ptr;
+ };
+ s_pos++; if (s_pos == s_end) s_pos=s_ptr;
+ d_pos++;
+ }
+ free(s_ptr);
+ if (d_block && DDC_checksum(d_block,EDID1_LEN)) return NULL;
+ return (resort(d_block));
+}
+
+/* fetch entire EDID record; DDC bit needs to be masked */
+static unsigned int *
+FetchEDID_DDC1(register ScrnInfoPtr pScrn,
+ register unsigned int (*read_DDC)(ScrnInfoPtr))
+{
+ int count = NUM;
+ unsigned int *ptr, *xp;
+
+ ptr=xp=malloc(sizeof(int)*NUM);
+
+ if (!ptr) return NULL;
+ do {
+ /* wait for next retrace */
+ *xp = read_DDC(pScrn);
+ xp++;
+ } while(--count);
+ return (ptr);
+}
+
+/* test if DDC1 return 0 if not */
+static Bool
+TestDDC1(ScrnInfoPtr pScrn, unsigned int (*read_DDC)(ScrnInfoPtr))
+{
+ int old, count;
+
+ old = read_DDC(pScrn);
+ count = HEADER * BITS_PER_BYTE;
+ do {
+ /* wait for next retrace */
+ if (old != read_DDC(pScrn)) break;
+ } while(count--);
+ return (count);
+}
+
+/*
+ * read EDID record , pass it to callback function to interpret.
+ * callback function will store it for further use by calling
+ * function; it will also decide if we need to reread it
+ */
+static unsigned char *
+EDIDRead_DDC1(ScrnInfoPtr pScrn, DDC1SetSpeedProc DDCSpeed,
+ unsigned int (*read_DDC)(ScrnInfoPtr))
+{
+ unsigned char *EDID_block = NULL;
+ int count = RETRIES;
+
+ if (!read_DDC) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
+ "chipset doesn't support DDC1\n");
+ return NULL;
+ };
+
+ if (TestDDC1(pScrn,read_DDC)==-1) {
+ xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "No DDC signal\n");
+ return NULL;
+ };
+
+ if (DDCSpeed) DDCSpeed(pScrn,DDC_FAST);
+ do {
+ EDID_block = GetEDID_DDC1(FetchEDID_DDC1(pScrn,read_DDC));
+ count --;
+ } while (!EDID_block && count);
+ if (DDCSpeed) DDCSpeed(pScrn,DDC_SLOW);
+
+ return EDID_block;
+}
+
+/**
+ * Attempts to probe the monitor for EDID information, if NoDDC and NoDDC1 are
+ * unset. EDID information blocks are interpreted and the results returned in
+ * an xf86MonPtr.
+ *
+ * This function does not affect the list of modes used by drivers -- it is up
+ * to the driver to decide policy on what to do with EDID information.
+ *
+ * @return pointer to a new xf86MonPtr containing the EDID information.
+ * @return NULL if no monitor attached or failure to interpret the EDID.
+ */
+xf86MonPtr
+xf86DoEDID_DDC1(
+ int scrnIndex, DDC1SetSpeedProc DDC1SetSpeed,
+ unsigned int (*DDC1Read)(ScrnInfoPtr)
+)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ unsigned char *EDID_block = NULL;
+ xf86MonPtr tmp = NULL;
+ int sigio;
+ /* Default DDC and DDC1 to enabled. */
+ Bool noddc = FALSE, noddc1 = FALSE;
+ OptionInfoPtr options;
+
+ options = xnfalloc(sizeof(DDCOptions));
+ (void)memcpy(options, DDCOptions, sizeof(DDCOptions));
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
+
+ xf86GetOptValBool(options, DDCOPT_NODDC, &noddc);
+ xf86GetOptValBool(options, DDCOPT_NODDC1, &noddc1);
+ free(options);
+
+ if (noddc || noddc1)
+ return NULL;
+
+ sigio = xf86BlockSIGIO();
+ EDID_block = EDIDRead_DDC1(pScrn,DDC1SetSpeed,DDC1Read);
+ xf86UnblockSIGIO(sigio);
+
+ if (EDID_block){
+ tmp = xf86InterpretEDID(scrnIndex,EDID_block);
+ }
+#ifdef DEBUG
+ else ErrorF("No EDID block returned\n");
+ if (!tmp)
+ ErrorF("Cannot interpret EDID block\n");
+#endif
+ return tmp;
+}
+
+/* DDC2 */
+
+static I2CDevPtr
+DDC2MakeDevice(I2CBusPtr pBus, int address, char *name)
+{
+ I2CDevPtr dev = NULL;
+
+ if (!(dev = xf86I2CFindDev(pBus, address))) {
+ dev = xf86CreateI2CDevRec();
+ dev->DevName = name;
+ dev->SlaveAddr = address;
+ dev->ByteTimeout = 2200; /* VESA DDC spec 3 p. 43 (+10 %) */
+ dev->StartTimeout = 550;
+ dev->BitTimeout = 40;
+ dev->AcknTimeout = 40;
+
+ dev->pI2CBus = pBus;
+ if (!xf86I2CDevInit(dev)) {
+ xf86DrvMsg(pBus->scrnIndex, X_PROBED, "No DDC2 device\n");
+ return NULL;
+ }
+ }
+
+ return dev;
+}
+
+static I2CDevPtr
+DDC2Init(int scrnIndex, I2CBusPtr pBus)
+{
+ I2CDevPtr dev = NULL;
+
+ /*
+ * Slow down the bus so that older monitors don't
+ * miss things.
+ */
+ pBus->RiseFallTime = 20;
+
+ dev = DDC2MakeDevice(pBus, 0x00A0, "ddc2");
+ if (xf86I2CProbeAddress(pBus, 0x0060))
+ DDC2MakeDevice(pBus, 0x0060, "E-EDID segment register");
+ if (xf86I2CProbeAddress(pBus, 0x0062))
+ DDC2MakeDevice(pBus, 0x0062, "EDID EEPROM interface");
+ if (xf86I2CProbeAddress(pBus, 0x006E))
+ DDC2MakeDevice(pBus, 0x006E, "DDC control interface");
+
+ return dev;
+}
+
+/* Mmmm, smell the hacks */
+static void
+EEDIDStop(I2CDevPtr d)
+{
+}
+
+/* block is the EDID block number. a segment is two blocks. */
+static Bool
+DDC2Read(I2CDevPtr dev, int block, unsigned char *R_Buffer)
+{
+ unsigned char W_Buffer[1];
+ int i, segment;
+ I2CDevPtr seg;
+ void (*stop)(I2CDevPtr);
+
+ for (i = 0; i < RETRIES; i++) {
+ /* Stop bits reset the segment pointer to 0, so be careful here. */
+ segment = block >> 1;
+ if (segment) {
+ Bool b;
+
+ if (!(seg = xf86I2CFindDev(dev->pI2CBus, 0x0060)))
+ return FALSE;
+
+ W_Buffer[0] = segment;
+
+ stop = dev->pI2CBus->I2CStop;
+ dev->pI2CBus->I2CStop = EEDIDStop;
+
+ b = xf86I2CWriteRead(seg, W_Buffer, 1, NULL, 0);
+
+ dev->pI2CBus->I2CStop = stop;
+ if (!b) {
+ dev->pI2CBus->I2CStop(dev);
+ continue;
+ }
+ }
+
+ W_Buffer[0] = (block & 0x01) * EDID1_LEN;
+
+ if (xf86I2CWriteRead(dev, W_Buffer, 1, R_Buffer, EDID1_LEN)) {
+ if (!DDC_checksum(R_Buffer, EDID1_LEN))
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/**
+ * Attempts to probe the monitor for EDID information, if NoDDC and NoDDC2 are
+ * unset. EDID information blocks are interpreted and the results returned in
+ * an xf86MonPtr. Unlike xf86DoEDID_DDC[12](), this function will return
+ * the complete EDID data, including all extension blocks, if the 'complete'
+ * parameter is TRUE;
+ *
+ * This function does not affect the list of modes used by drivers -- it is up
+ * to the driver to decide policy on what to do with EDID information.
+ *
+ * @return pointer to a new xf86MonPtr containing the EDID information.
+ * @return NULL if no monitor attached or failure to interpret the EDID.
+ */
+xf86MonPtr
+xf86DoEEDID(int scrnIndex, I2CBusPtr pBus, Bool complete)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ unsigned char *EDID_block = NULL;
+ xf86MonPtr tmp = NULL;
+ I2CDevPtr dev = NULL;
+ /* Default DDC and DDC2 to enabled. */
+ Bool noddc = FALSE, noddc2 = FALSE;
+ OptionInfoPtr options;
+
+ options = malloc(sizeof(DDCOptions));
+ if (!options)
+ return NULL;
+ memcpy(options, DDCOptions, sizeof(DDCOptions));
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
+
+ xf86GetOptValBool(options, DDCOPT_NODDC, &noddc);
+ xf86GetOptValBool(options, DDCOPT_NODDC2, &noddc2);
+ free(options);
+
+ if (noddc || noddc2)
+ return NULL;
+
+ if (!(dev = DDC2Init(scrnIndex, pBus)))
+ return NULL;
+
+ EDID_block = calloc(1, EDID1_LEN);
+ if (!EDID_block)
+ return NULL;
+
+ if (DDC2Read(dev, 0, EDID_block)) {
+ int i, n = EDID_block[0x7e];
+
+ if (complete && n) {
+ EDID_block = realloc(EDID_block, EDID1_LEN * (1+n));
+
+ for (i = 0; i < n; i++)
+ DDC2Read(dev, i+1, EDID_block + (EDID1_LEN * (1+i)));
+ }
+
+ tmp = xf86InterpretEEDID(scrnIndex, EDID_block);
+ }
+
+ if (tmp && complete)
+ tmp->flags |= MONITOR_EDID_COMPLETE_RAWDATA;
+
+ return tmp;
+}
+
+/**
+ * Attempts to probe the monitor for EDID information, if NoDDC and NoDDC2 are
+ * unset. EDID information blocks are interpreted and the results returned in
+ * an xf86MonPtr.
+ *
+ * This function does not affect the list of modes used by drivers -- it is up
+ * to the driver to decide policy on what to do with EDID information.
+ *
+ * @return pointer to a new xf86MonPtr containing the EDID information.
+ * @return NULL if no monitor attached or failure to interpret the EDID.
+ */
+xf86MonPtr
+xf86DoEDID_DDC2(int scrnIndex, I2CBusPtr pBus)
+{
+ return xf86DoEEDID(scrnIndex, pBus, FALSE);
+}
+
+/* XXX write me */
+static void *
+DDC2ReadDisplayID(void)
+{
+ return FALSE;
+}
+
+/**
+ * Attempts to probe the monitor for DisplayID information, if NoDDC and
+ * NoDDC2 are unset. DisplayID blocks are interpreted and the results
+ * returned in an xf86MonPtr.
+ *
+ * This function does not affect the list of modes used by drivers -- it is up
+ * to the driver to decide policy on what to do with DisplayID information.
+ *
+ * @return pointer to a new xf86MonPtr containing the DisplayID information.
+ * @return NULL if no monitor attached or failure to interpret the DisplayID.
+ */
+xf86MonPtr
+xf86DoDisplayID(int scrnIndex, I2CBusPtr pBus)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ unsigned char *did = NULL;
+ xf86MonPtr tmp = NULL;
+ I2CDevPtr dev = NULL;
+ /* Default DDC and DDC2 to enabled. */
+ Bool noddc = FALSE, noddc2 = FALSE;
+ OptionInfoPtr options;
+
+ options = malloc(sizeof(DDCOptions));
+ if (!options)
+ return NULL;
+ memcpy(options, DDCOptions, sizeof(DDCOptions));
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
+
+ xf86GetOptValBool(options, DDCOPT_NODDC, &noddc);
+ xf86GetOptValBool(options, DDCOPT_NODDC2, &noddc2);
+ free(options);
+
+ if (noddc || noddc2)
+ return NULL;
+
+ if (!(dev = DDC2Init(scrnIndex, pBus)))
+ return NULL;
+
+ if ((did = DDC2ReadDisplayID())) {
+ tmp = calloc(1, sizeof(*tmp));
+ if (!tmp)
+ return NULL;
+
+ tmp->scrnIndex = scrnIndex;
+ tmp->flags |= MONITOR_DISPLAYID;
+ tmp->rawData = did;
+ }
+
+ return tmp;
+}
diff --git a/xorg-server/hw/xfree86/ddc/ddcProperty.c b/xorg-server/hw/xfree86/ddc/ddcProperty.c
index 329a63964..d4ae1006d 100644
--- a/xorg-server/hw/xfree86/ddc/ddcProperty.c
+++ b/xorg-server/hw/xfree86/ddc/ddcProperty.c
@@ -1,125 +1,125 @@
-/*
- * Copyright 2006 Luc Verhaegen.
- *
- * 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, sub license,
- * 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 (including the
- * next paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "xf86.h"
-#include "xf86DDC.h"
-#include <X11/Xatom.h>
-#include "property.h"
-#include "propertyst.h"
-#include "xf86DDC.h"
-#include <string.h>
-
-#define EDID1_ATOM_NAME "XFree86_DDC_EDID1_RAWDATA"
-#define EDID2_ATOM_NAME "XFree86_DDC_EDID2_RAWDATA"
-
-static void
-edidMakeAtom(int i, const char *name, CARD8 *data, int size)
-{
- Atom atom;
- unsigned char *atom_data;
-
- if (!(atom_data = xalloc(size*sizeof(CARD8))))
- return;
-
- atom = MakeAtom(name, strlen(name), TRUE);
- memcpy(atom_data, data, size);
- xf86RegisterRootWindowProperty(i, atom, XA_INTEGER, 8, size, atom_data);
-}
-
-static void
-addRootWindowProperties(ScrnInfoPtr pScrn, xf86MonPtr DDC)
-{
- int i, scrnIndex = pScrn->scrnIndex;
- Bool makeEDID1prop = FALSE;
- Bool makeEDID2prop = FALSE;
-
- if (DDC->flags & MONITOR_DISPLAYID) {
- /* Don't bother, use RANDR already */
- return;
- } else if (DDC->ver.version == 1) {
- makeEDID1prop = TRUE;
- } else if (DDC->ver.version == 2) {
- int checksum1;
- int checksum2;
- makeEDID2prop = TRUE;
-
- /* Some monitors (eg Panasonic PanaSync4)
- * report version==2 because they used EDID v2 spec document,
- * although they use EDID v1 data structure :-(
- *
- * Try using checksum to determine when we have such a monitor.
- */
- checksum2 = 0;
- for (i = 0; i < 256; i++)
- checksum2 += DDC->rawData[i];
- if (checksum2 % 256) {
- xf86DrvMsg(scrnIndex, X_INFO, "Monitor EDID v2 checksum failed\n");
- xf86DrvMsg(scrnIndex, X_INFO,
- "XFree86_DDC_EDID2_RAWDATA property may be bad\n");
- checksum1 = 0;
- for (i = 0; i < 128; i++)
- checksum1 += DDC->rawData[i];
- if (!(checksum1 % 256)) {
- xf86DrvMsg(scrnIndex, X_INFO,
- "Monitor EDID v1 checksum passed,\n");
- xf86DrvMsg(scrnIndex, X_INFO,
- "XFree86_DDC_EDID1_RAWDATA property created\n");
- makeEDID1prop = TRUE;
- }
- }
- } else {
- xf86DrvMsg(scrnIndex, X_PROBED, "unexpected EDID version %d.%d\n",
- DDC->ver.version, DDC->ver.revision);
- return;
- }
-
- if (makeEDID1prop) {
- int size = 128 +
- (DDC->flags & EDID_COMPLETE_RAWDATA ? DDC->no_sections * 128 : 0);
-
- edidMakeAtom(scrnIndex, EDID1_ATOM_NAME, DDC->rawData, size);
- }
-
- if (makeEDID2prop)
- edidMakeAtom(scrnIndex, EDID2_ATOM_NAME, DDC->rawData, 256);
-}
-
-Bool
-xf86SetDDCproperties(ScrnInfoPtr pScrn, xf86MonPtr DDC)
-{
- if (!pScrn || !pScrn->monitor || !DDC)
- return FALSE;
-
- if (DDC->flags & MONITOR_DISPLAYID)
- ;
- else
- xf86EdidMonitorSet(pScrn->scrnIndex, pScrn->monitor, DDC);
-
- addRootWindowProperties(pScrn, DDC);
-
- return TRUE;
-}
+/*
+ * Copyright 2006 Luc Verhaegen.
+ *
+ * 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, sub license,
+ * 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 (including the
+ * next paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "xf86.h"
+#include "xf86DDC.h"
+#include <X11/Xatom.h>
+#include "property.h"
+#include "propertyst.h"
+#include "xf86DDC.h"
+#include <string.h>
+
+#define EDID1_ATOM_NAME "XFree86_DDC_EDID1_RAWDATA"
+#define EDID2_ATOM_NAME "XFree86_DDC_EDID2_RAWDATA"
+
+static void
+edidMakeAtom(int i, const char *name, CARD8 *data, int size)
+{
+ Atom atom;
+ unsigned char *atom_data;
+
+ if (!(atom_data = malloc(size*sizeof(CARD8))))
+ return;
+
+ atom = MakeAtom(name, strlen(name), TRUE);
+ memcpy(atom_data, data, size);
+ xf86RegisterRootWindowProperty(i, atom, XA_INTEGER, 8, size, atom_data);
+}
+
+static void
+addRootWindowProperties(ScrnInfoPtr pScrn, xf86MonPtr DDC)
+{
+ int i, scrnIndex = pScrn->scrnIndex;
+ Bool makeEDID1prop = FALSE;
+ Bool makeEDID2prop = FALSE;
+
+ if (DDC->flags & MONITOR_DISPLAYID) {
+ /* Don't bother, use RANDR already */
+ return;
+ } else if (DDC->ver.version == 1) {
+ makeEDID1prop = TRUE;
+ } else if (DDC->ver.version == 2) {
+ int checksum1;
+ int checksum2;
+ makeEDID2prop = TRUE;
+
+ /* Some monitors (eg Panasonic PanaSync4)
+ * report version==2 because they used EDID v2 spec document,
+ * although they use EDID v1 data structure :-(
+ *
+ * Try using checksum to determine when we have such a monitor.
+ */
+ checksum2 = 0;
+ for (i = 0; i < 256; i++)
+ checksum2 += DDC->rawData[i];
+ if (checksum2 % 256) {
+ xf86DrvMsg(scrnIndex, X_INFO, "Monitor EDID v2 checksum failed\n");
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "XFree86_DDC_EDID2_RAWDATA property may be bad\n");
+ checksum1 = 0;
+ for (i = 0; i < 128; i++)
+ checksum1 += DDC->rawData[i];
+ if (!(checksum1 % 256)) {
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Monitor EDID v1 checksum passed,\n");
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "XFree86_DDC_EDID1_RAWDATA property created\n");
+ makeEDID1prop = TRUE;
+ }
+ }
+ } else {
+ xf86DrvMsg(scrnIndex, X_PROBED, "unexpected EDID version %d.%d\n",
+ DDC->ver.version, DDC->ver.revision);
+ return;
+ }
+
+ if (makeEDID1prop) {
+ int size = 128 +
+ (DDC->flags & EDID_COMPLETE_RAWDATA ? DDC->no_sections * 128 : 0);
+
+ edidMakeAtom(scrnIndex, EDID1_ATOM_NAME, DDC->rawData, size);
+ }
+
+ if (makeEDID2prop)
+ edidMakeAtom(scrnIndex, EDID2_ATOM_NAME, DDC->rawData, 256);
+}
+
+Bool
+xf86SetDDCproperties(ScrnInfoPtr pScrn, xf86MonPtr DDC)
+{
+ if (!pScrn || !pScrn->monitor || !DDC)
+ return FALSE;
+
+ if (DDC->flags & MONITOR_DISPLAYID)
+ ;
+ else
+ xf86EdidMonitorSet(pScrn->scrnIndex, pScrn->monitor, DDC);
+
+ addRootWindowProperties(pScrn, DDC);
+
+ return TRUE;
+}
diff --git a/xorg-server/hw/xfree86/ddc/interpret_edid.c b/xorg-server/hw/xfree86/ddc/interpret_edid.c
index f3e593aec..1a2d2f487 100644
--- a/xorg-server/hw/xfree86/ddc/interpret_edid.c
+++ b/xorg-server/hw/xfree86/ddc/interpret_edid.c
@@ -1,685 +1,685 @@
-/*
- * Copyright 1998 by Egbert Eich <Egbert.Eich@Physik.TU-Darmstadt.DE>
- * Copyright 2007 Red Hat, 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 (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * interpret_edid.c: interpret a primary EDID block
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "misc.h"
-#include "xf86.h"
-#include "xf86_OSproc.h"
-#define _PARSE_EDID_
-#include "xf86DDC.h"
-#include <string.h>
-
-static void get_vendor_section(Uchar*, struct vendor *);
-static void get_version_section(Uchar*, struct edid_version *);
-static void get_display_section(Uchar*, struct disp_features *,
- struct edid_version *);
-static void get_established_timing_section(Uchar*, struct established_timings *);
-static void get_std_timing_section(Uchar*, struct std_timings *,
- struct edid_version *);
-static void fetch_detailed_block(Uchar *c, struct edid_version *ver,
- struct detailed_monitor_section *det_mon);
-static void get_dt_md_section(Uchar *, struct edid_version *,
- struct detailed_monitor_section *det_mon);
-static void copy_string(Uchar *, Uchar *);
-static void get_dst_timing_section(Uchar *, struct std_timings *,
- struct edid_version *);
-static void get_monitor_ranges(Uchar *, struct monitor_ranges *);
-static void get_whitepoint_section(Uchar *, struct whitePoints *);
-static void get_detailed_timing_section(Uchar*, struct detailed_timings *);
-static Bool validate_version(int scrnIndex, struct edid_version *);
-
-static void
-find_ranges_section(struct detailed_monitor_section *det, void *ranges)
-{
- if (det->type == DS_RANGES && det->section.ranges.max_clock)
- *(struct monitor_ranges **)ranges = &det->section.ranges;
-}
-
-static void
-find_max_detailed_clock(struct detailed_monitor_section *det, void *ret)
-{
- if (det->type == DT) {
- *(int *)ret = max(*((int *)ret),
- det->section.d_timings.clock);
- }
-}
-
-static void
-handle_edid_quirks(xf86MonPtr m)
-{
- struct monitor_ranges *ranges = NULL;
-
- /*
- * max_clock is only encoded in EDID in tens of MHz, so occasionally we
- * find a monitor claiming a max of 160 with a mode requiring 162, or
- * similar. Strictly we should refuse to round up too far, but let's
- * see how well this works.
- */
-
- /* Try to find Monitor Range and max clock, then re-set range value*/
- xf86ForEachDetailedBlock(m, find_ranges_section, &ranges);
- if (ranges && ranges->max_clock) {
- int clock = 0;
- xf86ForEachDetailedBlock(m, find_max_detailed_clock, &clock);
- if (clock && (ranges->max_clock * 1e6 < clock)) {
- xf86Msg(X_WARNING, "EDID timing clock %.2f exceeds claimed max "
- "%dMHz, fixing\n", clock / 1.0e6, ranges->max_clock);
- ranges->max_clock = (clock+999999)/1e6;
- }
- }
-}
-
-struct det_hv_parameter {
- int real_hsize;
- int real_vsize;
- float target_aspect;
-};
-
-static void handle_detailed_hvsize(struct detailed_monitor_section *det_mon,
- void *data)
-{
- struct det_hv_parameter *p = (struct det_hv_parameter *)data;
- float timing_aspect;
-
- if (det_mon->type == DT) {
- struct detailed_timings *timing;
- timing = &det_mon->section.d_timings;
-
- if (!timing->v_size)
- return;
-
- timing_aspect = (float)timing->h_size / timing->v_size;
- if (fabs(1 - (timing_aspect / p->target_aspect)) < 0.05) {
- p->real_hsize = max(p->real_hsize, timing->h_size);
- p->real_vsize = max(p->real_vsize, timing->v_size);
- }
- }
-}
-
-static void encode_aspect_ratio(xf86MonPtr m)
-{
- /*
- * some monitors encode the aspect ratio instead of the physical size.
- * try to find the largest detailed timing that matches that aspect
- * ratio and use that to fill in the feature section.
- */
- if ((m->features.hsize == 16 && m->features.vsize == 9) ||
- (m->features.hsize == 16 && m->features.vsize == 10) ||
- (m->features.hsize == 4 && m->features.vsize == 3) ||
- (m->features.hsize == 5 && m->features.vsize == 4)) {
-
- struct det_hv_parameter p;
- p.real_hsize = 0;
- p.real_vsize = 0;
- p.target_aspect = (float)m->features.hsize /m->features.vsize;
-
- xf86ForEachDetailedBlock(m, handle_detailed_hvsize, &p);
-
- if (!p.real_hsize || !p.real_vsize) {
- m->features.hsize = m->features.vsize = 0;
- } else if ((m->features.hsize * 10 == p.real_hsize) &&
- (m->features.vsize * 10 == p.real_vsize)) {
- /* exact match is just unlikely, should do a better check though */
- m->features.hsize = m->features.vsize = 0;
- } else {
- /* convert mm to cm */
- m->features.hsize = (p.real_hsize + 5) / 10;
- m->features.vsize = (p.real_vsize + 5) / 10;
- }
-
- xf86Msg(X_INFO, "Quirked EDID physical size to %dx%d cm\n",
- m->features.hsize, m->features.vsize);
- }
-}
-
-xf86MonPtr
-xf86InterpretEDID(int scrnIndex, Uchar *block)
-{
- xf86MonPtr m;
-
- if (!block) return NULL;
- if (! (m = xnfcalloc(sizeof(xf86Monitor),1))) return NULL;
- m->scrnIndex = scrnIndex;
- m->rawData = block;
-
- get_vendor_section(SECTION(VENDOR_SECTION,block),&m->vendor);
- get_version_section(SECTION(VERSION_SECTION,block),&m->ver);
- if (!validate_version(scrnIndex, &m->ver)) goto error;
- get_display_section(SECTION(DISPLAY_SECTION,block),&m->features,
- &m->ver);
- get_established_timing_section(SECTION(ESTABLISHED_TIMING_SECTION,block),
- &m->timings1);
- get_std_timing_section(SECTION(STD_TIMING_SECTION,block),m->timings2,
- &m->ver);
- get_dt_md_section(SECTION(DET_TIMING_SECTION,block),&m->ver, m->det_mon);
- m->no_sections = (int)*(char *)SECTION(NO_EDID,block);
-
- handle_edid_quirks(m);
- encode_aspect_ratio(m);
-
- return (m);
-
- error:
- xfree(m);
- return NULL;
-}
-
-static int get_cea_detail_timing(Uchar *blk, xf86MonPtr mon,
- struct detailed_monitor_section *det_mon)
-{
- int dt_num;
- int dt_offset = ((struct cea_ext_body *)blk)->dt_offset;
-
- dt_num = 0;
-
- if (dt_offset < CEA_EXT_MIN_DATA_OFFSET)
- return dt_num;
-
- for (; dt_offset < (CEA_EXT_MAX_DATA_OFFSET - DET_TIMING_INFO_LEN) &&
- dt_num < CEA_EXT_DET_TIMING_NUM;
- _NEXT_DT_MD_SECTION(dt_offset)) {
-
- fetch_detailed_block(blk + dt_offset, &mon->ver, det_mon + dt_num);
- dt_num = dt_num + 1 ;
- }
-
- return dt_num;
-}
-
-static void handle_cea_detail_block(Uchar *ext, xf86MonPtr mon,
- handle_detailed_fn fn,
- void *data)
-{
- int i;
- struct detailed_monitor_section det_mon[CEA_EXT_DET_TIMING_NUM];
- int det_mon_num;
-
- det_mon_num = get_cea_detail_timing(ext, mon, det_mon);
-
- for (i = 0; i < det_mon_num; i++)
- fn(det_mon + i, data);
-}
-
-void xf86ForEachDetailedBlock(xf86MonPtr mon,
- handle_detailed_fn fn,
- void *data)
-{
- int i;
- Uchar *ext;
-
- if (mon == NULL)
- return;
-
- for (i = 0; i < DET_TIMINGS; i++)
- fn(mon->det_mon + i, data);
-
- for (i = 0; i < mon->no_sections; i++) {
- ext = mon->rawData + EDID1_LEN * (i + 1);
- switch (ext[EXT_TAG]){
- case CEA_EXT:
- handle_cea_detail_block(ext, mon, fn, data);
- break;
- case VTB_EXT:
- case DI_EXT:
- case LS_EXT:
- case MI_EXT:
- break;
- }
- }
-}
-
-static struct cea_data_block *
-extract_cea_data_block(Uchar *ext, int data_type)
-{
- struct cea_ext_body *cea;
- struct cea_data_block *data_collection;
- struct cea_data_block *data_end;
-
- cea = (struct cea_ext_body *)ext;
-
- if (cea->dt_offset <= CEA_EXT_MIN_DATA_OFFSET)
- return NULL;
-
- data_collection = &cea->data_collection;
- data_end = (struct cea_data_block *)(cea->dt_offset + ext);
-
- for ( ;data_collection < data_end;) {
-
- if (data_type == data_collection->tag) {
- return data_collection;
- }
- data_collection = (void *)((unsigned char *)data_collection +
- data_collection->len + 1);
- }
-
- return NULL;
-}
-
-static void handle_cea_video_block(Uchar *ext, handle_video_fn fn, void *data)
-{
- struct cea_video_block *video;
- struct cea_video_block *video_end;
- struct cea_data_block *data_collection;
-
- data_collection = extract_cea_data_block(ext, CEA_VIDEO_BLK);
- if (data_collection == NULL)
- return;
-
- video = &data_collection->u.video;
- video_end = (struct cea_video_block *)
- ((Uchar *)video + data_collection->len);
-
- for (; video < video_end; video = video + 1) {
- fn(video, data);
- }
-}
-
-void xf86ForEachVideoBlock(xf86MonPtr mon,
- handle_video_fn fn,
- void *data)
-{
- int i;
- Uchar *ext;
-
- if (mon == NULL)
- return;
-
- for (i = 0; i < mon->no_sections; i++) {
- ext = mon->rawData + EDID1_LEN * (i + 1);
- switch (ext[EXT_TAG]) {
- case CEA_EXT:
- handle_cea_video_block(ext, fn, data);
- break;
- case VTB_EXT:
- case DI_EXT:
- case LS_EXT:
- case MI_EXT:
- break;
- }
- }
-}
-
-xf86MonPtr
-xf86InterpretEEDID(int scrnIndex, Uchar *block)
-{
- xf86MonPtr m;
-
- m = xf86InterpretEDID(scrnIndex, block);
- if (!m)
- return NULL;
-
- /* extension parse */
-
- return m;
-}
-
-static void
-get_vendor_section(Uchar *c, struct vendor *r)
-{
- r->name[0] = L1;
- r->name[1] = L2;
- r->name[2] = L3;
- r->name[3] = '\0';
-
- r->prod_id = PROD_ID;
- r->serial = SERIAL_NO;
- r->week = WEEK;
- r->year = YEAR;
-}
-
-static void
-get_version_section(Uchar *c, struct edid_version *r)
-{
- r->version = VERSION;
- r->revision = REVISION;
-}
-
-static void
-get_display_section(Uchar *c, struct disp_features *r,
- struct edid_version *v)
-{
- r->input_type = INPUT_TYPE;
- if (!DIGITAL(r->input_type)) {
- r->input_voltage = INPUT_VOLTAGE;
- r->input_setup = SETUP;
- r->input_sync = SYNC;
- } else if (v->revision == 2 || v->revision == 3) {
- r->input_dfp = DFP;
- } else if (v->revision >= 4) {
- r->input_bpc = BPC;
- r->input_interface = DIGITAL_INTERFACE;
- }
- r->hsize = HSIZE_MAX;
- r->vsize = VSIZE_MAX;
- r->gamma = GAMMA;
- r->dpms = DPMS;
- r->display_type = DISPLAY_TYPE;
- r->msc = MSC;
- r->redx = REDX;
- r->redy = REDY;
- r->greenx = GREENX;
- r->greeny = GREENY;
- r->bluex = BLUEX;
- r->bluey = BLUEY;
- r->whitex = WHITEX;
- r->whitey = WHITEY;
-}
-
-static void
-get_established_timing_section(Uchar *c, struct established_timings *r)
-{
- r->t1 = T1;
- r->t2 = T2;
- r->t_manu = T_MANU;
-}
-
-static void
-get_cvt_timing_section(Uchar *c, struct cvt_timings *r)
-{
- int i;
-
- for (i = 0; i < 4; i++) {
- if (c[0] && c[1] && c[2]) {
- r[i].height = (c[0] + ((c[1] & 0xF0) << 8) + 1) * 2;
- switch (c[1] & 0xc0) {
- case 0x00: r[i].width = r[i].height * 4 / 3; break;
- case 0x40: r[i].width = r[i].height * 16 / 9; break;
- case 0x80: r[i].width = r[i].height * 16 / 10; break;
- case 0xc0: r[i].width = r[i].height * 15 / 9; break;
- }
- switch (c[2] & 0x60) {
- case 0x00: r[i].rate = 50; break;
- case 0x20: r[i].rate = 60; break;
- case 0x40: r[i].rate = 75; break;
- case 0x60: r[i].rate = 85; break;
- }
- r[i].rates = c[2] & 0x1f;
- } else {
- return;
- }
- c += 3;
- }
-}
-
-static void
-get_std_timing_section(Uchar *c, struct std_timings *r,
- struct edid_version *v)
-{
- int i;
-
- for (i=0;i<STD_TIMINGS;i++){
- if (VALID_TIMING) {
- r[i].hsize = HSIZE1;
- VSIZE1(r[i].vsize);
- r[i].refresh = REFRESH_R;
- r[i].id = STD_TIMING_ID;
- } else {
- r[i].hsize = r[i].vsize = r[i].refresh = r[i].id = 0;
- }
- NEXT_STD_TIMING;
- }
-}
-
-static const unsigned char empty_block[18];
-
-static void
-fetch_detailed_block(Uchar *c, struct edid_version *ver,
- struct detailed_monitor_section *det_mon)
-{
- if (ver->version == 1 && ver->revision >= 1 && IS_MONITOR_DESC) {
- switch (MONITOR_DESC_TYPE) {
- case SERIAL_NUMBER:
- det_mon->type = DS_SERIAL;
- copy_string(c,det_mon->section.serial);
- break;
- case ASCII_STR:
- det_mon->type = DS_ASCII_STR;
- copy_string(c,det_mon->section.ascii_data);
- break;
- case MONITOR_RANGES:
- det_mon->type = DS_RANGES;
- get_monitor_ranges(c,&det_mon->section.ranges);
- break;
- case MONITOR_NAME:
- det_mon->type = DS_NAME;
- copy_string(c,det_mon->section.name);
- break;
- case ADD_COLOR_POINT:
- det_mon->type = DS_WHITE_P;
- get_whitepoint_section(c,det_mon->section.wp);
- break;
- case ADD_STD_TIMINGS:
- det_mon->type = DS_STD_TIMINGS;
- get_dst_timing_section(c,det_mon->section.std_t, ver);
- break;
- case COLOR_MANAGEMENT_DATA:
- det_mon->type = DS_CMD;
- break;
- case CVT_3BYTE_DATA:
- det_mon->type = DS_CVT;
- get_cvt_timing_section(c, det_mon->section.cvt);
- break;
- case ADD_EST_TIMINGS:
- det_mon->type = DS_EST_III;
- memcpy(det_mon->section.est_iii, c + 6, 6);
- break;
- case ADD_DUMMY:
- det_mon->type = DS_DUMMY;
- break;
- default:
- det_mon->type = DS_UNKOWN;
- break;
- }
- if (c[3] <= 0x0F && memcmp(c, empty_block, sizeof(empty_block))) {
- det_mon->type = DS_VENDOR + c[3];
- }
- } else {
- det_mon->type = DT;
- get_detailed_timing_section(c, &det_mon->section.d_timings);
- }
-}
-
-static void
-get_dt_md_section(Uchar *c, struct edid_version *ver,
- struct detailed_monitor_section *det_mon)
-{
- int i;
-
- for (i=0; i < DET_TIMINGS; i++) {
- fetch_detailed_block(c, ver, det_mon + i);
- NEXT_DT_MD_SECTION;
- }
-}
-
-static void
-copy_string(Uchar *c, Uchar *s)
-{
- int i;
- c = c + 5;
- for (i = 0; (i < 13 && *c != 0x0A); i++)
- *(s++) = *(c++);
- *s = 0;
- while (i-- && (*--s == 0x20)) *s = 0;
-}
-
-static void
-get_dst_timing_section(Uchar *c, struct std_timings *t,
- struct edid_version *v)
-{
- int j;
- c = c + 5;
- for (j = 0; j < 5; j++) {
- t[j].hsize = HSIZE1;
- VSIZE1(t[j].vsize);
- t[j].refresh = REFRESH_R;
- t[j].id = STD_TIMING_ID;
- NEXT_STD_TIMING;
- }
-}
-
-static void
-get_monitor_ranges(Uchar *c, struct monitor_ranges *r)
-{
- r->min_v = MIN_V;
- r->max_v = MAX_V;
- r->min_h = MIN_H;
- r->max_h = MAX_H;
- r->max_clock = 0;
- if(MAX_CLOCK != 0xff) /* is specified? */
- r->max_clock = MAX_CLOCK * 10;
- if (HAVE_2ND_GTF) {
- r->gtf_2nd_f = F_2ND_GTF;
- r->gtf_2nd_c = C_2ND_GTF;
- r->gtf_2nd_m = M_2ND_GTF;
- r->gtf_2nd_k = K_2ND_GTF;
- r->gtf_2nd_j = J_2ND_GTF;
- } else {
- r->gtf_2nd_f = 0;
- }
- if (HAVE_CVT) {
- r->max_clock_khz = MAX_CLOCK_KHZ;
- r->max_clock = r->max_clock_khz / 1000;
- r->maxwidth = MAXWIDTH;
- r->supported_aspect = SUPPORTED_ASPECT;
- r->preferred_aspect = PREFERRED_ASPECT;
- r->supported_blanking = SUPPORTED_BLANKING;
- r->supported_scaling = SUPPORTED_SCALING;
- r->preferred_refresh = PREFERRED_REFRESH;
- } else {
- r->max_clock_khz = 0;
- }
-}
-
-static void
-get_whitepoint_section(Uchar *c, struct whitePoints *wp)
-{
- wp[0].white_x = WHITEX1;
- wp[0].white_y = WHITEY1;
- wp[1].white_x = WHITEX2;
- wp[1].white_y = WHITEY2;
- wp[0].index = WHITE_INDEX1;
- wp[1].index = WHITE_INDEX2;
- wp[0].white_gamma = WHITE_GAMMA1;
- wp[1].white_gamma = WHITE_GAMMA2;
-}
-
-static void
-get_detailed_timing_section(Uchar *c, struct detailed_timings *r)
-{
- r->clock = PIXEL_CLOCK;
- r->h_active = H_ACTIVE;
- r->h_blanking = H_BLANK;
- r->v_active = V_ACTIVE;
- r->v_blanking = V_BLANK;
- r->h_sync_off = H_SYNC_OFF;
- r->h_sync_width = H_SYNC_WIDTH;
- r->v_sync_off = V_SYNC_OFF;
- r->v_sync_width = V_SYNC_WIDTH;
- r->h_size = H_SIZE;
- r->v_size = V_SIZE;
- r->h_border = H_BORDER;
- r->v_border = V_BORDER;
- r->interlaced = INTERLACED;
- r->stereo = STEREO;
- r->stereo_1 = STEREO1;
- r->sync = SYNC_T;
- r->misc = MISC;
-}
-
-#define MAX_EDID_MINOR 4
-
-static Bool
-validate_version(int scrnIndex, struct edid_version *r)
-{
- if (r->version != 1) {
- xf86DrvMsg(scrnIndex, X_ERROR, "Unknown EDID version %d\n",
- r->version);
- return FALSE;
- }
-
- if (r->revision > MAX_EDID_MINOR)
- xf86DrvMsg(scrnIndex, X_WARNING,
- "Assuming version 1.%d is compatible with 1.%d\n",
- r->revision, MAX_EDID_MINOR);
-
- return TRUE;
-}
-
-/*
- * Returns true if HDMI, false if definitely not or unknown.
- */
-Bool
-xf86MonitorIsHDMI(xf86MonPtr mon)
-{
- int i = 0, version, offset;
- char *edid = NULL;
-
- if (!mon)
- return FALSE;
-
- if (!(mon->flags & EDID_COMPLETE_RAWDATA))
- return FALSE;
-
- if (!mon->no_sections)
- return FALSE;
-
- edid = (char *)mon->rawData;
- if (!edid)
- return FALSE;
-
- /* find the CEA extension block */
- for (i = 1; i <= mon->no_sections; i++)
- if (edid[i * 128] == 0x02)
- break;
- if (i == mon->no_sections + 1)
- return FALSE;
- edid += (i * 128);
-
- version = edid[1];
- offset = edid[2];
- if (version < 3 || offset < 4)
- return FALSE;
-
- /* walk the cea data blocks */
- for (i = 4; i < offset; i += (edid[i] & 0x1f) + 1) {
- char *x = edid + i;
-
- /* find a vendor specific block */
- if ((x[0] & 0xe0) >> 5 == 0x03) {
- int oui = (x[3] << 16) + (x[2] << 8) + x[1];
-
- /* find the HDMI vendor OUI */
- if (oui == 0x000c03)
- return TRUE;
- }
- }
-
- /* guess it's not HDMI after all */
- return FALSE;
-}
+/*
+ * Copyright 1998 by Egbert Eich <Egbert.Eich@Physik.TU-Darmstadt.DE>
+ * Copyright 2007 Red Hat, 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 (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * interpret_edid.c: interpret a primary EDID block
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#define _PARSE_EDID_
+#include "xf86DDC.h"
+#include <string.h>
+
+static void get_vendor_section(Uchar*, struct vendor *);
+static void get_version_section(Uchar*, struct edid_version *);
+static void get_display_section(Uchar*, struct disp_features *,
+ struct edid_version *);
+static void get_established_timing_section(Uchar*, struct established_timings *);
+static void get_std_timing_section(Uchar*, struct std_timings *,
+ struct edid_version *);
+static void fetch_detailed_block(Uchar *c, struct edid_version *ver,
+ struct detailed_monitor_section *det_mon);
+static void get_dt_md_section(Uchar *, struct edid_version *,
+ struct detailed_monitor_section *det_mon);
+static void copy_string(Uchar *, Uchar *);
+static void get_dst_timing_section(Uchar *, struct std_timings *,
+ struct edid_version *);
+static void get_monitor_ranges(Uchar *, struct monitor_ranges *);
+static void get_whitepoint_section(Uchar *, struct whitePoints *);
+static void get_detailed_timing_section(Uchar*, struct detailed_timings *);
+static Bool validate_version(int scrnIndex, struct edid_version *);
+
+static void
+find_ranges_section(struct detailed_monitor_section *det, void *ranges)
+{
+ if (det->type == DS_RANGES && det->section.ranges.max_clock)
+ *(struct monitor_ranges **)ranges = &det->section.ranges;
+}
+
+static void
+find_max_detailed_clock(struct detailed_monitor_section *det, void *ret)
+{
+ if (det->type == DT) {
+ *(int *)ret = max(*((int *)ret),
+ det->section.d_timings.clock);
+ }
+}
+
+static void
+handle_edid_quirks(xf86MonPtr m)
+{
+ struct monitor_ranges *ranges = NULL;
+
+ /*
+ * max_clock is only encoded in EDID in tens of MHz, so occasionally we
+ * find a monitor claiming a max of 160 with a mode requiring 162, or
+ * similar. Strictly we should refuse to round up too far, but let's
+ * see how well this works.
+ */
+
+ /* Try to find Monitor Range and max clock, then re-set range value*/
+ xf86ForEachDetailedBlock(m, find_ranges_section, &ranges);
+ if (ranges && ranges->max_clock) {
+ int clock = 0;
+ xf86ForEachDetailedBlock(m, find_max_detailed_clock, &clock);
+ if (clock && (ranges->max_clock * 1e6 < clock)) {
+ xf86Msg(X_WARNING, "EDID timing clock %.2f exceeds claimed max "
+ "%dMHz, fixing\n", clock / 1.0e6, ranges->max_clock);
+ ranges->max_clock = (clock+999999)/1e6;
+ }
+ }
+}
+
+struct det_hv_parameter {
+ int real_hsize;
+ int real_vsize;
+ float target_aspect;
+};
+
+static void handle_detailed_hvsize(struct detailed_monitor_section *det_mon,
+ void *data)
+{
+ struct det_hv_parameter *p = (struct det_hv_parameter *)data;
+ float timing_aspect;
+
+ if (det_mon->type == DT) {
+ struct detailed_timings *timing;
+ timing = &det_mon->section.d_timings;
+
+ if (!timing->v_size)
+ return;
+
+ timing_aspect = (float)timing->h_size / timing->v_size;
+ if (fabs(1 - (timing_aspect / p->target_aspect)) < 0.05) {
+ p->real_hsize = max(p->real_hsize, timing->h_size);
+ p->real_vsize = max(p->real_vsize, timing->v_size);
+ }
+ }
+}
+
+static void encode_aspect_ratio(xf86MonPtr m)
+{
+ /*
+ * some monitors encode the aspect ratio instead of the physical size.
+ * try to find the largest detailed timing that matches that aspect
+ * ratio and use that to fill in the feature section.
+ */
+ if ((m->features.hsize == 16 && m->features.vsize == 9) ||
+ (m->features.hsize == 16 && m->features.vsize == 10) ||
+ (m->features.hsize == 4 && m->features.vsize == 3) ||
+ (m->features.hsize == 5 && m->features.vsize == 4)) {
+
+ struct det_hv_parameter p;
+ p.real_hsize = 0;
+ p.real_vsize = 0;
+ p.target_aspect = (float)m->features.hsize /m->features.vsize;
+
+ xf86ForEachDetailedBlock(m, handle_detailed_hvsize, &p);
+
+ if (!p.real_hsize || !p.real_vsize) {
+ m->features.hsize = m->features.vsize = 0;
+ } else if ((m->features.hsize * 10 == p.real_hsize) &&
+ (m->features.vsize * 10 == p.real_vsize)) {
+ /* exact match is just unlikely, should do a better check though */
+ m->features.hsize = m->features.vsize = 0;
+ } else {
+ /* convert mm to cm */
+ m->features.hsize = (p.real_hsize + 5) / 10;
+ m->features.vsize = (p.real_vsize + 5) / 10;
+ }
+
+ xf86Msg(X_INFO, "Quirked EDID physical size to %dx%d cm\n",
+ m->features.hsize, m->features.vsize);
+ }
+}
+
+xf86MonPtr
+xf86InterpretEDID(int scrnIndex, Uchar *block)
+{
+ xf86MonPtr m;
+
+ if (!block) return NULL;
+ if (! (m = xnfcalloc(sizeof(xf86Monitor),1))) return NULL;
+ m->scrnIndex = scrnIndex;
+ m->rawData = block;
+
+ get_vendor_section(SECTION(VENDOR_SECTION,block),&m->vendor);
+ get_version_section(SECTION(VERSION_SECTION,block),&m->ver);
+ if (!validate_version(scrnIndex, &m->ver)) goto error;
+ get_display_section(SECTION(DISPLAY_SECTION,block),&m->features,
+ &m->ver);
+ get_established_timing_section(SECTION(ESTABLISHED_TIMING_SECTION,block),
+ &m->timings1);
+ get_std_timing_section(SECTION(STD_TIMING_SECTION,block),m->timings2,
+ &m->ver);
+ get_dt_md_section(SECTION(DET_TIMING_SECTION,block),&m->ver, m->det_mon);
+ m->no_sections = (int)*(char *)SECTION(NO_EDID,block);
+
+ handle_edid_quirks(m);
+ encode_aspect_ratio(m);
+
+ return (m);
+
+ error:
+ free(m);
+ return NULL;
+}
+
+static int get_cea_detail_timing(Uchar *blk, xf86MonPtr mon,
+ struct detailed_monitor_section *det_mon)
+{
+ int dt_num;
+ int dt_offset = ((struct cea_ext_body *)blk)->dt_offset;
+
+ dt_num = 0;
+
+ if (dt_offset < CEA_EXT_MIN_DATA_OFFSET)
+ return dt_num;
+
+ for (; dt_offset < (CEA_EXT_MAX_DATA_OFFSET - DET_TIMING_INFO_LEN) &&
+ dt_num < CEA_EXT_DET_TIMING_NUM;
+ _NEXT_DT_MD_SECTION(dt_offset)) {
+
+ fetch_detailed_block(blk + dt_offset, &mon->ver, det_mon + dt_num);
+ dt_num = dt_num + 1 ;
+ }
+
+ return dt_num;
+}
+
+static void handle_cea_detail_block(Uchar *ext, xf86MonPtr mon,
+ handle_detailed_fn fn,
+ void *data)
+{
+ int i;
+ struct detailed_monitor_section det_mon[CEA_EXT_DET_TIMING_NUM];
+ int det_mon_num;
+
+ det_mon_num = get_cea_detail_timing(ext, mon, det_mon);
+
+ for (i = 0; i < det_mon_num; i++)
+ fn(det_mon + i, data);
+}
+
+void xf86ForEachDetailedBlock(xf86MonPtr mon,
+ handle_detailed_fn fn,
+ void *data)
+{
+ int i;
+ Uchar *ext;
+
+ if (mon == NULL)
+ return;
+
+ for (i = 0; i < DET_TIMINGS; i++)
+ fn(mon->det_mon + i, data);
+
+ for (i = 0; i < mon->no_sections; i++) {
+ ext = mon->rawData + EDID1_LEN * (i + 1);
+ switch (ext[EXT_TAG]){
+ case CEA_EXT:
+ handle_cea_detail_block(ext, mon, fn, data);
+ break;
+ case VTB_EXT:
+ case DI_EXT:
+ case LS_EXT:
+ case MI_EXT:
+ break;
+ }
+ }
+}
+
+static struct cea_data_block *
+extract_cea_data_block(Uchar *ext, int data_type)
+{
+ struct cea_ext_body *cea;
+ struct cea_data_block *data_collection;
+ struct cea_data_block *data_end;
+
+ cea = (struct cea_ext_body *)ext;
+
+ if (cea->dt_offset <= CEA_EXT_MIN_DATA_OFFSET)
+ return NULL;
+
+ data_collection = &cea->data_collection;
+ data_end = (struct cea_data_block *)(cea->dt_offset + ext);
+
+ for ( ;data_collection < data_end;) {
+
+ if (data_type == data_collection->tag) {
+ return data_collection;
+ }
+ data_collection = (void *)((unsigned char *)data_collection +
+ data_collection->len + 1);
+ }
+
+ return NULL;
+}
+
+static void handle_cea_video_block(Uchar *ext, handle_video_fn fn, void *data)
+{
+ struct cea_video_block *video;
+ struct cea_video_block *video_end;
+ struct cea_data_block *data_collection;
+
+ data_collection = extract_cea_data_block(ext, CEA_VIDEO_BLK);
+ if (data_collection == NULL)
+ return;
+
+ video = &data_collection->u.video;
+ video_end = (struct cea_video_block *)
+ ((Uchar *)video + data_collection->len);
+
+ for (; video < video_end; video = video + 1) {
+ fn(video, data);
+ }
+}
+
+void xf86ForEachVideoBlock(xf86MonPtr mon,
+ handle_video_fn fn,
+ void *data)
+{
+ int i;
+ Uchar *ext;
+
+ if (mon == NULL)
+ return;
+
+ for (i = 0; i < mon->no_sections; i++) {
+ ext = mon->rawData + EDID1_LEN * (i + 1);
+ switch (ext[EXT_TAG]) {
+ case CEA_EXT:
+ handle_cea_video_block(ext, fn, data);
+ break;
+ case VTB_EXT:
+ case DI_EXT:
+ case LS_EXT:
+ case MI_EXT:
+ break;
+ }
+ }
+}
+
+xf86MonPtr
+xf86InterpretEEDID(int scrnIndex, Uchar *block)
+{
+ xf86MonPtr m;
+
+ m = xf86InterpretEDID(scrnIndex, block);
+ if (!m)
+ return NULL;
+
+ /* extension parse */
+
+ return m;
+}
+
+static void
+get_vendor_section(Uchar *c, struct vendor *r)
+{
+ r->name[0] = L1;
+ r->name[1] = L2;
+ r->name[2] = L3;
+ r->name[3] = '\0';
+
+ r->prod_id = PROD_ID;
+ r->serial = SERIAL_NO;
+ r->week = WEEK;
+ r->year = YEAR;
+}
+
+static void
+get_version_section(Uchar *c, struct edid_version *r)
+{
+ r->version = VERSION;
+ r->revision = REVISION;
+}
+
+static void
+get_display_section(Uchar *c, struct disp_features *r,
+ struct edid_version *v)
+{
+ r->input_type = INPUT_TYPE;
+ if (!DIGITAL(r->input_type)) {
+ r->input_voltage = INPUT_VOLTAGE;
+ r->input_setup = SETUP;
+ r->input_sync = SYNC;
+ } else if (v->revision == 2 || v->revision == 3) {
+ r->input_dfp = DFP;
+ } else if (v->revision >= 4) {
+ r->input_bpc = BPC;
+ r->input_interface = DIGITAL_INTERFACE;
+ }
+ r->hsize = HSIZE_MAX;
+ r->vsize = VSIZE_MAX;
+ r->gamma = GAMMA;
+ r->dpms = DPMS;
+ r->display_type = DISPLAY_TYPE;
+ r->msc = MSC;
+ r->redx = REDX;
+ r->redy = REDY;
+ r->greenx = GREENX;
+ r->greeny = GREENY;
+ r->bluex = BLUEX;
+ r->bluey = BLUEY;
+ r->whitex = WHITEX;
+ r->whitey = WHITEY;
+}
+
+static void
+get_established_timing_section(Uchar *c, struct established_timings *r)
+{
+ r->t1 = T1;
+ r->t2 = T2;
+ r->t_manu = T_MANU;
+}
+
+static void
+get_cvt_timing_section(Uchar *c, struct cvt_timings *r)
+{
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ if (c[0] && c[1] && c[2]) {
+ r[i].height = (c[0] + ((c[1] & 0xF0) << 8) + 1) * 2;
+ switch (c[1] & 0xc0) {
+ case 0x00: r[i].width = r[i].height * 4 / 3; break;
+ case 0x40: r[i].width = r[i].height * 16 / 9; break;
+ case 0x80: r[i].width = r[i].height * 16 / 10; break;
+ case 0xc0: r[i].width = r[i].height * 15 / 9; break;
+ }
+ switch (c[2] & 0x60) {
+ case 0x00: r[i].rate = 50; break;
+ case 0x20: r[i].rate = 60; break;
+ case 0x40: r[i].rate = 75; break;
+ case 0x60: r[i].rate = 85; break;
+ }
+ r[i].rates = c[2] & 0x1f;
+ } else {
+ return;
+ }
+ c += 3;
+ }
+}
+
+static void
+get_std_timing_section(Uchar *c, struct std_timings *r,
+ struct edid_version *v)
+{
+ int i;
+
+ for (i=0;i<STD_TIMINGS;i++){
+ if (VALID_TIMING) {
+ r[i].hsize = HSIZE1;
+ VSIZE1(r[i].vsize);
+ r[i].refresh = REFRESH_R;
+ r[i].id = STD_TIMING_ID;
+ } else {
+ r[i].hsize = r[i].vsize = r[i].refresh = r[i].id = 0;
+ }
+ NEXT_STD_TIMING;
+ }
+}
+
+static const unsigned char empty_block[18];
+
+static void
+fetch_detailed_block(Uchar *c, struct edid_version *ver,
+ struct detailed_monitor_section *det_mon)
+{
+ if (ver->version == 1 && ver->revision >= 1 && IS_MONITOR_DESC) {
+ switch (MONITOR_DESC_TYPE) {
+ case SERIAL_NUMBER:
+ det_mon->type = DS_SERIAL;
+ copy_string(c,det_mon->section.serial);
+ break;
+ case ASCII_STR:
+ det_mon->type = DS_ASCII_STR;
+ copy_string(c,det_mon->section.ascii_data);
+ break;
+ case MONITOR_RANGES:
+ det_mon->type = DS_RANGES;
+ get_monitor_ranges(c,&det_mon->section.ranges);
+ break;
+ case MONITOR_NAME:
+ det_mon->type = DS_NAME;
+ copy_string(c,det_mon->section.name);
+ break;
+ case ADD_COLOR_POINT:
+ det_mon->type = DS_WHITE_P;
+ get_whitepoint_section(c,det_mon->section.wp);
+ break;
+ case ADD_STD_TIMINGS:
+ det_mon->type = DS_STD_TIMINGS;
+ get_dst_timing_section(c,det_mon->section.std_t, ver);
+ break;
+ case COLOR_MANAGEMENT_DATA:
+ det_mon->type = DS_CMD;
+ break;
+ case CVT_3BYTE_DATA:
+ det_mon->type = DS_CVT;
+ get_cvt_timing_section(c, det_mon->section.cvt);
+ break;
+ case ADD_EST_TIMINGS:
+ det_mon->type = DS_EST_III;
+ memcpy(det_mon->section.est_iii, c + 6, 6);
+ break;
+ case ADD_DUMMY:
+ det_mon->type = DS_DUMMY;
+ break;
+ default:
+ det_mon->type = DS_UNKOWN;
+ break;
+ }
+ if (c[3] <= 0x0F && memcmp(c, empty_block, sizeof(empty_block))) {
+ det_mon->type = DS_VENDOR + c[3];
+ }
+ } else {
+ det_mon->type = DT;
+ get_detailed_timing_section(c, &det_mon->section.d_timings);
+ }
+}
+
+static void
+get_dt_md_section(Uchar *c, struct edid_version *ver,
+ struct detailed_monitor_section *det_mon)
+{
+ int i;
+
+ for (i=0; i < DET_TIMINGS; i++) {
+ fetch_detailed_block(c, ver, det_mon + i);
+ NEXT_DT_MD_SECTION;
+ }
+}
+
+static void
+copy_string(Uchar *c, Uchar *s)
+{
+ int i;
+ c = c + 5;
+ for (i = 0; (i < 13 && *c != 0x0A); i++)
+ *(s++) = *(c++);
+ *s = 0;
+ while (i-- && (*--s == 0x20)) *s = 0;
+}
+
+static void
+get_dst_timing_section(Uchar *c, struct std_timings *t,
+ struct edid_version *v)
+{
+ int j;
+ c = c + 5;
+ for (j = 0; j < 5; j++) {
+ t[j].hsize = HSIZE1;
+ VSIZE1(t[j].vsize);
+ t[j].refresh = REFRESH_R;
+ t[j].id = STD_TIMING_ID;
+ NEXT_STD_TIMING;
+ }
+}
+
+static void
+get_monitor_ranges(Uchar *c, struct monitor_ranges *r)
+{
+ r->min_v = MIN_V;
+ r->max_v = MAX_V;
+ r->min_h = MIN_H;
+ r->max_h = MAX_H;
+ r->max_clock = 0;
+ if(MAX_CLOCK != 0xff) /* is specified? */
+ r->max_clock = MAX_CLOCK * 10;
+ if (HAVE_2ND_GTF) {
+ r->gtf_2nd_f = F_2ND_GTF;
+ r->gtf_2nd_c = C_2ND_GTF;
+ r->gtf_2nd_m = M_2ND_GTF;
+ r->gtf_2nd_k = K_2ND_GTF;
+ r->gtf_2nd_j = J_2ND_GTF;
+ } else {
+ r->gtf_2nd_f = 0;
+ }
+ if (HAVE_CVT) {
+ r->max_clock_khz = MAX_CLOCK_KHZ;
+ r->max_clock = r->max_clock_khz / 1000;
+ r->maxwidth = MAXWIDTH;
+ r->supported_aspect = SUPPORTED_ASPECT;
+ r->preferred_aspect = PREFERRED_ASPECT;
+ r->supported_blanking = SUPPORTED_BLANKING;
+ r->supported_scaling = SUPPORTED_SCALING;
+ r->preferred_refresh = PREFERRED_REFRESH;
+ } else {
+ r->max_clock_khz = 0;
+ }
+}
+
+static void
+get_whitepoint_section(Uchar *c, struct whitePoints *wp)
+{
+ wp[0].white_x = WHITEX1;
+ wp[0].white_y = WHITEY1;
+ wp[1].white_x = WHITEX2;
+ wp[1].white_y = WHITEY2;
+ wp[0].index = WHITE_INDEX1;
+ wp[1].index = WHITE_INDEX2;
+ wp[0].white_gamma = WHITE_GAMMA1;
+ wp[1].white_gamma = WHITE_GAMMA2;
+}
+
+static void
+get_detailed_timing_section(Uchar *c, struct detailed_timings *r)
+{
+ r->clock = PIXEL_CLOCK;
+ r->h_active = H_ACTIVE;
+ r->h_blanking = H_BLANK;
+ r->v_active = V_ACTIVE;
+ r->v_blanking = V_BLANK;
+ r->h_sync_off = H_SYNC_OFF;
+ r->h_sync_width = H_SYNC_WIDTH;
+ r->v_sync_off = V_SYNC_OFF;
+ r->v_sync_width = V_SYNC_WIDTH;
+ r->h_size = H_SIZE;
+ r->v_size = V_SIZE;
+ r->h_border = H_BORDER;
+ r->v_border = V_BORDER;
+ r->interlaced = INTERLACED;
+ r->stereo = STEREO;
+ r->stereo_1 = STEREO1;
+ r->sync = SYNC_T;
+ r->misc = MISC;
+}
+
+#define MAX_EDID_MINOR 4
+
+static Bool
+validate_version(int scrnIndex, struct edid_version *r)
+{
+ if (r->version != 1) {
+ xf86DrvMsg(scrnIndex, X_ERROR, "Unknown EDID version %d\n",
+ r->version);
+ return FALSE;
+ }
+
+ if (r->revision > MAX_EDID_MINOR)
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Assuming version 1.%d is compatible with 1.%d\n",
+ r->revision, MAX_EDID_MINOR);
+
+ return TRUE;
+}
+
+/*
+ * Returns true if HDMI, false if definitely not or unknown.
+ */
+Bool
+xf86MonitorIsHDMI(xf86MonPtr mon)
+{
+ int i = 0, version, offset;
+ char *edid = NULL;
+
+ if (!mon)
+ return FALSE;
+
+ if (!(mon->flags & EDID_COMPLETE_RAWDATA))
+ return FALSE;
+
+ if (!mon->no_sections)
+ return FALSE;
+
+ edid = (char *)mon->rawData;
+ if (!edid)
+ return FALSE;
+
+ /* find the CEA extension block */
+ for (i = 1; i <= mon->no_sections; i++)
+ if (edid[i * 128] == 0x02)
+ break;
+ if (i == mon->no_sections + 1)
+ return FALSE;
+ edid += (i * 128);
+
+ version = edid[1];
+ offset = edid[2];
+ if (version < 3 || offset < 4)
+ return FALSE;
+
+ /* walk the cea data blocks */
+ for (i = 4; i < offset; i += (edid[i] & 0x1f) + 1) {
+ char *x = edid + i;
+
+ /* find a vendor specific block */
+ if ((x[0] & 0xe0) >> 5 == 0x03) {
+ int oui = (x[3] << 16) + (x[2] << 8) + x[1];
+
+ /* find the HDMI vendor OUI */
+ if (oui == 0x000c03)
+ return TRUE;
+ }
+ }
+
+ /* guess it's not HDMI after all */
+ return FALSE;
+}
diff --git a/xorg-server/hw/xfree86/dixmods/extmod/modinit.c b/xorg-server/hw/xfree86/dixmods/extmod/modinit.c
index 7d2086802..c0c17d722 100644
--- a/xorg-server/hw/xfree86/dixmods/extmod/modinit.c
+++ b/xorg-server/hw/xfree86/dixmods/extmod/modinit.c
@@ -1,187 +1,187 @@
-/*
- * Copyright (c) 1997 Matthieu Herrb
- *
- * 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 Matthieu Herrb not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Matthieu Herrb makes no
- * representations about the suitability of this software for any purpose.
- * It is provided "as is" without express or implied warranty.
- *
- * MATTHIEU HERRB DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL MATTHIEU HERRB 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 "xf86Module.h"
-#include "xf86Opt.h"
-
-#include <X11/Xproto.h>
-
-#include "modinit.h"
-#include "globals.h"
-
-static MODULESETUPPROTO(extmodSetup);
-
-/*
- * Array describing extensions to be initialized
- */
-static ExtensionModule extensionModules[] = {
-#ifdef XSELINUX
- {
- SELinuxExtensionInit,
- SELINUX_EXTENSION_NAME,
- &noSELinuxExtension,
- NULL,
- NULL
- },
-#endif
-#ifdef SCREENSAVER
- {
- ScreenSaverExtensionInit,
- ScreenSaverName,
- &noScreenSaverExtension,
- NULL,
- NULL
- },
-#endif
-#ifdef XF86VIDMODE
- {
- XFree86VidModeExtensionInit,
- XF86VIDMODENAME,
- &noXFree86VidModeExtension,
- NULL,
- NULL
- },
-#endif
-#ifdef XFreeXDGA
- {
- XFree86DGAExtensionInit,
- XF86DGANAME,
- &noXFree86DGAExtension,
- XFree86DGARegister,
- NULL
- },
-#endif
-#ifdef DPMSExtension
- {
- DPMSExtensionInit,
- DPMSExtensionName,
- &noDPMSExtension,
- NULL,
- NULL
- },
-#endif
-#ifdef XV
- {
- XvExtensionInit,
- XvName,
- &noXvExtension,
- XvRegister,
- NULL
- },
- {
- XvMCExtensionInit,
- XvMCName,
- &noXvExtension,
- NULL,
- NULL
- },
-#endif
-#ifdef RES
- {
- ResExtensionInit,
- XRES_NAME,
- &noResExtension,
- NULL,
- NULL
- },
-#endif
- { /* DON'T delete this entry ! */
- NULL,
- NULL,
- NULL,
- NULL,
- NULL
- }
-};
-
-static XF86ModuleVersionInfo VersRec =
-{
- "extmod",
- MODULEVENDORSTRING,
- MODINFOSTRING1,
- MODINFOSTRING2,
- XORG_VERSION_CURRENT,
- 1, 0, 0,
- ABI_CLASS_EXTENSION,
- ABI_EXTENSION_VERSION,
- MOD_CLASS_EXTENSION,
- {0,0,0,0}
-};
-
-/*
- * Data for the loader
- */
-_X_EXPORT XF86ModuleData extmodModuleData = { &VersRec, extmodSetup, NULL };
-
-static pointer
-extmodSetup(pointer module, pointer opts, int *errmaj, int *errmin)
-{
- int i;
-
- /* XXX the option stuff here is largely a sample/test case */
-
- for (i = 0; extensionModules[i].name != NULL; i++) {
- if (opts) {
- char *s;
- s = (char *)xalloc(strlen(extensionModules[i].name) + 5);
- if (s) {
- pointer o;
- strcpy(s, "omit");
- strcat(s, extensionModules[i].name);
- o = xf86FindOption(opts, s);
- xfree(s);
- if (o) {
- xf86MarkOptionUsed(o);
- continue;
- }
- }
- }
-
-#ifdef XSELINUX
- if (! strcmp(SELINUX_EXTENSION_NAME, extensionModules[i].name)) {
- pointer o;
- selinuxEnforcingState = SELINUX_MODE_DEFAULT;
-
- if ((o = xf86FindOption(opts, "SELinux mode disabled"))) {
- xf86MarkOptionUsed(o);
- selinuxEnforcingState = SELINUX_MODE_DISABLED;
- }
- if ((o = xf86FindOption(opts, "SELinux mode permissive"))) {
- xf86MarkOptionUsed(o);
- selinuxEnforcingState = SELINUX_MODE_PERMISSIVE;
- }
- if ((o = xf86FindOption(opts, "SELinux mode enforcing"))) {
- xf86MarkOptionUsed(o);
- selinuxEnforcingState = SELINUX_MODE_ENFORCING;
- }
- }
-#endif
-
- LoadExtension(&extensionModules[i], FALSE);
- }
- /* Need a non-NULL return */
- return (pointer)1;
-}
+/*
+ * Copyright (c) 1997 Matthieu Herrb
+ *
+ * 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 Matthieu Herrb not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Matthieu Herrb makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ * MATTHIEU HERRB DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL MATTHIEU HERRB 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 "xf86Module.h"
+#include "xf86Opt.h"
+
+#include <X11/Xproto.h>
+
+#include "modinit.h"
+#include "globals.h"
+
+static MODULESETUPPROTO(extmodSetup);
+
+/*
+ * Array describing extensions to be initialized
+ */
+static ExtensionModule extensionModules[] = {
+#ifdef XSELINUX
+ {
+ SELinuxExtensionInit,
+ SELINUX_EXTENSION_NAME,
+ &noSELinuxExtension,
+ NULL,
+ NULL
+ },
+#endif
+#ifdef SCREENSAVER
+ {
+ ScreenSaverExtensionInit,
+ ScreenSaverName,
+ &noScreenSaverExtension,
+ NULL,
+ NULL
+ },
+#endif
+#ifdef XF86VIDMODE
+ {
+ XFree86VidModeExtensionInit,
+ XF86VIDMODENAME,
+ &noXFree86VidModeExtension,
+ NULL,
+ NULL
+ },
+#endif
+#ifdef XFreeXDGA
+ {
+ XFree86DGAExtensionInit,
+ XF86DGANAME,
+ &noXFree86DGAExtension,
+ XFree86DGARegister,
+ NULL
+ },
+#endif
+#ifdef DPMSExtension
+ {
+ DPMSExtensionInit,
+ DPMSExtensionName,
+ &noDPMSExtension,
+ NULL,
+ NULL
+ },
+#endif
+#ifdef XV
+ {
+ XvExtensionInit,
+ XvName,
+ &noXvExtension,
+ XvRegister,
+ NULL
+ },
+ {
+ XvMCExtensionInit,
+ XvMCName,
+ &noXvExtension,
+ NULL,
+ NULL
+ },
+#endif
+#ifdef RES
+ {
+ ResExtensionInit,
+ XRES_NAME,
+ &noResExtension,
+ NULL,
+ NULL
+ },
+#endif
+ { /* DON'T delete this entry ! */
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ }
+};
+
+static XF86ModuleVersionInfo VersRec =
+{
+ "extmod",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XORG_VERSION_CURRENT,
+ 1, 0, 0,
+ ABI_CLASS_EXTENSION,
+ ABI_EXTENSION_VERSION,
+ MOD_CLASS_EXTENSION,
+ {0,0,0,0}
+};
+
+/*
+ * Data for the loader
+ */
+_X_EXPORT XF86ModuleData extmodModuleData = { &VersRec, extmodSetup, NULL };
+
+static pointer
+extmodSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ int i;
+
+ /* XXX the option stuff here is largely a sample/test case */
+
+ for (i = 0; extensionModules[i].name != NULL; i++) {
+ if (opts) {
+ char *s;
+ s = (char *)malloc(strlen(extensionModules[i].name) + 5);
+ if (s) {
+ pointer o;
+ strcpy(s, "omit");
+ strcat(s, extensionModules[i].name);
+ o = xf86FindOption(opts, s);
+ free(s);
+ if (o) {
+ xf86MarkOptionUsed(o);
+ continue;
+ }
+ }
+ }
+
+#ifdef XSELINUX
+ if (! strcmp(SELINUX_EXTENSION_NAME, extensionModules[i].name)) {
+ pointer o;
+ selinuxEnforcingState = SELINUX_MODE_DEFAULT;
+
+ if ((o = xf86FindOption(opts, "SELinux mode disabled"))) {
+ xf86MarkOptionUsed(o);
+ selinuxEnforcingState = SELINUX_MODE_DISABLED;
+ }
+ if ((o = xf86FindOption(opts, "SELinux mode permissive"))) {
+ xf86MarkOptionUsed(o);
+ selinuxEnforcingState = SELINUX_MODE_PERMISSIVE;
+ }
+ if ((o = xf86FindOption(opts, "SELinux mode enforcing"))) {
+ xf86MarkOptionUsed(o);
+ selinuxEnforcingState = SELINUX_MODE_ENFORCING;
+ }
+ }
+#endif
+
+ LoadExtension(&extensionModules[i], FALSE);
+ }
+ /* Need a non-NULL return */
+ return (pointer)1;
+}
diff --git a/xorg-server/hw/xfree86/dixmods/extmod/xf86dga2.c b/xorg-server/hw/xfree86/dixmods/extmod/xf86dga2.c
index 038551467..fae8d8b5d 100644
--- a/xorg-server/hw/xfree86/dixmods/extmod/xf86dga2.c
+++ b/xorg-server/hw/xfree86/dixmods/extmod/xf86dga2.c
@@ -1,1062 +1,1058 @@
-/*
- * Copyright (c) 1995 Jon Tombs
- * Copyright (c) 1995, 1996, 1999 XFree86 Inc
- * Copyright (c) 1999 - The XFree86 Project Inc.
- *
- * Written by Mark Vojkovich
- */
-
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "dixstruct.h"
-#include "dixevents.h"
-#include "pixmapstr.h"
-#include "extnsionst.h"
-#include "colormapst.h"
-#include "cursorstr.h"
-#include "scrnintstr.h"
-#include "servermd.h"
-#include <X11/extensions/xf86dgaproto.h>
-#include "swaprep.h"
-#include "dgaproc.h"
-#include "xf86dgaext.h"
-#include "protocol-versions.h"
-
-#include <string.h>
-
-#include "modinit.h"
-
-#define DGA_PROTOCOL_OLD_SUPPORT 1
-
-static DISPATCH_PROC(ProcXDGADispatch);
-static DISPATCH_PROC(SProcXDGADispatch);
-static DISPATCH_PROC(ProcXDGAQueryVersion);
-static DISPATCH_PROC(ProcXDGAQueryModes);
-static DISPATCH_PROC(ProcXDGASetMode);
-static DISPATCH_PROC(ProcXDGAOpenFramebuffer);
-static DISPATCH_PROC(ProcXDGACloseFramebuffer);
-static DISPATCH_PROC(ProcXDGASetViewport);
-static DISPATCH_PROC(ProcXDGAInstallColormap);
-static DISPATCH_PROC(ProcXDGASelectInput);
-static DISPATCH_PROC(ProcXDGAFillRectangle);
-static DISPATCH_PROC(ProcXDGACopyArea);
-static DISPATCH_PROC(ProcXDGACopyTransparentArea);
-static DISPATCH_PROC(ProcXDGAGetViewportStatus);
-static DISPATCH_PROC(ProcXDGASync);
-static DISPATCH_PROC(ProcXDGASetClientVersion);
-static DISPATCH_PROC(ProcXDGAChangePixmapMode);
-static DISPATCH_PROC(ProcXDGACreateColormap);
-
-static void XDGAResetProc(ExtensionEntry *extEntry);
-
-static void DGAClientStateChange (CallbackListPtr*, pointer, pointer);
-
-unsigned char DGAReqCode = 0;
-int DGAErrorBase;
-int DGAEventBase;
-
-static int DGAScreenPrivateKeyIndex;
-static DevPrivateKey DGAScreenPrivateKey = &DGAScreenPrivateKeyIndex;
-static int DGAClientPrivateKeyIndex;
-static DevPrivateKey DGAClientPrivateKey = &DGAClientPrivateKeyIndex;
-static int DGACallbackRefCount = 0;
-
-/* This holds the client's version information */
-typedef struct {
- int major;
- int minor;
-} DGAPrivRec, *DGAPrivPtr;
-
-#define DGA_GETCLIENT(idx) ((ClientPtr) \
- dixLookupPrivate(&screenInfo.screens[idx]->devPrivates, DGAScreenPrivateKey))
-#define DGA_SETCLIENT(idx,p) \
- dixSetPrivate(&screenInfo.screens[idx]->devPrivates, DGAScreenPrivateKey, p)
-
-#define DGA_GETPRIV(c) ((DGAPrivPtr) \
- dixLookupPrivate(&(c)->devPrivates, DGAClientPrivateKey))
-#define DGA_SETPRIV(c,p) \
- dixSetPrivate(&(c)->devPrivates, DGAClientPrivateKey, p)
-
-
-void
-XFree86DGAExtensionInit(INITARGS)
-{
- ExtensionEntry* extEntry;
-
- if ((extEntry = AddExtension(XF86DGANAME,
- XF86DGANumberEvents,
- XF86DGANumberErrors,
- ProcXDGADispatch,
- SProcXDGADispatch,
- XDGAResetProc,
- StandardMinorOpcode))) {
- int i;
-
- DGAReqCode = (unsigned char)extEntry->base;
- DGAErrorBase = extEntry->errorBase;
- DGAEventBase = extEntry->eventBase;
- for (i = KeyPress; i <= MotionNotify; i++)
- SetCriticalEvent (DGAEventBase + i);
- }
-}
-
-
-
-static void
-XDGAResetProc (ExtensionEntry *extEntry)
-{
- DeleteCallback (&ClientStateCallback, DGAClientStateChange, NULL);
- DGACallbackRefCount = 0;
-}
-
-
-static int
-ProcXDGAQueryVersion(ClientPtr client)
-{
- xXDGAQueryVersionReply rep;
-
- REQUEST_SIZE_MATCH(xXDGAQueryVersionReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.majorVersion = SERVER_XDGA_MAJOR_VERSION;
- rep.minorVersion = SERVER_XDGA_MINOR_VERSION;
-
- WriteToClient(client, sizeof(xXDGAQueryVersionReply), (char *)&rep);
- return (client->noClientException);
-}
-
-
-static int
-ProcXDGAOpenFramebuffer(ClientPtr client)
-{
- REQUEST(xXDGAOpenFramebufferReq);
- xXDGAOpenFramebufferReply rep;
- char *deviceName;
- int nameSize;
-
- if (stuff->screen > screenInfo.numScreens)
- return BadValue;
-
- if (!DGAAvailable(stuff->screen))
- return DGAErrorBase + XF86DGANoDirectVideoMode;
-
- REQUEST_SIZE_MATCH(xXDGAOpenFramebufferReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- if(!DGAOpenFramebuffer(stuff->screen, &deviceName,
- (unsigned char**)(&rep.mem1),
- (int*)&rep.size, (int*)&rep.offset, (int*)&rep.extra))
- {
- return BadAlloc;
- }
-
- nameSize = deviceName ? (strlen(deviceName) + 1) : 0;
- rep.length = bytes_to_int32(nameSize);
-
- WriteToClient(client, sizeof(xXDGAOpenFramebufferReply), (char *)&rep);
- if(rep.length)
- WriteToClient(client, nameSize, deviceName);
-
- return (client->noClientException);
-}
-
-
-static int
-ProcXDGACloseFramebuffer(ClientPtr client)
-{
- REQUEST(xXDGACloseFramebufferReq);
-
- if (stuff->screen > screenInfo.numScreens)
- return BadValue;
-
- if (!DGAAvailable(stuff->screen))
- return DGAErrorBase + XF86DGANoDirectVideoMode;
-
- REQUEST_SIZE_MATCH(xXDGACloseFramebufferReq);
-
- DGACloseFramebuffer(stuff->screen);
-
- return (client->noClientException);
-}
-
-static int
-ProcXDGAQueryModes(ClientPtr client)
-{
- int i, num, size;
- REQUEST(xXDGAQueryModesReq);
- xXDGAQueryModesReply rep;
- xXDGAModeInfo info;
- XDGAModePtr mode;
-
- if (stuff->screen > screenInfo.numScreens)
- return BadValue;
-
- REQUEST_SIZE_MATCH(xXDGAQueryModesReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.number = 0;
- rep.sequenceNumber = client->sequence;
-
- if (!DGAAvailable(stuff->screen)) {
- rep.number = 0;
- rep.length = 0;
- WriteToClient(client, sz_xXDGAQueryModesReply, (char*)&rep);
- return (client->noClientException);
- }
-
- if(!(num = DGAGetModes(stuff->screen))) {
- WriteToClient(client, sz_xXDGAQueryModesReply, (char*)&rep);
- return (client->noClientException);
- }
-
- if(!(mode = (XDGAModePtr)xalloc(num * sizeof(XDGAModeRec))))
- return BadAlloc;
-
- for(i = 0; i < num; i++)
- DGAGetModeInfo(stuff->screen, mode + i, i + 1);
-
- size = num * sz_xXDGAModeInfo;
- for(i = 0; i < num; i++)
- size += pad_to_int32(strlen(mode[i].name) + 1); /* plus NULL */
-
- rep.number = num;
- rep.length = bytes_to_int32(size);
-
- WriteToClient(client, sz_xXDGAQueryModesReply, (char*)&rep);
-
- for(i = 0; i < num; i++) {
- size = strlen(mode[i].name) + 1;
-
- info.byte_order = mode[i].byteOrder;
- info.depth = mode[i].depth;
- info.num = mode[i].num;
- info.bpp = mode[i].bitsPerPixel;
- info.name_size = (size + 3) & ~3L;
- info.vsync_num = mode[i].VSync_num;
- info.vsync_den = mode[i].VSync_den;
- info.flags = mode[i].flags;
- info.image_width = mode[i].imageWidth;
- info.image_height = mode[i].imageHeight;
- info.pixmap_width = mode[i].pixmapWidth;
- info.pixmap_height = mode[i].pixmapHeight;
- info.bytes_per_scanline = mode[i].bytesPerScanline;
- info.red_mask = mode[i].red_mask;
- info.green_mask = mode[i].green_mask;
- info.blue_mask = mode[i].blue_mask;
- info.visual_class = mode[i].visualClass;
- info.viewport_width = mode[i].viewportWidth;
- info.viewport_height = mode[i].viewportHeight;
- info.viewport_xstep = mode[i].xViewportStep;
- info.viewport_ystep = mode[i].yViewportStep;
- info.viewport_xmax = mode[i].maxViewportX;
- info.viewport_ymax = mode[i].maxViewportY;
- info.viewport_flags = mode[i].viewportFlags;
- info.reserved1 = mode[i].reserved1;
- info.reserved2 = mode[i].reserved2;
-
- WriteToClient(client, sz_xXDGAModeInfo, (char*)(&info));
- WriteToClient(client, size, mode[i].name);
- }
-
- xfree(mode);
-
- return (client->noClientException);
-}
-
-
-static void
-DGAClientStateChange (
- CallbackListPtr* pcbl,
- pointer nulldata,
- pointer calldata
-){
- NewClientInfoRec* pci = (NewClientInfoRec*) calldata;
- ClientPtr client = NULL;
- int i;
-
- for(i = 0; i < screenInfo.numScreens; i++) {
- if(DGA_GETCLIENT(i) == pci->client) {
- client = pci->client;
- break;
- }
- }
-
- if(client &&
- ((client->clientState == ClientStateGone) ||
- (client->clientState == ClientStateRetained))) {
- XDGAModeRec mode;
- PixmapPtr pPix;
-
- DGA_SETCLIENT(i, NULL);
- DGASelectInput(i, NULL, 0);
- DGASetMode(i, 0, &mode, &pPix);
-
- if(--DGACallbackRefCount == 0)
- DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL);
- }
-}
-
-static int
-ProcXDGASetMode(ClientPtr client)
-{
- REQUEST(xXDGASetModeReq);
- xXDGASetModeReply rep;
- XDGAModeRec mode;
- xXDGAModeInfo info;
- PixmapPtr pPix;
- ClientPtr owner;
- int size;
-
- if (stuff->screen > screenInfo.numScreens)
- return BadValue;
- owner = DGA_GETCLIENT(stuff->screen);
-
- REQUEST_SIZE_MATCH(xXDGASetModeReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.offset = 0;
- rep.flags = 0;
- rep.sequenceNumber = client->sequence;
-
- if (!DGAAvailable(stuff->screen))
- return DGAErrorBase + XF86DGANoDirectVideoMode;
-
- if(owner && owner != client)
- return DGAErrorBase + XF86DGANoDirectVideoMode;
-
- if(!stuff->mode) {
- if(owner) {
- if(--DGACallbackRefCount == 0)
- DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL);
- }
- DGA_SETCLIENT(stuff->screen, NULL);
- DGASelectInput(stuff->screen, NULL, 0);
- DGASetMode(stuff->screen, 0, &mode, &pPix);
- WriteToClient(client, sz_xXDGASetModeReply, (char*)&rep);
- return (client->noClientException);
- }
-
- if(Success != DGASetMode(stuff->screen, stuff->mode, &mode, &pPix))
- return BadValue;
-
- if(!owner) {
- if(DGACallbackRefCount++ == 0)
- AddCallback (&ClientStateCallback, DGAClientStateChange, NULL);
- }
-
- DGA_SETCLIENT(stuff->screen, client);
-
- if(pPix) {
- if(AddResource(stuff->pid, RT_PIXMAP, (pointer)(pPix))) {
- pPix->drawable.id = (int)stuff->pid;
- rep.flags = DGA_PIXMAP_AVAILABLE;
- }
- }
-
- size = strlen(mode.name) + 1;
-
- info.byte_order = mode.byteOrder;
- info.depth = mode.depth;
- info.num = mode.num;
- info.bpp = mode.bitsPerPixel;
- info.name_size = (size + 3) & ~3L;
- info.vsync_num = mode.VSync_num;
- info.vsync_den = mode.VSync_den;
- info.flags = mode.flags;
- info.image_width = mode.imageWidth;
- info.image_height = mode.imageHeight;
- info.pixmap_width = mode.pixmapWidth;
- info.pixmap_height = mode.pixmapHeight;
- info.bytes_per_scanline = mode.bytesPerScanline;
- info.red_mask = mode.red_mask;
- info.green_mask = mode.green_mask;
- info.blue_mask = mode.blue_mask;
- info.visual_class = mode.visualClass;
- info.viewport_width = mode.viewportWidth;
- info.viewport_height = mode.viewportHeight;
- info.viewport_xstep = mode.xViewportStep;
- info.viewport_ystep = mode.yViewportStep;
- info.viewport_xmax = mode.maxViewportX;
- info.viewport_ymax = mode.maxViewportY;
- info.viewport_flags = mode.viewportFlags;
- info.reserved1 = mode.reserved1;
- info.reserved2 = mode.reserved2;
-
- rep.length = bytes_to_int32(sz_xXDGAModeInfo + info.name_size);
-
- WriteToClient(client, sz_xXDGASetModeReply, (char*)&rep);
- WriteToClient(client, sz_xXDGAModeInfo, (char*)(&info));
- WriteToClient(client, size, mode.name);
-
- return (client->noClientException);
-}
-
-static int
-ProcXDGASetViewport(ClientPtr client)
-{
- REQUEST(xXDGASetViewportReq);
-
- if (stuff->screen > screenInfo.numScreens)
- return BadValue;
-
- if(DGA_GETCLIENT(stuff->screen) != client)
- return DGAErrorBase + XF86DGADirectNotActivated;
-
- REQUEST_SIZE_MATCH(xXDGASetViewportReq);
-
- DGASetViewport(stuff->screen, stuff->x, stuff->y, stuff->flags);
-
- return (client->noClientException);
-}
-
-static int
-ProcXDGAInstallColormap(ClientPtr client)
-{
- ColormapPtr cmap;
- int rc;
- REQUEST(xXDGAInstallColormapReq);
-
- if (stuff->screen > screenInfo.numScreens)
- return BadValue;
-
- if(DGA_GETCLIENT(stuff->screen) != client)
- return DGAErrorBase + XF86DGADirectNotActivated;
-
- REQUEST_SIZE_MATCH(xXDGAInstallColormapReq);
-
- rc = dixLookupResourceByType((pointer *)&cmap, stuff->cmap, RT_COLORMAP,
- client, DixInstallAccess);
- if (rc == Success) {
- DGAInstallCmap(cmap);
- return (client->noClientException);
- } else {
- return (rc == BadValue) ? BadColor : rc;
- }
-
- return (client->noClientException);
-}
-
-
-static int
-ProcXDGASelectInput(ClientPtr client)
-{
- REQUEST(xXDGASelectInputReq);
-
- if (stuff->screen > screenInfo.numScreens)
- return BadValue;
-
- if(DGA_GETCLIENT(stuff->screen) != client)
- return DGAErrorBase + XF86DGADirectNotActivated;
-
- REQUEST_SIZE_MATCH(xXDGASelectInputReq);
-
- if(DGA_GETCLIENT(stuff->screen) == client)
- DGASelectInput(stuff->screen, client, stuff->mask);
-
- return (client->noClientException);
-}
-
-
-static int
-ProcXDGAFillRectangle(ClientPtr client)
-{
- REQUEST(xXDGAFillRectangleReq);
-
- if (stuff->screen > screenInfo.numScreens)
- return BadValue;
-
- if(DGA_GETCLIENT(stuff->screen) != client)
- return DGAErrorBase + XF86DGADirectNotActivated;
-
- REQUEST_SIZE_MATCH(xXDGAFillRectangleReq);
-
- if(Success != DGAFillRect(stuff->screen, stuff->x, stuff->y,
- stuff->width, stuff->height, stuff->color))
- return BadMatch;
-
- return (client->noClientException);
-}
-
-static int
-ProcXDGACopyArea(ClientPtr client)
-{
- REQUEST(xXDGACopyAreaReq);
-
- if (stuff->screen > screenInfo.numScreens)
- return BadValue;
-
- if(DGA_GETCLIENT(stuff->screen) != client)
- return DGAErrorBase + XF86DGADirectNotActivated;
-
- REQUEST_SIZE_MATCH(xXDGACopyAreaReq);
-
- if(Success != DGABlitRect(stuff->screen, stuff->srcx, stuff->srcy,
- stuff->width, stuff->height, stuff->dstx, stuff->dsty))
- return BadMatch;
-
- return (client->noClientException);
-}
-
-
-static int
-ProcXDGACopyTransparentArea(ClientPtr client)
-{
- REQUEST(xXDGACopyTransparentAreaReq);
-
- if (stuff->screen > screenInfo.numScreens)
- return BadValue;
-
- if(DGA_GETCLIENT(stuff->screen) != client)
- return DGAErrorBase + XF86DGADirectNotActivated;
-
- REQUEST_SIZE_MATCH(xXDGACopyTransparentAreaReq);
-
- if(Success != DGABlitTransRect(stuff->screen, stuff->srcx, stuff->srcy,
- stuff->width, stuff->height, stuff->dstx, stuff->dsty, stuff->key))
- return BadMatch;
-
- return (client->noClientException);
-}
-
-
-static int
-ProcXDGAGetViewportStatus(ClientPtr client)
-{
- REQUEST(xXDGAGetViewportStatusReq);
- xXDGAGetViewportStatusReply rep;
-
- if (stuff->screen > screenInfo.numScreens)
- return BadValue;
-
- if(DGA_GETCLIENT(stuff->screen) != client)
- return DGAErrorBase + XF86DGADirectNotActivated;
-
- REQUEST_SIZE_MATCH(xXDGAGetViewportStatusReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- rep.status = DGAGetViewportStatus(stuff->screen);
-
- WriteToClient(client, sizeof(xXDGAGetViewportStatusReply), (char *)&rep);
- return (client->noClientException);
-}
-
-static int
-ProcXDGASync(ClientPtr client)
-{
- REQUEST(xXDGASyncReq);
- xXDGASyncReply rep;
-
- if (stuff->screen > screenInfo.numScreens)
- return BadValue;
-
- if(DGA_GETCLIENT(stuff->screen) != client)
- return DGAErrorBase + XF86DGADirectNotActivated;
-
- REQUEST_SIZE_MATCH(xXDGASyncReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- DGASync(stuff->screen);
-
- WriteToClient(client, sizeof(xXDGASyncReply), (char *)&rep);
- return (client->noClientException);
-}
-
-static int
-ProcXDGASetClientVersion(ClientPtr client)
-{
- REQUEST(xXDGASetClientVersionReq);
-
- DGAPrivPtr pPriv;
-
- REQUEST_SIZE_MATCH(xXDGASetClientVersionReq);
- if ((pPriv = DGA_GETPRIV(client)) == NULL) {
- pPriv = xalloc(sizeof(DGAPrivRec));
- /* XXX Need to look into freeing this */
- if (!pPriv)
- return BadAlloc;
- DGA_SETPRIV(client, pPriv);
- }
- pPriv->major = stuff->major;
- pPriv->minor = stuff->minor;
-
- return (client->noClientException);
-}
-
-static int
-ProcXDGAChangePixmapMode(ClientPtr client)
-{
- REQUEST(xXDGAChangePixmapModeReq);
- xXDGAChangePixmapModeReply rep;
- int x, y;
-
- if (stuff->screen > screenInfo.numScreens)
- return BadValue;
-
- if(DGA_GETCLIENT(stuff->screen) != client)
- return DGAErrorBase + XF86DGADirectNotActivated;
-
- REQUEST_SIZE_MATCH(xXDGAChangePixmapModeReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- x = stuff->x;
- y = stuff->y;
-
- if(!DGAChangePixmapMode(stuff->screen, &x, &y, stuff->flags))
- return BadMatch;
-
- rep.x = x;
- rep.y = y;
- WriteToClient(client, sizeof(xXDGAChangePixmapModeReply), (char *)&rep);
-
- return (client->noClientException);
-}
-
-
-static int
-ProcXDGACreateColormap(ClientPtr client)
-{
- REQUEST(xXDGACreateColormapReq);
- int result;
-
- if (stuff->screen > screenInfo.numScreens)
- return BadValue;
-
- if(DGA_GETCLIENT(stuff->screen) != client)
- return DGAErrorBase + XF86DGADirectNotActivated;
-
- REQUEST_SIZE_MATCH(xXDGACreateColormapReq);
-
- if(!stuff->mode)
- return BadValue;
-
- result = DGACreateColormap(stuff->screen, client, stuff->id,
- stuff->mode, stuff->alloc);
- if(result != Success)
- return result;
-
- return (client->noClientException);
-}
-
-/*
- *
- * Support for the old DGA protocol, used to live in xf86dga.c
- *
- */
-
-#ifdef DGA_PROTOCOL_OLD_SUPPORT
-
-static DISPATCH_PROC(ProcXF86DGADirectVideo);
-static DISPATCH_PROC(ProcXF86DGAGetVidPage);
-static DISPATCH_PROC(ProcXF86DGAGetVideoLL);
-static DISPATCH_PROC(ProcXF86DGAGetViewPortSize);
-static DISPATCH_PROC(ProcXF86DGASetVidPage);
-static DISPATCH_PROC(ProcXF86DGASetViewPort);
-static DISPATCH_PROC(ProcXF86DGAInstallColormap);
-static DISPATCH_PROC(ProcXF86DGAQueryDirectVideo);
-static DISPATCH_PROC(ProcXF86DGAViewPortChanged);
-
-
-static int
-ProcXF86DGAGetVideoLL(ClientPtr client)
-{
- REQUEST(xXF86DGAGetVideoLLReq);
- xXF86DGAGetVideoLLReply rep;
- XDGAModeRec mode;
- int num, offset, flags;
- char *name;
-
- if (stuff->screen > screenInfo.numScreens)
- return BadValue;
-
- REQUEST_SIZE_MATCH(xXF86DGAGetVideoLLReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- if(!DGAAvailable(stuff->screen))
- return (DGAErrorBase + XF86DGANoDirectVideoMode);
-
- if(!(num = DGAGetOldDGAMode(stuff->screen)))
- return (DGAErrorBase + XF86DGANoDirectVideoMode);
-
- /* get the parameters for the mode that best matches */
- DGAGetModeInfo(stuff->screen, &mode, num);
-
- if(!DGAOpenFramebuffer(stuff->screen, &name,
- (unsigned char**)(&rep.offset),
- (int*)(&rep.bank_size), &offset, &flags))
- return BadAlloc;
-
- rep.offset += mode.offset;
- rep.width = mode.bytesPerScanline / (mode.bitsPerPixel >> 3);
- rep.ram_size = rep.bank_size >> 10;
-
- WriteToClient(client, SIZEOF(xXF86DGAGetVideoLLReply), (char *)&rep);
- return (client->noClientException);
-}
-
-static int
-ProcXF86DGADirectVideo(ClientPtr client)
-{
- int num;
- PixmapPtr pix;
- XDGAModeRec mode;
- ClientPtr owner;
- REQUEST(xXF86DGADirectVideoReq);
-
- if (stuff->screen > screenInfo.numScreens)
- return BadValue;
- owner = DGA_GETCLIENT(stuff->screen);
-
- REQUEST_SIZE_MATCH(xXF86DGADirectVideoReq);
-
- if (!DGAAvailable(stuff->screen))
- return DGAErrorBase + XF86DGANoDirectVideoMode;
-
- if (owner && owner != client)
- return DGAErrorBase + XF86DGANoDirectVideoMode;
-
- if (stuff->enable & XF86DGADirectGraphics) {
- if(!(num = DGAGetOldDGAMode(stuff->screen)))
- return (DGAErrorBase + XF86DGANoDirectVideoMode);
- } else
- num = 0;
-
- if(Success != DGASetMode(stuff->screen, num, &mode, &pix))
- return (DGAErrorBase + XF86DGAScreenNotActive);
-
- DGASetInputMode (stuff->screen,
- (stuff->enable & XF86DGADirectKeyb) != 0,
- (stuff->enable & XF86DGADirectMouse) != 0);
-
- /* We need to track the client and attach the teardown callback */
- if (stuff->enable &
- (XF86DGADirectGraphics | XF86DGADirectKeyb | XF86DGADirectMouse)) {
- if (!owner) {
- if (DGACallbackRefCount++ == 0)
- AddCallback (&ClientStateCallback, DGAClientStateChange, NULL);
- }
-
- DGA_SETCLIENT(stuff->screen, client);
- } else {
- if (owner) {
- if (--DGACallbackRefCount == 0)
- DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL);
- }
-
- DGA_SETCLIENT(stuff->screen, NULL);
- }
-
- return (client->noClientException);
-}
-
-static int
-ProcXF86DGAGetViewPortSize(ClientPtr client)
-{
- int num;
- XDGAModeRec mode;
- REQUEST(xXF86DGAGetViewPortSizeReq);
- xXF86DGAGetViewPortSizeReply rep;
-
- if (stuff->screen > screenInfo.numScreens)
- return BadValue;
-
- REQUEST_SIZE_MATCH(xXF86DGAGetViewPortSizeReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- if (!DGAAvailable(stuff->screen))
- return (DGAErrorBase + XF86DGANoDirectVideoMode);
-
- if(!(num = DGAGetOldDGAMode(stuff->screen)))
- return (DGAErrorBase + XF86DGANoDirectVideoMode);
-
- DGAGetModeInfo(stuff->screen, &mode, num);
-
- rep.width = mode.viewportWidth;
- rep.height = mode.viewportHeight;
-
- WriteToClient(client, SIZEOF(xXF86DGAGetViewPortSizeReply), (char *)&rep);
- return (client->noClientException);
-}
-
-static int
-ProcXF86DGASetViewPort(ClientPtr client)
-{
- REQUEST(xXF86DGASetViewPortReq);
-
- if (stuff->screen > screenInfo.numScreens)
- return BadValue;
-
- if (DGA_GETCLIENT(stuff->screen) != client)
- return DGAErrorBase + XF86DGADirectNotActivated;
-
- REQUEST_SIZE_MATCH(xXF86DGASetViewPortReq);
-
- if (!DGAAvailable(stuff->screen))
- return (DGAErrorBase + XF86DGANoDirectVideoMode);
-
- if (!DGAActive(stuff->screen))
- return DGAErrorBase + XF86DGADirectNotActivated;
-
- if (DGASetViewport(stuff->screen, stuff->x, stuff->y, DGA_FLIP_RETRACE)
- != Success)
- return DGAErrorBase + XF86DGADirectNotActivated;
-
- return (client->noClientException);
-}
-
-static int
-ProcXF86DGAGetVidPage(ClientPtr client)
-{
- REQUEST(xXF86DGAGetVidPageReq);
- xXF86DGAGetVidPageReply rep;
-
- if (stuff->screen > screenInfo.numScreens)
- return BadValue;
-
- REQUEST_SIZE_MATCH(xXF86DGAGetVidPageReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.vpage = 0; /* silently fail */
-
- WriteToClient(client, SIZEOF(xXF86DGAGetVidPageReply), (char *)&rep);
- return (client->noClientException);
-}
-
-
-static int
-ProcXF86DGASetVidPage(ClientPtr client)
-{
- REQUEST(xXF86DGASetVidPageReq);
-
- if (stuff->screen > screenInfo.numScreens)
- return BadValue;
-
- REQUEST_SIZE_MATCH(xXF86DGASetVidPageReq);
-
- /* silently fail */
-
- return (client->noClientException);
-}
-
-
-static int
-ProcXF86DGAInstallColormap(ClientPtr client)
-{
- ColormapPtr pcmp;
- int rc;
- REQUEST(xXF86DGAInstallColormapReq);
-
- if (stuff->screen > screenInfo.numScreens)
- return BadValue;
-
- if (DGA_GETCLIENT(stuff->screen) != client)
- return DGAErrorBase + XF86DGADirectNotActivated;
-
- REQUEST_SIZE_MATCH(xXF86DGAInstallColormapReq);
-
- if (!DGAActive(stuff->screen))
- return (DGAErrorBase + XF86DGADirectNotActivated);
-
- rc = dixLookupResourceByType((pointer *)&pcmp, stuff->id, RT_COLORMAP,
- client, DixInstallAccess);
- if (rc == Success) {
- DGAInstallCmap(pcmp);
- return (client->noClientException);
- } else {
- return (rc == BadValue) ? BadColor : rc;
- }
-}
-
-static int
-ProcXF86DGAQueryDirectVideo(ClientPtr client)
-{
- REQUEST(xXF86DGAQueryDirectVideoReq);
- xXF86DGAQueryDirectVideoReply rep;
-
- if (stuff->screen > screenInfo.numScreens)
- return BadValue;
-
- REQUEST_SIZE_MATCH(xXF86DGAQueryDirectVideoReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.flags = 0;
-
- if (DGAAvailable(stuff->screen))
- rep.flags = XF86DGADirectPresent;
-
- WriteToClient(client, SIZEOF(xXF86DGAQueryDirectVideoReply), (char *)&rep);
- return (client->noClientException);
-}
-
-static int
-ProcXF86DGAViewPortChanged(ClientPtr client)
-{
- REQUEST(xXF86DGAViewPortChangedReq);
- xXF86DGAViewPortChangedReply rep;
-
- if (stuff->screen > screenInfo.numScreens)
- return BadValue;
-
- if (DGA_GETCLIENT(stuff->screen) != client)
- return DGAErrorBase + XF86DGADirectNotActivated;
-
- REQUEST_SIZE_MATCH(xXF86DGAViewPortChangedReq);
-
- if (!DGAActive(stuff->screen))
- return (DGAErrorBase + XF86DGADirectNotActivated);
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.result = 1;
-
- WriteToClient(client, SIZEOF(xXF86DGAViewPortChangedReply), (char *)&rep);
- return (client->noClientException);
-}
-
-#endif /* DGA_PROTOCOL_OLD_SUPPORT */
-
-static int
-SProcXDGADispatch (ClientPtr client)
-{
- return DGAErrorBase + XF86DGAClientNotLocal;
-}
-
-#if 0
-#define DGA_REQ_DEBUG
-#endif
-
-#ifdef DGA_REQ_DEBUG
-static char *dgaMinor[] = {
- "QueryVersion",
- "GetVideoLL",
- "DirectVideo",
- "GetViewPortSize",
- "SetViewPort",
- "GetVidPage",
- "SetVidPage",
- "InstallColormap",
- "QueryDirectVideo",
- "ViewPortChanged",
- "10",
- "11",
- "QueryModes",
- "SetMode",
- "SetViewport",
- "InstallColormap",
- "SelectInput",
- "FillRectangle",
- "CopyArea",
- "CopyTransparentArea",
- "GetViewportStatus",
- "Sync",
- "OpenFramebuffer",
- "CloseFramebuffer",
- "SetClientVersion",
- "ChangePixmapMode",
- "CreateColormap",
-};
-#endif
-
-static int
-ProcXDGADispatch (ClientPtr client)
-{
- REQUEST(xReq);
-
- if (!LocalClient(client))
- return DGAErrorBase + XF86DGAClientNotLocal;
-
-#ifdef DGA_REQ_DEBUG
- if (stuff->data <= X_XDGACreateColormap)
- fprintf (stderr, " DGA %s\n", dgaMinor[stuff->data]);
-#endif
-
- switch (stuff->data){
- /*
- * DGA2 Protocol
- */
- case X_XDGAQueryVersion:
- return ProcXDGAQueryVersion(client);
- case X_XDGAQueryModes:
- return ProcXDGAQueryModes(client);
- case X_XDGASetMode:
- return ProcXDGASetMode(client);
- case X_XDGAOpenFramebuffer:
- return ProcXDGAOpenFramebuffer(client);
- case X_XDGACloseFramebuffer:
- return ProcXDGACloseFramebuffer(client);
- case X_XDGASetViewport:
- return ProcXDGASetViewport(client);
- case X_XDGAInstallColormap:
- return ProcXDGAInstallColormap(client);
- case X_XDGASelectInput:
- return ProcXDGASelectInput(client);
- case X_XDGAFillRectangle:
- return ProcXDGAFillRectangle(client);
- case X_XDGACopyArea:
- return ProcXDGACopyArea(client);
- case X_XDGACopyTransparentArea:
- return ProcXDGACopyTransparentArea(client);
- case X_XDGAGetViewportStatus:
- return ProcXDGAGetViewportStatus(client);
- case X_XDGASync:
- return ProcXDGASync(client);
- case X_XDGASetClientVersion:
- return ProcXDGASetClientVersion(client);
- case X_XDGAChangePixmapMode:
- return ProcXDGAChangePixmapMode(client);
- case X_XDGACreateColormap:
- return ProcXDGACreateColormap(client);
- /*
- * Old DGA Protocol
- */
-#ifdef DGA_PROTOCOL_OLD_SUPPORT
- case X_XF86DGAGetVideoLL:
- return ProcXF86DGAGetVideoLL(client);
- case X_XF86DGADirectVideo:
- return ProcXF86DGADirectVideo(client);
- case X_XF86DGAGetViewPortSize:
- return ProcXF86DGAGetViewPortSize(client);
- case X_XF86DGASetViewPort:
- return ProcXF86DGASetViewPort(client);
- case X_XF86DGAGetVidPage:
- return ProcXF86DGAGetVidPage(client);
- case X_XF86DGASetVidPage:
- return ProcXF86DGASetVidPage(client);
- case X_XF86DGAInstallColormap:
- return ProcXF86DGAInstallColormap(client);
- case X_XF86DGAQueryDirectVideo:
- return ProcXF86DGAQueryDirectVideo(client);
- case X_XF86DGAViewPortChanged:
- return ProcXF86DGAViewPortChanged(client);
-#endif /* DGA_PROTOCOL_OLD_SUPPORT */
- default:
- return BadRequest;
- }
-}
-
-void
-XFree86DGARegister(INITARGS)
-{
- XDGAEventBase = &DGAEventBase;
-}
+/*
+ * Copyright (c) 1995 Jon Tombs
+ * Copyright (c) 1995, 1996, 1999 XFree86 Inc
+ * Copyright (c) 1999 - The XFree86 Project Inc.
+ *
+ * Written by Mark Vojkovich
+ */
+
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "dixstruct.h"
+#include "dixevents.h"
+#include "pixmapstr.h"
+#include "extnsionst.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+#include <X11/extensions/xf86dgaproto.h>
+#include "swaprep.h"
+#include "dgaproc.h"
+#include "xf86dgaext.h"
+#include "protocol-versions.h"
+
+#include <string.h>
+
+#include "modinit.h"
+
+#define DGA_PROTOCOL_OLD_SUPPORT 1
+
+static DISPATCH_PROC(ProcXDGADispatch);
+static DISPATCH_PROC(SProcXDGADispatch);
+static DISPATCH_PROC(ProcXDGAQueryVersion);
+static DISPATCH_PROC(ProcXDGAQueryModes);
+static DISPATCH_PROC(ProcXDGASetMode);
+static DISPATCH_PROC(ProcXDGAOpenFramebuffer);
+static DISPATCH_PROC(ProcXDGACloseFramebuffer);
+static DISPATCH_PROC(ProcXDGASetViewport);
+static DISPATCH_PROC(ProcXDGAInstallColormap);
+static DISPATCH_PROC(ProcXDGASelectInput);
+static DISPATCH_PROC(ProcXDGAFillRectangle);
+static DISPATCH_PROC(ProcXDGACopyArea);
+static DISPATCH_PROC(ProcXDGACopyTransparentArea);
+static DISPATCH_PROC(ProcXDGAGetViewportStatus);
+static DISPATCH_PROC(ProcXDGASync);
+static DISPATCH_PROC(ProcXDGASetClientVersion);
+static DISPATCH_PROC(ProcXDGAChangePixmapMode);
+static DISPATCH_PROC(ProcXDGACreateColormap);
+
+static void XDGAResetProc(ExtensionEntry *extEntry);
+
+static void DGAClientStateChange (CallbackListPtr*, pointer, pointer);
+
+unsigned char DGAReqCode = 0;
+int DGAErrorBase;
+int DGAEventBase;
+
+static int DGAScreenPrivateKeyIndex;
+static DevPrivateKey DGAScreenPrivateKey = &DGAScreenPrivateKeyIndex;
+static int DGAClientPrivateKeyIndex;
+static DevPrivateKey DGAClientPrivateKey = &DGAClientPrivateKeyIndex;
+static int DGACallbackRefCount = 0;
+
+/* This holds the client's version information */
+typedef struct {
+ int major;
+ int minor;
+} DGAPrivRec, *DGAPrivPtr;
+
+#define DGA_GETCLIENT(idx) ((ClientPtr) \
+ dixLookupPrivate(&screenInfo.screens[idx]->devPrivates, DGAScreenPrivateKey))
+#define DGA_SETCLIENT(idx,p) \
+ dixSetPrivate(&screenInfo.screens[idx]->devPrivates, DGAScreenPrivateKey, p)
+
+#define DGA_GETPRIV(c) ((DGAPrivPtr) \
+ dixLookupPrivate(&(c)->devPrivates, DGAClientPrivateKey))
+#define DGA_SETPRIV(c,p) \
+ dixSetPrivate(&(c)->devPrivates, DGAClientPrivateKey, p)
+
+
+void
+XFree86DGAExtensionInit(INITARGS)
+{
+ ExtensionEntry* extEntry;
+
+ if ((extEntry = AddExtension(XF86DGANAME,
+ XF86DGANumberEvents,
+ XF86DGANumberErrors,
+ ProcXDGADispatch,
+ SProcXDGADispatch,
+ XDGAResetProc,
+ StandardMinorOpcode))) {
+ int i;
+
+ DGAReqCode = (unsigned char)extEntry->base;
+ DGAErrorBase = extEntry->errorBase;
+ DGAEventBase = extEntry->eventBase;
+ for (i = KeyPress; i <= MotionNotify; i++)
+ SetCriticalEvent (DGAEventBase + i);
+ }
+}
+
+
+
+static void
+XDGAResetProc (ExtensionEntry *extEntry)
+{
+ DeleteCallback (&ClientStateCallback, DGAClientStateChange, NULL);
+ DGACallbackRefCount = 0;
+}
+
+
+static int
+ProcXDGAQueryVersion(ClientPtr client)
+{
+ xXDGAQueryVersionReply rep;
+
+ REQUEST_SIZE_MATCH(xXDGAQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = SERVER_XDGA_MAJOR_VERSION;
+ rep.minorVersion = SERVER_XDGA_MINOR_VERSION;
+
+ WriteToClient(client, sizeof(xXDGAQueryVersionReply), (char *)&rep);
+ return Success;
+}
+
+
+static int
+ProcXDGAOpenFramebuffer(ClientPtr client)
+{
+ REQUEST(xXDGAOpenFramebufferReq);
+ xXDGAOpenFramebufferReply rep;
+ char *deviceName;
+ int nameSize;
+
+ if (stuff->screen > screenInfo.numScreens)
+ return BadValue;
+
+ if (!DGAAvailable(stuff->screen))
+ return DGAErrorBase + XF86DGANoDirectVideoMode;
+
+ REQUEST_SIZE_MATCH(xXDGAOpenFramebufferReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ if(!DGAOpenFramebuffer(stuff->screen, &deviceName,
+ (unsigned char**)(&rep.mem1),
+ (int*)&rep.size, (int*)&rep.offset, (int*)&rep.extra))
+ {
+ return BadAlloc;
+ }
+
+ nameSize = deviceName ? (strlen(deviceName) + 1) : 0;
+ rep.length = bytes_to_int32(nameSize);
+
+ WriteToClient(client, sizeof(xXDGAOpenFramebufferReply), (char *)&rep);
+ if(rep.length)
+ WriteToClient(client, nameSize, deviceName);
+
+ return Success;
+}
+
+
+static int
+ProcXDGACloseFramebuffer(ClientPtr client)
+{
+ REQUEST(xXDGACloseFramebufferReq);
+
+ if (stuff->screen > screenInfo.numScreens)
+ return BadValue;
+
+ if (!DGAAvailable(stuff->screen))
+ return DGAErrorBase + XF86DGANoDirectVideoMode;
+
+ REQUEST_SIZE_MATCH(xXDGACloseFramebufferReq);
+
+ DGACloseFramebuffer(stuff->screen);
+
+ return Success;
+}
+
+static int
+ProcXDGAQueryModes(ClientPtr client)
+{
+ int i, num, size;
+ REQUEST(xXDGAQueryModesReq);
+ xXDGAQueryModesReply rep;
+ xXDGAModeInfo info;
+ XDGAModePtr mode;
+
+ if (stuff->screen > screenInfo.numScreens)
+ return BadValue;
+
+ REQUEST_SIZE_MATCH(xXDGAQueryModesReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.number = 0;
+ rep.sequenceNumber = client->sequence;
+
+ if (!DGAAvailable(stuff->screen)) {
+ rep.number = 0;
+ rep.length = 0;
+ WriteToClient(client, sz_xXDGAQueryModesReply, (char*)&rep);
+ return Success;
+ }
+
+ if(!(num = DGAGetModes(stuff->screen))) {
+ WriteToClient(client, sz_xXDGAQueryModesReply, (char*)&rep);
+ return Success;
+ }
+
+ if(!(mode = (XDGAModePtr)malloc(num * sizeof(XDGAModeRec))))
+ return BadAlloc;
+
+ for(i = 0; i < num; i++)
+ DGAGetModeInfo(stuff->screen, mode + i, i + 1);
+
+ size = num * sz_xXDGAModeInfo;
+ for(i = 0; i < num; i++)
+ size += pad_to_int32(strlen(mode[i].name) + 1); /* plus NULL */
+
+ rep.number = num;
+ rep.length = bytes_to_int32(size);
+
+ WriteToClient(client, sz_xXDGAQueryModesReply, (char*)&rep);
+
+ for(i = 0; i < num; i++) {
+ size = strlen(mode[i].name) + 1;
+
+ info.byte_order = mode[i].byteOrder;
+ info.depth = mode[i].depth;
+ info.num = mode[i].num;
+ info.bpp = mode[i].bitsPerPixel;
+ info.name_size = (size + 3) & ~3L;
+ info.vsync_num = mode[i].VSync_num;
+ info.vsync_den = mode[i].VSync_den;
+ info.flags = mode[i].flags;
+ info.image_width = mode[i].imageWidth;
+ info.image_height = mode[i].imageHeight;
+ info.pixmap_width = mode[i].pixmapWidth;
+ info.pixmap_height = mode[i].pixmapHeight;
+ info.bytes_per_scanline = mode[i].bytesPerScanline;
+ info.red_mask = mode[i].red_mask;
+ info.green_mask = mode[i].green_mask;
+ info.blue_mask = mode[i].blue_mask;
+ info.visual_class = mode[i].visualClass;
+ info.viewport_width = mode[i].viewportWidth;
+ info.viewport_height = mode[i].viewportHeight;
+ info.viewport_xstep = mode[i].xViewportStep;
+ info.viewport_ystep = mode[i].yViewportStep;
+ info.viewport_xmax = mode[i].maxViewportX;
+ info.viewport_ymax = mode[i].maxViewportY;
+ info.viewport_flags = mode[i].viewportFlags;
+ info.reserved1 = mode[i].reserved1;
+ info.reserved2 = mode[i].reserved2;
+
+ WriteToClient(client, sz_xXDGAModeInfo, (char*)(&info));
+ WriteToClient(client, size, mode[i].name);
+ }
+
+ free(mode);
+
+ return Success;
+}
+
+
+static void
+DGAClientStateChange (
+ CallbackListPtr* pcbl,
+ pointer nulldata,
+ pointer calldata
+){
+ NewClientInfoRec* pci = (NewClientInfoRec*) calldata;
+ ClientPtr client = NULL;
+ int i;
+
+ for(i = 0; i < screenInfo.numScreens; i++) {
+ if(DGA_GETCLIENT(i) == pci->client) {
+ client = pci->client;
+ break;
+ }
+ }
+
+ if(client &&
+ ((client->clientState == ClientStateGone) ||
+ (client->clientState == ClientStateRetained))) {
+ XDGAModeRec mode;
+ PixmapPtr pPix;
+
+ DGA_SETCLIENT(i, NULL);
+ DGASelectInput(i, NULL, 0);
+ DGASetMode(i, 0, &mode, &pPix);
+
+ if(--DGACallbackRefCount == 0)
+ DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL);
+ }
+}
+
+static int
+ProcXDGASetMode(ClientPtr client)
+{
+ REQUEST(xXDGASetModeReq);
+ xXDGASetModeReply rep;
+ XDGAModeRec mode;
+ xXDGAModeInfo info;
+ PixmapPtr pPix;
+ ClientPtr owner;
+ int size;
+
+ if (stuff->screen > screenInfo.numScreens)
+ return BadValue;
+ owner = DGA_GETCLIENT(stuff->screen);
+
+ REQUEST_SIZE_MATCH(xXDGASetModeReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.offset = 0;
+ rep.flags = 0;
+ rep.sequenceNumber = client->sequence;
+
+ if (!DGAAvailable(stuff->screen))
+ return DGAErrorBase + XF86DGANoDirectVideoMode;
+
+ if(owner && owner != client)
+ return DGAErrorBase + XF86DGANoDirectVideoMode;
+
+ if(!stuff->mode) {
+ if(owner) {
+ if(--DGACallbackRefCount == 0)
+ DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL);
+ }
+ DGA_SETCLIENT(stuff->screen, NULL);
+ DGASelectInput(stuff->screen, NULL, 0);
+ DGASetMode(stuff->screen, 0, &mode, &pPix);
+ WriteToClient(client, sz_xXDGASetModeReply, (char*)&rep);
+ return Success;
+ }
+
+ if(Success != DGASetMode(stuff->screen, stuff->mode, &mode, &pPix))
+ return BadValue;
+
+ if(!owner) {
+ if(DGACallbackRefCount++ == 0)
+ AddCallback (&ClientStateCallback, DGAClientStateChange, NULL);
+ }
+
+ DGA_SETCLIENT(stuff->screen, client);
+
+ if(pPix) {
+ if(AddResource(stuff->pid, RT_PIXMAP, (pointer)(pPix))) {
+ pPix->drawable.id = (int)stuff->pid;
+ rep.flags = DGA_PIXMAP_AVAILABLE;
+ }
+ }
+
+ size = strlen(mode.name) + 1;
+
+ info.byte_order = mode.byteOrder;
+ info.depth = mode.depth;
+ info.num = mode.num;
+ info.bpp = mode.bitsPerPixel;
+ info.name_size = (size + 3) & ~3L;
+ info.vsync_num = mode.VSync_num;
+ info.vsync_den = mode.VSync_den;
+ info.flags = mode.flags;
+ info.image_width = mode.imageWidth;
+ info.image_height = mode.imageHeight;
+ info.pixmap_width = mode.pixmapWidth;
+ info.pixmap_height = mode.pixmapHeight;
+ info.bytes_per_scanline = mode.bytesPerScanline;
+ info.red_mask = mode.red_mask;
+ info.green_mask = mode.green_mask;
+ info.blue_mask = mode.blue_mask;
+ info.visual_class = mode.visualClass;
+ info.viewport_width = mode.viewportWidth;
+ info.viewport_height = mode.viewportHeight;
+ info.viewport_xstep = mode.xViewportStep;
+ info.viewport_ystep = mode.yViewportStep;
+ info.viewport_xmax = mode.maxViewportX;
+ info.viewport_ymax = mode.maxViewportY;
+ info.viewport_flags = mode.viewportFlags;
+ info.reserved1 = mode.reserved1;
+ info.reserved2 = mode.reserved2;
+
+ rep.length = bytes_to_int32(sz_xXDGAModeInfo + info.name_size);
+
+ WriteToClient(client, sz_xXDGASetModeReply, (char*)&rep);
+ WriteToClient(client, sz_xXDGAModeInfo, (char*)(&info));
+ WriteToClient(client, size, mode.name);
+
+ return Success;
+}
+
+static int
+ProcXDGASetViewport(ClientPtr client)
+{
+ REQUEST(xXDGASetViewportReq);
+
+ if (stuff->screen > screenInfo.numScreens)
+ return BadValue;
+
+ if(DGA_GETCLIENT(stuff->screen) != client)
+ return DGAErrorBase + XF86DGADirectNotActivated;
+
+ REQUEST_SIZE_MATCH(xXDGASetViewportReq);
+
+ DGASetViewport(stuff->screen, stuff->x, stuff->y, stuff->flags);
+
+ return Success;
+}
+
+static int
+ProcXDGAInstallColormap(ClientPtr client)
+{
+ ColormapPtr cmap;
+ int rc;
+ REQUEST(xXDGAInstallColormapReq);
+
+ if (stuff->screen > screenInfo.numScreens)
+ return BadValue;
+
+ if(DGA_GETCLIENT(stuff->screen) != client)
+ return DGAErrorBase + XF86DGADirectNotActivated;
+
+ REQUEST_SIZE_MATCH(xXDGAInstallColormapReq);
+
+ rc = dixLookupResourceByType((pointer *)&cmap, stuff->cmap, RT_COLORMAP,
+ client, DixInstallAccess);
+ if (rc != Success)
+ return (rc == BadValue) ? BadColor : rc;
+ DGAInstallCmap(cmap);
+ return Success;
+}
+
+
+static int
+ProcXDGASelectInput(ClientPtr client)
+{
+ REQUEST(xXDGASelectInputReq);
+
+ if (stuff->screen > screenInfo.numScreens)
+ return BadValue;
+
+ if(DGA_GETCLIENT(stuff->screen) != client)
+ return DGAErrorBase + XF86DGADirectNotActivated;
+
+ REQUEST_SIZE_MATCH(xXDGASelectInputReq);
+
+ if(DGA_GETCLIENT(stuff->screen) == client)
+ DGASelectInput(stuff->screen, client, stuff->mask);
+
+ return Success;
+}
+
+
+static int
+ProcXDGAFillRectangle(ClientPtr client)
+{
+ REQUEST(xXDGAFillRectangleReq);
+
+ if (stuff->screen > screenInfo.numScreens)
+ return BadValue;
+
+ if(DGA_GETCLIENT(stuff->screen) != client)
+ return DGAErrorBase + XF86DGADirectNotActivated;
+
+ REQUEST_SIZE_MATCH(xXDGAFillRectangleReq);
+
+ if(Success != DGAFillRect(stuff->screen, stuff->x, stuff->y,
+ stuff->width, stuff->height, stuff->color))
+ return BadMatch;
+
+ return Success;
+}
+
+static int
+ProcXDGACopyArea(ClientPtr client)
+{
+ REQUEST(xXDGACopyAreaReq);
+
+ if (stuff->screen > screenInfo.numScreens)
+ return BadValue;
+
+ if(DGA_GETCLIENT(stuff->screen) != client)
+ return DGAErrorBase + XF86DGADirectNotActivated;
+
+ REQUEST_SIZE_MATCH(xXDGACopyAreaReq);
+
+ if(Success != DGABlitRect(stuff->screen, stuff->srcx, stuff->srcy,
+ stuff->width, stuff->height, stuff->dstx, stuff->dsty))
+ return BadMatch;
+
+ return Success;
+}
+
+
+static int
+ProcXDGACopyTransparentArea(ClientPtr client)
+{
+ REQUEST(xXDGACopyTransparentAreaReq);
+
+ if (stuff->screen > screenInfo.numScreens)
+ return BadValue;
+
+ if(DGA_GETCLIENT(stuff->screen) != client)
+ return DGAErrorBase + XF86DGADirectNotActivated;
+
+ REQUEST_SIZE_MATCH(xXDGACopyTransparentAreaReq);
+
+ if(Success != DGABlitTransRect(stuff->screen, stuff->srcx, stuff->srcy,
+ stuff->width, stuff->height, stuff->dstx, stuff->dsty, stuff->key))
+ return BadMatch;
+
+ return Success;
+}
+
+
+static int
+ProcXDGAGetViewportStatus(ClientPtr client)
+{
+ REQUEST(xXDGAGetViewportStatusReq);
+ xXDGAGetViewportStatusReply rep;
+
+ if (stuff->screen > screenInfo.numScreens)
+ return BadValue;
+
+ if(DGA_GETCLIENT(stuff->screen) != client)
+ return DGAErrorBase + XF86DGADirectNotActivated;
+
+ REQUEST_SIZE_MATCH(xXDGAGetViewportStatusReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ rep.status = DGAGetViewportStatus(stuff->screen);
+
+ WriteToClient(client, sizeof(xXDGAGetViewportStatusReply), (char *)&rep);
+ return Success;
+}
+
+static int
+ProcXDGASync(ClientPtr client)
+{
+ REQUEST(xXDGASyncReq);
+ xXDGASyncReply rep;
+
+ if (stuff->screen > screenInfo.numScreens)
+ return BadValue;
+
+ if(DGA_GETCLIENT(stuff->screen) != client)
+ return DGAErrorBase + XF86DGADirectNotActivated;
+
+ REQUEST_SIZE_MATCH(xXDGASyncReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ DGASync(stuff->screen);
+
+ WriteToClient(client, sizeof(xXDGASyncReply), (char *)&rep);
+ return Success;
+}
+
+static int
+ProcXDGASetClientVersion(ClientPtr client)
+{
+ REQUEST(xXDGASetClientVersionReq);
+
+ DGAPrivPtr pPriv;
+
+ REQUEST_SIZE_MATCH(xXDGASetClientVersionReq);
+ if ((pPriv = DGA_GETPRIV(client)) == NULL) {
+ pPriv = malloc(sizeof(DGAPrivRec));
+ /* XXX Need to look into freeing this */
+ if (!pPriv)
+ return BadAlloc;
+ DGA_SETPRIV(client, pPriv);
+ }
+ pPriv->major = stuff->major;
+ pPriv->minor = stuff->minor;
+
+ return Success;
+}
+
+static int
+ProcXDGAChangePixmapMode(ClientPtr client)
+{
+ REQUEST(xXDGAChangePixmapModeReq);
+ xXDGAChangePixmapModeReply rep;
+ int x, y;
+
+ if (stuff->screen > screenInfo.numScreens)
+ return BadValue;
+
+ if(DGA_GETCLIENT(stuff->screen) != client)
+ return DGAErrorBase + XF86DGADirectNotActivated;
+
+ REQUEST_SIZE_MATCH(xXDGAChangePixmapModeReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ x = stuff->x;
+ y = stuff->y;
+
+ if(!DGAChangePixmapMode(stuff->screen, &x, &y, stuff->flags))
+ return BadMatch;
+
+ rep.x = x;
+ rep.y = y;
+ WriteToClient(client, sizeof(xXDGAChangePixmapModeReply), (char *)&rep);
+
+ return Success;
+}
+
+
+static int
+ProcXDGACreateColormap(ClientPtr client)
+{
+ REQUEST(xXDGACreateColormapReq);
+ int result;
+
+ if (stuff->screen > screenInfo.numScreens)
+ return BadValue;
+
+ if(DGA_GETCLIENT(stuff->screen) != client)
+ return DGAErrorBase + XF86DGADirectNotActivated;
+
+ REQUEST_SIZE_MATCH(xXDGACreateColormapReq);
+
+ if(!stuff->mode)
+ return BadValue;
+
+ result = DGACreateColormap(stuff->screen, client, stuff->id,
+ stuff->mode, stuff->alloc);
+ if(result != Success)
+ return result;
+
+ return Success;
+}
+
+/*
+ *
+ * Support for the old DGA protocol, used to live in xf86dga.c
+ *
+ */
+
+#ifdef DGA_PROTOCOL_OLD_SUPPORT
+
+static DISPATCH_PROC(ProcXF86DGADirectVideo);
+static DISPATCH_PROC(ProcXF86DGAGetVidPage);
+static DISPATCH_PROC(ProcXF86DGAGetVideoLL);
+static DISPATCH_PROC(ProcXF86DGAGetViewPortSize);
+static DISPATCH_PROC(ProcXF86DGASetVidPage);
+static DISPATCH_PROC(ProcXF86DGASetViewPort);
+static DISPATCH_PROC(ProcXF86DGAInstallColormap);
+static DISPATCH_PROC(ProcXF86DGAQueryDirectVideo);
+static DISPATCH_PROC(ProcXF86DGAViewPortChanged);
+
+
+static int
+ProcXF86DGAGetVideoLL(ClientPtr client)
+{
+ REQUEST(xXF86DGAGetVideoLLReq);
+ xXF86DGAGetVideoLLReply rep;
+ XDGAModeRec mode;
+ int num, offset, flags;
+ char *name;
+
+ if (stuff->screen > screenInfo.numScreens)
+ return BadValue;
+
+ REQUEST_SIZE_MATCH(xXF86DGAGetVideoLLReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ if(!DGAAvailable(stuff->screen))
+ return (DGAErrorBase + XF86DGANoDirectVideoMode);
+
+ if(!(num = DGAGetOldDGAMode(stuff->screen)))
+ return (DGAErrorBase + XF86DGANoDirectVideoMode);
+
+ /* get the parameters for the mode that best matches */
+ DGAGetModeInfo(stuff->screen, &mode, num);
+
+ if(!DGAOpenFramebuffer(stuff->screen, &name,
+ (unsigned char**)(&rep.offset),
+ (int*)(&rep.bank_size), &offset, &flags))
+ return BadAlloc;
+
+ rep.offset += mode.offset;
+ rep.width = mode.bytesPerScanline / (mode.bitsPerPixel >> 3);
+ rep.ram_size = rep.bank_size >> 10;
+
+ WriteToClient(client, SIZEOF(xXF86DGAGetVideoLLReply), (char *)&rep);
+ return Success;
+}
+
+static int
+ProcXF86DGADirectVideo(ClientPtr client)
+{
+ int num;
+ PixmapPtr pix;
+ XDGAModeRec mode;
+ ClientPtr owner;
+ REQUEST(xXF86DGADirectVideoReq);
+
+ if (stuff->screen > screenInfo.numScreens)
+ return BadValue;
+ owner = DGA_GETCLIENT(stuff->screen);
+
+ REQUEST_SIZE_MATCH(xXF86DGADirectVideoReq);
+
+ if (!DGAAvailable(stuff->screen))
+ return DGAErrorBase + XF86DGANoDirectVideoMode;
+
+ if (owner && owner != client)
+ return DGAErrorBase + XF86DGANoDirectVideoMode;
+
+ if (stuff->enable & XF86DGADirectGraphics) {
+ if(!(num = DGAGetOldDGAMode(stuff->screen)))
+ return (DGAErrorBase + XF86DGANoDirectVideoMode);
+ } else
+ num = 0;
+
+ if(Success != DGASetMode(stuff->screen, num, &mode, &pix))
+ return (DGAErrorBase + XF86DGAScreenNotActive);
+
+ DGASetInputMode (stuff->screen,
+ (stuff->enable & XF86DGADirectKeyb) != 0,
+ (stuff->enable & XF86DGADirectMouse) != 0);
+
+ /* We need to track the client and attach the teardown callback */
+ if (stuff->enable &
+ (XF86DGADirectGraphics | XF86DGADirectKeyb | XF86DGADirectMouse)) {
+ if (!owner) {
+ if (DGACallbackRefCount++ == 0)
+ AddCallback (&ClientStateCallback, DGAClientStateChange, NULL);
+ }
+
+ DGA_SETCLIENT(stuff->screen, client);
+ } else {
+ if (owner) {
+ if (--DGACallbackRefCount == 0)
+ DeleteCallback(&ClientStateCallback, DGAClientStateChange, NULL);
+ }
+
+ DGA_SETCLIENT(stuff->screen, NULL);
+ }
+
+ return Success;
+}
+
+static int
+ProcXF86DGAGetViewPortSize(ClientPtr client)
+{
+ int num;
+ XDGAModeRec mode;
+ REQUEST(xXF86DGAGetViewPortSizeReq);
+ xXF86DGAGetViewPortSizeReply rep;
+
+ if (stuff->screen > screenInfo.numScreens)
+ return BadValue;
+
+ REQUEST_SIZE_MATCH(xXF86DGAGetViewPortSizeReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ if (!DGAAvailable(stuff->screen))
+ return (DGAErrorBase + XF86DGANoDirectVideoMode);
+
+ if(!(num = DGAGetOldDGAMode(stuff->screen)))
+ return (DGAErrorBase + XF86DGANoDirectVideoMode);
+
+ DGAGetModeInfo(stuff->screen, &mode, num);
+
+ rep.width = mode.viewportWidth;
+ rep.height = mode.viewportHeight;
+
+ WriteToClient(client, SIZEOF(xXF86DGAGetViewPortSizeReply), (char *)&rep);
+ return Success;
+}
+
+static int
+ProcXF86DGASetViewPort(ClientPtr client)
+{
+ REQUEST(xXF86DGASetViewPortReq);
+
+ if (stuff->screen > screenInfo.numScreens)
+ return BadValue;
+
+ if (DGA_GETCLIENT(stuff->screen) != client)
+ return DGAErrorBase + XF86DGADirectNotActivated;
+
+ REQUEST_SIZE_MATCH(xXF86DGASetViewPortReq);
+
+ if (!DGAAvailable(stuff->screen))
+ return (DGAErrorBase + XF86DGANoDirectVideoMode);
+
+ if (!DGAActive(stuff->screen))
+ return DGAErrorBase + XF86DGADirectNotActivated;
+
+ if (DGASetViewport(stuff->screen, stuff->x, stuff->y, DGA_FLIP_RETRACE)
+ != Success)
+ return DGAErrorBase + XF86DGADirectNotActivated;
+
+ return Success;
+}
+
+static int
+ProcXF86DGAGetVidPage(ClientPtr client)
+{
+ REQUEST(xXF86DGAGetVidPageReq);
+ xXF86DGAGetVidPageReply rep;
+
+ if (stuff->screen > screenInfo.numScreens)
+ return BadValue;
+
+ REQUEST_SIZE_MATCH(xXF86DGAGetVidPageReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.vpage = 0; /* silently fail */
+
+ WriteToClient(client, SIZEOF(xXF86DGAGetVidPageReply), (char *)&rep);
+ return Success;
+}
+
+
+static int
+ProcXF86DGASetVidPage(ClientPtr client)
+{
+ REQUEST(xXF86DGASetVidPageReq);
+
+ if (stuff->screen > screenInfo.numScreens)
+ return BadValue;
+
+ REQUEST_SIZE_MATCH(xXF86DGASetVidPageReq);
+
+ /* silently fail */
+
+ return Success;
+}
+
+
+static int
+ProcXF86DGAInstallColormap(ClientPtr client)
+{
+ ColormapPtr pcmp;
+ int rc;
+ REQUEST(xXF86DGAInstallColormapReq);
+
+ if (stuff->screen > screenInfo.numScreens)
+ return BadValue;
+
+ if (DGA_GETCLIENT(stuff->screen) != client)
+ return DGAErrorBase + XF86DGADirectNotActivated;
+
+ REQUEST_SIZE_MATCH(xXF86DGAInstallColormapReq);
+
+ if (!DGAActive(stuff->screen))
+ return (DGAErrorBase + XF86DGADirectNotActivated);
+
+ rc = dixLookupResourceByType((pointer *)&pcmp, stuff->id, RT_COLORMAP,
+ client, DixInstallAccess);
+ if (rc == Success) {
+ DGAInstallCmap(pcmp);
+ return Success;
+ } else {
+ return (rc == BadValue) ? BadColor : rc;
+ }
+}
+
+static int
+ProcXF86DGAQueryDirectVideo(ClientPtr client)
+{
+ REQUEST(xXF86DGAQueryDirectVideoReq);
+ xXF86DGAQueryDirectVideoReply rep;
+
+ if (stuff->screen > screenInfo.numScreens)
+ return BadValue;
+
+ REQUEST_SIZE_MATCH(xXF86DGAQueryDirectVideoReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.flags = 0;
+
+ if (DGAAvailable(stuff->screen))
+ rep.flags = XF86DGADirectPresent;
+
+ WriteToClient(client, SIZEOF(xXF86DGAQueryDirectVideoReply), (char *)&rep);
+ return Success;
+}
+
+static int
+ProcXF86DGAViewPortChanged(ClientPtr client)
+{
+ REQUEST(xXF86DGAViewPortChangedReq);
+ xXF86DGAViewPortChangedReply rep;
+
+ if (stuff->screen > screenInfo.numScreens)
+ return BadValue;
+
+ if (DGA_GETCLIENT(stuff->screen) != client)
+ return DGAErrorBase + XF86DGADirectNotActivated;
+
+ REQUEST_SIZE_MATCH(xXF86DGAViewPortChangedReq);
+
+ if (!DGAActive(stuff->screen))
+ return (DGAErrorBase + XF86DGADirectNotActivated);
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.result = 1;
+
+ WriteToClient(client, SIZEOF(xXF86DGAViewPortChangedReply), (char *)&rep);
+ return Success;
+}
+
+#endif /* DGA_PROTOCOL_OLD_SUPPORT */
+
+static int
+SProcXDGADispatch (ClientPtr client)
+{
+ return DGAErrorBase + XF86DGAClientNotLocal;
+}
+
+#if 0
+#define DGA_REQ_DEBUG
+#endif
+
+#ifdef DGA_REQ_DEBUG
+static char *dgaMinor[] = {
+ "QueryVersion",
+ "GetVideoLL",
+ "DirectVideo",
+ "GetViewPortSize",
+ "SetViewPort",
+ "GetVidPage",
+ "SetVidPage",
+ "InstallColormap",
+ "QueryDirectVideo",
+ "ViewPortChanged",
+ "10",
+ "11",
+ "QueryModes",
+ "SetMode",
+ "SetViewport",
+ "InstallColormap",
+ "SelectInput",
+ "FillRectangle",
+ "CopyArea",
+ "CopyTransparentArea",
+ "GetViewportStatus",
+ "Sync",
+ "OpenFramebuffer",
+ "CloseFramebuffer",
+ "SetClientVersion",
+ "ChangePixmapMode",
+ "CreateColormap",
+};
+#endif
+
+static int
+ProcXDGADispatch (ClientPtr client)
+{
+ REQUEST(xReq);
+
+ if (!LocalClient(client))
+ return DGAErrorBase + XF86DGAClientNotLocal;
+
+#ifdef DGA_REQ_DEBUG
+ if (stuff->data <= X_XDGACreateColormap)
+ fprintf (stderr, " DGA %s\n", dgaMinor[stuff->data]);
+#endif
+
+ switch (stuff->data){
+ /*
+ * DGA2 Protocol
+ */
+ case X_XDGAQueryVersion:
+ return ProcXDGAQueryVersion(client);
+ case X_XDGAQueryModes:
+ return ProcXDGAQueryModes(client);
+ case X_XDGASetMode:
+ return ProcXDGASetMode(client);
+ case X_XDGAOpenFramebuffer:
+ return ProcXDGAOpenFramebuffer(client);
+ case X_XDGACloseFramebuffer:
+ return ProcXDGACloseFramebuffer(client);
+ case X_XDGASetViewport:
+ return ProcXDGASetViewport(client);
+ case X_XDGAInstallColormap:
+ return ProcXDGAInstallColormap(client);
+ case X_XDGASelectInput:
+ return ProcXDGASelectInput(client);
+ case X_XDGAFillRectangle:
+ return ProcXDGAFillRectangle(client);
+ case X_XDGACopyArea:
+ return ProcXDGACopyArea(client);
+ case X_XDGACopyTransparentArea:
+ return ProcXDGACopyTransparentArea(client);
+ case X_XDGAGetViewportStatus:
+ return ProcXDGAGetViewportStatus(client);
+ case X_XDGASync:
+ return ProcXDGASync(client);
+ case X_XDGASetClientVersion:
+ return ProcXDGASetClientVersion(client);
+ case X_XDGAChangePixmapMode:
+ return ProcXDGAChangePixmapMode(client);
+ case X_XDGACreateColormap:
+ return ProcXDGACreateColormap(client);
+ /*
+ * Old DGA Protocol
+ */
+#ifdef DGA_PROTOCOL_OLD_SUPPORT
+ case X_XF86DGAGetVideoLL:
+ return ProcXF86DGAGetVideoLL(client);
+ case X_XF86DGADirectVideo:
+ return ProcXF86DGADirectVideo(client);
+ case X_XF86DGAGetViewPortSize:
+ return ProcXF86DGAGetViewPortSize(client);
+ case X_XF86DGASetViewPort:
+ return ProcXF86DGASetViewPort(client);
+ case X_XF86DGAGetVidPage:
+ return ProcXF86DGAGetVidPage(client);
+ case X_XF86DGASetVidPage:
+ return ProcXF86DGASetVidPage(client);
+ case X_XF86DGAInstallColormap:
+ return ProcXF86DGAInstallColormap(client);
+ case X_XF86DGAQueryDirectVideo:
+ return ProcXF86DGAQueryDirectVideo(client);
+ case X_XF86DGAViewPortChanged:
+ return ProcXF86DGAViewPortChanged(client);
+#endif /* DGA_PROTOCOL_OLD_SUPPORT */
+ default:
+ return BadRequest;
+ }
+}
+
+void
+XFree86DGARegister(INITARGS)
+{
+ XDGAEventBase = &DGAEventBase;
+}
diff --git a/xorg-server/hw/xfree86/dixmods/extmod/xf86vmode.c b/xorg-server/hw/xfree86/dixmods/extmod/xf86vmode.c
index a304a42d4..483b92ab1 100644
--- a/xorg-server/hw/xfree86/dixmods/extmod/xf86vmode.c
+++ b/xorg-server/hw/xfree86/dixmods/extmod/xf86vmode.c
@@ -1,2170 +1,2170 @@
-
-/*
-
-Copyright 1995 Kaleb S. KEITHLEY
-
-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 Kaleb S. KEITHLEY 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 Kaleb S. KEITHLEY
-shall not be used in advertising or otherwise to promote the sale, use
-or other dealings in this Software without prior written authorization
-from Kaleb S. KEITHLEY
-
-*/
-/* THIS IS NOT AN X CONSORTIUM STANDARD OR AN X PROJECT TEAM SPECIFICATION */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "dixstruct.h"
-#include "extnsionst.h"
-#include "scrnintstr.h"
-#include "servermd.h"
-#include <X11/extensions/xf86vmproto.h>
-#include "swaprep.h"
-#include "xf86.h"
-#include "vidmodeproc.h"
-#include "globals.h"
-#include "protocol-versions.h"
-
-#define DEFAULT_XF86VIDMODE_VERBOSITY 3
-
-static int VidModeErrorBase;
-static int VidModeClientPrivateKeyIndex;
-static DevPrivateKey VidModeClientPrivateKey = &VidModeClientPrivateKeyIndex;
-
-/* This holds the client's version information */
-typedef struct {
- int major;
- int minor;
-} VidModePrivRec, *VidModePrivPtr;
-
-#define VM_GETPRIV(c) ((VidModePrivPtr) \
- dixLookupPrivate(&(c)->devPrivates, VidModeClientPrivateKey))
-#define VM_SETPRIV(c,p) \
- dixSetPrivate(&(c)->devPrivates, VidModeClientPrivateKey, p)
-
-static DISPATCH_PROC(ProcXF86VidModeDispatch);
-static DISPATCH_PROC(ProcXF86VidModeGetAllModeLines);
-static DISPATCH_PROC(ProcXF86VidModeGetModeLine);
-static DISPATCH_PROC(ProcXF86VidModeGetMonitor);
-static DISPATCH_PROC(ProcXF86VidModeLockModeSwitch);
-static DISPATCH_PROC(ProcXF86VidModeAddModeLine);
-static DISPATCH_PROC(ProcXF86VidModeDeleteModeLine);
-static DISPATCH_PROC(ProcXF86VidModeModModeLine);
-static DISPATCH_PROC(ProcXF86VidModeValidateModeLine);
-static DISPATCH_PROC(ProcXF86VidModeQueryVersion);
-static DISPATCH_PROC(ProcXF86VidModeSwitchMode);
-static DISPATCH_PROC(ProcXF86VidModeSwitchToMode);
-static DISPATCH_PROC(ProcXF86VidModeGetViewPort);
-static DISPATCH_PROC(ProcXF86VidModeSetViewPort);
-static DISPATCH_PROC(ProcXF86VidModeGetDotClocks);
-static DISPATCH_PROC(ProcXF86VidModeSetGamma);
-static DISPATCH_PROC(ProcXF86VidModeGetGamma);
-static DISPATCH_PROC(ProcXF86VidModeSetClientVersion);
-static DISPATCH_PROC(ProcXF86VidModeGetGammaRamp);
-static DISPATCH_PROC(ProcXF86VidModeSetGammaRamp);
-static DISPATCH_PROC(ProcXF86VidModeGetGammaRampSize);
-static DISPATCH_PROC(SProcXF86VidModeDispatch);
-static DISPATCH_PROC(SProcXF86VidModeGetAllModeLines);
-static DISPATCH_PROC(SProcXF86VidModeGetModeLine);
-static DISPATCH_PROC(SProcXF86VidModeGetMonitor);
-static DISPATCH_PROC(SProcXF86VidModeLockModeSwitch);
-static DISPATCH_PROC(SProcXF86VidModeAddModeLine);
-static DISPATCH_PROC(SProcXF86VidModeDeleteModeLine);
-static DISPATCH_PROC(SProcXF86VidModeModModeLine);
-static DISPATCH_PROC(SProcXF86VidModeValidateModeLine);
-static DISPATCH_PROC(SProcXF86VidModeQueryVersion);
-static DISPATCH_PROC(SProcXF86VidModeSwitchMode);
-static DISPATCH_PROC(SProcXF86VidModeSwitchToMode);
-static DISPATCH_PROC(SProcXF86VidModeGetViewPort);
-static DISPATCH_PROC(SProcXF86VidModeSetViewPort);
-static DISPATCH_PROC(SProcXF86VidModeGetDotClocks);
-static DISPATCH_PROC(SProcXF86VidModeSetGamma);
-static DISPATCH_PROC(SProcXF86VidModeGetGamma);
-static DISPATCH_PROC(SProcXF86VidModeSetClientVersion);
-static DISPATCH_PROC(SProcXF86VidModeGetGammaRamp);
-static DISPATCH_PROC(SProcXF86VidModeSetGammaRamp);
-static DISPATCH_PROC(SProcXF86VidModeGetGammaRampSize);
-
-#if 0
-static unsigned char XF86VidModeReqCode = 0;
-#endif
-
-/* The XF86VIDMODE_EVENTS code is far from complete */
-
-#ifdef XF86VIDMODE_EVENTS
-static int XF86VidModeEventBase = 0;
-
-static void SXF86VidModeNotifyEvent();
- xXF86VidModeNotifyEvent * /* from */,
- xXF86VidModeNotifyEvent * /* to */
-);
-
-static RESTYPE EventType; /* resource type for event masks */
-
-typedef struct _XF86VidModeEvent *XF86VidModeEventPtr;
-
-typedef struct _XF86VidModeEvent {
- XF86VidModeEventPtr next;
- ClientPtr client;
- ScreenPtr screen;
- XID resource;
- CARD32 mask;
-} XF86VidModeEventRec;
-
-static int XF86VidModeFreeEvents();
-
-typedef struct _XF86VidModeScreenPrivate {
- XF86VidModeEventPtr events;
- Bool hasWindow;
-} XF86VidModeScreenPrivateRec, *XF86VidModeScreenPrivatePtr;
-
-static int ScreenPrivateKeyIndex;
-static DevPrivateKey ScreenPrivateKey = &ScreenPrivateKeyIndex;
-
-#define GetScreenPrivate(s) ((ScreenSaverScreenPrivatePtr) \
- dixLookupPrivate(&(s)->devPrivates, ScreenPrivateKey))
-#define SetScreenPrivate(s,v) \
- dixSetPrivate(&(s)->devPrivates, ScreenPrivateKey, v)
-#define SetupScreen(s) ScreenSaverScreenPrivatePtr pPriv = GetScreenPrivate(s)
-
-#define New(t) (xalloc (sizeof (t)))
-#endif
-
-#ifdef DEBUG
-# define DEBUG_P(x) ErrorF(x"\n");
-#else
-# define DEBUG_P(x) /**/
-#endif
-
-void
-XFree86VidModeExtensionInit(void)
-{
- ExtensionEntry* extEntry;
- ScreenPtr pScreen;
- int i;
- Bool enabled = FALSE;
-
- DEBUG_P("XFree86VidModeExtensionInit");
-
-#ifdef XF86VIDMODE_EVENTS
- EventType = CreateNewResourceType(XF86VidModeFreeEvents, "VidModeEvent");
-#endif
-
- for(i = 0; i < screenInfo.numScreens; i++) {
- pScreen = screenInfo.screens[i];
- if (VidModeExtensionInit(pScreen))
- enabled = TRUE;
-#ifdef XF86VIDMODE_EVENTS
- SetScreenPrivate (pScreen, NULL);
-#endif
- }
- /* This means that the DDX doesn't want the vidmode extension enabled */
- if (!enabled)
- return;
-
- if (
-#ifdef XF86VIDMODE_EVENTS
- EventType &&
-#endif
- (extEntry = AddExtension(XF86VIDMODENAME,
- XF86VidModeNumberEvents,
- XF86VidModeNumberErrors,
- ProcXF86VidModeDispatch,
- SProcXF86VidModeDispatch,
- NULL,
- StandardMinorOpcode))) {
-#if 0
- XF86VidModeReqCode = (unsigned char)extEntry->base;
-#endif
- VidModeErrorBase = extEntry->errorBase;
-#ifdef XF86VIDMODE_EVENTS
- XF86VidModeEventBase = extEntry->eventBase;
- EventSwapVector[XF86VidModeEventBase] = (EventSwapPtr)SXF86VidModeNotifyEvent;
-#endif
- }
-}
-
-static int
-ClientMajorVersion(ClientPtr client)
-{
- VidModePrivPtr pPriv;
-
- pPriv = VM_GETPRIV(client);
- if (!pPriv)
- return 0;
- else
- return pPriv->major;
-}
-
-#ifdef XF86VIDMODE_EVENTS
-static void
-CheckScreenPrivate (pScreen)
- ScreenPtr pScreen;
-{
- SetupScreen (pScreen);
-
- if (!pPriv)
- return;
- if (!pPriv->events && !pPriv->hasWindow) {
- xfree (pPriv);
- SetScreenPrivate (pScreen, NULL);
- }
-}
-
-static XF86VidModeScreenPrivatePtr
-MakeScreenPrivate (pScreen)
- ScreenPtr pScreen;
-{
- SetupScreen (pScreen);
-
- if (pPriv)
- return pPriv;
- pPriv = New (XF86VidModeScreenPrivateRec);
- if (!pPriv)
- return 0;
- pPriv->events = 0;
- pPriv->hasWindow = FALSE;
- SetScreenPrivate (pScreen, pPriv);
- return pPriv;
-}
-
-static unsigned long
-getEventMask (ScreenPtr pScreen, ClientPtr client)
-{
- SetupScreen(pScreen);
- XF86VidModeEventPtr pEv;
-
- if (!pPriv)
- return 0;
- for (pEv = pPriv->events; pEv; pEv = pEv->next)
- if (pEv->client == client)
- return pEv->mask;
- return 0;
-}
-
-static Bool
-setEventMask (ScreenPtr pScreen, ClientPtr client, unsigned long mask)
-{
- SetupScreen(pScreen);
- XF86VidModeEventPtr pEv, *pPrev;
-
- if (getEventMask (pScreen, client) == mask)
- return TRUE;
- if (!pPriv) {
- pPriv = MakeScreenPrivate (pScreen);
- if (!pPriv)
- return FALSE;
- }
- for (pPrev = &pPriv->events; pEv = *pPrev; pPrev = &pEv->next)
- if (pEv->client == client)
- break;
- if (mask == 0) {
- *pPrev = pEv->next;
- xfree (pEv);
- CheckScreenPrivate (pScreen);
- } else {
- if (!pEv) {
- pEv = New (ScreenSaverEventRec);
- if (!pEv) {
- CheckScreenPrivate (pScreen);
- return FALSE;
- }
- *pPrev = pEv;
- pEv->next = NULL;
- pEv->client = client;
- pEv->screen = pScreen;
- pEv->resource = FakeClientID (client->index);
- }
- pEv->mask = mask;
- }
- return TRUE;
-}
-
-static int
-XF86VidModeFreeEvents(pointer value, XID id)
-{
- XF86VidModeEventPtr pOld = (XF86VidModeEventPtr)value;
- ScreenPtr pScreen = pOld->screen;
- SetupScreen (pScreen);
- XF86VidModeEventPtr pEv, *pPrev;
-
- if (!pPriv)
- return TRUE;
- for (pPrev = &pPriv->events; pEv = *pPrev; pPrev = &pEv->next)
- if (pEv == pOld)
- break;
- if (!pEv)
- return TRUE;
- *pPrev = pEv->next;
- xfree (pEv);
- CheckScreenPrivate (pScreen);
- return TRUE;
-}
-
-static void
-SendXF86VidModeNotify(ScreenPtr pScreen, int state, Bool forced)
-{
- XF86VidModeScreenPrivatePtr pPriv;
- XF86VidModeEventPtr pEv;
- unsigned long mask;
- xXF86VidModeNotifyEvent ev;
- ClientPtr client;
- int kind;
-
- UpdateCurrentTimeIf ();
- mask = XF86VidModeNotifyMask;
- pScreen = screenInfo.screens[pScreen->myNum];
- pPriv = GetScreenPrivate(pScreen);
- if (!pPriv)
- return;
- kind = XF86VidModeModeChange;
- for (pEv = pPriv->events; pEv; pEv = pEv->next)
- {
- client = pEv->client;
- if (client->clientGone)
- continue;
- if (!(pEv->mask & mask))
- continue;
- ev.type = XF86VidModeNotify + XF86VidModeEventBase;
- ev.state = state;
- ev.sequenceNumber = client->sequence;
- ev.timestamp = currentTime.milliseconds;
- ev.root = WindowTable[pScreen->myNum]->drawable.id;
- ev.kind = kind;
- ev.forced = forced;
- WriteEventsToClient (client, 1, (xEvent *) &ev);
- }
-}
-
-static void
-SXF86VidModeNotifyEvent(xXF86VidModeNotifyEvent *from,
- xXF86VidModeNotifyEvent *to)
-{
- to->type = from->type;
- to->state = from->state;
- cpswaps (from->sequenceNumber, to->sequenceNumber);
- cpswapl (from->timestamp, to->timestamp);
- cpswapl (from->root, to->root);
- to->kind = from->kind;
- to->forced = from->forced;
-}
-#endif
-
-static int
-ProcXF86VidModeQueryVersion(ClientPtr client)
-{
- xXF86VidModeQueryVersionReply rep;
- register int n;
-
- DEBUG_P("XF86VidModeQueryVersion");
-
- REQUEST_SIZE_MATCH(xXF86VidModeQueryVersionReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.majorVersion = SERVER_XF86VIDMODE_MAJOR_VERSION;
- rep.minorVersion = SERVER_XF86VIDMODE_MINOR_VERSION;
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swaps(&rep.majorVersion, n);
- swaps(&rep.minorVersion, n);
- }
- WriteToClient(client, sizeof(xXF86VidModeQueryVersionReply), (char *)&rep);
- return (client->noClientException);
-}
-
-static int
-ProcXF86VidModeGetModeLine(ClientPtr client)
-{
- REQUEST(xXF86VidModeGetModeLineReq);
- xXF86VidModeGetModeLineReply rep;
- xXF86OldVidModeGetModeLineReply oldrep;
- pointer mode;
- register int n;
- int dotClock;
- int ver;
-
- DEBUG_P("XF86VidModeGetModeline");
-
- ver = ClientMajorVersion(client);
- REQUEST_SIZE_MATCH(xXF86VidModeGetModeLineReq);
- rep.type = X_Reply;
- if (ver < 2) {
- rep.length = bytes_to_int32(SIZEOF(xXF86OldVidModeGetModeLineReply) -
- SIZEOF(xGenericReply));
- } else {
- rep.length = bytes_to_int32(SIZEOF(xXF86VidModeGetModeLineReply) -
- SIZEOF(xGenericReply));
- }
- rep.sequenceNumber = client->sequence;
-
- if(stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- if (!VidModeGetCurrentModeline(stuff->screen, &mode, &dotClock))
- return BadValue;
-
- rep.dotclock = dotClock;
- rep.hdisplay = VidModeGetModeValue(mode, VIDMODE_H_DISPLAY);
- rep.hsyncstart = VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART);
- rep.hsyncend = VidModeGetModeValue(mode, VIDMODE_H_SYNCEND);
- rep.htotal = VidModeGetModeValue(mode, VIDMODE_H_TOTAL);
- rep.hskew = VidModeGetModeValue(mode, VIDMODE_H_SKEW);
- rep.vdisplay = VidModeGetModeValue(mode, VIDMODE_V_DISPLAY);
- rep.vsyncstart = VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART);
- rep.vsyncend = VidModeGetModeValue(mode, VIDMODE_V_SYNCEND);
- rep.vtotal = VidModeGetModeValue(mode, VIDMODE_V_TOTAL);
- rep.flags = VidModeGetModeValue(mode, VIDMODE_FLAGS);
-
- if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) {
- ErrorF("GetModeLine - scrn: %d clock: %ld\n",
- stuff->screen, (unsigned long)rep.dotclock);
- ErrorF("GetModeLine - hdsp: %d hbeg: %d hend: %d httl: %d\n",
- rep.hdisplay, rep.hsyncstart,
- rep.hsyncend, rep.htotal);
- ErrorF(" vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
- rep.vdisplay, rep.vsyncstart, rep.vsyncend,
- rep.vtotal, (unsigned long)rep.flags);
- }
-
- /*
- * Older servers sometimes had server privates that the VidMode
- * extention made available. So to be compatiable pretend that
- * there are no server privates to pass to the client
- */
- rep.privsize = 0;
-
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swapl(&rep.dotclock, n);
- swaps(&rep.hdisplay, n);
- swaps(&rep.hsyncstart, n);
- swaps(&rep.hsyncend, n);
- swaps(&rep.htotal, n);
- swaps(&rep.hskew, n);
- swaps(&rep.vdisplay, n);
- swaps(&rep.vsyncstart, n);
- swaps(&rep.vsyncend, n);
- swaps(&rep.vtotal, n);
- swapl(&rep.flags, n);
- swapl(&rep.privsize, n);
- }
- if (ver < 2) {
- oldrep.type = rep.type;
- oldrep.sequenceNumber = rep.sequenceNumber;
- oldrep.length = rep.length;
- oldrep.dotclock = rep.dotclock;
- oldrep.hdisplay = rep.hdisplay;
- oldrep.hsyncstart = rep.hsyncstart;
- oldrep.hsyncend = rep.hsyncend;
- oldrep.htotal = rep.htotal;
- oldrep.vdisplay = rep.vdisplay;
- oldrep.vsyncstart = rep.vsyncstart;
- oldrep.vsyncend = rep.vsyncend;
- oldrep.vtotal = rep.vtotal;
- oldrep.flags = rep.flags;
- oldrep.privsize = rep.privsize;
- WriteToClient(client, sizeof(xXF86OldVidModeGetModeLineReply),
- (char *)&oldrep);
- } else {
- WriteToClient(client, sizeof(xXF86VidModeGetModeLineReply),
- (char *)&rep);
- }
- return (client->noClientException);
-}
-
-static int
-ProcXF86VidModeGetAllModeLines(ClientPtr client)
-{
- REQUEST(xXF86VidModeGetAllModeLinesReq);
- xXF86VidModeGetAllModeLinesReply rep;
- xXF86VidModeModeInfo mdinf;
- xXF86OldVidModeModeInfo oldmdinf;
- pointer mode;
- int modecount, dotClock;
- register int n;
- int ver;
-
- DEBUG_P("XF86VidModeGetAllModelines");
-
- REQUEST_SIZE_MATCH(xXF86VidModeGetAllModeLinesReq);
-
- if(stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- ver = ClientMajorVersion(client);
-
- modecount = VidModeGetNumOfModes(stuff->screen);
- if (modecount < 1)
- return (VidModeErrorBase + XF86VidModeExtensionDisabled);
-
- if (!VidModeGetFirstModeline(stuff->screen, &mode, &dotClock))
- return BadValue;
-
- rep.type = X_Reply;
- rep.length = SIZEOF(xXF86VidModeGetAllModeLinesReply) -
- SIZEOF(xGenericReply);
- if (ver < 2)
- rep.length += modecount * sizeof(xXF86OldVidModeModeInfo);
- else
- rep.length += modecount * sizeof(xXF86VidModeModeInfo);
- rep.length >>= 2;
- rep.sequenceNumber = client->sequence;
- rep.modecount = modecount;
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swapl(&rep.modecount, n);
- }
- WriteToClient(client, sizeof(xXF86VidModeGetAllModeLinesReply), (char *)&rep);
-
- do {
- mdinf.dotclock = dotClock;
- mdinf.hdisplay = VidModeGetModeValue(mode, VIDMODE_H_DISPLAY);
- mdinf.hsyncstart = VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART);
- mdinf.hsyncend = VidModeGetModeValue(mode, VIDMODE_H_SYNCEND);
- mdinf.htotal = VidModeGetModeValue(mode, VIDMODE_H_TOTAL);
- mdinf.hskew = VidModeGetModeValue(mode, VIDMODE_H_SKEW);
- mdinf.vdisplay = VidModeGetModeValue(mode, VIDMODE_V_DISPLAY);
- mdinf.vsyncstart = VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART);
- mdinf.vsyncend = VidModeGetModeValue(mode, VIDMODE_V_SYNCEND);
- mdinf.vtotal = VidModeGetModeValue(mode, VIDMODE_V_TOTAL);
- mdinf.flags = VidModeGetModeValue(mode, VIDMODE_FLAGS);
- mdinf.privsize = 0;
- if (client->swapped) {
- swapl(&mdinf.dotclock, n);
- swaps(&mdinf.hdisplay, n);
- swaps(&mdinf.hsyncstart, n);
- swaps(&mdinf.hsyncend, n);
- swaps(&mdinf.htotal, n);
- swaps(&mdinf.hskew, n);
- swaps(&mdinf.vdisplay, n);
- swaps(&mdinf.vsyncstart, n);
- swaps(&mdinf.vsyncend, n);
- swaps(&mdinf.vtotal, n);
- swapl(&mdinf.flags, n);
- swapl(&mdinf.privsize, n);
- }
- if (ver < 2) {
- oldmdinf.dotclock = mdinf.dotclock;
- oldmdinf.hdisplay = mdinf.hdisplay;
- oldmdinf.hsyncstart = mdinf.hsyncstart;
- oldmdinf.hsyncend = mdinf.hsyncend;
- oldmdinf.htotal = mdinf.htotal;
- oldmdinf.vdisplay = mdinf.vdisplay;
- oldmdinf.vsyncstart = mdinf.vsyncstart;
- oldmdinf.vsyncend = mdinf.vsyncend;
- oldmdinf.vtotal = mdinf.vtotal;
- oldmdinf.flags = mdinf.flags;
- oldmdinf.privsize = mdinf.privsize;
- WriteToClient(client, sizeof(xXF86OldVidModeModeInfo),
- (char *)&oldmdinf);
- } else {
- WriteToClient(client, sizeof(xXF86VidModeModeInfo), (char *)&mdinf);
- }
-
- } while (VidModeGetNextModeline(stuff->screen, &mode, &dotClock));
-
- return (client->noClientException);
-}
-
-#define MODEMATCH(mode,stuff) \
- (VidModeGetModeValue(mode, VIDMODE_H_DISPLAY) == stuff->hdisplay \
- && VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART) == stuff->hsyncstart \
- && VidModeGetModeValue(mode, VIDMODE_H_SYNCEND) == stuff->hsyncend \
- && VidModeGetModeValue(mode, VIDMODE_H_TOTAL) == stuff->htotal \
- && VidModeGetModeValue(mode, VIDMODE_V_DISPLAY) == stuff->vdisplay \
- && VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART) == stuff->vsyncstart \
- && VidModeGetModeValue(mode, VIDMODE_V_SYNCEND) == stuff->vsyncend \
- && VidModeGetModeValue(mode, VIDMODE_V_TOTAL) == stuff->vtotal \
- && VidModeGetModeValue(mode, VIDMODE_FLAGS) == stuff->flags )
-
-static int
-ProcXF86VidModeAddModeLine(ClientPtr client)
-{
- REQUEST(xXF86VidModeAddModeLineReq);
- xXF86OldVidModeAddModeLineReq *oldstuff =
- (xXF86OldVidModeAddModeLineReq *)client->requestBuffer;
- xXF86VidModeAddModeLineReq newstuff;
- pointer mode;
- int len;
- int dotClock;
- int ver;
-
- DEBUG_P("XF86VidModeAddModeline");
-
- ver = ClientMajorVersion(client);
- if (ver < 2) {
- /* convert from old format */
- stuff = &newstuff;
- stuff->length = oldstuff->length;
- stuff->screen = oldstuff->screen;
- stuff->dotclock = oldstuff->dotclock;
- stuff->hdisplay = oldstuff->hdisplay;
- stuff->hsyncstart = oldstuff->hsyncstart;
- stuff->hsyncend = oldstuff->hsyncend;
- stuff->htotal = oldstuff->htotal;
- stuff->hskew = 0;
- stuff->vdisplay = oldstuff->vdisplay;
- stuff->vsyncstart = oldstuff->vsyncstart;
- stuff->vsyncend = oldstuff->vsyncend;
- stuff->vtotal = oldstuff->vtotal;
- stuff->flags = oldstuff->flags;
- stuff->privsize = oldstuff->privsize;
- stuff->after_dotclock = oldstuff->after_dotclock;
- stuff->after_hdisplay = oldstuff->after_hdisplay;
- stuff->after_hsyncstart = oldstuff->after_hsyncstart;
- stuff->after_hsyncend = oldstuff->after_hsyncend;
- stuff->after_htotal = oldstuff->after_htotal;
- stuff->after_hskew = 0;
- stuff->after_vdisplay = oldstuff->after_vdisplay;
- stuff->after_vsyncstart = oldstuff->after_vsyncstart;
- stuff->after_vsyncend = oldstuff->after_vsyncend;
- stuff->after_vtotal = oldstuff->after_vtotal;
- stuff->after_flags = oldstuff->after_flags;
- }
- if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) {
- ErrorF("AddModeLine - scrn: %d clock: %ld\n",
- (int)stuff->screen, (unsigned long)stuff->dotclock);
- ErrorF("AddModeLine - hdsp: %d hbeg: %d hend: %d httl: %d\n",
- stuff->hdisplay, stuff->hsyncstart,
- stuff->hsyncend, stuff->htotal);
- ErrorF(" vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
- stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend,
- stuff->vtotal, (unsigned long)stuff->flags);
- ErrorF(" after - scrn: %d clock: %ld\n",
- (int)stuff->screen, (unsigned long)stuff->after_dotclock);
- ErrorF(" hdsp: %d hbeg: %d hend: %d httl: %d\n",
- stuff->after_hdisplay, stuff->after_hsyncstart,
- stuff->after_hsyncend, stuff->after_htotal);
- ErrorF(" vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
- stuff->after_vdisplay, stuff->after_vsyncstart,
- stuff->after_vsyncend, stuff->after_vtotal,
- (unsigned long)stuff->after_flags);
- }
-
- if (ver < 2) {
- REQUEST_AT_LEAST_SIZE(xXF86OldVidModeAddModeLineReq);
- len = client->req_len - bytes_to_int32(sizeof(xXF86OldVidModeAddModeLineReq));
- } else {
- REQUEST_AT_LEAST_SIZE(xXF86VidModeAddModeLineReq);
- len = client->req_len - bytes_to_int32(sizeof(xXF86VidModeAddModeLineReq));
- }
- if (len != stuff->privsize)
- return BadLength;
-
- if(stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- if (stuff->hsyncstart < stuff->hdisplay ||
- stuff->hsyncend < stuff->hsyncstart ||
- stuff->htotal < stuff->hsyncend ||
- stuff->vsyncstart < stuff->vdisplay ||
- stuff->vsyncend < stuff->vsyncstart ||
- stuff->vtotal < stuff->vsyncend)
- return BadValue;
-
- if (stuff->after_hsyncstart < stuff->after_hdisplay ||
- stuff->after_hsyncend < stuff->after_hsyncstart ||
- stuff->after_htotal < stuff->after_hsyncend ||
- stuff->after_vsyncstart < stuff->after_vdisplay ||
- stuff->after_vsyncend < stuff->after_vsyncstart ||
- stuff->after_vtotal < stuff->after_vsyncend)
- return BadValue;
-
- if (stuff->after_htotal != 0 || stuff->after_vtotal != 0) {
- Bool found = FALSE;
- if (VidModeGetFirstModeline(stuff->screen, &mode, &dotClock)) {
- do {
- if ((VidModeGetDotClock(stuff->screen, stuff->dotclock)
- == dotClock) && MODEMATCH(mode, stuff)) {
- found = TRUE;
- break;
- }
- } while (VidModeGetNextModeline(stuff->screen, &mode, &dotClock));
- }
- if (!found)
- return BadValue;
- }
-
-
- mode = VidModeCreateMode();
- if (mode == NULL)
- return BadValue;
-
- VidModeSetModeValue(mode, VIDMODE_CLOCK, stuff->dotclock);
- VidModeSetModeValue(mode, VIDMODE_H_DISPLAY, stuff->hdisplay);
- VidModeSetModeValue(mode, VIDMODE_H_SYNCSTART, stuff->hsyncstart);
- VidModeSetModeValue(mode, VIDMODE_H_SYNCEND, stuff->hsyncend);
- VidModeSetModeValue(mode, VIDMODE_H_TOTAL, stuff->htotal);
- VidModeSetModeValue(mode, VIDMODE_H_SKEW, stuff->hskew);
- VidModeSetModeValue(mode, VIDMODE_V_DISPLAY, stuff->vdisplay);
- VidModeSetModeValue(mode, VIDMODE_V_SYNCSTART, stuff->vsyncstart);
- VidModeSetModeValue(mode, VIDMODE_V_SYNCEND, stuff->vsyncend);
- VidModeSetModeValue(mode, VIDMODE_V_TOTAL, stuff->vtotal);
- VidModeSetModeValue(mode, VIDMODE_FLAGS, stuff->flags);
-
- if (stuff->privsize)
- ErrorF("AddModeLine - Privates in request have been ignored\n");
-
- /* Check that the mode is consistent with the monitor specs */
- switch (VidModeCheckModeForMonitor(stuff->screen, mode)) {
- case MODE_OK:
- break;
- case MODE_HSYNC:
- case MODE_H_ILLEGAL:
- xfree(mode);
- return VidModeErrorBase + XF86VidModeBadHTimings;
- case MODE_VSYNC:
- case MODE_V_ILLEGAL:
- xfree(mode);
- return VidModeErrorBase + XF86VidModeBadVTimings;
- default:
- xfree(mode);
- return VidModeErrorBase + XF86VidModeModeUnsuitable;
- }
-
- /* Check that the driver is happy with the mode */
- if (VidModeCheckModeForDriver(stuff->screen, mode) != MODE_OK) {
- xfree(mode);
- return VidModeErrorBase + XF86VidModeModeUnsuitable;
- }
-
- VidModeSetCrtcForMode(stuff->screen, mode);
-
- VidModeAddModeline(stuff->screen, mode);
-
- if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY)
- ErrorF("AddModeLine - Succeeded\n");
- return client->noClientException;
-}
-
-static int
-ProcXF86VidModeDeleteModeLine(ClientPtr client)
-{
- REQUEST(xXF86VidModeDeleteModeLineReq);
- xXF86OldVidModeDeleteModeLineReq *oldstuff =
- (xXF86OldVidModeDeleteModeLineReq *)client->requestBuffer;
- xXF86VidModeDeleteModeLineReq newstuff;
- pointer mode;
- int len, dotClock;
- int ver;
-
- DEBUG_P("XF86VidModeDeleteModeline");
-
- ver = ClientMajorVersion(client);
- if (ver < 2) {
- /* convert from old format */
- stuff = &newstuff;
- stuff->length = oldstuff->length;
- stuff->screen = oldstuff->screen;
- stuff->dotclock = oldstuff->dotclock;
- stuff->hdisplay = oldstuff->hdisplay;
- stuff->hsyncstart = oldstuff->hsyncstart;
- stuff->hsyncend = oldstuff->hsyncend;
- stuff->htotal = oldstuff->htotal;
- stuff->hskew = 0;
- stuff->vdisplay = oldstuff->vdisplay;
- stuff->vsyncstart = oldstuff->vsyncstart;
- stuff->vsyncend = oldstuff->vsyncend;
- stuff->vtotal = oldstuff->vtotal;
- stuff->flags = oldstuff->flags;
- stuff->privsize = oldstuff->privsize;
- }
- if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) {
- ErrorF("DeleteModeLine - scrn: %d clock: %ld\n",
- (int)stuff->screen, (unsigned long)stuff->dotclock);
- ErrorF(" hdsp: %d hbeg: %d hend: %d httl: %d\n",
- stuff->hdisplay, stuff->hsyncstart,
- stuff->hsyncend, stuff->htotal);
- ErrorF(" vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
- stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend,
- stuff->vtotal, (unsigned long)stuff->flags);
- }
-
- if (ver < 2) {
- REQUEST_AT_LEAST_SIZE(xXF86OldVidModeDeleteModeLineReq);
- len = client->req_len - bytes_to_int32(sizeof(xXF86OldVidModeDeleteModeLineReq));
- } else {
- REQUEST_AT_LEAST_SIZE(xXF86VidModeDeleteModeLineReq);
- len = client->req_len - bytes_to_int32(sizeof(xXF86VidModeDeleteModeLineReq));
- }
- if (len != stuff->privsize) {
- if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) {
- ErrorF("req_len = %ld, sizeof(Req) = %d, privsize = %ld, "
- "len = %d, length = %d\n",
- (unsigned long)client->req_len,
- (int)sizeof(xXF86VidModeDeleteModeLineReq)>>2,
- (unsigned long)stuff->privsize, len, stuff->length);
- }
- return BadLength;
- }
-
- if(stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- if (!VidModeGetCurrentModeline(stuff->screen, &mode, &dotClock))
- return BadValue;
-
- if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) {
- ErrorF("Checking against clock: %d (%d)\n",
- VidModeGetModeValue(mode, VIDMODE_CLOCK), dotClock);
- ErrorF(" hdsp: %d hbeg: %d hend: %d httl: %d\n",
- VidModeGetModeValue(mode, VIDMODE_H_DISPLAY),
- VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART),
- VidModeGetModeValue(mode, VIDMODE_H_SYNCEND),
- VidModeGetModeValue(mode, VIDMODE_H_TOTAL));
- ErrorF(" vdsp: %d vbeg: %d vend: %d vttl: %d flags: %d\n",
- VidModeGetModeValue(mode, VIDMODE_V_DISPLAY),
- VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART),
- VidModeGetModeValue(mode, VIDMODE_V_SYNCEND),
- VidModeGetModeValue(mode, VIDMODE_V_TOTAL),
- VidModeGetModeValue(mode, VIDMODE_FLAGS));
- }
- if ((VidModeGetDotClock(stuff->screen, stuff->dotclock) == dotClock) &&
- MODEMATCH(mode, stuff))
- return BadValue;
-
- if (!VidModeGetFirstModeline(stuff->screen, &mode, &dotClock))
- return BadValue;
-
- do {
- if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) {
- ErrorF("Checking against clock: %d (%d)\n",
- VidModeGetModeValue(mode, VIDMODE_CLOCK), dotClock);
- ErrorF(" hdsp: %d hbeg: %d hend: %d httl: %d\n",
- VidModeGetModeValue(mode, VIDMODE_H_DISPLAY),
- VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART),
- VidModeGetModeValue(mode, VIDMODE_H_SYNCEND),
- VidModeGetModeValue(mode, VIDMODE_H_TOTAL));
- ErrorF(" vdsp: %d vbeg: %d vend: %d vttl: %d flags: %d\n",
- VidModeGetModeValue(mode, VIDMODE_V_DISPLAY),
- VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART),
- VidModeGetModeValue(mode, VIDMODE_V_SYNCEND),
- VidModeGetModeValue(mode, VIDMODE_V_TOTAL),
- VidModeGetModeValue(mode, VIDMODE_FLAGS));
- }
- if ((VidModeGetDotClock(stuff->screen, stuff->dotclock) == dotClock) &&
- MODEMATCH(mode, stuff)) {
- VidModeDeleteModeline(stuff->screen, mode);
- if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY)
- ErrorF("DeleteModeLine - Succeeded\n");
- return(client->noClientException);
- }
- } while (VidModeGetNextModeline(stuff->screen, &mode, &dotClock));
-
- return BadValue;
-}
-
-static int
-ProcXF86VidModeModModeLine(ClientPtr client)
-{
- REQUEST(xXF86VidModeModModeLineReq);
- xXF86OldVidModeModModeLineReq *oldstuff =
- (xXF86OldVidModeModModeLineReq *)client->requestBuffer;
- xXF86VidModeModModeLineReq newstuff;
- pointer mode, modetmp;
- int len, dotClock;
- int ver;
-
- DEBUG_P("XF86VidModeModModeline");
-
- ver = ClientMajorVersion(client);
- if (ver < 2 ) {
- /* convert from old format */
- stuff = &newstuff;
- stuff->length = oldstuff->length;
- stuff->screen = oldstuff->screen;
- stuff->hdisplay = oldstuff->hdisplay;
- stuff->hsyncstart = oldstuff->hsyncstart;
- stuff->hsyncend = oldstuff->hsyncend;
- stuff->htotal = oldstuff->htotal;
- stuff->hskew = 0;
- stuff->vdisplay = oldstuff->vdisplay;
- stuff->vsyncstart = oldstuff->vsyncstart;
- stuff->vsyncend = oldstuff->vsyncend;
- stuff->vtotal = oldstuff->vtotal;
- stuff->flags = oldstuff->flags;
- stuff->privsize = oldstuff->privsize;
- }
- if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) {
- ErrorF("ModModeLine - scrn: %d hdsp: %d hbeg: %d hend: %d httl: %d\n",
- (int)stuff->screen, stuff->hdisplay, stuff->hsyncstart,
- stuff->hsyncend, stuff->htotal);
- ErrorF(" vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
- stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend,
- stuff->vtotal, (unsigned long)stuff->flags);
- }
-
- if (ver < 2) {
- REQUEST_AT_LEAST_SIZE(xXF86OldVidModeModModeLineReq);
- len = client->req_len - bytes_to_int32(sizeof(xXF86OldVidModeModModeLineReq));
- } else {
- REQUEST_AT_LEAST_SIZE(xXF86VidModeModModeLineReq);
- len = client->req_len - bytes_to_int32(sizeof(xXF86VidModeModModeLineReq));
- }
- if (len != stuff->privsize)
- return BadLength;
-
- if (stuff->hsyncstart < stuff->hdisplay ||
- stuff->hsyncend < stuff->hsyncstart ||
- stuff->htotal < stuff->hsyncend ||
- stuff->vsyncstart < stuff->vdisplay ||
- stuff->vsyncend < stuff->vsyncstart ||
- stuff->vtotal < stuff->vsyncend)
- return BadValue;
-
- if(stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- if (!VidModeGetCurrentModeline(stuff->screen, &mode, &dotClock))
- return BadValue;
-
- modetmp = VidModeCreateMode();
- VidModeCopyMode(mode, modetmp);
-
- VidModeSetModeValue(modetmp, VIDMODE_H_DISPLAY, stuff->hdisplay);
- VidModeSetModeValue(modetmp, VIDMODE_H_SYNCSTART, stuff->hsyncstart);
- VidModeSetModeValue(modetmp, VIDMODE_H_SYNCEND, stuff->hsyncend);
- VidModeSetModeValue(modetmp, VIDMODE_H_TOTAL, stuff->htotal);
- VidModeSetModeValue(modetmp, VIDMODE_H_SKEW, stuff->hskew);
- VidModeSetModeValue(modetmp, VIDMODE_V_DISPLAY, stuff->vdisplay);
- VidModeSetModeValue(modetmp, VIDMODE_V_SYNCSTART, stuff->vsyncstart);
- VidModeSetModeValue(modetmp, VIDMODE_V_SYNCEND, stuff->vsyncend);
- VidModeSetModeValue(modetmp, VIDMODE_V_TOTAL, stuff->vtotal);
- VidModeSetModeValue(modetmp, VIDMODE_FLAGS, stuff->flags);
-
- if (stuff->privsize)
- ErrorF("ModModeLine - Privates in request have been ignored\n");
-
- /* Check that the mode is consistent with the monitor specs */
- switch (VidModeCheckModeForMonitor(stuff->screen, modetmp)) {
- case MODE_OK:
- break;
- case MODE_HSYNC:
- case MODE_H_ILLEGAL:
- xfree(modetmp);
- return VidModeErrorBase + XF86VidModeBadHTimings;
- case MODE_VSYNC:
- case MODE_V_ILLEGAL:
- xfree(modetmp);
- return VidModeErrorBase + XF86VidModeBadVTimings;
- default:
- xfree(modetmp);
- return VidModeErrorBase + XF86VidModeModeUnsuitable;
- }
-
- /* Check that the driver is happy with the mode */
- if (VidModeCheckModeForDriver(stuff->screen, modetmp) != MODE_OK) {
- xfree(modetmp);
- return VidModeErrorBase + XF86VidModeModeUnsuitable;
- }
- xfree(modetmp);
-
- VidModeSetModeValue(mode, VIDMODE_H_DISPLAY, stuff->hdisplay);
- VidModeSetModeValue(mode, VIDMODE_H_SYNCSTART, stuff->hsyncstart);
- VidModeSetModeValue(mode, VIDMODE_H_SYNCEND, stuff->hsyncend);
- VidModeSetModeValue(mode, VIDMODE_H_TOTAL, stuff->htotal);
- VidModeSetModeValue(mode, VIDMODE_H_SKEW, stuff->hskew);
- VidModeSetModeValue(mode, VIDMODE_V_DISPLAY, stuff->vdisplay);
- VidModeSetModeValue(mode, VIDMODE_V_SYNCSTART, stuff->vsyncstart);
- VidModeSetModeValue(mode, VIDMODE_V_SYNCEND, stuff->vsyncend);
- VidModeSetModeValue(mode, VIDMODE_V_TOTAL, stuff->vtotal);
- VidModeSetModeValue(mode, VIDMODE_FLAGS, stuff->flags);
-
- VidModeSetCrtcForMode(stuff->screen, mode);
- VidModeSwitchMode(stuff->screen, mode);
-
- if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY)
- ErrorF("ModModeLine - Succeeded\n");
- return(client->noClientException);
-}
-
-static int
-ProcXF86VidModeValidateModeLine(ClientPtr client)
-{
- REQUEST(xXF86VidModeValidateModeLineReq);
- xXF86OldVidModeValidateModeLineReq *oldstuff =
- (xXF86OldVidModeValidateModeLineReq *)client->requestBuffer;
- xXF86VidModeValidateModeLineReq newstuff;
- xXF86VidModeValidateModeLineReply rep;
- pointer mode, modetmp = NULL;
- int len, status, dotClock;
- int ver;
-
- DEBUG_P("XF86VidModeValidateModeline");
-
- ver = ClientMajorVersion(client);
- if (ver < 2) {
- /* convert from old format */
- stuff = &newstuff;
- stuff->length = oldstuff->length;
- stuff->screen = oldstuff->screen;
- stuff->dotclock = oldstuff->dotclock;
- stuff->hdisplay = oldstuff->hdisplay;
- stuff->hsyncstart = oldstuff->hsyncstart;
- stuff->hsyncend = oldstuff->hsyncend;
- stuff->htotal = oldstuff->htotal;
- stuff->hskew = 0;
- stuff->vdisplay = oldstuff->vdisplay;
- stuff->vsyncstart = oldstuff->vsyncstart;
- stuff->vsyncend = oldstuff->vsyncend;
- stuff->vtotal = oldstuff->vtotal;
- stuff->flags = oldstuff->flags;
- stuff->privsize = oldstuff->privsize;
- }
- if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) {
- ErrorF("ValidateModeLine - scrn: %d clock: %ld\n",
- (int)stuff->screen, (unsigned long)stuff->dotclock);
- ErrorF(" hdsp: %d hbeg: %d hend: %d httl: %d\n",
- stuff->hdisplay, stuff->hsyncstart,
- stuff->hsyncend, stuff->htotal);
- ErrorF(" vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
- stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend,
- stuff->vtotal, (unsigned long)stuff->flags);
- }
-
- if (ver < 2) {
- REQUEST_AT_LEAST_SIZE(xXF86OldVidModeValidateModeLineReq);
- len = client->req_len -
- bytes_to_int32(sizeof(xXF86OldVidModeValidateModeLineReq));
- } else {
- REQUEST_AT_LEAST_SIZE(xXF86VidModeValidateModeLineReq);
- len = client->req_len - bytes_to_int32(sizeof(xXF86VidModeValidateModeLineReq));
- }
- if (len != stuff->privsize)
- return BadLength;
-
- if(stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- status = MODE_OK;
-
- if (stuff->hsyncstart < stuff->hdisplay ||
- stuff->hsyncend < stuff->hsyncstart ||
- stuff->htotal < stuff->hsyncend ||
- stuff->vsyncstart < stuff->vdisplay ||
- stuff->vsyncend < stuff->vsyncstart ||
- stuff->vtotal < stuff->vsyncend)
- {
- status = MODE_BAD;
- goto status_reply;
- }
-
- if (!VidModeGetCurrentModeline(stuff->screen, &mode, &dotClock))
- return BadValue;
-
- modetmp = VidModeCreateMode();
- VidModeCopyMode(mode, modetmp);
-
- VidModeSetModeValue(modetmp, VIDMODE_H_DISPLAY, stuff->hdisplay);
- VidModeSetModeValue(modetmp, VIDMODE_H_SYNCSTART, stuff->hsyncstart);
- VidModeSetModeValue(modetmp, VIDMODE_H_SYNCEND, stuff->hsyncend);
- VidModeSetModeValue(modetmp, VIDMODE_H_TOTAL, stuff->htotal);
- VidModeSetModeValue(modetmp, VIDMODE_H_SKEW, stuff->hskew);
- VidModeSetModeValue(modetmp, VIDMODE_V_DISPLAY, stuff->vdisplay);
- VidModeSetModeValue(modetmp, VIDMODE_V_SYNCSTART, stuff->vsyncstart);
- VidModeSetModeValue(modetmp, VIDMODE_V_SYNCEND, stuff->vsyncend);
- VidModeSetModeValue(modetmp, VIDMODE_V_TOTAL, stuff->vtotal);
- VidModeSetModeValue(modetmp, VIDMODE_FLAGS, stuff->flags);
- if (stuff->privsize)
- ErrorF("ValidateModeLine - Privates in request have been ignored\n");
-
- /* Check that the mode is consistent with the monitor specs */
- if ((status = VidModeCheckModeForMonitor(stuff->screen, modetmp)) != MODE_OK)
- goto status_reply;
-
- /* Check that the driver is happy with the mode */
- status = VidModeCheckModeForDriver(stuff->screen, modetmp);
-
-status_reply:
- if(modetmp)
- xfree(modetmp);
-
- rep.type = X_Reply;
- rep.length = bytes_to_int32(SIZEOF(xXF86VidModeValidateModeLineReply)
- - SIZEOF(xGenericReply));
- rep.sequenceNumber = client->sequence;
- rep.status = status;
- if (client->swapped) {
- register int n;
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swapl(&rep.status, n);
- }
- WriteToClient(client, sizeof(xXF86VidModeValidateModeLineReply), (char *)&rep);
- if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY)
- ErrorF("ValidateModeLine - Succeeded (status = %d)\n", status);
- return(client->noClientException);
-}
-
-static int
-ProcXF86VidModeSwitchMode(ClientPtr client)
-{
- REQUEST(xXF86VidModeSwitchModeReq);
-
- DEBUG_P("XF86VidModeSwitchMode");
-
- REQUEST_SIZE_MATCH(xXF86VidModeSwitchModeReq);
-
- if(stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- VidModeZoomViewport(stuff->screen, (short)stuff->zoom);
-
- return (client->noClientException);
-}
-
-static int
-ProcXF86VidModeSwitchToMode(ClientPtr client)
-{
- REQUEST(xXF86VidModeSwitchToModeReq);
- xXF86OldVidModeSwitchToModeReq *oldstuff =
- (xXF86OldVidModeSwitchToModeReq *)client->requestBuffer;
- xXF86VidModeSwitchToModeReq newstuff;
- pointer mode;
- int len, dotClock;
- int ver;
-
- DEBUG_P("XF86VidModeSwitchToMode");
-
- ver = ClientMajorVersion(client);
- if (ver < 2) {
- /* convert from old format */
- stuff = &newstuff;
- stuff->length = oldstuff->length;
- stuff->screen = oldstuff->screen;
- stuff->dotclock = oldstuff->dotclock;
- stuff->hdisplay = oldstuff->hdisplay;
- stuff->hsyncstart = oldstuff->hsyncstart;
- stuff->hsyncend = oldstuff->hsyncend;
- stuff->htotal = oldstuff->htotal;
- stuff->hskew = 0;
- stuff->vdisplay = oldstuff->vdisplay;
- stuff->vsyncstart = oldstuff->vsyncstart;
- stuff->vsyncend = oldstuff->vsyncend;
- stuff->vtotal = oldstuff->vtotal;
- stuff->flags = oldstuff->flags;
- stuff->privsize = oldstuff->privsize;
- }
- if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) {
- ErrorF("SwitchToMode - scrn: %d clock: %ld\n",
- (int)stuff->screen, (unsigned long)stuff->dotclock);
- ErrorF(" hdsp: %d hbeg: %d hend: %d httl: %d\n",
- stuff->hdisplay, stuff->hsyncstart,
- stuff->hsyncend, stuff->htotal);
- ErrorF(" vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
- stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend,
- stuff->vtotal, (unsigned long)stuff->flags);
- }
-
- if (ver < 2) {
- REQUEST_AT_LEAST_SIZE(xXF86OldVidModeSwitchToModeReq);
- len = client->req_len - bytes_to_int32(sizeof(xXF86OldVidModeSwitchToModeReq));
- } else {
- REQUEST_AT_LEAST_SIZE(xXF86VidModeSwitchToModeReq);
- len = client->req_len - bytes_to_int32(sizeof(xXF86VidModeSwitchToModeReq));
- }
- if (len != stuff->privsize)
- return BadLength;
-
- if(stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- if (!VidModeGetCurrentModeline(stuff->screen, &mode, &dotClock))
- return BadValue;
-
- if ((VidModeGetDotClock(stuff->screen, stuff->dotclock) == dotClock)
- && MODEMATCH(mode, stuff))
- return (client->noClientException);
-
- if (!VidModeGetFirstModeline(stuff->screen, &mode, &dotClock))
- return BadValue;
-
- do {
- if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) {
- ErrorF("Checking against clock: %d (%d)\n",
- VidModeGetModeValue(mode, VIDMODE_CLOCK), dotClock);
- ErrorF(" hdsp: %d hbeg: %d hend: %d httl: %d\n",
- VidModeGetModeValue(mode, VIDMODE_H_DISPLAY),
- VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART),
- VidModeGetModeValue(mode, VIDMODE_H_SYNCEND),
- VidModeGetModeValue(mode, VIDMODE_H_TOTAL));
- ErrorF(" vdsp: %d vbeg: %d vend: %d vttl: %d flags: %d\n",
- VidModeGetModeValue(mode, VIDMODE_V_DISPLAY),
- VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART),
- VidModeGetModeValue(mode, VIDMODE_V_SYNCEND),
- VidModeGetModeValue(mode, VIDMODE_V_TOTAL),
- VidModeGetModeValue(mode, VIDMODE_FLAGS));
- }
- if ((VidModeGetDotClock(stuff->screen, stuff->dotclock) == dotClock) &&
- MODEMATCH(mode, stuff)) {
-
- if (!VidModeSwitchMode(stuff->screen, mode))
- return BadValue;
-
- if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY)
- ErrorF("SwitchToMode - Succeeded\n");
- return(client->noClientException);
- }
- } while (VidModeGetNextModeline(stuff->screen, &mode, &dotClock));
-
- return BadValue;
-}
-
-static int
-ProcXF86VidModeLockModeSwitch(ClientPtr client)
-{
- REQUEST(xXF86VidModeLockModeSwitchReq);
-
- REQUEST_SIZE_MATCH(xXF86VidModeLockModeSwitchReq);
-
- DEBUG_P("XF86VidModeLockModeSwitch");
-
- if(stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- if (!VidModeLockZoom(stuff->screen, (short)stuff->lock))
- return VidModeErrorBase + XF86VidModeZoomLocked;
-
- return (client->noClientException);
-}
-
-static int
-ProcXF86VidModeGetMonitor(ClientPtr client)
-{
- REQUEST(xXF86VidModeGetMonitorReq);
- xXF86VidModeGetMonitorReply rep;
- register int n;
- CARD32 *hsyncdata, *vsyncdata;
- int i, nHsync, nVrefresh;
- pointer monitor;
-
- DEBUG_P("XF86VidModeGetMonitor");
-
- REQUEST_SIZE_MATCH(xXF86VidModeGetMonitorReq);
-
- if(stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- if (!VidModeGetMonitor(stuff->screen, &monitor))
- return BadValue;
-
- nHsync = VidModeGetMonitorValue(monitor, VIDMODE_MON_NHSYNC, 0).i;
- nVrefresh = VidModeGetMonitorValue(monitor, VIDMODE_MON_NVREFRESH, 0).i;
-
- rep.type = X_Reply;
- if ((char *)(VidModeGetMonitorValue(monitor, VIDMODE_MON_VENDOR, 0)).ptr)
- rep.vendorLength = strlen((char *)(VidModeGetMonitorValue(monitor,
- VIDMODE_MON_VENDOR, 0)).ptr);
- else
- rep.vendorLength = 0;
- if ((char *)(VidModeGetMonitorValue(monitor, VIDMODE_MON_MODEL, 0)).ptr)
- rep.modelLength = strlen((char *)(VidModeGetMonitorValue(monitor,
- VIDMODE_MON_MODEL, 0)).ptr);
- else
- rep.modelLength = 0;
- rep.length = bytes_to_int32(SIZEOF(xXF86VidModeGetMonitorReply) - SIZEOF(xGenericReply) +
- (nHsync + nVrefresh) * sizeof(CARD32) +
- pad_to_int32(rep.vendorLength) +
- pad_to_int32(rep.modelLength));
- rep.sequenceNumber = client->sequence;
- rep.nhsync = nHsync;
- rep.nvsync = nVrefresh;
- hsyncdata = xalloc(nHsync * sizeof(CARD32));
- if (!hsyncdata) {
- return BadAlloc;
- }
-
- vsyncdata = xalloc(nVrefresh * sizeof(CARD32));
- if (!vsyncdata) {
- xfree(hsyncdata);
- return BadAlloc;
- }
-
- for (i = 0; i < nHsync; i++) {
- hsyncdata[i] = (unsigned short)(VidModeGetMonitorValue(monitor,
- VIDMODE_MON_HSYNC_LO, i)).f |
- (unsigned short)(VidModeGetMonitorValue(monitor,
- VIDMODE_MON_HSYNC_HI, i)).f << 16;
- }
- for (i = 0; i < nVrefresh; i++) {
- vsyncdata[i] = (unsigned short)(VidModeGetMonitorValue(monitor,
- VIDMODE_MON_VREFRESH_LO, i)).f |
- (unsigned short)(VidModeGetMonitorValue(monitor,
- VIDMODE_MON_VREFRESH_HI, i)).f << 16;
- }
-
-
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- }
- WriteToClient(client, SIZEOF(xXF86VidModeGetMonitorReply), (char *)&rep);
- client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
- WriteSwappedDataToClient(client, nHsync * sizeof(CARD32),
- hsyncdata);
- WriteSwappedDataToClient(client, nVrefresh * sizeof(CARD32),
- vsyncdata);
- if (rep.vendorLength)
- WriteToClient(client, rep.vendorLength, (char *)(VidModeGetMonitorValue(monitor, VIDMODE_MON_VENDOR, 0)).ptr);
- if (rep.modelLength)
- WriteToClient(client, rep.modelLength, (char *)(VidModeGetMonitorValue(monitor, VIDMODE_MON_MODEL, 0)).ptr);
-
- xfree(hsyncdata);
- xfree(vsyncdata);
-
- return (client->noClientException);
-}
-
-static int
-ProcXF86VidModeGetViewPort(ClientPtr client)
-{
- REQUEST(xXF86VidModeGetViewPortReq);
- xXF86VidModeGetViewPortReply rep;
- int x, y, n;
-
- DEBUG_P("XF86VidModeGetViewPort");
-
- REQUEST_SIZE_MATCH(xXF86VidModeGetViewPortReq);
-
- if(stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- VidModeGetViewPort(stuff->screen, &x, &y);
- rep.x = x;
- rep.y = y;
-
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swapl(&rep.x, n);
- swapl(&rep.y, n);
- }
- WriteToClient(client, SIZEOF(xXF86VidModeGetViewPortReply), (char *)&rep);
- return (client->noClientException);
-}
-
-static int
-ProcXF86VidModeSetViewPort(ClientPtr client)
-{
- REQUEST(xXF86VidModeSetViewPortReq);
-
- DEBUG_P("XF86VidModeSetViewPort");
-
- REQUEST_SIZE_MATCH(xXF86VidModeSetViewPortReq);
-
- if(stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- if (!VidModeSetViewPort(stuff->screen, stuff->x, stuff->y))
- return BadValue;
-
- return (client->noClientException);
-}
-
-static int
-ProcXF86VidModeGetDotClocks(ClientPtr client)
-{
- REQUEST(xXF86VidModeGetDotClocksReq);
- xXF86VidModeGetDotClocksReply rep;
- register int n;
- int numClocks;
- CARD32 dotclock;
- int *Clocks = NULL;
- Bool ClockProg;
-
- DEBUG_P("XF86VidModeGetDotClocks");
-
- REQUEST_SIZE_MATCH(xXF86VidModeGetDotClocksReq);
-
- if(stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- numClocks = VidModeGetNumOfClocks(stuff->screen, &ClockProg);
-
- rep.type = X_Reply;
- rep.length = bytes_to_int32(SIZEOF(xXF86VidModeGetDotClocksReply)
- - SIZEOF(xGenericReply) + numClocks);
- rep.sequenceNumber = client->sequence;
- rep.clocks = numClocks;
- rep.maxclocks = MAXCLOCKS;
- rep.flags = 0;
-
- if (!ClockProg) {
- Clocks = xalloc(numClocks * sizeof(int));
- if (!Clocks)
- return BadValue;
- if (!VidModeGetClocks(stuff->screen, Clocks)) {
- xfree(Clocks);
- return BadValue;
- }
- }
-
- if (ClockProg) {
- rep.flags |= CLKFLAG_PROGRAMABLE;
- }
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swapl(&rep.clocks, n);
- swapl(&rep.maxclocks, n);
- swapl(&rep.flags, n);
- }
- WriteToClient(client, sizeof(xXF86VidModeGetDotClocksReply), (char *)&rep);
- if (!ClockProg) {
- for (n = 0; n < numClocks; n++) {
- dotclock = *Clocks++;
- if (client->swapped) {
- WriteSwappedDataToClient(client, 4, (char *)&dotclock);
- } else {
- WriteToClient(client, 4, (char *)&dotclock);
- }
- }
- }
-
- xfree(Clocks);
- return (client->noClientException);
-}
-
-static int
-ProcXF86VidModeSetGamma(ClientPtr client)
-{
- REQUEST(xXF86VidModeSetGammaReq);
-
- DEBUG_P("XF86VidModeSetGamma");
-
- REQUEST_SIZE_MATCH(xXF86VidModeSetGammaReq);
-
- if(stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- if (!VidModeSetGamma(stuff->screen, ((float)stuff->red)/10000.,
- ((float)stuff->green)/10000., ((float)stuff->blue)/10000.))
- return BadValue;
-
- return (client->noClientException);
-}
-
-static int
-ProcXF86VidModeGetGamma(ClientPtr client)
-{
- REQUEST(xXF86VidModeGetGammaReq);
- xXF86VidModeGetGammaReply rep;
- register int n;
- float red, green, blue;
-
- DEBUG_P("XF86VidModeGetGamma");
-
- REQUEST_SIZE_MATCH(xXF86VidModeGetGammaReq);
-
- if(stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- if (!VidModeGetGamma(stuff->screen, &red, &green, &blue))
- return BadValue;
- rep.red = (CARD32)(red * 10000.);
- rep.green = (CARD32)(green * 10000.);
- rep.blue = (CARD32)(blue * 10000.);
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swapl(&rep.red, n);
- swapl(&rep.green, n);
- swapl(&rep.blue, n);
- }
- WriteToClient(client, sizeof(xXF86VidModeGetGammaReply), (char *)&rep);
- return (client->noClientException);
-}
-
-static int
-ProcXF86VidModeSetGammaRamp(ClientPtr client)
-{
- CARD16 *r, *g, *b;
- int length;
- REQUEST(xXF86VidModeSetGammaRampReq);
-
- if(stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- if(stuff->size != VidModeGetGammaRampSize(stuff->screen))
- return BadValue;
-
- length = (stuff->size + 1) & ~1;
-
- REQUEST_FIXED_SIZE(xXF86VidModeSetGammaRampReq, length * 6);
-
- r = (CARD16*)&stuff[1];
- g = r + length;
- b = g + length;
-
- if (!VidModeSetGammaRamp(stuff->screen, stuff->size, r, g, b))
- return BadValue;
-
- return (client->noClientException);
-}
-
-static int
-ProcXF86VidModeGetGammaRamp(ClientPtr client)
-{
- CARD16 *ramp = NULL;
- int n, length;
- size_t ramplen = 0;
- xXF86VidModeGetGammaRampReply rep;
- REQUEST(xXF86VidModeGetGammaRampReq);
-
- if(stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- if(stuff->size != VidModeGetGammaRampSize(stuff->screen))
- return BadValue;
-
- REQUEST_SIZE_MATCH(xXF86VidModeGetGammaRampReq);
-
- length = (stuff->size + 1) & ~1;
-
- if(stuff->size) {
- ramplen = length * 3 * sizeof(CARD16);
- if (!(ramp = xalloc(ramplen)))
- return BadAlloc;
-
- if (!VidModeGetGammaRamp(stuff->screen, stuff->size,
- ramp, ramp + length, ramp + (length * 2))) {
- xfree(ramp);
- return BadValue;
- }
- }
-
- rep.type = X_Reply;
- rep.length = (length >> 1) * 3;
- rep.sequenceNumber = client->sequence;
- rep.size = stuff->size;
- if(client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swaps(&rep.size, n);
- SwapShorts((short*)ramp, length * 3);
- }
- WriteToClient(client, sizeof(xXF86VidModeGetGammaRampReply), (char *)&rep);
-
- if(stuff->size) {
- WriteToClient(client, ramplen, (char*)ramp);
- xfree(ramp);
- }
-
- return (client->noClientException);
-}
-
-
-static int
-ProcXF86VidModeGetGammaRampSize(ClientPtr client)
-{
- xXF86VidModeGetGammaRampSizeReply rep;
- int n;
- REQUEST(xXF86VidModeGetGammaRampSizeReq);
-
- if(stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- REQUEST_SIZE_MATCH(xXF86VidModeGetGammaRampSizeReq);
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.size = VidModeGetGammaRampSize(stuff->screen);
- if(client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swaps(&rep.size, n);
- }
- WriteToClient(client,sizeof(xXF86VidModeGetGammaRampSizeReply),(char*)&rep);
-
- return (client->noClientException);
-}
-
-static int
-ProcXF86VidModeGetPermissions(ClientPtr client)
-{
- xXF86VidModeGetPermissionsReply rep;
- int n;
- REQUEST(xXF86VidModeGetPermissionsReq);
-
- if(stuff->screen >= screenInfo.numScreens)
- return BadValue;
-
- REQUEST_SIZE_MATCH(xXF86VidModeGetPermissionsReq);
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.permissions = XF86VM_READ_PERMISSION;
- if (xf86GetVidModeEnabled() &&
- (xf86GetVidModeAllowNonLocal() || LocalClient (client))) {
- rep.permissions |= XF86VM_WRITE_PERMISSION;
- }
- if(client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swapl(&rep.permissions, n);
- }
- WriteToClient(client,sizeof(xXF86VidModeGetPermissionsReply),(char*)&rep);
-
- return (client->noClientException);
-}
-
-
-static int
-ProcXF86VidModeSetClientVersion(ClientPtr client)
-{
- REQUEST(xXF86VidModeSetClientVersionReq);
-
- VidModePrivPtr pPriv;
-
- DEBUG_P("XF86VidModeSetClientVersion");
-
- REQUEST_SIZE_MATCH(xXF86VidModeSetClientVersionReq);
-
- if ((pPriv = VM_GETPRIV(client)) == NULL) {
- pPriv = xalloc(sizeof(VidModePrivRec));
- if (!pPriv)
- return BadAlloc;
- VM_SETPRIV(client, pPriv);
- }
- pPriv->major = stuff->major;
- pPriv->minor = stuff->minor;
-
- return (client->noClientException);
-}
-
-static int
-ProcXF86VidModeDispatch(ClientPtr client)
-{
- REQUEST(xReq);
- switch (stuff->data)
- {
- case X_XF86VidModeQueryVersion:
- return ProcXF86VidModeQueryVersion(client);
- case X_XF86VidModeGetModeLine:
- return ProcXF86VidModeGetModeLine(client);
- case X_XF86VidModeGetMonitor:
- return ProcXF86VidModeGetMonitor(client);
- case X_XF86VidModeGetAllModeLines:
- return ProcXF86VidModeGetAllModeLines(client);
- case X_XF86VidModeValidateModeLine:
- return ProcXF86VidModeValidateModeLine(client);
- case X_XF86VidModeGetViewPort:
- return ProcXF86VidModeGetViewPort(client);
- case X_XF86VidModeGetDotClocks:
- return ProcXF86VidModeGetDotClocks(client);
- case X_XF86VidModeSetClientVersion:
- return ProcXF86VidModeSetClientVersion(client);
- case X_XF86VidModeGetGamma:
- return ProcXF86VidModeGetGamma(client);
- case X_XF86VidModeGetGammaRamp:
- return ProcXF86VidModeGetGammaRamp(client);
- case X_XF86VidModeGetGammaRampSize:
- return ProcXF86VidModeGetGammaRampSize(client);
- case X_XF86VidModeGetPermissions:
- return ProcXF86VidModeGetPermissions(client);
- default:
- if (!xf86GetVidModeEnabled())
- return VidModeErrorBase + XF86VidModeExtensionDisabled;
- if (xf86GetVidModeAllowNonLocal() || LocalClient (client)) {
- switch (stuff->data) {
- case X_XF86VidModeAddModeLine:
- return ProcXF86VidModeAddModeLine(client);
- case X_XF86VidModeDeleteModeLine:
- return ProcXF86VidModeDeleteModeLine(client);
- case X_XF86VidModeModModeLine:
- return ProcXF86VidModeModModeLine(client);
- case X_XF86VidModeSwitchMode:
- return ProcXF86VidModeSwitchMode(client);
- case X_XF86VidModeSwitchToMode:
- return ProcXF86VidModeSwitchToMode(client);
- case X_XF86VidModeLockModeSwitch:
- return ProcXF86VidModeLockModeSwitch(client);
- case X_XF86VidModeSetViewPort:
- return ProcXF86VidModeSetViewPort(client);
- case X_XF86VidModeSetGamma:
- return ProcXF86VidModeSetGamma(client);
- case X_XF86VidModeSetGammaRamp:
- return ProcXF86VidModeSetGammaRamp(client);
- default:
- return BadRequest;
- }
- } else
- return VidModeErrorBase + XF86VidModeClientNotLocal;
- }
-}
-
-static int
-SProcXF86VidModeQueryVersion(ClientPtr client)
-{
- register int n;
- REQUEST(xXF86VidModeQueryVersionReq);
- swaps(&stuff->length, n);
- return ProcXF86VidModeQueryVersion(client);
-}
-
-static int
-SProcXF86VidModeGetModeLine(ClientPtr client)
-{
- register int n;
- REQUEST(xXF86VidModeGetModeLineReq);
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xXF86VidModeGetModeLineReq);
- swaps(&stuff->screen, n);
- return ProcXF86VidModeGetModeLine(client);
-}
-
-static int
-SProcXF86VidModeGetAllModeLines(ClientPtr client)
-{
- register int n;
- REQUEST(xXF86VidModeGetAllModeLinesReq);
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xXF86VidModeGetAllModeLinesReq);
- swaps(&stuff->screen, n);
- return ProcXF86VidModeGetAllModeLines(client);
-}
-
-static int
-SProcXF86VidModeAddModeLine(ClientPtr client)
-{
- xXF86OldVidModeAddModeLineReq *oldstuff =
- (xXF86OldVidModeAddModeLineReq *)client->requestBuffer;
- int ver;
- register int n;
-
- REQUEST(xXF86VidModeAddModeLineReq);
- ver = ClientMajorVersion(client);
- if (ver < 2) {
- swaps(&oldstuff->length, n);
- REQUEST_AT_LEAST_SIZE(xXF86OldVidModeAddModeLineReq);
- swapl(&oldstuff->screen, n);
- swaps(&oldstuff->hdisplay, n);
- swaps(&oldstuff->hsyncstart, n);
- swaps(&oldstuff->hsyncend, n);
- swaps(&oldstuff->htotal, n);
- swaps(&oldstuff->vdisplay, n);
- swaps(&oldstuff->vsyncstart, n);
- swaps(&oldstuff->vsyncend, n);
- swaps(&oldstuff->vtotal, n);
- swapl(&oldstuff->flags, n);
- swapl(&oldstuff->privsize, n);
- SwapRestL(oldstuff);
- } else {
- swaps(&stuff->length, n);
- REQUEST_AT_LEAST_SIZE(xXF86VidModeAddModeLineReq);
- swapl(&stuff->screen, n);
- swaps(&stuff->hdisplay, n);
- swaps(&stuff->hsyncstart, n);
- swaps(&stuff->hsyncend, n);
- swaps(&stuff->htotal, n);
- swaps(&stuff->hskew, n);
- swaps(&stuff->vdisplay, n);
- swaps(&stuff->vsyncstart, n);
- swaps(&stuff->vsyncend, n);
- swaps(&stuff->vtotal, n);
- swapl(&stuff->flags, n);
- swapl(&stuff->privsize, n);
- SwapRestL(stuff);
- }
- return ProcXF86VidModeAddModeLine(client);
-}
-
-static int
-SProcXF86VidModeDeleteModeLine(ClientPtr client)
-{
- xXF86OldVidModeDeleteModeLineReq *oldstuff =
- (xXF86OldVidModeDeleteModeLineReq *)client->requestBuffer;
- int ver;
- register int n;
-
- REQUEST(xXF86VidModeDeleteModeLineReq);
- ver = ClientMajorVersion(client);
- if (ver < 2) {
- swaps(&oldstuff->length, n);
- REQUEST_AT_LEAST_SIZE(xXF86OldVidModeDeleteModeLineReq);
- swapl(&oldstuff->screen, n);
- swaps(&oldstuff->hdisplay, n);
- swaps(&oldstuff->hsyncstart, n);
- swaps(&oldstuff->hsyncend, n);
- swaps(&oldstuff->htotal, n);
- swaps(&oldstuff->vdisplay, n);
- swaps(&oldstuff->vsyncstart, n);
- swaps(&oldstuff->vsyncend, n);
- swaps(&oldstuff->vtotal, n);
- swapl(&oldstuff->flags, n);
- swapl(&oldstuff->privsize, n);
- SwapRestL(oldstuff);
- } else {
- swaps(&stuff->length, n);
- REQUEST_AT_LEAST_SIZE(xXF86VidModeDeleteModeLineReq);
- swapl(&stuff->screen, n);
- swaps(&stuff->hdisplay, n);
- swaps(&stuff->hsyncstart, n);
- swaps(&stuff->hsyncend, n);
- swaps(&stuff->htotal, n);
- swaps(&stuff->hskew, n);
- swaps(&stuff->vdisplay, n);
- swaps(&stuff->vsyncstart, n);
- swaps(&stuff->vsyncend, n);
- swaps(&stuff->vtotal, n);
- swapl(&stuff->flags, n);
- swapl(&stuff->privsize, n);
- SwapRestL(stuff);
- }
- return ProcXF86VidModeDeleteModeLine(client);
-}
-
-static int
-SProcXF86VidModeModModeLine(ClientPtr client)
-{
- xXF86OldVidModeModModeLineReq *oldstuff =
- (xXF86OldVidModeModModeLineReq *)client->requestBuffer;
- int ver;
- register int n;
-
- REQUEST(xXF86VidModeModModeLineReq);
- ver = ClientMajorVersion(client);
- if (ver < 2) {
- swaps(&oldstuff->length, n);
- REQUEST_AT_LEAST_SIZE(xXF86OldVidModeModModeLineReq);
- swapl(&oldstuff->screen, n);
- swaps(&oldstuff->hdisplay, n);
- swaps(&oldstuff->hsyncstart, n);
- swaps(&oldstuff->hsyncend, n);
- swaps(&oldstuff->htotal, n);
- swaps(&oldstuff->vdisplay, n);
- swaps(&oldstuff->vsyncstart, n);
- swaps(&oldstuff->vsyncend, n);
- swaps(&oldstuff->vtotal, n);
- swapl(&oldstuff->flags, n);
- swapl(&oldstuff->privsize, n);
- SwapRestL(oldstuff);
- } else {
- swaps(&stuff->length, n);
- REQUEST_AT_LEAST_SIZE(xXF86VidModeModModeLineReq);
- swapl(&stuff->screen, n);
- swaps(&stuff->hdisplay, n);
- swaps(&stuff->hsyncstart, n);
- swaps(&stuff->hsyncend, n);
- swaps(&stuff->htotal, n);
- swaps(&stuff->hskew, n);
- swaps(&stuff->vdisplay, n);
- swaps(&stuff->vsyncstart, n);
- swaps(&stuff->vsyncend, n);
- swaps(&stuff->vtotal, n);
- swapl(&stuff->flags, n);
- swapl(&stuff->privsize, n);
- SwapRestL(stuff);
- }
- return ProcXF86VidModeModModeLine(client);
-}
-
-static int
-SProcXF86VidModeValidateModeLine(ClientPtr client)
-{
- xXF86OldVidModeValidateModeLineReq *oldstuff =
- (xXF86OldVidModeValidateModeLineReq *)client->requestBuffer;
- int ver;
- register int n;
-
- REQUEST(xXF86VidModeValidateModeLineReq);
- ver = ClientMajorVersion(client);
- if (ver < 2) {
- swaps(&oldstuff->length, n);
- REQUEST_AT_LEAST_SIZE(xXF86OldVidModeValidateModeLineReq);
- swapl(&oldstuff->screen, n);
- swaps(&oldstuff->hdisplay, n);
- swaps(&oldstuff->hsyncstart, n);
- swaps(&oldstuff->hsyncend, n);
- swaps(&oldstuff->htotal, n);
- swaps(&oldstuff->vdisplay, n);
- swaps(&oldstuff->vsyncstart, n);
- swaps(&oldstuff->vsyncend, n);
- swaps(&oldstuff->vtotal, n);
- swapl(&oldstuff->flags, n);
- swapl(&oldstuff->privsize, n);
- SwapRestL(oldstuff);
- } else {
- swaps(&stuff->length, n);
- REQUEST_AT_LEAST_SIZE(xXF86VidModeValidateModeLineReq);
- swapl(&stuff->screen, n);
- swaps(&stuff->hdisplay, n);
- swaps(&stuff->hsyncstart, n);
- swaps(&stuff->hsyncend, n);
- swaps(&stuff->htotal, n);
- swaps(&stuff->hskew, n);
- swaps(&stuff->vdisplay, n);
- swaps(&stuff->vsyncstart, n);
- swaps(&stuff->vsyncend, n);
- swaps(&stuff->vtotal, n);
- swapl(&stuff->flags, n);
- swapl(&stuff->privsize, n);
- SwapRestL(stuff);
- }
- return ProcXF86VidModeValidateModeLine(client);
-}
-
-static int
-SProcXF86VidModeSwitchMode(ClientPtr client)
-{
- register int n;
- REQUEST(xXF86VidModeSwitchModeReq);
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xXF86VidModeSwitchModeReq);
- swaps(&stuff->screen, n);
- swaps(&stuff->zoom, n);
- return ProcXF86VidModeSwitchMode(client);
-}
-
-static int
-SProcXF86VidModeSwitchToMode(ClientPtr client)
-{
- register int n;
- REQUEST(xXF86VidModeSwitchToModeReq);
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xXF86VidModeSwitchToModeReq);
- swaps(&stuff->screen, n);
- return ProcXF86VidModeSwitchToMode(client);
-}
-
-static int
-SProcXF86VidModeLockModeSwitch(ClientPtr client)
-{
- register int n;
- REQUEST(xXF86VidModeLockModeSwitchReq);
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xXF86VidModeLockModeSwitchReq);
- swaps(&stuff->screen, n);
- swaps(&stuff->lock, n);
- return ProcXF86VidModeLockModeSwitch(client);
-}
-
-static int
-SProcXF86VidModeGetMonitor(ClientPtr client)
-{
- register int n;
- REQUEST(xXF86VidModeGetMonitorReq);
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xXF86VidModeGetMonitorReq);
- swaps(&stuff->screen, n);
- return ProcXF86VidModeGetMonitor(client);
-}
-
-static int
-SProcXF86VidModeGetViewPort(ClientPtr client)
-{
- register int n;
- REQUEST(xXF86VidModeGetViewPortReq);
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xXF86VidModeGetViewPortReq);
- swaps(&stuff->screen, n);
- return ProcXF86VidModeGetViewPort(client);
-}
-
-static int
-SProcXF86VidModeSetViewPort(ClientPtr client)
-{
- register int n;
- REQUEST(xXF86VidModeSetViewPortReq);
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xXF86VidModeSetViewPortReq);
- swaps(&stuff->screen, n);
- swapl(&stuff->x, n);
- swapl(&stuff->y, n);
- return ProcXF86VidModeSetViewPort(client);
-}
-
-static int
-SProcXF86VidModeGetDotClocks(ClientPtr client)
-{
- register int n;
- REQUEST(xXF86VidModeGetDotClocksReq);
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xXF86VidModeGetDotClocksReq);
- swaps(&stuff->screen, n);
- return ProcXF86VidModeGetDotClocks(client);
-}
-
-static int
-SProcXF86VidModeSetClientVersion(ClientPtr client)
-{
- register int n;
- REQUEST(xXF86VidModeSetClientVersionReq);
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xXF86VidModeSetClientVersionReq);
- swaps(&stuff->major, n);
- swaps(&stuff->minor, n);
- return ProcXF86VidModeSetClientVersion(client);
-}
-
-static int
-SProcXF86VidModeSetGamma(ClientPtr client)
-{
- register int n;
- REQUEST(xXF86VidModeSetGammaReq);
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xXF86VidModeSetGammaReq);
- swaps(&stuff->screen, n);
- swapl(&stuff->red, n);
- swapl(&stuff->green, n);
- swapl(&stuff->blue, n);
- return ProcXF86VidModeSetGamma(client);
-}
-
-static int
-SProcXF86VidModeGetGamma(ClientPtr client)
-{
- register int n;
- REQUEST(xXF86VidModeGetGammaReq);
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xXF86VidModeGetGammaReq);
- swaps(&stuff->screen, n);
- return ProcXF86VidModeGetGamma(client);
-}
-
-static int
-SProcXF86VidModeSetGammaRamp(ClientPtr client)
-{
- int length, n;
- REQUEST(xXF86VidModeSetGammaRampReq);
- swaps(&stuff->length, n);
- REQUEST_AT_LEAST_SIZE(xXF86VidModeSetGammaRampReq);
- swaps(&stuff->size, n);
- swaps(&stuff->screen, n);
- length = ((stuff->size + 1) & ~1) * 6;
- REQUEST_FIXED_SIZE(xXF86VidModeSetGammaRampReq, length);
- SwapRestS(stuff);
- return ProcXF86VidModeSetGammaRamp(client);
-}
-
-static int
-SProcXF86VidModeGetGammaRamp(ClientPtr client)
-{
- int n;
- REQUEST(xXF86VidModeGetGammaRampReq);
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xXF86VidModeGetGammaRampReq);
- swaps(&stuff->size, n);
- swaps(&stuff->screen, n);
- return ProcXF86VidModeGetGammaRamp(client);
-}
-
-static int
-SProcXF86VidModeGetGammaRampSize(ClientPtr client)
-{
- int n;
- REQUEST(xXF86VidModeGetGammaRampSizeReq);
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xXF86VidModeGetGammaRampSizeReq);
- swaps(&stuff->screen, n);
- return ProcXF86VidModeGetGammaRampSize(client);
-}
-
-static int
-SProcXF86VidModeGetPermissions(ClientPtr client)
-{
- int n;
- REQUEST(xXF86VidModeGetPermissionsReq);
- swaps(&stuff->length, n);
- REQUEST_SIZE_MATCH(xXF86VidModeGetPermissionsReq);
- swaps(&stuff->screen, n);
- return ProcXF86VidModeGetPermissions(client);
-}
-
-
-static int
-SProcXF86VidModeDispatch(ClientPtr client)
-{
- REQUEST(xReq);
- switch (stuff->data)
- {
- case X_XF86VidModeQueryVersion:
- return SProcXF86VidModeQueryVersion(client);
- case X_XF86VidModeGetModeLine:
- return SProcXF86VidModeGetModeLine(client);
- case X_XF86VidModeGetMonitor:
- return SProcXF86VidModeGetMonitor(client);
- case X_XF86VidModeGetAllModeLines:
- return SProcXF86VidModeGetAllModeLines(client);
- case X_XF86VidModeGetViewPort:
- return SProcXF86VidModeGetViewPort(client);
- case X_XF86VidModeValidateModeLine:
- return SProcXF86VidModeValidateModeLine(client);
- case X_XF86VidModeGetDotClocks:
- return SProcXF86VidModeGetDotClocks(client);
- case X_XF86VidModeSetClientVersion:
- return SProcXF86VidModeSetClientVersion(client);
- case X_XF86VidModeGetGamma:
- return SProcXF86VidModeGetGamma(client);
- case X_XF86VidModeGetGammaRamp:
- return SProcXF86VidModeGetGammaRamp(client);
- case X_XF86VidModeGetGammaRampSize:
- return SProcXF86VidModeGetGammaRampSize(client);
- case X_XF86VidModeGetPermissions:
- return SProcXF86VidModeGetPermissions(client);
- default:
- if (!xf86GetVidModeEnabled())
- return VidModeErrorBase + XF86VidModeExtensionDisabled;
- if (xf86GetVidModeAllowNonLocal() || LocalClient(client)) {
- switch (stuff->data) {
- case X_XF86VidModeAddModeLine:
- return SProcXF86VidModeAddModeLine(client);
- case X_XF86VidModeDeleteModeLine:
- return SProcXF86VidModeDeleteModeLine(client);
- case X_XF86VidModeModModeLine:
- return SProcXF86VidModeModModeLine(client);
- case X_XF86VidModeSwitchMode:
- return SProcXF86VidModeSwitchMode(client);
- case X_XF86VidModeSwitchToMode:
- return SProcXF86VidModeSwitchToMode(client);
- case X_XF86VidModeLockModeSwitch:
- return SProcXF86VidModeLockModeSwitch(client);
- case X_XF86VidModeSetViewPort:
- return SProcXF86VidModeSetViewPort(client);
- case X_XF86VidModeSetGamma:
- return SProcXF86VidModeSetGamma(client);
- case X_XF86VidModeSetGammaRamp:
- return SProcXF86VidModeSetGammaRamp(client);
- default:
- return BadRequest;
- }
- } else
- return VidModeErrorBase + XF86VidModeClientNotLocal;
- }
-}
+
+/*
+
+Copyright 1995 Kaleb S. KEITHLEY
+
+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 Kaleb S. KEITHLEY 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 Kaleb S. KEITHLEY
+shall not be used in advertising or otherwise to promote the sale, use
+or other dealings in this Software without prior written authorization
+from Kaleb S. KEITHLEY
+
+*/
+/* THIS IS NOT AN X CONSORTIUM STANDARD OR AN X PROJECT TEAM SPECIFICATION */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+#include <X11/extensions/xf86vmproto.h>
+#include "swaprep.h"
+#include "xf86.h"
+#include "vidmodeproc.h"
+#include "globals.h"
+#include "protocol-versions.h"
+
+#define DEFAULT_XF86VIDMODE_VERBOSITY 3
+
+static int VidModeErrorBase;
+static int VidModeClientPrivateKeyIndex;
+static DevPrivateKey VidModeClientPrivateKey = &VidModeClientPrivateKeyIndex;
+
+/* This holds the client's version information */
+typedef struct {
+ int major;
+ int minor;
+} VidModePrivRec, *VidModePrivPtr;
+
+#define VM_GETPRIV(c) ((VidModePrivPtr) \
+ dixLookupPrivate(&(c)->devPrivates, VidModeClientPrivateKey))
+#define VM_SETPRIV(c,p) \
+ dixSetPrivate(&(c)->devPrivates, VidModeClientPrivateKey, p)
+
+static DISPATCH_PROC(ProcXF86VidModeDispatch);
+static DISPATCH_PROC(ProcXF86VidModeGetAllModeLines);
+static DISPATCH_PROC(ProcXF86VidModeGetModeLine);
+static DISPATCH_PROC(ProcXF86VidModeGetMonitor);
+static DISPATCH_PROC(ProcXF86VidModeLockModeSwitch);
+static DISPATCH_PROC(ProcXF86VidModeAddModeLine);
+static DISPATCH_PROC(ProcXF86VidModeDeleteModeLine);
+static DISPATCH_PROC(ProcXF86VidModeModModeLine);
+static DISPATCH_PROC(ProcXF86VidModeValidateModeLine);
+static DISPATCH_PROC(ProcXF86VidModeQueryVersion);
+static DISPATCH_PROC(ProcXF86VidModeSwitchMode);
+static DISPATCH_PROC(ProcXF86VidModeSwitchToMode);
+static DISPATCH_PROC(ProcXF86VidModeGetViewPort);
+static DISPATCH_PROC(ProcXF86VidModeSetViewPort);
+static DISPATCH_PROC(ProcXF86VidModeGetDotClocks);
+static DISPATCH_PROC(ProcXF86VidModeSetGamma);
+static DISPATCH_PROC(ProcXF86VidModeGetGamma);
+static DISPATCH_PROC(ProcXF86VidModeSetClientVersion);
+static DISPATCH_PROC(ProcXF86VidModeGetGammaRamp);
+static DISPATCH_PROC(ProcXF86VidModeSetGammaRamp);
+static DISPATCH_PROC(ProcXF86VidModeGetGammaRampSize);
+static DISPATCH_PROC(SProcXF86VidModeDispatch);
+static DISPATCH_PROC(SProcXF86VidModeGetAllModeLines);
+static DISPATCH_PROC(SProcXF86VidModeGetModeLine);
+static DISPATCH_PROC(SProcXF86VidModeGetMonitor);
+static DISPATCH_PROC(SProcXF86VidModeLockModeSwitch);
+static DISPATCH_PROC(SProcXF86VidModeAddModeLine);
+static DISPATCH_PROC(SProcXF86VidModeDeleteModeLine);
+static DISPATCH_PROC(SProcXF86VidModeModModeLine);
+static DISPATCH_PROC(SProcXF86VidModeValidateModeLine);
+static DISPATCH_PROC(SProcXF86VidModeQueryVersion);
+static DISPATCH_PROC(SProcXF86VidModeSwitchMode);
+static DISPATCH_PROC(SProcXF86VidModeSwitchToMode);
+static DISPATCH_PROC(SProcXF86VidModeGetViewPort);
+static DISPATCH_PROC(SProcXF86VidModeSetViewPort);
+static DISPATCH_PROC(SProcXF86VidModeGetDotClocks);
+static DISPATCH_PROC(SProcXF86VidModeSetGamma);
+static DISPATCH_PROC(SProcXF86VidModeGetGamma);
+static DISPATCH_PROC(SProcXF86VidModeSetClientVersion);
+static DISPATCH_PROC(SProcXF86VidModeGetGammaRamp);
+static DISPATCH_PROC(SProcXF86VidModeSetGammaRamp);
+static DISPATCH_PROC(SProcXF86VidModeGetGammaRampSize);
+
+#if 0
+static unsigned char XF86VidModeReqCode = 0;
+#endif
+
+/* The XF86VIDMODE_EVENTS code is far from complete */
+
+#ifdef XF86VIDMODE_EVENTS
+static int XF86VidModeEventBase = 0;
+
+static void SXF86VidModeNotifyEvent();
+ xXF86VidModeNotifyEvent * /* from */,
+ xXF86VidModeNotifyEvent * /* to */
+);
+
+static RESTYPE EventType; /* resource type for event masks */
+
+typedef struct _XF86VidModeEvent *XF86VidModeEventPtr;
+
+typedef struct _XF86VidModeEvent {
+ XF86VidModeEventPtr next;
+ ClientPtr client;
+ ScreenPtr screen;
+ XID resource;
+ CARD32 mask;
+} XF86VidModeEventRec;
+
+static int XF86VidModeFreeEvents();
+
+typedef struct _XF86VidModeScreenPrivate {
+ XF86VidModeEventPtr events;
+ Bool hasWindow;
+} XF86VidModeScreenPrivateRec, *XF86VidModeScreenPrivatePtr;
+
+static int ScreenPrivateKeyIndex;
+static DevPrivateKey ScreenPrivateKey = &ScreenPrivateKeyIndex;
+
+#define GetScreenPrivate(s) ((ScreenSaverScreenPrivatePtr) \
+ dixLookupPrivate(&(s)->devPrivates, ScreenPrivateKey))
+#define SetScreenPrivate(s,v) \
+ dixSetPrivate(&(s)->devPrivates, ScreenPrivateKey, v)
+#define SetupScreen(s) ScreenSaverScreenPrivatePtr pPriv = GetScreenPrivate(s)
+
+#define New(t) (malloc(sizeof (t)))
+#endif
+
+#ifdef DEBUG
+# define DEBUG_P(x) ErrorF(x"\n");
+#else
+# define DEBUG_P(x) /**/
+#endif
+
+void
+XFree86VidModeExtensionInit(void)
+{
+ ExtensionEntry* extEntry;
+ ScreenPtr pScreen;
+ int i;
+ Bool enabled = FALSE;
+
+ DEBUG_P("XFree86VidModeExtensionInit");
+
+#ifdef XF86VIDMODE_EVENTS
+ EventType = CreateNewResourceType(XF86VidModeFreeEvents, "VidModeEvent");
+#endif
+
+ for(i = 0; i < screenInfo.numScreens; i++) {
+ pScreen = screenInfo.screens[i];
+ if (VidModeExtensionInit(pScreen))
+ enabled = TRUE;
+#ifdef XF86VIDMODE_EVENTS
+ SetScreenPrivate (pScreen, NULL);
+#endif
+ }
+ /* This means that the DDX doesn't want the vidmode extension enabled */
+ if (!enabled)
+ return;
+
+ if (
+#ifdef XF86VIDMODE_EVENTS
+ EventType &&
+#endif
+ (extEntry = AddExtension(XF86VIDMODENAME,
+ XF86VidModeNumberEvents,
+ XF86VidModeNumberErrors,
+ ProcXF86VidModeDispatch,
+ SProcXF86VidModeDispatch,
+ NULL,
+ StandardMinorOpcode))) {
+#if 0
+ XF86VidModeReqCode = (unsigned char)extEntry->base;
+#endif
+ VidModeErrorBase = extEntry->errorBase;
+#ifdef XF86VIDMODE_EVENTS
+ XF86VidModeEventBase = extEntry->eventBase;
+ EventSwapVector[XF86VidModeEventBase] = (EventSwapPtr)SXF86VidModeNotifyEvent;
+#endif
+ }
+}
+
+static int
+ClientMajorVersion(ClientPtr client)
+{
+ VidModePrivPtr pPriv;
+
+ pPriv = VM_GETPRIV(client);
+ if (!pPriv)
+ return 0;
+ else
+ return pPriv->major;
+}
+
+#ifdef XF86VIDMODE_EVENTS
+static void
+CheckScreenPrivate (pScreen)
+ ScreenPtr pScreen;
+{
+ SetupScreen (pScreen);
+
+ if (!pPriv)
+ return;
+ if (!pPriv->events && !pPriv->hasWindow) {
+ free(pPriv);
+ SetScreenPrivate (pScreen, NULL);
+ }
+}
+
+static XF86VidModeScreenPrivatePtr
+MakeScreenPrivate (pScreen)
+ ScreenPtr pScreen;
+{
+ SetupScreen (pScreen);
+
+ if (pPriv)
+ return pPriv;
+ pPriv = New (XF86VidModeScreenPrivateRec);
+ if (!pPriv)
+ return 0;
+ pPriv->events = 0;
+ pPriv->hasWindow = FALSE;
+ SetScreenPrivate (pScreen, pPriv);
+ return pPriv;
+}
+
+static unsigned long
+getEventMask (ScreenPtr pScreen, ClientPtr client)
+{
+ SetupScreen(pScreen);
+ XF86VidModeEventPtr pEv;
+
+ if (!pPriv)
+ return 0;
+ for (pEv = pPriv->events; pEv; pEv = pEv->next)
+ if (pEv->client == client)
+ return pEv->mask;
+ return 0;
+}
+
+static Bool
+setEventMask (ScreenPtr pScreen, ClientPtr client, unsigned long mask)
+{
+ SetupScreen(pScreen);
+ XF86VidModeEventPtr pEv, *pPrev;
+
+ if (getEventMask (pScreen, client) == mask)
+ return TRUE;
+ if (!pPriv) {
+ pPriv = MakeScreenPrivate (pScreen);
+ if (!pPriv)
+ return FALSE;
+ }
+ for (pPrev = &pPriv->events; pEv = *pPrev; pPrev = &pEv->next)
+ if (pEv->client == client)
+ break;
+ if (mask == 0) {
+ *pPrev = pEv->next;
+ free(pEv);
+ CheckScreenPrivate (pScreen);
+ } else {
+ if (!pEv) {
+ pEv = New (ScreenSaverEventRec);
+ if (!pEv) {
+ CheckScreenPrivate (pScreen);
+ return FALSE;
+ }
+ *pPrev = pEv;
+ pEv->next = NULL;
+ pEv->client = client;
+ pEv->screen = pScreen;
+ pEv->resource = FakeClientID (client->index);
+ }
+ pEv->mask = mask;
+ }
+ return TRUE;
+}
+
+static int
+XF86VidModeFreeEvents(pointer value, XID id)
+{
+ XF86VidModeEventPtr pOld = (XF86VidModeEventPtr)value;
+ ScreenPtr pScreen = pOld->screen;
+ SetupScreen (pScreen);
+ XF86VidModeEventPtr pEv, *pPrev;
+
+ if (!pPriv)
+ return TRUE;
+ for (pPrev = &pPriv->events; pEv = *pPrev; pPrev = &pEv->next)
+ if (pEv == pOld)
+ break;
+ if (!pEv)
+ return TRUE;
+ *pPrev = pEv->next;
+ free(pEv);
+ CheckScreenPrivate (pScreen);
+ return TRUE;
+}
+
+static void
+SendXF86VidModeNotify(ScreenPtr pScreen, int state, Bool forced)
+{
+ XF86VidModeScreenPrivatePtr pPriv;
+ XF86VidModeEventPtr pEv;
+ unsigned long mask;
+ xXF86VidModeNotifyEvent ev;
+ ClientPtr client;
+ int kind;
+
+ UpdateCurrentTimeIf ();
+ mask = XF86VidModeNotifyMask;
+ pScreen = screenInfo.screens[pScreen->myNum];
+ pPriv = GetScreenPrivate(pScreen);
+ if (!pPriv)
+ return;
+ kind = XF86VidModeModeChange;
+ for (pEv = pPriv->events; pEv; pEv = pEv->next)
+ {
+ client = pEv->client;
+ if (client->clientGone)
+ continue;
+ if (!(pEv->mask & mask))
+ continue;
+ ev.type = XF86VidModeNotify + XF86VidModeEventBase;
+ ev.state = state;
+ ev.sequenceNumber = client->sequence;
+ ev.timestamp = currentTime.milliseconds;
+ ev.root = WindowTable[pScreen->myNum]->drawable.id;
+ ev.kind = kind;
+ ev.forced = forced;
+ WriteEventsToClient (client, 1, (xEvent *) &ev);
+ }
+}
+
+static void
+SXF86VidModeNotifyEvent(xXF86VidModeNotifyEvent *from,
+ xXF86VidModeNotifyEvent *to)
+{
+ to->type = from->type;
+ to->state = from->state;
+ cpswaps (from->sequenceNumber, to->sequenceNumber);
+ cpswapl (from->timestamp, to->timestamp);
+ cpswapl (from->root, to->root);
+ to->kind = from->kind;
+ to->forced = from->forced;
+}
+#endif
+
+static int
+ProcXF86VidModeQueryVersion(ClientPtr client)
+{
+ xXF86VidModeQueryVersionReply rep;
+ register int n;
+
+ DEBUG_P("XF86VidModeQueryVersion");
+
+ REQUEST_SIZE_MATCH(xXF86VidModeQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = SERVER_XF86VIDMODE_MAJOR_VERSION;
+ rep.minorVersion = SERVER_XF86VIDMODE_MINOR_VERSION;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.majorVersion, n);
+ swaps(&rep.minorVersion, n);
+ }
+ WriteToClient(client, sizeof(xXF86VidModeQueryVersionReply), (char *)&rep);
+ return Success;
+}
+
+static int
+ProcXF86VidModeGetModeLine(ClientPtr client)
+{
+ REQUEST(xXF86VidModeGetModeLineReq);
+ xXF86VidModeGetModeLineReply rep;
+ xXF86OldVidModeGetModeLineReply oldrep;
+ pointer mode;
+ register int n;
+ int dotClock;
+ int ver;
+
+ DEBUG_P("XF86VidModeGetModeline");
+
+ ver = ClientMajorVersion(client);
+ REQUEST_SIZE_MATCH(xXF86VidModeGetModeLineReq);
+ rep.type = X_Reply;
+ if (ver < 2) {
+ rep.length = bytes_to_int32(SIZEOF(xXF86OldVidModeGetModeLineReply) -
+ SIZEOF(xGenericReply));
+ } else {
+ rep.length = bytes_to_int32(SIZEOF(xXF86VidModeGetModeLineReply) -
+ SIZEOF(xGenericReply));
+ }
+ rep.sequenceNumber = client->sequence;
+
+ if(stuff->screen >= screenInfo.numScreens)
+ return BadValue;
+
+ if (!VidModeGetCurrentModeline(stuff->screen, &mode, &dotClock))
+ return BadValue;
+
+ rep.dotclock = dotClock;
+ rep.hdisplay = VidModeGetModeValue(mode, VIDMODE_H_DISPLAY);
+ rep.hsyncstart = VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART);
+ rep.hsyncend = VidModeGetModeValue(mode, VIDMODE_H_SYNCEND);
+ rep.htotal = VidModeGetModeValue(mode, VIDMODE_H_TOTAL);
+ rep.hskew = VidModeGetModeValue(mode, VIDMODE_H_SKEW);
+ rep.vdisplay = VidModeGetModeValue(mode, VIDMODE_V_DISPLAY);
+ rep.vsyncstart = VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART);
+ rep.vsyncend = VidModeGetModeValue(mode, VIDMODE_V_SYNCEND);
+ rep.vtotal = VidModeGetModeValue(mode, VIDMODE_V_TOTAL);
+ rep.flags = VidModeGetModeValue(mode, VIDMODE_FLAGS);
+
+ if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) {
+ ErrorF("GetModeLine - scrn: %d clock: %ld\n",
+ stuff->screen, (unsigned long)rep.dotclock);
+ ErrorF("GetModeLine - hdsp: %d hbeg: %d hend: %d httl: %d\n",
+ rep.hdisplay, rep.hsyncstart,
+ rep.hsyncend, rep.htotal);
+ ErrorF(" vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
+ rep.vdisplay, rep.vsyncstart, rep.vsyncend,
+ rep.vtotal, (unsigned long)rep.flags);
+ }
+
+ /*
+ * Older servers sometimes had server privates that the VidMode
+ * extention made available. So to be compatiable pretend that
+ * there are no server privates to pass to the client
+ */
+ rep.privsize = 0;
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.dotclock, n);
+ swaps(&rep.hdisplay, n);
+ swaps(&rep.hsyncstart, n);
+ swaps(&rep.hsyncend, n);
+ swaps(&rep.htotal, n);
+ swaps(&rep.hskew, n);
+ swaps(&rep.vdisplay, n);
+ swaps(&rep.vsyncstart, n);
+ swaps(&rep.vsyncend, n);
+ swaps(&rep.vtotal, n);
+ swapl(&rep.flags, n);
+ swapl(&rep.privsize, n);
+ }
+ if (ver < 2) {
+ oldrep.type = rep.type;
+ oldrep.sequenceNumber = rep.sequenceNumber;
+ oldrep.length = rep.length;
+ oldrep.dotclock = rep.dotclock;
+ oldrep.hdisplay = rep.hdisplay;
+ oldrep.hsyncstart = rep.hsyncstart;
+ oldrep.hsyncend = rep.hsyncend;
+ oldrep.htotal = rep.htotal;
+ oldrep.vdisplay = rep.vdisplay;
+ oldrep.vsyncstart = rep.vsyncstart;
+ oldrep.vsyncend = rep.vsyncend;
+ oldrep.vtotal = rep.vtotal;
+ oldrep.flags = rep.flags;
+ oldrep.privsize = rep.privsize;
+ WriteToClient(client, sizeof(xXF86OldVidModeGetModeLineReply),
+ (char *)&oldrep);
+ } else {
+ WriteToClient(client, sizeof(xXF86VidModeGetModeLineReply),
+ (char *)&rep);
+ }
+ return Success;
+}
+
+static int
+ProcXF86VidModeGetAllModeLines(ClientPtr client)
+{
+ REQUEST(xXF86VidModeGetAllModeLinesReq);
+ xXF86VidModeGetAllModeLinesReply rep;
+ xXF86VidModeModeInfo mdinf;
+ xXF86OldVidModeModeInfo oldmdinf;
+ pointer mode;
+ int modecount, dotClock;
+ register int n;
+ int ver;
+
+ DEBUG_P("XF86VidModeGetAllModelines");
+
+ REQUEST_SIZE_MATCH(xXF86VidModeGetAllModeLinesReq);
+
+ if(stuff->screen >= screenInfo.numScreens)
+ return BadValue;
+
+ ver = ClientMajorVersion(client);
+
+ modecount = VidModeGetNumOfModes(stuff->screen);
+ if (modecount < 1)
+ return (VidModeErrorBase + XF86VidModeExtensionDisabled);
+
+ if (!VidModeGetFirstModeline(stuff->screen, &mode, &dotClock))
+ return BadValue;
+
+ rep.type = X_Reply;
+ rep.length = SIZEOF(xXF86VidModeGetAllModeLinesReply) -
+ SIZEOF(xGenericReply);
+ if (ver < 2)
+ rep.length += modecount * sizeof(xXF86OldVidModeModeInfo);
+ else
+ rep.length += modecount * sizeof(xXF86VidModeModeInfo);
+ rep.length >>= 2;
+ rep.sequenceNumber = client->sequence;
+ rep.modecount = modecount;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.modecount, n);
+ }
+ WriteToClient(client, sizeof(xXF86VidModeGetAllModeLinesReply), (char *)&rep);
+
+ do {
+ mdinf.dotclock = dotClock;
+ mdinf.hdisplay = VidModeGetModeValue(mode, VIDMODE_H_DISPLAY);
+ mdinf.hsyncstart = VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART);
+ mdinf.hsyncend = VidModeGetModeValue(mode, VIDMODE_H_SYNCEND);
+ mdinf.htotal = VidModeGetModeValue(mode, VIDMODE_H_TOTAL);
+ mdinf.hskew = VidModeGetModeValue(mode, VIDMODE_H_SKEW);
+ mdinf.vdisplay = VidModeGetModeValue(mode, VIDMODE_V_DISPLAY);
+ mdinf.vsyncstart = VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART);
+ mdinf.vsyncend = VidModeGetModeValue(mode, VIDMODE_V_SYNCEND);
+ mdinf.vtotal = VidModeGetModeValue(mode, VIDMODE_V_TOTAL);
+ mdinf.flags = VidModeGetModeValue(mode, VIDMODE_FLAGS);
+ mdinf.privsize = 0;
+ if (client->swapped) {
+ swapl(&mdinf.dotclock, n);
+ swaps(&mdinf.hdisplay, n);
+ swaps(&mdinf.hsyncstart, n);
+ swaps(&mdinf.hsyncend, n);
+ swaps(&mdinf.htotal, n);
+ swaps(&mdinf.hskew, n);
+ swaps(&mdinf.vdisplay, n);
+ swaps(&mdinf.vsyncstart, n);
+ swaps(&mdinf.vsyncend, n);
+ swaps(&mdinf.vtotal, n);
+ swapl(&mdinf.flags, n);
+ swapl(&mdinf.privsize, n);
+ }
+ if (ver < 2) {
+ oldmdinf.dotclock = mdinf.dotclock;
+ oldmdinf.hdisplay = mdinf.hdisplay;
+ oldmdinf.hsyncstart = mdinf.hsyncstart;
+ oldmdinf.hsyncend = mdinf.hsyncend;
+ oldmdinf.htotal = mdinf.htotal;
+ oldmdinf.vdisplay = mdinf.vdisplay;
+ oldmdinf.vsyncstart = mdinf.vsyncstart;
+ oldmdinf.vsyncend = mdinf.vsyncend;
+ oldmdinf.vtotal = mdinf.vtotal;
+ oldmdinf.flags = mdinf.flags;
+ oldmdinf.privsize = mdinf.privsize;
+ WriteToClient(client, sizeof(xXF86OldVidModeModeInfo),
+ (char *)&oldmdinf);
+ } else {
+ WriteToClient(client, sizeof(xXF86VidModeModeInfo), (char *)&mdinf);
+ }
+
+ } while (VidModeGetNextModeline(stuff->screen, &mode, &dotClock));
+
+ return Success;
+}
+
+#define MODEMATCH(mode,stuff) \
+ (VidModeGetModeValue(mode, VIDMODE_H_DISPLAY) == stuff->hdisplay \
+ && VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART) == stuff->hsyncstart \
+ && VidModeGetModeValue(mode, VIDMODE_H_SYNCEND) == stuff->hsyncend \
+ && VidModeGetModeValue(mode, VIDMODE_H_TOTAL) == stuff->htotal \
+ && VidModeGetModeValue(mode, VIDMODE_V_DISPLAY) == stuff->vdisplay \
+ && VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART) == stuff->vsyncstart \
+ && VidModeGetModeValue(mode, VIDMODE_V_SYNCEND) == stuff->vsyncend \
+ && VidModeGetModeValue(mode, VIDMODE_V_TOTAL) == stuff->vtotal \
+ && VidModeGetModeValue(mode, VIDMODE_FLAGS) == stuff->flags )
+
+static int
+ProcXF86VidModeAddModeLine(ClientPtr client)
+{
+ REQUEST(xXF86VidModeAddModeLineReq);
+ xXF86OldVidModeAddModeLineReq *oldstuff =
+ (xXF86OldVidModeAddModeLineReq *)client->requestBuffer;
+ xXF86VidModeAddModeLineReq newstuff;
+ pointer mode;
+ int len;
+ int dotClock;
+ int ver;
+
+ DEBUG_P("XF86VidModeAddModeline");
+
+ ver = ClientMajorVersion(client);
+ if (ver < 2) {
+ /* convert from old format */
+ stuff = &newstuff;
+ stuff->length = oldstuff->length;
+ stuff->screen = oldstuff->screen;
+ stuff->dotclock = oldstuff->dotclock;
+ stuff->hdisplay = oldstuff->hdisplay;
+ stuff->hsyncstart = oldstuff->hsyncstart;
+ stuff->hsyncend = oldstuff->hsyncend;
+ stuff->htotal = oldstuff->htotal;
+ stuff->hskew = 0;
+ stuff->vdisplay = oldstuff->vdisplay;
+ stuff->vsyncstart = oldstuff->vsyncstart;
+ stuff->vsyncend = oldstuff->vsyncend;
+ stuff->vtotal = oldstuff->vtotal;
+ stuff->flags = oldstuff->flags;
+ stuff->privsize = oldstuff->privsize;
+ stuff->after_dotclock = oldstuff->after_dotclock;
+ stuff->after_hdisplay = oldstuff->after_hdisplay;
+ stuff->after_hsyncstart = oldstuff->after_hsyncstart;
+ stuff->after_hsyncend = oldstuff->after_hsyncend;
+ stuff->after_htotal = oldstuff->after_htotal;
+ stuff->after_hskew = 0;
+ stuff->after_vdisplay = oldstuff->after_vdisplay;
+ stuff->after_vsyncstart = oldstuff->after_vsyncstart;
+ stuff->after_vsyncend = oldstuff->after_vsyncend;
+ stuff->after_vtotal = oldstuff->after_vtotal;
+ stuff->after_flags = oldstuff->after_flags;
+ }
+ if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) {
+ ErrorF("AddModeLine - scrn: %d clock: %ld\n",
+ (int)stuff->screen, (unsigned long)stuff->dotclock);
+ ErrorF("AddModeLine - hdsp: %d hbeg: %d hend: %d httl: %d\n",
+ stuff->hdisplay, stuff->hsyncstart,
+ stuff->hsyncend, stuff->htotal);
+ ErrorF(" vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
+ stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend,
+ stuff->vtotal, (unsigned long)stuff->flags);
+ ErrorF(" after - scrn: %d clock: %ld\n",
+ (int)stuff->screen, (unsigned long)stuff->after_dotclock);
+ ErrorF(" hdsp: %d hbeg: %d hend: %d httl: %d\n",
+ stuff->after_hdisplay, stuff->after_hsyncstart,
+ stuff->after_hsyncend, stuff->after_htotal);
+ ErrorF(" vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
+ stuff->after_vdisplay, stuff->after_vsyncstart,
+ stuff->after_vsyncend, stuff->after_vtotal,
+ (unsigned long)stuff->after_flags);
+ }
+
+ if (ver < 2) {
+ REQUEST_AT_LEAST_SIZE(xXF86OldVidModeAddModeLineReq);
+ len = client->req_len - bytes_to_int32(sizeof(xXF86OldVidModeAddModeLineReq));
+ } else {
+ REQUEST_AT_LEAST_SIZE(xXF86VidModeAddModeLineReq);
+ len = client->req_len - bytes_to_int32(sizeof(xXF86VidModeAddModeLineReq));
+ }
+ if (len != stuff->privsize)
+ return BadLength;
+
+ if(stuff->screen >= screenInfo.numScreens)
+ return BadValue;
+
+ if (stuff->hsyncstart < stuff->hdisplay ||
+ stuff->hsyncend < stuff->hsyncstart ||
+ stuff->htotal < stuff->hsyncend ||
+ stuff->vsyncstart < stuff->vdisplay ||
+ stuff->vsyncend < stuff->vsyncstart ||
+ stuff->vtotal < stuff->vsyncend)
+ return BadValue;
+
+ if (stuff->after_hsyncstart < stuff->after_hdisplay ||
+ stuff->after_hsyncend < stuff->after_hsyncstart ||
+ stuff->after_htotal < stuff->after_hsyncend ||
+ stuff->after_vsyncstart < stuff->after_vdisplay ||
+ stuff->after_vsyncend < stuff->after_vsyncstart ||
+ stuff->after_vtotal < stuff->after_vsyncend)
+ return BadValue;
+
+ if (stuff->after_htotal != 0 || stuff->after_vtotal != 0) {
+ Bool found = FALSE;
+ if (VidModeGetFirstModeline(stuff->screen, &mode, &dotClock)) {
+ do {
+ if ((VidModeGetDotClock(stuff->screen, stuff->dotclock)
+ == dotClock) && MODEMATCH(mode, stuff)) {
+ found = TRUE;
+ break;
+ }
+ } while (VidModeGetNextModeline(stuff->screen, &mode, &dotClock));
+ }
+ if (!found)
+ return BadValue;
+ }
+
+
+ mode = VidModeCreateMode();
+ if (mode == NULL)
+ return BadValue;
+
+ VidModeSetModeValue(mode, VIDMODE_CLOCK, stuff->dotclock);
+ VidModeSetModeValue(mode, VIDMODE_H_DISPLAY, stuff->hdisplay);
+ VidModeSetModeValue(mode, VIDMODE_H_SYNCSTART, stuff->hsyncstart);
+ VidModeSetModeValue(mode, VIDMODE_H_SYNCEND, stuff->hsyncend);
+ VidModeSetModeValue(mode, VIDMODE_H_TOTAL, stuff->htotal);
+ VidModeSetModeValue(mode, VIDMODE_H_SKEW, stuff->hskew);
+ VidModeSetModeValue(mode, VIDMODE_V_DISPLAY, stuff->vdisplay);
+ VidModeSetModeValue(mode, VIDMODE_V_SYNCSTART, stuff->vsyncstart);
+ VidModeSetModeValue(mode, VIDMODE_V_SYNCEND, stuff->vsyncend);
+ VidModeSetModeValue(mode, VIDMODE_V_TOTAL, stuff->vtotal);
+ VidModeSetModeValue(mode, VIDMODE_FLAGS, stuff->flags);
+
+ if (stuff->privsize)
+ ErrorF("AddModeLine - Privates in request have been ignored\n");
+
+ /* Check that the mode is consistent with the monitor specs */
+ switch (VidModeCheckModeForMonitor(stuff->screen, mode)) {
+ case MODE_OK:
+ break;
+ case MODE_HSYNC:
+ case MODE_H_ILLEGAL:
+ free(mode);
+ return VidModeErrorBase + XF86VidModeBadHTimings;
+ case MODE_VSYNC:
+ case MODE_V_ILLEGAL:
+ free(mode);
+ return VidModeErrorBase + XF86VidModeBadVTimings;
+ default:
+ free(mode);
+ return VidModeErrorBase + XF86VidModeModeUnsuitable;
+ }
+
+ /* Check that the driver is happy with the mode */
+ if (VidModeCheckModeForDriver(stuff->screen, mode) != MODE_OK) {
+ free(mode);
+ return VidModeErrorBase + XF86VidModeModeUnsuitable;
+ }
+
+ VidModeSetCrtcForMode(stuff->screen, mode);
+
+ VidModeAddModeline(stuff->screen, mode);
+
+ if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY)
+ ErrorF("AddModeLine - Succeeded\n");
+ return Success;
+}
+
+static int
+ProcXF86VidModeDeleteModeLine(ClientPtr client)
+{
+ REQUEST(xXF86VidModeDeleteModeLineReq);
+ xXF86OldVidModeDeleteModeLineReq *oldstuff =
+ (xXF86OldVidModeDeleteModeLineReq *)client->requestBuffer;
+ xXF86VidModeDeleteModeLineReq newstuff;
+ pointer mode;
+ int len, dotClock;
+ int ver;
+
+ DEBUG_P("XF86VidModeDeleteModeline");
+
+ ver = ClientMajorVersion(client);
+ if (ver < 2) {
+ /* convert from old format */
+ stuff = &newstuff;
+ stuff->length = oldstuff->length;
+ stuff->screen = oldstuff->screen;
+ stuff->dotclock = oldstuff->dotclock;
+ stuff->hdisplay = oldstuff->hdisplay;
+ stuff->hsyncstart = oldstuff->hsyncstart;
+ stuff->hsyncend = oldstuff->hsyncend;
+ stuff->htotal = oldstuff->htotal;
+ stuff->hskew = 0;
+ stuff->vdisplay = oldstuff->vdisplay;
+ stuff->vsyncstart = oldstuff->vsyncstart;
+ stuff->vsyncend = oldstuff->vsyncend;
+ stuff->vtotal = oldstuff->vtotal;
+ stuff->flags = oldstuff->flags;
+ stuff->privsize = oldstuff->privsize;
+ }
+ if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) {
+ ErrorF("DeleteModeLine - scrn: %d clock: %ld\n",
+ (int)stuff->screen, (unsigned long)stuff->dotclock);
+ ErrorF(" hdsp: %d hbeg: %d hend: %d httl: %d\n",
+ stuff->hdisplay, stuff->hsyncstart,
+ stuff->hsyncend, stuff->htotal);
+ ErrorF(" vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
+ stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend,
+ stuff->vtotal, (unsigned long)stuff->flags);
+ }
+
+ if (ver < 2) {
+ REQUEST_AT_LEAST_SIZE(xXF86OldVidModeDeleteModeLineReq);
+ len = client->req_len - bytes_to_int32(sizeof(xXF86OldVidModeDeleteModeLineReq));
+ } else {
+ REQUEST_AT_LEAST_SIZE(xXF86VidModeDeleteModeLineReq);
+ len = client->req_len - bytes_to_int32(sizeof(xXF86VidModeDeleteModeLineReq));
+ }
+ if (len != stuff->privsize) {
+ if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) {
+ ErrorF("req_len = %ld, sizeof(Req) = %d, privsize = %ld, "
+ "len = %d, length = %d\n",
+ (unsigned long)client->req_len,
+ (int)sizeof(xXF86VidModeDeleteModeLineReq)>>2,
+ (unsigned long)stuff->privsize, len, stuff->length);
+ }
+ return BadLength;
+ }
+
+ if(stuff->screen >= screenInfo.numScreens)
+ return BadValue;
+
+ if (!VidModeGetCurrentModeline(stuff->screen, &mode, &dotClock))
+ return BadValue;
+
+ if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) {
+ ErrorF("Checking against clock: %d (%d)\n",
+ VidModeGetModeValue(mode, VIDMODE_CLOCK), dotClock);
+ ErrorF(" hdsp: %d hbeg: %d hend: %d httl: %d\n",
+ VidModeGetModeValue(mode, VIDMODE_H_DISPLAY),
+ VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART),
+ VidModeGetModeValue(mode, VIDMODE_H_SYNCEND),
+ VidModeGetModeValue(mode, VIDMODE_H_TOTAL));
+ ErrorF(" vdsp: %d vbeg: %d vend: %d vttl: %d flags: %d\n",
+ VidModeGetModeValue(mode, VIDMODE_V_DISPLAY),
+ VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART),
+ VidModeGetModeValue(mode, VIDMODE_V_SYNCEND),
+ VidModeGetModeValue(mode, VIDMODE_V_TOTAL),
+ VidModeGetModeValue(mode, VIDMODE_FLAGS));
+ }
+ if ((VidModeGetDotClock(stuff->screen, stuff->dotclock) == dotClock) &&
+ MODEMATCH(mode, stuff))
+ return BadValue;
+
+ if (!VidModeGetFirstModeline(stuff->screen, &mode, &dotClock))
+ return BadValue;
+
+ do {
+ if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) {
+ ErrorF("Checking against clock: %d (%d)\n",
+ VidModeGetModeValue(mode, VIDMODE_CLOCK), dotClock);
+ ErrorF(" hdsp: %d hbeg: %d hend: %d httl: %d\n",
+ VidModeGetModeValue(mode, VIDMODE_H_DISPLAY),
+ VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART),
+ VidModeGetModeValue(mode, VIDMODE_H_SYNCEND),
+ VidModeGetModeValue(mode, VIDMODE_H_TOTAL));
+ ErrorF(" vdsp: %d vbeg: %d vend: %d vttl: %d flags: %d\n",
+ VidModeGetModeValue(mode, VIDMODE_V_DISPLAY),
+ VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART),
+ VidModeGetModeValue(mode, VIDMODE_V_SYNCEND),
+ VidModeGetModeValue(mode, VIDMODE_V_TOTAL),
+ VidModeGetModeValue(mode, VIDMODE_FLAGS));
+ }
+ if ((VidModeGetDotClock(stuff->screen, stuff->dotclock) == dotClock) &&
+ MODEMATCH(mode, stuff)) {
+ VidModeDeleteModeline(stuff->screen, mode);
+ if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY)
+ ErrorF("DeleteModeLine - Succeeded\n");
+ return Success;
+ }
+ } while (VidModeGetNextModeline(stuff->screen, &mode, &dotClock));
+
+ return BadValue;
+}
+
+static int
+ProcXF86VidModeModModeLine(ClientPtr client)
+{
+ REQUEST(xXF86VidModeModModeLineReq);
+ xXF86OldVidModeModModeLineReq *oldstuff =
+ (xXF86OldVidModeModModeLineReq *)client->requestBuffer;
+ xXF86VidModeModModeLineReq newstuff;
+ pointer mode, modetmp;
+ int len, dotClock;
+ int ver;
+
+ DEBUG_P("XF86VidModeModModeline");
+
+ ver = ClientMajorVersion(client);
+ if (ver < 2 ) {
+ /* convert from old format */
+ stuff = &newstuff;
+ stuff->length = oldstuff->length;
+ stuff->screen = oldstuff->screen;
+ stuff->hdisplay = oldstuff->hdisplay;
+ stuff->hsyncstart = oldstuff->hsyncstart;
+ stuff->hsyncend = oldstuff->hsyncend;
+ stuff->htotal = oldstuff->htotal;
+ stuff->hskew = 0;
+ stuff->vdisplay = oldstuff->vdisplay;
+ stuff->vsyncstart = oldstuff->vsyncstart;
+ stuff->vsyncend = oldstuff->vsyncend;
+ stuff->vtotal = oldstuff->vtotal;
+ stuff->flags = oldstuff->flags;
+ stuff->privsize = oldstuff->privsize;
+ }
+ if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) {
+ ErrorF("ModModeLine - scrn: %d hdsp: %d hbeg: %d hend: %d httl: %d\n",
+ (int)stuff->screen, stuff->hdisplay, stuff->hsyncstart,
+ stuff->hsyncend, stuff->htotal);
+ ErrorF(" vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
+ stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend,
+ stuff->vtotal, (unsigned long)stuff->flags);
+ }
+
+ if (ver < 2) {
+ REQUEST_AT_LEAST_SIZE(xXF86OldVidModeModModeLineReq);
+ len = client->req_len - bytes_to_int32(sizeof(xXF86OldVidModeModModeLineReq));
+ } else {
+ REQUEST_AT_LEAST_SIZE(xXF86VidModeModModeLineReq);
+ len = client->req_len - bytes_to_int32(sizeof(xXF86VidModeModModeLineReq));
+ }
+ if (len != stuff->privsize)
+ return BadLength;
+
+ if (stuff->hsyncstart < stuff->hdisplay ||
+ stuff->hsyncend < stuff->hsyncstart ||
+ stuff->htotal < stuff->hsyncend ||
+ stuff->vsyncstart < stuff->vdisplay ||
+ stuff->vsyncend < stuff->vsyncstart ||
+ stuff->vtotal < stuff->vsyncend)
+ return BadValue;
+
+ if(stuff->screen >= screenInfo.numScreens)
+ return BadValue;
+
+ if (!VidModeGetCurrentModeline(stuff->screen, &mode, &dotClock))
+ return BadValue;
+
+ modetmp = VidModeCreateMode();
+ VidModeCopyMode(mode, modetmp);
+
+ VidModeSetModeValue(modetmp, VIDMODE_H_DISPLAY, stuff->hdisplay);
+ VidModeSetModeValue(modetmp, VIDMODE_H_SYNCSTART, stuff->hsyncstart);
+ VidModeSetModeValue(modetmp, VIDMODE_H_SYNCEND, stuff->hsyncend);
+ VidModeSetModeValue(modetmp, VIDMODE_H_TOTAL, stuff->htotal);
+ VidModeSetModeValue(modetmp, VIDMODE_H_SKEW, stuff->hskew);
+ VidModeSetModeValue(modetmp, VIDMODE_V_DISPLAY, stuff->vdisplay);
+ VidModeSetModeValue(modetmp, VIDMODE_V_SYNCSTART, stuff->vsyncstart);
+ VidModeSetModeValue(modetmp, VIDMODE_V_SYNCEND, stuff->vsyncend);
+ VidModeSetModeValue(modetmp, VIDMODE_V_TOTAL, stuff->vtotal);
+ VidModeSetModeValue(modetmp, VIDMODE_FLAGS, stuff->flags);
+
+ if (stuff->privsize)
+ ErrorF("ModModeLine - Privates in request have been ignored\n");
+
+ /* Check that the mode is consistent with the monitor specs */
+ switch (VidModeCheckModeForMonitor(stuff->screen, modetmp)) {
+ case MODE_OK:
+ break;
+ case MODE_HSYNC:
+ case MODE_H_ILLEGAL:
+ free(modetmp);
+ return VidModeErrorBase + XF86VidModeBadHTimings;
+ case MODE_VSYNC:
+ case MODE_V_ILLEGAL:
+ free(modetmp);
+ return VidModeErrorBase + XF86VidModeBadVTimings;
+ default:
+ free(modetmp);
+ return VidModeErrorBase + XF86VidModeModeUnsuitable;
+ }
+
+ /* Check that the driver is happy with the mode */
+ if (VidModeCheckModeForDriver(stuff->screen, modetmp) != MODE_OK) {
+ free(modetmp);
+ return VidModeErrorBase + XF86VidModeModeUnsuitable;
+ }
+ free(modetmp);
+
+ VidModeSetModeValue(mode, VIDMODE_H_DISPLAY, stuff->hdisplay);
+ VidModeSetModeValue(mode, VIDMODE_H_SYNCSTART, stuff->hsyncstart);
+ VidModeSetModeValue(mode, VIDMODE_H_SYNCEND, stuff->hsyncend);
+ VidModeSetModeValue(mode, VIDMODE_H_TOTAL, stuff->htotal);
+ VidModeSetModeValue(mode, VIDMODE_H_SKEW, stuff->hskew);
+ VidModeSetModeValue(mode, VIDMODE_V_DISPLAY, stuff->vdisplay);
+ VidModeSetModeValue(mode, VIDMODE_V_SYNCSTART, stuff->vsyncstart);
+ VidModeSetModeValue(mode, VIDMODE_V_SYNCEND, stuff->vsyncend);
+ VidModeSetModeValue(mode, VIDMODE_V_TOTAL, stuff->vtotal);
+ VidModeSetModeValue(mode, VIDMODE_FLAGS, stuff->flags);
+
+ VidModeSetCrtcForMode(stuff->screen, mode);
+ VidModeSwitchMode(stuff->screen, mode);
+
+ if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY)
+ ErrorF("ModModeLine - Succeeded\n");
+ return Success;
+}
+
+static int
+ProcXF86VidModeValidateModeLine(ClientPtr client)
+{
+ REQUEST(xXF86VidModeValidateModeLineReq);
+ xXF86OldVidModeValidateModeLineReq *oldstuff =
+ (xXF86OldVidModeValidateModeLineReq *)client->requestBuffer;
+ xXF86VidModeValidateModeLineReq newstuff;
+ xXF86VidModeValidateModeLineReply rep;
+ pointer mode, modetmp = NULL;
+ int len, status, dotClock;
+ int ver;
+
+ DEBUG_P("XF86VidModeValidateModeline");
+
+ ver = ClientMajorVersion(client);
+ if (ver < 2) {
+ /* convert from old format */
+ stuff = &newstuff;
+ stuff->length = oldstuff->length;
+ stuff->screen = oldstuff->screen;
+ stuff->dotclock = oldstuff->dotclock;
+ stuff->hdisplay = oldstuff->hdisplay;
+ stuff->hsyncstart = oldstuff->hsyncstart;
+ stuff->hsyncend = oldstuff->hsyncend;
+ stuff->htotal = oldstuff->htotal;
+ stuff->hskew = 0;
+ stuff->vdisplay = oldstuff->vdisplay;
+ stuff->vsyncstart = oldstuff->vsyncstart;
+ stuff->vsyncend = oldstuff->vsyncend;
+ stuff->vtotal = oldstuff->vtotal;
+ stuff->flags = oldstuff->flags;
+ stuff->privsize = oldstuff->privsize;
+ }
+ if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) {
+ ErrorF("ValidateModeLine - scrn: %d clock: %ld\n",
+ (int)stuff->screen, (unsigned long)stuff->dotclock);
+ ErrorF(" hdsp: %d hbeg: %d hend: %d httl: %d\n",
+ stuff->hdisplay, stuff->hsyncstart,
+ stuff->hsyncend, stuff->htotal);
+ ErrorF(" vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
+ stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend,
+ stuff->vtotal, (unsigned long)stuff->flags);
+ }
+
+ if (ver < 2) {
+ REQUEST_AT_LEAST_SIZE(xXF86OldVidModeValidateModeLineReq);
+ len = client->req_len -
+ bytes_to_int32(sizeof(xXF86OldVidModeValidateModeLineReq));
+ } else {
+ REQUEST_AT_LEAST_SIZE(xXF86VidModeValidateModeLineReq);
+ len = client->req_len - bytes_to_int32(sizeof(xXF86VidModeValidateModeLineReq));
+ }
+ if (len != stuff->privsize)
+ return BadLength;
+
+ if(stuff->screen >= screenInfo.numScreens)
+ return BadValue;
+
+ status = MODE_OK;
+
+ if (stuff->hsyncstart < stuff->hdisplay ||
+ stuff->hsyncend < stuff->hsyncstart ||
+ stuff->htotal < stuff->hsyncend ||
+ stuff->vsyncstart < stuff->vdisplay ||
+ stuff->vsyncend < stuff->vsyncstart ||
+ stuff->vtotal < stuff->vsyncend)
+ {
+ status = MODE_BAD;
+ goto status_reply;
+ }
+
+ if (!VidModeGetCurrentModeline(stuff->screen, &mode, &dotClock))
+ return BadValue;
+
+ modetmp = VidModeCreateMode();
+ VidModeCopyMode(mode, modetmp);
+
+ VidModeSetModeValue(modetmp, VIDMODE_H_DISPLAY, stuff->hdisplay);
+ VidModeSetModeValue(modetmp, VIDMODE_H_SYNCSTART, stuff->hsyncstart);
+ VidModeSetModeValue(modetmp, VIDMODE_H_SYNCEND, stuff->hsyncend);
+ VidModeSetModeValue(modetmp, VIDMODE_H_TOTAL, stuff->htotal);
+ VidModeSetModeValue(modetmp, VIDMODE_H_SKEW, stuff->hskew);
+ VidModeSetModeValue(modetmp, VIDMODE_V_DISPLAY, stuff->vdisplay);
+ VidModeSetModeValue(modetmp, VIDMODE_V_SYNCSTART, stuff->vsyncstart);
+ VidModeSetModeValue(modetmp, VIDMODE_V_SYNCEND, stuff->vsyncend);
+ VidModeSetModeValue(modetmp, VIDMODE_V_TOTAL, stuff->vtotal);
+ VidModeSetModeValue(modetmp, VIDMODE_FLAGS, stuff->flags);
+ if (stuff->privsize)
+ ErrorF("ValidateModeLine - Privates in request have been ignored\n");
+
+ /* Check that the mode is consistent with the monitor specs */
+ if ((status = VidModeCheckModeForMonitor(stuff->screen, modetmp)) != MODE_OK)
+ goto status_reply;
+
+ /* Check that the driver is happy with the mode */
+ status = VidModeCheckModeForDriver(stuff->screen, modetmp);
+
+status_reply:
+ if(modetmp)
+ free(modetmp);
+
+ rep.type = X_Reply;
+ rep.length = bytes_to_int32(SIZEOF(xXF86VidModeValidateModeLineReply)
+ - SIZEOF(xGenericReply));
+ rep.sequenceNumber = client->sequence;
+ rep.status = status;
+ if (client->swapped) {
+ register int n;
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.status, n);
+ }
+ WriteToClient(client, sizeof(xXF86VidModeValidateModeLineReply), (char *)&rep);
+ if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY)
+ ErrorF("ValidateModeLine - Succeeded (status = %d)\n", status);
+ return Success;
+}
+
+static int
+ProcXF86VidModeSwitchMode(ClientPtr client)
+{
+ REQUEST(xXF86VidModeSwitchModeReq);
+
+ DEBUG_P("XF86VidModeSwitchMode");
+
+ REQUEST_SIZE_MATCH(xXF86VidModeSwitchModeReq);
+
+ if(stuff->screen >= screenInfo.numScreens)
+ return BadValue;
+
+ VidModeZoomViewport(stuff->screen, (short)stuff->zoom);
+
+ return Success;
+}
+
+static int
+ProcXF86VidModeSwitchToMode(ClientPtr client)
+{
+ REQUEST(xXF86VidModeSwitchToModeReq);
+ xXF86OldVidModeSwitchToModeReq *oldstuff =
+ (xXF86OldVidModeSwitchToModeReq *)client->requestBuffer;
+ xXF86VidModeSwitchToModeReq newstuff;
+ pointer mode;
+ int len, dotClock;
+ int ver;
+
+ DEBUG_P("XF86VidModeSwitchToMode");
+
+ ver = ClientMajorVersion(client);
+ if (ver < 2) {
+ /* convert from old format */
+ stuff = &newstuff;
+ stuff->length = oldstuff->length;
+ stuff->screen = oldstuff->screen;
+ stuff->dotclock = oldstuff->dotclock;
+ stuff->hdisplay = oldstuff->hdisplay;
+ stuff->hsyncstart = oldstuff->hsyncstart;
+ stuff->hsyncend = oldstuff->hsyncend;
+ stuff->htotal = oldstuff->htotal;
+ stuff->hskew = 0;
+ stuff->vdisplay = oldstuff->vdisplay;
+ stuff->vsyncstart = oldstuff->vsyncstart;
+ stuff->vsyncend = oldstuff->vsyncend;
+ stuff->vtotal = oldstuff->vtotal;
+ stuff->flags = oldstuff->flags;
+ stuff->privsize = oldstuff->privsize;
+ }
+ if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) {
+ ErrorF("SwitchToMode - scrn: %d clock: %ld\n",
+ (int)stuff->screen, (unsigned long)stuff->dotclock);
+ ErrorF(" hdsp: %d hbeg: %d hend: %d httl: %d\n",
+ stuff->hdisplay, stuff->hsyncstart,
+ stuff->hsyncend, stuff->htotal);
+ ErrorF(" vdsp: %d vbeg: %d vend: %d vttl: %d flags: %ld\n",
+ stuff->vdisplay, stuff->vsyncstart, stuff->vsyncend,
+ stuff->vtotal, (unsigned long)stuff->flags);
+ }
+
+ if (ver < 2) {
+ REQUEST_AT_LEAST_SIZE(xXF86OldVidModeSwitchToModeReq);
+ len = client->req_len - bytes_to_int32(sizeof(xXF86OldVidModeSwitchToModeReq));
+ } else {
+ REQUEST_AT_LEAST_SIZE(xXF86VidModeSwitchToModeReq);
+ len = client->req_len - bytes_to_int32(sizeof(xXF86VidModeSwitchToModeReq));
+ }
+ if (len != stuff->privsize)
+ return BadLength;
+
+ if(stuff->screen >= screenInfo.numScreens)
+ return BadValue;
+
+ if (!VidModeGetCurrentModeline(stuff->screen, &mode, &dotClock))
+ return BadValue;
+
+ if ((VidModeGetDotClock(stuff->screen, stuff->dotclock) == dotClock)
+ && MODEMATCH(mode, stuff))
+ return Success;
+
+ if (!VidModeGetFirstModeline(stuff->screen, &mode, &dotClock))
+ return BadValue;
+
+ do {
+ if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY) {
+ ErrorF("Checking against clock: %d (%d)\n",
+ VidModeGetModeValue(mode, VIDMODE_CLOCK), dotClock);
+ ErrorF(" hdsp: %d hbeg: %d hend: %d httl: %d\n",
+ VidModeGetModeValue(mode, VIDMODE_H_DISPLAY),
+ VidModeGetModeValue(mode, VIDMODE_H_SYNCSTART),
+ VidModeGetModeValue(mode, VIDMODE_H_SYNCEND),
+ VidModeGetModeValue(mode, VIDMODE_H_TOTAL));
+ ErrorF(" vdsp: %d vbeg: %d vend: %d vttl: %d flags: %d\n",
+ VidModeGetModeValue(mode, VIDMODE_V_DISPLAY),
+ VidModeGetModeValue(mode, VIDMODE_V_SYNCSTART),
+ VidModeGetModeValue(mode, VIDMODE_V_SYNCEND),
+ VidModeGetModeValue(mode, VIDMODE_V_TOTAL),
+ VidModeGetModeValue(mode, VIDMODE_FLAGS));
+ }
+ if ((VidModeGetDotClock(stuff->screen, stuff->dotclock) == dotClock) &&
+ MODEMATCH(mode, stuff)) {
+
+ if (!VidModeSwitchMode(stuff->screen, mode))
+ return BadValue;
+
+ if (xf86GetVerbosity() > DEFAULT_XF86VIDMODE_VERBOSITY)
+ ErrorF("SwitchToMode - Succeeded\n");
+ return Success;
+ }
+ } while (VidModeGetNextModeline(stuff->screen, &mode, &dotClock));
+
+ return BadValue;
+}
+
+static int
+ProcXF86VidModeLockModeSwitch(ClientPtr client)
+{
+ REQUEST(xXF86VidModeLockModeSwitchReq);
+
+ REQUEST_SIZE_MATCH(xXF86VidModeLockModeSwitchReq);
+
+ DEBUG_P("XF86VidModeLockModeSwitch");
+
+ if(stuff->screen >= screenInfo.numScreens)
+ return BadValue;
+
+ if (!VidModeLockZoom(stuff->screen, (short)stuff->lock))
+ return VidModeErrorBase + XF86VidModeZoomLocked;
+
+ return Success;
+}
+
+static int
+ProcXF86VidModeGetMonitor(ClientPtr client)
+{
+ REQUEST(xXF86VidModeGetMonitorReq);
+ xXF86VidModeGetMonitorReply rep;
+ register int n;
+ CARD32 *hsyncdata, *vsyncdata;
+ int i, nHsync, nVrefresh;
+ pointer monitor;
+
+ DEBUG_P("XF86VidModeGetMonitor");
+
+ REQUEST_SIZE_MATCH(xXF86VidModeGetMonitorReq);
+
+ if(stuff->screen >= screenInfo.numScreens)
+ return BadValue;
+
+ if (!VidModeGetMonitor(stuff->screen, &monitor))
+ return BadValue;
+
+ nHsync = VidModeGetMonitorValue(monitor, VIDMODE_MON_NHSYNC, 0).i;
+ nVrefresh = VidModeGetMonitorValue(monitor, VIDMODE_MON_NVREFRESH, 0).i;
+
+ rep.type = X_Reply;
+ if ((char *)(VidModeGetMonitorValue(monitor, VIDMODE_MON_VENDOR, 0)).ptr)
+ rep.vendorLength = strlen((char *)(VidModeGetMonitorValue(monitor,
+ VIDMODE_MON_VENDOR, 0)).ptr);
+ else
+ rep.vendorLength = 0;
+ if ((char *)(VidModeGetMonitorValue(monitor, VIDMODE_MON_MODEL, 0)).ptr)
+ rep.modelLength = strlen((char *)(VidModeGetMonitorValue(monitor,
+ VIDMODE_MON_MODEL, 0)).ptr);
+ else
+ rep.modelLength = 0;
+ rep.length = bytes_to_int32(SIZEOF(xXF86VidModeGetMonitorReply) - SIZEOF(xGenericReply) +
+ (nHsync + nVrefresh) * sizeof(CARD32) +
+ pad_to_int32(rep.vendorLength) +
+ pad_to_int32(rep.modelLength));
+ rep.sequenceNumber = client->sequence;
+ rep.nhsync = nHsync;
+ rep.nvsync = nVrefresh;
+ hsyncdata = malloc(nHsync * sizeof(CARD32));
+ if (!hsyncdata) {
+ return BadAlloc;
+ }
+
+ vsyncdata = malloc(nVrefresh * sizeof(CARD32));
+ if (!vsyncdata) {
+ free(hsyncdata);
+ return BadAlloc;
+ }
+
+ for (i = 0; i < nHsync; i++) {
+ hsyncdata[i] = (unsigned short)(VidModeGetMonitorValue(monitor,
+ VIDMODE_MON_HSYNC_LO, i)).f |
+ (unsigned short)(VidModeGetMonitorValue(monitor,
+ VIDMODE_MON_HSYNC_HI, i)).f << 16;
+ }
+ for (i = 0; i < nVrefresh; i++) {
+ vsyncdata[i] = (unsigned short)(VidModeGetMonitorValue(monitor,
+ VIDMODE_MON_VREFRESH_LO, i)).f |
+ (unsigned short)(VidModeGetMonitorValue(monitor,
+ VIDMODE_MON_VREFRESH_HI, i)).f << 16;
+ }
+
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ }
+ WriteToClient(client, SIZEOF(xXF86VidModeGetMonitorReply), (char *)&rep);
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, nHsync * sizeof(CARD32),
+ hsyncdata);
+ WriteSwappedDataToClient(client, nVrefresh * sizeof(CARD32),
+ vsyncdata);
+ if (rep.vendorLength)
+ WriteToClient(client, rep.vendorLength, (char *)(VidModeGetMonitorValue(monitor, VIDMODE_MON_VENDOR, 0)).ptr);
+ if (rep.modelLength)
+ WriteToClient(client, rep.modelLength, (char *)(VidModeGetMonitorValue(monitor, VIDMODE_MON_MODEL, 0)).ptr);
+
+ free(hsyncdata);
+ free(vsyncdata);
+
+ return Success;
+}
+
+static int
+ProcXF86VidModeGetViewPort(ClientPtr client)
+{
+ REQUEST(xXF86VidModeGetViewPortReq);
+ xXF86VidModeGetViewPortReply rep;
+ int x, y, n;
+
+ DEBUG_P("XF86VidModeGetViewPort");
+
+ REQUEST_SIZE_MATCH(xXF86VidModeGetViewPortReq);
+
+ if(stuff->screen >= screenInfo.numScreens)
+ return BadValue;
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ VidModeGetViewPort(stuff->screen, &x, &y);
+ rep.x = x;
+ rep.y = y;
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.x, n);
+ swapl(&rep.y, n);
+ }
+ WriteToClient(client, SIZEOF(xXF86VidModeGetViewPortReply), (char *)&rep);
+ return Success;
+}
+
+static int
+ProcXF86VidModeSetViewPort(ClientPtr client)
+{
+ REQUEST(xXF86VidModeSetViewPortReq);
+
+ DEBUG_P("XF86VidModeSetViewPort");
+
+ REQUEST_SIZE_MATCH(xXF86VidModeSetViewPortReq);
+
+ if(stuff->screen >= screenInfo.numScreens)
+ return BadValue;
+
+ if (!VidModeSetViewPort(stuff->screen, stuff->x, stuff->y))
+ return BadValue;
+
+ return Success;
+}
+
+static int
+ProcXF86VidModeGetDotClocks(ClientPtr client)
+{
+ REQUEST(xXF86VidModeGetDotClocksReq);
+ xXF86VidModeGetDotClocksReply rep;
+ register int n;
+ int numClocks;
+ CARD32 dotclock;
+ int *Clocks = NULL;
+ Bool ClockProg;
+
+ DEBUG_P("XF86VidModeGetDotClocks");
+
+ REQUEST_SIZE_MATCH(xXF86VidModeGetDotClocksReq);
+
+ if(stuff->screen >= screenInfo.numScreens)
+ return BadValue;
+
+ numClocks = VidModeGetNumOfClocks(stuff->screen, &ClockProg);
+
+ rep.type = X_Reply;
+ rep.length = bytes_to_int32(SIZEOF(xXF86VidModeGetDotClocksReply)
+ - SIZEOF(xGenericReply) + numClocks);
+ rep.sequenceNumber = client->sequence;
+ rep.clocks = numClocks;
+ rep.maxclocks = MAXCLOCKS;
+ rep.flags = 0;
+
+ if (!ClockProg) {
+ Clocks = malloc(numClocks * sizeof(int));
+ if (!Clocks)
+ return BadValue;
+ if (!VidModeGetClocks(stuff->screen, Clocks)) {
+ free(Clocks);
+ return BadValue;
+ }
+ }
+
+ if (ClockProg) {
+ rep.flags |= CLKFLAG_PROGRAMABLE;
+ }
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.clocks, n);
+ swapl(&rep.maxclocks, n);
+ swapl(&rep.flags, n);
+ }
+ WriteToClient(client, sizeof(xXF86VidModeGetDotClocksReply), (char *)&rep);
+ if (!ClockProg) {
+ for (n = 0; n < numClocks; n++) {
+ dotclock = *Clocks++;
+ if (client->swapped) {
+ WriteSwappedDataToClient(client, 4, (char *)&dotclock);
+ } else {
+ WriteToClient(client, 4, (char *)&dotclock);
+ }
+ }
+ }
+
+ free(Clocks);
+ return Success;
+}
+
+static int
+ProcXF86VidModeSetGamma(ClientPtr client)
+{
+ REQUEST(xXF86VidModeSetGammaReq);
+
+ DEBUG_P("XF86VidModeSetGamma");
+
+ REQUEST_SIZE_MATCH(xXF86VidModeSetGammaReq);
+
+ if(stuff->screen >= screenInfo.numScreens)
+ return BadValue;
+
+ if (!VidModeSetGamma(stuff->screen, ((float)stuff->red)/10000.,
+ ((float)stuff->green)/10000., ((float)stuff->blue)/10000.))
+ return BadValue;
+
+ return Success;
+}
+
+static int
+ProcXF86VidModeGetGamma(ClientPtr client)
+{
+ REQUEST(xXF86VidModeGetGammaReq);
+ xXF86VidModeGetGammaReply rep;
+ register int n;
+ float red, green, blue;
+
+ DEBUG_P("XF86VidModeGetGamma");
+
+ REQUEST_SIZE_MATCH(xXF86VidModeGetGammaReq);
+
+ if(stuff->screen >= screenInfo.numScreens)
+ return BadValue;
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ if (!VidModeGetGamma(stuff->screen, &red, &green, &blue))
+ return BadValue;
+ rep.red = (CARD32)(red * 10000.);
+ rep.green = (CARD32)(green * 10000.);
+ rep.blue = (CARD32)(blue * 10000.);
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.red, n);
+ swapl(&rep.green, n);
+ swapl(&rep.blue, n);
+ }
+ WriteToClient(client, sizeof(xXF86VidModeGetGammaReply), (char *)&rep);
+ return Success;
+}
+
+static int
+ProcXF86VidModeSetGammaRamp(ClientPtr client)
+{
+ CARD16 *r, *g, *b;
+ int length;
+ REQUEST(xXF86VidModeSetGammaRampReq);
+
+ if(stuff->screen >= screenInfo.numScreens)
+ return BadValue;
+
+ if(stuff->size != VidModeGetGammaRampSize(stuff->screen))
+ return BadValue;
+
+ length = (stuff->size + 1) & ~1;
+
+ REQUEST_FIXED_SIZE(xXF86VidModeSetGammaRampReq, length * 6);
+
+ r = (CARD16*)&stuff[1];
+ g = r + length;
+ b = g + length;
+
+ if (!VidModeSetGammaRamp(stuff->screen, stuff->size, r, g, b))
+ return BadValue;
+
+ return Success;
+}
+
+static int
+ProcXF86VidModeGetGammaRamp(ClientPtr client)
+{
+ CARD16 *ramp = NULL;
+ int n, length;
+ size_t ramplen = 0;
+ xXF86VidModeGetGammaRampReply rep;
+ REQUEST(xXF86VidModeGetGammaRampReq);
+
+ if(stuff->screen >= screenInfo.numScreens)
+ return BadValue;
+
+ if(stuff->size != VidModeGetGammaRampSize(stuff->screen))
+ return BadValue;
+
+ REQUEST_SIZE_MATCH(xXF86VidModeGetGammaRampReq);
+
+ length = (stuff->size + 1) & ~1;
+
+ if(stuff->size) {
+ ramplen = length * 3 * sizeof(CARD16);
+ if (!(ramp = malloc(ramplen)))
+ return BadAlloc;
+
+ if (!VidModeGetGammaRamp(stuff->screen, stuff->size,
+ ramp, ramp + length, ramp + (length * 2))) {
+ free(ramp);
+ return BadValue;
+ }
+ }
+
+ rep.type = X_Reply;
+ rep.length = (length >> 1) * 3;
+ rep.sequenceNumber = client->sequence;
+ rep.size = stuff->size;
+ if(client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.size, n);
+ SwapShorts((short*)ramp, length * 3);
+ }
+ WriteToClient(client, sizeof(xXF86VidModeGetGammaRampReply), (char *)&rep);
+
+ if(stuff->size) {
+ WriteToClient(client, ramplen, (char*)ramp);
+ free(ramp);
+ }
+
+ return Success;
+}
+
+
+static int
+ProcXF86VidModeGetGammaRampSize(ClientPtr client)
+{
+ xXF86VidModeGetGammaRampSizeReply rep;
+ int n;
+ REQUEST(xXF86VidModeGetGammaRampSizeReq);
+
+ if(stuff->screen >= screenInfo.numScreens)
+ return BadValue;
+
+ REQUEST_SIZE_MATCH(xXF86VidModeGetGammaRampSizeReq);
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.size = VidModeGetGammaRampSize(stuff->screen);
+ if(client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.size, n);
+ }
+ WriteToClient(client,sizeof(xXF86VidModeGetGammaRampSizeReply),(char*)&rep);
+
+ return Success;
+}
+
+static int
+ProcXF86VidModeGetPermissions(ClientPtr client)
+{
+ xXF86VidModeGetPermissionsReply rep;
+ int n;
+ REQUEST(xXF86VidModeGetPermissionsReq);
+
+ if(stuff->screen >= screenInfo.numScreens)
+ return BadValue;
+
+ REQUEST_SIZE_MATCH(xXF86VidModeGetPermissionsReq);
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.permissions = XF86VM_READ_PERMISSION;
+ if (xf86GetVidModeEnabled() &&
+ (xf86GetVidModeAllowNonLocal() || LocalClient (client))) {
+ rep.permissions |= XF86VM_WRITE_PERMISSION;
+ }
+ if(client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swapl(&rep.permissions, n);
+ }
+ WriteToClient(client,sizeof(xXF86VidModeGetPermissionsReply),(char*)&rep);
+
+ return Success;
+}
+
+
+static int
+ProcXF86VidModeSetClientVersion(ClientPtr client)
+{
+ REQUEST(xXF86VidModeSetClientVersionReq);
+
+ VidModePrivPtr pPriv;
+
+ DEBUG_P("XF86VidModeSetClientVersion");
+
+ REQUEST_SIZE_MATCH(xXF86VidModeSetClientVersionReq);
+
+ if ((pPriv = VM_GETPRIV(client)) == NULL) {
+ pPriv = malloc(sizeof(VidModePrivRec));
+ if (!pPriv)
+ return BadAlloc;
+ VM_SETPRIV(client, pPriv);
+ }
+ pPriv->major = stuff->major;
+ pPriv->minor = stuff->minor;
+
+ return Success;
+}
+
+static int
+ProcXF86VidModeDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_XF86VidModeQueryVersion:
+ return ProcXF86VidModeQueryVersion(client);
+ case X_XF86VidModeGetModeLine:
+ return ProcXF86VidModeGetModeLine(client);
+ case X_XF86VidModeGetMonitor:
+ return ProcXF86VidModeGetMonitor(client);
+ case X_XF86VidModeGetAllModeLines:
+ return ProcXF86VidModeGetAllModeLines(client);
+ case X_XF86VidModeValidateModeLine:
+ return ProcXF86VidModeValidateModeLine(client);
+ case X_XF86VidModeGetViewPort:
+ return ProcXF86VidModeGetViewPort(client);
+ case X_XF86VidModeGetDotClocks:
+ return ProcXF86VidModeGetDotClocks(client);
+ case X_XF86VidModeSetClientVersion:
+ return ProcXF86VidModeSetClientVersion(client);
+ case X_XF86VidModeGetGamma:
+ return ProcXF86VidModeGetGamma(client);
+ case X_XF86VidModeGetGammaRamp:
+ return ProcXF86VidModeGetGammaRamp(client);
+ case X_XF86VidModeGetGammaRampSize:
+ return ProcXF86VidModeGetGammaRampSize(client);
+ case X_XF86VidModeGetPermissions:
+ return ProcXF86VidModeGetPermissions(client);
+ default:
+ if (!xf86GetVidModeEnabled())
+ return VidModeErrorBase + XF86VidModeExtensionDisabled;
+ if (xf86GetVidModeAllowNonLocal() || LocalClient (client)) {
+ switch (stuff->data) {
+ case X_XF86VidModeAddModeLine:
+ return ProcXF86VidModeAddModeLine(client);
+ case X_XF86VidModeDeleteModeLine:
+ return ProcXF86VidModeDeleteModeLine(client);
+ case X_XF86VidModeModModeLine:
+ return ProcXF86VidModeModModeLine(client);
+ case X_XF86VidModeSwitchMode:
+ return ProcXF86VidModeSwitchMode(client);
+ case X_XF86VidModeSwitchToMode:
+ return ProcXF86VidModeSwitchToMode(client);
+ case X_XF86VidModeLockModeSwitch:
+ return ProcXF86VidModeLockModeSwitch(client);
+ case X_XF86VidModeSetViewPort:
+ return ProcXF86VidModeSetViewPort(client);
+ case X_XF86VidModeSetGamma:
+ return ProcXF86VidModeSetGamma(client);
+ case X_XF86VidModeSetGammaRamp:
+ return ProcXF86VidModeSetGammaRamp(client);
+ default:
+ return BadRequest;
+ }
+ } else
+ return VidModeErrorBase + XF86VidModeClientNotLocal;
+ }
+}
+
+static int
+SProcXF86VidModeQueryVersion(ClientPtr client)
+{
+ register int n;
+ REQUEST(xXF86VidModeQueryVersionReq);
+ swaps(&stuff->length, n);
+ return ProcXF86VidModeQueryVersion(client);
+}
+
+static int
+SProcXF86VidModeGetModeLine(ClientPtr client)
+{
+ register int n;
+ REQUEST(xXF86VidModeGetModeLineReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXF86VidModeGetModeLineReq);
+ swaps(&stuff->screen, n);
+ return ProcXF86VidModeGetModeLine(client);
+}
+
+static int
+SProcXF86VidModeGetAllModeLines(ClientPtr client)
+{
+ register int n;
+ REQUEST(xXF86VidModeGetAllModeLinesReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXF86VidModeGetAllModeLinesReq);
+ swaps(&stuff->screen, n);
+ return ProcXF86VidModeGetAllModeLines(client);
+}
+
+static int
+SProcXF86VidModeAddModeLine(ClientPtr client)
+{
+ xXF86OldVidModeAddModeLineReq *oldstuff =
+ (xXF86OldVidModeAddModeLineReq *)client->requestBuffer;
+ int ver;
+ register int n;
+
+ REQUEST(xXF86VidModeAddModeLineReq);
+ ver = ClientMajorVersion(client);
+ if (ver < 2) {
+ swaps(&oldstuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xXF86OldVidModeAddModeLineReq);
+ swapl(&oldstuff->screen, n);
+ swaps(&oldstuff->hdisplay, n);
+ swaps(&oldstuff->hsyncstart, n);
+ swaps(&oldstuff->hsyncend, n);
+ swaps(&oldstuff->htotal, n);
+ swaps(&oldstuff->vdisplay, n);
+ swaps(&oldstuff->vsyncstart, n);
+ swaps(&oldstuff->vsyncend, n);
+ swaps(&oldstuff->vtotal, n);
+ swapl(&oldstuff->flags, n);
+ swapl(&oldstuff->privsize, n);
+ SwapRestL(oldstuff);
+ } else {
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xXF86VidModeAddModeLineReq);
+ swapl(&stuff->screen, n);
+ swaps(&stuff->hdisplay, n);
+ swaps(&stuff->hsyncstart, n);
+ swaps(&stuff->hsyncend, n);
+ swaps(&stuff->htotal, n);
+ swaps(&stuff->hskew, n);
+ swaps(&stuff->vdisplay, n);
+ swaps(&stuff->vsyncstart, n);
+ swaps(&stuff->vsyncend, n);
+ swaps(&stuff->vtotal, n);
+ swapl(&stuff->flags, n);
+ swapl(&stuff->privsize, n);
+ SwapRestL(stuff);
+ }
+ return ProcXF86VidModeAddModeLine(client);
+}
+
+static int
+SProcXF86VidModeDeleteModeLine(ClientPtr client)
+{
+ xXF86OldVidModeDeleteModeLineReq *oldstuff =
+ (xXF86OldVidModeDeleteModeLineReq *)client->requestBuffer;
+ int ver;
+ register int n;
+
+ REQUEST(xXF86VidModeDeleteModeLineReq);
+ ver = ClientMajorVersion(client);
+ if (ver < 2) {
+ swaps(&oldstuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xXF86OldVidModeDeleteModeLineReq);
+ swapl(&oldstuff->screen, n);
+ swaps(&oldstuff->hdisplay, n);
+ swaps(&oldstuff->hsyncstart, n);
+ swaps(&oldstuff->hsyncend, n);
+ swaps(&oldstuff->htotal, n);
+ swaps(&oldstuff->vdisplay, n);
+ swaps(&oldstuff->vsyncstart, n);
+ swaps(&oldstuff->vsyncend, n);
+ swaps(&oldstuff->vtotal, n);
+ swapl(&oldstuff->flags, n);
+ swapl(&oldstuff->privsize, n);
+ SwapRestL(oldstuff);
+ } else {
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xXF86VidModeDeleteModeLineReq);
+ swapl(&stuff->screen, n);
+ swaps(&stuff->hdisplay, n);
+ swaps(&stuff->hsyncstart, n);
+ swaps(&stuff->hsyncend, n);
+ swaps(&stuff->htotal, n);
+ swaps(&stuff->hskew, n);
+ swaps(&stuff->vdisplay, n);
+ swaps(&stuff->vsyncstart, n);
+ swaps(&stuff->vsyncend, n);
+ swaps(&stuff->vtotal, n);
+ swapl(&stuff->flags, n);
+ swapl(&stuff->privsize, n);
+ SwapRestL(stuff);
+ }
+ return ProcXF86VidModeDeleteModeLine(client);
+}
+
+static int
+SProcXF86VidModeModModeLine(ClientPtr client)
+{
+ xXF86OldVidModeModModeLineReq *oldstuff =
+ (xXF86OldVidModeModModeLineReq *)client->requestBuffer;
+ int ver;
+ register int n;
+
+ REQUEST(xXF86VidModeModModeLineReq);
+ ver = ClientMajorVersion(client);
+ if (ver < 2) {
+ swaps(&oldstuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xXF86OldVidModeModModeLineReq);
+ swapl(&oldstuff->screen, n);
+ swaps(&oldstuff->hdisplay, n);
+ swaps(&oldstuff->hsyncstart, n);
+ swaps(&oldstuff->hsyncend, n);
+ swaps(&oldstuff->htotal, n);
+ swaps(&oldstuff->vdisplay, n);
+ swaps(&oldstuff->vsyncstart, n);
+ swaps(&oldstuff->vsyncend, n);
+ swaps(&oldstuff->vtotal, n);
+ swapl(&oldstuff->flags, n);
+ swapl(&oldstuff->privsize, n);
+ SwapRestL(oldstuff);
+ } else {
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xXF86VidModeModModeLineReq);
+ swapl(&stuff->screen, n);
+ swaps(&stuff->hdisplay, n);
+ swaps(&stuff->hsyncstart, n);
+ swaps(&stuff->hsyncend, n);
+ swaps(&stuff->htotal, n);
+ swaps(&stuff->hskew, n);
+ swaps(&stuff->vdisplay, n);
+ swaps(&stuff->vsyncstart, n);
+ swaps(&stuff->vsyncend, n);
+ swaps(&stuff->vtotal, n);
+ swapl(&stuff->flags, n);
+ swapl(&stuff->privsize, n);
+ SwapRestL(stuff);
+ }
+ return ProcXF86VidModeModModeLine(client);
+}
+
+static int
+SProcXF86VidModeValidateModeLine(ClientPtr client)
+{
+ xXF86OldVidModeValidateModeLineReq *oldstuff =
+ (xXF86OldVidModeValidateModeLineReq *)client->requestBuffer;
+ int ver;
+ register int n;
+
+ REQUEST(xXF86VidModeValidateModeLineReq);
+ ver = ClientMajorVersion(client);
+ if (ver < 2) {
+ swaps(&oldstuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xXF86OldVidModeValidateModeLineReq);
+ swapl(&oldstuff->screen, n);
+ swaps(&oldstuff->hdisplay, n);
+ swaps(&oldstuff->hsyncstart, n);
+ swaps(&oldstuff->hsyncend, n);
+ swaps(&oldstuff->htotal, n);
+ swaps(&oldstuff->vdisplay, n);
+ swaps(&oldstuff->vsyncstart, n);
+ swaps(&oldstuff->vsyncend, n);
+ swaps(&oldstuff->vtotal, n);
+ swapl(&oldstuff->flags, n);
+ swapl(&oldstuff->privsize, n);
+ SwapRestL(oldstuff);
+ } else {
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xXF86VidModeValidateModeLineReq);
+ swapl(&stuff->screen, n);
+ swaps(&stuff->hdisplay, n);
+ swaps(&stuff->hsyncstart, n);
+ swaps(&stuff->hsyncend, n);
+ swaps(&stuff->htotal, n);
+ swaps(&stuff->hskew, n);
+ swaps(&stuff->vdisplay, n);
+ swaps(&stuff->vsyncstart, n);
+ swaps(&stuff->vsyncend, n);
+ swaps(&stuff->vtotal, n);
+ swapl(&stuff->flags, n);
+ swapl(&stuff->privsize, n);
+ SwapRestL(stuff);
+ }
+ return ProcXF86VidModeValidateModeLine(client);
+}
+
+static int
+SProcXF86VidModeSwitchMode(ClientPtr client)
+{
+ register int n;
+ REQUEST(xXF86VidModeSwitchModeReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXF86VidModeSwitchModeReq);
+ swaps(&stuff->screen, n);
+ swaps(&stuff->zoom, n);
+ return ProcXF86VidModeSwitchMode(client);
+}
+
+static int
+SProcXF86VidModeSwitchToMode(ClientPtr client)
+{
+ register int n;
+ REQUEST(xXF86VidModeSwitchToModeReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXF86VidModeSwitchToModeReq);
+ swaps(&stuff->screen, n);
+ return ProcXF86VidModeSwitchToMode(client);
+}
+
+static int
+SProcXF86VidModeLockModeSwitch(ClientPtr client)
+{
+ register int n;
+ REQUEST(xXF86VidModeLockModeSwitchReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXF86VidModeLockModeSwitchReq);
+ swaps(&stuff->screen, n);
+ swaps(&stuff->lock, n);
+ return ProcXF86VidModeLockModeSwitch(client);
+}
+
+static int
+SProcXF86VidModeGetMonitor(ClientPtr client)
+{
+ register int n;
+ REQUEST(xXF86VidModeGetMonitorReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXF86VidModeGetMonitorReq);
+ swaps(&stuff->screen, n);
+ return ProcXF86VidModeGetMonitor(client);
+}
+
+static int
+SProcXF86VidModeGetViewPort(ClientPtr client)
+{
+ register int n;
+ REQUEST(xXF86VidModeGetViewPortReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXF86VidModeGetViewPortReq);
+ swaps(&stuff->screen, n);
+ return ProcXF86VidModeGetViewPort(client);
+}
+
+static int
+SProcXF86VidModeSetViewPort(ClientPtr client)
+{
+ register int n;
+ REQUEST(xXF86VidModeSetViewPortReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXF86VidModeSetViewPortReq);
+ swaps(&stuff->screen, n);
+ swapl(&stuff->x, n);
+ swapl(&stuff->y, n);
+ return ProcXF86VidModeSetViewPort(client);
+}
+
+static int
+SProcXF86VidModeGetDotClocks(ClientPtr client)
+{
+ register int n;
+ REQUEST(xXF86VidModeGetDotClocksReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXF86VidModeGetDotClocksReq);
+ swaps(&stuff->screen, n);
+ return ProcXF86VidModeGetDotClocks(client);
+}
+
+static int
+SProcXF86VidModeSetClientVersion(ClientPtr client)
+{
+ register int n;
+ REQUEST(xXF86VidModeSetClientVersionReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXF86VidModeSetClientVersionReq);
+ swaps(&stuff->major, n);
+ swaps(&stuff->minor, n);
+ return ProcXF86VidModeSetClientVersion(client);
+}
+
+static int
+SProcXF86VidModeSetGamma(ClientPtr client)
+{
+ register int n;
+ REQUEST(xXF86VidModeSetGammaReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXF86VidModeSetGammaReq);
+ swaps(&stuff->screen, n);
+ swapl(&stuff->red, n);
+ swapl(&stuff->green, n);
+ swapl(&stuff->blue, n);
+ return ProcXF86VidModeSetGamma(client);
+}
+
+static int
+SProcXF86VidModeGetGamma(ClientPtr client)
+{
+ register int n;
+ REQUEST(xXF86VidModeGetGammaReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXF86VidModeGetGammaReq);
+ swaps(&stuff->screen, n);
+ return ProcXF86VidModeGetGamma(client);
+}
+
+static int
+SProcXF86VidModeSetGammaRamp(ClientPtr client)
+{
+ int length, n;
+ REQUEST(xXF86VidModeSetGammaRampReq);
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xXF86VidModeSetGammaRampReq);
+ swaps(&stuff->size, n);
+ swaps(&stuff->screen, n);
+ length = ((stuff->size + 1) & ~1) * 6;
+ REQUEST_FIXED_SIZE(xXF86VidModeSetGammaRampReq, length);
+ SwapRestS(stuff);
+ return ProcXF86VidModeSetGammaRamp(client);
+}
+
+static int
+SProcXF86VidModeGetGammaRamp(ClientPtr client)
+{
+ int n;
+ REQUEST(xXF86VidModeGetGammaRampReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXF86VidModeGetGammaRampReq);
+ swaps(&stuff->size, n);
+ swaps(&stuff->screen, n);
+ return ProcXF86VidModeGetGammaRamp(client);
+}
+
+static int
+SProcXF86VidModeGetGammaRampSize(ClientPtr client)
+{
+ int n;
+ REQUEST(xXF86VidModeGetGammaRampSizeReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXF86VidModeGetGammaRampSizeReq);
+ swaps(&stuff->screen, n);
+ return ProcXF86VidModeGetGammaRampSize(client);
+}
+
+static int
+SProcXF86VidModeGetPermissions(ClientPtr client)
+{
+ int n;
+ REQUEST(xXF86VidModeGetPermissionsReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXF86VidModeGetPermissionsReq);
+ swaps(&stuff->screen, n);
+ return ProcXF86VidModeGetPermissions(client);
+}
+
+
+static int
+SProcXF86VidModeDispatch(ClientPtr client)
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_XF86VidModeQueryVersion:
+ return SProcXF86VidModeQueryVersion(client);
+ case X_XF86VidModeGetModeLine:
+ return SProcXF86VidModeGetModeLine(client);
+ case X_XF86VidModeGetMonitor:
+ return SProcXF86VidModeGetMonitor(client);
+ case X_XF86VidModeGetAllModeLines:
+ return SProcXF86VidModeGetAllModeLines(client);
+ case X_XF86VidModeGetViewPort:
+ return SProcXF86VidModeGetViewPort(client);
+ case X_XF86VidModeValidateModeLine:
+ return SProcXF86VidModeValidateModeLine(client);
+ case X_XF86VidModeGetDotClocks:
+ return SProcXF86VidModeGetDotClocks(client);
+ case X_XF86VidModeSetClientVersion:
+ return SProcXF86VidModeSetClientVersion(client);
+ case X_XF86VidModeGetGamma:
+ return SProcXF86VidModeGetGamma(client);
+ case X_XF86VidModeGetGammaRamp:
+ return SProcXF86VidModeGetGammaRamp(client);
+ case X_XF86VidModeGetGammaRampSize:
+ return SProcXF86VidModeGetGammaRampSize(client);
+ case X_XF86VidModeGetPermissions:
+ return SProcXF86VidModeGetPermissions(client);
+ default:
+ if (!xf86GetVidModeEnabled())
+ return VidModeErrorBase + XF86VidModeExtensionDisabled;
+ if (xf86GetVidModeAllowNonLocal() || LocalClient(client)) {
+ switch (stuff->data) {
+ case X_XF86VidModeAddModeLine:
+ return SProcXF86VidModeAddModeLine(client);
+ case X_XF86VidModeDeleteModeLine:
+ return SProcXF86VidModeDeleteModeLine(client);
+ case X_XF86VidModeModModeLine:
+ return SProcXF86VidModeModModeLine(client);
+ case X_XF86VidModeSwitchMode:
+ return SProcXF86VidModeSwitchMode(client);
+ case X_XF86VidModeSwitchToMode:
+ return SProcXF86VidModeSwitchToMode(client);
+ case X_XF86VidModeLockModeSwitch:
+ return SProcXF86VidModeLockModeSwitch(client);
+ case X_XF86VidModeSetViewPort:
+ return SProcXF86VidModeSetViewPort(client);
+ case X_XF86VidModeSetGamma:
+ return SProcXF86VidModeSetGamma(client);
+ case X_XF86VidModeSetGammaRamp:
+ return SProcXF86VidModeSetGammaRamp(client);
+ default:
+ return BadRequest;
+ }
+ } else
+ return VidModeErrorBase + XF86VidModeClientNotLocal;
+ }
+}
diff --git a/xorg-server/hw/xfree86/dri/dri.c b/xorg-server/hw/xfree86/dri/dri.c
index 836967c73..a8b050a94 100644
--- a/xorg-server/hw/xfree86/dri/dri.c
+++ b/xorg-server/hw/xfree86/dri/dri.c
@@ -1,2504 +1,2504 @@
-/**************************************************************************
-
-Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
-Copyright 2000 VA Linux Systems, 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, sub license, 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 (including the
-next paragraph) 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 NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Jens Owen <jens@tungstengraphics.com>
- * Rickard E. (Rik) Faith <faith@valinux.com>
- *
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "xf86.h"
-#include <sys/time.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-#include <sys/ioctl.h>
-#include <errno.h>
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "xf86drm.h"
-#include "misc.h"
-#include "dixstruct.h"
-#include "extnsionst.h"
-#include "colormapst.h"
-#include "cursorstr.h"
-#include "scrnintstr.h"
-#include "windowstr.h"
-#include "servermd.h"
-#define _XF86DRI_SERVER_
-#include <X11/dri/xf86driproto.h>
-#include "swaprep.h"
-#include "xf86str.h"
-#include "dri.h"
-#include "sarea.h"
-#include "dristruct.h"
-#include "xf86.h"
-#include "xf86drm.h"
-#include "mi.h"
-#include "mipointer.h"
-#include "xf86_OSproc.h"
-#include "inputstr.h"
-#include "xf86VGAarbiter.h"
-
-#define PCI_BUS_NO_DOMAIN(bus) ((bus) & 0xffu)
-
-static int DRIEntPrivIndex = -1;
-static int DRIScreenPrivKeyIndex;
-static DevPrivateKey DRIScreenPrivKey = &DRIScreenPrivKeyIndex;
-static int DRIWindowPrivKeyIndex;
-static DevPrivateKey DRIWindowPrivKey = &DRIWindowPrivKeyIndex;
-static unsigned long DRIGeneration = 0;
-static unsigned int DRIDrawableValidationStamp = 0;
-
-static RESTYPE DRIDrawablePrivResType;
-static RESTYPE DRIContextPrivResType;
-static void DRIDestroyDummyContext(ScreenPtr pScreen, Bool hasCtxPriv);
-
-drmServerInfo DRIDRMServerInfo;
-
- /* Wrapper just like xf86DrvMsg, but
- without the verbosity level checking.
- This will make it easy to turn off some
- messages later, based on verbosity
- level. */
-
-/*
- * Since we're already referencing things from the XFree86 common layer in
- * this file, we'd might as well just call xf86VDrvMsgVerb, and have
- * consistent message formatting. The verbosity of these messages can be
- * easily changed here.
- */
-#define DRI_MSG_VERBOSITY 1
-static void
-DRIDrvMsg(int scrnIndex, MessageType type, const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- xf86VDrvMsgVerb(scrnIndex, type, DRI_MSG_VERBOSITY, format, ap);
- va_end(ap);
-}
-
-
-static void
-DRIOpenDRMCleanup(DRIEntPrivPtr pDRIEntPriv)
-{
- if (pDRIEntPriv->pLSAREA != NULL) {
- drmUnmap(pDRIEntPriv->pLSAREA, pDRIEntPriv->sAreaSize);
- pDRIEntPriv->pLSAREA = NULL;
- }
- if (pDRIEntPriv->hLSAREA != 0) {
- drmRmMap(pDRIEntPriv->drmFD, pDRIEntPriv->hLSAREA);
- }
- if (pDRIEntPriv->drmFD >= 0) {
- drmClose(pDRIEntPriv->drmFD);
- pDRIEntPriv->drmFD = 0;
- }
-}
-
-int
-DRIMasterFD(ScrnInfoPtr pScrn)
-{
- return DRI_ENT_PRIV(pScrn)->drmFD;
-}
-
-void *
-DRIMasterSareaPointer(ScrnInfoPtr pScrn)
-{
- return DRI_ENT_PRIV(pScrn)->pLSAREA;
-}
-
-drm_handle_t
-DRIMasterSareaHandle(ScrnInfoPtr pScrn)
-{
- return DRI_ENT_PRIV(pScrn)->hLSAREA;
-}
-
-
-Bool
-DRIOpenDRMMaster(ScrnInfoPtr pScrn,
- unsigned long sAreaSize,
- const char *busID,
- const char *drmDriverName)
-{
- drmSetVersion saveSv, sv;
- Bool drmWasAvailable;
- DRIEntPrivPtr pDRIEntPriv;
- DRIEntPrivRec tmp;
- drmVersionPtr drmlibv;
- int drmlibmajor, drmlibminor;
- const char *openBusID;
- int count;
- int err;
-
- if (DRIEntPrivIndex == -1)
- DRIEntPrivIndex = xf86AllocateEntityPrivateIndex();
-
- pDRIEntPriv = DRI_ENT_PRIV(pScrn);
-
- if (pDRIEntPriv && pDRIEntPriv->drmFD != -1)
- return TRUE;
-
- drmWasAvailable = drmAvailable();
-
- memset(&tmp, 0, sizeof(tmp));
-
- /* Check the DRM lib version.
- * drmGetLibVersion was not supported in version 1.0, so check for
- * symbol first to avoid possible crash or hang.
- */
-
- drmlibmajor = 1;
- drmlibminor = 0;
- if (xf86LoaderCheckSymbol("drmGetLibVersion")) {
- drmlibv = drmGetLibVersion(-1);
- if (drmlibv != NULL) {
- drmlibmajor = drmlibv->version_major;
- drmlibminor = drmlibv->version_minor;
- drmFreeVersion(drmlibv);
- }
- }
-
- /* Check if the libdrm can handle falling back to loading based on name
- * if a busid string is passed.
- */
- openBusID = (drmlibmajor == 1 && drmlibminor >= 2) ? busID : NULL;
-
- tmp.drmFD = -1;
- sv.drm_di_major = 1;
- sv.drm_di_minor = 1;
- sv.drm_dd_major = -1;
-
- saveSv = sv;
- count = 10;
- while (count--) {
- tmp.drmFD = drmOpen(drmDriverName, openBusID);
-
- if (tmp.drmFD < 0) {
- DRIDrvMsg(-1, X_ERROR, "[drm] drmOpen failed.\n");
- goto out_err;
- }
-
- err = drmSetInterfaceVersion(tmp.drmFD, &sv);
-
- if (err != -EPERM)
- break;
-
- sv = saveSv;
- drmClose(tmp.drmFD);
- tmp.drmFD = -1;
- usleep(100000);
- }
-
- if (tmp.drmFD <= 0) {
- DRIDrvMsg(-1, X_ERROR, "[drm] DRM was busy with another master.\n");
- goto out_err;
- }
-
- if (!drmWasAvailable) {
- DRIDrvMsg(-1, X_INFO,
- "[drm] loaded kernel module for \"%s\" driver.\n",
- drmDriverName);
- }
-
- if (err != 0) {
- sv.drm_di_major = 1;
- sv.drm_di_minor = 0;
- }
-
- DRIDrvMsg(-1, X_INFO, "[drm] DRM interface version %d.%d\n",
- sv.drm_di_major, sv.drm_di_minor);
-
- if (sv.drm_di_major == 1 && sv.drm_di_minor >= 1)
- err = 0;
- else
- err = drmSetBusid(tmp.drmFD, busID);
-
- if (err) {
- DRIDrvMsg(-1, X_ERROR, "[drm] Could not set DRM device bus ID.\n");
- goto out_err;
- }
-
- /*
- * Create a lock-containing sarea.
- */
-
- if (drmAddMap( tmp.drmFD, 0, sAreaSize, DRM_SHM,
- DRM_CONTAINS_LOCK, &tmp.hLSAREA) < 0) {
- DRIDrvMsg(-1, X_INFO, "[drm] Could not create SAREA for DRM lock.\n");
- tmp.hLSAREA = 0;
- goto out_err;
- }
-
- if (drmMap( tmp.drmFD, tmp.hLSAREA, sAreaSize,
- (drmAddressPtr)(&tmp.pLSAREA)) < 0) {
- DRIDrvMsg(-1, X_INFO, "[drm] Mapping SAREA for DRM lock failed.\n");
- tmp.pLSAREA = NULL;
- goto out_err;
- }
-
- memset(tmp.pLSAREA, 0, sAreaSize);
-
- /*
- * Reserved contexts are handled by the first opened screen.
- */
-
- tmp.resOwner = NULL;
-
- if (!pDRIEntPriv)
- pDRIEntPriv = xnfcalloc(sizeof(*pDRIEntPriv), 1);
-
- if (!pDRIEntPriv) {
- DRIDrvMsg(-1, X_INFO, "[drm] Failed to allocate memory for "
- "DRM device.\n");
- goto out_err;
- }
- *pDRIEntPriv = tmp;
- xf86GetEntityPrivate((pScrn)->entityList[0],DRIEntPrivIndex)->ptr =
- pDRIEntPriv;
-
- DRIDrvMsg(-1, X_INFO, "[drm] DRM open master succeeded.\n");
- return TRUE;
-
- out_err:
-
- DRIOpenDRMCleanup(&tmp);
- return FALSE;
-}
-
-static void
-DRIClipNotifyAllDrawables(ScreenPtr pScreen);
-
-static void
-dri_crtc_notify(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIClipNotifyAllDrawables(pScreen);
- xf86_unwrap_crtc_notify(pScreen, pDRIPriv->xf86_crtc_notify);
- xf86_crtc_notify(pScreen);
- pDRIPriv->xf86_crtc_notify = xf86_wrap_crtc_notify(pScreen, dri_crtc_notify);
-}
-
-Bool
-DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
-{
- DRIScreenPrivPtr pDRIPriv;
- drm_context_t * reserved;
- int reserved_count;
- int i;
- DRIEntPrivPtr pDRIEntPriv;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- DRIContextFlags flags = 0;
- DRIContextPrivPtr pDRIContextPriv;
-
- /* If the DRI extension is disabled, do not initialize the DRI */
- if (noXFree86DRIExtension) {
- DRIDrvMsg(pScreen->myNum, X_WARNING,
- "Direct rendering has been disabled.\n");
- return FALSE;
- }
-
- if (!xf86VGAarbiterAllowDRI(pScreen)) {
- DRIDrvMsg(pScreen->myNum, X_WARNING,
- "Direct rendering is not supported when VGA arb is necessary for the device\n");
- return FALSE;
- }
-
-#ifdef PANORAMIX
- /*
- * If Xinerama is on, don't allow DRI to initialise. It won't be usable
- * anyway.
- */
- if (!noPanoramiXExtension) {
- DRIDrvMsg(pScreen->myNum, X_WARNING,
- "Direct rendering is not supported when Xinerama is enabled\n");
- return FALSE;
- }
-#endif
-
- if (!DRIOpenDRMMaster(pScrn, pDRIInfo->SAREASize,
- pDRIInfo->busIdString,
- pDRIInfo->drmDriverName))
- return FALSE;
-
- pDRIEntPriv = DRI_ENT_PRIV(pScrn);
-
- if (DRIGeneration != serverGeneration)
- DRIGeneration = serverGeneration;
-
- pDRIPriv = (DRIScreenPrivPtr) xcalloc(1, sizeof(DRIScreenPrivRec));
- if (!pDRIPriv) {
- dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL);
- return FALSE;
- }
-
- dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, pDRIPriv);
- pDRIPriv->drmFD = pDRIEntPriv->drmFD;
- pDRIPriv->directRenderingSupport = TRUE;
- pDRIPriv->pDriverInfo = pDRIInfo;
- pDRIPriv->nrWindows = 0;
- pDRIPriv->nrWindowsVisible = 0;
- pDRIPriv->fullscreen = NULL;
-
- pDRIPriv->createDummyCtx = pDRIInfo->createDummyCtx;
- pDRIPriv->createDummyCtxPriv = pDRIInfo->createDummyCtxPriv;
-
- pDRIPriv->grabbedDRILock = FALSE;
- pDRIPriv->drmSIGIOHandlerInstalled = FALSE;
- *pDRMFD = pDRIPriv->drmFD;
-
- if (pDRIEntPriv->sAreaGrabbed || pDRIInfo->allocSarea) {
-
- if (drmAddMap( pDRIPriv->drmFD,
- 0,
- pDRIPriv->pDriverInfo->SAREASize,
- DRM_SHM,
- 0,
- &pDRIPriv->hSAREA) < 0)
- {
- pDRIPriv->directRenderingSupport = FALSE;
- dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL);
- drmClose(pDRIPriv->drmFD);
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[drm] drmAddMap failed\n");
- return FALSE;
- }
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[drm] added %d byte SAREA at %p\n",
- pDRIPriv->pDriverInfo->SAREASize, pDRIPriv->hSAREA);
-
- /* Backwards compat. */
- if (drmMap( pDRIPriv->drmFD,
- pDRIPriv->hSAREA,
- pDRIPriv->pDriverInfo->SAREASize,
- (drmAddressPtr)(&pDRIPriv->pSAREA)) < 0)
- {
- pDRIPriv->directRenderingSupport = FALSE;
- dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL);
- drmClose(pDRIPriv->drmFD);
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[drm] drmMap failed\n");
- return FALSE;
- }
- DRIDrvMsg(pScreen->myNum, X_INFO, "[drm] mapped SAREA %p to %p\n",
- pDRIPriv->hSAREA, pDRIPriv->pSAREA);
- memset(pDRIPriv->pSAREA, 0, pDRIPriv->pDriverInfo->SAREASize);
- } else {
- DRIDrvMsg(pScreen->myNum, X_INFO, "[drm] Using the DRM lock "
- "SAREA also for drawables.\n");
- pDRIPriv->hSAREA = pDRIEntPriv->hLSAREA;
- pDRIPriv->pSAREA = (XF86DRISAREAPtr) pDRIEntPriv->pLSAREA;
- pDRIEntPriv->sAreaGrabbed = TRUE;
- }
-
- pDRIPriv->hLSAREA = pDRIEntPriv->hLSAREA;
- pDRIPriv->pLSAREA = pDRIEntPriv->pLSAREA;
-
- if (!pDRIPriv->pDriverInfo->dontMapFrameBuffer)
- {
- if (drmAddMap( pDRIPriv->drmFD,
- (drm_handle_t)pDRIPriv->pDriverInfo->frameBufferPhysicalAddress,
- pDRIPriv->pDriverInfo->frameBufferSize,
- DRM_FRAME_BUFFER,
- 0,
- &pDRIPriv->pDriverInfo->hFrameBuffer) < 0)
- {
- pDRIPriv->directRenderingSupport = FALSE;
- dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL);
- drmUnmap(pDRIPriv->pSAREA, pDRIPriv->pDriverInfo->SAREASize);
- drmClose(pDRIPriv->drmFD);
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[drm] drmAddMap failed\n");
- return FALSE;
- }
- DRIDrvMsg(pScreen->myNum, X_INFO, "[drm] framebuffer handle = %p\n",
- pDRIPriv->pDriverInfo->hFrameBuffer);
- } else {
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[drm] framebuffer mapped by ddx driver\n");
- }
-
- if (pDRIEntPriv->resOwner == NULL) {
- pDRIEntPriv->resOwner = pScreen;
-
- /* Add tags for reserved contexts */
- if ((reserved = drmGetReservedContextList(pDRIPriv->drmFD,
- &reserved_count))) {
- int i;
- void *tag;
-
- for (i = 0; i < reserved_count; i++) {
- tag = DRICreateContextPrivFromHandle(pScreen,
- reserved[i],
- DRI_CONTEXT_RESERVED);
- drmAddContextTag(pDRIPriv->drmFD, reserved[i], tag);
- }
- drmFreeReservedContextList(reserved);
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[drm] added %d reserved context%s for kernel\n",
- reserved_count, reserved_count > 1 ? "s" : "");
- }
- }
-
- /* validate max drawable table entry set by driver */
- if ((pDRIPriv->pDriverInfo->maxDrawableTableEntry <= 0) ||
- (pDRIPriv->pDriverInfo->maxDrawableTableEntry > SAREA_MAX_DRAWABLES)) {
- DRIDrvMsg(pScreen->myNum, X_ERROR,
- "Invalid max drawable table size set by driver: %d\n",
- pDRIPriv->pDriverInfo->maxDrawableTableEntry);
- }
-
- /* Initialize drawable tables (screen private and SAREA) */
- for( i=0; i < pDRIPriv->pDriverInfo->maxDrawableTableEntry; i++) {
- pDRIPriv->DRIDrawables[i] = NULL;
- pDRIPriv->pSAREA->drawableTable[i].stamp = 0;
- pDRIPriv->pSAREA->drawableTable[i].flags = 0;
- }
-
- pDRIPriv->pLockRefCount = &pDRIEntPriv->lockRefCount;
- pDRIPriv->pLockingContext = &pDRIEntPriv->lockingContext;
-
- if (!pDRIEntPriv->keepFDOpen)
- pDRIEntPriv->keepFDOpen = pDRIInfo->keepFDOpen;
-
- pDRIEntPriv->refCount++;
-
- /* Set up flags for DRICreateContextPriv */
- switch (pDRIInfo->driverSwapMethod) {
- case DRI_KERNEL_SWAP:
- flags = DRI_CONTEXT_2DONLY;
- break;
- case DRI_HIDE_X_CONTEXT:
- flags = DRI_CONTEXT_PRESERVED;
- break;
- }
-
- if (!(pDRIContextPriv = DRICreateContextPriv(pScreen,
- &pDRIPriv->myContext,
- flags))) {
- DRIDrvMsg(pScreen->myNum, X_ERROR,
- "failed to create server context\n");
- return FALSE;
- }
- pDRIPriv->myContextPriv = pDRIContextPriv;
-
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "X context handle = %p\n", pDRIPriv->myContext);
-
- /* Now that we have created the X server's context, we can grab the
- * hardware lock for the X server.
- */
- DRILock(pScreen, 0);
- pDRIPriv->grabbedDRILock = TRUE;
-
- /* pointers so that we can prevent memory leaks later */
- pDRIPriv->hiddenContextStore = NULL;
- pDRIPriv->partial3DContextStore = NULL;
-
- switch(pDRIInfo->driverSwapMethod) {
- case DRI_HIDE_X_CONTEXT:
- /* Server will handle 3D swaps, and hide 2D swaps from kernel.
- * Register server context as a preserved context.
- */
-
- /* allocate memory for hidden context store */
- pDRIPriv->hiddenContextStore
- = (void *)xcalloc(1, pDRIInfo->contextSize);
- if (!pDRIPriv->hiddenContextStore) {
- DRIDrvMsg(pScreen->myNum, X_ERROR,
- "failed to allocate hidden context\n");
- DRIDestroyContextPriv(pDRIContextPriv);
- return FALSE;
- }
-
- /* allocate memory for partial 3D context store */
- pDRIPriv->partial3DContextStore
- = (void *)xcalloc(1, pDRIInfo->contextSize);
- if (!pDRIPriv->partial3DContextStore) {
- DRIDrvMsg(pScreen->myNum, X_ERROR,
- "[DRI] failed to allocate partial 3D context\n");
- xfree(pDRIPriv->hiddenContextStore);
- DRIDestroyContextPriv(pDRIContextPriv);
- return FALSE;
- }
-
- /* save initial context store */
- if (pDRIInfo->SwapContext) {
- (*pDRIInfo->SwapContext)(
- pScreen,
- DRI_NO_SYNC,
- DRI_2D_CONTEXT,
- pDRIPriv->hiddenContextStore,
- DRI_NO_CONTEXT,
- NULL);
- }
- /* fall through */
-
- case DRI_SERVER_SWAP:
- /* For swap methods of DRI_SERVER_SWAP and DRI_HIDE_X_CONTEXT
- * setup signal handler for receiving swap requests from kernel
- */
- if (!(pDRIPriv->drmSIGIOHandlerInstalled =
- drmInstallSIGIOHandler(pDRIPriv->drmFD, DRISwapContext))) {
- DRIDrvMsg(pScreen->myNum, X_ERROR,
- "[drm] failed to setup DRM signal handler\n");
- if (pDRIPriv->hiddenContextStore)
- xfree(pDRIPriv->hiddenContextStore);
- if (pDRIPriv->partial3DContextStore)
- xfree(pDRIPriv->partial3DContextStore);
- DRIDestroyContextPriv(pDRIContextPriv);
- return FALSE;
- } else {
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[drm] installed DRM signal handler\n");
- }
-
- default:
- break;
- }
-
- return TRUE;
-}
-
-Bool
-DRIFinishScreenInit(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
-
- /* Wrap DRI support */
- if (pDRIInfo->wrap.ValidateTree) {
- pDRIPriv->wrap.ValidateTree = pScreen->ValidateTree;
- pScreen->ValidateTree = pDRIInfo->wrap.ValidateTree;
- }
- if (pDRIInfo->wrap.PostValidateTree) {
- pDRIPriv->wrap.PostValidateTree = pScreen->PostValidateTree;
- pScreen->PostValidateTree = pDRIInfo->wrap.PostValidateTree;
- }
- if (pDRIInfo->wrap.WindowExposures) {
- pDRIPriv->wrap.WindowExposures = pScreen->WindowExposures;
- pScreen->WindowExposures = pDRIInfo->wrap.WindowExposures;
- }
-
- pDRIPriv->DestroyWindow = pScreen->DestroyWindow;
- pScreen->DestroyWindow = DRIDestroyWindow;
-
- pDRIPriv->xf86_crtc_notify = xf86_wrap_crtc_notify(pScreen,
- dri_crtc_notify);
-
- if (pDRIInfo->wrap.CopyWindow) {
- pDRIPriv->wrap.CopyWindow = pScreen->CopyWindow;
- pScreen->CopyWindow = pDRIInfo->wrap.CopyWindow;
- }
- if (pDRIInfo->wrap.ClipNotify) {
- pDRIPriv->wrap.ClipNotify = pScreen->ClipNotify;
- pScreen->ClipNotify = pDRIInfo->wrap.ClipNotify;
- }
- if (pDRIInfo->wrap.AdjustFrame) {
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- pDRIPriv->wrap.AdjustFrame = pScrn->AdjustFrame;
- pScrn->AdjustFrame = pDRIInfo->wrap.AdjustFrame;
- }
- pDRIPriv->wrapped = TRUE;
-
- DRIDrvMsg(pScreen->myNum, X_INFO, "[DRI] installation complete\n");
-
- return TRUE;
-}
-
-void
-DRICloseScreen(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIInfoPtr pDRIInfo;
- drm_context_t * reserved;
- int reserved_count;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- DRIEntPrivPtr pDRIEntPriv = DRI_ENT_PRIV(pScrn);
- Bool closeMaster;
-
- if (pDRIPriv) {
-
- pDRIInfo = pDRIPriv->pDriverInfo;
-
- if (pDRIPriv->wrapped) {
- /* Unwrap DRI Functions */
- if (pDRIInfo->wrap.ValidateTree) {
- pScreen->ValidateTree = pDRIPriv->wrap.ValidateTree;
- pDRIPriv->wrap.ValidateTree = NULL;
- }
- if (pDRIInfo->wrap.PostValidateTree) {
- pScreen->PostValidateTree = pDRIPriv->wrap.PostValidateTree;
- pDRIPriv->wrap.PostValidateTree = NULL;
- }
- if (pDRIInfo->wrap.WindowExposures) {
- pScreen->WindowExposures = pDRIPriv->wrap.WindowExposures;
- pDRIPriv->wrap.WindowExposures = NULL;
- }
- if (pDRIPriv->DestroyWindow) {
- pScreen->DestroyWindow = pDRIPriv->DestroyWindow;
- pDRIPriv->DestroyWindow = NULL;
- }
-
- xf86_unwrap_crtc_notify(pScreen, pDRIPriv->xf86_crtc_notify);
-
- if (pDRIInfo->wrap.CopyWindow) {
- pScreen->CopyWindow = pDRIPriv->wrap.CopyWindow;
- pDRIPriv->wrap.CopyWindow = NULL;
- }
- if (pDRIInfo->wrap.ClipNotify) {
- pScreen->ClipNotify = pDRIPriv->wrap.ClipNotify;
- pDRIPriv->wrap.ClipNotify = NULL;
- }
- if (pDRIInfo->wrap.AdjustFrame) {
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- pScrn->AdjustFrame = pDRIPriv->wrap.AdjustFrame;
- pDRIPriv->wrap.AdjustFrame = NULL;
- }
-
- pDRIPriv->wrapped = FALSE;
- }
-
- if (pDRIPriv->drmSIGIOHandlerInstalled) {
- if (!drmRemoveSIGIOHandler(pDRIPriv->drmFD)) {
- DRIDrvMsg(pScreen->myNum, X_ERROR,
- "[drm] failed to remove DRM signal handler\n");
- }
- }
-
- if (pDRIPriv->dummyCtxPriv && pDRIPriv->createDummyCtx) {
- DRIDestroyDummyContext(pScreen, pDRIPriv->createDummyCtxPriv);
- }
-
- if (!DRIDestroyContextPriv(pDRIPriv->myContextPriv)) {
- DRIDrvMsg(pScreen->myNum, X_ERROR,
- "failed to destroy server context\n");
- }
-
- /* Remove tags for reserved contexts */
- if (pDRIEntPriv->resOwner == pScreen) {
- pDRIEntPriv->resOwner = NULL;
-
- if ((reserved = drmGetReservedContextList(pDRIPriv->drmFD,
- &reserved_count))) {
- int i;
-
- for (i = 0; i < reserved_count; i++) {
- DRIDestroyContextPriv(drmGetContextTag(pDRIPriv->drmFD,
- reserved[i]));
- }
- drmFreeReservedContextList(reserved);
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[drm] removed %d reserved context%s for kernel\n",
- reserved_count, reserved_count > 1 ? "s" : "");
- }
- }
-
- /* Make sure signals get unblocked etc. */
- drmUnlock(pDRIPriv->drmFD, pDRIPriv->myContext);
- pDRIPriv->pLockRefCount = NULL;
- closeMaster = (--pDRIEntPriv->refCount == 0) &&
- !pDRIEntPriv->keepFDOpen;
- if (closeMaster || pDRIPriv->hSAREA != pDRIEntPriv->hLSAREA) {
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[drm] unmapping %d bytes of SAREA %p at %p\n",
- pDRIInfo->SAREASize,
- pDRIPriv->hSAREA,
- pDRIPriv->pSAREA);
- if (drmUnmap(pDRIPriv->pSAREA, pDRIInfo->SAREASize)) {
- DRIDrvMsg(pScreen->myNum, X_ERROR,
- "[drm] unable to unmap %d bytes"
- " of SAREA %p at %p\n",
- pDRIInfo->SAREASize,
- pDRIPriv->hSAREA,
- pDRIPriv->pSAREA);
- }
- } else {
- pDRIEntPriv->sAreaGrabbed = FALSE;
- }
-
- if (closeMaster || (pDRIEntPriv->drmFD != pDRIPriv->drmFD)) {
- drmClose(pDRIPriv->drmFD);
- if (pDRIEntPriv->drmFD == pDRIPriv->drmFD) {
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[drm] Closed DRM master.\n");
- pDRIEntPriv->drmFD = -1;
- }
- }
-
- xfree(pDRIPriv);
- dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL);
- }
-}
-
-#define DRM_MSG_VERBOSITY 3
-
-static int dri_drm_debug_print(const char *format, va_list ap)
-{
- xf86VDrvMsgVerb(-1, X_NONE, DRM_MSG_VERBOSITY, format, ap);
- return 0;
-}
-
-static void dri_drm_get_perms(gid_t *group, mode_t *mode)
-{
- *group = xf86ConfigDRI.group;
- *mode = xf86ConfigDRI.mode;
-}
-
-drmServerInfo DRIDRMServerInfo = {
- dri_drm_debug_print,
- xf86LoadKernelModule,
- dri_drm_get_perms,
-};
-
-Bool
-DRIExtensionInit(void)
-{
- if (!DRIScreenPrivKey || DRIGeneration != serverGeneration) {
- return FALSE;
- }
-
- DRIDrawablePrivResType = CreateNewResourceType(DRIDrawablePrivDelete,
- "DRIDrawable");
- DRIContextPrivResType = CreateNewResourceType(DRIContextPrivDelete,
- "DRIContext");
-
- if (!DRIDrawablePrivResType || !DRIContextPrivResType)
- return FALSE;
-
- RegisterBlockAndWakeupHandlers(DRIBlockHandler, DRIWakeupHandler, NULL);
-
- return TRUE;
-}
-
-void
-DRIReset(void)
-{
- /*
- * This stub routine is called when the X Server recycles, resources
- * allocated by DRIExtensionInit need to be managed here.
- *
- * Currently this routine is a stub because all the interesting resources
- * are managed via the screen init process.
- */
-}
-
-Bool
-DRIQueryDirectRenderingCapable(ScreenPtr pScreen, Bool* isCapable)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if (pDRIPriv)
- *isCapable = pDRIPriv->directRenderingSupport;
- else
- *isCapable = FALSE;
-
- return TRUE;
-}
-
-Bool
-DRIOpenConnection(ScreenPtr pScreen, drm_handle_t * hSAREA, char **busIdString)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- *hSAREA = pDRIPriv->hSAREA;
- *busIdString = pDRIPriv->pDriverInfo->busIdString;
-
- return TRUE;
-}
-
-Bool
-DRIAuthConnection(ScreenPtr pScreen, drm_magic_t magic)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if (drmAuthMagic(pDRIPriv->drmFD, magic)) return FALSE;
- return TRUE;
-}
-
-Bool
-DRICloseConnection(ScreenPtr pScreen)
-{
- return TRUE;
-}
-
-Bool
-DRIGetClientDriverName(ScreenPtr pScreen,
- int *ddxDriverMajorVersion,
- int *ddxDriverMinorVersion,
- int *ddxDriverPatchVersion,
- char **clientDriverName)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- *ddxDriverMajorVersion = pDRIPriv->pDriverInfo->ddxDriverMajorVersion;
- *ddxDriverMinorVersion = pDRIPriv->pDriverInfo->ddxDriverMinorVersion;
- *ddxDriverPatchVersion = pDRIPriv->pDriverInfo->ddxDriverPatchVersion;
- *clientDriverName = pDRIPriv->pDriverInfo->clientDriverName;
-
- return TRUE;
-}
-
-/* DRICreateContextPriv and DRICreateContextPrivFromHandle are helper
- functions that layer on drmCreateContext and drmAddContextTag.
-
- DRICreateContextPriv always creates a kernel drm_context_t and then calls
- DRICreateContextPrivFromHandle to create a DRIContextPriv structure for
- DRI tracking. For the SIGIO handler, the drm_context_t is associated with
- DRIContextPrivPtr. Any special flags are stored in the DRIContextPriv
- area and are passed to the kernel (if necessary).
-
- DRICreateContextPriv returns a pointer to newly allocated
- DRIContextPriv, and returns the kernel drm_context_t in pHWContext. */
-
-DRIContextPrivPtr
-DRICreateContextPriv(ScreenPtr pScreen,
- drm_context_t * pHWContext,
- DRIContextFlags flags)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if (drmCreateContext(pDRIPriv->drmFD, pHWContext)) {
- return NULL;
- }
-
- return DRICreateContextPrivFromHandle(pScreen, *pHWContext, flags);
-}
-
-DRIContextPrivPtr
-DRICreateContextPrivFromHandle(ScreenPtr pScreen,
- drm_context_t hHWContext,
- DRIContextFlags flags)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIContextPrivPtr pDRIContextPriv;
- int contextPrivSize;
-
- contextPrivSize = sizeof(DRIContextPrivRec) +
- pDRIPriv->pDriverInfo->contextSize;
- if (!(pDRIContextPriv = xcalloc(1, contextPrivSize))) {
- return NULL;
- }
- pDRIContextPriv->pContextStore = (void *)(pDRIContextPriv + 1);
-
- drmAddContextTag(pDRIPriv->drmFD, hHWContext, pDRIContextPriv);
-
- pDRIContextPriv->hwContext = hHWContext;
- pDRIContextPriv->pScreen = pScreen;
- pDRIContextPriv->flags = flags;
- pDRIContextPriv->valid3D = FALSE;
-
- if (flags & DRI_CONTEXT_2DONLY) {
- if (drmSetContextFlags(pDRIPriv->drmFD,
- hHWContext,
- DRM_CONTEXT_2DONLY)) {
- DRIDrvMsg(pScreen->myNum, X_ERROR,
- "[drm] failed to set 2D context flag\n");
- DRIDestroyContextPriv(pDRIContextPriv);
- return NULL;
- }
- }
- if (flags & DRI_CONTEXT_PRESERVED) {
- if (drmSetContextFlags(pDRIPriv->drmFD,
- hHWContext,
- DRM_CONTEXT_PRESERVED)) {
- DRIDrvMsg(pScreen->myNum, X_ERROR,
- "[drm] failed to set preserved flag\n");
- DRIDestroyContextPriv(pDRIContextPriv);
- return NULL;
- }
- }
- return pDRIContextPriv;
-}
-
-Bool
-DRIDestroyContextPriv(DRIContextPrivPtr pDRIContextPriv)
-{
- DRIScreenPrivPtr pDRIPriv;
-
- if (!pDRIContextPriv) return TRUE;
-
- pDRIPriv = DRI_SCREEN_PRIV(pDRIContextPriv->pScreen);
-
- if (!(pDRIContextPriv->flags & DRI_CONTEXT_RESERVED)) {
- /* Don't delete reserved contexts from
- kernel area -- the kernel manages its
- reserved contexts itself. */
- if (drmDestroyContext(pDRIPriv->drmFD, pDRIContextPriv->hwContext))
- return FALSE;
- }
-
- /* Remove the tag last to prevent a race
- condition where the context has pending
- buffers. The context can't be re-used
- while in this thread, but buffers can be
- dispatched asynchronously. */
- drmDelContextTag(pDRIPriv->drmFD, pDRIContextPriv->hwContext);
- xfree(pDRIContextPriv);
- return TRUE;
-}
-
-static Bool
-DRICreateDummyContext(ScreenPtr pScreen, Bool needCtxPriv)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIContextPrivPtr pDRIContextPriv;
- void *contextStore;
-
- if (!(pDRIContextPriv =
- DRICreateContextPriv(pScreen,
- &pDRIPriv->pSAREA->dummy_context, 0))) {
- return FALSE;
- }
-
- contextStore = DRIGetContextStore(pDRIContextPriv);
- if (pDRIPriv->pDriverInfo->CreateContext && needCtxPriv) {
- if (!pDRIPriv->pDriverInfo->CreateContext(pScreen, NULL,
- pDRIPriv->pSAREA->dummy_context,
- NULL,
- (DRIContextType)(long)contextStore)) {
- DRIDestroyContextPriv(pDRIContextPriv);
- return FALSE;
- }
- }
-
- pDRIPriv->dummyCtxPriv = pDRIContextPriv;
- return TRUE;
-}
-
-static void
-DRIDestroyDummyContext(ScreenPtr pScreen, Bool hasCtxPriv)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIContextPrivPtr pDRIContextPriv = pDRIPriv->dummyCtxPriv;
- void *contextStore;
-
- if (!pDRIContextPriv) return;
- if (pDRIPriv->pDriverInfo->DestroyContext && hasCtxPriv) {
- contextStore = DRIGetContextStore(pDRIContextPriv);
- pDRIPriv->pDriverInfo->DestroyContext(pDRIContextPriv->pScreen,
- pDRIContextPriv->hwContext,
- (DRIContextType)(long)contextStore);
- }
-
- DRIDestroyContextPriv(pDRIPriv->dummyCtxPriv);
- pDRIPriv->dummyCtxPriv = NULL;
-}
-
-Bool
-DRICreateContext(ScreenPtr pScreen, VisualPtr visual,
- XID context, drm_context_t * pHWContext)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIContextPrivPtr pDRIContextPriv;
- void *contextStore;
-
- if (pDRIPriv->createDummyCtx && !pDRIPriv->dummyCtxPriv) {
- if (!DRICreateDummyContext(pScreen, pDRIPriv->createDummyCtxPriv)) {
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[drm] Could not create dummy context\n");
- return FALSE;
- }
- }
-
- if (!(pDRIContextPriv = DRICreateContextPriv(pScreen, pHWContext, 0))) {
- return FALSE;
- }
-
- contextStore = DRIGetContextStore(pDRIContextPriv);
- if (pDRIPriv->pDriverInfo->CreateContext) {
- if (!((*pDRIPriv->pDriverInfo->CreateContext)(pScreen, NULL,
- *pHWContext, NULL,
- (DRIContextType)(long)contextStore))) {
- DRIDestroyContextPriv(pDRIContextPriv);
- return FALSE;
- }
- }
-
- /* track this in case the client dies before cleanup */
- AddResource(context, DRIContextPrivResType, (pointer)pDRIContextPriv);
-
- return TRUE;
-}
-
-Bool
-DRIDestroyContext(ScreenPtr pScreen, XID context)
-{
- FreeResourceByType(context, DRIContextPrivResType, FALSE);
-
- return TRUE;
-}
-
-/* DRIContextPrivDelete is called by the resource manager. */
-Bool
-DRIContextPrivDelete(pointer pResource, XID id)
-{
- DRIContextPrivPtr pDRIContextPriv = (DRIContextPrivPtr)pResource;
- DRIScreenPrivPtr pDRIPriv;
- void *contextStore;
-
- pDRIPriv = DRI_SCREEN_PRIV(pDRIContextPriv->pScreen);
- if (pDRIPriv->pDriverInfo->DestroyContext) {
- contextStore = DRIGetContextStore(pDRIContextPriv);
- pDRIPriv->pDriverInfo->DestroyContext(pDRIContextPriv->pScreen,
- pDRIContextPriv->hwContext,
- (DRIContextType)(long)contextStore);
- }
- return DRIDestroyContextPriv(pDRIContextPriv);
-}
-
-
-/* This walks the drawable timestamp array and invalidates all of them
- * in the case of transition from private to shared backbuffers. It's
- * not necessary for correctness, because DRIClipNotify gets called in
- * time to prevent any conflict, but the transition from
- * shared->private is sometimes missed if we don't do this.
- */
-static void
-DRIClipNotifyAllDrawables(ScreenPtr pScreen)
-{
- int i;
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- for( i=0; i < pDRIPriv->pDriverInfo->maxDrawableTableEntry; i++) {
- pDRIPriv->pSAREA->drawableTable[i].stamp = DRIDrawableValidationStamp++;
- }
-}
-
-
-static void
-DRITransitionToSharedBuffers(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
-
- DRIClipNotifyAllDrawables( pScreen );
-
- if (pDRIInfo->TransitionSingleToMulti3D)
- pDRIInfo->TransitionSingleToMulti3D( pScreen );
-}
-
-
-static void
-DRITransitionToPrivateBuffers(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
-
- DRIClipNotifyAllDrawables( pScreen );
-
- if (pDRIInfo->TransitionMultiToSingle3D)
- pDRIInfo->TransitionMultiToSingle3D( pScreen );
-}
-
-
-static void
-DRITransitionTo3d(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
-
- DRIClipNotifyAllDrawables( pScreen );
-
- if (pDRIInfo->TransitionTo3d)
- pDRIInfo->TransitionTo3d( pScreen );
-}
-
-static void
-DRITransitionTo2d(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
-
- DRIClipNotifyAllDrawables( pScreen );
-
- if (pDRIInfo->TransitionTo2d)
- pDRIInfo->TransitionTo2d( pScreen );
-}
-
-
-static int
-DRIDCNTreeTraversal(WindowPtr pWin, pointer data)
-{
- DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
-
- if (pDRIDrawablePriv) {
- ScreenPtr pScreen = pWin->drawable.pScreen;
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if (REGION_NUM_RECTS(&pWin->clipList) > 0) {
- WindowPtr *pDRIWindows = (WindowPtr*)data;
- int i = 0;
-
- while (pDRIWindows[i])
- i++;
-
- pDRIWindows[i] = pWin;
-
- pDRIPriv->nrWalked++;
- }
-
- if (pDRIPriv->nrWindows == pDRIPriv->nrWalked)
- return WT_STOPWALKING;
- }
-
- return WT_WALKCHILDREN;
-}
-
-static void
-DRIDriverClipNotify(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if (pDRIPriv->pDriverInfo->ClipNotify) {
- WindowPtr *pDRIWindows = xcalloc(sizeof(WindowPtr), pDRIPriv->nrWindows);
- DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
-
- if (pDRIPriv->nrWindows > 0) {
- pDRIPriv->nrWalked = 0;
- TraverseTree(WindowTable[pScreen->myNum], DRIDCNTreeTraversal,
- (pointer)pDRIWindows);
- }
-
- pDRIInfo->ClipNotify(pScreen, pDRIWindows, pDRIPriv->nrWindows);
-
- xfree(pDRIWindows);
- }
-}
-
-static void
-DRIIncreaseNumberVisible(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- switch (++pDRIPriv->nrWindowsVisible) {
- case 1:
- DRITransitionTo3d( pScreen );
- break;
- case 2:
- DRITransitionToSharedBuffers( pScreen );
- break;
- default:
- break;
- }
-
- DRIDriverClipNotify(pScreen);
-}
-
-static void
-DRIDecreaseNumberVisible(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- switch (--pDRIPriv->nrWindowsVisible) {
- case 0:
- DRITransitionTo2d( pScreen );
- break;
- case 1:
- DRITransitionToPrivateBuffers( pScreen );
- break;
- default:
- break;
- }
-
- DRIDriverClipNotify(pScreen);
-}
-
-Bool
-DRICreateDrawable(ScreenPtr pScreen, ClientPtr client, DrawablePtr pDrawable,
- drm_drawable_t * hHWDrawable)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIDrawablePrivPtr pDRIDrawablePriv;
- WindowPtr pWin;
-
- if (pDrawable->type == DRAWABLE_WINDOW) {
- pWin = (WindowPtr)pDrawable;
- if ((pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin))) {
- pDRIDrawablePriv->refCount++;
-
- if (!pDRIDrawablePriv->hwDrawable) {
- drmCreateDrawable(pDRIPriv->drmFD, &pDRIDrawablePriv->hwDrawable);
- }
- }
- else {
- /* allocate a DRI Window Private record */
- if (!(pDRIDrawablePriv = xalloc(sizeof(DRIDrawablePrivRec)))) {
- return FALSE;
- }
-
- /* Only create a drm_drawable_t once */
- if (drmCreateDrawable(pDRIPriv->drmFD,
- &pDRIDrawablePriv->hwDrawable)) {
- xfree(pDRIDrawablePriv);
- return FALSE;
- }
-
- /* add it to the list of DRI drawables for this screen */
- pDRIDrawablePriv->pScreen = pScreen;
- pDRIDrawablePriv->refCount = 1;
- pDRIDrawablePriv->drawableIndex = -1;
- pDRIDrawablePriv->nrects = REGION_NUM_RECTS(&pWin->clipList);
-
- /* save private off of preallocated index */
- dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey,
- pDRIDrawablePriv);
- pDRIPriv->nrWindows++;
-
- if (pDRIDrawablePriv->nrects)
- DRIIncreaseNumberVisible(pScreen);
- }
-
- /* track this in case the client dies */
- AddResource(FakeClientID(client->index), DRIDrawablePrivResType,
- (pointer)(intptr_t)pDrawable->id);
-
- if (pDRIDrawablePriv->hwDrawable) {
- drmUpdateDrawableInfo(pDRIPriv->drmFD,
- pDRIDrawablePriv->hwDrawable,
- DRM_DRAWABLE_CLIPRECTS,
- REGION_NUM_RECTS(&pWin->clipList),
- REGION_RECTS(&pWin->clipList));
- *hHWDrawable = pDRIDrawablePriv->hwDrawable;
- }
- }
- else if (pDrawable->type != DRAWABLE_PIXMAP) { /* PBuffer */
- /* NOT_DONE */
- return FALSE;
- }
-
- return TRUE;
-}
-
-static void
-DRIDrawablePrivDestroy(WindowPtr pWin)
-{
- DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
- ScreenPtr pScreen;
- DRIScreenPrivPtr pDRIPriv;
-
- if (!pDRIDrawablePriv)
- return;
-
- pScreen = pWin->drawable.pScreen;
- pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if (pDRIDrawablePriv->drawableIndex != -1) {
- /* bump stamp to force outstanding 3D requests to resync */
- pDRIPriv->pSAREA->drawableTable[pDRIDrawablePriv->drawableIndex].stamp
- = DRIDrawableValidationStamp++;
-
- /* release drawable table entry */
- pDRIPriv->DRIDrawables[pDRIDrawablePriv->drawableIndex] = NULL;
- }
-
- pDRIPriv->nrWindows--;
-
- if (pDRIDrawablePriv->nrects)
- DRIDecreaseNumberVisible(pScreen);
-
- drmDestroyDrawable(pDRIPriv->drmFD, pDRIDrawablePriv->hwDrawable);
-
- xfree(pDRIDrawablePriv);
- dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey, NULL);
-}
-
-static Bool
-DRIDestroyDrawableCB(pointer value, XID id, pointer data)
-{
- if (value == data) {
- /* This calls back DRIDrawablePrivDelete which frees private area */
- FreeResourceByType(id, DRIDrawablePrivResType, FALSE);
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-Bool
-DRIDestroyDrawable(ScreenPtr pScreen, ClientPtr client, DrawablePtr pDrawable)
-{
- if (pDrawable->type == DRAWABLE_WINDOW) {
- LookupClientResourceComplex(client, DRIDrawablePrivResType,
- DRIDestroyDrawableCB,
- (pointer)(intptr_t)pDrawable->id);
- }
- else { /* pixmap (or for GLX 1.3, a PBuffer) */
- /* NOT_DONE */
- return FALSE;
- }
-
- return TRUE;
-}
-
-Bool
-DRIDrawablePrivDelete(pointer pResource, XID id)
-{
- WindowPtr pWin;
- int rc;
-
- /* For DRIDrawablePrivResType, the XID is the client's fake ID. The
- * important XID is the value in pResource. */
- id = (XID)(intptr_t)pResource;
- rc = dixLookupWindow(&pWin, id, serverClient, DixGetAttrAccess);
-
- if (rc == Success) {
- DRIDrawablePrivPtr pDRIDrwPriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
-
- if (!pDRIDrwPriv)
- return FALSE;
-
- if (--pDRIDrwPriv->refCount == 0)
- DRIDrawablePrivDestroy(pWin);
-
- return TRUE;
- }
- else { /* pixmap (or for GLX 1.3, a PBuffer) */
- /* NOT_DONE */
- return FALSE;
- }
-}
-
-Bool
-DRIGetDrawableInfo(ScreenPtr pScreen,
- DrawablePtr pDrawable,
- unsigned int* index,
- unsigned int* stamp,
- int* X,
- int* Y,
- int* W,
- int* H,
- int* numClipRects,
- drm_clip_rect_t ** pClipRects,
- int* backX,
- int* backY,
- int* numBackClipRects,
- drm_clip_rect_t ** pBackClipRects)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIDrawablePrivPtr pDRIDrawablePriv, pOldDrawPriv;
- WindowPtr pWin, pOldWin;
- int i;
-
-#if 0
- printf("maxDrawableTableEntry = %d\n", pDRIPriv->pDriverInfo->maxDrawableTableEntry);
-#endif
-
- if (pDrawable->type == DRAWABLE_WINDOW) {
- pWin = (WindowPtr)pDrawable;
- if ((pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin))) {
-
- /* Manage drawable table */
- if (pDRIDrawablePriv->drawableIndex == -1) { /* load SAREA table */
-
- /* Search table for empty entry */
- i = 0;
- while (i < pDRIPriv->pDriverInfo->maxDrawableTableEntry) {
- if (!(pDRIPriv->DRIDrawables[i])) {
- pDRIPriv->DRIDrawables[i] = pDrawable;
- pDRIDrawablePriv->drawableIndex = i;
- pDRIPriv->pSAREA->drawableTable[i].stamp =
- DRIDrawableValidationStamp++;
- break;
- }
- i++;
- }
-
- /* Search table for oldest entry */
- if (i == pDRIPriv->pDriverInfo->maxDrawableTableEntry) {
- unsigned int oldestStamp = ~0;
- int oldestIndex = 0;
- i = pDRIPriv->pDriverInfo->maxDrawableTableEntry;
- while (i--) {
- if (pDRIPriv->pSAREA->drawableTable[i].stamp <
- oldestStamp) {
- oldestIndex = i;
- oldestStamp =
- pDRIPriv->pSAREA->drawableTable[i].stamp;
- }
- }
- pDRIDrawablePriv->drawableIndex = oldestIndex;
-
- /* release oldest drawable table entry */
- pOldWin = (WindowPtr)pDRIPriv->DRIDrawables[oldestIndex];
- pOldDrawPriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pOldWin);
- pOldDrawPriv->drawableIndex = -1;
-
- /* claim drawable table entry */
- pDRIPriv->DRIDrawables[oldestIndex] = pDrawable;
-
- /* validate SAREA entry */
- pDRIPriv->pSAREA->drawableTable[oldestIndex].stamp =
- DRIDrawableValidationStamp++;
-
- /* check for stamp wrap around */
- if (oldestStamp > DRIDrawableValidationStamp) {
-
- /* walk SAREA table and invalidate all drawables */
- for( i=0;
- i < pDRIPriv->pDriverInfo->maxDrawableTableEntry;
- i++) {
- pDRIPriv->pSAREA->drawableTable[i].stamp =
- DRIDrawableValidationStamp++;
- }
- }
- }
-
- /* If the driver wants to be notified when the index is
- * set for a drawable, let it know now.
- */
- if (pDRIPriv->pDriverInfo->SetDrawableIndex)
- pDRIPriv->pDriverInfo->SetDrawableIndex(pWin,
- pDRIDrawablePriv->drawableIndex);
-
- /* reinit drawable ID if window is visible */
- if ((pWin->viewable) &&
- (pDRIPriv->pDriverInfo->bufferRequests != DRI_NO_WINDOWS))
- {
- (*pDRIPriv->pDriverInfo->InitBuffers)(pWin,
- &pWin->clipList, pDRIDrawablePriv->drawableIndex);
- }
- }
-
- *index = pDRIDrawablePriv->drawableIndex;
- *stamp = pDRIPriv->pSAREA->drawableTable[*index].stamp;
- *X = (int)(pWin->drawable.x);
- *Y = (int)(pWin->drawable.y);
-#if 0
- *W = (int)(pWin->winSize.extents.x2 - pWin->winSize.extents.x1);
- *H = (int)(pWin->winSize.extents.y2 - pWin->winSize.extents.y1);
-#endif
- *W = (int)(pWin->drawable.width);
- *H = (int)(pWin->drawable.height);
- *numClipRects = REGION_NUM_RECTS(&pWin->clipList);
- *pClipRects = (drm_clip_rect_t *)REGION_RECTS(&pWin->clipList);
-
- if (!*numClipRects && pDRIPriv->fullscreen) {
- /* use fake full-screen clip rect */
- pDRIPriv->fullscreen_rect.x1 = *X;
- pDRIPriv->fullscreen_rect.y1 = *Y;
- pDRIPriv->fullscreen_rect.x2 = *X + *W;
- pDRIPriv->fullscreen_rect.y2 = *Y + *H;
-
- *numClipRects = 1;
- *pClipRects = &pDRIPriv->fullscreen_rect;
- }
-
- *backX = *X;
- *backY = *Y;
-
- if (pDRIPriv->nrWindowsVisible == 1 && *numClipRects) {
- /* Use a single cliprect. */
-
- int x0 = *X;
- int y0 = *Y;
- int x1 = x0 + *W;
- int y1 = y0 + *H;
-
- if (x0 < 0) x0 = 0;
- if (y0 < 0) y0 = 0;
- if (x1 > pScreen->width) x1 = pScreen->width;
- if (y1 > pScreen->height) y1 = pScreen->height;
-
- if (y0 >= y1 || x0 >= x1) {
- *numBackClipRects = 0;
- *pBackClipRects = NULL;
- } else {
- pDRIPriv->private_buffer_rect.x1 = x0;
- pDRIPriv->private_buffer_rect.y1 = y0;
- pDRIPriv->private_buffer_rect.x2 = x1;
- pDRIPriv->private_buffer_rect.y2 = y1;
-
- *numBackClipRects = 1;
- *pBackClipRects = &(pDRIPriv->private_buffer_rect);
- }
- } else {
- /* Use the frontbuffer cliprects for back buffers. */
- *numBackClipRects = 0;
- *pBackClipRects = 0;
- }
- }
- else {
- /* Not a DRIDrawable */
- return FALSE;
- }
- }
- else { /* pixmap (or for GLX 1.3, a PBuffer) */
- /* NOT_DONE */
- return FALSE;
- }
-
- return TRUE;
-}
-
-Bool
-DRIGetDeviceInfo(ScreenPtr pScreen,
- drm_handle_t * hFrameBuffer,
- int* fbOrigin,
- int* fbSize,
- int* fbStride,
- int* devPrivateSize,
- void** pDevPrivate)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- *hFrameBuffer = pDRIPriv->pDriverInfo->hFrameBuffer;
- *fbOrigin = 0;
- *fbSize = pDRIPriv->pDriverInfo->frameBufferSize;
- *fbStride = pDRIPriv->pDriverInfo->frameBufferStride;
- *devPrivateSize = pDRIPriv->pDriverInfo->devPrivateSize;
- *pDevPrivate = pDRIPriv->pDriverInfo->devPrivate;
-
- return TRUE;
-}
-
-DRIInfoPtr
-DRICreateInfoRec(void)
-{
- DRIInfoPtr inforec = (DRIInfoPtr)xcalloc(1, sizeof(DRIInfoRec));
- if (!inforec) return NULL;
-
- /* Initialize defaults */
- inforec->busIdString = NULL;
-
- /* Wrapped function defaults */
- inforec->wrap.WakeupHandler = DRIDoWakeupHandler;
- inforec->wrap.BlockHandler = DRIDoBlockHandler;
- inforec->wrap.WindowExposures = DRIWindowExposures;
- inforec->wrap.CopyWindow = DRICopyWindow;
- inforec->wrap.ValidateTree = DRIValidateTree;
- inforec->wrap.PostValidateTree = DRIPostValidateTree;
- inforec->wrap.ClipNotify = DRIClipNotify;
- inforec->wrap.AdjustFrame = DRIAdjustFrame;
-
- inforec->TransitionTo2d = 0;
- inforec->TransitionTo3d = 0;
- inforec->SetDrawableIndex = 0;
-
- return inforec;
-}
-
-void
-DRIDestroyInfoRec(DRIInfoPtr DRIInfo)
-{
- if (DRIInfo->busIdString) xfree(DRIInfo->busIdString);
- xfree((char*)DRIInfo);
-}
-
-
-void
-DRIWakeupHandler(pointer wakeupData, int result, pointer pReadmask)
-{
- int i;
-
- for (i = 0; i < screenInfo.numScreens; i++) {
- ScreenPtr pScreen = screenInfo.screens[i];
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if (pDRIPriv &&
- pDRIPriv->pDriverInfo->wrap.WakeupHandler)
- (*pDRIPriv->pDriverInfo->wrap.WakeupHandler)(i, wakeupData,
- result, pReadmask);
- }
-}
-
-void
-DRIBlockHandler(pointer blockData, OSTimePtr pTimeout, pointer pReadmask)
-{
- int i;
-
- for (i = 0; i < screenInfo.numScreens; i++) {
- ScreenPtr pScreen = screenInfo.screens[i];
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if (pDRIPriv &&
- pDRIPriv->pDriverInfo->wrap.BlockHandler)
- (*pDRIPriv->pDriverInfo->wrap.BlockHandler)(i, blockData,
- pTimeout, pReadmask);
- }
-}
-
-void
-DRIDoWakeupHandler(int screenNum, pointer wakeupData,
- unsigned long result, pointer pReadmask)
-{
- ScreenPtr pScreen = screenInfo.screens[screenNum];
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- DRILock(pScreen, 0);
- if (pDRIPriv->pDriverInfo->driverSwapMethod == DRI_HIDE_X_CONTEXT) {
- /* hide X context by swapping 2D component here */
- (*pDRIPriv->pDriverInfo->SwapContext)(pScreen,
- DRI_3D_SYNC,
- DRI_2D_CONTEXT,
- pDRIPriv->partial3DContextStore,
- DRI_2D_CONTEXT,
- pDRIPriv->hiddenContextStore);
- }
-}
-
-void
-DRIDoBlockHandler(int screenNum, pointer blockData,
- pointer pTimeout, pointer pReadmask)
-{
- ScreenPtr pScreen = screenInfo.screens[screenNum];
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if (pDRIPriv->pDriverInfo->driverSwapMethod == DRI_HIDE_X_CONTEXT) {
- /* hide X context by swapping 2D component here */
- (*pDRIPriv->pDriverInfo->SwapContext)(pScreen,
- DRI_2D_SYNC,
- DRI_NO_CONTEXT,
- NULL,
- DRI_2D_CONTEXT,
- pDRIPriv->partial3DContextStore);
- }
-
- if (pDRIPriv->windowsTouched)
- DRM_SPINUNLOCK(&pDRIPriv->pSAREA->drawable_lock, 1);
- pDRIPriv->windowsTouched = FALSE;
-
- DRIUnlock(pScreen);
-}
-
-void
-DRISwapContext(int drmFD, void *oldctx, void *newctx)
-{
- DRIContextPrivPtr oldContext = (DRIContextPrivPtr)oldctx;
- DRIContextPrivPtr newContext = (DRIContextPrivPtr)newctx;
- ScreenPtr pScreen = newContext->pScreen;
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- void* oldContextStore = NULL;
- DRIContextType oldContextType;
- void* newContextStore = NULL;
- DRIContextType newContextType;
- DRISyncType syncType;
-#ifdef DEBUG
- static int count = 0;
-
- if (!newContext) {
- DRIDrvMsg(pScreen->myNum, X_ERROR,
- "[DRI] Context Switch Error: oldContext=%x, newContext=%x\n",
- oldContext, newContext);
- return;
- }
-
- /* usefull for debugging, just print out after n context switches */
- if (!count || !(count % 1)) {
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[DRI] Context switch %5d from %p/0x%08x (%d)\n",
- count,
- oldContext,
- oldContext ? oldContext->flags : 0,
- oldContext ? oldContext->hwContext : -1);
- DRIDrvMsg(pScreen->myNum, X_INFO,
- "[DRI] Context switch %5d to %p/0x%08x (%d)\n",
- count,
- newContext,
- newContext ? newContext->flags : 0,
- newContext ? newContext->hwContext : -1);
- }
- ++count;
-#endif
-
- if (!pDRIPriv->pDriverInfo->SwapContext) {
- DRIDrvMsg(pScreen->myNum, X_ERROR,
- "[DRI] DDX driver missing context swap call back\n");
- return;
- }
-
- if (pDRIPriv->pDriverInfo->driverSwapMethod == DRI_HIDE_X_CONTEXT) {
-
- /* only 3D contexts are swapped in this case */
- if (oldContext) {
- oldContextStore = DRIGetContextStore(oldContext);
- oldContext->valid3D = TRUE;
- oldContextType = DRI_3D_CONTEXT;
- } else {
- oldContextType = DRI_NO_CONTEXT;
- }
- newContextStore = DRIGetContextStore(newContext);
- if ((newContext->valid3D) &&
- (newContext->hwContext != pDRIPriv->myContext)) {
- newContextType = DRI_3D_CONTEXT;
- }
- else {
- newContextType = DRI_2D_CONTEXT;
- }
- syncType = DRI_3D_SYNC;
- }
- else /* default: driverSwapMethod == DRI_SERVER_SWAP */ {
-
- /* optimize 2D context swaps */
-
- if (newContext->flags & DRI_CONTEXT_2DONLY) {
- /* go from 3D context to 2D context and only save 2D
- * subset of 3D state
- */
- oldContextStore = DRIGetContextStore(oldContext);
- oldContextType = DRI_2D_CONTEXT;
- newContextStore = DRIGetContextStore(newContext);
- newContextType = DRI_2D_CONTEXT;
- syncType = DRI_3D_SYNC;
- pDRIPriv->lastPartial3DContext = oldContext;
- }
- else if (oldContext->flags & DRI_CONTEXT_2DONLY) {
- if (pDRIPriv->lastPartial3DContext == newContext) {
- /* go from 2D context back to previous 3D context and
- * only restore 2D subset of previous 3D state
- */
- oldContextStore = DRIGetContextStore(oldContext);
- oldContextType = DRI_2D_CONTEXT;
- newContextStore = DRIGetContextStore(newContext);
- newContextType = DRI_2D_CONTEXT;
- syncType = DRI_2D_SYNC;
- }
- else {
- /* go from 2D context to a different 3D context */
-
- /* call DDX driver to do partial restore */
- oldContextStore = DRIGetContextStore(oldContext);
- newContextStore =
- DRIGetContextStore(pDRIPriv->lastPartial3DContext);
- (*pDRIPriv->pDriverInfo->SwapContext)(pScreen,
- DRI_2D_SYNC,
- DRI_2D_CONTEXT,
- oldContextStore,
- DRI_2D_CONTEXT,
- newContextStore);
-
- /* now setup for a complete 3D swap */
- oldContextStore = newContextStore;
- oldContext->valid3D = TRUE;
- oldContextType = DRI_3D_CONTEXT;
- newContextStore = DRIGetContextStore(newContext);
- if ((newContext->valid3D) &&
- (newContext->hwContext != pDRIPriv->myContext)) {
- newContextType = DRI_3D_CONTEXT;
- }
- else {
- newContextType = DRI_2D_CONTEXT;
- }
- syncType = DRI_NO_SYNC;
- }
- }
- else {
- /* now setup for a complete 3D swap */
- oldContextStore = newContextStore;
- oldContext->valid3D = TRUE;
- oldContextType = DRI_3D_CONTEXT;
- newContextStore = DRIGetContextStore(newContext);
- if ((newContext->valid3D) &&
- (newContext->hwContext != pDRIPriv->myContext)) {
- newContextType = DRI_3D_CONTEXT;
- }
- else {
- newContextType = DRI_2D_CONTEXT;
- }
- syncType = DRI_3D_SYNC;
- }
- }
-
- /* call DDX driver to perform the swap */
- (*pDRIPriv->pDriverInfo->SwapContext)(pScreen,
- syncType,
- oldContextType,
- oldContextStore,
- newContextType,
- newContextStore);
-}
-
-void*
-DRIGetContextStore(DRIContextPrivPtr context)
-{
- return((void *)context->pContextStore);
-}
-
-void
-DRIWindowExposures(WindowPtr pWin, RegionPtr prgn, RegionPtr bsreg)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
-
- if(pDRIDrawablePriv) {
- (*pDRIPriv->pDriverInfo->InitBuffers)(pWin, prgn,
- pDRIDrawablePriv->drawableIndex);
- }
-
- /* call lower wrapped functions */
- if (pDRIPriv && pDRIPriv->wrap.WindowExposures) {
-
- /* unwrap */
- pScreen->WindowExposures = pDRIPriv->wrap.WindowExposures;
-
- /* call lower layers */
- (*pScreen->WindowExposures)(pWin, prgn, bsreg);
-
- /* rewrap */
- pDRIPriv->wrap.WindowExposures = pScreen->WindowExposures;
- pScreen->WindowExposures = DRIWindowExposures;
- }
-}
-
-
-static int
-DRITreeTraversal(WindowPtr pWin, pointer data)
-{
- DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
-
- if(pDRIDrawablePriv) {
- ScreenPtr pScreen = pWin->drawable.pScreen;
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if(REGION_NUM_RECTS(&(pWin->clipList)) > 0) {
- RegionPtr reg = (RegionPtr)data;
-
- REGION_UNION(pScreen, reg, reg, &(pWin->clipList));
- pDRIPriv->nrWalked++;
- }
-
- if(pDRIPriv->nrWindows == pDRIPriv->nrWalked)
- return WT_STOPWALKING;
- }
- return WT_WALKCHILDREN;
-}
-
-Bool
-DRIDestroyWindow(WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- Bool retval = TRUE;
-
- DRIDrawablePrivDestroy(pWin);
-
- /* call lower wrapped functions */
- if(pDRIPriv->DestroyWindow) {
- /* unwrap */
- pScreen->DestroyWindow = pDRIPriv->DestroyWindow;
-
- /* call lower layers */
- retval = (*pScreen->DestroyWindow)(pWin);
-
- /* rewrap */
- pDRIPriv->DestroyWindow = pScreen->DestroyWindow;
- pScreen->DestroyWindow = DRIDestroyWindow;
- }
-
- return retval;
-}
-
-void
-DRICopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if(!pDRIPriv) return;
-
- if(pDRIPriv->nrWindowsVisible > 0) {
- RegionRec reg;
-
- REGION_NULL(pScreen, &reg);
- pDRIPriv->nrWalked = 0;
- TraverseTree(pWin, DRITreeTraversal, (pointer)(&reg));
-
- if(REGION_NOTEMPTY(pScreen, &reg)) {
- REGION_TRANSLATE(pScreen, &reg, ptOldOrg.x - pWin->drawable.x,
- ptOldOrg.y - pWin->drawable.y);
- REGION_INTERSECT(pScreen, &reg, &reg, prgnSrc);
-
- /* The MoveBuffers interface is not ideal */
- (*pDRIPriv->pDriverInfo->MoveBuffers)(pWin, ptOldOrg, &reg,
- pDRIPriv->pDriverInfo->ddxDrawableTableEntry);
- }
-
- REGION_UNINIT(pScreen, &reg);
- }
-
- /* call lower wrapped functions */
- if(pDRIPriv->wrap.CopyWindow) {
- /* unwrap */
- pScreen->CopyWindow = pDRIPriv->wrap.CopyWindow;
-
- /* call lower layers */
- (*pScreen->CopyWindow)(pWin, ptOldOrg, prgnSrc);
-
- /* rewrap */
- pDRIPriv->wrap.CopyWindow = pScreen->CopyWindow;
- pScreen->CopyWindow = DRICopyWindow;
- }
-}
-
-static void
-DRIGetSecs(long *secs, long *usecs)
-{
- struct timeval tv;
-
- gettimeofday(&tv, NULL);
-
- *secs = tv.tv_sec;
- *usecs = tv.tv_usec;
-}
-
-static unsigned long
-DRIComputeMilliSeconds(unsigned long s_secs, unsigned long s_usecs,
- unsigned long f_secs, unsigned long f_usecs)
-{
- if (f_usecs < s_usecs) {
- --f_secs;
- f_usecs += 1000000;
- }
- return (f_secs - s_secs) * 1000 + (f_usecs - s_usecs) / 1000;
-}
-
-static void
-DRISpinLockTimeout(drmLock *lock, int val, unsigned long timeout /* in mS */)
-{
- int count = 10000;
-#if !defined(__alpha__) && !defined(__powerpc__)
- char ret;
-#else
- int ret;
-#endif
- long s_secs, s_usecs;
- long f_secs, f_usecs;
- long msecs;
- long prev = 0;
-
- DRIGetSecs(&s_secs, &s_usecs);
-
- do {
- DRM_SPINLOCK_COUNT(lock, val, count, ret);
- if (!ret) return; /* Got lock */
- DRIGetSecs(&f_secs, &f_usecs);
- msecs = DRIComputeMilliSeconds(s_secs, s_usecs, f_secs, f_usecs);
- if (msecs - prev < 250) count *= 2; /* Not more than 0.5S */
- } while (msecs < timeout);
-
- /* Didn't get lock, so take it. The worst
- that can happen is that there is some
- garbage written to the wrong part of the
- framebuffer that a refresh will repair.
- That's undesirable, but better than
- locking the server. This should be a
- very rare event. */
- DRM_SPINLOCK_TAKE(lock, val);
-}
-
-static void
-DRILockTree(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if(!pDRIPriv) return;
-
- /* Restore the last known 3D context if the X context is hidden */
- if (pDRIPriv->pDriverInfo->driverSwapMethod == DRI_HIDE_X_CONTEXT) {
- (*pDRIPriv->pDriverInfo->SwapContext)(pScreen,
- DRI_2D_SYNC,
- DRI_NO_CONTEXT,
- NULL,
- DRI_2D_CONTEXT,
- pDRIPriv->partial3DContextStore);
- }
-
- /* Call kernel to release lock */
- DRIUnlock(pScreen);
-
- /* Grab drawable spin lock: a time out between 10 and 30 seconds is
- appropriate, since this should never time out except in the case of
- client death while the lock is being held. The timeout must be
- greater than any reasonable rendering time. */
- DRISpinLockTimeout(&pDRIPriv->pSAREA->drawable_lock, 1, 10000); /*10 secs*/
-
- /* Call kernel flush outstanding buffers and relock */
- DRILock(pScreen, DRM_LOCK_QUIESCENT|DRM_LOCK_FLUSH_ALL);
-
- /* Switch back to our 2D context if the X context is hidden */
- if (pDRIPriv->pDriverInfo->driverSwapMethod == DRI_HIDE_X_CONTEXT) {
- /* hide X context by swapping 2D component here */
- (*pDRIPriv->pDriverInfo->SwapContext)(pScreen,
- DRI_3D_SYNC,
- DRI_2D_CONTEXT,
- pDRIPriv->partial3DContextStore,
- DRI_2D_CONTEXT,
- pDRIPriv->hiddenContextStore);
- }
-}
-
-int
-DRIValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind)
-{
- ScreenPtr pScreen = pParent->drawable.pScreen;
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- int returnValue = 1; /* always return 1, not checked by dix/window.c */
-
- if(!pDRIPriv) return returnValue;
-
- /* call lower wrapped functions */
- if(pDRIPriv->wrap.ValidateTree) {
- /* unwrap */
- pScreen->ValidateTree = pDRIPriv->wrap.ValidateTree;
-
- /* call lower layers */
- returnValue = (*pScreen->ValidateTree)(pParent, pChild, kind);
-
- /* rewrap */
- pDRIPriv->wrap.ValidateTree = pScreen->ValidateTree;
- pScreen->ValidateTree = DRIValidateTree;
- }
-
- return returnValue;
-}
-
-void
-DRIPostValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind)
-{
- ScreenPtr pScreen;
- DRIScreenPrivPtr pDRIPriv;
-
- if (pParent) {
- pScreen = pParent->drawable.pScreen;
- } else {
- pScreen = pChild->drawable.pScreen;
- }
- if(!(pDRIPriv = DRI_SCREEN_PRIV(pScreen))) return;
-
- if (pDRIPriv->wrap.PostValidateTree) {
- /* unwrap */
- pScreen->PostValidateTree = pDRIPriv->wrap.PostValidateTree;
-
- /* call lower layers */
- (*pScreen->PostValidateTree)(pParent, pChild, kind);
-
- /* rewrap */
- pDRIPriv->wrap.PostValidateTree = pScreen->PostValidateTree;
- pScreen->PostValidateTree = DRIPostValidateTree;
- }
-}
-
-void
-DRIClipNotify(WindowPtr pWin, int dx, int dy)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIDrawablePrivPtr pDRIDrawablePriv;
-
- if(!pDRIPriv) return;
-
- if ((pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin))) {
- int nrects = REGION_NUM_RECTS(&pWin->clipList);
-
- if(!pDRIPriv->windowsTouched) {
- DRILockTree(pScreen);
- pDRIPriv->windowsTouched = TRUE;
- }
-
- if (nrects && !pDRIDrawablePriv->nrects)
- DRIIncreaseNumberVisible(pScreen);
- else if (!nrects && pDRIDrawablePriv->nrects)
- DRIDecreaseNumberVisible(pScreen);
- else
- DRIDriverClipNotify(pScreen);
-
- pDRIDrawablePriv->nrects = nrects;
-
- pDRIPriv->pSAREA->drawableTable[pDRIDrawablePriv->drawableIndex].stamp
- = DRIDrawableValidationStamp++;
-
- drmUpdateDrawableInfo(pDRIPriv->drmFD, pDRIDrawablePriv->hwDrawable,
- DRM_DRAWABLE_CLIPRECTS,
- nrects, REGION_RECTS(&pWin->clipList));
- }
-
- /* call lower wrapped functions */
- if(pDRIPriv->wrap.ClipNotify) {
-
- /* unwrap */
- pScreen->ClipNotify = pDRIPriv->wrap.ClipNotify;
-
- /* call lower layers */
- (*pScreen->ClipNotify)(pWin, dx, dy);
-
- /* rewrap */
- pDRIPriv->wrap.ClipNotify = pScreen->ClipNotify;
- pScreen->ClipNotify = DRIClipNotify;
- }
-}
-
-CARD32
-DRIGetDrawableIndex(WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
- CARD32 index;
-
- if (pDRIDrawablePriv) {
- index = pDRIDrawablePriv->drawableIndex;
- }
- else {
- index = pDRIPriv->pDriverInfo->ddxDrawableTableEntry;
- }
-
- return index;
-}
-
-unsigned int
-DRIGetDrawableStamp(ScreenPtr pScreen, CARD32 drawable_index)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- return pDRIPriv->pSAREA->drawableTable[drawable_index].stamp;
-}
-
-
-void
-DRIPrintDrawableLock(ScreenPtr pScreen, char *msg)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- ErrorF("%s: %d\n", msg, pDRIPriv->pSAREA->drawable_lock.lock);
-}
-
-void
-DRILock(ScreenPtr pScreen, int flags)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if(!pDRIPriv || !pDRIPriv->pLockRefCount) return;
-
- if (!*pDRIPriv->pLockRefCount) {
- DRM_LOCK(pDRIPriv->drmFD, pDRIPriv->pLSAREA, pDRIPriv->myContext, flags);
- *pDRIPriv->pLockingContext = pDRIPriv->myContext;
- } else if (*pDRIPriv->pLockingContext != pDRIPriv->myContext) {
- DRIDrvMsg(pScreen->myNum, X_ERROR,
- "[DRI] Locking deadlock.\n"
- "\tAlready locked with context %d,\n"
- "\ttrying to lock with context %d.\n",
- pDRIPriv->pLockingContext,
- pDRIPriv->myContext);
- }
- (*pDRIPriv->pLockRefCount)++;
-}
-
-void
-DRIUnlock(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if(!pDRIPriv || !pDRIPriv->pLockRefCount) return;
-
- if (*pDRIPriv->pLockRefCount > 0) {
- if (pDRIPriv->myContext != *pDRIPriv->pLockingContext) {
- DRIDrvMsg(pScreen->myNum, X_ERROR,
- "[DRI] Unlocking inconsistency:\n"
- "\tContext %d trying to unlock lock held by context %d\n",
- pDRIPriv->pLockingContext,
- pDRIPriv->myContext);
- }
- (*pDRIPriv->pLockRefCount)--;
- } else {
- DRIDrvMsg(pScreen->myNum, X_ERROR,
- "DRIUnlock called when not locked.\n");
- return;
- }
- if (! *pDRIPriv->pLockRefCount)
- DRM_UNLOCK(pDRIPriv->drmFD, pDRIPriv->pLSAREA, pDRIPriv->myContext);
-}
-
-void *
-DRIGetSAREAPrivate(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- if (!pDRIPriv) return 0;
-
- return (void *)(((char*)pDRIPriv->pSAREA)+sizeof(XF86DRISAREARec));
-}
-
-drm_context_t
-DRIGetContext(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- if (!pDRIPriv) return 0;
-
- return pDRIPriv->myContext;
-}
-
-void
-DRIGetTexOffsetFuncs(ScreenPtr pScreen,
- DRITexOffsetStartProcPtr *texOffsetStartFunc,
- DRITexOffsetFinishProcPtr *texOffsetFinishFunc)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if (!pDRIPriv) return;
-
- *texOffsetStartFunc = pDRIPriv->pDriverInfo->texOffsetStart;
- *texOffsetFinishFunc = pDRIPriv->pDriverInfo->texOffsetFinish;
-}
-
-/* This lets get at the unwrapped functions so that they can correctly
- * call the lowerlevel functions, and choose whether they will be
- * called at every level of recursion (eg in validatetree).
- */
-DRIWrappedFuncsRec *
-DRIGetWrappedFuncs(ScreenPtr pScreen)
-{
- return &(DRI_SCREEN_PRIV(pScreen)->wrap);
-}
-
-/* note that this returns the library version, not the protocol version */
-void
-DRIQueryVersion(int *majorVersion,
- int *minorVersion,
- int *patchVersion)
-{
- *majorVersion = DRIINFO_MAJOR_VERSION;
- *minorVersion = DRIINFO_MINOR_VERSION;
- *patchVersion = DRIINFO_PATCH_VERSION;
-}
-
-static void
-_DRIAdjustFrame(ScrnInfoPtr pScrn, DRIScreenPrivPtr pDRIPriv, int x, int y)
-{
- pDRIPriv->pSAREA->frame.x = x;
- pDRIPriv->pSAREA->frame.y = y;
- pDRIPriv->pSAREA->frame.width = pScrn->frameX1 - x + 1;
- pDRIPriv->pSAREA->frame.height = pScrn->frameY1 - y + 1;
-}
-
-void
-DRIAdjustFrame(int scrnIndex, int x, int y, int flags)
-{
- ScreenPtr pScreen = screenInfo.screens[scrnIndex];
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- int px, py;
-
- if (!pDRIPriv || !pDRIPriv->pSAREA) {
- DRIDrvMsg(scrnIndex, X_ERROR, "[DRI] No SAREA (%p %p)\n",
- pDRIPriv, pDRIPriv ? pDRIPriv->pSAREA : NULL);
- return;
- }
-
- if (pDRIPriv->fullscreen) {
- /* Fix up frame */
- pScrn->frameX0 = pDRIPriv->pSAREA->frame.x;
- pScrn->frameY0 = pDRIPriv->pSAREA->frame.y;
- pScrn->frameX1 = pScrn->frameX0 + pDRIPriv->pSAREA->frame.width - 1;
- pScrn->frameY1 = pScrn->frameY0 + pDRIPriv->pSAREA->frame.height - 1;
-
- /* Fix up cursor */
- miPointerGetPosition(inputInfo.pointer, &px, &py);
- if (px < pScrn->frameX0) px = pScrn->frameX0;
- if (px > pScrn->frameX1) px = pScrn->frameX1;
- if (py < pScrn->frameY0) py = pScrn->frameY0;
- if (py > pScrn->frameY1) py = pScrn->frameY1;
- pScreen->SetCursorPosition(inputInfo.pointer, pScreen, px, py, TRUE);
- return;
- }
-
- if (pDRIPriv->wrap.AdjustFrame) {
- /* unwrap */
- pScrn->AdjustFrame = pDRIPriv->wrap.AdjustFrame;
- /* call lower layers */
- (*pScrn->AdjustFrame)(scrnIndex, x, y, flags);
- /* rewrap */
- pDRIPriv->wrap.AdjustFrame = pScrn->AdjustFrame;
- pScrn->AdjustFrame = DRIAdjustFrame;
- }
-
- _DRIAdjustFrame(pScrn, pDRIPriv, x, y);
-}
-
-/*
- * DRIMoveBuffersHelper swaps the regions rects in place leaving you
- * a region with the rects in the order that you need to blit them,
- * but it is possibly (likely) an invalid region afterwards. If you
- * need to use the region again for anything you have to call
- * REGION_VALIDATE on it, or better yet, save a copy first.
- */
-
-void
-DRIMoveBuffersHelper(
- ScreenPtr pScreen,
- int dx,
- int dy,
- int *xdir,
- int *ydir,
- RegionPtr reg
-)
-{
- BoxPtr extents, pbox, firstBox, lastBox;
- BoxRec tmpBox;
- int y, nbox;
-
- extents = REGION_EXTENTS(pScreen, reg);
- nbox = REGION_NUM_RECTS(reg);
- pbox = REGION_RECTS(reg);
-
- if((dy > 0) && (dy < (extents->y2 - extents->y1))) {
- *ydir = -1;
- if(nbox > 1) {
- firstBox = pbox;
- lastBox = pbox + nbox - 1;
- while((unsigned long)firstBox < (unsigned long)lastBox) {
- tmpBox = *firstBox;
- *firstBox = *lastBox;
- *lastBox = tmpBox;
- firstBox++;
- lastBox--;
- }
- }
- } else *ydir = 1;
-
- if((dx > 0) && (dx < (extents->x2 - extents->x1))) {
- *xdir = -1;
- if(nbox > 1) {
- firstBox = lastBox = pbox;
- y = pbox->y1;
- while(--nbox) {
- pbox++;
- if(pbox->y1 == y) lastBox++;
- else {
- while((unsigned long)firstBox < (unsigned long)lastBox) {
- tmpBox = *firstBox;
- *firstBox = *lastBox;
- *lastBox = tmpBox;
- firstBox++;
- lastBox--;
- }
-
- firstBox = lastBox = pbox;
- y = pbox->y1;
- }
- }
- while((unsigned long)firstBox < (unsigned long)lastBox) {
- tmpBox = *firstBox;
- *firstBox = *lastBox;
- *lastBox = tmpBox;
- firstBox++;
- lastBox--;
- }
- }
- } else *xdir = 1;
-
-}
-
-char *
-DRICreatePCIBusID(const struct pci_device * dev)
-{
- char *busID;
-
- busID = xalloc(20);
- if (busID == NULL)
- return NULL;
-
- snprintf(busID, 20, "pci:%04x:%02x:%02x.%d", dev->domain, dev->bus,
- dev->dev, dev->func);
-
- return busID;
-}
-
-static void drmSIGIOHandler(int interrupt, void *closure)
-{
- unsigned long key;
- void *value;
- ssize_t count;
- drm_ctx_t ctx;
- typedef void (*_drmCallback)(int, void *, void *);
- char buf[256];
- drm_context_t old;
- drm_context_t new;
- void *oldctx;
- void *newctx;
- char *pt;
- drmHashEntry *entry;
- void *hash_table;
-
- hash_table = drmGetHashTable();
-
- if (!hash_table) return;
- if (drmHashFirst(hash_table, &key, &value)) {
- entry = value;
- do {
-#if 0
- fprintf(stderr, "Trying %d\n", entry->fd);
-#endif
- if ((count = read(entry->fd, buf, sizeof(buf) - 1)) > 0) {
- buf[count] = '\0';
-#if 0
- fprintf(stderr, "Got %s\n", buf);
-#endif
-
- for (pt = buf; *pt != ' '; ++pt); /* Find first space */
- ++pt;
- old = strtol(pt, &pt, 0);
- new = strtol(pt, NULL, 0);
- oldctx = drmGetContextTag(entry->fd, old);
- newctx = drmGetContextTag(entry->fd, new);
-#if 0
- fprintf(stderr, "%d %d %p %p\n", old, new, oldctx, newctx);
-#endif
- ((_drmCallback)entry->f)(entry->fd, oldctx, newctx);
- ctx.handle = new;
- ioctl(entry->fd, DRM_IOCTL_NEW_CTX, &ctx);
- }
- } while (drmHashNext(hash_table, &key, &value));
- }
-}
-
-
-int drmInstallSIGIOHandler(int fd, void (*f)(int, void *, void *))
-{
- drmHashEntry *entry;
-
- entry = drmGetEntry(fd);
- entry->f = f;
-
- return xf86InstallSIGIOHandler(fd, drmSIGIOHandler, 0);
-}
-
-int drmRemoveSIGIOHandler(int fd)
-{
- drmHashEntry *entry = drmGetEntry(fd);
-
- entry->f = NULL;
-
- return xf86RemoveSIGIOHandler(fd);
-}
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+Copyright 2000 VA Linux Systems, 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, sub license, 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 (including the
+next paragraph) 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 NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Jens Owen <jens@tungstengraphics.com>
+ * Rickard E. (Rik) Faith <faith@valinux.com>
+ *
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "xf86.h"
+#include <sys/time.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "xf86drm.h"
+#include "misc.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "servermd.h"
+#define _XF86DRI_SERVER_
+#include <X11/dri/xf86driproto.h>
+#include "swaprep.h"
+#include "xf86str.h"
+#include "dri.h"
+#include "sarea.h"
+#include "dristruct.h"
+#include "xf86.h"
+#include "xf86drm.h"
+#include "mi.h"
+#include "mipointer.h"
+#include "xf86_OSproc.h"
+#include "inputstr.h"
+#include "xf86VGAarbiter.h"
+
+#define PCI_BUS_NO_DOMAIN(bus) ((bus) & 0xffu)
+
+static int DRIEntPrivIndex = -1;
+static int DRIScreenPrivKeyIndex;
+static DevPrivateKey DRIScreenPrivKey = &DRIScreenPrivKeyIndex;
+static int DRIWindowPrivKeyIndex;
+static DevPrivateKey DRIWindowPrivKey = &DRIWindowPrivKeyIndex;
+static unsigned long DRIGeneration = 0;
+static unsigned int DRIDrawableValidationStamp = 0;
+
+static RESTYPE DRIDrawablePrivResType;
+static RESTYPE DRIContextPrivResType;
+static void DRIDestroyDummyContext(ScreenPtr pScreen, Bool hasCtxPriv);
+
+drmServerInfo DRIDRMServerInfo;
+
+ /* Wrapper just like xf86DrvMsg, but
+ without the verbosity level checking.
+ This will make it easy to turn off some
+ messages later, based on verbosity
+ level. */
+
+/*
+ * Since we're already referencing things from the XFree86 common layer in
+ * this file, we'd might as well just call xf86VDrvMsgVerb, and have
+ * consistent message formatting. The verbosity of these messages can be
+ * easily changed here.
+ */
+#define DRI_MSG_VERBOSITY 1
+static void
+DRIDrvMsg(int scrnIndex, MessageType type, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ xf86VDrvMsgVerb(scrnIndex, type, DRI_MSG_VERBOSITY, format, ap);
+ va_end(ap);
+}
+
+
+static void
+DRIOpenDRMCleanup(DRIEntPrivPtr pDRIEntPriv)
+{
+ if (pDRIEntPriv->pLSAREA != NULL) {
+ drmUnmap(pDRIEntPriv->pLSAREA, pDRIEntPriv->sAreaSize);
+ pDRIEntPriv->pLSAREA = NULL;
+ }
+ if (pDRIEntPriv->hLSAREA != 0) {
+ drmRmMap(pDRIEntPriv->drmFD, pDRIEntPriv->hLSAREA);
+ }
+ if (pDRIEntPriv->drmFD >= 0) {
+ drmClose(pDRIEntPriv->drmFD);
+ pDRIEntPriv->drmFD = 0;
+ }
+}
+
+int
+DRIMasterFD(ScrnInfoPtr pScrn)
+{
+ return DRI_ENT_PRIV(pScrn)->drmFD;
+}
+
+void *
+DRIMasterSareaPointer(ScrnInfoPtr pScrn)
+{
+ return DRI_ENT_PRIV(pScrn)->pLSAREA;
+}
+
+drm_handle_t
+DRIMasterSareaHandle(ScrnInfoPtr pScrn)
+{
+ return DRI_ENT_PRIV(pScrn)->hLSAREA;
+}
+
+
+Bool
+DRIOpenDRMMaster(ScrnInfoPtr pScrn,
+ unsigned long sAreaSize,
+ const char *busID,
+ const char *drmDriverName)
+{
+ drmSetVersion saveSv, sv;
+ Bool drmWasAvailable;
+ DRIEntPrivPtr pDRIEntPriv;
+ DRIEntPrivRec tmp;
+ drmVersionPtr drmlibv;
+ int drmlibmajor, drmlibminor;
+ const char *openBusID;
+ int count;
+ int err;
+
+ if (DRIEntPrivIndex == -1)
+ DRIEntPrivIndex = xf86AllocateEntityPrivateIndex();
+
+ pDRIEntPriv = DRI_ENT_PRIV(pScrn);
+
+ if (pDRIEntPriv && pDRIEntPriv->drmFD != -1)
+ return TRUE;
+
+ drmWasAvailable = drmAvailable();
+
+ memset(&tmp, 0, sizeof(tmp));
+
+ /* Check the DRM lib version.
+ * drmGetLibVersion was not supported in version 1.0, so check for
+ * symbol first to avoid possible crash or hang.
+ */
+
+ drmlibmajor = 1;
+ drmlibminor = 0;
+ if (xf86LoaderCheckSymbol("drmGetLibVersion")) {
+ drmlibv = drmGetLibVersion(-1);
+ if (drmlibv != NULL) {
+ drmlibmajor = drmlibv->version_major;
+ drmlibminor = drmlibv->version_minor;
+ drmFreeVersion(drmlibv);
+ }
+ }
+
+ /* Check if the libdrm can handle falling back to loading based on name
+ * if a busid string is passed.
+ */
+ openBusID = (drmlibmajor == 1 && drmlibminor >= 2) ? busID : NULL;
+
+ tmp.drmFD = -1;
+ sv.drm_di_major = 1;
+ sv.drm_di_minor = 1;
+ sv.drm_dd_major = -1;
+
+ saveSv = sv;
+ count = 10;
+ while (count--) {
+ tmp.drmFD = drmOpen(drmDriverName, openBusID);
+
+ if (tmp.drmFD < 0) {
+ DRIDrvMsg(-1, X_ERROR, "[drm] drmOpen failed.\n");
+ goto out_err;
+ }
+
+ err = drmSetInterfaceVersion(tmp.drmFD, &sv);
+
+ if (err != -EPERM)
+ break;
+
+ sv = saveSv;
+ drmClose(tmp.drmFD);
+ tmp.drmFD = -1;
+ usleep(100000);
+ }
+
+ if (tmp.drmFD <= 0) {
+ DRIDrvMsg(-1, X_ERROR, "[drm] DRM was busy with another master.\n");
+ goto out_err;
+ }
+
+ if (!drmWasAvailable) {
+ DRIDrvMsg(-1, X_INFO,
+ "[drm] loaded kernel module for \"%s\" driver.\n",
+ drmDriverName);
+ }
+
+ if (err != 0) {
+ sv.drm_di_major = 1;
+ sv.drm_di_minor = 0;
+ }
+
+ DRIDrvMsg(-1, X_INFO, "[drm] DRM interface version %d.%d\n",
+ sv.drm_di_major, sv.drm_di_minor);
+
+ if (sv.drm_di_major == 1 && sv.drm_di_minor >= 1)
+ err = 0;
+ else
+ err = drmSetBusid(tmp.drmFD, busID);
+
+ if (err) {
+ DRIDrvMsg(-1, X_ERROR, "[drm] Could not set DRM device bus ID.\n");
+ goto out_err;
+ }
+
+ /*
+ * Create a lock-containing sarea.
+ */
+
+ if (drmAddMap( tmp.drmFD, 0, sAreaSize, DRM_SHM,
+ DRM_CONTAINS_LOCK, &tmp.hLSAREA) < 0) {
+ DRIDrvMsg(-1, X_INFO, "[drm] Could not create SAREA for DRM lock.\n");
+ tmp.hLSAREA = 0;
+ goto out_err;
+ }
+
+ if (drmMap( tmp.drmFD, tmp.hLSAREA, sAreaSize,
+ (drmAddressPtr)(&tmp.pLSAREA)) < 0) {
+ DRIDrvMsg(-1, X_INFO, "[drm] Mapping SAREA for DRM lock failed.\n");
+ tmp.pLSAREA = NULL;
+ goto out_err;
+ }
+
+ memset(tmp.pLSAREA, 0, sAreaSize);
+
+ /*
+ * Reserved contexts are handled by the first opened screen.
+ */
+
+ tmp.resOwner = NULL;
+
+ if (!pDRIEntPriv)
+ pDRIEntPriv = xnfcalloc(sizeof(*pDRIEntPriv), 1);
+
+ if (!pDRIEntPriv) {
+ DRIDrvMsg(-1, X_INFO, "[drm] Failed to allocate memory for "
+ "DRM device.\n");
+ goto out_err;
+ }
+ *pDRIEntPriv = tmp;
+ xf86GetEntityPrivate((pScrn)->entityList[0],DRIEntPrivIndex)->ptr =
+ pDRIEntPriv;
+
+ DRIDrvMsg(-1, X_INFO, "[drm] DRM open master succeeded.\n");
+ return TRUE;
+
+ out_err:
+
+ DRIOpenDRMCleanup(&tmp);
+ return FALSE;
+}
+
+static void
+DRIClipNotifyAllDrawables(ScreenPtr pScreen);
+
+static void
+dri_crtc_notify(ScreenPtr pScreen)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIClipNotifyAllDrawables(pScreen);
+ xf86_unwrap_crtc_notify(pScreen, pDRIPriv->xf86_crtc_notify);
+ xf86_crtc_notify(pScreen);
+ pDRIPriv->xf86_crtc_notify = xf86_wrap_crtc_notify(pScreen, dri_crtc_notify);
+}
+
+Bool
+DRIScreenInit(ScreenPtr pScreen, DRIInfoPtr pDRIInfo, int *pDRMFD)
+{
+ DRIScreenPrivPtr pDRIPriv;
+ drm_context_t * reserved;
+ int reserved_count;
+ int i;
+ DRIEntPrivPtr pDRIEntPriv;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ DRIContextFlags flags = 0;
+ DRIContextPrivPtr pDRIContextPriv;
+
+ /* If the DRI extension is disabled, do not initialize the DRI */
+ if (noXFree86DRIExtension) {
+ DRIDrvMsg(pScreen->myNum, X_WARNING,
+ "Direct rendering has been disabled.\n");
+ return FALSE;
+ }
+
+ if (!xf86VGAarbiterAllowDRI(pScreen)) {
+ DRIDrvMsg(pScreen->myNum, X_WARNING,
+ "Direct rendering is not supported when VGA arb is necessary for the device\n");
+ return FALSE;
+ }
+
+#ifdef PANORAMIX
+ /*
+ * If Xinerama is on, don't allow DRI to initialise. It won't be usable
+ * anyway.
+ */
+ if (!noPanoramiXExtension) {
+ DRIDrvMsg(pScreen->myNum, X_WARNING,
+ "Direct rendering is not supported when Xinerama is enabled\n");
+ return FALSE;
+ }
+#endif
+
+ if (!DRIOpenDRMMaster(pScrn, pDRIInfo->SAREASize,
+ pDRIInfo->busIdString,
+ pDRIInfo->drmDriverName))
+ return FALSE;
+
+ pDRIEntPriv = DRI_ENT_PRIV(pScrn);
+
+ if (DRIGeneration != serverGeneration)
+ DRIGeneration = serverGeneration;
+
+ pDRIPriv = (DRIScreenPrivPtr) calloc(1, sizeof(DRIScreenPrivRec));
+ if (!pDRIPriv) {
+ dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL);
+ return FALSE;
+ }
+
+ dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, pDRIPriv);
+ pDRIPriv->drmFD = pDRIEntPriv->drmFD;
+ pDRIPriv->directRenderingSupport = TRUE;
+ pDRIPriv->pDriverInfo = pDRIInfo;
+ pDRIPriv->nrWindows = 0;
+ pDRIPriv->nrWindowsVisible = 0;
+ pDRIPriv->fullscreen = NULL;
+
+ pDRIPriv->createDummyCtx = pDRIInfo->createDummyCtx;
+ pDRIPriv->createDummyCtxPriv = pDRIInfo->createDummyCtxPriv;
+
+ pDRIPriv->grabbedDRILock = FALSE;
+ pDRIPriv->drmSIGIOHandlerInstalled = FALSE;
+ *pDRMFD = pDRIPriv->drmFD;
+
+ if (pDRIEntPriv->sAreaGrabbed || pDRIInfo->allocSarea) {
+
+ if (drmAddMap( pDRIPriv->drmFD,
+ 0,
+ pDRIPriv->pDriverInfo->SAREASize,
+ DRM_SHM,
+ 0,
+ &pDRIPriv->hSAREA) < 0)
+ {
+ pDRIPriv->directRenderingSupport = FALSE;
+ dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL);
+ drmClose(pDRIPriv->drmFD);
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "[drm] drmAddMap failed\n");
+ return FALSE;
+ }
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "[drm] added %d byte SAREA at %p\n",
+ pDRIPriv->pDriverInfo->SAREASize, pDRIPriv->hSAREA);
+
+ /* Backwards compat. */
+ if (drmMap( pDRIPriv->drmFD,
+ pDRIPriv->hSAREA,
+ pDRIPriv->pDriverInfo->SAREASize,
+ (drmAddressPtr)(&pDRIPriv->pSAREA)) < 0)
+ {
+ pDRIPriv->directRenderingSupport = FALSE;
+ dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL);
+ drmClose(pDRIPriv->drmFD);
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "[drm] drmMap failed\n");
+ return FALSE;
+ }
+ DRIDrvMsg(pScreen->myNum, X_INFO, "[drm] mapped SAREA %p to %p\n",
+ pDRIPriv->hSAREA, pDRIPriv->pSAREA);
+ memset(pDRIPriv->pSAREA, 0, pDRIPriv->pDriverInfo->SAREASize);
+ } else {
+ DRIDrvMsg(pScreen->myNum, X_INFO, "[drm] Using the DRM lock "
+ "SAREA also for drawables.\n");
+ pDRIPriv->hSAREA = pDRIEntPriv->hLSAREA;
+ pDRIPriv->pSAREA = (XF86DRISAREAPtr) pDRIEntPriv->pLSAREA;
+ pDRIEntPriv->sAreaGrabbed = TRUE;
+ }
+
+ pDRIPriv->hLSAREA = pDRIEntPriv->hLSAREA;
+ pDRIPriv->pLSAREA = pDRIEntPriv->pLSAREA;
+
+ if (!pDRIPriv->pDriverInfo->dontMapFrameBuffer)
+ {
+ if (drmAddMap( pDRIPriv->drmFD,
+ (drm_handle_t)pDRIPriv->pDriverInfo->frameBufferPhysicalAddress,
+ pDRIPriv->pDriverInfo->frameBufferSize,
+ DRM_FRAME_BUFFER,
+ 0,
+ &pDRIPriv->pDriverInfo->hFrameBuffer) < 0)
+ {
+ pDRIPriv->directRenderingSupport = FALSE;
+ dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL);
+ drmUnmap(pDRIPriv->pSAREA, pDRIPriv->pDriverInfo->SAREASize);
+ drmClose(pDRIPriv->drmFD);
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "[drm] drmAddMap failed\n");
+ return FALSE;
+ }
+ DRIDrvMsg(pScreen->myNum, X_INFO, "[drm] framebuffer handle = %p\n",
+ pDRIPriv->pDriverInfo->hFrameBuffer);
+ } else {
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "[drm] framebuffer mapped by ddx driver\n");
+ }
+
+ if (pDRIEntPriv->resOwner == NULL) {
+ pDRIEntPriv->resOwner = pScreen;
+
+ /* Add tags for reserved contexts */
+ if ((reserved = drmGetReservedContextList(pDRIPriv->drmFD,
+ &reserved_count))) {
+ int i;
+ void *tag;
+
+ for (i = 0; i < reserved_count; i++) {
+ tag = DRICreateContextPrivFromHandle(pScreen,
+ reserved[i],
+ DRI_CONTEXT_RESERVED);
+ drmAddContextTag(pDRIPriv->drmFD, reserved[i], tag);
+ }
+ drmFreeReservedContextList(reserved);
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "[drm] added %d reserved context%s for kernel\n",
+ reserved_count, reserved_count > 1 ? "s" : "");
+ }
+ }
+
+ /* validate max drawable table entry set by driver */
+ if ((pDRIPriv->pDriverInfo->maxDrawableTableEntry <= 0) ||
+ (pDRIPriv->pDriverInfo->maxDrawableTableEntry > SAREA_MAX_DRAWABLES)) {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "Invalid max drawable table size set by driver: %d\n",
+ pDRIPriv->pDriverInfo->maxDrawableTableEntry);
+ }
+
+ /* Initialize drawable tables (screen private and SAREA) */
+ for( i=0; i < pDRIPriv->pDriverInfo->maxDrawableTableEntry; i++) {
+ pDRIPriv->DRIDrawables[i] = NULL;
+ pDRIPriv->pSAREA->drawableTable[i].stamp = 0;
+ pDRIPriv->pSAREA->drawableTable[i].flags = 0;
+ }
+
+ pDRIPriv->pLockRefCount = &pDRIEntPriv->lockRefCount;
+ pDRIPriv->pLockingContext = &pDRIEntPriv->lockingContext;
+
+ if (!pDRIEntPriv->keepFDOpen)
+ pDRIEntPriv->keepFDOpen = pDRIInfo->keepFDOpen;
+
+ pDRIEntPriv->refCount++;
+
+ /* Set up flags for DRICreateContextPriv */
+ switch (pDRIInfo->driverSwapMethod) {
+ case DRI_KERNEL_SWAP:
+ flags = DRI_CONTEXT_2DONLY;
+ break;
+ case DRI_HIDE_X_CONTEXT:
+ flags = DRI_CONTEXT_PRESERVED;
+ break;
+ }
+
+ if (!(pDRIContextPriv = DRICreateContextPriv(pScreen,
+ &pDRIPriv->myContext,
+ flags))) {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "failed to create server context\n");
+ return FALSE;
+ }
+ pDRIPriv->myContextPriv = pDRIContextPriv;
+
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "X context handle = %p\n", pDRIPriv->myContext);
+
+ /* Now that we have created the X server's context, we can grab the
+ * hardware lock for the X server.
+ */
+ DRILock(pScreen, 0);
+ pDRIPriv->grabbedDRILock = TRUE;
+
+ /* pointers so that we can prevent memory leaks later */
+ pDRIPriv->hiddenContextStore = NULL;
+ pDRIPriv->partial3DContextStore = NULL;
+
+ switch(pDRIInfo->driverSwapMethod) {
+ case DRI_HIDE_X_CONTEXT:
+ /* Server will handle 3D swaps, and hide 2D swaps from kernel.
+ * Register server context as a preserved context.
+ */
+
+ /* allocate memory for hidden context store */
+ pDRIPriv->hiddenContextStore
+ = (void *)calloc(1, pDRIInfo->contextSize);
+ if (!pDRIPriv->hiddenContextStore) {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "failed to allocate hidden context\n");
+ DRIDestroyContextPriv(pDRIContextPriv);
+ return FALSE;
+ }
+
+ /* allocate memory for partial 3D context store */
+ pDRIPriv->partial3DContextStore
+ = (void *)calloc(1, pDRIInfo->contextSize);
+ if (!pDRIPriv->partial3DContextStore) {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI] failed to allocate partial 3D context\n");
+ free(pDRIPriv->hiddenContextStore);
+ DRIDestroyContextPriv(pDRIContextPriv);
+ return FALSE;
+ }
+
+ /* save initial context store */
+ if (pDRIInfo->SwapContext) {
+ (*pDRIInfo->SwapContext)(
+ pScreen,
+ DRI_NO_SYNC,
+ DRI_2D_CONTEXT,
+ pDRIPriv->hiddenContextStore,
+ DRI_NO_CONTEXT,
+ NULL);
+ }
+ /* fall through */
+
+ case DRI_SERVER_SWAP:
+ /* For swap methods of DRI_SERVER_SWAP and DRI_HIDE_X_CONTEXT
+ * setup signal handler for receiving swap requests from kernel
+ */
+ if (!(pDRIPriv->drmSIGIOHandlerInstalled =
+ drmInstallSIGIOHandler(pDRIPriv->drmFD, DRISwapContext))) {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] failed to setup DRM signal handler\n");
+ if (pDRIPriv->hiddenContextStore)
+ free(pDRIPriv->hiddenContextStore);
+ if (pDRIPriv->partial3DContextStore)
+ free(pDRIPriv->partial3DContextStore);
+ DRIDestroyContextPriv(pDRIContextPriv);
+ return FALSE;
+ } else {
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "[drm] installed DRM signal handler\n");
+ }
+
+ default:
+ break;
+ }
+
+ return TRUE;
+}
+
+Bool
+DRIFinishScreenInit(ScreenPtr pScreen)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
+
+ /* Wrap DRI support */
+ if (pDRIInfo->wrap.ValidateTree) {
+ pDRIPriv->wrap.ValidateTree = pScreen->ValidateTree;
+ pScreen->ValidateTree = pDRIInfo->wrap.ValidateTree;
+ }
+ if (pDRIInfo->wrap.PostValidateTree) {
+ pDRIPriv->wrap.PostValidateTree = pScreen->PostValidateTree;
+ pScreen->PostValidateTree = pDRIInfo->wrap.PostValidateTree;
+ }
+ if (pDRIInfo->wrap.WindowExposures) {
+ pDRIPriv->wrap.WindowExposures = pScreen->WindowExposures;
+ pScreen->WindowExposures = pDRIInfo->wrap.WindowExposures;
+ }
+
+ pDRIPriv->DestroyWindow = pScreen->DestroyWindow;
+ pScreen->DestroyWindow = DRIDestroyWindow;
+
+ pDRIPriv->xf86_crtc_notify = xf86_wrap_crtc_notify(pScreen,
+ dri_crtc_notify);
+
+ if (pDRIInfo->wrap.CopyWindow) {
+ pDRIPriv->wrap.CopyWindow = pScreen->CopyWindow;
+ pScreen->CopyWindow = pDRIInfo->wrap.CopyWindow;
+ }
+ if (pDRIInfo->wrap.ClipNotify) {
+ pDRIPriv->wrap.ClipNotify = pScreen->ClipNotify;
+ pScreen->ClipNotify = pDRIInfo->wrap.ClipNotify;
+ }
+ if (pDRIInfo->wrap.AdjustFrame) {
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ pDRIPriv->wrap.AdjustFrame = pScrn->AdjustFrame;
+ pScrn->AdjustFrame = pDRIInfo->wrap.AdjustFrame;
+ }
+ pDRIPriv->wrapped = TRUE;
+
+ DRIDrvMsg(pScreen->myNum, X_INFO, "[DRI] installation complete\n");
+
+ return TRUE;
+}
+
+void
+DRICloseScreen(ScreenPtr pScreen)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIInfoPtr pDRIInfo;
+ drm_context_t * reserved;
+ int reserved_count;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ DRIEntPrivPtr pDRIEntPriv = DRI_ENT_PRIV(pScrn);
+ Bool closeMaster;
+
+ if (pDRIPriv) {
+
+ pDRIInfo = pDRIPriv->pDriverInfo;
+
+ if (pDRIPriv->wrapped) {
+ /* Unwrap DRI Functions */
+ if (pDRIInfo->wrap.ValidateTree) {
+ pScreen->ValidateTree = pDRIPriv->wrap.ValidateTree;
+ pDRIPriv->wrap.ValidateTree = NULL;
+ }
+ if (pDRIInfo->wrap.PostValidateTree) {
+ pScreen->PostValidateTree = pDRIPriv->wrap.PostValidateTree;
+ pDRIPriv->wrap.PostValidateTree = NULL;
+ }
+ if (pDRIInfo->wrap.WindowExposures) {
+ pScreen->WindowExposures = pDRIPriv->wrap.WindowExposures;
+ pDRIPriv->wrap.WindowExposures = NULL;
+ }
+ if (pDRIPriv->DestroyWindow) {
+ pScreen->DestroyWindow = pDRIPriv->DestroyWindow;
+ pDRIPriv->DestroyWindow = NULL;
+ }
+
+ xf86_unwrap_crtc_notify(pScreen, pDRIPriv->xf86_crtc_notify);
+
+ if (pDRIInfo->wrap.CopyWindow) {
+ pScreen->CopyWindow = pDRIPriv->wrap.CopyWindow;
+ pDRIPriv->wrap.CopyWindow = NULL;
+ }
+ if (pDRIInfo->wrap.ClipNotify) {
+ pScreen->ClipNotify = pDRIPriv->wrap.ClipNotify;
+ pDRIPriv->wrap.ClipNotify = NULL;
+ }
+ if (pDRIInfo->wrap.AdjustFrame) {
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ pScrn->AdjustFrame = pDRIPriv->wrap.AdjustFrame;
+ pDRIPriv->wrap.AdjustFrame = NULL;
+ }
+
+ pDRIPriv->wrapped = FALSE;
+ }
+
+ if (pDRIPriv->drmSIGIOHandlerInstalled) {
+ if (!drmRemoveSIGIOHandler(pDRIPriv->drmFD)) {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] failed to remove DRM signal handler\n");
+ }
+ }
+
+ if (pDRIPriv->dummyCtxPriv && pDRIPriv->createDummyCtx) {
+ DRIDestroyDummyContext(pScreen, pDRIPriv->createDummyCtxPriv);
+ }
+
+ if (!DRIDestroyContextPriv(pDRIPriv->myContextPriv)) {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "failed to destroy server context\n");
+ }
+
+ /* Remove tags for reserved contexts */
+ if (pDRIEntPriv->resOwner == pScreen) {
+ pDRIEntPriv->resOwner = NULL;
+
+ if ((reserved = drmGetReservedContextList(pDRIPriv->drmFD,
+ &reserved_count))) {
+ int i;
+
+ for (i = 0; i < reserved_count; i++) {
+ DRIDestroyContextPriv(drmGetContextTag(pDRIPriv->drmFD,
+ reserved[i]));
+ }
+ drmFreeReservedContextList(reserved);
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "[drm] removed %d reserved context%s for kernel\n",
+ reserved_count, reserved_count > 1 ? "s" : "");
+ }
+ }
+
+ /* Make sure signals get unblocked etc. */
+ drmUnlock(pDRIPriv->drmFD, pDRIPriv->myContext);
+ pDRIPriv->pLockRefCount = NULL;
+ closeMaster = (--pDRIEntPriv->refCount == 0) &&
+ !pDRIEntPriv->keepFDOpen;
+ if (closeMaster || pDRIPriv->hSAREA != pDRIEntPriv->hLSAREA) {
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "[drm] unmapping %d bytes of SAREA %p at %p\n",
+ pDRIInfo->SAREASize,
+ pDRIPriv->hSAREA,
+ pDRIPriv->pSAREA);
+ if (drmUnmap(pDRIPriv->pSAREA, pDRIInfo->SAREASize)) {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] unable to unmap %d bytes"
+ " of SAREA %p at %p\n",
+ pDRIInfo->SAREASize,
+ pDRIPriv->hSAREA,
+ pDRIPriv->pSAREA);
+ }
+ } else {
+ pDRIEntPriv->sAreaGrabbed = FALSE;
+ }
+
+ if (closeMaster || (pDRIEntPriv->drmFD != pDRIPriv->drmFD)) {
+ drmClose(pDRIPriv->drmFD);
+ if (pDRIEntPriv->drmFD == pDRIPriv->drmFD) {
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "[drm] Closed DRM master.\n");
+ pDRIEntPriv->drmFD = -1;
+ }
+ }
+
+ free(pDRIPriv);
+ dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL);
+ }
+}
+
+#define DRM_MSG_VERBOSITY 3
+
+static int dri_drm_debug_print(const char *format, va_list ap)
+{
+ xf86VDrvMsgVerb(-1, X_NONE, DRM_MSG_VERBOSITY, format, ap);
+ return 0;
+}
+
+static void dri_drm_get_perms(gid_t *group, mode_t *mode)
+{
+ *group = xf86ConfigDRI.group;
+ *mode = xf86ConfigDRI.mode;
+}
+
+drmServerInfo DRIDRMServerInfo = {
+ dri_drm_debug_print,
+ xf86LoadKernelModule,
+ dri_drm_get_perms,
+};
+
+Bool
+DRIExtensionInit(void)
+{
+ if (!DRIScreenPrivKey || DRIGeneration != serverGeneration) {
+ return FALSE;
+ }
+
+ DRIDrawablePrivResType = CreateNewResourceType(DRIDrawablePrivDelete,
+ "DRIDrawable");
+ DRIContextPrivResType = CreateNewResourceType(DRIContextPrivDelete,
+ "DRIContext");
+
+ if (!DRIDrawablePrivResType || !DRIContextPrivResType)
+ return FALSE;
+
+ RegisterBlockAndWakeupHandlers(DRIBlockHandler, DRIWakeupHandler, NULL);
+
+ return TRUE;
+}
+
+void
+DRIReset(void)
+{
+ /*
+ * This stub routine is called when the X Server recycles, resources
+ * allocated by DRIExtensionInit need to be managed here.
+ *
+ * Currently this routine is a stub because all the interesting resources
+ * are managed via the screen init process.
+ */
+}
+
+Bool
+DRIQueryDirectRenderingCapable(ScreenPtr pScreen, Bool* isCapable)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if (pDRIPriv)
+ *isCapable = pDRIPriv->directRenderingSupport;
+ else
+ *isCapable = FALSE;
+
+ return TRUE;
+}
+
+Bool
+DRIOpenConnection(ScreenPtr pScreen, drm_handle_t * hSAREA, char **busIdString)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ *hSAREA = pDRIPriv->hSAREA;
+ *busIdString = pDRIPriv->pDriverInfo->busIdString;
+
+ return TRUE;
+}
+
+Bool
+DRIAuthConnection(ScreenPtr pScreen, drm_magic_t magic)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if (drmAuthMagic(pDRIPriv->drmFD, magic)) return FALSE;
+ return TRUE;
+}
+
+Bool
+DRICloseConnection(ScreenPtr pScreen)
+{
+ return TRUE;
+}
+
+Bool
+DRIGetClientDriverName(ScreenPtr pScreen,
+ int *ddxDriverMajorVersion,
+ int *ddxDriverMinorVersion,
+ int *ddxDriverPatchVersion,
+ char **clientDriverName)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ *ddxDriverMajorVersion = pDRIPriv->pDriverInfo->ddxDriverMajorVersion;
+ *ddxDriverMinorVersion = pDRIPriv->pDriverInfo->ddxDriverMinorVersion;
+ *ddxDriverPatchVersion = pDRIPriv->pDriverInfo->ddxDriverPatchVersion;
+ *clientDriverName = pDRIPriv->pDriverInfo->clientDriverName;
+
+ return TRUE;
+}
+
+/* DRICreateContextPriv and DRICreateContextPrivFromHandle are helper
+ functions that layer on drmCreateContext and drmAddContextTag.
+
+ DRICreateContextPriv always creates a kernel drm_context_t and then calls
+ DRICreateContextPrivFromHandle to create a DRIContextPriv structure for
+ DRI tracking. For the SIGIO handler, the drm_context_t is associated with
+ DRIContextPrivPtr. Any special flags are stored in the DRIContextPriv
+ area and are passed to the kernel (if necessary).
+
+ DRICreateContextPriv returns a pointer to newly allocated
+ DRIContextPriv, and returns the kernel drm_context_t in pHWContext. */
+
+DRIContextPrivPtr
+DRICreateContextPriv(ScreenPtr pScreen,
+ drm_context_t * pHWContext,
+ DRIContextFlags flags)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if (drmCreateContext(pDRIPriv->drmFD, pHWContext)) {
+ return NULL;
+ }
+
+ return DRICreateContextPrivFromHandle(pScreen, *pHWContext, flags);
+}
+
+DRIContextPrivPtr
+DRICreateContextPrivFromHandle(ScreenPtr pScreen,
+ drm_context_t hHWContext,
+ DRIContextFlags flags)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIContextPrivPtr pDRIContextPriv;
+ int contextPrivSize;
+
+ contextPrivSize = sizeof(DRIContextPrivRec) +
+ pDRIPriv->pDriverInfo->contextSize;
+ if (!(pDRIContextPriv = calloc(1, contextPrivSize))) {
+ return NULL;
+ }
+ pDRIContextPriv->pContextStore = (void *)(pDRIContextPriv + 1);
+
+ drmAddContextTag(pDRIPriv->drmFD, hHWContext, pDRIContextPriv);
+
+ pDRIContextPriv->hwContext = hHWContext;
+ pDRIContextPriv->pScreen = pScreen;
+ pDRIContextPriv->flags = flags;
+ pDRIContextPriv->valid3D = FALSE;
+
+ if (flags & DRI_CONTEXT_2DONLY) {
+ if (drmSetContextFlags(pDRIPriv->drmFD,
+ hHWContext,
+ DRM_CONTEXT_2DONLY)) {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] failed to set 2D context flag\n");
+ DRIDestroyContextPriv(pDRIContextPriv);
+ return NULL;
+ }
+ }
+ if (flags & DRI_CONTEXT_PRESERVED) {
+ if (drmSetContextFlags(pDRIPriv->drmFD,
+ hHWContext,
+ DRM_CONTEXT_PRESERVED)) {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "[drm] failed to set preserved flag\n");
+ DRIDestroyContextPriv(pDRIContextPriv);
+ return NULL;
+ }
+ }
+ return pDRIContextPriv;
+}
+
+Bool
+DRIDestroyContextPriv(DRIContextPrivPtr pDRIContextPriv)
+{
+ DRIScreenPrivPtr pDRIPriv;
+
+ if (!pDRIContextPriv) return TRUE;
+
+ pDRIPriv = DRI_SCREEN_PRIV(pDRIContextPriv->pScreen);
+
+ if (!(pDRIContextPriv->flags & DRI_CONTEXT_RESERVED)) {
+ /* Don't delete reserved contexts from
+ kernel area -- the kernel manages its
+ reserved contexts itself. */
+ if (drmDestroyContext(pDRIPriv->drmFD, pDRIContextPriv->hwContext))
+ return FALSE;
+ }
+
+ /* Remove the tag last to prevent a race
+ condition where the context has pending
+ buffers. The context can't be re-used
+ while in this thread, but buffers can be
+ dispatched asynchronously. */
+ drmDelContextTag(pDRIPriv->drmFD, pDRIContextPriv->hwContext);
+ free(pDRIContextPriv);
+ return TRUE;
+}
+
+static Bool
+DRICreateDummyContext(ScreenPtr pScreen, Bool needCtxPriv)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIContextPrivPtr pDRIContextPriv;
+ void *contextStore;
+
+ if (!(pDRIContextPriv =
+ DRICreateContextPriv(pScreen,
+ &pDRIPriv->pSAREA->dummy_context, 0))) {
+ return FALSE;
+ }
+
+ contextStore = DRIGetContextStore(pDRIContextPriv);
+ if (pDRIPriv->pDriverInfo->CreateContext && needCtxPriv) {
+ if (!pDRIPriv->pDriverInfo->CreateContext(pScreen, NULL,
+ pDRIPriv->pSAREA->dummy_context,
+ NULL,
+ (DRIContextType)(long)contextStore)) {
+ DRIDestroyContextPriv(pDRIContextPriv);
+ return FALSE;
+ }
+ }
+
+ pDRIPriv->dummyCtxPriv = pDRIContextPriv;
+ return TRUE;
+}
+
+static void
+DRIDestroyDummyContext(ScreenPtr pScreen, Bool hasCtxPriv)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIContextPrivPtr pDRIContextPriv = pDRIPriv->dummyCtxPriv;
+ void *contextStore;
+
+ if (!pDRIContextPriv) return;
+ if (pDRIPriv->pDriverInfo->DestroyContext && hasCtxPriv) {
+ contextStore = DRIGetContextStore(pDRIContextPriv);
+ pDRIPriv->pDriverInfo->DestroyContext(pDRIContextPriv->pScreen,
+ pDRIContextPriv->hwContext,
+ (DRIContextType)(long)contextStore);
+ }
+
+ DRIDestroyContextPriv(pDRIPriv->dummyCtxPriv);
+ pDRIPriv->dummyCtxPriv = NULL;
+}
+
+Bool
+DRICreateContext(ScreenPtr pScreen, VisualPtr visual,
+ XID context, drm_context_t * pHWContext)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIContextPrivPtr pDRIContextPriv;
+ void *contextStore;
+
+ if (pDRIPriv->createDummyCtx && !pDRIPriv->dummyCtxPriv) {
+ if (!DRICreateDummyContext(pScreen, pDRIPriv->createDummyCtxPriv)) {
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "[drm] Could not create dummy context\n");
+ return FALSE;
+ }
+ }
+
+ if (!(pDRIContextPriv = DRICreateContextPriv(pScreen, pHWContext, 0))) {
+ return FALSE;
+ }
+
+ contextStore = DRIGetContextStore(pDRIContextPriv);
+ if (pDRIPriv->pDriverInfo->CreateContext) {
+ if (!((*pDRIPriv->pDriverInfo->CreateContext)(pScreen, NULL,
+ *pHWContext, NULL,
+ (DRIContextType)(long)contextStore))) {
+ DRIDestroyContextPriv(pDRIContextPriv);
+ return FALSE;
+ }
+ }
+
+ /* track this in case the client dies before cleanup */
+ AddResource(context, DRIContextPrivResType, (pointer)pDRIContextPriv);
+
+ return TRUE;
+}
+
+Bool
+DRIDestroyContext(ScreenPtr pScreen, XID context)
+{
+ FreeResourceByType(context, DRIContextPrivResType, FALSE);
+
+ return TRUE;
+}
+
+/* DRIContextPrivDelete is called by the resource manager. */
+Bool
+DRIContextPrivDelete(pointer pResource, XID id)
+{
+ DRIContextPrivPtr pDRIContextPriv = (DRIContextPrivPtr)pResource;
+ DRIScreenPrivPtr pDRIPriv;
+ void *contextStore;
+
+ pDRIPriv = DRI_SCREEN_PRIV(pDRIContextPriv->pScreen);
+ if (pDRIPriv->pDriverInfo->DestroyContext) {
+ contextStore = DRIGetContextStore(pDRIContextPriv);
+ pDRIPriv->pDriverInfo->DestroyContext(pDRIContextPriv->pScreen,
+ pDRIContextPriv->hwContext,
+ (DRIContextType)(long)contextStore);
+ }
+ return DRIDestroyContextPriv(pDRIContextPriv);
+}
+
+
+/* This walks the drawable timestamp array and invalidates all of them
+ * in the case of transition from private to shared backbuffers. It's
+ * not necessary for correctness, because DRIClipNotify gets called in
+ * time to prevent any conflict, but the transition from
+ * shared->private is sometimes missed if we don't do this.
+ */
+static void
+DRIClipNotifyAllDrawables(ScreenPtr pScreen)
+{
+ int i;
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ for( i=0; i < pDRIPriv->pDriverInfo->maxDrawableTableEntry; i++) {
+ pDRIPriv->pSAREA->drawableTable[i].stamp = DRIDrawableValidationStamp++;
+ }
+}
+
+
+static void
+DRITransitionToSharedBuffers(ScreenPtr pScreen)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
+
+ DRIClipNotifyAllDrawables( pScreen );
+
+ if (pDRIInfo->TransitionSingleToMulti3D)
+ pDRIInfo->TransitionSingleToMulti3D( pScreen );
+}
+
+
+static void
+DRITransitionToPrivateBuffers(ScreenPtr pScreen)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
+
+ DRIClipNotifyAllDrawables( pScreen );
+
+ if (pDRIInfo->TransitionMultiToSingle3D)
+ pDRIInfo->TransitionMultiToSingle3D( pScreen );
+}
+
+
+static void
+DRITransitionTo3d(ScreenPtr pScreen)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
+
+ DRIClipNotifyAllDrawables( pScreen );
+
+ if (pDRIInfo->TransitionTo3d)
+ pDRIInfo->TransitionTo3d( pScreen );
+}
+
+static void
+DRITransitionTo2d(ScreenPtr pScreen)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
+
+ DRIClipNotifyAllDrawables( pScreen );
+
+ if (pDRIInfo->TransitionTo2d)
+ pDRIInfo->TransitionTo2d( pScreen );
+}
+
+
+static int
+DRIDCNTreeTraversal(WindowPtr pWin, pointer data)
+{
+ DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
+
+ if (pDRIDrawablePriv) {
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if (REGION_NUM_RECTS(&pWin->clipList) > 0) {
+ WindowPtr *pDRIWindows = (WindowPtr*)data;
+ int i = 0;
+
+ while (pDRIWindows[i])
+ i++;
+
+ pDRIWindows[i] = pWin;
+
+ pDRIPriv->nrWalked++;
+ }
+
+ if (pDRIPriv->nrWindows == pDRIPriv->nrWalked)
+ return WT_STOPWALKING;
+ }
+
+ return WT_WALKCHILDREN;
+}
+
+static void
+DRIDriverClipNotify(ScreenPtr pScreen)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if (pDRIPriv->pDriverInfo->ClipNotify) {
+ WindowPtr *pDRIWindows = calloc(sizeof(WindowPtr), pDRIPriv->nrWindows);
+ DRIInfoPtr pDRIInfo = pDRIPriv->pDriverInfo;
+
+ if (pDRIPriv->nrWindows > 0) {
+ pDRIPriv->nrWalked = 0;
+ TraverseTree(WindowTable[pScreen->myNum], DRIDCNTreeTraversal,
+ (pointer)pDRIWindows);
+ }
+
+ pDRIInfo->ClipNotify(pScreen, pDRIWindows, pDRIPriv->nrWindows);
+
+ free(pDRIWindows);
+ }
+}
+
+static void
+DRIIncreaseNumberVisible(ScreenPtr pScreen)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ switch (++pDRIPriv->nrWindowsVisible) {
+ case 1:
+ DRITransitionTo3d( pScreen );
+ break;
+ case 2:
+ DRITransitionToSharedBuffers( pScreen );
+ break;
+ default:
+ break;
+ }
+
+ DRIDriverClipNotify(pScreen);
+}
+
+static void
+DRIDecreaseNumberVisible(ScreenPtr pScreen)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ switch (--pDRIPriv->nrWindowsVisible) {
+ case 0:
+ DRITransitionTo2d( pScreen );
+ break;
+ case 1:
+ DRITransitionToPrivateBuffers( pScreen );
+ break;
+ default:
+ break;
+ }
+
+ DRIDriverClipNotify(pScreen);
+}
+
+Bool
+DRICreateDrawable(ScreenPtr pScreen, ClientPtr client, DrawablePtr pDrawable,
+ drm_drawable_t * hHWDrawable)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIDrawablePrivPtr pDRIDrawablePriv;
+ WindowPtr pWin;
+
+ if (pDrawable->type == DRAWABLE_WINDOW) {
+ pWin = (WindowPtr)pDrawable;
+ if ((pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin))) {
+ pDRIDrawablePriv->refCount++;
+
+ if (!pDRIDrawablePriv->hwDrawable) {
+ drmCreateDrawable(pDRIPriv->drmFD, &pDRIDrawablePriv->hwDrawable);
+ }
+ }
+ else {
+ /* allocate a DRI Window Private record */
+ if (!(pDRIDrawablePriv = malloc(sizeof(DRIDrawablePrivRec)))) {
+ return FALSE;
+ }
+
+ /* Only create a drm_drawable_t once */
+ if (drmCreateDrawable(pDRIPriv->drmFD,
+ &pDRIDrawablePriv->hwDrawable)) {
+ free(pDRIDrawablePriv);
+ return FALSE;
+ }
+
+ /* add it to the list of DRI drawables for this screen */
+ pDRIDrawablePriv->pScreen = pScreen;
+ pDRIDrawablePriv->refCount = 1;
+ pDRIDrawablePriv->drawableIndex = -1;
+ pDRIDrawablePriv->nrects = REGION_NUM_RECTS(&pWin->clipList);
+
+ /* save private off of preallocated index */
+ dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey,
+ pDRIDrawablePriv);
+ pDRIPriv->nrWindows++;
+
+ if (pDRIDrawablePriv->nrects)
+ DRIIncreaseNumberVisible(pScreen);
+ }
+
+ /* track this in case the client dies */
+ AddResource(FakeClientID(client->index), DRIDrawablePrivResType,
+ (pointer)(intptr_t)pDrawable->id);
+
+ if (pDRIDrawablePriv->hwDrawable) {
+ drmUpdateDrawableInfo(pDRIPriv->drmFD,
+ pDRIDrawablePriv->hwDrawable,
+ DRM_DRAWABLE_CLIPRECTS,
+ REGION_NUM_RECTS(&pWin->clipList),
+ REGION_RECTS(&pWin->clipList));
+ *hHWDrawable = pDRIDrawablePriv->hwDrawable;
+ }
+ }
+ else if (pDrawable->type != DRAWABLE_PIXMAP) { /* PBuffer */
+ /* NOT_DONE */
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+DRIDrawablePrivDestroy(WindowPtr pWin)
+{
+ DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
+ ScreenPtr pScreen;
+ DRIScreenPrivPtr pDRIPriv;
+
+ if (!pDRIDrawablePriv)
+ return;
+
+ pScreen = pWin->drawable.pScreen;
+ pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if (pDRIDrawablePriv->drawableIndex != -1) {
+ /* bump stamp to force outstanding 3D requests to resync */
+ pDRIPriv->pSAREA->drawableTable[pDRIDrawablePriv->drawableIndex].stamp
+ = DRIDrawableValidationStamp++;
+
+ /* release drawable table entry */
+ pDRIPriv->DRIDrawables[pDRIDrawablePriv->drawableIndex] = NULL;
+ }
+
+ pDRIPriv->nrWindows--;
+
+ if (pDRIDrawablePriv->nrects)
+ DRIDecreaseNumberVisible(pScreen);
+
+ drmDestroyDrawable(pDRIPriv->drmFD, pDRIDrawablePriv->hwDrawable);
+
+ free(pDRIDrawablePriv);
+ dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey, NULL);
+}
+
+static Bool
+DRIDestroyDrawableCB(pointer value, XID id, pointer data)
+{
+ if (value == data) {
+ /* This calls back DRIDrawablePrivDelete which frees private area */
+ FreeResourceByType(id, DRIDrawablePrivResType, FALSE);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+Bool
+DRIDestroyDrawable(ScreenPtr pScreen, ClientPtr client, DrawablePtr pDrawable)
+{
+ if (pDrawable->type == DRAWABLE_WINDOW) {
+ LookupClientResourceComplex(client, DRIDrawablePrivResType,
+ DRIDestroyDrawableCB,
+ (pointer)(intptr_t)pDrawable->id);
+ }
+ else { /* pixmap (or for GLX 1.3, a PBuffer) */
+ /* NOT_DONE */
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool
+DRIDrawablePrivDelete(pointer pResource, XID id)
+{
+ WindowPtr pWin;
+ int rc;
+
+ /* For DRIDrawablePrivResType, the XID is the client's fake ID. The
+ * important XID is the value in pResource. */
+ id = (XID)(intptr_t)pResource;
+ rc = dixLookupWindow(&pWin, id, serverClient, DixGetAttrAccess);
+
+ if (rc == Success) {
+ DRIDrawablePrivPtr pDRIDrwPriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
+
+ if (!pDRIDrwPriv)
+ return FALSE;
+
+ if (--pDRIDrwPriv->refCount == 0)
+ DRIDrawablePrivDestroy(pWin);
+
+ return TRUE;
+ }
+ else { /* pixmap (or for GLX 1.3, a PBuffer) */
+ /* NOT_DONE */
+ return FALSE;
+ }
+}
+
+Bool
+DRIGetDrawableInfo(ScreenPtr pScreen,
+ DrawablePtr pDrawable,
+ unsigned int* index,
+ unsigned int* stamp,
+ int* X,
+ int* Y,
+ int* W,
+ int* H,
+ int* numClipRects,
+ drm_clip_rect_t ** pClipRects,
+ int* backX,
+ int* backY,
+ int* numBackClipRects,
+ drm_clip_rect_t ** pBackClipRects)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIDrawablePrivPtr pDRIDrawablePriv, pOldDrawPriv;
+ WindowPtr pWin, pOldWin;
+ int i;
+
+#if 0
+ printf("maxDrawableTableEntry = %d\n", pDRIPriv->pDriverInfo->maxDrawableTableEntry);
+#endif
+
+ if (pDrawable->type == DRAWABLE_WINDOW) {
+ pWin = (WindowPtr)pDrawable;
+ if ((pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin))) {
+
+ /* Manage drawable table */
+ if (pDRIDrawablePriv->drawableIndex == -1) { /* load SAREA table */
+
+ /* Search table for empty entry */
+ i = 0;
+ while (i < pDRIPriv->pDriverInfo->maxDrawableTableEntry) {
+ if (!(pDRIPriv->DRIDrawables[i])) {
+ pDRIPriv->DRIDrawables[i] = pDrawable;
+ pDRIDrawablePriv->drawableIndex = i;
+ pDRIPriv->pSAREA->drawableTable[i].stamp =
+ DRIDrawableValidationStamp++;
+ break;
+ }
+ i++;
+ }
+
+ /* Search table for oldest entry */
+ if (i == pDRIPriv->pDriverInfo->maxDrawableTableEntry) {
+ unsigned int oldestStamp = ~0;
+ int oldestIndex = 0;
+ i = pDRIPriv->pDriverInfo->maxDrawableTableEntry;
+ while (i--) {
+ if (pDRIPriv->pSAREA->drawableTable[i].stamp <
+ oldestStamp) {
+ oldestIndex = i;
+ oldestStamp =
+ pDRIPriv->pSAREA->drawableTable[i].stamp;
+ }
+ }
+ pDRIDrawablePriv->drawableIndex = oldestIndex;
+
+ /* release oldest drawable table entry */
+ pOldWin = (WindowPtr)pDRIPriv->DRIDrawables[oldestIndex];
+ pOldDrawPriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pOldWin);
+ pOldDrawPriv->drawableIndex = -1;
+
+ /* claim drawable table entry */
+ pDRIPriv->DRIDrawables[oldestIndex] = pDrawable;
+
+ /* validate SAREA entry */
+ pDRIPriv->pSAREA->drawableTable[oldestIndex].stamp =
+ DRIDrawableValidationStamp++;
+
+ /* check for stamp wrap around */
+ if (oldestStamp > DRIDrawableValidationStamp) {
+
+ /* walk SAREA table and invalidate all drawables */
+ for( i=0;
+ i < pDRIPriv->pDriverInfo->maxDrawableTableEntry;
+ i++) {
+ pDRIPriv->pSAREA->drawableTable[i].stamp =
+ DRIDrawableValidationStamp++;
+ }
+ }
+ }
+
+ /* If the driver wants to be notified when the index is
+ * set for a drawable, let it know now.
+ */
+ if (pDRIPriv->pDriverInfo->SetDrawableIndex)
+ pDRIPriv->pDriverInfo->SetDrawableIndex(pWin,
+ pDRIDrawablePriv->drawableIndex);
+
+ /* reinit drawable ID if window is visible */
+ if ((pWin->viewable) &&
+ (pDRIPriv->pDriverInfo->bufferRequests != DRI_NO_WINDOWS))
+ {
+ (*pDRIPriv->pDriverInfo->InitBuffers)(pWin,
+ &pWin->clipList, pDRIDrawablePriv->drawableIndex);
+ }
+ }
+
+ *index = pDRIDrawablePriv->drawableIndex;
+ *stamp = pDRIPriv->pSAREA->drawableTable[*index].stamp;
+ *X = (int)(pWin->drawable.x);
+ *Y = (int)(pWin->drawable.y);
+#if 0
+ *W = (int)(pWin->winSize.extents.x2 - pWin->winSize.extents.x1);
+ *H = (int)(pWin->winSize.extents.y2 - pWin->winSize.extents.y1);
+#endif
+ *W = (int)(pWin->drawable.width);
+ *H = (int)(pWin->drawable.height);
+ *numClipRects = REGION_NUM_RECTS(&pWin->clipList);
+ *pClipRects = (drm_clip_rect_t *)REGION_RECTS(&pWin->clipList);
+
+ if (!*numClipRects && pDRIPriv->fullscreen) {
+ /* use fake full-screen clip rect */
+ pDRIPriv->fullscreen_rect.x1 = *X;
+ pDRIPriv->fullscreen_rect.y1 = *Y;
+ pDRIPriv->fullscreen_rect.x2 = *X + *W;
+ pDRIPriv->fullscreen_rect.y2 = *Y + *H;
+
+ *numClipRects = 1;
+ *pClipRects = &pDRIPriv->fullscreen_rect;
+ }
+
+ *backX = *X;
+ *backY = *Y;
+
+ if (pDRIPriv->nrWindowsVisible == 1 && *numClipRects) {
+ /* Use a single cliprect. */
+
+ int x0 = *X;
+ int y0 = *Y;
+ int x1 = x0 + *W;
+ int y1 = y0 + *H;
+
+ if (x0 < 0) x0 = 0;
+ if (y0 < 0) y0 = 0;
+ if (x1 > pScreen->width) x1 = pScreen->width;
+ if (y1 > pScreen->height) y1 = pScreen->height;
+
+ if (y0 >= y1 || x0 >= x1) {
+ *numBackClipRects = 0;
+ *pBackClipRects = NULL;
+ } else {
+ pDRIPriv->private_buffer_rect.x1 = x0;
+ pDRIPriv->private_buffer_rect.y1 = y0;
+ pDRIPriv->private_buffer_rect.x2 = x1;
+ pDRIPriv->private_buffer_rect.y2 = y1;
+
+ *numBackClipRects = 1;
+ *pBackClipRects = &(pDRIPriv->private_buffer_rect);
+ }
+ } else {
+ /* Use the frontbuffer cliprects for back buffers. */
+ *numBackClipRects = 0;
+ *pBackClipRects = 0;
+ }
+ }
+ else {
+ /* Not a DRIDrawable */
+ return FALSE;
+ }
+ }
+ else { /* pixmap (or for GLX 1.3, a PBuffer) */
+ /* NOT_DONE */
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+Bool
+DRIGetDeviceInfo(ScreenPtr pScreen,
+ drm_handle_t * hFrameBuffer,
+ int* fbOrigin,
+ int* fbSize,
+ int* fbStride,
+ int* devPrivateSize,
+ void** pDevPrivate)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ *hFrameBuffer = pDRIPriv->pDriverInfo->hFrameBuffer;
+ *fbOrigin = 0;
+ *fbSize = pDRIPriv->pDriverInfo->frameBufferSize;
+ *fbStride = pDRIPriv->pDriverInfo->frameBufferStride;
+ *devPrivateSize = pDRIPriv->pDriverInfo->devPrivateSize;
+ *pDevPrivate = pDRIPriv->pDriverInfo->devPrivate;
+
+ return TRUE;
+}
+
+DRIInfoPtr
+DRICreateInfoRec(void)
+{
+ DRIInfoPtr inforec = (DRIInfoPtr)calloc(1, sizeof(DRIInfoRec));
+ if (!inforec) return NULL;
+
+ /* Initialize defaults */
+ inforec->busIdString = NULL;
+
+ /* Wrapped function defaults */
+ inforec->wrap.WakeupHandler = DRIDoWakeupHandler;
+ inforec->wrap.BlockHandler = DRIDoBlockHandler;
+ inforec->wrap.WindowExposures = DRIWindowExposures;
+ inforec->wrap.CopyWindow = DRICopyWindow;
+ inforec->wrap.ValidateTree = DRIValidateTree;
+ inforec->wrap.PostValidateTree = DRIPostValidateTree;
+ inforec->wrap.ClipNotify = DRIClipNotify;
+ inforec->wrap.AdjustFrame = DRIAdjustFrame;
+
+ inforec->TransitionTo2d = 0;
+ inforec->TransitionTo3d = 0;
+ inforec->SetDrawableIndex = 0;
+
+ return inforec;
+}
+
+void
+DRIDestroyInfoRec(DRIInfoPtr DRIInfo)
+{
+ if (DRIInfo->busIdString) free(DRIInfo->busIdString);
+ free((char*)DRIInfo);
+}
+
+
+void
+DRIWakeupHandler(pointer wakeupData, int result, pointer pReadmask)
+{
+ int i;
+
+ for (i = 0; i < screenInfo.numScreens; i++) {
+ ScreenPtr pScreen = screenInfo.screens[i];
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if (pDRIPriv &&
+ pDRIPriv->pDriverInfo->wrap.WakeupHandler)
+ (*pDRIPriv->pDriverInfo->wrap.WakeupHandler)(i, wakeupData,
+ result, pReadmask);
+ }
+}
+
+void
+DRIBlockHandler(pointer blockData, OSTimePtr pTimeout, pointer pReadmask)
+{
+ int i;
+
+ for (i = 0; i < screenInfo.numScreens; i++) {
+ ScreenPtr pScreen = screenInfo.screens[i];
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if (pDRIPriv &&
+ pDRIPriv->pDriverInfo->wrap.BlockHandler)
+ (*pDRIPriv->pDriverInfo->wrap.BlockHandler)(i, blockData,
+ pTimeout, pReadmask);
+ }
+}
+
+void
+DRIDoWakeupHandler(int screenNum, pointer wakeupData,
+ unsigned long result, pointer pReadmask)
+{
+ ScreenPtr pScreen = screenInfo.screens[screenNum];
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ DRILock(pScreen, 0);
+ if (pDRIPriv->pDriverInfo->driverSwapMethod == DRI_HIDE_X_CONTEXT) {
+ /* hide X context by swapping 2D component here */
+ (*pDRIPriv->pDriverInfo->SwapContext)(pScreen,
+ DRI_3D_SYNC,
+ DRI_2D_CONTEXT,
+ pDRIPriv->partial3DContextStore,
+ DRI_2D_CONTEXT,
+ pDRIPriv->hiddenContextStore);
+ }
+}
+
+void
+DRIDoBlockHandler(int screenNum, pointer blockData,
+ pointer pTimeout, pointer pReadmask)
+{
+ ScreenPtr pScreen = screenInfo.screens[screenNum];
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if (pDRIPriv->pDriverInfo->driverSwapMethod == DRI_HIDE_X_CONTEXT) {
+ /* hide X context by swapping 2D component here */
+ (*pDRIPriv->pDriverInfo->SwapContext)(pScreen,
+ DRI_2D_SYNC,
+ DRI_NO_CONTEXT,
+ NULL,
+ DRI_2D_CONTEXT,
+ pDRIPriv->partial3DContextStore);
+ }
+
+ if (pDRIPriv->windowsTouched)
+ DRM_SPINUNLOCK(&pDRIPriv->pSAREA->drawable_lock, 1);
+ pDRIPriv->windowsTouched = FALSE;
+
+ DRIUnlock(pScreen);
+}
+
+void
+DRISwapContext(int drmFD, void *oldctx, void *newctx)
+{
+ DRIContextPrivPtr oldContext = (DRIContextPrivPtr)oldctx;
+ DRIContextPrivPtr newContext = (DRIContextPrivPtr)newctx;
+ ScreenPtr pScreen = newContext->pScreen;
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ void* oldContextStore = NULL;
+ DRIContextType oldContextType;
+ void* newContextStore = NULL;
+ DRIContextType newContextType;
+ DRISyncType syncType;
+#ifdef DEBUG
+ static int count = 0;
+
+ if (!newContext) {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI] Context Switch Error: oldContext=%x, newContext=%x\n",
+ oldContext, newContext);
+ return;
+ }
+
+ /* usefull for debugging, just print out after n context switches */
+ if (!count || !(count % 1)) {
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "[DRI] Context switch %5d from %p/0x%08x (%d)\n",
+ count,
+ oldContext,
+ oldContext ? oldContext->flags : 0,
+ oldContext ? oldContext->hwContext : -1);
+ DRIDrvMsg(pScreen->myNum, X_INFO,
+ "[DRI] Context switch %5d to %p/0x%08x (%d)\n",
+ count,
+ newContext,
+ newContext ? newContext->flags : 0,
+ newContext ? newContext->hwContext : -1);
+ }
+ ++count;
+#endif
+
+ if (!pDRIPriv->pDriverInfo->SwapContext) {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI] DDX driver missing context swap call back\n");
+ return;
+ }
+
+ if (pDRIPriv->pDriverInfo->driverSwapMethod == DRI_HIDE_X_CONTEXT) {
+
+ /* only 3D contexts are swapped in this case */
+ if (oldContext) {
+ oldContextStore = DRIGetContextStore(oldContext);
+ oldContext->valid3D = TRUE;
+ oldContextType = DRI_3D_CONTEXT;
+ } else {
+ oldContextType = DRI_NO_CONTEXT;
+ }
+ newContextStore = DRIGetContextStore(newContext);
+ if ((newContext->valid3D) &&
+ (newContext->hwContext != pDRIPriv->myContext)) {
+ newContextType = DRI_3D_CONTEXT;
+ }
+ else {
+ newContextType = DRI_2D_CONTEXT;
+ }
+ syncType = DRI_3D_SYNC;
+ }
+ else /* default: driverSwapMethod == DRI_SERVER_SWAP */ {
+
+ /* optimize 2D context swaps */
+
+ if (newContext->flags & DRI_CONTEXT_2DONLY) {
+ /* go from 3D context to 2D context and only save 2D
+ * subset of 3D state
+ */
+ oldContextStore = DRIGetContextStore(oldContext);
+ oldContextType = DRI_2D_CONTEXT;
+ newContextStore = DRIGetContextStore(newContext);
+ newContextType = DRI_2D_CONTEXT;
+ syncType = DRI_3D_SYNC;
+ pDRIPriv->lastPartial3DContext = oldContext;
+ }
+ else if (oldContext->flags & DRI_CONTEXT_2DONLY) {
+ if (pDRIPriv->lastPartial3DContext == newContext) {
+ /* go from 2D context back to previous 3D context and
+ * only restore 2D subset of previous 3D state
+ */
+ oldContextStore = DRIGetContextStore(oldContext);
+ oldContextType = DRI_2D_CONTEXT;
+ newContextStore = DRIGetContextStore(newContext);
+ newContextType = DRI_2D_CONTEXT;
+ syncType = DRI_2D_SYNC;
+ }
+ else {
+ /* go from 2D context to a different 3D context */
+
+ /* call DDX driver to do partial restore */
+ oldContextStore = DRIGetContextStore(oldContext);
+ newContextStore =
+ DRIGetContextStore(pDRIPriv->lastPartial3DContext);
+ (*pDRIPriv->pDriverInfo->SwapContext)(pScreen,
+ DRI_2D_SYNC,
+ DRI_2D_CONTEXT,
+ oldContextStore,
+ DRI_2D_CONTEXT,
+ newContextStore);
+
+ /* now setup for a complete 3D swap */
+ oldContextStore = newContextStore;
+ oldContext->valid3D = TRUE;
+ oldContextType = DRI_3D_CONTEXT;
+ newContextStore = DRIGetContextStore(newContext);
+ if ((newContext->valid3D) &&
+ (newContext->hwContext != pDRIPriv->myContext)) {
+ newContextType = DRI_3D_CONTEXT;
+ }
+ else {
+ newContextType = DRI_2D_CONTEXT;
+ }
+ syncType = DRI_NO_SYNC;
+ }
+ }
+ else {
+ /* now setup for a complete 3D swap */
+ oldContextStore = newContextStore;
+ oldContext->valid3D = TRUE;
+ oldContextType = DRI_3D_CONTEXT;
+ newContextStore = DRIGetContextStore(newContext);
+ if ((newContext->valid3D) &&
+ (newContext->hwContext != pDRIPriv->myContext)) {
+ newContextType = DRI_3D_CONTEXT;
+ }
+ else {
+ newContextType = DRI_2D_CONTEXT;
+ }
+ syncType = DRI_3D_SYNC;
+ }
+ }
+
+ /* call DDX driver to perform the swap */
+ (*pDRIPriv->pDriverInfo->SwapContext)(pScreen,
+ syncType,
+ oldContextType,
+ oldContextStore,
+ newContextType,
+ newContextStore);
+}
+
+void*
+DRIGetContextStore(DRIContextPrivPtr context)
+{
+ return((void *)context->pContextStore);
+}
+
+void
+DRIWindowExposures(WindowPtr pWin, RegionPtr prgn, RegionPtr bsreg)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
+
+ if(pDRIDrawablePriv) {
+ (*pDRIPriv->pDriverInfo->InitBuffers)(pWin, prgn,
+ pDRIDrawablePriv->drawableIndex);
+ }
+
+ /* call lower wrapped functions */
+ if (pDRIPriv && pDRIPriv->wrap.WindowExposures) {
+
+ /* unwrap */
+ pScreen->WindowExposures = pDRIPriv->wrap.WindowExposures;
+
+ /* call lower layers */
+ (*pScreen->WindowExposures)(pWin, prgn, bsreg);
+
+ /* rewrap */
+ pDRIPriv->wrap.WindowExposures = pScreen->WindowExposures;
+ pScreen->WindowExposures = DRIWindowExposures;
+ }
+}
+
+
+static int
+DRITreeTraversal(WindowPtr pWin, pointer data)
+{
+ DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
+
+ if(pDRIDrawablePriv) {
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if(REGION_NUM_RECTS(&(pWin->clipList)) > 0) {
+ RegionPtr reg = (RegionPtr)data;
+
+ REGION_UNION(pScreen, reg, reg, &(pWin->clipList));
+ pDRIPriv->nrWalked++;
+ }
+
+ if(pDRIPriv->nrWindows == pDRIPriv->nrWalked)
+ return WT_STOPWALKING;
+ }
+ return WT_WALKCHILDREN;
+}
+
+Bool
+DRIDestroyWindow(WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ Bool retval = TRUE;
+
+ DRIDrawablePrivDestroy(pWin);
+
+ /* call lower wrapped functions */
+ if(pDRIPriv->DestroyWindow) {
+ /* unwrap */
+ pScreen->DestroyWindow = pDRIPriv->DestroyWindow;
+
+ /* call lower layers */
+ retval = (*pScreen->DestroyWindow)(pWin);
+
+ /* rewrap */
+ pDRIPriv->DestroyWindow = pScreen->DestroyWindow;
+ pScreen->DestroyWindow = DRIDestroyWindow;
+ }
+
+ return retval;
+}
+
+void
+DRICopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if(!pDRIPriv) return;
+
+ if(pDRIPriv->nrWindowsVisible > 0) {
+ RegionRec reg;
+
+ REGION_NULL(pScreen, &reg);
+ pDRIPriv->nrWalked = 0;
+ TraverseTree(pWin, DRITreeTraversal, (pointer)(&reg));
+
+ if(REGION_NOTEMPTY(pScreen, &reg)) {
+ REGION_TRANSLATE(pScreen, &reg, ptOldOrg.x - pWin->drawable.x,
+ ptOldOrg.y - pWin->drawable.y);
+ REGION_INTERSECT(pScreen, &reg, &reg, prgnSrc);
+
+ /* The MoveBuffers interface is not ideal */
+ (*pDRIPriv->pDriverInfo->MoveBuffers)(pWin, ptOldOrg, &reg,
+ pDRIPriv->pDriverInfo->ddxDrawableTableEntry);
+ }
+
+ REGION_UNINIT(pScreen, &reg);
+ }
+
+ /* call lower wrapped functions */
+ if(pDRIPriv->wrap.CopyWindow) {
+ /* unwrap */
+ pScreen->CopyWindow = pDRIPriv->wrap.CopyWindow;
+
+ /* call lower layers */
+ (*pScreen->CopyWindow)(pWin, ptOldOrg, prgnSrc);
+
+ /* rewrap */
+ pDRIPriv->wrap.CopyWindow = pScreen->CopyWindow;
+ pScreen->CopyWindow = DRICopyWindow;
+ }
+}
+
+static void
+DRIGetSecs(long *secs, long *usecs)
+{
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+
+ *secs = tv.tv_sec;
+ *usecs = tv.tv_usec;
+}
+
+static unsigned long
+DRIComputeMilliSeconds(unsigned long s_secs, unsigned long s_usecs,
+ unsigned long f_secs, unsigned long f_usecs)
+{
+ if (f_usecs < s_usecs) {
+ --f_secs;
+ f_usecs += 1000000;
+ }
+ return (f_secs - s_secs) * 1000 + (f_usecs - s_usecs) / 1000;
+}
+
+static void
+DRISpinLockTimeout(drmLock *lock, int val, unsigned long timeout /* in mS */)
+{
+ int count = 10000;
+#if !defined(__alpha__) && !defined(__powerpc__)
+ char ret;
+#else
+ int ret;
+#endif
+ long s_secs, s_usecs;
+ long f_secs, f_usecs;
+ long msecs;
+ long prev = 0;
+
+ DRIGetSecs(&s_secs, &s_usecs);
+
+ do {
+ DRM_SPINLOCK_COUNT(lock, val, count, ret);
+ if (!ret) return; /* Got lock */
+ DRIGetSecs(&f_secs, &f_usecs);
+ msecs = DRIComputeMilliSeconds(s_secs, s_usecs, f_secs, f_usecs);
+ if (msecs - prev < 250) count *= 2; /* Not more than 0.5S */
+ } while (msecs < timeout);
+
+ /* Didn't get lock, so take it. The worst
+ that can happen is that there is some
+ garbage written to the wrong part of the
+ framebuffer that a refresh will repair.
+ That's undesirable, but better than
+ locking the server. This should be a
+ very rare event. */
+ DRM_SPINLOCK_TAKE(lock, val);
+}
+
+static void
+DRILockTree(ScreenPtr pScreen)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if(!pDRIPriv) return;
+
+ /* Restore the last known 3D context if the X context is hidden */
+ if (pDRIPriv->pDriverInfo->driverSwapMethod == DRI_HIDE_X_CONTEXT) {
+ (*pDRIPriv->pDriverInfo->SwapContext)(pScreen,
+ DRI_2D_SYNC,
+ DRI_NO_CONTEXT,
+ NULL,
+ DRI_2D_CONTEXT,
+ pDRIPriv->partial3DContextStore);
+ }
+
+ /* Call kernel to release lock */
+ DRIUnlock(pScreen);
+
+ /* Grab drawable spin lock: a time out between 10 and 30 seconds is
+ appropriate, since this should never time out except in the case of
+ client death while the lock is being held. The timeout must be
+ greater than any reasonable rendering time. */
+ DRISpinLockTimeout(&pDRIPriv->pSAREA->drawable_lock, 1, 10000); /*10 secs*/
+
+ /* Call kernel flush outstanding buffers and relock */
+ DRILock(pScreen, DRM_LOCK_QUIESCENT|DRM_LOCK_FLUSH_ALL);
+
+ /* Switch back to our 2D context if the X context is hidden */
+ if (pDRIPriv->pDriverInfo->driverSwapMethod == DRI_HIDE_X_CONTEXT) {
+ /* hide X context by swapping 2D component here */
+ (*pDRIPriv->pDriverInfo->SwapContext)(pScreen,
+ DRI_3D_SYNC,
+ DRI_2D_CONTEXT,
+ pDRIPriv->partial3DContextStore,
+ DRI_2D_CONTEXT,
+ pDRIPriv->hiddenContextStore);
+ }
+}
+
+int
+DRIValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind)
+{
+ ScreenPtr pScreen = pParent->drawable.pScreen;
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ int returnValue = 1; /* always return 1, not checked by dix/window.c */
+
+ if(!pDRIPriv) return returnValue;
+
+ /* call lower wrapped functions */
+ if(pDRIPriv->wrap.ValidateTree) {
+ /* unwrap */
+ pScreen->ValidateTree = pDRIPriv->wrap.ValidateTree;
+
+ /* call lower layers */
+ returnValue = (*pScreen->ValidateTree)(pParent, pChild, kind);
+
+ /* rewrap */
+ pDRIPriv->wrap.ValidateTree = pScreen->ValidateTree;
+ pScreen->ValidateTree = DRIValidateTree;
+ }
+
+ return returnValue;
+}
+
+void
+DRIPostValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind)
+{
+ ScreenPtr pScreen;
+ DRIScreenPrivPtr pDRIPriv;
+
+ if (pParent) {
+ pScreen = pParent->drawable.pScreen;
+ } else {
+ pScreen = pChild->drawable.pScreen;
+ }
+ if(!(pDRIPriv = DRI_SCREEN_PRIV(pScreen))) return;
+
+ if (pDRIPriv->wrap.PostValidateTree) {
+ /* unwrap */
+ pScreen->PostValidateTree = pDRIPriv->wrap.PostValidateTree;
+
+ /* call lower layers */
+ (*pScreen->PostValidateTree)(pParent, pChild, kind);
+
+ /* rewrap */
+ pDRIPriv->wrap.PostValidateTree = pScreen->PostValidateTree;
+ pScreen->PostValidateTree = DRIPostValidateTree;
+ }
+}
+
+void
+DRIClipNotify(WindowPtr pWin, int dx, int dy)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIDrawablePrivPtr pDRIDrawablePriv;
+
+ if(!pDRIPriv) return;
+
+ if ((pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin))) {
+ int nrects = REGION_NUM_RECTS(&pWin->clipList);
+
+ if(!pDRIPriv->windowsTouched) {
+ DRILockTree(pScreen);
+ pDRIPriv->windowsTouched = TRUE;
+ }
+
+ if (nrects && !pDRIDrawablePriv->nrects)
+ DRIIncreaseNumberVisible(pScreen);
+ else if (!nrects && pDRIDrawablePriv->nrects)
+ DRIDecreaseNumberVisible(pScreen);
+ else
+ DRIDriverClipNotify(pScreen);
+
+ pDRIDrawablePriv->nrects = nrects;
+
+ pDRIPriv->pSAREA->drawableTable[pDRIDrawablePriv->drawableIndex].stamp
+ = DRIDrawableValidationStamp++;
+
+ drmUpdateDrawableInfo(pDRIPriv->drmFD, pDRIDrawablePriv->hwDrawable,
+ DRM_DRAWABLE_CLIPRECTS,
+ nrects, REGION_RECTS(&pWin->clipList));
+ }
+
+ /* call lower wrapped functions */
+ if(pDRIPriv->wrap.ClipNotify) {
+
+ /* unwrap */
+ pScreen->ClipNotify = pDRIPriv->wrap.ClipNotify;
+
+ /* call lower layers */
+ (*pScreen->ClipNotify)(pWin, dx, dy);
+
+ /* rewrap */
+ pDRIPriv->wrap.ClipNotify = pScreen->ClipNotify;
+ pScreen->ClipNotify = DRIClipNotify;
+ }
+}
+
+CARD32
+DRIGetDrawableIndex(WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
+ CARD32 index;
+
+ if (pDRIDrawablePriv) {
+ index = pDRIDrawablePriv->drawableIndex;
+ }
+ else {
+ index = pDRIPriv->pDriverInfo->ddxDrawableTableEntry;
+ }
+
+ return index;
+}
+
+unsigned int
+DRIGetDrawableStamp(ScreenPtr pScreen, CARD32 drawable_index)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ return pDRIPriv->pSAREA->drawableTable[drawable_index].stamp;
+}
+
+
+void
+DRIPrintDrawableLock(ScreenPtr pScreen, char *msg)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ ErrorF("%s: %d\n", msg, pDRIPriv->pSAREA->drawable_lock.lock);
+}
+
+void
+DRILock(ScreenPtr pScreen, int flags)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if(!pDRIPriv || !pDRIPriv->pLockRefCount) return;
+
+ if (!*pDRIPriv->pLockRefCount) {
+ DRM_LOCK(pDRIPriv->drmFD, pDRIPriv->pLSAREA, pDRIPriv->myContext, flags);
+ *pDRIPriv->pLockingContext = pDRIPriv->myContext;
+ } else if (*pDRIPriv->pLockingContext != pDRIPriv->myContext) {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI] Locking deadlock.\n"
+ "\tAlready locked with context %d,\n"
+ "\ttrying to lock with context %d.\n",
+ pDRIPriv->pLockingContext,
+ pDRIPriv->myContext);
+ }
+ (*pDRIPriv->pLockRefCount)++;
+}
+
+void
+DRIUnlock(ScreenPtr pScreen)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if(!pDRIPriv || !pDRIPriv->pLockRefCount) return;
+
+ if (*pDRIPriv->pLockRefCount > 0) {
+ if (pDRIPriv->myContext != *pDRIPriv->pLockingContext) {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "[DRI] Unlocking inconsistency:\n"
+ "\tContext %d trying to unlock lock held by context %d\n",
+ pDRIPriv->pLockingContext,
+ pDRIPriv->myContext);
+ }
+ (*pDRIPriv->pLockRefCount)--;
+ } else {
+ DRIDrvMsg(pScreen->myNum, X_ERROR,
+ "DRIUnlock called when not locked.\n");
+ return;
+ }
+ if (! *pDRIPriv->pLockRefCount)
+ DRM_UNLOCK(pDRIPriv->drmFD, pDRIPriv->pLSAREA, pDRIPriv->myContext);
+}
+
+void *
+DRIGetSAREAPrivate(ScreenPtr pScreen)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ if (!pDRIPriv) return 0;
+
+ return (void *)(((char*)pDRIPriv->pSAREA)+sizeof(XF86DRISAREARec));
+}
+
+drm_context_t
+DRIGetContext(ScreenPtr pScreen)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ if (!pDRIPriv) return 0;
+
+ return pDRIPriv->myContext;
+}
+
+void
+DRIGetTexOffsetFuncs(ScreenPtr pScreen,
+ DRITexOffsetStartProcPtr *texOffsetStartFunc,
+ DRITexOffsetFinishProcPtr *texOffsetFinishFunc)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if (!pDRIPriv) return;
+
+ *texOffsetStartFunc = pDRIPriv->pDriverInfo->texOffsetStart;
+ *texOffsetFinishFunc = pDRIPriv->pDriverInfo->texOffsetFinish;
+}
+
+/* This lets get at the unwrapped functions so that they can correctly
+ * call the lowerlevel functions, and choose whether they will be
+ * called at every level of recursion (eg in validatetree).
+ */
+DRIWrappedFuncsRec *
+DRIGetWrappedFuncs(ScreenPtr pScreen)
+{
+ return &(DRI_SCREEN_PRIV(pScreen)->wrap);
+}
+
+/* note that this returns the library version, not the protocol version */
+void
+DRIQueryVersion(int *majorVersion,
+ int *minorVersion,
+ int *patchVersion)
+{
+ *majorVersion = DRIINFO_MAJOR_VERSION;
+ *minorVersion = DRIINFO_MINOR_VERSION;
+ *patchVersion = DRIINFO_PATCH_VERSION;
+}
+
+static void
+_DRIAdjustFrame(ScrnInfoPtr pScrn, DRIScreenPrivPtr pDRIPriv, int x, int y)
+{
+ pDRIPriv->pSAREA->frame.x = x;
+ pDRIPriv->pSAREA->frame.y = y;
+ pDRIPriv->pSAREA->frame.width = pScrn->frameX1 - x + 1;
+ pDRIPriv->pSAREA->frame.height = pScrn->frameY1 - y + 1;
+}
+
+void
+DRIAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ ScreenPtr pScreen = screenInfo.screens[scrnIndex];
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ int px, py;
+
+ if (!pDRIPriv || !pDRIPriv->pSAREA) {
+ DRIDrvMsg(scrnIndex, X_ERROR, "[DRI] No SAREA (%p %p)\n",
+ pDRIPriv, pDRIPriv ? pDRIPriv->pSAREA : NULL);
+ return;
+ }
+
+ if (pDRIPriv->fullscreen) {
+ /* Fix up frame */
+ pScrn->frameX0 = pDRIPriv->pSAREA->frame.x;
+ pScrn->frameY0 = pDRIPriv->pSAREA->frame.y;
+ pScrn->frameX1 = pScrn->frameX0 + pDRIPriv->pSAREA->frame.width - 1;
+ pScrn->frameY1 = pScrn->frameY0 + pDRIPriv->pSAREA->frame.height - 1;
+
+ /* Fix up cursor */
+ miPointerGetPosition(inputInfo.pointer, &px, &py);
+ if (px < pScrn->frameX0) px = pScrn->frameX0;
+ if (px > pScrn->frameX1) px = pScrn->frameX1;
+ if (py < pScrn->frameY0) py = pScrn->frameY0;
+ if (py > pScrn->frameY1) py = pScrn->frameY1;
+ pScreen->SetCursorPosition(inputInfo.pointer, pScreen, px, py, TRUE);
+ return;
+ }
+
+ if (pDRIPriv->wrap.AdjustFrame) {
+ /* unwrap */
+ pScrn->AdjustFrame = pDRIPriv->wrap.AdjustFrame;
+ /* call lower layers */
+ (*pScrn->AdjustFrame)(scrnIndex, x, y, flags);
+ /* rewrap */
+ pDRIPriv->wrap.AdjustFrame = pScrn->AdjustFrame;
+ pScrn->AdjustFrame = DRIAdjustFrame;
+ }
+
+ _DRIAdjustFrame(pScrn, pDRIPriv, x, y);
+}
+
+/*
+ * DRIMoveBuffersHelper swaps the regions rects in place leaving you
+ * a region with the rects in the order that you need to blit them,
+ * but it is possibly (likely) an invalid region afterwards. If you
+ * need to use the region again for anything you have to call
+ * REGION_VALIDATE on it, or better yet, save a copy first.
+ */
+
+void
+DRIMoveBuffersHelper(
+ ScreenPtr pScreen,
+ int dx,
+ int dy,
+ int *xdir,
+ int *ydir,
+ RegionPtr reg
+)
+{
+ BoxPtr extents, pbox, firstBox, lastBox;
+ BoxRec tmpBox;
+ int y, nbox;
+
+ extents = REGION_EXTENTS(pScreen, reg);
+ nbox = REGION_NUM_RECTS(reg);
+ pbox = REGION_RECTS(reg);
+
+ if((dy > 0) && (dy < (extents->y2 - extents->y1))) {
+ *ydir = -1;
+ if(nbox > 1) {
+ firstBox = pbox;
+ lastBox = pbox + nbox - 1;
+ while((unsigned long)firstBox < (unsigned long)lastBox) {
+ tmpBox = *firstBox;
+ *firstBox = *lastBox;
+ *lastBox = tmpBox;
+ firstBox++;
+ lastBox--;
+ }
+ }
+ } else *ydir = 1;
+
+ if((dx > 0) && (dx < (extents->x2 - extents->x1))) {
+ *xdir = -1;
+ if(nbox > 1) {
+ firstBox = lastBox = pbox;
+ y = pbox->y1;
+ while(--nbox) {
+ pbox++;
+ if(pbox->y1 == y) lastBox++;
+ else {
+ while((unsigned long)firstBox < (unsigned long)lastBox) {
+ tmpBox = *firstBox;
+ *firstBox = *lastBox;
+ *lastBox = tmpBox;
+ firstBox++;
+ lastBox--;
+ }
+
+ firstBox = lastBox = pbox;
+ y = pbox->y1;
+ }
+ }
+ while((unsigned long)firstBox < (unsigned long)lastBox) {
+ tmpBox = *firstBox;
+ *firstBox = *lastBox;
+ *lastBox = tmpBox;
+ firstBox++;
+ lastBox--;
+ }
+ }
+ } else *xdir = 1;
+
+}
+
+char *
+DRICreatePCIBusID(const struct pci_device * dev)
+{
+ char *busID;
+
+ busID = malloc(20);
+ if (busID == NULL)
+ return NULL;
+
+ snprintf(busID, 20, "pci:%04x:%02x:%02x.%d", dev->domain, dev->bus,
+ dev->dev, dev->func);
+
+ return busID;
+}
+
+static void drmSIGIOHandler(int interrupt, void *closure)
+{
+ unsigned long key;
+ void *value;
+ ssize_t count;
+ drm_ctx_t ctx;
+ typedef void (*_drmCallback)(int, void *, void *);
+ char buf[256];
+ drm_context_t old;
+ drm_context_t new;
+ void *oldctx;
+ void *newctx;
+ char *pt;
+ drmHashEntry *entry;
+ void *hash_table;
+
+ hash_table = drmGetHashTable();
+
+ if (!hash_table) return;
+ if (drmHashFirst(hash_table, &key, &value)) {
+ entry = value;
+ do {
+#if 0
+ fprintf(stderr, "Trying %d\n", entry->fd);
+#endif
+ if ((count = read(entry->fd, buf, sizeof(buf) - 1)) > 0) {
+ buf[count] = '\0';
+#if 0
+ fprintf(stderr, "Got %s\n", buf);
+#endif
+
+ for (pt = buf; *pt != ' '; ++pt); /* Find first space */
+ ++pt;
+ old = strtol(pt, &pt, 0);
+ new = strtol(pt, NULL, 0);
+ oldctx = drmGetContextTag(entry->fd, old);
+ newctx = drmGetContextTag(entry->fd, new);
+#if 0
+ fprintf(stderr, "%d %d %p %p\n", old, new, oldctx, newctx);
+#endif
+ ((_drmCallback)entry->f)(entry->fd, oldctx, newctx);
+ ctx.handle = new;
+ ioctl(entry->fd, DRM_IOCTL_NEW_CTX, &ctx);
+ }
+ } while (drmHashNext(hash_table, &key, &value));
+ }
+}
+
+
+int drmInstallSIGIOHandler(int fd, void (*f)(int, void *, void *))
+{
+ drmHashEntry *entry;
+
+ entry = drmGetEntry(fd);
+ entry->f = f;
+
+ return xf86InstallSIGIOHandler(fd, drmSIGIOHandler, 0);
+}
+
+int drmRemoveSIGIOHandler(int fd)
+{
+ drmHashEntry *entry = drmGetEntry(fd);
+
+ entry->f = NULL;
+
+ return xf86RemoveSIGIOHandler(fd);
+}
diff --git a/xorg-server/hw/xfree86/dri/xf86dri.c b/xorg-server/hw/xfree86/dri/xf86dri.c
index 78003991b..40914ed19 100644
--- a/xorg-server/hw/xfree86/dri/xf86dri.c
+++ b/xorg-server/hw/xfree86/dri/xf86dri.c
@@ -1,679 +1,679 @@
-/**************************************************************************
-
-Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
-Copyright 2000 VA Linux Systems, 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, sub license, 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 (including the
-next paragraph) 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 NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Kevin E. Martin <martin@valinux.com>
- * Jens Owen <jens@tungstengraphics.com>
- * Rickard E. (Rik) Faith <faith@valinux.com>
- *
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <string.h>
-
-#include "xf86.h"
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "dixstruct.h"
-#include "extnsionst.h"
-#include "colormapst.h"
-#include "cursorstr.h"
-#include "scrnintstr.h"
-#include "servermd.h"
-#define _XF86DRI_SERVER_
-#include <X11/dri/xf86driproto.h>
-#include "swaprep.h"
-#include "xf86str.h"
-#include "dri.h"
-#include "sarea.h"
-#include "dristruct.h"
-#include "xf86.h"
-#include "xf86drm.h"
-#include "protocol-versions.h"
-
-static int DRIErrorBase;
-
-static DISPATCH_PROC(ProcXF86DRIQueryVersion);
-static DISPATCH_PROC(ProcXF86DRIQueryDirectRenderingCapable);
-static DISPATCH_PROC(ProcXF86DRIOpenConnection);
-static DISPATCH_PROC(ProcXF86DRICloseConnection);
-static DISPATCH_PROC(ProcXF86DRIGetClientDriverName);
-static DISPATCH_PROC(ProcXF86DRICreateContext);
-static DISPATCH_PROC(ProcXF86DRIDestroyContext);
-static DISPATCH_PROC(ProcXF86DRICreateDrawable);
-static DISPATCH_PROC(ProcXF86DRIDestroyDrawable);
-static DISPATCH_PROC(ProcXF86DRIGetDrawableInfo);
-static DISPATCH_PROC(ProcXF86DRIGetDeviceInfo);
-static DISPATCH_PROC(ProcXF86DRIDispatch);
-static DISPATCH_PROC(ProcXF86DRIAuthConnection);
-
-static DISPATCH_PROC(SProcXF86DRIQueryVersion);
-static DISPATCH_PROC(SProcXF86DRIQueryDirectRenderingCapable);
-static DISPATCH_PROC(SProcXF86DRIDispatch);
-
-static void XF86DRIResetProc(ExtensionEntry* extEntry);
-
-static unsigned char DRIReqCode = 0;
-
-extern void XFree86DRIExtensionInit(void);
-
-void
-XFree86DRIExtensionInit(void)
-{
- ExtensionEntry* extEntry;
-
-#ifdef XF86DRI_EVENTS
- EventType = CreateNewResourceType(XF86DRIFreeEvents, "DRIEvent");
-#endif
-
- if (
- DRIExtensionInit() &&
-#ifdef XF86DRI_EVENTS
- EventType && ScreenPrivateIndex != -1 &&
-#endif
- (extEntry = AddExtension(XF86DRINAME,
- XF86DRINumberEvents,
- XF86DRINumberErrors,
- ProcXF86DRIDispatch,
- SProcXF86DRIDispatch,
- XF86DRIResetProc,
- StandardMinorOpcode))) {
- DRIReqCode = (unsigned char)extEntry->base;
- DRIErrorBase = extEntry->errorBase;
- }
-}
-
-/*ARGSUSED*/
-static void
-XF86DRIResetProc (
- ExtensionEntry* extEntry
-)
-{
- DRIReset();
-}
-
-static int
-ProcXF86DRIQueryVersion(
- register ClientPtr client
-)
-{
- xXF86DRIQueryVersionReply rep;
- register int n;
-
- REQUEST_SIZE_MATCH(xXF86DRIQueryVersionReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.majorVersion = SERVER_XF86DRI_MAJOR_VERSION;
- rep.minorVersion = SERVER_XF86DRI_MINOR_VERSION;
- rep.patchVersion = SERVER_XF86DRI_PATCH_VERSION;
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- swaps(&rep.majorVersion, n);
- swaps(&rep.minorVersion, n);
- swapl(&rep.patchVersion, n);
- }
- WriteToClient(client, sizeof(xXF86DRIQueryVersionReply), (char *)&rep);
- return (client->noClientException);
-}
-
-static int
-ProcXF86DRIQueryDirectRenderingCapable(
- register ClientPtr client
-)
-{
- xXF86DRIQueryDirectRenderingCapableReply rep;
- Bool isCapable;
- register int n;
-
- REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
- REQUEST_SIZE_MATCH(xXF86DRIQueryDirectRenderingCapableReq);
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- if (!DRIQueryDirectRenderingCapable( screenInfo.screens[stuff->screen],
- &isCapable)) {
- return BadValue;
- }
- rep.isCapable = isCapable;
-
- if (!LocalClient(client) || client->swapped)
- rep.isCapable = 0;
-
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- }
-
- WriteToClient(client,
- sizeof(xXF86DRIQueryDirectRenderingCapableReply), (char *)&rep);
- return (client->noClientException);
-}
-
-static int
-ProcXF86DRIOpenConnection(
- register ClientPtr client
-)
-{
- xXF86DRIOpenConnectionReply rep;
- drm_handle_t hSAREA;
- char* busIdString;
-
- REQUEST(xXF86DRIOpenConnectionReq);
- REQUEST_SIZE_MATCH(xXF86DRIOpenConnectionReq);
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- if (!DRIOpenConnection( screenInfo.screens[stuff->screen],
- &hSAREA,
- &busIdString)) {
- return BadValue;
- }
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.busIdStringLength = 0;
- if (busIdString)
- rep.busIdStringLength = strlen(busIdString);
- rep.length = bytes_to_int32(SIZEOF(xXF86DRIOpenConnectionReply) - SIZEOF(xGenericReply) +
- pad_to_int32(rep.busIdStringLength));
-
- rep.hSAREALow = (CARD32)(hSAREA & 0xffffffff);
-#if defined(LONG64) && !defined(__linux__)
- rep.hSAREAHigh = (CARD32)(hSAREA >> 32);
-#else
- rep.hSAREAHigh = 0;
-#endif
-
- WriteToClient(client, sizeof(xXF86DRIOpenConnectionReply), (char *)&rep);
- if (rep.busIdStringLength)
- WriteToClient(client, rep.busIdStringLength, busIdString);
- return (client->noClientException);
-}
-
-static int
-ProcXF86DRIAuthConnection(
- register ClientPtr client
-)
-{
- xXF86DRIAuthConnectionReply rep;
-
- REQUEST(xXF86DRIAuthConnectionReq);
- REQUEST_SIZE_MATCH(xXF86DRIAuthConnectionReq);
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.authenticated = 1;
-
- if (!DRIAuthConnection( screenInfo.screens[stuff->screen], stuff->magic)) {
- ErrorF("Failed to authenticate %lu\n", (unsigned long)stuff->magic);
- rep.authenticated = 0;
- }
- WriteToClient(client, sizeof(xXF86DRIAuthConnectionReply), (char *)&rep);
- return (client->noClientException);
-}
-
-static int
-ProcXF86DRICloseConnection(
- register ClientPtr client
-)
-{
- REQUEST(xXF86DRICloseConnectionReq);
- REQUEST_SIZE_MATCH(xXF86DRICloseConnectionReq);
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- DRICloseConnection( screenInfo.screens[stuff->screen]);
-
- return (client->noClientException);
-}
-
-static int
-ProcXF86DRIGetClientDriverName(
- register ClientPtr client
-)
-{
- xXF86DRIGetClientDriverNameReply rep;
- char* clientDriverName;
-
- REQUEST(xXF86DRIGetClientDriverNameReq);
- REQUEST_SIZE_MATCH(xXF86DRIGetClientDriverNameReq);
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- DRIGetClientDriverName( screenInfo.screens[stuff->screen],
- (int *)&rep.ddxDriverMajorVersion,
- (int *)&rep.ddxDriverMinorVersion,
- (int *)&rep.ddxDriverPatchVersion,
- &clientDriverName);
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.clientDriverNameLength = 0;
- if (clientDriverName)
- rep.clientDriverNameLength = strlen(clientDriverName);
- rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetClientDriverNameReply) -
- SIZEOF(xGenericReply) +
- pad_to_int32(rep.clientDriverNameLength));
-
- WriteToClient(client,
- sizeof(xXF86DRIGetClientDriverNameReply), (char *)&rep);
- if (rep.clientDriverNameLength)
- WriteToClient(client,
- rep.clientDriverNameLength,
- clientDriverName);
- return (client->noClientException);
-}
-
-static int
-ProcXF86DRICreateContext(
- register ClientPtr client
-)
-{
- xXF86DRICreateContextReply rep;
- ScreenPtr pScreen;
-
- REQUEST(xXF86DRICreateContextReq);
- REQUEST_SIZE_MATCH(xXF86DRICreateContextReq);
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- pScreen = screenInfo.screens[stuff->screen];
-
- if (!DRICreateContext( pScreen,
- NULL,
- stuff->context,
- (drm_context_t *)&rep.hHWContext)) {
- return BadValue;
- }
-
- WriteToClient(client, sizeof(xXF86DRICreateContextReply), (char *)&rep);
- return (client->noClientException);
-}
-
-static int
-ProcXF86DRIDestroyContext(
- register ClientPtr client
-)
-{
- REQUEST(xXF86DRIDestroyContextReq);
- REQUEST_SIZE_MATCH(xXF86DRIDestroyContextReq);
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- if (!DRIDestroyContext( screenInfo.screens[stuff->screen],
- stuff->context)) {
- return BadValue;
- }
-
- return (client->noClientException);
-}
-
-static int
-ProcXF86DRICreateDrawable(
- ClientPtr client
-)
-{
- xXF86DRICreateDrawableReply rep;
- DrawablePtr pDrawable;
- int rc;
-
- REQUEST(xXF86DRICreateDrawableReq);
- REQUEST_SIZE_MATCH(xXF86DRICreateDrawableReq);
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
- DixReadAccess);
- if (rc != Success)
- return rc;
-
- if (!DRICreateDrawable(screenInfo.screens[stuff->screen], client,
- pDrawable, (drm_drawable_t *)&rep.hHWDrawable)) {
- return BadValue;
- }
-
- WriteToClient(client, sizeof(xXF86DRICreateDrawableReply), (char *)&rep);
- return (client->noClientException);
-}
-
-static int
-ProcXF86DRIDestroyDrawable(
- register ClientPtr client
-)
-{
- REQUEST(xXF86DRIDestroyDrawableReq);
- DrawablePtr pDrawable;
- int rc;
- REQUEST_SIZE_MATCH(xXF86DRIDestroyDrawableReq);
-
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
- DixReadAccess);
- if (rc != Success)
- return rc;
-
- if (!DRIDestroyDrawable(screenInfo.screens[stuff->screen], client,
- pDrawable)) {
- return BadValue;
- }
-
- return (client->noClientException);
-}
-
-static int
-ProcXF86DRIGetDrawableInfo(
- register ClientPtr client
-)
-{
- xXF86DRIGetDrawableInfoReply rep;
- DrawablePtr pDrawable;
- int X, Y, W, H;
- drm_clip_rect_t * pClipRects, *pClippedRects;
- drm_clip_rect_t * pBackClipRects;
- int backX, backY, rc;
-
- REQUEST(xXF86DRIGetDrawableInfoReq);
- REQUEST_SIZE_MATCH(xXF86DRIGetDrawableInfoReq);
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
- DixReadAccess);
- if (rc != Success)
- return rc;
-
- if (!DRIGetDrawableInfo( screenInfo.screens[stuff->screen],
- pDrawable,
- (unsigned int*)&rep.drawableTableIndex,
- (unsigned int*)&rep.drawableTableStamp,
- (int*)&X,
- (int*)&Y,
- (int*)&W,
- (int*)&H,
- (int*)&rep.numClipRects,
- &pClipRects,
- &backX,
- &backY,
- (int*)&rep.numBackClipRects,
- &pBackClipRects)) {
- return BadValue;
- }
-
- rep.drawableX = X;
- rep.drawableY = Y;
- rep.drawableWidth = W;
- rep.drawableHeight = H;
- rep.length = (SIZEOF(xXF86DRIGetDrawableInfoReply) -
- SIZEOF(xGenericReply));
-
- rep.backX = backX;
- rep.backY = backY;
-
- if (rep.numBackClipRects)
- rep.length += sizeof(drm_clip_rect_t) * rep.numBackClipRects;
-
- pClippedRects = pClipRects;
-
- if (rep.numClipRects) {
- /* Clip cliprects to screen dimensions (redirected windows) */
- pClippedRects = xalloc(rep.numClipRects * sizeof(drm_clip_rect_t));
-
- if (pClippedRects) {
- ScreenPtr pScreen = screenInfo.screens[stuff->screen];
- int i, j;
-
- for (i = 0, j = 0; i < rep.numClipRects; i++) {
- pClippedRects[j].x1 = max(pClipRects[i].x1, 0);
- pClippedRects[j].y1 = max(pClipRects[i].y1, 0);
- pClippedRects[j].x2 = min(pClipRects[i].x2, pScreen->width);
- pClippedRects[j].y2 = min(pClipRects[i].y2, pScreen->height);
-
- if (pClippedRects[j].x1 < pClippedRects[j].x2 &&
- pClippedRects[j].y1 < pClippedRects[j].y2) {
- j++;
- }
- }
-
- rep.numClipRects = j;
- } else {
- rep.numClipRects = 0;
- }
-
- rep.length += sizeof(drm_clip_rect_t) * rep.numClipRects;
- }
-
- rep.length = bytes_to_int32(rep.length);
-
- WriteToClient(client, sizeof(xXF86DRIGetDrawableInfoReply), (char *)&rep);
-
- if (rep.numClipRects) {
- WriteToClient(client,
- sizeof(drm_clip_rect_t) * rep.numClipRects,
- (char *)pClippedRects);
- xfree(pClippedRects);
- }
-
- if (rep.numBackClipRects) {
- WriteToClient(client,
- sizeof(drm_clip_rect_t) * rep.numBackClipRects,
- (char *)pBackClipRects);
- }
-
- return (client->noClientException);
-}
-
-static int
-ProcXF86DRIGetDeviceInfo(
- register ClientPtr client
-)
-{
- xXF86DRIGetDeviceInfoReply rep;
- drm_handle_t hFrameBuffer;
- void *pDevPrivate;
-
- REQUEST(xXF86DRIGetDeviceInfoReq);
- REQUEST_SIZE_MATCH(xXF86DRIGetDeviceInfoReq);
- if (stuff->screen >= screenInfo.numScreens) {
- client->errorValue = stuff->screen;
- return BadValue;
- }
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- if (!DRIGetDeviceInfo( screenInfo.screens[stuff->screen],
- &hFrameBuffer,
- (int*)&rep.framebufferOrigin,
- (int*)&rep.framebufferSize,
- (int*)&rep.framebufferStride,
- (int*)&rep.devPrivateSize,
- &pDevPrivate)) {
- return BadValue;
- }
-
- rep.hFrameBufferLow = (CARD32)(hFrameBuffer & 0xffffffff);
-#if defined(LONG64) && !defined(__linux__)
- rep.hFrameBufferHigh = (CARD32)(hFrameBuffer >> 32);
-#else
- rep.hFrameBufferHigh = 0;
-#endif
-
- rep.length = 0;
- if (rep.devPrivateSize) {
- rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetDeviceInfoReply) -
- SIZEOF(xGenericReply) +
- pad_to_int32(rep.devPrivateSize));
- }
-
- WriteToClient(client, sizeof(xXF86DRIGetDeviceInfoReply), (char *)&rep);
- if (rep.length) {
- WriteToClient(client, rep.devPrivateSize, (char *)pDevPrivate);
- }
- return (client->noClientException);
-}
-
-static int
-ProcXF86DRIDispatch (
- register ClientPtr client
-)
-{
- REQUEST(xReq);
-
- switch (stuff->data)
- {
- case X_XF86DRIQueryVersion:
- return ProcXF86DRIQueryVersion(client);
- case X_XF86DRIQueryDirectRenderingCapable:
- return ProcXF86DRIQueryDirectRenderingCapable(client);
- }
-
- if (!LocalClient(client))
- return DRIErrorBase + XF86DRIClientNotLocal;
-
- switch (stuff->data)
- {
- case X_XF86DRIOpenConnection:
- return ProcXF86DRIOpenConnection(client);
- case X_XF86DRICloseConnection:
- return ProcXF86DRICloseConnection(client);
- case X_XF86DRIGetClientDriverName:
- return ProcXF86DRIGetClientDriverName(client);
- case X_XF86DRICreateContext:
- return ProcXF86DRICreateContext(client);
- case X_XF86DRIDestroyContext:
- return ProcXF86DRIDestroyContext(client);
- case X_XF86DRICreateDrawable:
- return ProcXF86DRICreateDrawable(client);
- case X_XF86DRIDestroyDrawable:
- return ProcXF86DRIDestroyDrawable(client);
- case X_XF86DRIGetDrawableInfo:
- return ProcXF86DRIGetDrawableInfo(client);
- case X_XF86DRIGetDeviceInfo:
- return ProcXF86DRIGetDeviceInfo(client);
- case X_XF86DRIAuthConnection:
- return ProcXF86DRIAuthConnection(client);
- /* {Open,Close}FullScreen are deprecated now */
- default:
- return BadRequest;
- }
-}
-
-static int
-SProcXF86DRIQueryVersion(
- register ClientPtr client
-)
-{
- register int n;
- REQUEST(xXF86DRIQueryVersionReq);
- swaps(&stuff->length, n);
- return ProcXF86DRIQueryVersion(client);
-}
-
-static int
-SProcXF86DRIQueryDirectRenderingCapable(
- register ClientPtr client
-)
-{
- register int n;
- REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
- swaps(&stuff->length, n);
- swapl(&stuff->screen, n);
- return ProcXF86DRIQueryDirectRenderingCapable(client);
-}
-
-static int
-SProcXF86DRIDispatch (
- register ClientPtr client
-)
-{
- REQUEST(xReq);
-
- /*
- * Only local clients are allowed DRI access, but remote clients still need
- * these requests to find out cleanly.
- */
- switch (stuff->data)
- {
- case X_XF86DRIQueryVersion:
- return SProcXF86DRIQueryVersion(client);
- case X_XF86DRIQueryDirectRenderingCapable:
- return SProcXF86DRIQueryDirectRenderingCapable(client);
- default:
- return DRIErrorBase + XF86DRIClientNotLocal;
- }
-}
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+Copyright 2000 VA Linux Systems, 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, sub license, 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 (including the
+next paragraph) 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 NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <martin@valinux.com>
+ * Jens Owen <jens@tungstengraphics.com>
+ * Rickard E. (Rik) Faith <faith@valinux.com>
+ *
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <string.h>
+
+#include "xf86.h"
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+#define _XF86DRI_SERVER_
+#include <X11/dri/xf86driproto.h>
+#include "swaprep.h"
+#include "xf86str.h"
+#include "dri.h"
+#include "sarea.h"
+#include "dristruct.h"
+#include "xf86.h"
+#include "xf86drm.h"
+#include "protocol-versions.h"
+
+static int DRIErrorBase;
+
+static DISPATCH_PROC(ProcXF86DRIQueryVersion);
+static DISPATCH_PROC(ProcXF86DRIQueryDirectRenderingCapable);
+static DISPATCH_PROC(ProcXF86DRIOpenConnection);
+static DISPATCH_PROC(ProcXF86DRICloseConnection);
+static DISPATCH_PROC(ProcXF86DRIGetClientDriverName);
+static DISPATCH_PROC(ProcXF86DRICreateContext);
+static DISPATCH_PROC(ProcXF86DRIDestroyContext);
+static DISPATCH_PROC(ProcXF86DRICreateDrawable);
+static DISPATCH_PROC(ProcXF86DRIDestroyDrawable);
+static DISPATCH_PROC(ProcXF86DRIGetDrawableInfo);
+static DISPATCH_PROC(ProcXF86DRIGetDeviceInfo);
+static DISPATCH_PROC(ProcXF86DRIDispatch);
+static DISPATCH_PROC(ProcXF86DRIAuthConnection);
+
+static DISPATCH_PROC(SProcXF86DRIQueryVersion);
+static DISPATCH_PROC(SProcXF86DRIQueryDirectRenderingCapable);
+static DISPATCH_PROC(SProcXF86DRIDispatch);
+
+static void XF86DRIResetProc(ExtensionEntry* extEntry);
+
+static unsigned char DRIReqCode = 0;
+
+extern void XFree86DRIExtensionInit(void);
+
+void
+XFree86DRIExtensionInit(void)
+{
+ ExtensionEntry* extEntry;
+
+#ifdef XF86DRI_EVENTS
+ EventType = CreateNewResourceType(XF86DRIFreeEvents, "DRIEvent");
+#endif
+
+ if (
+ DRIExtensionInit() &&
+#ifdef XF86DRI_EVENTS
+ EventType && ScreenPrivateIndex != -1 &&
+#endif
+ (extEntry = AddExtension(XF86DRINAME,
+ XF86DRINumberEvents,
+ XF86DRINumberErrors,
+ ProcXF86DRIDispatch,
+ SProcXF86DRIDispatch,
+ XF86DRIResetProc,
+ StandardMinorOpcode))) {
+ DRIReqCode = (unsigned char)extEntry->base;
+ DRIErrorBase = extEntry->errorBase;
+ }
+}
+
+/*ARGSUSED*/
+static void
+XF86DRIResetProc (
+ ExtensionEntry* extEntry
+)
+{
+ DRIReset();
+}
+
+static int
+ProcXF86DRIQueryVersion(
+ register ClientPtr client
+)
+{
+ xXF86DRIQueryVersionReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH(xXF86DRIQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = SERVER_XF86DRI_MAJOR_VERSION;
+ rep.minorVersion = SERVER_XF86DRI_MINOR_VERSION;
+ rep.patchVersion = SERVER_XF86DRI_PATCH_VERSION;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.majorVersion, n);
+ swaps(&rep.minorVersion, n);
+ swapl(&rep.patchVersion, n);
+ }
+ WriteToClient(client, sizeof(xXF86DRIQueryVersionReply), (char *)&rep);
+ return Success;
+}
+
+static int
+ProcXF86DRIQueryDirectRenderingCapable(
+ register ClientPtr client
+)
+{
+ xXF86DRIQueryDirectRenderingCapableReply rep;
+ Bool isCapable;
+ register int n;
+
+ REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
+ REQUEST_SIZE_MATCH(xXF86DRIQueryDirectRenderingCapableReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ if (!DRIQueryDirectRenderingCapable( screenInfo.screens[stuff->screen],
+ &isCapable)) {
+ return BadValue;
+ }
+ rep.isCapable = isCapable;
+
+ if (!LocalClient(client) || client->swapped)
+ rep.isCapable = 0;
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ }
+
+ WriteToClient(client,
+ sizeof(xXF86DRIQueryDirectRenderingCapableReply), (char *)&rep);
+ return Success;
+}
+
+static int
+ProcXF86DRIOpenConnection(
+ register ClientPtr client
+)
+{
+ xXF86DRIOpenConnectionReply rep;
+ drm_handle_t hSAREA;
+ char* busIdString;
+
+ REQUEST(xXF86DRIOpenConnectionReq);
+ REQUEST_SIZE_MATCH(xXF86DRIOpenConnectionReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ if (!DRIOpenConnection( screenInfo.screens[stuff->screen],
+ &hSAREA,
+ &busIdString)) {
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.busIdStringLength = 0;
+ if (busIdString)
+ rep.busIdStringLength = strlen(busIdString);
+ rep.length = bytes_to_int32(SIZEOF(xXF86DRIOpenConnectionReply) - SIZEOF(xGenericReply) +
+ pad_to_int32(rep.busIdStringLength));
+
+ rep.hSAREALow = (CARD32)(hSAREA & 0xffffffff);
+#if defined(LONG64) && !defined(__linux__)
+ rep.hSAREAHigh = (CARD32)(hSAREA >> 32);
+#else
+ rep.hSAREAHigh = 0;
+#endif
+
+ WriteToClient(client, sizeof(xXF86DRIOpenConnectionReply), (char *)&rep);
+ if (rep.busIdStringLength)
+ WriteToClient(client, rep.busIdStringLength, busIdString);
+ return Success;
+}
+
+static int
+ProcXF86DRIAuthConnection(
+ register ClientPtr client
+)
+{
+ xXF86DRIAuthConnectionReply rep;
+
+ REQUEST(xXF86DRIAuthConnectionReq);
+ REQUEST_SIZE_MATCH(xXF86DRIAuthConnectionReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.authenticated = 1;
+
+ if (!DRIAuthConnection( screenInfo.screens[stuff->screen], stuff->magic)) {
+ ErrorF("Failed to authenticate %lu\n", (unsigned long)stuff->magic);
+ rep.authenticated = 0;
+ }
+ WriteToClient(client, sizeof(xXF86DRIAuthConnectionReply), (char *)&rep);
+ return Success;
+}
+
+static int
+ProcXF86DRICloseConnection(
+ register ClientPtr client
+)
+{
+ REQUEST(xXF86DRICloseConnectionReq);
+ REQUEST_SIZE_MATCH(xXF86DRICloseConnectionReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ DRICloseConnection( screenInfo.screens[stuff->screen]);
+
+ return Success;
+}
+
+static int
+ProcXF86DRIGetClientDriverName(
+ register ClientPtr client
+)
+{
+ xXF86DRIGetClientDriverNameReply rep;
+ char* clientDriverName;
+
+ REQUEST(xXF86DRIGetClientDriverNameReq);
+ REQUEST_SIZE_MATCH(xXF86DRIGetClientDriverNameReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ DRIGetClientDriverName( screenInfo.screens[stuff->screen],
+ (int *)&rep.ddxDriverMajorVersion,
+ (int *)&rep.ddxDriverMinorVersion,
+ (int *)&rep.ddxDriverPatchVersion,
+ &clientDriverName);
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.clientDriverNameLength = 0;
+ if (clientDriverName)
+ rep.clientDriverNameLength = strlen(clientDriverName);
+ rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetClientDriverNameReply) -
+ SIZEOF(xGenericReply) +
+ pad_to_int32(rep.clientDriverNameLength));
+
+ WriteToClient(client,
+ sizeof(xXF86DRIGetClientDriverNameReply), (char *)&rep);
+ if (rep.clientDriverNameLength)
+ WriteToClient(client,
+ rep.clientDriverNameLength,
+ clientDriverName);
+ return Success;
+}
+
+static int
+ProcXF86DRICreateContext(
+ register ClientPtr client
+)
+{
+ xXF86DRICreateContextReply rep;
+ ScreenPtr pScreen;
+
+ REQUEST(xXF86DRICreateContextReq);
+ REQUEST_SIZE_MATCH(xXF86DRICreateContextReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ pScreen = screenInfo.screens[stuff->screen];
+
+ if (!DRICreateContext( pScreen,
+ NULL,
+ stuff->context,
+ (drm_context_t *)&rep.hHWContext)) {
+ return BadValue;
+ }
+
+ WriteToClient(client, sizeof(xXF86DRICreateContextReply), (char *)&rep);
+ return Success;
+}
+
+static int
+ProcXF86DRIDestroyContext(
+ register ClientPtr client
+)
+{
+ REQUEST(xXF86DRIDestroyContextReq);
+ REQUEST_SIZE_MATCH(xXF86DRIDestroyContextReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ if (!DRIDestroyContext( screenInfo.screens[stuff->screen],
+ stuff->context)) {
+ return BadValue;
+ }
+
+ return Success;
+}
+
+static int
+ProcXF86DRICreateDrawable(
+ ClientPtr client
+)
+{
+ xXF86DRICreateDrawableReply rep;
+ DrawablePtr pDrawable;
+ int rc;
+
+ REQUEST(xXF86DRICreateDrawableReq);
+ REQUEST_SIZE_MATCH(xXF86DRICreateDrawableReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
+ DixReadAccess);
+ if (rc != Success)
+ return rc;
+
+ if (!DRICreateDrawable(screenInfo.screens[stuff->screen], client,
+ pDrawable, (drm_drawable_t *)&rep.hHWDrawable)) {
+ return BadValue;
+ }
+
+ WriteToClient(client, sizeof(xXF86DRICreateDrawableReply), (char *)&rep);
+ return Success;
+}
+
+static int
+ProcXF86DRIDestroyDrawable(
+ register ClientPtr client
+)
+{
+ REQUEST(xXF86DRIDestroyDrawableReq);
+ DrawablePtr pDrawable;
+ int rc;
+ REQUEST_SIZE_MATCH(xXF86DRIDestroyDrawableReq);
+
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
+ DixReadAccess);
+ if (rc != Success)
+ return rc;
+
+ if (!DRIDestroyDrawable(screenInfo.screens[stuff->screen], client,
+ pDrawable)) {
+ return BadValue;
+ }
+
+ return Success;
+}
+
+static int
+ProcXF86DRIGetDrawableInfo(
+ register ClientPtr client
+)
+{
+ xXF86DRIGetDrawableInfoReply rep;
+ DrawablePtr pDrawable;
+ int X, Y, W, H;
+ drm_clip_rect_t * pClipRects, *pClippedRects;
+ drm_clip_rect_t * pBackClipRects;
+ int backX, backY, rc;
+
+ REQUEST(xXF86DRIGetDrawableInfoReq);
+ REQUEST_SIZE_MATCH(xXF86DRIGetDrawableInfoReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
+ DixReadAccess);
+ if (rc != Success)
+ return rc;
+
+ if (!DRIGetDrawableInfo( screenInfo.screens[stuff->screen],
+ pDrawable,
+ (unsigned int*)&rep.drawableTableIndex,
+ (unsigned int*)&rep.drawableTableStamp,
+ (int*)&X,
+ (int*)&Y,
+ (int*)&W,
+ (int*)&H,
+ (int*)&rep.numClipRects,
+ &pClipRects,
+ &backX,
+ &backY,
+ (int*)&rep.numBackClipRects,
+ &pBackClipRects)) {
+ return BadValue;
+ }
+
+ rep.drawableX = X;
+ rep.drawableY = Y;
+ rep.drawableWidth = W;
+ rep.drawableHeight = H;
+ rep.length = (SIZEOF(xXF86DRIGetDrawableInfoReply) -
+ SIZEOF(xGenericReply));
+
+ rep.backX = backX;
+ rep.backY = backY;
+
+ if (rep.numBackClipRects)
+ rep.length += sizeof(drm_clip_rect_t) * rep.numBackClipRects;
+
+ pClippedRects = pClipRects;
+
+ if (rep.numClipRects) {
+ /* Clip cliprects to screen dimensions (redirected windows) */
+ pClippedRects = malloc(rep.numClipRects * sizeof(drm_clip_rect_t));
+
+ if (pClippedRects) {
+ ScreenPtr pScreen = screenInfo.screens[stuff->screen];
+ int i, j;
+
+ for (i = 0, j = 0; i < rep.numClipRects; i++) {
+ pClippedRects[j].x1 = max(pClipRects[i].x1, 0);
+ pClippedRects[j].y1 = max(pClipRects[i].y1, 0);
+ pClippedRects[j].x2 = min(pClipRects[i].x2, pScreen->width);
+ pClippedRects[j].y2 = min(pClipRects[i].y2, pScreen->height);
+
+ if (pClippedRects[j].x1 < pClippedRects[j].x2 &&
+ pClippedRects[j].y1 < pClippedRects[j].y2) {
+ j++;
+ }
+ }
+
+ rep.numClipRects = j;
+ } else {
+ rep.numClipRects = 0;
+ }
+
+ rep.length += sizeof(drm_clip_rect_t) * rep.numClipRects;
+ }
+
+ rep.length = bytes_to_int32(rep.length);
+
+ WriteToClient(client, sizeof(xXF86DRIGetDrawableInfoReply), (char *)&rep);
+
+ if (rep.numClipRects) {
+ WriteToClient(client,
+ sizeof(drm_clip_rect_t) * rep.numClipRects,
+ (char *)pClippedRects);
+ free(pClippedRects);
+ }
+
+ if (rep.numBackClipRects) {
+ WriteToClient(client,
+ sizeof(drm_clip_rect_t) * rep.numBackClipRects,
+ (char *)pBackClipRects);
+ }
+
+ return Success;
+}
+
+static int
+ProcXF86DRIGetDeviceInfo(
+ register ClientPtr client
+)
+{
+ xXF86DRIGetDeviceInfoReply rep;
+ drm_handle_t hFrameBuffer;
+ void *pDevPrivate;
+
+ REQUEST(xXF86DRIGetDeviceInfoReq);
+ REQUEST_SIZE_MATCH(xXF86DRIGetDeviceInfoReq);
+ if (stuff->screen >= screenInfo.numScreens) {
+ client->errorValue = stuff->screen;
+ return BadValue;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ if (!DRIGetDeviceInfo( screenInfo.screens[stuff->screen],
+ &hFrameBuffer,
+ (int*)&rep.framebufferOrigin,
+ (int*)&rep.framebufferSize,
+ (int*)&rep.framebufferStride,
+ (int*)&rep.devPrivateSize,
+ &pDevPrivate)) {
+ return BadValue;
+ }
+
+ rep.hFrameBufferLow = (CARD32)(hFrameBuffer & 0xffffffff);
+#if defined(LONG64) && !defined(__linux__)
+ rep.hFrameBufferHigh = (CARD32)(hFrameBuffer >> 32);
+#else
+ rep.hFrameBufferHigh = 0;
+#endif
+
+ rep.length = 0;
+ if (rep.devPrivateSize) {
+ rep.length = bytes_to_int32(SIZEOF(xXF86DRIGetDeviceInfoReply) -
+ SIZEOF(xGenericReply) +
+ pad_to_int32(rep.devPrivateSize));
+ }
+
+ WriteToClient(client, sizeof(xXF86DRIGetDeviceInfoReply), (char *)&rep);
+ if (rep.length) {
+ WriteToClient(client, rep.devPrivateSize, (char *)pDevPrivate);
+ }
+ return Success;
+}
+
+static int
+ProcXF86DRIDispatch (
+ register ClientPtr client
+)
+{
+ REQUEST(xReq);
+
+ switch (stuff->data)
+ {
+ case X_XF86DRIQueryVersion:
+ return ProcXF86DRIQueryVersion(client);
+ case X_XF86DRIQueryDirectRenderingCapable:
+ return ProcXF86DRIQueryDirectRenderingCapable(client);
+ }
+
+ if (!LocalClient(client))
+ return DRIErrorBase + XF86DRIClientNotLocal;
+
+ switch (stuff->data)
+ {
+ case X_XF86DRIOpenConnection:
+ return ProcXF86DRIOpenConnection(client);
+ case X_XF86DRICloseConnection:
+ return ProcXF86DRICloseConnection(client);
+ case X_XF86DRIGetClientDriverName:
+ return ProcXF86DRIGetClientDriverName(client);
+ case X_XF86DRICreateContext:
+ return ProcXF86DRICreateContext(client);
+ case X_XF86DRIDestroyContext:
+ return ProcXF86DRIDestroyContext(client);
+ case X_XF86DRICreateDrawable:
+ return ProcXF86DRICreateDrawable(client);
+ case X_XF86DRIDestroyDrawable:
+ return ProcXF86DRIDestroyDrawable(client);
+ case X_XF86DRIGetDrawableInfo:
+ return ProcXF86DRIGetDrawableInfo(client);
+ case X_XF86DRIGetDeviceInfo:
+ return ProcXF86DRIGetDeviceInfo(client);
+ case X_XF86DRIAuthConnection:
+ return ProcXF86DRIAuthConnection(client);
+ /* {Open,Close}FullScreen are deprecated now */
+ default:
+ return BadRequest;
+ }
+}
+
+static int
+SProcXF86DRIQueryVersion(
+ register ClientPtr client
+)
+{
+ register int n;
+ REQUEST(xXF86DRIQueryVersionReq);
+ swaps(&stuff->length, n);
+ return ProcXF86DRIQueryVersion(client);
+}
+
+static int
+SProcXF86DRIQueryDirectRenderingCapable(
+ register ClientPtr client
+)
+{
+ register int n;
+ REQUEST(xXF86DRIQueryDirectRenderingCapableReq);
+ swaps(&stuff->length, n);
+ swapl(&stuff->screen, n);
+ return ProcXF86DRIQueryDirectRenderingCapable(client);
+}
+
+static int
+SProcXF86DRIDispatch (
+ register ClientPtr client
+)
+{
+ REQUEST(xReq);
+
+ /*
+ * Only local clients are allowed DRI access, but remote clients still need
+ * these requests to find out cleanly.
+ */
+ switch (stuff->data)
+ {
+ case X_XF86DRIQueryVersion:
+ return SProcXF86DRIQueryVersion(client);
+ case X_XF86DRIQueryDirectRenderingCapable:
+ return SProcXF86DRIQueryDirectRenderingCapable(client);
+ default:
+ return DRIErrorBase + XF86DRIClientNotLocal;
+ }
+}
diff --git a/xorg-server/hw/xfree86/dri2/dri2.c b/xorg-server/hw/xfree86/dri2/dri2.c
index abcb96668..64be079ca 100644
--- a/xorg-server/hw/xfree86/dri2/dri2.c
+++ b/xorg-server/hw/xfree86/dri2/dri2.c
@@ -96,6 +96,8 @@ typedef struct _DRI2Screen {
DRI2ScheduleWaitMSCProcPtr ScheduleWaitMSC;
HandleExposuresProcPtr HandleExposures;
+
+ ConfigNotifyProcPtr ConfigNotify;
} DRI2ScreenRec;
static DRI2ScreenPtr
@@ -128,7 +130,7 @@ DRI2AllocateDrawable(DrawablePtr pDraw)
WindowPtr pWin;
PixmapPtr pPixmap;
- pPriv = xalloc(sizeof *pPriv);
+ pPriv = malloc(sizeof *pPriv);
if (pPriv == NULL)
return NULL;
@@ -165,9 +167,11 @@ DRI2AllocateDrawable(DrawablePtr pDraw)
}
typedef struct DRI2DrawableRefRec {
- XID id;
- XID dri2_id;
- struct list link;
+ XID id;
+ XID dri2_id;
+ DRI2InvalidateProcPtr invalidate;
+ void *priv;
+ struct list link;
} DRI2DrawableRefRec, *DRI2DrawableRefPtr;
static DRI2DrawableRefPtr
@@ -184,7 +188,8 @@ DRI2LookupDrawableRef(DRI2DrawablePtr pPriv, XID id)
}
static int
-DRI2AddDrawableRef(DRI2DrawablePtr pPriv, XID id, XID dri2_id)
+DRI2AddDrawableRef(DRI2DrawablePtr pPriv, XID id, XID dri2_id,
+ DRI2InvalidateProcPtr invalidate, void *priv)
{
DRI2DrawableRefPtr ref;
@@ -200,13 +205,16 @@ DRI2AddDrawableRef(DRI2DrawablePtr pPriv, XID id, XID dri2_id)
ref->id = id;
ref->dri2_id = dri2_id;
+ ref->invalidate = invalidate;
+ ref->priv = priv;
list_add(&ref->link, &pPriv->reference_list);
return Success;
}
int
-DRI2CreateDrawable(ClientPtr client, DrawablePtr pDraw, XID id)
+DRI2CreateDrawable(ClientPtr client, DrawablePtr pDraw, XID id,
+ DRI2InvalidateProcPtr invalidate, void *priv)
{
DRI2DrawablePtr pPriv;
XID dri2_id;
@@ -219,7 +227,7 @@ DRI2CreateDrawable(ClientPtr client, DrawablePtr pDraw, XID id)
return BadAlloc;
dri2_id = FakeClientID(client->index);
- rc = DRI2AddDrawableRef(pPriv, id, dri2_id);
+ rc = DRI2AddDrawableRef(pPriv, id, dri2_id, invalidate, priv);
if (rc != Success)
return rc;
@@ -270,10 +278,10 @@ static int DRI2DrawableGone(pointer p, XID id)
for (i = 0; i < pPriv->bufferCount; i++)
(*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
- xfree(pPriv->buffers);
+ free(pPriv->buffers);
}
- xfree(pPriv);
+ free(pPriv);
return Success;
}
@@ -318,6 +326,31 @@ allocate_or_reuse_buffer(DrawablePtr pDraw, DRI2ScreenPtr ds,
}
}
+static void
+update_dri2_drawable_buffers(DRI2DrawablePtr pPriv, DrawablePtr pDraw,
+ DRI2BufferPtr *buffers, int *out_count, int *width, int *height)
+{
+ DRI2ScreenPtr ds = DRI2GetScreen(pDraw->pScreen);
+ int i;
+
+ if (pPriv->buffers != NULL) {
+ for (i = 0; i < pPriv->bufferCount; i++) {
+ if (pPriv->buffers[i] != NULL) {
+ (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
+ }
+ }
+
+ free(pPriv->buffers);
+ }
+
+ pPriv->buffers = buffers;
+ pPriv->bufferCount = *out_count;
+ pPriv->width = pDraw->width;
+ pPriv->height = pDraw->height;
+ *width = pPriv->width;
+ *height = pPriv->height;
+}
+
static DRI2BufferPtr *
do_get_buffers(DrawablePtr pDraw, int *width, int *height,
unsigned int *attachments, int count, int *out_count,
@@ -344,7 +377,7 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
dimensions_match = (pDraw->width == pPriv->width)
&& (pDraw->height == pPriv->height);
- buffers = xalloc((count + 1) * sizeof(buffers[0]));
+ buffers = malloc((count + 1) * sizeof(buffers[0]));
for (i = 0; i < count; i++) {
const unsigned attachment = *(attachments++);
@@ -355,6 +388,9 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
&buffers[i]))
buffers_changed = 1;
+ if (buffers[i] == NULL)
+ goto err_out;
+
/* If the drawable is a window and the front-buffer is requested,
* silently add the fake front-buffer to the list of requested
* attachments. The counting logic in the loop accounts for the case
@@ -387,6 +423,9 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
front_format, dimensions_match,
&buffers[i++]))
buffers_changed = 1;
+
+ if (buffers[i] == NULL)
+ goto err_out;
}
if (need_fake_front > 0) {
@@ -395,29 +434,15 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
&buffers[i++]))
buffers_changed = 1;
+ if (buffers[i] == NULL)
+ goto err_out;
+
have_fake_front = 1;
}
*out_count = i;
-
- if (pPriv->buffers != NULL) {
- for (i = 0; i < pPriv->bufferCount; i++) {
- if (pPriv->buffers[i] != NULL) {
- (*ds->DestroyBuffer)(pDraw, pPriv->buffers[i]);
- }
- }
-
- xfree(pPriv->buffers);
- }
-
- pPriv->buffers = buffers;
- pPriv->bufferCount = *out_count;
- pPriv->width = pDraw->width;
- pPriv->height = pDraw->height;
- *width = pPriv->width;
- *height = pPriv->height;
-
+ update_dri2_drawable_buffers(pPriv, pDraw, buffers, out_count, width, height);
/* If the client is getting a fake front-buffer, pre-fill it with the
* contents of the real front-buffer. This ensures correct operation of
@@ -438,6 +463,22 @@ do_get_buffers(DrawablePtr pDraw, int *width, int *height,
}
return pPriv->buffers;
+
+err_out:
+
+ *out_count = 0;
+
+ for (i = 0; i < count; i++) {
+ if (buffers[i] != NULL)
+ (*ds->DestroyBuffer)(pDraw, buffers[i]);
+ }
+
+ free(buffers);
+ buffers = NULL;
+
+ update_dri2_drawable_buffers(pPriv, pDraw, buffers, out_count, width, height);
+
+ return buffers;
}
DRI2BufferPtr *
@@ -456,6 +497,19 @@ DRI2GetBuffersWithFormat(DrawablePtr pDraw, int *width, int *height,
out_count, TRUE);
}
+static void
+DRI2InvalidateDrawable(DrawablePtr pDraw)
+{
+ DRI2DrawablePtr pPriv = DRI2GetDrawable(pDraw);
+ DRI2DrawableRefPtr ref;
+
+ if (!pPriv)
+ return;
+
+ list_for_each_entry(ref, &pPriv->reference_list, link)
+ ref->invalidate(pDraw, ref->priv);
+}
+
/*
* In the direct rendered case, we throttle the clients that have more
* than their share of outstanding swaps (and thus busy buffers) when a
@@ -634,6 +688,8 @@ DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw, int frame,
ScreenPtr pScreen = pDraw->pScreen;
DRI2DrawablePtr pPriv;
CARD64 ust = 0;
+ BoxRec box;
+ RegionRec region;
pPriv = DRI2GetDrawable(pDraw);
if (pPriv == NULL) {
@@ -645,6 +701,14 @@ DRI2SwapComplete(ClientPtr client, DrawablePtr pDraw, int frame,
pPriv->swapsPending--;
pPriv->swap_count++;
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pDraw->width;
+ box.y2 = pDraw->height;
+ REGION_INIT(pScreen, &region, &box, 0);
+ DRI2CopyRegion(pDraw, &region, DRI2BufferFakeFrontLeft,
+ DRI2BufferFrontLeft);
+
ust = ((CARD64)tv_sec * 1000000) + tv_usec;
if (swap_complete)
swap_complete(client, swap_data, type, ust, frame, pPriv->swap_count);
@@ -756,6 +820,8 @@ DRI2SwapBuffers(ClientPtr client, DrawablePtr pDraw, CARD64 target_msc,
*/
*swap_target = pPriv->swap_count + pPriv->swapsPending;
+ DRI2InvalidateDrawable(pDraw);
+
return Success;
}
@@ -906,6 +972,30 @@ DRI2Authenticate(ScreenPtr pScreen, drm_magic_t magic)
return TRUE;
}
+static void
+DRI2ConfigNotify(WindowPtr pWin, int x, int y, int w, int h, int bw,
+ WindowPtr pSib)
+{
+ DrawablePtr pDraw = (DrawablePtr)pWin;
+ ScreenPtr pScreen = pDraw->pScreen;
+ DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
+ DRI2DrawablePtr dd = DRI2GetDrawable(pDraw);
+
+ if (ds->ConfigNotify) {
+ pScreen->ConfigNotify = ds->ConfigNotify;
+
+ (*pScreen->ConfigNotify)(pWin, x, y, w, h, bw, pSib);
+
+ ds->ConfigNotify = pScreen->ConfigNotify;
+ pScreen->ConfigNotify = DRI2ConfigNotify;
+ }
+
+ if (!dd || (dd->width == w && dd->height == h))
+ return;
+
+ DRI2InvalidateDrawable(pDraw);
+}
+
Bool
DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
{
@@ -926,7 +1016,7 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
return FALSE;
}
- ds = xcalloc(1, sizeof *ds);
+ ds = calloc(1, sizeof *ds);
if (!ds)
return FALSE;
@@ -943,7 +1033,7 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
ds->ScheduleSwap = info->ScheduleSwap;
ds->ScheduleWaitMSC = info->ScheduleWaitMSC;
ds->GetMSC = info->GetMSC;
- cur_minor = 2;
+ cur_minor = 3;
} else {
cur_minor = 1;
}
@@ -955,17 +1045,17 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
if (info->version == 3 || info->numDrivers == 0) {
/* Driver too old: use the old-style driverName field */
ds->numDrivers = 1;
- ds->driverNames = xalloc(sizeof(*ds->driverNames));
+ ds->driverNames = malloc(sizeof(*ds->driverNames));
if (!ds->driverNames) {
- xfree(ds);
+ free(ds);
return FALSE;
}
ds->driverNames[0] = info->driverName;
} else {
ds->numDrivers = info->numDrivers;
- ds->driverNames = xalloc(info->numDrivers * sizeof(*ds->driverNames));
+ ds->driverNames = malloc(info->numDrivers * sizeof(*ds->driverNames));
if (!ds->driverNames) {
- xfree(ds);
+ free(ds);
return FALSE;
}
memcpy(ds->driverNames, info->driverNames,
@@ -974,6 +1064,9 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, ds);
+ ds->ConfigNotify = pScreen->ConfigNotify;
+ pScreen->ConfigNotify = DRI2ConfigNotify;
+
xf86DrvMsg(pScreen->myNum, X_INFO, "[DRI2] Setup complete\n");
for (i = 0; i < sizeof(driverTypeNames) / sizeof(driverTypeNames[0]); i++) {
if (i < ds->numDrivers && ds->driverNames[i]) {
@@ -990,8 +1083,8 @@ DRI2CloseScreen(ScreenPtr pScreen)
{
DRI2ScreenPtr ds = DRI2GetScreen(pScreen);
- xfree(ds->driverNames);
- xfree(ds);
+ free(ds->driverNames);
+ free(ds);
dixSetPrivate(&pScreen->devPrivates, dri2ScreenPrivateKey, NULL);
}
diff --git a/xorg-server/hw/xfree86/dri2/dri2.h b/xorg-server/hw/xfree86/dri2/dri2.h
index cc15f120d..c43aa6a04 100644
--- a/xorg-server/hw/xfree86/dri2/dri2.h
+++ b/xorg-server/hw/xfree86/dri2/dri2.h
@@ -152,6 +152,10 @@ typedef int (*DRI2ScheduleWaitMSCProcPtr)(ClientPtr client,
CARD64 target_msc,
CARD64 divisor,
CARD64 remainder);
+
+typedef void (*DRI2InvalidateProcPtr)(DrawablePtr pDraw,
+ void *data);
+
/**
* Version of the DRI2InfoRec structure defined in this header
*/
@@ -199,7 +203,10 @@ extern _X_EXPORT Bool DRI2Connect(ScreenPtr pScreen,
extern _X_EXPORT Bool DRI2Authenticate(ScreenPtr pScreen, drm_magic_t magic);
extern _X_EXPORT int DRI2CreateDrawable(ClientPtr client,
- DrawablePtr pDraw, XID id);
+ DrawablePtr pDraw,
+ XID id,
+ DRI2InvalidateProcPtr invalidate,
+ void *priv);
extern _X_EXPORT void DRI2DestroyDrawable(DrawablePtr pDraw);
diff --git a/xorg-server/hw/xfree86/dri2/dri2ext.c b/xorg-server/hw/xfree86/dri2/dri2ext.c
index 8bed02055..38efc86e0 100644
--- a/xorg-server/hw/xfree86/dri2/dri2ext.c
+++ b/xorg-server/hw/xfree86/dri2/dri2ext.c
@@ -91,7 +91,7 @@ ProcDRI2QueryVersion(ClientPtr client)
WriteToClient(client, sizeof(xDRI2QueryVersionReply), &rep);
- return client->noClientException;
+ return Success;
}
static int
@@ -129,7 +129,7 @@ ProcDRI2Connect(ClientPtr client)
WriteToClient(client, rep.driverNameLength, driverName);
WriteToClient(client, rep.deviceNameLength, deviceName);
- return client->noClientException;
+ return Success;
}
static int
@@ -151,7 +151,23 @@ ProcDRI2Authenticate(ClientPtr client)
rep.authenticated = DRI2Authenticate(pDraw->pScreen, stuff->magic);
WriteToClient(client, sizeof(xDRI2AuthenticateReply), &rep);
- return client->noClientException;
+ return Success;
+}
+
+static void
+DRI2InvalidateBuffersEvent(DrawablePtr pDraw, void *priv)
+{
+ xDRI2InvalidateBuffers event;
+ ClientPtr client = priv;
+
+ if (client->clientGone)
+ return;
+
+ event.type = DRI2EventBase + DRI2_InvalidateBuffers;
+ event.sequenceNumber = client->sequence;
+ event.drawable = pDraw->id;
+
+ WriteEventsToClient(client, 1, (xEvent *)&event);
}
static int
@@ -167,11 +183,12 @@ ProcDRI2CreateDrawable(ClientPtr client)
&pDrawable, &status))
return status;
- status = DRI2CreateDrawable(client, pDrawable, stuff->drawable);
+ status = DRI2CreateDrawable(client, pDrawable, stuff->drawable,
+ DRI2InvalidateBuffersEvent, client);
if (status != Success)
return status;
- return client->noClientException;
+ return Success;
}
static int
@@ -186,11 +203,11 @@ ProcDRI2DestroyDrawable(ClientPtr client)
&pDrawable, &status))
return status;
- return client->noClientException;
+ return Success;
}
-static void
+static int
send_buffers_reply(ClientPtr client, DrawablePtr pDrawable,
DRI2BufferPtr *buffers, int count, int width, int height)
{
@@ -198,6 +215,9 @@ send_buffers_reply(ClientPtr client, DrawablePtr pDrawable,
int skip = 0;
int i;
+ if (buffers == NULL)
+ return BadAlloc;
+
if (pDrawable->type == DRAWABLE_WINDOW) {
for (i = 0; i < count; i++) {
/* Do not send the real front buffer of a window to the client.
@@ -234,6 +254,7 @@ send_buffers_reply(ClientPtr client, DrawablePtr pDrawable,
buffer.flags = buffers[i]->flags;
WriteToClient(client, sizeof(xDRI2Buffer), &buffer);
}
+ return Success;
}
@@ -252,16 +273,15 @@ ProcDRI2GetBuffers(ClientPtr client)
return status;
if (DRI2ThrottleClient(client, pDrawable))
- return client->noClientException;
+ return Success;
attachments = (unsigned int *) &stuff[1];
buffers = DRI2GetBuffers(pDrawable, &width, &height,
attachments, stuff->count, &count);
- send_buffers_reply(client, pDrawable, buffers, count, width, height);
+ return send_buffers_reply(client, pDrawable, buffers, count, width, height);
- return client->noClientException;
}
static int
@@ -279,15 +299,13 @@ ProcDRI2GetBuffersWithFormat(ClientPtr client)
return status;
if (DRI2ThrottleClient(client, pDrawable))
- return client->noClientException;
+ return Success;
attachments = (unsigned int *) &stuff[1];
buffers = DRI2GetBuffersWithFormat(pDrawable, &width, &height,
attachments, stuff->count, &count);
- send_buffers_reply(client, pDrawable, buffers, count, width, height);
-
- return client->noClientException;
+ return send_buffers_reply(client, pDrawable, buffers, count, width, height);
}
static int
@@ -324,7 +342,7 @@ ProcDRI2CopyRegion(ClientPtr client)
WriteToClient(client, sizeof(xDRI2CopyRegionReply), &rep);
- return client->noClientException;
+ return Success;
}
static void
@@ -381,7 +399,7 @@ ProcDRI2SwapBuffers(ClientPtr client)
* also orders swaps.
*/
if (DRI2ThrottleClient(client, pDrawable))
- return client->noClientException;
+ return Success;
target_msc = vals_to_card64(stuff->target_msc_lo, stuff->target_msc_hi);
divisor = vals_to_card64(stuff->divisor_lo, stuff->divisor_hi);
@@ -399,7 +417,7 @@ ProcDRI2SwapBuffers(ClientPtr client)
WriteToClient(client, sizeof(xDRI2SwapBuffersReply), &rep);
- return client->noClientException;
+ return Success;
}
static void
@@ -439,7 +457,7 @@ ProcDRI2GetMSC(ClientPtr client)
WriteToClient(client, sizeof(xDRI2MSCReply), &rep);
- return client->noClientException;
+ return Success;
}
static int
@@ -466,7 +484,7 @@ ProcDRI2WaitMSC(ClientPtr client)
if (status != Success)
return status;
- return client->noClientException;
+ return Success;
}
int
@@ -481,7 +499,7 @@ ProcDRI2WaitMSCReply(ClientPtr client, CARD64 ust, CARD64 msc, CARD64 sbc)
WriteToClient(client, sizeof(xDRI2MSCReply), &rep);
- return client->noClientException;
+ return Success;
}
static int
@@ -501,7 +519,7 @@ ProcDRI2SwapInterval(ClientPtr client)
DRI2SwapInterval(pDrawable, stuff->interval);
- return client->noClientException;
+ return Success;
}
static int
@@ -531,7 +549,7 @@ ProcDRI2WaitSBC(ClientPtr client)
WriteToClient(client, sizeof(xDRI2MSCReply), &rep);
- return client->noClientException;
+ return Success;
}
static int
@@ -596,7 +614,7 @@ SProcDRI2Connect(ClientPtr client)
rep.driverNameLength = 0;
rep.deviceNameLength = 0;
- return client->noClientException;
+ return Success;
}
static int
diff --git a/xorg-server/hw/xfree86/exa/examodule.c b/xorg-server/hw/xfree86/exa/examodule.c
index bcb6a405c..6238582c0 100644
--- a/xorg-server/hw/xfree86/exa/examodule.c
+++ b/xorg-server/hw/xfree86/exa/examodule.c
@@ -1,198 +1,198 @@
-/*
- * Copyright © 2006 Intel Corporation
- *
- * 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 (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- * Eric Anholt <anholt@FreeBSD.org>
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <string.h>
-
-#include "exa_priv.h"
-
-#include "xf86str.h"
-#include "xf86.h"
-
-typedef struct _ExaXorgScreenPrivRec {
- CloseScreenProcPtr SavedCloseScreen;
- EnableDisableFBAccessProcPtr SavedEnableDisableFBAccess;
- OptionInfoPtr options;
-} ExaXorgScreenPrivRec, *ExaXorgScreenPrivPtr;
-
-static int exaXorgScreenPrivateKeyIndex;
-static DevPrivateKey exaXorgScreenPrivateKey = &exaXorgScreenPrivateKeyIndex;
-
-typedef enum {
- EXAOPT_MIGRATION_HEURISTIC,
- EXAOPT_NO_COMPOSITE,
- EXAOPT_NO_UTS,
- EXAOPT_NO_DFS,
- EXAOPT_OPTIMIZE_MIGRATION
-} EXAOpts;
-
-static const OptionInfoRec EXAOptions[] = {
- { EXAOPT_MIGRATION_HEURISTIC, "MigrationHeuristic",
- OPTV_ANYSTR, {0}, FALSE },
- { EXAOPT_NO_COMPOSITE, "EXANoComposite",
- OPTV_BOOLEAN, {0}, FALSE },
- { EXAOPT_NO_UTS, "EXANoUploadToScreen",
- OPTV_BOOLEAN, {0}, FALSE },
- { EXAOPT_NO_DFS, "EXANoDownloadFromScreen",
- OPTV_BOOLEAN, {0}, FALSE },
- { EXAOPT_OPTIMIZE_MIGRATION, "EXAOptimizeMigration",
- OPTV_BOOLEAN, {0}, FALSE },
- { -1, NULL,
- OPTV_NONE, {0}, FALSE }
-};
-
-static Bool
-exaXorgCloseScreen (int i, ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen);
- ExaXorgScreenPrivPtr pScreenPriv = (ExaXorgScreenPrivPtr)
- dixLookupPrivate(&pScreen->devPrivates, exaXorgScreenPrivateKey);
-
- pScreen->CloseScreen = pScreenPriv->SavedCloseScreen;
-
- pScrn->EnableDisableFBAccess = pScreenPriv->SavedEnableDisableFBAccess;
-
- xfree (pScreenPriv->options);
- xfree (pScreenPriv);
-
- return pScreen->CloseScreen (i, pScreen);
-}
-
-static void
-exaXorgEnableDisableFBAccess (int index, Bool enable)
-{
- ScreenPtr pScreen = screenInfo.screens[index];
- ExaXorgScreenPrivPtr pScreenPriv = (ExaXorgScreenPrivPtr)
- dixLookupPrivate(&pScreen->devPrivates, exaXorgScreenPrivateKey);
-
- if (!enable)
- exaEnableDisableFBAccess (index, enable);
-
- if (pScreenPriv->SavedEnableDisableFBAccess)
- pScreenPriv->SavedEnableDisableFBAccess (index, enable);
-
- if (enable)
- exaEnableDisableFBAccess (index, enable);
-}
-
-/**
- * This will be called during exaDriverInit, giving us the chance to set options
- * and hook in our EnableDisableFBAccess.
- */
-void
-exaDDXDriverInit(ScreenPtr pScreen)
-{
- ExaScreenPriv(pScreen);
- /* Do NOT use XF86SCRNINFO macro here!! */
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- ExaXorgScreenPrivPtr pScreenPriv;
-
- pScreenPriv = xcalloc (1, sizeof(ExaXorgScreenPrivRec));
- if (pScreenPriv == NULL)
- return;
-
- pScreenPriv->options = xnfalloc (sizeof(EXAOptions));
- memcpy(pScreenPriv->options, EXAOptions, sizeof(EXAOptions));
- xf86ProcessOptions (pScrn->scrnIndex, pScrn->options, pScreenPriv->options);
-
- if (pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS) {
- if (!(pExaScr->info->flags & EXA_HANDLES_PIXMAPS) &&
- pExaScr->info->offScreenBase < pExaScr->info->memorySize) {
- char *heuristicName;
-
- heuristicName = xf86GetOptValString (pScreenPriv->options,
- EXAOPT_MIGRATION_HEURISTIC);
- if (heuristicName != NULL) {
- if (strcmp(heuristicName, "greedy") == 0)
- pExaScr->migration = ExaMigrationGreedy;
- else if (strcmp(heuristicName, "always") == 0)
- pExaScr->migration = ExaMigrationAlways;
- else if (strcmp(heuristicName, "smart") == 0)
- pExaScr->migration = ExaMigrationSmart;
- else {
- xf86DrvMsg (pScreen->myNum, X_WARNING,
- "EXA: unknown migration heuristic %s\n",
- heuristicName);
- }
- }
- }
-
- pExaScr->optimize_migration =
- xf86ReturnOptValBool(pScreenPriv->options,
- EXAOPT_OPTIMIZE_MIGRATION,
- TRUE);
- }
-
- if (xf86ReturnOptValBool(pScreenPriv->options,
- EXAOPT_NO_COMPOSITE, FALSE)) {
- xf86DrvMsg(pScreen->myNum, X_CONFIG,
- "EXA: Disabling Composite operation "
- "(RENDER acceleration)\n");
- pExaScr->info->CheckComposite = NULL;
- pExaScr->info->PrepareComposite = NULL;
- }
-
- if (xf86ReturnOptValBool(pScreenPriv->options, EXAOPT_NO_UTS, FALSE)) {
- xf86DrvMsg(pScreen->myNum, X_CONFIG,
- "EXA: Disabling UploadToScreen\n");
- pExaScr->info->UploadToScreen = NULL;
- }
-
- if (xf86ReturnOptValBool(pScreenPriv->options, EXAOPT_NO_DFS, FALSE)) {
- xf86DrvMsg(pScreen->myNum, X_CONFIG,
- "EXA: Disabling DownloadFromScreen\n");
- pExaScr->info->DownloadFromScreen = NULL;
- }
-
- dixSetPrivate(&pScreen->devPrivates, exaXorgScreenPrivateKey, pScreenPriv);
-
- pScreenPriv->SavedEnableDisableFBAccess = pScrn->EnableDisableFBAccess;
- pScrn->EnableDisableFBAccess = exaXorgEnableDisableFBAccess;
-
- pScreenPriv->SavedCloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = exaXorgCloseScreen;
-
-}
-
-static XF86ModuleVersionInfo exaVersRec =
-{
- "exa",
- MODULEVENDORSTRING,
- MODINFOSTRING1,
- MODINFOSTRING2,
- XORG_VERSION_CURRENT,
- EXA_VERSION_MAJOR, EXA_VERSION_MINOR, EXA_VERSION_RELEASE,
- ABI_CLASS_VIDEODRV, /* requires the video driver ABI */
- ABI_VIDEODRV_VERSION,
- MOD_CLASS_NONE,
- {0,0,0,0}
-};
-
-_X_EXPORT XF86ModuleData exaModuleData = { &exaVersRec, NULL, NULL };
+/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * 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 (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <anholt@FreeBSD.org>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <string.h>
+
+#include "exa_priv.h"
+
+#include "xf86str.h"
+#include "xf86.h"
+
+typedef struct _ExaXorgScreenPrivRec {
+ CloseScreenProcPtr SavedCloseScreen;
+ EnableDisableFBAccessProcPtr SavedEnableDisableFBAccess;
+ OptionInfoPtr options;
+} ExaXorgScreenPrivRec, *ExaXorgScreenPrivPtr;
+
+static int exaXorgScreenPrivateKeyIndex;
+static DevPrivateKey exaXorgScreenPrivateKey = &exaXorgScreenPrivateKeyIndex;
+
+typedef enum {
+ EXAOPT_MIGRATION_HEURISTIC,
+ EXAOPT_NO_COMPOSITE,
+ EXAOPT_NO_UTS,
+ EXAOPT_NO_DFS,
+ EXAOPT_OPTIMIZE_MIGRATION
+} EXAOpts;
+
+static const OptionInfoRec EXAOptions[] = {
+ { EXAOPT_MIGRATION_HEURISTIC, "MigrationHeuristic",
+ OPTV_ANYSTR, {0}, FALSE },
+ { EXAOPT_NO_COMPOSITE, "EXANoComposite",
+ OPTV_BOOLEAN, {0}, FALSE },
+ { EXAOPT_NO_UTS, "EXANoUploadToScreen",
+ OPTV_BOOLEAN, {0}, FALSE },
+ { EXAOPT_NO_DFS, "EXANoDownloadFromScreen",
+ OPTV_BOOLEAN, {0}, FALSE },
+ { EXAOPT_OPTIMIZE_MIGRATION, "EXAOptimizeMigration",
+ OPTV_BOOLEAN, {0}, FALSE },
+ { -1, NULL,
+ OPTV_NONE, {0}, FALSE }
+};
+
+static Bool
+exaXorgCloseScreen (int i, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen);
+ ExaXorgScreenPrivPtr pScreenPriv = (ExaXorgScreenPrivPtr)
+ dixLookupPrivate(&pScreen->devPrivates, exaXorgScreenPrivateKey);
+
+ pScreen->CloseScreen = pScreenPriv->SavedCloseScreen;
+
+ pScrn->EnableDisableFBAccess = pScreenPriv->SavedEnableDisableFBAccess;
+
+ free(pScreenPriv->options);
+ free(pScreenPriv);
+
+ return pScreen->CloseScreen (i, pScreen);
+}
+
+static void
+exaXorgEnableDisableFBAccess (int index, Bool enable)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ ExaXorgScreenPrivPtr pScreenPriv = (ExaXorgScreenPrivPtr)
+ dixLookupPrivate(&pScreen->devPrivates, exaXorgScreenPrivateKey);
+
+ if (!enable)
+ exaEnableDisableFBAccess (index, enable);
+
+ if (pScreenPriv->SavedEnableDisableFBAccess)
+ pScreenPriv->SavedEnableDisableFBAccess (index, enable);
+
+ if (enable)
+ exaEnableDisableFBAccess (index, enable);
+}
+
+/**
+ * This will be called during exaDriverInit, giving us the chance to set options
+ * and hook in our EnableDisableFBAccess.
+ */
+void
+exaDDXDriverInit(ScreenPtr pScreen)
+{
+ ExaScreenPriv(pScreen);
+ /* Do NOT use XF86SCRNINFO macro here!! */
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ ExaXorgScreenPrivPtr pScreenPriv;
+
+ pScreenPriv = calloc(1, sizeof(ExaXorgScreenPrivRec));
+ if (pScreenPriv == NULL)
+ return;
+
+ pScreenPriv->options = xnfalloc (sizeof(EXAOptions));
+ memcpy(pScreenPriv->options, EXAOptions, sizeof(EXAOptions));
+ xf86ProcessOptions (pScrn->scrnIndex, pScrn->options, pScreenPriv->options);
+
+ if (pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS) {
+ if (!(pExaScr->info->flags & EXA_HANDLES_PIXMAPS) &&
+ pExaScr->info->offScreenBase < pExaScr->info->memorySize) {
+ char *heuristicName;
+
+ heuristicName = xf86GetOptValString (pScreenPriv->options,
+ EXAOPT_MIGRATION_HEURISTIC);
+ if (heuristicName != NULL) {
+ if (strcmp(heuristicName, "greedy") == 0)
+ pExaScr->migration = ExaMigrationGreedy;
+ else if (strcmp(heuristicName, "always") == 0)
+ pExaScr->migration = ExaMigrationAlways;
+ else if (strcmp(heuristicName, "smart") == 0)
+ pExaScr->migration = ExaMigrationSmart;
+ else {
+ xf86DrvMsg (pScreen->myNum, X_WARNING,
+ "EXA: unknown migration heuristic %s\n",
+ heuristicName);
+ }
+ }
+ }
+
+ pExaScr->optimize_migration =
+ xf86ReturnOptValBool(pScreenPriv->options,
+ EXAOPT_OPTIMIZE_MIGRATION,
+ TRUE);
+ }
+
+ if (xf86ReturnOptValBool(pScreenPriv->options,
+ EXAOPT_NO_COMPOSITE, FALSE)) {
+ xf86DrvMsg(pScreen->myNum, X_CONFIG,
+ "EXA: Disabling Composite operation "
+ "(RENDER acceleration)\n");
+ pExaScr->info->CheckComposite = NULL;
+ pExaScr->info->PrepareComposite = NULL;
+ }
+
+ if (xf86ReturnOptValBool(pScreenPriv->options, EXAOPT_NO_UTS, FALSE)) {
+ xf86DrvMsg(pScreen->myNum, X_CONFIG,
+ "EXA: Disabling UploadToScreen\n");
+ pExaScr->info->UploadToScreen = NULL;
+ }
+
+ if (xf86ReturnOptValBool(pScreenPriv->options, EXAOPT_NO_DFS, FALSE)) {
+ xf86DrvMsg(pScreen->myNum, X_CONFIG,
+ "EXA: Disabling DownloadFromScreen\n");
+ pExaScr->info->DownloadFromScreen = NULL;
+ }
+
+ dixSetPrivate(&pScreen->devPrivates, exaXorgScreenPrivateKey, pScreenPriv);
+
+ pScreenPriv->SavedEnableDisableFBAccess = pScrn->EnableDisableFBAccess;
+ pScrn->EnableDisableFBAccess = exaXorgEnableDisableFBAccess;
+
+ pScreenPriv->SavedCloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = exaXorgCloseScreen;
+
+}
+
+static XF86ModuleVersionInfo exaVersRec =
+{
+ "exa",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XORG_VERSION_CURRENT,
+ EXA_VERSION_MAJOR, EXA_VERSION_MINOR, EXA_VERSION_RELEASE,
+ ABI_CLASS_VIDEODRV, /* requires the video driver ABI */
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_NONE,
+ {0,0,0,0}
+};
+
+_X_EXPORT XF86ModuleData exaModuleData = { &exaVersRec, NULL, NULL };
diff --git a/xorg-server/hw/xfree86/fbdevhw/fbdevhw.c b/xorg-server/hw/xfree86/fbdevhw/fbdevhw.c
index 880f0a20e..3f7391d50 100644
--- a/xorg-server/hw/xfree86/fbdevhw/fbdevhw.c
+++ b/xorg-server/hw/xfree86/fbdevhw/fbdevhw.c
@@ -1,1009 +1,1009 @@
-/* all driver need this */
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <string.h>
-
-#include "xf86.h"
-#include "xf86_OSproc.h"
-
-/* pci stuff */
-#include "xf86PciInfo.h"
-#include "xf86Pci.h"
-
-#include "xf86cmap.h"
-
-#include "fbdevhw.h"
-#include "fbpriv.h"
-
-#define PAGE_MASK (~(getpagesize() - 1))
-
-#include "globals.h"
-#include <X11/extensions/dpmsconst.h>
-
-#define DEBUG 0
-
-#define PAGE_MASK (~(getpagesize() - 1))
-
-#if DEBUG
-# define TRACE_ENTER(str) ErrorF("fbdevHW: " str " %d\n",pScrn->scrnIndex)
-#else
-# define TRACE_ENTER(str)
-#endif
-
-/* -------------------------------------------------------------------- */
-
-static MODULESETUPPROTO(fbdevhwSetup);
-
-static XF86ModuleVersionInfo fbdevHWVersRec =
-{
- "fbdevhw",
- MODULEVENDORSTRING,
- MODINFOSTRING1,
- MODINFOSTRING2,
- XORG_VERSION_CURRENT,
- 0, 0, 2,
- ABI_CLASS_VIDEODRV,
- ABI_VIDEODRV_VERSION,
- MOD_CLASS_NONE,
- {0,0,0,0}
-};
-
-_X_EXPORT XF86ModuleData fbdevhwModuleData = {
- &fbdevHWVersRec,
- fbdevhwSetup,
- NULL
-};
-
-static pointer
-fbdevhwSetup(pointer module, pointer opts, int *errmaj, int *errmin)
-{
- return (pointer)1;
-}
-
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-
-/* -------------------------------------------------------------------- */
-/* our private data, and two functions to allocate/free this */
-
-#define FBDEVHWPTRLVAL(p) (p)->privates[fbdevHWPrivateIndex].ptr
-#define FBDEVHWPTR(p) ((fbdevHWPtr)(FBDEVHWPTRLVAL(p)))
-
-static int fbdevHWPrivateIndex = -1;
-
-typedef struct {
- /* framebuffer device: filename (/dev/fb*), handle, more */
- char* device;
- int fd;
- void* fbmem;
- unsigned int fbmem_len;
- unsigned int fboff;
- char* mmio;
- unsigned int mmio_len;
-
- /* current hardware state */
- struct fb_fix_screeninfo fix;
- struct fb_var_screeninfo var;
-
- /* saved video mode */
- struct fb_var_screeninfo saved_var;
-
- /* FIXME: unused??? [geert] */
- struct fb_cmap saved_cmap;
- unsigned short *saved_red;
- unsigned short *saved_green;
- unsigned short *saved_blue;
-
- /* buildin video mode */
- DisplayModeRec buildin;
-
-} fbdevHWRec, *fbdevHWPtr;
-
-Bool
-fbdevHWGetRec(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr;
-
- if (fbdevHWPrivateIndex < 0)
- fbdevHWPrivateIndex = xf86AllocateScrnInfoPrivateIndex();
-
- if (FBDEVHWPTR(pScrn) != NULL)
- return TRUE;
-
- fPtr = FBDEVHWPTRLVAL(pScrn) = xnfcalloc(sizeof(fbdevHWRec), 1);
- return TRUE;
-}
-
-void
-fbdevHWFreeRec(ScrnInfoPtr pScrn)
-{
- if (fbdevHWPrivateIndex < 0)
- return;
- if (FBDEVHWPTR(pScrn) == NULL)
- return;
- xfree(FBDEVHWPTR(pScrn));
- FBDEVHWPTRLVAL(pScrn) = NULL;
-}
-
-int
-fbdevHWGetFD(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr;
-
- fbdevHWGetRec(pScrn);
- fPtr = FBDEVHWPTR(pScrn);
-
- return fPtr->fd;
-}
-
-/* -------------------------------------------------------------------- */
-/* some helpers for printing debug informations */
-
-#if DEBUG
-static void
-print_fbdev_mode(char *txt, struct fb_var_screeninfo *var)
-{
- ErrorF( "fbdev %s mode:\t%d %d %d %d %d %d %d %d %d %d %d:%d:%d\n",
- txt,var->pixclock,
- var->xres, var->right_margin, var->hsync_len, var->left_margin,
- var->yres, var->lower_margin, var->vsync_len, var->upper_margin,
- var->bits_per_pixel,
- var->red.length, var->green.length, var->blue.length);
-}
-
-static void
-print_xfree_mode(char *txt, DisplayModePtr mode)
-{
- ErrorF( "xfree %s mode:\t%d %d %d %d %d %d %d %d %d\n",
- txt,mode->Clock,
- mode->HDisplay, mode->HSyncStart, mode->HSyncEnd, mode->HTotal,
- mode->VDisplay, mode->VSyncStart, mode->VSyncEnd, mode->VTotal);
-}
-#endif
-
-/* -------------------------------------------------------------------- */
-/* Convert timings between the XFree and the Frame Buffer Device */
-
-static void
-xfree2fbdev_fblayout(ScrnInfoPtr pScrn, struct fb_var_screeninfo *var)
-{
- var->xres_virtual = pScrn->displayWidth ? pScrn->displayWidth :
- pScrn->virtualX;
- var->yres_virtual = pScrn->virtualY;
- var->bits_per_pixel = pScrn->bitsPerPixel;
- if (pScrn->defaultVisual == TrueColor ||
- pScrn->defaultVisual == DirectColor) {
- var->red.length = pScrn->weight.red;
- var->green.length = pScrn->weight.green;
- var->blue.length = pScrn->weight.blue;
- } else {
- var->red.length = 8;
- var->green.length = 8;
- var->blue.length = 8;
- }
-}
-
-static void
-xfree2fbdev_timing(DisplayModePtr mode, struct fb_var_screeninfo *var)
-{
- var->xres = mode->HDisplay;
- var->yres = mode->VDisplay;
- if (var->xres_virtual < var->xres)
- var->xres_virtual = var->xres;
- if (var->yres_virtual < var->yres)
- var->yres_virtual = var->yres;
- var->xoffset = var->yoffset = 0;
- var->pixclock = mode->Clock ? 1000000000/mode->Clock : 0;
- var->right_margin = mode->HSyncStart-mode->HDisplay;
- var->hsync_len = mode->HSyncEnd-mode->HSyncStart;
- var->left_margin = mode->HTotal-mode->HSyncEnd;
- var->lower_margin = mode->VSyncStart-mode->VDisplay;
- var->vsync_len = mode->VSyncEnd-mode->VSyncStart;
- var->upper_margin = mode->VTotal-mode->VSyncEnd;
- var->sync = 0;
- if (mode->Flags & V_PHSYNC)
- var->sync |= FB_SYNC_HOR_HIGH_ACT;
- if (mode->Flags & V_PVSYNC)
- var->sync |= FB_SYNC_VERT_HIGH_ACT;
- if (mode->Flags & V_PCSYNC)
- var->sync |= FB_SYNC_COMP_HIGH_ACT;
- if (mode->Flags & V_BCAST)
- var->sync |= FB_SYNC_BROADCAST;
- if (mode->Flags & V_INTERLACE)
- var->vmode = FB_VMODE_INTERLACED;
- else if (mode->Flags & V_DBLSCAN)
- var->vmode = FB_VMODE_DOUBLE;
- else
- var->vmode = FB_VMODE_NONINTERLACED;
-}
-
-static Bool
-fbdev_modes_equal(struct fb_var_screeninfo *set, struct fb_var_screeninfo *req)
-{
- return (set->xres_virtual >= req->xres_virtual &&
- set->yres_virtual >= req->yres_virtual &&
- set->bits_per_pixel == req->bits_per_pixel &&
- set->red.length == req->red.length &&
- set->green.length == req->green.length &&
- set->blue.length == req->blue.length &&
- set->xres == req->xres && set->yres == req->yres &&
- set->right_margin == req->right_margin &&
- set->hsync_len == req->hsync_len &&
- set->left_margin == req->left_margin &&
- set->lower_margin == req->lower_margin &&
- set->vsync_len == req->vsync_len &&
- set->upper_margin == req->upper_margin &&
- set->sync == req->sync && set->vmode == req->vmode);
-}
-
-static void
-fbdev2xfree_timing(struct fb_var_screeninfo *var, DisplayModePtr mode)
-{
- mode->Clock = var->pixclock ? 1000000000/var->pixclock : 0;
- mode->HDisplay = var->xres;
- mode->HSyncStart = mode->HDisplay+var->right_margin;
- mode->HSyncEnd = mode->HSyncStart+var->hsync_len;
- mode->HTotal = mode->HSyncEnd+var->left_margin;
- mode->VDisplay = var->yres;
- mode->VSyncStart = mode->VDisplay+var->lower_margin;
- mode->VSyncEnd = mode->VSyncStart+var->vsync_len;
- mode->VTotal = mode->VSyncEnd+var->upper_margin;
- mode->Flags = 0;
- mode->Flags |= var->sync & FB_SYNC_HOR_HIGH_ACT ? V_PHSYNC : V_NHSYNC;
- mode->Flags |= var->sync & FB_SYNC_VERT_HIGH_ACT ? V_PVSYNC : V_NVSYNC;
- mode->Flags |= var->sync & FB_SYNC_COMP_HIGH_ACT ? V_PCSYNC : V_NCSYNC;
- if (var->sync & FB_SYNC_BROADCAST)
- mode->Flags |= V_BCAST;
- if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)
- mode->Flags |= V_INTERLACE;
- else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
- mode->Flags |= V_DBLSCAN;
- mode->SynthClock = mode->Clock;
- mode->CrtcHDisplay = mode->HDisplay;
- mode->CrtcHSyncStart = mode->HSyncStart;
- mode->CrtcHSyncEnd = mode->HSyncEnd;
- mode->CrtcHTotal = mode->HTotal;
- mode->CrtcVDisplay = mode->VDisplay;
- mode->CrtcVSyncStart = mode->VSyncStart;
- mode->CrtcVSyncEnd = mode->VSyncEnd;
- mode->CrtcVTotal = mode->VTotal;
- mode->CrtcHAdjusted = FALSE;
- mode->CrtcVAdjusted = FALSE;
-}
-
-
-/* -------------------------------------------------------------------- */
-/* open correct framebuffer device */
-
-/**
- * Try to find the framebuffer device for a given PCI device
- */
-static int
-fbdev_open_pci(struct pci_device * pPci, char **namep)
-{
- struct fb_fix_screeninfo fix;
- char filename[256];
- int fd,i,j;
-
-
- /* There are two ways to that we can determine which fb device is
- * associated with this PCI device. The more modern way is to look in
- * the sysfs directory for the PCI device for a file named
- * "graphics/fb*"
- */
-
- for (i = 0; i < 8; i++) {
- sprintf(filename,
- "/sys/bus/pci/devices/%04x:%02x:%02x.%d/graphics/fb%d",
- pPci->domain, pPci->bus, pPci->dev, pPci->func, i);
-
- fd = open(filename, O_RDONLY, 0);
- if (fd < 0) {
- sprintf(filename,
- "/sys/bus/pci/devices/%04x:%02x:%02x.%d/graphics:fb%d",
- pPci->domain, pPci->bus, pPci->dev, pPci->func, i);
- fd = open(filename, O_RDONLY, 0);
- }
- if (fd >= 0) {
- close(fd);
- sprintf(filename, "/dev/fb%d", i);
-
- fd = open(filename, O_RDWR, 0);
- if (fd != -1) {
- if (ioctl(fd, FBIOGET_FSCREENINFO, (void*) & fix) != -1) {
- if (namep) {
- *namep = xnfalloc(16);
- strncpy(*namep,fix.id,16);
- }
-
- return fd;
- }
- close(fd);
- }
- }
- }
-
-
- /* The other way is to examine the resources associated with each fb
- * device and see if there is a match with the PCI device. This technique
- * has some problems on certain mixed 64-bit / 32-bit architectures.
- * There is a flaw in the fb_fix_screeninfo structure in that it only
- * returns the low 32-bits of the address of the resources associated with
- * a device. However, on a mixed architecture the base addresses of PCI
- * devices, even for 32-bit applications, may be higher than 0x0f0000000.
- */
-
- for (i = 0; i < 8; i++) {
- sprintf(filename,"/dev/fb%d",i);
- if (-1 == (fd = open(filename,O_RDWR,0))) {
- xf86DrvMsg(-1, X_WARNING,
- "open %s: %s\n", filename, strerror(errno));
- continue;
- }
- if (-1 == ioctl(fd,FBIOGET_FSCREENINFO,(void*)&fix)) {
- close(fd);
- continue;
- }
- for (j = 0; j < 6; j++) {
- const pciaddr_t res_start = pPci->regions[j].base_addr;
- const pciaddr_t res_end = res_start + pPci->regions[j].size;
-
- if ((0 != fix.smem_len &&
- (pciaddr_t) fix.smem_start >= res_start &&
- (pciaddr_t) fix.smem_start < res_end) ||
- (0 != fix.mmio_len &&
- (pciaddr_t) fix.mmio_start >= res_start &&
- (pciaddr_t) fix.mmio_start < res_end))
- break;
- }
- if (j == 6) {
- close(fd);
- continue;
- }
- if (namep) {
- *namep = xnfalloc(16);
- strncpy(*namep,fix.id,16);
- }
- return fd;
- }
-
- if (namep)
- *namep = NULL;
-
- xf86DrvMsg(-1, X_ERROR,
- "Unable to find a valid framebuffer device\n");
- return -1;
-}
-
-static int
-fbdev_open(int scrnIndex, char *dev, char** namep)
-{
- struct fb_fix_screeninfo fix;
- int fd;
-
- /* try argument (from XF86Config) first */
- if (dev) {
- fd = open(dev,O_RDWR,0);
- } else {
- /* second: environment variable */
- dev = getenv("FRAMEBUFFER");
- if ((NULL == dev) || ((fd = open(dev,O_RDWR,0)) == -1)) {
- /* last try: default device */
- dev = "/dev/fb0";
- fd = open(dev,O_RDWR,0);
- }
- }
-
- if (fd == -1) {
- xf86DrvMsg(scrnIndex, X_ERROR,
- "open %s: %s\n", dev, strerror(errno));
- return -1;
- }
-
- if (namep) {
- if (-1 == ioctl(fd,FBIOGET_FSCREENINFO,(void*)(&fix))) {
- *namep = NULL;
- xf86DrvMsg(scrnIndex, X_ERROR,
- "FBIOGET_FSCREENINFO: %s\n", strerror(errno));
- return -1;
- } else {
- *namep = xnfalloc(16);
- strncpy(*namep,fix.id,16);
- }
- }
- return fd;
-}
-
-/* -------------------------------------------------------------------- */
-
-Bool
-fbdevHWProbe(struct pci_device * pPci, char *device,char **namep)
-{
- int fd;
-
- if (pPci)
- fd = fbdev_open_pci(pPci,namep);
- else
- fd = fbdev_open(-1,device,namep);
-
- if (-1 == fd)
- return FALSE;
- close(fd);
- return TRUE;
-}
-
-Bool
-fbdevHWInit(ScrnInfoPtr pScrn, struct pci_device * pPci, char *device)
-{
- fbdevHWPtr fPtr;
-
- TRACE_ENTER("Init");
-
- fbdevHWGetRec(pScrn);
- fPtr = FBDEVHWPTR(pScrn);
-
- /* open device */
- if (pPci)
- fPtr->fd = fbdev_open_pci(pPci,NULL);
- else
- fPtr->fd = fbdev_open(pScrn->scrnIndex,device,NULL);
- if (-1 == fPtr->fd) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Failed to open framebuffer device, consult warnings"
- " and/or errors above for possible reasons\n"
- "\t(you may have to look at the server log to see"
- " warnings)\n");
- return FALSE;
- }
-
- /* get current fb device settings */
- if (-1 == ioctl(fPtr->fd,FBIOGET_FSCREENINFO,(void*)(&fPtr->fix))) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "ioctl FBIOGET_FSCREENINFO: %s\n",
- strerror(errno));
- return FALSE;
- }
- if (-1 == ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->var))) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "ioctl FBIOGET_VSCREENINFO: %s\n",
- strerror(errno));
- return FALSE;
- }
-
- /* we can use the current settings as "buildin mode" */
- fbdev2xfree_timing(&fPtr->var, &fPtr->buildin);
- fPtr->buildin.name = "current";
- fPtr->buildin.next = &fPtr->buildin;
- fPtr->buildin.prev = &fPtr->buildin;
- fPtr->buildin.type |= M_T_BUILTIN;
-
- return TRUE;
-}
-
-char*
-fbdevHWGetName(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
- return fPtr->fix.id;
-}
-
-int
-fbdevHWGetDepth(ScrnInfoPtr pScrn, int *fbbpp)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- if (fbbpp)
- *fbbpp = fPtr->var.bits_per_pixel;
-
- if (fPtr->fix.visual == FB_VISUAL_TRUECOLOR ||
- fPtr->fix.visual == FB_VISUAL_DIRECTCOLOR)
- return fPtr->var.red.length+fPtr->var.green.length+
- fPtr->var.blue.length;
- else
- return fPtr->var.bits_per_pixel;
-}
-
-int
-fbdevHWGetLineLength(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- if (fPtr->fix.line_length)
- return fPtr->fix.line_length;
- else
- return fPtr->var.xres_virtual*fPtr->var.bits_per_pixel/8;
-}
-
-int
-fbdevHWGetType(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
- return fPtr->fix.type;
-}
-
-int
-fbdevHWGetVidmem(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
- return fPtr->fix.smem_len;
-}
-
-static Bool
-fbdevHWSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, Bool check)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
- struct fb_var_screeninfo req_var = fPtr->var, set_var;
-
- TRACE_ENTER("SetMode");
-
- xfree2fbdev_fblayout(pScrn, &req_var);
- xfree2fbdev_timing(mode, &req_var);
-
-#if DEBUG
- print_xfree_mode("init", mode);
- print_fbdev_mode("init", &req_var);
-#endif
-
- set_var = req_var;
-
- if (check)
- set_var.activate = FB_ACTIVATE_TEST;
-
- if (0 != ioctl(fPtr->fd, FBIOPUT_VSCREENINFO, (void*)(&set_var))) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "FBIOPUT_VSCREENINFO: %s\n", strerror(errno));
- return FALSE;
- }
-
- if (!fbdev_modes_equal(&set_var, &req_var)) {
- if (!check)
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "FBIOPUT_VSCREENINFO succeeded but modified "
- "mode\n");
-#if DEBUG
- print_fbdev_mode("returned", &set_var);
-#endif
- return FALSE;
- }
-
- if (!check)
- fPtr->var = set_var;
-
- return TRUE;
-}
-
-void
-fbdevHWSetVideoModes(ScrnInfoPtr pScrn)
-{
- char **modename;
- DisplayModePtr mode,this,last = pScrn->modes;
-
- TRACE_ENTER("VerifyModes");
- if (NULL == pScrn->display->modes)
- return;
-
- pScrn->virtualX = pScrn->display->virtualX;
- pScrn->virtualY = pScrn->display->virtualY;
-
- for (modename = pScrn->display->modes; *modename != NULL; modename++) {
- for (mode = pScrn->monitor->Modes; mode != NULL; mode = mode->next)
- if (0 == strcmp(mode->name,*modename))
- break;
- if (NULL == mode) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "\tmode \"%s\" not found\n", *modename);
- continue;
- }
-
- if (!fbdevHWSetMode(pScrn, mode, TRUE)) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "\tmode \"%s\" test failed\n", *modename);
- continue;
- }
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "\tmode \"%s\" ok\n", *modename);
-
- if (pScrn->virtualX < mode->HDisplay)
- pScrn->virtualX = mode->HDisplay;
- if (pScrn->virtualY < mode->VDisplay)
- pScrn->virtualY = mode->VDisplay;
-
- if (NULL == pScrn->modes) {
- this = pScrn->modes = xf86DuplicateMode(mode);
- this->next = this;
- this->prev = this;
- } else {
- this = xf86DuplicateMode(mode);
- this->next = pScrn->modes;
- this->prev = last;
- last->next = this;
- pScrn->modes->prev = this;
- }
- last = this;
- }
-}
-
-DisplayModePtr
-fbdevHWGetBuildinMode(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
- return &fPtr->buildin;
-}
-
-void
-fbdevHWUseBuildinMode(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- TRACE_ENTER("UseBuildinMode");
- pScrn->modes = &fPtr->buildin;
- pScrn->virtualX = pScrn->display->virtualX;
- pScrn->virtualY = pScrn->display->virtualY;
- if (pScrn->virtualX < fPtr->buildin.HDisplay)
- pScrn->virtualX = fPtr->buildin.HDisplay;
- if (pScrn->virtualY < fPtr->buildin.VDisplay)
- pScrn->virtualY = fPtr->buildin.VDisplay;
-}
-
-/* -------------------------------------------------------------------- */
-
-static void
-calculateFbmem_len(fbdevHWPtr fPtr)
-{
- fPtr->fboff = (unsigned long) fPtr->fix.smem_start & ~PAGE_MASK;
- fPtr->fbmem_len = (fPtr->fboff+fPtr->fix.smem_len+~PAGE_MASK) &
- PAGE_MASK;
-}
-
-
-void*
-fbdevHWMapVidmem(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- TRACE_ENTER("MapVidmem");
- if (NULL == fPtr->fbmem) {
- calculateFbmem_len(fPtr);
- fPtr->fbmem = mmap(NULL, fPtr->fbmem_len, PROT_READ | PROT_WRITE,
- MAP_SHARED, fPtr->fd, 0);
- if (-1 == (long)fPtr->fbmem) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "mmap fbmem: %s\n", strerror(errno));
- fPtr->fbmem = NULL;
- } else {
- /* Perhaps we'd better add fboff to fbmem and return 0 in
- fbdevHWLinearOffset()? Of course we then need to mask
- fPtr->fbmem with PAGE_MASK in fbdevHWUnmapVidmem() as
- well. [geert] */
- }
- }
- pScrn->memPhysBase = (unsigned long)fPtr->fix.smem_start & (unsigned long)(PAGE_MASK);
- pScrn->fbOffset = (unsigned long)fPtr->fix.smem_start & (unsigned long)(~PAGE_MASK);
- return fPtr->fbmem;
-}
-
-int
-fbdevHWLinearOffset(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- TRACE_ENTER("LinearOffset");
- return fPtr->fboff;
-}
-
-Bool
-fbdevHWUnmapVidmem(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- TRACE_ENTER("UnmapVidmem");
- if (NULL != fPtr->fbmem) {
- if (-1 == munmap(fPtr->fbmem, fPtr->fbmem_len))
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "munmap fbmem: %s\n", strerror(errno));
- fPtr->fbmem = NULL;
- }
- return TRUE;
-}
-
-void*
-fbdevHWMapMMIO(ScrnInfoPtr pScrn)
-{
- unsigned int mmio_off;
-
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- TRACE_ENTER("MapMMIO");
- if (NULL == fPtr->mmio) {
- /* tell the kernel not to use accels to speed up console scrolling */
- fPtr->var.accel_flags = 0;
- if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->var))) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "FBIOPUT_VSCREENINFO: %s\n", strerror(errno));
- return FALSE;
- }
- mmio_off = (unsigned long) fPtr->fix.mmio_start & ~PAGE_MASK;
- fPtr->mmio_len = (mmio_off+fPtr->fix.mmio_len+~PAGE_MASK) &
- PAGE_MASK;
- if (NULL == fPtr->fbmem)
- calculateFbmem_len(fPtr);
- fPtr->mmio = mmap(NULL, fPtr->mmio_len, PROT_READ | PROT_WRITE,
- MAP_SHARED, fPtr->fd, fPtr->fbmem_len);
- if (-1 == (long)fPtr->mmio) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "mmap mmio: %s\n", strerror(errno));
- fPtr->mmio = NULL;
- } else
- fPtr->mmio += mmio_off;
- }
- return fPtr->mmio;
-}
-
-Bool
-fbdevHWUnmapMMIO(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- TRACE_ENTER("UnmapMMIO");
- if (NULL != fPtr->mmio) {
- if (-1 == munmap((void *)((unsigned long)fPtr->mmio & PAGE_MASK), fPtr->mmio_len))
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "munmap mmio: %s\n", strerror(errno));
- fPtr->mmio = NULL;
- /* FIXME: restore var.accel_flags [geert] */
- }
- return TRUE;
-}
-
-/* -------------------------------------------------------------------- */
-
-Bool
-fbdevHWModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- pScrn->vtSema = TRUE;
-
- /* set */
- if (!fbdevHWSetMode(pScrn, mode, FALSE))
- return FALSE;
-
- /* read back */
- if (0 != ioctl(fPtr->fd,FBIOGET_FSCREENINFO,(void*)(&fPtr->fix))) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "FBIOGET_FSCREENINFO: %s\n", strerror(errno));
- return FALSE;
- }
- if (0 != ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->var))) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "FBIOGET_VSCREENINFO: %s\n", strerror(errno));
- return FALSE;
- }
-
- if (pScrn->defaultVisual == TrueColor ||
- pScrn->defaultVisual == DirectColor) {
- /* XXX: This is a hack, but it should be a NOP for all the setups that
- * worked before and actually seems to fix some others...
- */
- pScrn->offset.red = fPtr->var.red.offset;
- pScrn->offset.green = fPtr->var.green.offset;
- pScrn->offset.blue = fPtr->var.blue.offset;
- pScrn->mask.red = ((1 << fPtr->var.red.length) - 1) << fPtr->var.red.offset;
- pScrn->mask.green = ((1 << fPtr->var.green.length) - 1) << fPtr->var.green.offset;
- pScrn->mask.blue = ((1 << fPtr->var.blue.length) - 1) << fPtr->var.blue.offset;
- }
-
- return TRUE;
-}
-
-/* -------------------------------------------------------------------- */
-/* video mode save/restore */
-
-/* TODO: colormap */
-void
-fbdevHWSave(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- TRACE_ENTER("Save");
- if (0 != ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->saved_var)))
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "FBIOGET_VSCREENINFO: %s\n", strerror(errno));
-}
-
-void
-fbdevHWRestore(ScrnInfoPtr pScrn)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- TRACE_ENTER("Restore");
- if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->saved_var)))
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "FBIOPUT_VSCREENINFO: %s\n", strerror(errno));
-}
-
-/* -------------------------------------------------------------------- */
-/* callback for xf86HandleColormaps */
-
-void
-fbdevHWLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
- LOCO *colors, VisualPtr pVisual)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
- struct fb_cmap cmap;
- unsigned short red,green,blue;
- int i;
-
- TRACE_ENTER("LoadPalette");
- cmap.len = 1;
- cmap.red = &red;
- cmap.green = &green;
- cmap.blue = &blue;
- cmap.transp = NULL;
- for (i = 0; i < numColors; i++) {
- cmap.start = indices[i];
- red = (colors[indices[i]].red << 8) |
- colors[indices[i]].red;
- green = (colors[indices[i]].green << 8) |
- colors[indices[i]].green;
- blue = (colors[indices[i]].blue << 8) |
- colors[indices[i]].blue;
- if (-1 == ioctl(fPtr->fd,FBIOPUTCMAP,(void*)&cmap))
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "FBIOPUTCMAP: %s\n", strerror(errno));
- }
-}
-
-/* -------------------------------------------------------------------- */
-/* these can be hooked directly into ScrnInfoRec */
-
-ModeStatus
-fbdevHWValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
-
- TRACE_ENTER("ValidMode");
-
- if (!fbdevHWSetMode(pScrn, mode, TRUE))
- return MODE_BAD;
-
- return MODE_OK;
-}
-
-Bool
-fbdevHWSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
-
- TRACE_ENTER("SwitchMode");
-
- if (!fbdevHWSetMode(pScrn, mode, FALSE))
- return FALSE;
-
- return TRUE;
-}
-
-void
-fbdevHWAdjustFrame(int scrnIndex, int x, int y, int flags)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
-
- TRACE_ENTER("AdjustFrame");
- if ( x < 0 || x + fPtr->var.xres > fPtr->var.xres_virtual ||
- y < 0 || y + fPtr->var.yres > fPtr->var.yres_virtual )
- return;
-
- fPtr->var.xoffset = x;
- fPtr->var.yoffset = y;
- if (-1 == ioctl(fPtr->fd,FBIOPAN_DISPLAY,(void*)&fPtr->var))
- xf86DrvMsgVerb(scrnIndex, X_WARNING, 5,
- "FBIOPAN_DISPLAY: %s\n", strerror(errno));
-}
-
-Bool
-fbdevHWEnterVT(int scrnIndex, int flags)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
-
- TRACE_ENTER("EnterVT");
- if (!fbdevHWModeInit(pScrn, pScrn->currentMode))
- return FALSE;
- fbdevHWAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
- return TRUE;
-}
-
-void
-fbdevHWLeaveVT(int scrnIndex, int flags)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
-
- TRACE_ENTER("LeaveVT");
- fbdevHWRestore(pScrn);
-}
-
-void
-fbdevHWDPMSSet(ScrnInfoPtr pScrn, int mode, int flags)
-{
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
- unsigned long fbmode;
-
- TRACE_ENTER("DPMSSet");
- if (!pScrn->vtSema)
- return;
-
- switch (mode) {
- case DPMSModeOn:
- fbmode = 0;
- break;
- case DPMSModeStandby:
- fbmode = 2;
- break;
- case DPMSModeSuspend:
- fbmode = 3;
- break;
- case DPMSModeOff:
- fbmode = 4;
- break;
- default:
- return;
- }
-
- if (-1 == ioctl(fPtr->fd, FBIOBLANK, (void *)fbmode))
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "FBIOBLANK: %s\n", strerror(errno));
-}
-
-Bool
-fbdevHWSaveScreen(ScreenPtr pScreen, int mode)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
- unsigned long unblank;
-
- TRACE_ENTER("HWSaveScreen");
- if (!pScrn->vtSema)
- return TRUE;
-
- unblank = xf86IsUnblank(mode);
-
- if (-1 == ioctl(fPtr->fd, FBIOBLANK, (void *)(1-unblank))) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "FBIOBLANK: %s\n", strerror(errno));
- return FALSE;
- }
-
- return TRUE;
-}
-
-xf86SwitchModeProc *
-fbdevHWSwitchModeWeak(void) { return fbdevHWSwitchMode; }
-
-xf86AdjustFrameProc *
-fbdevHWAdjustFrameWeak(void) { return fbdevHWAdjustFrame; }
-
-xf86EnterVTProc *
-fbdevHWEnterVTWeak(void) { return fbdevHWEnterVT; }
-
-xf86LeaveVTProc *
-fbdevHWLeaveVTWeak(void) { return fbdevHWLeaveVT; }
-
-xf86ValidModeProc *
-fbdevHWValidModeWeak(void) { return fbdevHWValidMode; }
-
-xf86DPMSSetProc *
-fbdevHWDPMSSetWeak(void) { return fbdevHWDPMSSet; }
-
-xf86LoadPaletteProc *
-fbdevHWLoadPaletteWeak(void) { return fbdevHWLoadPalette; }
-
-SaveScreenProcPtr
-fbdevHWSaveScreenWeak(void) { return fbdevHWSaveScreen; }
+/* all driver need this */
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <string.h>
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+/* pci stuff */
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+#include "xf86cmap.h"
+
+#include "fbdevhw.h"
+#include "fbpriv.h"
+
+#define PAGE_MASK (~(getpagesize() - 1))
+
+#include "globals.h"
+#include <X11/extensions/dpmsconst.h>
+
+#define DEBUG 0
+
+#define PAGE_MASK (~(getpagesize() - 1))
+
+#if DEBUG
+# define TRACE_ENTER(str) ErrorF("fbdevHW: " str " %d\n",pScrn->scrnIndex)
+#else
+# define TRACE_ENTER(str)
+#endif
+
+/* -------------------------------------------------------------------- */
+
+static MODULESETUPPROTO(fbdevhwSetup);
+
+static XF86ModuleVersionInfo fbdevHWVersRec =
+{
+ "fbdevhw",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XORG_VERSION_CURRENT,
+ 0, 0, 2,
+ ABI_CLASS_VIDEODRV,
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_NONE,
+ {0,0,0,0}
+};
+
+_X_EXPORT XF86ModuleData fbdevhwModuleData = {
+ &fbdevHWVersRec,
+ fbdevhwSetup,
+ NULL
+};
+
+static pointer
+fbdevhwSetup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ return (pointer)1;
+}
+
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+/* -------------------------------------------------------------------- */
+/* our private data, and two functions to allocate/free this */
+
+#define FBDEVHWPTRLVAL(p) (p)->privates[fbdevHWPrivateIndex].ptr
+#define FBDEVHWPTR(p) ((fbdevHWPtr)(FBDEVHWPTRLVAL(p)))
+
+static int fbdevHWPrivateIndex = -1;
+
+typedef struct {
+ /* framebuffer device: filename (/dev/fb*), handle, more */
+ char* device;
+ int fd;
+ void* fbmem;
+ unsigned int fbmem_len;
+ unsigned int fboff;
+ char* mmio;
+ unsigned int mmio_len;
+
+ /* current hardware state */
+ struct fb_fix_screeninfo fix;
+ struct fb_var_screeninfo var;
+
+ /* saved video mode */
+ struct fb_var_screeninfo saved_var;
+
+ /* FIXME: unused??? [geert] */
+ struct fb_cmap saved_cmap;
+ unsigned short *saved_red;
+ unsigned short *saved_green;
+ unsigned short *saved_blue;
+
+ /* buildin video mode */
+ DisplayModeRec buildin;
+
+} fbdevHWRec, *fbdevHWPtr;
+
+Bool
+fbdevHWGetRec(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr;
+
+ if (fbdevHWPrivateIndex < 0)
+ fbdevHWPrivateIndex = xf86AllocateScrnInfoPrivateIndex();
+
+ if (FBDEVHWPTR(pScrn) != NULL)
+ return TRUE;
+
+ fPtr = FBDEVHWPTRLVAL(pScrn) = xnfcalloc(sizeof(fbdevHWRec), 1);
+ return TRUE;
+}
+
+void
+fbdevHWFreeRec(ScrnInfoPtr pScrn)
+{
+ if (fbdevHWPrivateIndex < 0)
+ return;
+ if (FBDEVHWPTR(pScrn) == NULL)
+ return;
+ free(FBDEVHWPTR(pScrn));
+ FBDEVHWPTRLVAL(pScrn) = NULL;
+}
+
+int
+fbdevHWGetFD(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr;
+
+ fbdevHWGetRec(pScrn);
+ fPtr = FBDEVHWPTR(pScrn);
+
+ return fPtr->fd;
+}
+
+/* -------------------------------------------------------------------- */
+/* some helpers for printing debug informations */
+
+#if DEBUG
+static void
+print_fbdev_mode(char *txt, struct fb_var_screeninfo *var)
+{
+ ErrorF( "fbdev %s mode:\t%d %d %d %d %d %d %d %d %d %d %d:%d:%d\n",
+ txt,var->pixclock,
+ var->xres, var->right_margin, var->hsync_len, var->left_margin,
+ var->yres, var->lower_margin, var->vsync_len, var->upper_margin,
+ var->bits_per_pixel,
+ var->red.length, var->green.length, var->blue.length);
+}
+
+static void
+print_xfree_mode(char *txt, DisplayModePtr mode)
+{
+ ErrorF( "xfree %s mode:\t%d %d %d %d %d %d %d %d %d\n",
+ txt,mode->Clock,
+ mode->HDisplay, mode->HSyncStart, mode->HSyncEnd, mode->HTotal,
+ mode->VDisplay, mode->VSyncStart, mode->VSyncEnd, mode->VTotal);
+}
+#endif
+
+/* -------------------------------------------------------------------- */
+/* Convert timings between the XFree and the Frame Buffer Device */
+
+static void
+xfree2fbdev_fblayout(ScrnInfoPtr pScrn, struct fb_var_screeninfo *var)
+{
+ var->xres_virtual = pScrn->displayWidth ? pScrn->displayWidth :
+ pScrn->virtualX;
+ var->yres_virtual = pScrn->virtualY;
+ var->bits_per_pixel = pScrn->bitsPerPixel;
+ if (pScrn->defaultVisual == TrueColor ||
+ pScrn->defaultVisual == DirectColor) {
+ var->red.length = pScrn->weight.red;
+ var->green.length = pScrn->weight.green;
+ var->blue.length = pScrn->weight.blue;
+ } else {
+ var->red.length = 8;
+ var->green.length = 8;
+ var->blue.length = 8;
+ }
+}
+
+static void
+xfree2fbdev_timing(DisplayModePtr mode, struct fb_var_screeninfo *var)
+{
+ var->xres = mode->HDisplay;
+ var->yres = mode->VDisplay;
+ if (var->xres_virtual < var->xres)
+ var->xres_virtual = var->xres;
+ if (var->yres_virtual < var->yres)
+ var->yres_virtual = var->yres;
+ var->xoffset = var->yoffset = 0;
+ var->pixclock = mode->Clock ? 1000000000/mode->Clock : 0;
+ var->right_margin = mode->HSyncStart-mode->HDisplay;
+ var->hsync_len = mode->HSyncEnd-mode->HSyncStart;
+ var->left_margin = mode->HTotal-mode->HSyncEnd;
+ var->lower_margin = mode->VSyncStart-mode->VDisplay;
+ var->vsync_len = mode->VSyncEnd-mode->VSyncStart;
+ var->upper_margin = mode->VTotal-mode->VSyncEnd;
+ var->sync = 0;
+ if (mode->Flags & V_PHSYNC)
+ var->sync |= FB_SYNC_HOR_HIGH_ACT;
+ if (mode->Flags & V_PVSYNC)
+ var->sync |= FB_SYNC_VERT_HIGH_ACT;
+ if (mode->Flags & V_PCSYNC)
+ var->sync |= FB_SYNC_COMP_HIGH_ACT;
+ if (mode->Flags & V_BCAST)
+ var->sync |= FB_SYNC_BROADCAST;
+ if (mode->Flags & V_INTERLACE)
+ var->vmode = FB_VMODE_INTERLACED;
+ else if (mode->Flags & V_DBLSCAN)
+ var->vmode = FB_VMODE_DOUBLE;
+ else
+ var->vmode = FB_VMODE_NONINTERLACED;
+}
+
+static Bool
+fbdev_modes_equal(struct fb_var_screeninfo *set, struct fb_var_screeninfo *req)
+{
+ return (set->xres_virtual >= req->xres_virtual &&
+ set->yres_virtual >= req->yres_virtual &&
+ set->bits_per_pixel == req->bits_per_pixel &&
+ set->red.length == req->red.length &&
+ set->green.length == req->green.length &&
+ set->blue.length == req->blue.length &&
+ set->xres == req->xres && set->yres == req->yres &&
+ set->right_margin == req->right_margin &&
+ set->hsync_len == req->hsync_len &&
+ set->left_margin == req->left_margin &&
+ set->lower_margin == req->lower_margin &&
+ set->vsync_len == req->vsync_len &&
+ set->upper_margin == req->upper_margin &&
+ set->sync == req->sync && set->vmode == req->vmode);
+}
+
+static void
+fbdev2xfree_timing(struct fb_var_screeninfo *var, DisplayModePtr mode)
+{
+ mode->Clock = var->pixclock ? 1000000000/var->pixclock : 0;
+ mode->HDisplay = var->xres;
+ mode->HSyncStart = mode->HDisplay+var->right_margin;
+ mode->HSyncEnd = mode->HSyncStart+var->hsync_len;
+ mode->HTotal = mode->HSyncEnd+var->left_margin;
+ mode->VDisplay = var->yres;
+ mode->VSyncStart = mode->VDisplay+var->lower_margin;
+ mode->VSyncEnd = mode->VSyncStart+var->vsync_len;
+ mode->VTotal = mode->VSyncEnd+var->upper_margin;
+ mode->Flags = 0;
+ mode->Flags |= var->sync & FB_SYNC_HOR_HIGH_ACT ? V_PHSYNC : V_NHSYNC;
+ mode->Flags |= var->sync & FB_SYNC_VERT_HIGH_ACT ? V_PVSYNC : V_NVSYNC;
+ mode->Flags |= var->sync & FB_SYNC_COMP_HIGH_ACT ? V_PCSYNC : V_NCSYNC;
+ if (var->sync & FB_SYNC_BROADCAST)
+ mode->Flags |= V_BCAST;
+ if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)
+ mode->Flags |= V_INTERLACE;
+ else if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
+ mode->Flags |= V_DBLSCAN;
+ mode->SynthClock = mode->Clock;
+ mode->CrtcHDisplay = mode->HDisplay;
+ mode->CrtcHSyncStart = mode->HSyncStart;
+ mode->CrtcHSyncEnd = mode->HSyncEnd;
+ mode->CrtcHTotal = mode->HTotal;
+ mode->CrtcVDisplay = mode->VDisplay;
+ mode->CrtcVSyncStart = mode->VSyncStart;
+ mode->CrtcVSyncEnd = mode->VSyncEnd;
+ mode->CrtcVTotal = mode->VTotal;
+ mode->CrtcHAdjusted = FALSE;
+ mode->CrtcVAdjusted = FALSE;
+}
+
+
+/* -------------------------------------------------------------------- */
+/* open correct framebuffer device */
+
+/**
+ * Try to find the framebuffer device for a given PCI device
+ */
+static int
+fbdev_open_pci(struct pci_device * pPci, char **namep)
+{
+ struct fb_fix_screeninfo fix;
+ char filename[256];
+ int fd,i,j;
+
+
+ /* There are two ways to that we can determine which fb device is
+ * associated with this PCI device. The more modern way is to look in
+ * the sysfs directory for the PCI device for a file named
+ * "graphics/fb*"
+ */
+
+ for (i = 0; i < 8; i++) {
+ sprintf(filename,
+ "/sys/bus/pci/devices/%04x:%02x:%02x.%d/graphics/fb%d",
+ pPci->domain, pPci->bus, pPci->dev, pPci->func, i);
+
+ fd = open(filename, O_RDONLY, 0);
+ if (fd < 0) {
+ sprintf(filename,
+ "/sys/bus/pci/devices/%04x:%02x:%02x.%d/graphics:fb%d",
+ pPci->domain, pPci->bus, pPci->dev, pPci->func, i);
+ fd = open(filename, O_RDONLY, 0);
+ }
+ if (fd >= 0) {
+ close(fd);
+ sprintf(filename, "/dev/fb%d", i);
+
+ fd = open(filename, O_RDWR, 0);
+ if (fd != -1) {
+ if (ioctl(fd, FBIOGET_FSCREENINFO, (void*) & fix) != -1) {
+ if (namep) {
+ *namep = xnfalloc(16);
+ strncpy(*namep,fix.id,16);
+ }
+
+ return fd;
+ }
+ close(fd);
+ }
+ }
+ }
+
+
+ /* The other way is to examine the resources associated with each fb
+ * device and see if there is a match with the PCI device. This technique
+ * has some problems on certain mixed 64-bit / 32-bit architectures.
+ * There is a flaw in the fb_fix_screeninfo structure in that it only
+ * returns the low 32-bits of the address of the resources associated with
+ * a device. However, on a mixed architecture the base addresses of PCI
+ * devices, even for 32-bit applications, may be higher than 0x0f0000000.
+ */
+
+ for (i = 0; i < 8; i++) {
+ sprintf(filename,"/dev/fb%d",i);
+ if (-1 == (fd = open(filename,O_RDWR,0))) {
+ xf86DrvMsg(-1, X_WARNING,
+ "open %s: %s\n", filename, strerror(errno));
+ continue;
+ }
+ if (-1 == ioctl(fd,FBIOGET_FSCREENINFO,(void*)&fix)) {
+ close(fd);
+ continue;
+ }
+ for (j = 0; j < 6; j++) {
+ const pciaddr_t res_start = pPci->regions[j].base_addr;
+ const pciaddr_t res_end = res_start + pPci->regions[j].size;
+
+ if ((0 != fix.smem_len &&
+ (pciaddr_t) fix.smem_start >= res_start &&
+ (pciaddr_t) fix.smem_start < res_end) ||
+ (0 != fix.mmio_len &&
+ (pciaddr_t) fix.mmio_start >= res_start &&
+ (pciaddr_t) fix.mmio_start < res_end))
+ break;
+ }
+ if (j == 6) {
+ close(fd);
+ continue;
+ }
+ if (namep) {
+ *namep = xnfalloc(16);
+ strncpy(*namep,fix.id,16);
+ }
+ return fd;
+ }
+
+ if (namep)
+ *namep = NULL;
+
+ xf86DrvMsg(-1, X_ERROR,
+ "Unable to find a valid framebuffer device\n");
+ return -1;
+}
+
+static int
+fbdev_open(int scrnIndex, char *dev, char** namep)
+{
+ struct fb_fix_screeninfo fix;
+ int fd;
+
+ /* try argument (from XF86Config) first */
+ if (dev) {
+ fd = open(dev,O_RDWR,0);
+ } else {
+ /* second: environment variable */
+ dev = getenv("FRAMEBUFFER");
+ if ((NULL == dev) || ((fd = open(dev,O_RDWR,0)) == -1)) {
+ /* last try: default device */
+ dev = "/dev/fb0";
+ fd = open(dev,O_RDWR,0);
+ }
+ }
+
+ if (fd == -1) {
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "open %s: %s\n", dev, strerror(errno));
+ return -1;
+ }
+
+ if (namep) {
+ if (-1 == ioctl(fd,FBIOGET_FSCREENINFO,(void*)(&fix))) {
+ *namep = NULL;
+ xf86DrvMsg(scrnIndex, X_ERROR,
+ "FBIOGET_FSCREENINFO: %s\n", strerror(errno));
+ return -1;
+ } else {
+ *namep = xnfalloc(16);
+ strncpy(*namep,fix.id,16);
+ }
+ }
+ return fd;
+}
+
+/* -------------------------------------------------------------------- */
+
+Bool
+fbdevHWProbe(struct pci_device * pPci, char *device,char **namep)
+{
+ int fd;
+
+ if (pPci)
+ fd = fbdev_open_pci(pPci,namep);
+ else
+ fd = fbdev_open(-1,device,namep);
+
+ if (-1 == fd)
+ return FALSE;
+ close(fd);
+ return TRUE;
+}
+
+Bool
+fbdevHWInit(ScrnInfoPtr pScrn, struct pci_device * pPci, char *device)
+{
+ fbdevHWPtr fPtr;
+
+ TRACE_ENTER("Init");
+
+ fbdevHWGetRec(pScrn);
+ fPtr = FBDEVHWPTR(pScrn);
+
+ /* open device */
+ if (pPci)
+ fPtr->fd = fbdev_open_pci(pPci,NULL);
+ else
+ fPtr->fd = fbdev_open(pScrn->scrnIndex,device,NULL);
+ if (-1 == fPtr->fd) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to open framebuffer device, consult warnings"
+ " and/or errors above for possible reasons\n"
+ "\t(you may have to look at the server log to see"
+ " warnings)\n");
+ return FALSE;
+ }
+
+ /* get current fb device settings */
+ if (-1 == ioctl(fPtr->fd,FBIOGET_FSCREENINFO,(void*)(&fPtr->fix))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "ioctl FBIOGET_FSCREENINFO: %s\n",
+ strerror(errno));
+ return FALSE;
+ }
+ if (-1 == ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->var))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "ioctl FBIOGET_VSCREENINFO: %s\n",
+ strerror(errno));
+ return FALSE;
+ }
+
+ /* we can use the current settings as "buildin mode" */
+ fbdev2xfree_timing(&fPtr->var, &fPtr->buildin);
+ fPtr->buildin.name = "current";
+ fPtr->buildin.next = &fPtr->buildin;
+ fPtr->buildin.prev = &fPtr->buildin;
+ fPtr->buildin.type |= M_T_BUILTIN;
+
+ return TRUE;
+}
+
+char*
+fbdevHWGetName(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+ return fPtr->fix.id;
+}
+
+int
+fbdevHWGetDepth(ScrnInfoPtr pScrn, int *fbbpp)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ if (fbbpp)
+ *fbbpp = fPtr->var.bits_per_pixel;
+
+ if (fPtr->fix.visual == FB_VISUAL_TRUECOLOR ||
+ fPtr->fix.visual == FB_VISUAL_DIRECTCOLOR)
+ return fPtr->var.red.length+fPtr->var.green.length+
+ fPtr->var.blue.length;
+ else
+ return fPtr->var.bits_per_pixel;
+}
+
+int
+fbdevHWGetLineLength(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ if (fPtr->fix.line_length)
+ return fPtr->fix.line_length;
+ else
+ return fPtr->var.xres_virtual*fPtr->var.bits_per_pixel/8;
+}
+
+int
+fbdevHWGetType(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+ return fPtr->fix.type;
+}
+
+int
+fbdevHWGetVidmem(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+ return fPtr->fix.smem_len;
+}
+
+static Bool
+fbdevHWSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode, Bool check)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+ struct fb_var_screeninfo req_var = fPtr->var, set_var;
+
+ TRACE_ENTER("SetMode");
+
+ xfree2fbdev_fblayout(pScrn, &req_var);
+ xfree2fbdev_timing(mode, &req_var);
+
+#if DEBUG
+ print_xfree_mode("init", mode);
+ print_fbdev_mode("init", &req_var);
+#endif
+
+ set_var = req_var;
+
+ if (check)
+ set_var.activate = FB_ACTIVATE_TEST;
+
+ if (0 != ioctl(fPtr->fd, FBIOPUT_VSCREENINFO, (void*)(&set_var))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "FBIOPUT_VSCREENINFO: %s\n", strerror(errno));
+ return FALSE;
+ }
+
+ if (!fbdev_modes_equal(&set_var, &req_var)) {
+ if (!check)
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "FBIOPUT_VSCREENINFO succeeded but modified "
+ "mode\n");
+#if DEBUG
+ print_fbdev_mode("returned", &set_var);
+#endif
+ return FALSE;
+ }
+
+ if (!check)
+ fPtr->var = set_var;
+
+ return TRUE;
+}
+
+void
+fbdevHWSetVideoModes(ScrnInfoPtr pScrn)
+{
+ char **modename;
+ DisplayModePtr mode,this,last = pScrn->modes;
+
+ TRACE_ENTER("VerifyModes");
+ if (NULL == pScrn->display->modes)
+ return;
+
+ pScrn->virtualX = pScrn->display->virtualX;
+ pScrn->virtualY = pScrn->display->virtualY;
+
+ for (modename = pScrn->display->modes; *modename != NULL; modename++) {
+ for (mode = pScrn->monitor->Modes; mode != NULL; mode = mode->next)
+ if (0 == strcmp(mode->name,*modename))
+ break;
+ if (NULL == mode) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "\tmode \"%s\" not found\n", *modename);
+ continue;
+ }
+
+ if (!fbdevHWSetMode(pScrn, mode, TRUE)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "\tmode \"%s\" test failed\n", *modename);
+ continue;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "\tmode \"%s\" ok\n", *modename);
+
+ if (pScrn->virtualX < mode->HDisplay)
+ pScrn->virtualX = mode->HDisplay;
+ if (pScrn->virtualY < mode->VDisplay)
+ pScrn->virtualY = mode->VDisplay;
+
+ if (NULL == pScrn->modes) {
+ this = pScrn->modes = xf86DuplicateMode(mode);
+ this->next = this;
+ this->prev = this;
+ } else {
+ this = xf86DuplicateMode(mode);
+ this->next = pScrn->modes;
+ this->prev = last;
+ last->next = this;
+ pScrn->modes->prev = this;
+ }
+ last = this;
+ }
+}
+
+DisplayModePtr
+fbdevHWGetBuildinMode(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+ return &fPtr->buildin;
+}
+
+void
+fbdevHWUseBuildinMode(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ TRACE_ENTER("UseBuildinMode");
+ pScrn->modes = &fPtr->buildin;
+ pScrn->virtualX = pScrn->display->virtualX;
+ pScrn->virtualY = pScrn->display->virtualY;
+ if (pScrn->virtualX < fPtr->buildin.HDisplay)
+ pScrn->virtualX = fPtr->buildin.HDisplay;
+ if (pScrn->virtualY < fPtr->buildin.VDisplay)
+ pScrn->virtualY = fPtr->buildin.VDisplay;
+}
+
+/* -------------------------------------------------------------------- */
+
+static void
+calculateFbmem_len(fbdevHWPtr fPtr)
+{
+ fPtr->fboff = (unsigned long) fPtr->fix.smem_start & ~PAGE_MASK;
+ fPtr->fbmem_len = (fPtr->fboff+fPtr->fix.smem_len+~PAGE_MASK) &
+ PAGE_MASK;
+}
+
+
+void*
+fbdevHWMapVidmem(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ TRACE_ENTER("MapVidmem");
+ if (NULL == fPtr->fbmem) {
+ calculateFbmem_len(fPtr);
+ fPtr->fbmem = mmap(NULL, fPtr->fbmem_len, PROT_READ | PROT_WRITE,
+ MAP_SHARED, fPtr->fd, 0);
+ if (-1 == (long)fPtr->fbmem) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "mmap fbmem: %s\n", strerror(errno));
+ fPtr->fbmem = NULL;
+ } else {
+ /* Perhaps we'd better add fboff to fbmem and return 0 in
+ fbdevHWLinearOffset()? Of course we then need to mask
+ fPtr->fbmem with PAGE_MASK in fbdevHWUnmapVidmem() as
+ well. [geert] */
+ }
+ }
+ pScrn->memPhysBase = (unsigned long)fPtr->fix.smem_start & (unsigned long)(PAGE_MASK);
+ pScrn->fbOffset = (unsigned long)fPtr->fix.smem_start & (unsigned long)(~PAGE_MASK);
+ return fPtr->fbmem;
+}
+
+int
+fbdevHWLinearOffset(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ TRACE_ENTER("LinearOffset");
+ return fPtr->fboff;
+}
+
+Bool
+fbdevHWUnmapVidmem(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ TRACE_ENTER("UnmapVidmem");
+ if (NULL != fPtr->fbmem) {
+ if (-1 == munmap(fPtr->fbmem, fPtr->fbmem_len))
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "munmap fbmem: %s\n", strerror(errno));
+ fPtr->fbmem = NULL;
+ }
+ return TRUE;
+}
+
+void*
+fbdevHWMapMMIO(ScrnInfoPtr pScrn)
+{
+ unsigned int mmio_off;
+
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ TRACE_ENTER("MapMMIO");
+ if (NULL == fPtr->mmio) {
+ /* tell the kernel not to use accels to speed up console scrolling */
+ fPtr->var.accel_flags = 0;
+ if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->var))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "FBIOPUT_VSCREENINFO: %s\n", strerror(errno));
+ return FALSE;
+ }
+ mmio_off = (unsigned long) fPtr->fix.mmio_start & ~PAGE_MASK;
+ fPtr->mmio_len = (mmio_off+fPtr->fix.mmio_len+~PAGE_MASK) &
+ PAGE_MASK;
+ if (NULL == fPtr->fbmem)
+ calculateFbmem_len(fPtr);
+ fPtr->mmio = mmap(NULL, fPtr->mmio_len, PROT_READ | PROT_WRITE,
+ MAP_SHARED, fPtr->fd, fPtr->fbmem_len);
+ if (-1 == (long)fPtr->mmio) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "mmap mmio: %s\n", strerror(errno));
+ fPtr->mmio = NULL;
+ } else
+ fPtr->mmio += mmio_off;
+ }
+ return fPtr->mmio;
+}
+
+Bool
+fbdevHWUnmapMMIO(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ TRACE_ENTER("UnmapMMIO");
+ if (NULL != fPtr->mmio) {
+ if (-1 == munmap((void *)((unsigned long)fPtr->mmio & PAGE_MASK), fPtr->mmio_len))
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "munmap mmio: %s\n", strerror(errno));
+ fPtr->mmio = NULL;
+ /* FIXME: restore var.accel_flags [geert] */
+ }
+ return TRUE;
+}
+
+/* -------------------------------------------------------------------- */
+
+Bool
+fbdevHWModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ pScrn->vtSema = TRUE;
+
+ /* set */
+ if (!fbdevHWSetMode(pScrn, mode, FALSE))
+ return FALSE;
+
+ /* read back */
+ if (0 != ioctl(fPtr->fd,FBIOGET_FSCREENINFO,(void*)(&fPtr->fix))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "FBIOGET_FSCREENINFO: %s\n", strerror(errno));
+ return FALSE;
+ }
+ if (0 != ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->var))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "FBIOGET_VSCREENINFO: %s\n", strerror(errno));
+ return FALSE;
+ }
+
+ if (pScrn->defaultVisual == TrueColor ||
+ pScrn->defaultVisual == DirectColor) {
+ /* XXX: This is a hack, but it should be a NOP for all the setups that
+ * worked before and actually seems to fix some others...
+ */
+ pScrn->offset.red = fPtr->var.red.offset;
+ pScrn->offset.green = fPtr->var.green.offset;
+ pScrn->offset.blue = fPtr->var.blue.offset;
+ pScrn->mask.red = ((1 << fPtr->var.red.length) - 1) << fPtr->var.red.offset;
+ pScrn->mask.green = ((1 << fPtr->var.green.length) - 1) << fPtr->var.green.offset;
+ pScrn->mask.blue = ((1 << fPtr->var.blue.length) - 1) << fPtr->var.blue.offset;
+ }
+
+ return TRUE;
+}
+
+/* -------------------------------------------------------------------- */
+/* video mode save/restore */
+
+/* TODO: colormap */
+void
+fbdevHWSave(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ TRACE_ENTER("Save");
+ if (0 != ioctl(fPtr->fd,FBIOGET_VSCREENINFO,(void*)(&fPtr->saved_var)))
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "FBIOGET_VSCREENINFO: %s\n", strerror(errno));
+}
+
+void
+fbdevHWRestore(ScrnInfoPtr pScrn)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ TRACE_ENTER("Restore");
+ if (0 != ioctl(fPtr->fd,FBIOPUT_VSCREENINFO,(void*)(&fPtr->saved_var)))
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "FBIOPUT_VSCREENINFO: %s\n", strerror(errno));
+}
+
+/* -------------------------------------------------------------------- */
+/* callback for xf86HandleColormaps */
+
+void
+fbdevHWLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
+ LOCO *colors, VisualPtr pVisual)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+ struct fb_cmap cmap;
+ unsigned short red,green,blue;
+ int i;
+
+ TRACE_ENTER("LoadPalette");
+ cmap.len = 1;
+ cmap.red = &red;
+ cmap.green = &green;
+ cmap.blue = &blue;
+ cmap.transp = NULL;
+ for (i = 0; i < numColors; i++) {
+ cmap.start = indices[i];
+ red = (colors[indices[i]].red << 8) |
+ colors[indices[i]].red;
+ green = (colors[indices[i]].green << 8) |
+ colors[indices[i]].green;
+ blue = (colors[indices[i]].blue << 8) |
+ colors[indices[i]].blue;
+ if (-1 == ioctl(fPtr->fd,FBIOPUTCMAP,(void*)&cmap))
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "FBIOPUTCMAP: %s\n", strerror(errno));
+ }
+}
+
+/* -------------------------------------------------------------------- */
+/* these can be hooked directly into ScrnInfoRec */
+
+ModeStatus
+fbdevHWValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+
+ TRACE_ENTER("ValidMode");
+
+ if (!fbdevHWSetMode(pScrn, mode, TRUE))
+ return MODE_BAD;
+
+ return MODE_OK;
+}
+
+Bool
+fbdevHWSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+
+ TRACE_ENTER("SwitchMode");
+
+ if (!fbdevHWSetMode(pScrn, mode, FALSE))
+ return FALSE;
+
+ return TRUE;
+}
+
+void
+fbdevHWAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+
+ TRACE_ENTER("AdjustFrame");
+ if ( x < 0 || x + fPtr->var.xres > fPtr->var.xres_virtual ||
+ y < 0 || y + fPtr->var.yres > fPtr->var.yres_virtual )
+ return;
+
+ fPtr->var.xoffset = x;
+ fPtr->var.yoffset = y;
+ if (-1 == ioctl(fPtr->fd,FBIOPAN_DISPLAY,(void*)&fPtr->var))
+ xf86DrvMsgVerb(scrnIndex, X_WARNING, 5,
+ "FBIOPAN_DISPLAY: %s\n", strerror(errno));
+}
+
+Bool
+fbdevHWEnterVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+
+ TRACE_ENTER("EnterVT");
+ if (!fbdevHWModeInit(pScrn, pScrn->currentMode))
+ return FALSE;
+ fbdevHWAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+ return TRUE;
+}
+
+void
+fbdevHWLeaveVT(int scrnIndex, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+
+ TRACE_ENTER("LeaveVT");
+ fbdevHWRestore(pScrn);
+}
+
+void
+fbdevHWDPMSSet(ScrnInfoPtr pScrn, int mode, int flags)
+{
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+ unsigned long fbmode;
+
+ TRACE_ENTER("DPMSSet");
+ if (!pScrn->vtSema)
+ return;
+
+ switch (mode) {
+ case DPMSModeOn:
+ fbmode = 0;
+ break;
+ case DPMSModeStandby:
+ fbmode = 2;
+ break;
+ case DPMSModeSuspend:
+ fbmode = 3;
+ break;
+ case DPMSModeOff:
+ fbmode = 4;
+ break;
+ default:
+ return;
+ }
+
+ if (-1 == ioctl(fPtr->fd, FBIOBLANK, (void *)fbmode))
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "FBIOBLANK: %s\n", strerror(errno));
+}
+
+Bool
+fbdevHWSaveScreen(ScreenPtr pScreen, int mode)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ fbdevHWPtr fPtr = FBDEVHWPTR(pScrn);
+ unsigned long unblank;
+
+ TRACE_ENTER("HWSaveScreen");
+ if (!pScrn->vtSema)
+ return TRUE;
+
+ unblank = xf86IsUnblank(mode);
+
+ if (-1 == ioctl(fPtr->fd, FBIOBLANK, (void *)(1-unblank))) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "FBIOBLANK: %s\n", strerror(errno));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+xf86SwitchModeProc *
+fbdevHWSwitchModeWeak(void) { return fbdevHWSwitchMode; }
+
+xf86AdjustFrameProc *
+fbdevHWAdjustFrameWeak(void) { return fbdevHWAdjustFrame; }
+
+xf86EnterVTProc *
+fbdevHWEnterVTWeak(void) { return fbdevHWEnterVT; }
+
+xf86LeaveVTProc *
+fbdevHWLeaveVTWeak(void) { return fbdevHWLeaveVT; }
+
+xf86ValidModeProc *
+fbdevHWValidModeWeak(void) { return fbdevHWValidMode; }
+
+xf86DPMSSetProc *
+fbdevHWDPMSSetWeak(void) { return fbdevHWDPMSSet; }
+
+xf86LoadPaletteProc *
+fbdevHWLoadPaletteWeak(void) { return fbdevHWLoadPalette; }
+
+SaveScreenProcPtr
+fbdevHWSaveScreenWeak(void) { return fbdevHWSaveScreen; }
diff --git a/xorg-server/hw/xfree86/i2c/bt829.c b/xorg-server/hw/xfree86/i2c/bt829.c
index 3963ecf47..64c711681 100644
--- a/xorg-server/hw/xfree86/i2c/bt829.c
+++ b/xorg-server/hw/xfree86/i2c/bt829.c
@@ -1,745 +1,745 @@
-/* TODO: clean up/fix CC code */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "xf86.h"
-#include "xf86i2c.h"
-#include "bt829.h"
-#include "i2c_def.h"
-
-/* Changing the following settings (especially VCROP) may */
-/* require modifying code that calls this driver. */
-#define HCROP 0 /* amount to crop from the left and right edges */
-#define VCROP 0 /* amount to crop from the top and bottom edges */
-
-#define BTVERSION (bt->id>>4)
-
-#define H(X) ( ((X)>>8) & 0xFF )
-#define L(X) ( (X) & 0xFF )
-
-#define LIMIT(X,A,B) (((X)<(A)) ? (A) : ((X)>(B)) ? (B) : (X) )
-
-/* Bt829 family chip ID's */
-#define BT815 0x02
-#define BT817 0x06
-#define BT819 0x07
-#define BT827 0x0C
-#define BT829 0x0E
-
-/* Bt829 registers */
-#define STATUS 0x00 /* Device Status */
-#define IFORM 0x01 /* Input Format */
-#define TDEC 0x02 /* Temporal Decimation */
-#define CROP 0x03 /* MSB Cropping */
-#define VDELAY_LO 0x04 /* Vertical Delay */
-#define VACTIVE_LO 0x05 /* Vertical Active */
-#define HDELAY_LO 0x06 /* Horizontal Delay */
-#define HACTIVE_LO 0x07 /* Horizontal Active */
-#define HSCALE_HI 0x08 /* Horizontal Scaling */
-#define HSCALE_LO 0x09 /* Horizontal Scaling */
-#define BRIGHT 0x0A /* Brightness Control */
-#define CONTROL 0x0B /* Miscellaneous Control */
-#define CONTRAST_LO 0x0C /* Luma Gain (Contrast) */
-#define SAT_U_LO 0x0D /* Chroma (U) Gain (Saturation) */
-#define SAT_V_LO 0x0E /* Chroma (V) Gain (Saturation) */
-#define HUE 0x0F /* Hue Control */
-#define SCLOOP 0x10 /* SC Loop Control */
-#define WC_UP 0x11 /* White Crush Up Count */
-#define OFORM 0x12 /* Output Format */
-#define VSCALE_HI 0x13 /* Vertical Scaling */
-#define VSCALE_LO 0x14 /* Vertical Scaling */
-#define TEST 0x15 /* Test Control */
-#define VPOLE 0x16 /* Video Timing Polarity */
-#define IDCODE 0x17 /* ID Code */
-#define ADELAY 0x18 /* AGC Delay */
-#define BDELAY 0x19 /* Burst Gate Delay */
-#define ADC 0x1A /* ADC Interface */
-#define VTC 0x1B /* Video Timing Control */
-#define CC_STATUS 0x1C /* Extended Data Services/Closed Capt Status */
-#define CC_DATA 0x1D /* Extended Data Services/Closed Capt Data */
-#define WC_DN 0x1E /* White Crush Down Count */
-#define SRESET 0x1F /* Software Reset */
-#define P_IO 0x3F /* Programmable I/O */
-
-static CARD8 btread(BT829Ptr bt, CARD8 reg)
-{
- CARD8 v;
-
- I2C_WriteRead(&(bt->d), &reg, 1, &v, 1);
-
- return v;
-}
-
-static void btwrite(BT829Ptr bt, CARD8 reg, CARD8 val)
-{
- CARD8 data[2];
-
- data[0] = reg;
- data[1] = val;
- I2C_WriteRead(&(bt->d), data, 2, NULL, 0);
-}
-
-/*
- * Register access
- */
-static void btwrite_status(BT829Ptr bt) /* STATUS */
-{
- btwrite(bt, STATUS, 0x00); /* clear */
-}
-
-static void btwrite_iform(BT829Ptr bt) /* IFORM */
-{
- int xtsel;
-
- switch (bt->format) {
- case BT829_NTSC:
- case BT829_NTSC_JAPAN:
- case BT829_PAL_M:
- case BT829_PAL_N_COMB: /* gatos says xtsel = 2 */
- xtsel = 1;
- break;
- case BT829_PAL:
- case BT829_PAL_N:
- case BT829_SECAM:
- xtsel = 2;
- break;
- default: /* shouldn't get here */
- xtsel = 3; /* hardware default */
- break;
- }
-
- btwrite(bt, IFORM, (bt->mux<<5) | (xtsel<<3) | bt->format);
-}
-
-static void btwrite_tdec(BT829Ptr bt) /* TDEC */
-{
- /* use default */
-}
-
-static void btwrite_crop(BT829Ptr bt) /* CROP */
-{
- btwrite(bt, CROP, (H(bt->vdelay)<<6) | (H(bt->vactive)<<4) |
- (H(bt->hdelay)<<2) | H(bt->width));
-}
-
-static void btwrite_vdelay_lo(BT829Ptr bt) /* VDELAY_LO */
-{
- btwrite(bt, VDELAY_LO, L(bt->vdelay));
-}
-
-static void btwrite_vactive_lo(BT829Ptr bt) /* VACTIVE_LO */
-{
- btwrite(bt, VACTIVE_LO, L(bt->vactive));
-}
-
-static void btwrite_hdelay_lo(BT829Ptr bt) /* HDELAY_LO */
-{
- btwrite(bt, HDELAY_LO, L(bt->hdelay));
-}
-
-static void btwrite_hactive_lo(BT829Ptr bt) /* HACTIVE_LO */
-{
- btwrite(bt, HACTIVE_LO, L(bt->width));
-}
-
-static void btwrite_hscale_hi(BT829Ptr bt) /* HSCALE_HI */
-{
- btwrite(bt, HSCALE_HI, H(bt->hscale));
-}
-
-static void btwrite_hscale_lo(BT829Ptr bt) /* HSCALE_LO */
-{
- btwrite(bt, HSCALE_LO, L(bt->hscale));
-}
-
-static void btwrite_bright(BT829Ptr bt) /* BRIGHT */
-{
- btwrite(bt, BRIGHT, bt->brightness);
-}
-
-static void btwrite_control(BT829Ptr bt) /* CONTROL */
-{
- int ldec;
-
- /* The data sheet says ldec should always be 0 for SECAM */
- /* but the picture quality is better with ldec = 1 */
- ldec = (bt->width > 360); /* gatos says 384 */
-
- btwrite(bt, CONTROL,
- ((bt->mux==bt->svideo_mux) ? 0xC0:0x00) | /* LNOTCH and COMP */
- (ldec<<5) | (H(bt->contrast)<<2) | (H(bt->sat_u)<<1) | H(bt->sat_v));
-}
-
-static void btwrite_contrast_lo(BT829Ptr bt) /* CONTRAST_LO */
-{
- btwrite(bt, CONTRAST_LO, L(bt->contrast));
-}
-
-static void btwrite_sat_u_lo(BT829Ptr bt) /* SAT_U_LO */
-{
- btwrite(bt, SAT_U_LO, L(bt->sat_u));
-}
-
-static void btwrite_sat_v_lo(BT829Ptr bt) /* SAT_V_LO */
-{
- btwrite(bt, SAT_V_LO, L(bt->sat_v));
-}
-
-static void btwrite_hue(BT829Ptr bt) /* HUE */
-{
- btwrite(bt, HUE, bt->hue);
-}
-
-static void btwrite_scloop(BT829Ptr bt) /* SCLOOP */
-{
- if (BTVERSION >= BT827) {
- btwrite(bt, SCLOOP,
- (bt->format==BT829_SECAM) ? 0x10:0x00 /* QCIF or AUTO */
- );
- }
-}
-
-static void btwrite_wc_up(BT829Ptr bt) /* WC_UP */
-{
- if (BTVERSION >= BT827) {
- /* use default */
- }
-}
-
-static void btwrite_oform(BT829Ptr bt) /* OFORM */
-{
- btwrite(bt, OFORM, (bt->code<<3) | (bt->len<<2) |
- 0x02 /* RANGE = 0, CORE = 0, VBI_FRAME = 0, OES = 2 (default) */
- );
-}
-
-static void btwrite_vscale_hi(BT829Ptr bt) /* VSCALE_HI */
-{
- btwrite(bt, VSCALE_HI, H(bt->vscale) |
- 0x60 /* YCOMB = 0, COMB = 1, INT = 1 (default) */
- );
-}
-
-static void btwrite_vscale_lo(BT829Ptr bt) /* VSCALE_LO */
-{
- btwrite(bt, VSCALE_LO, L(bt->vscale));
-}
-
-/* TEST should not be written to */
-
-static void btwrite_vpole(BT829Ptr bt) /* VPOLE */
-{
- btwrite(bt, VPOLE, (bt->out_en<<7));
-}
-
-/* IDCODE is read only */
-
-static void btwrite_adelay(BT829Ptr bt) /* ADELAY */
-{
- switch (bt->format) {
- case BT829_NTSC:
- case BT829_NTSC_JAPAN:
- case BT829_PAL_M:
- btwrite(bt, ADELAY, 104);
- break;
- case BT829_PAL:
- case BT829_PAL_N:
- case BT829_SECAM:
- case BT829_PAL_N_COMB:
- btwrite(bt, ADELAY, 127);
- break;
- default: /* shouldn't get here */
- btwrite(bt, ADELAY, 104); /* hardware default */
- break;
- }
-}
-
-static void btwrite_bdelay(BT829Ptr bt) /* BDELAY */
-{
- switch (bt->format) {
- case BT829_NTSC:
- case BT829_NTSC_JAPAN:
- case BT829_PAL_M:
- btwrite(bt, BDELAY, 93);
- break;
- case BT829_PAL:
- case BT829_PAL_N:
- case BT829_PAL_N_COMB:
- btwrite(bt, BDELAY, 114);
- break;
- case BT829_SECAM:
- btwrite(bt, BDELAY, 160);
- break;
- default: /* shouldn't get here */
- btwrite(bt, BDELAY, 93); /* hardware default */
- break;
- }
-}
-
-static void btwrite_adc(BT829Ptr bt) /* ADC */
-{
- btwrite(bt, ADC, bt->mux==bt->svideo_mux ? 0x80:0x82); /* CSLEEP = 0 or 1 */
-}
-
-static void btwrite_vtc(BT829Ptr bt) /* VTC */
-{
- int vfilt = 0; /* hardware default */
-
- if (BTVERSION > BT827) { /* gatos says >= BT827 */
- switch (bt->format) {
- case BT829_NTSC:
- case BT829_NTSC_JAPAN:
- case BT829_PAL_M:
- case BT829_PAL_N_COMB: /* gatos groups with BT829_PAL */
- if (bt->width <= 360) vfilt = 1; /* gatos says <= 240 */
- if (bt->width <= 180) vfilt = 2; /* gatos says <= 120 */
- if (bt->width <= 90) vfilt = 3; /* gatos says <= 60 */
- break;
- case BT829_PAL:
- case BT829_PAL_N:
- case BT829_SECAM:
- if (bt->width <= 384) vfilt = 1;
- if (bt->width <= 192) vfilt = 2;
- if (bt->width<= 96) vfilt = 3;
- break;
- default: /* shouldn't get here */
- break; /* use hardware default */
- }
- btwrite(bt, VTC, (bt->vbien<<4) | (bt->vbifmt<<3) | vfilt);
- }
-}
-
-static void btwrite_cc_status(BT829Ptr bt) /* CC_STATUS */
-{ /* FIXME: ATI specific */
- if (BTVERSION >= BT827) {
- if (bt->ccmode == 0) btwrite(bt, CC_STATUS, 0x00);
- /* 0x40 is activate to set the CCVALID line. Not required yet */
- else btwrite(bt, CC_STATUS, (bt->ccmode<<4) | 0x40);
- }
-}
-
-/* CC_DATA is read only */
-
-static void btwrite_wc_dn(BT829Ptr bt) /* WC_DN */
-{
- if (BTVERSION >= BT827) {
- /* use default */
- }
-}
-
-static void bt_reset(BT829Ptr bt) { /* SRESET */
- btwrite(bt, SRESET, 0x0); /* Reset all registers */
-}
-
-static void btwrite_p_io(BT829Ptr bt) /* P_IO */
-{
- if (BTVERSION >= BT827) {
- btwrite(bt, P_IO, bt->p_io);
- }
-}
-
-/*
- * Deal with dependencies
- */
-static void propagate_changes(BT829Ptr bt)
-{
- CARD16 hdelay, unscaled_hdelay, vdelay, hscale, vscale;
- int htotal, vactive;
-
- switch (bt->format) {
- case BT829_NTSC:
- case BT829_NTSC_JAPAN:
- case BT829_PAL_M:
- vdelay = 22;
- htotal = 754;
- vactive = 480;
- unscaled_hdelay = 135;
- break;
- case BT829_PAL:
- case BT829_PAL_N:
- vdelay = (bt->tunertype==5) ? 34 : 22;
- htotal = 922;
- vactive = 576;
- unscaled_hdelay = 186;
- break;
- case BT829_SECAM:
- vdelay = 34;
- htotal = 922;
- vactive = 576;
- unscaled_hdelay = 186;
- break;
- case BT829_PAL_N_COMB:
- vdelay = (bt->tunertype==5) ? 34 : 22; /* windows says 22 */
- htotal = 754; /* gatos and windows say 922 */
- vactive = 576;
- unscaled_hdelay = 135; /* gatos and windows say 186 */
- break;
- default: /* shouldn't get here */
- vdelay = 22; /* hardware default */
- htotal = 754;
- vactive = 480; /* hardware default */
- unscaled_hdelay = 135;
- break;
- }
-
- bt->htotal = htotal; /* Used for error checking in bt829_SetCaptSize */
-
- hscale = 4096 * htotal / (bt->width + 2 * HCROP)-4096;
- hdelay = (
- HCROP + (bt->width + 2 * HCROP) * unscaled_hdelay / htotal
- ) & 0x3FE;
-
- vactive = vactive - 2 * VCROP;
- vdelay = vdelay + VCROP;
- vscale = (0x10000 - (512*vactive/bt->height-512)) & 0x1FFF;
-
- if ((hdelay != bt->hdelay) || (vdelay != bt->vdelay) ||
- (vactive != bt->vactive) || (hscale != bt->hscale) ||
- (vscale != bt->vscale)) {
- bt->hdelay = hdelay;
- bt->vdelay = vdelay;
- bt->vactive = vactive;
- bt->hscale = hscale;
- bt->vscale = vscale;
- btwrite_crop(bt);
- btwrite_vdelay_lo(bt);
- btwrite_vactive_lo(bt);
- btwrite_hdelay_lo(bt);
- btwrite_hscale_hi(bt);
- btwrite_hscale_lo(bt);
- btwrite_control(bt);
- btwrite_vscale_hi(bt);
- btwrite_vscale_lo(bt);
- }
-}
-
-static void write_all(BT829Ptr bt)
-{
- bt_reset(bt);
- propagate_changes(bt); /* ensure consistency */
- btwrite_iform(bt);
- btwrite_tdec(bt);
- btwrite_crop(bt);
- btwrite_vdelay_lo(bt);
- btwrite_vactive_lo(bt);
- btwrite_hdelay_lo(bt);
- btwrite_hactive_lo(bt);
- btwrite_hscale_hi(bt);
- btwrite_hscale_lo(bt);
- btwrite_bright(bt);
- btwrite_control(bt);
- btwrite_contrast_lo(bt);
- btwrite_sat_u_lo(bt);
- btwrite_sat_v_lo(bt);
- btwrite_hue(bt);
- btwrite_scloop(bt);
- btwrite_wc_up(bt);
- btwrite_oform(bt);
- btwrite_vscale_hi(bt);
- btwrite_vscale_lo(bt);
- btwrite_vpole(bt);
- btwrite_adelay(bt);
- btwrite_bdelay(bt);
- btwrite_adc(bt);
- btwrite_vtc(bt);
-/* btwrite_cc_status(bt); */ /* FIXME: CC code needs cleaning */
- btwrite_wc_dn(bt);
- btwrite_p_io(bt);
-}
-
-/*
- * Public functions
- */
-BT829Ptr bt829_Detect(I2CBusPtr b, I2CSlaveAddr addr)
-{
- BT829Ptr bt;
- I2CByte a;
-
- bt = xcalloc(1, sizeof(BT829Rec));
- if(bt == NULL) return NULL;
- bt->d.DevName = strdup("BT829 video decoder");
- bt->d.SlaveAddr = addr;
- bt->d.pI2CBus = b;
- bt->d.NextDev = NULL;
- bt->d.StartTimeout = b->StartTimeout;
- bt->d.BitTimeout = b->BitTimeout;
- bt->d.AcknTimeout = b->AcknTimeout;
- bt->d.ByteTimeout = b->ByteTimeout;
-
-
- if(!I2C_WriteRead(&(bt->d), NULL, 0, &a, 1))
- {
- free(bt);
- return NULL;
- }
-
- bt->id = btread(bt,IDCODE);
-
- free(bt->d.DevName);
- bt->d.DevName = xcalloc(200, sizeof(char));
- switch(BTVERSION){
- case BT815:
- sprintf(bt->d.DevName, "bt815a video decoder, revision %d",bt->id & 0xf);
- break;
- case BT817:
- sprintf(bt->d.DevName, "bt817a video decoder, revision %d",bt->id & 0xf);
- break;
- case BT819:
- sprintf(bt->d.DevName, "bt819a video decoder, revision %d",bt->id & 0xf);
- break;
- case BT827:
- sprintf(bt->d.DevName, "bt827a/b video decoder, revision %d",bt->id & 0xf);
- break;
- case BT829:
- sprintf(bt->d.DevName, "bt829a/b video decoder, revision %d",bt->id & 0xf);
- break;
- default:
- sprintf(bt->d.DevName, "bt8xx/unknown video decoder version %d, revision %d",bt->id >> 4,bt->id & 0xf);
- break;
- }
-
- /* set default parameters */
- if(!I2CDevInit(&(bt->d)))
- {
- free(bt);
- return NULL;
- }
-
- bt->tunertype = 1;
-
- bt->brightness = 0; /* hardware default */
- bt->ccmode = 0;
- bt->code = 0; /* hardware default */
- bt->contrast = 216; /* hardware default */
- bt->format = BT829_NTSC;
- bt->height = 480; /* hardware default for vactive */
- bt->hue = 0; /* hardware default */
- bt->len = 1; /* hardware default */
- bt->mux = BT829_MUX0; /* hardware default */
- bt->out_en = 0; /* hardware default */
- bt->p_io = 0; /* hardware default */
- bt->sat_u = 254; /* hardware default */
- bt->sat_v = 180; /* hardware default */
- bt->vbien = 0; /* hardware default */
- bt->vbifmt = 0; /* hardware default */
- bt->width = 640; /* hardware default for hactive */
-
- bt->hdelay = 120; /* hardware default */
- bt->hscale = 684; /* hardware default */
- bt->vactive = 480; /* hardware default */
- bt->vdelay = 22; /* hardware default */
- bt->vscale = 0; /* hardware default */
-
- bt->htotal = 754; /* NTSC */
- bt->svideo_mux = 0; /* no s-video */
-
- return bt;
-}
-
-int bt829_ATIInit(BT829Ptr bt)
-{
- bt->code = 1;
- bt->len = 0;
- bt->vbien = 1;
- bt->vbifmt = 1;
- bt->svideo_mux = BT829_MUX1;
-
- write_all (bt);
-
- return 0;
-}
-
-int bt829_SetFormat(BT829Ptr bt, CARD8 format)
-{
- if ((format < 1) || (format > 7)) return -1;
- if ((BTVERSION <= BT819) &&
- (format != BT829_NTSC) && (format != BT829_PAL)) return -1;
- if (format == bt->format) return 0;
- bt->format = format;
- propagate_changes(bt);
- btwrite_iform(bt);
- btwrite_scloop(bt);
- btwrite_adelay(bt);
- btwrite_bdelay(bt);
- btwrite_vtc(bt);
- return 0;
-}
-
-int bt829_SetMux(BT829Ptr bt, CARD8 mux)
-{
- if ((mux < 1) || (mux > 3)) return -1;
- if (mux == bt->mux) return 0;
- bt->mux = mux;
- /* propagate_changes(bt); */ /* no dependencies */
- btwrite_iform(bt);
- btwrite_control(bt);
- btwrite_adc(bt);
- return 0;
-}
-
-void bt829_SetBrightness(BT829Ptr bt, int brightness)
-{
- brightness = LIMIT(brightness,-1000,999); /* ensure -128 <= brightness <= 127 below */
- brightness = (128*brightness)/1000;
- if (brightness == bt->brightness) return;
- bt->brightness = brightness;
- /* propagate_changes(bt); */ /* no dependencies */
- btwrite_bright(bt);
-}
-
-void bt829_SetContrast(BT829Ptr bt, int contrast)
-{
- contrast = LIMIT(contrast,-1000,1000);
- contrast = (216*(contrast+1000))/1000;
- if (contrast == bt->contrast) return;
- bt->contrast = contrast;
- /* propagate_changes(bt); */ /* no dependencies */
- btwrite_control(bt);
- btwrite_contrast_lo(bt);
-}
-
-void bt829_SetSaturation(BT829Ptr bt, int saturation)
-{
- CARD16 sat_u, sat_v;
-
- saturation = LIMIT(saturation,-1000,1000);
- sat_u = (254*(saturation+1000))/1000;
- sat_v = (180*(saturation+1000))/1000;
- if ((sat_u == bt->sat_u) && (sat_v == bt->sat_v)) return;
- bt->sat_u = sat_u;
- bt->sat_v = sat_v;
- /* propagate_changes(bt); */ /* no dependencies */
- btwrite_control(bt);
- btwrite_sat_u_lo(bt);
- btwrite_sat_v_lo(bt);
-}
-
-void bt829_SetTint(BT829Ptr bt, int hue)
-{
- hue = LIMIT(hue,-1000,999); /* ensure -128 <= hue <= 127 below */
- hue = (128*hue)/1000;
- if (hue == bt->hue) return;
- bt->hue = hue;
- /* propagate_changes(bt); */ /* no dependencies */
- btwrite_hue(bt);
-}
-
-int bt829_SetCaptSize(BT829Ptr bt, int width, int height)
-{
- if ((width > bt->htotal - 2 * HCROP) ||
- (16 * width < bt->htotal - 32 * HCROP)) return -1;
- if ((height > bt->vactive) || (16 * height < bt->vactive)) return -1;
- if ((width == bt->width) && (height == bt->height)) return 0;
- bt->width = width;
- bt->height = height;
- propagate_changes(bt);
- btwrite_crop(bt);
- btwrite_hactive_lo(bt);
- btwrite_control(bt);
- btwrite_vtc(bt);
- return 0;
-}
-
-int bt829_SetCC(BT829Ptr bt) /* FIXME: should take ccmode as a parameter */
-{
- if (BTVERSION < BT827) return -1; /* can't do it */
- /* propagate_changes(bt); */ /* no dependencies */
- btwrite_cc_status(bt);
- /* we write to STATUS to reset the CCVALID flag */
- if (bt->ccmode != 0) btwrite_status(bt);
- return 0;
-}
-
-void bt829_SetOUT_EN(BT829Ptr bt, BOOL out_en)
-{
- out_en = (out_en != 0);
- if (out_en == bt->out_en) return;
- bt->out_en = out_en;
- /* propagate_changes(bt); */ /* no dependencies */
- btwrite_vpole(bt);
-}
-
-void bt829_SetP_IO(BT829Ptr bt, CARD8 p_io)
-{
- if (p_io == bt->p_io) return;
- bt->p_io = p_io;
- /* propagate_changes(bt); */ /* no dependencies */
- btwrite_p_io(bt);
-}
-
-#define BTREAD(R) btread(bt,(R))
-
-#if 0
-
-void bt829_getCCdata(BT829Ptr bt,struct CCdata *data)
-{
- CARD8 status;
- data->num_valid=0;
- /* wait for buffer to be half full (means 8/16 bytes)
- * either 4 (one of CC/EDS) or 2 (both CC/EDS) frames */
- if(!(BTREAD(STATUS)&0x04)) return; /* could comment this line */
- for(;data->num_valid<CC_FIFO_SIZE;data->num_valid++) {
- status=BTREAD(CC_STATUS);
- if(!(status&0x04)) break;
- data->data[data->num_valid]= BTREAD(CC_DATA)&0x7f;
- /* stripped high bit (parity) */
- data->status[data->num_valid]= (CCS_EDS*((status&0x02)>>1)) |
- (CCS_HIGH*(status&0x01)) |
- (CCS_OVER*((status&0x08)>>3)) |
- (CCS_PAR*((status&0x80)>>7)) ; }
- btwrite(bt,STATUS,0x00); /* Reset CCVALID status bit */
- return;
-}
-
-#endif
-
-/* ------------------------------------------------------------------------ */
-/* Debug and report routines */
-
-#define DUMPREG(REG) \
- xf86DrvMsg(bt->d.pI2CBus->scrnIndex,X_INFO," %-12s (0x%02X) = 0x%02X\n", \
- #REG,REG,BTREAD(REG))
-
-/*static void bt829_dumpregs(BT829Ptr bt)
-{
- DUMPREG(STATUS);
- DUMPREG(IFORM);
- DUMPREG(TDEC);
- DUMPREG(CROP);
- DUMPREG(VDELAY_LO);
- DUMPREG(VACTIVE_LO);
- DUMPREG(HDELAY_LO);
- DUMPREG(HACTIVE_LO);
- DUMPREG(HSCALE_HI);
- DUMPREG(HSCALE_LO);
- DUMPREG(BRIGHT);
- DUMPREG(CONTROL);
- DUMPREG(CONTRAST_LO);
- DUMPREG(SAT_U_LO);
- DUMPREG(SAT_V_LO);
- DUMPREG(HUE);
- if (BTVERSION >= BT827) {
- DUMPREG(SCLOOP);
- DUMPREG(WC_UP) ; }
- DUMPREG(OFORM);
- DUMPREG(VSCALE_HI);
- DUMPREG(VSCALE_LO);
- DUMPREG(TEST);
- DUMPREG(VPOLE);
- DUMPREG(IDCODE);
- DUMPREG(ADELAY);
- DUMPREG(BDELAY);
- DUMPREG(ADC);
- if (BTVERSION >= BT827) {
- DUMPREG(VTC);
- DUMPREG(CC_STATUS);
- DUMPREG(CC_DATA);
- DUMPREG(WC_DN);
- DUMPREG(P_IO) ; }
-}*/
+/* TODO: clean up/fix CC code */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "xf86.h"
+#include "xf86i2c.h"
+#include "bt829.h"
+#include "i2c_def.h"
+
+/* Changing the following settings (especially VCROP) may */
+/* require modifying code that calls this driver. */
+#define HCROP 0 /* amount to crop from the left and right edges */
+#define VCROP 0 /* amount to crop from the top and bottom edges */
+
+#define BTVERSION (bt->id>>4)
+
+#define H(X) ( ((X)>>8) & 0xFF )
+#define L(X) ( (X) & 0xFF )
+
+#define LIMIT(X,A,B) (((X)<(A)) ? (A) : ((X)>(B)) ? (B) : (X) )
+
+/* Bt829 family chip ID's */
+#define BT815 0x02
+#define BT817 0x06
+#define BT819 0x07
+#define BT827 0x0C
+#define BT829 0x0E
+
+/* Bt829 registers */
+#define STATUS 0x00 /* Device Status */
+#define IFORM 0x01 /* Input Format */
+#define TDEC 0x02 /* Temporal Decimation */
+#define CROP 0x03 /* MSB Cropping */
+#define VDELAY_LO 0x04 /* Vertical Delay */
+#define VACTIVE_LO 0x05 /* Vertical Active */
+#define HDELAY_LO 0x06 /* Horizontal Delay */
+#define HACTIVE_LO 0x07 /* Horizontal Active */
+#define HSCALE_HI 0x08 /* Horizontal Scaling */
+#define HSCALE_LO 0x09 /* Horizontal Scaling */
+#define BRIGHT 0x0A /* Brightness Control */
+#define CONTROL 0x0B /* Miscellaneous Control */
+#define CONTRAST_LO 0x0C /* Luma Gain (Contrast) */
+#define SAT_U_LO 0x0D /* Chroma (U) Gain (Saturation) */
+#define SAT_V_LO 0x0E /* Chroma (V) Gain (Saturation) */
+#define HUE 0x0F /* Hue Control */
+#define SCLOOP 0x10 /* SC Loop Control */
+#define WC_UP 0x11 /* White Crush Up Count */
+#define OFORM 0x12 /* Output Format */
+#define VSCALE_HI 0x13 /* Vertical Scaling */
+#define VSCALE_LO 0x14 /* Vertical Scaling */
+#define TEST 0x15 /* Test Control */
+#define VPOLE 0x16 /* Video Timing Polarity */
+#define IDCODE 0x17 /* ID Code */
+#define ADELAY 0x18 /* AGC Delay */
+#define BDELAY 0x19 /* Burst Gate Delay */
+#define ADC 0x1A /* ADC Interface */
+#define VTC 0x1B /* Video Timing Control */
+#define CC_STATUS 0x1C /* Extended Data Services/Closed Capt Status */
+#define CC_DATA 0x1D /* Extended Data Services/Closed Capt Data */
+#define WC_DN 0x1E /* White Crush Down Count */
+#define SRESET 0x1F /* Software Reset */
+#define P_IO 0x3F /* Programmable I/O */
+
+static CARD8 btread(BT829Ptr bt, CARD8 reg)
+{
+ CARD8 v;
+
+ I2C_WriteRead(&(bt->d), &reg, 1, &v, 1);
+
+ return v;
+}
+
+static void btwrite(BT829Ptr bt, CARD8 reg, CARD8 val)
+{
+ CARD8 data[2];
+
+ data[0] = reg;
+ data[1] = val;
+ I2C_WriteRead(&(bt->d), data, 2, NULL, 0);
+}
+
+/*
+ * Register access
+ */
+static void btwrite_status(BT829Ptr bt) /* STATUS */
+{
+ btwrite(bt, STATUS, 0x00); /* clear */
+}
+
+static void btwrite_iform(BT829Ptr bt) /* IFORM */
+{
+ int xtsel;
+
+ switch (bt->format) {
+ case BT829_NTSC:
+ case BT829_NTSC_JAPAN:
+ case BT829_PAL_M:
+ case BT829_PAL_N_COMB: /* gatos says xtsel = 2 */
+ xtsel = 1;
+ break;
+ case BT829_PAL:
+ case BT829_PAL_N:
+ case BT829_SECAM:
+ xtsel = 2;
+ break;
+ default: /* shouldn't get here */
+ xtsel = 3; /* hardware default */
+ break;
+ }
+
+ btwrite(bt, IFORM, (bt->mux<<5) | (xtsel<<3) | bt->format);
+}
+
+static void btwrite_tdec(BT829Ptr bt) /* TDEC */
+{
+ /* use default */
+}
+
+static void btwrite_crop(BT829Ptr bt) /* CROP */
+{
+ btwrite(bt, CROP, (H(bt->vdelay)<<6) | (H(bt->vactive)<<4) |
+ (H(bt->hdelay)<<2) | H(bt->width));
+}
+
+static void btwrite_vdelay_lo(BT829Ptr bt) /* VDELAY_LO */
+{
+ btwrite(bt, VDELAY_LO, L(bt->vdelay));
+}
+
+static void btwrite_vactive_lo(BT829Ptr bt) /* VACTIVE_LO */
+{
+ btwrite(bt, VACTIVE_LO, L(bt->vactive));
+}
+
+static void btwrite_hdelay_lo(BT829Ptr bt) /* HDELAY_LO */
+{
+ btwrite(bt, HDELAY_LO, L(bt->hdelay));
+}
+
+static void btwrite_hactive_lo(BT829Ptr bt) /* HACTIVE_LO */
+{
+ btwrite(bt, HACTIVE_LO, L(bt->width));
+}
+
+static void btwrite_hscale_hi(BT829Ptr bt) /* HSCALE_HI */
+{
+ btwrite(bt, HSCALE_HI, H(bt->hscale));
+}
+
+static void btwrite_hscale_lo(BT829Ptr bt) /* HSCALE_LO */
+{
+ btwrite(bt, HSCALE_LO, L(bt->hscale));
+}
+
+static void btwrite_bright(BT829Ptr bt) /* BRIGHT */
+{
+ btwrite(bt, BRIGHT, bt->brightness);
+}
+
+static void btwrite_control(BT829Ptr bt) /* CONTROL */
+{
+ int ldec;
+
+ /* The data sheet says ldec should always be 0 for SECAM */
+ /* but the picture quality is better with ldec = 1 */
+ ldec = (bt->width > 360); /* gatos says 384 */
+
+ btwrite(bt, CONTROL,
+ ((bt->mux==bt->svideo_mux) ? 0xC0:0x00) | /* LNOTCH and COMP */
+ (ldec<<5) | (H(bt->contrast)<<2) | (H(bt->sat_u)<<1) | H(bt->sat_v));
+}
+
+static void btwrite_contrast_lo(BT829Ptr bt) /* CONTRAST_LO */
+{
+ btwrite(bt, CONTRAST_LO, L(bt->contrast));
+}
+
+static void btwrite_sat_u_lo(BT829Ptr bt) /* SAT_U_LO */
+{
+ btwrite(bt, SAT_U_LO, L(bt->sat_u));
+}
+
+static void btwrite_sat_v_lo(BT829Ptr bt) /* SAT_V_LO */
+{
+ btwrite(bt, SAT_V_LO, L(bt->sat_v));
+}
+
+static void btwrite_hue(BT829Ptr bt) /* HUE */
+{
+ btwrite(bt, HUE, bt->hue);
+}
+
+static void btwrite_scloop(BT829Ptr bt) /* SCLOOP */
+{
+ if (BTVERSION >= BT827) {
+ btwrite(bt, SCLOOP,
+ (bt->format==BT829_SECAM) ? 0x10:0x00 /* QCIF or AUTO */
+ );
+ }
+}
+
+static void btwrite_wc_up(BT829Ptr bt) /* WC_UP */
+{
+ if (BTVERSION >= BT827) {
+ /* use default */
+ }
+}
+
+static void btwrite_oform(BT829Ptr bt) /* OFORM */
+{
+ btwrite(bt, OFORM, (bt->code<<3) | (bt->len<<2) |
+ 0x02 /* RANGE = 0, CORE = 0, VBI_FRAME = 0, OES = 2 (default) */
+ );
+}
+
+static void btwrite_vscale_hi(BT829Ptr bt) /* VSCALE_HI */
+{
+ btwrite(bt, VSCALE_HI, H(bt->vscale) |
+ 0x60 /* YCOMB = 0, COMB = 1, INT = 1 (default) */
+ );
+}
+
+static void btwrite_vscale_lo(BT829Ptr bt) /* VSCALE_LO */
+{
+ btwrite(bt, VSCALE_LO, L(bt->vscale));
+}
+
+/* TEST should not be written to */
+
+static void btwrite_vpole(BT829Ptr bt) /* VPOLE */
+{
+ btwrite(bt, VPOLE, (bt->out_en<<7));
+}
+
+/* IDCODE is read only */
+
+static void btwrite_adelay(BT829Ptr bt) /* ADELAY */
+{
+ switch (bt->format) {
+ case BT829_NTSC:
+ case BT829_NTSC_JAPAN:
+ case BT829_PAL_M:
+ btwrite(bt, ADELAY, 104);
+ break;
+ case BT829_PAL:
+ case BT829_PAL_N:
+ case BT829_SECAM:
+ case BT829_PAL_N_COMB:
+ btwrite(bt, ADELAY, 127);
+ break;
+ default: /* shouldn't get here */
+ btwrite(bt, ADELAY, 104); /* hardware default */
+ break;
+ }
+}
+
+static void btwrite_bdelay(BT829Ptr bt) /* BDELAY */
+{
+ switch (bt->format) {
+ case BT829_NTSC:
+ case BT829_NTSC_JAPAN:
+ case BT829_PAL_M:
+ btwrite(bt, BDELAY, 93);
+ break;
+ case BT829_PAL:
+ case BT829_PAL_N:
+ case BT829_PAL_N_COMB:
+ btwrite(bt, BDELAY, 114);
+ break;
+ case BT829_SECAM:
+ btwrite(bt, BDELAY, 160);
+ break;
+ default: /* shouldn't get here */
+ btwrite(bt, BDELAY, 93); /* hardware default */
+ break;
+ }
+}
+
+static void btwrite_adc(BT829Ptr bt) /* ADC */
+{
+ btwrite(bt, ADC, bt->mux==bt->svideo_mux ? 0x80:0x82); /* CSLEEP = 0 or 1 */
+}
+
+static void btwrite_vtc(BT829Ptr bt) /* VTC */
+{
+ int vfilt = 0; /* hardware default */
+
+ if (BTVERSION > BT827) { /* gatos says >= BT827 */
+ switch (bt->format) {
+ case BT829_NTSC:
+ case BT829_NTSC_JAPAN:
+ case BT829_PAL_M:
+ case BT829_PAL_N_COMB: /* gatos groups with BT829_PAL */
+ if (bt->width <= 360) vfilt = 1; /* gatos says <= 240 */
+ if (bt->width <= 180) vfilt = 2; /* gatos says <= 120 */
+ if (bt->width <= 90) vfilt = 3; /* gatos says <= 60 */
+ break;
+ case BT829_PAL:
+ case BT829_PAL_N:
+ case BT829_SECAM:
+ if (bt->width <= 384) vfilt = 1;
+ if (bt->width <= 192) vfilt = 2;
+ if (bt->width<= 96) vfilt = 3;
+ break;
+ default: /* shouldn't get here */
+ break; /* use hardware default */
+ }
+ btwrite(bt, VTC, (bt->vbien<<4) | (bt->vbifmt<<3) | vfilt);
+ }
+}
+
+static void btwrite_cc_status(BT829Ptr bt) /* CC_STATUS */
+{ /* FIXME: ATI specific */
+ if (BTVERSION >= BT827) {
+ if (bt->ccmode == 0) btwrite(bt, CC_STATUS, 0x00);
+ /* 0x40 is activate to set the CCVALID line. Not required yet */
+ else btwrite(bt, CC_STATUS, (bt->ccmode<<4) | 0x40);
+ }
+}
+
+/* CC_DATA is read only */
+
+static void btwrite_wc_dn(BT829Ptr bt) /* WC_DN */
+{
+ if (BTVERSION >= BT827) {
+ /* use default */
+ }
+}
+
+static void bt_reset(BT829Ptr bt) { /* SRESET */
+ btwrite(bt, SRESET, 0x0); /* Reset all registers */
+}
+
+static void btwrite_p_io(BT829Ptr bt) /* P_IO */
+{
+ if (BTVERSION >= BT827) {
+ btwrite(bt, P_IO, bt->p_io);
+ }
+}
+
+/*
+ * Deal with dependencies
+ */
+static void propagate_changes(BT829Ptr bt)
+{
+ CARD16 hdelay, unscaled_hdelay, vdelay, hscale, vscale;
+ int htotal, vactive;
+
+ switch (bt->format) {
+ case BT829_NTSC:
+ case BT829_NTSC_JAPAN:
+ case BT829_PAL_M:
+ vdelay = 22;
+ htotal = 754;
+ vactive = 480;
+ unscaled_hdelay = 135;
+ break;
+ case BT829_PAL:
+ case BT829_PAL_N:
+ vdelay = (bt->tunertype==5) ? 34 : 22;
+ htotal = 922;
+ vactive = 576;
+ unscaled_hdelay = 186;
+ break;
+ case BT829_SECAM:
+ vdelay = 34;
+ htotal = 922;
+ vactive = 576;
+ unscaled_hdelay = 186;
+ break;
+ case BT829_PAL_N_COMB:
+ vdelay = (bt->tunertype==5) ? 34 : 22; /* windows says 22 */
+ htotal = 754; /* gatos and windows say 922 */
+ vactive = 576;
+ unscaled_hdelay = 135; /* gatos and windows say 186 */
+ break;
+ default: /* shouldn't get here */
+ vdelay = 22; /* hardware default */
+ htotal = 754;
+ vactive = 480; /* hardware default */
+ unscaled_hdelay = 135;
+ break;
+ }
+
+ bt->htotal = htotal; /* Used for error checking in bt829_SetCaptSize */
+
+ hscale = 4096 * htotal / (bt->width + 2 * HCROP)-4096;
+ hdelay = (
+ HCROP + (bt->width + 2 * HCROP) * unscaled_hdelay / htotal
+ ) & 0x3FE;
+
+ vactive = vactive - 2 * VCROP;
+ vdelay = vdelay + VCROP;
+ vscale = (0x10000 - (512*vactive/bt->height-512)) & 0x1FFF;
+
+ if ((hdelay != bt->hdelay) || (vdelay != bt->vdelay) ||
+ (vactive != bt->vactive) || (hscale != bt->hscale) ||
+ (vscale != bt->vscale)) {
+ bt->hdelay = hdelay;
+ bt->vdelay = vdelay;
+ bt->vactive = vactive;
+ bt->hscale = hscale;
+ bt->vscale = vscale;
+ btwrite_crop(bt);
+ btwrite_vdelay_lo(bt);
+ btwrite_vactive_lo(bt);
+ btwrite_hdelay_lo(bt);
+ btwrite_hscale_hi(bt);
+ btwrite_hscale_lo(bt);
+ btwrite_control(bt);
+ btwrite_vscale_hi(bt);
+ btwrite_vscale_lo(bt);
+ }
+}
+
+static void write_all(BT829Ptr bt)
+{
+ bt_reset(bt);
+ propagate_changes(bt); /* ensure consistency */
+ btwrite_iform(bt);
+ btwrite_tdec(bt);
+ btwrite_crop(bt);
+ btwrite_vdelay_lo(bt);
+ btwrite_vactive_lo(bt);
+ btwrite_hdelay_lo(bt);
+ btwrite_hactive_lo(bt);
+ btwrite_hscale_hi(bt);
+ btwrite_hscale_lo(bt);
+ btwrite_bright(bt);
+ btwrite_control(bt);
+ btwrite_contrast_lo(bt);
+ btwrite_sat_u_lo(bt);
+ btwrite_sat_v_lo(bt);
+ btwrite_hue(bt);
+ btwrite_scloop(bt);
+ btwrite_wc_up(bt);
+ btwrite_oform(bt);
+ btwrite_vscale_hi(bt);
+ btwrite_vscale_lo(bt);
+ btwrite_vpole(bt);
+ btwrite_adelay(bt);
+ btwrite_bdelay(bt);
+ btwrite_adc(bt);
+ btwrite_vtc(bt);
+/* btwrite_cc_status(bt); */ /* FIXME: CC code needs cleaning */
+ btwrite_wc_dn(bt);
+ btwrite_p_io(bt);
+}
+
+/*
+ * Public functions
+ */
+BT829Ptr bt829_Detect(I2CBusPtr b, I2CSlaveAddr addr)
+{
+ BT829Ptr bt;
+ I2CByte a;
+
+ bt = calloc(1, sizeof(BT829Rec));
+ if(bt == NULL) return NULL;
+ bt->d.DevName = strdup("BT829 video decoder");
+ bt->d.SlaveAddr = addr;
+ bt->d.pI2CBus = b;
+ bt->d.NextDev = NULL;
+ bt->d.StartTimeout = b->StartTimeout;
+ bt->d.BitTimeout = b->BitTimeout;
+ bt->d.AcknTimeout = b->AcknTimeout;
+ bt->d.ByteTimeout = b->ByteTimeout;
+
+
+ if(!I2C_WriteRead(&(bt->d), NULL, 0, &a, 1))
+ {
+ free(bt);
+ return NULL;
+ }
+
+ bt->id = btread(bt,IDCODE);
+
+ free(bt->d.DevName);
+ bt->d.DevName = calloc(200, sizeof(char));
+ switch(BTVERSION){
+ case BT815:
+ sprintf(bt->d.DevName, "bt815a video decoder, revision %d",bt->id & 0xf);
+ break;
+ case BT817:
+ sprintf(bt->d.DevName, "bt817a video decoder, revision %d",bt->id & 0xf);
+ break;
+ case BT819:
+ sprintf(bt->d.DevName, "bt819a video decoder, revision %d",bt->id & 0xf);
+ break;
+ case BT827:
+ sprintf(bt->d.DevName, "bt827a/b video decoder, revision %d",bt->id & 0xf);
+ break;
+ case BT829:
+ sprintf(bt->d.DevName, "bt829a/b video decoder, revision %d",bt->id & 0xf);
+ break;
+ default:
+ sprintf(bt->d.DevName, "bt8xx/unknown video decoder version %d, revision %d",bt->id >> 4,bt->id & 0xf);
+ break;
+ }
+
+ /* set default parameters */
+ if(!I2CDevInit(&(bt->d)))
+ {
+ free(bt);
+ return NULL;
+ }
+
+ bt->tunertype = 1;
+
+ bt->brightness = 0; /* hardware default */
+ bt->ccmode = 0;
+ bt->code = 0; /* hardware default */
+ bt->contrast = 216; /* hardware default */
+ bt->format = BT829_NTSC;
+ bt->height = 480; /* hardware default for vactive */
+ bt->hue = 0; /* hardware default */
+ bt->len = 1; /* hardware default */
+ bt->mux = BT829_MUX0; /* hardware default */
+ bt->out_en = 0; /* hardware default */
+ bt->p_io = 0; /* hardware default */
+ bt->sat_u = 254; /* hardware default */
+ bt->sat_v = 180; /* hardware default */
+ bt->vbien = 0; /* hardware default */
+ bt->vbifmt = 0; /* hardware default */
+ bt->width = 640; /* hardware default for hactive */
+
+ bt->hdelay = 120; /* hardware default */
+ bt->hscale = 684; /* hardware default */
+ bt->vactive = 480; /* hardware default */
+ bt->vdelay = 22; /* hardware default */
+ bt->vscale = 0; /* hardware default */
+
+ bt->htotal = 754; /* NTSC */
+ bt->svideo_mux = 0; /* no s-video */
+
+ return bt;
+}
+
+int bt829_ATIInit(BT829Ptr bt)
+{
+ bt->code = 1;
+ bt->len = 0;
+ bt->vbien = 1;
+ bt->vbifmt = 1;
+ bt->svideo_mux = BT829_MUX1;
+
+ write_all (bt);
+
+ return 0;
+}
+
+int bt829_SetFormat(BT829Ptr bt, CARD8 format)
+{
+ if ((format < 1) || (format > 7)) return -1;
+ if ((BTVERSION <= BT819) &&
+ (format != BT829_NTSC) && (format != BT829_PAL)) return -1;
+ if (format == bt->format) return 0;
+ bt->format = format;
+ propagate_changes(bt);
+ btwrite_iform(bt);
+ btwrite_scloop(bt);
+ btwrite_adelay(bt);
+ btwrite_bdelay(bt);
+ btwrite_vtc(bt);
+ return 0;
+}
+
+int bt829_SetMux(BT829Ptr bt, CARD8 mux)
+{
+ if ((mux < 1) || (mux > 3)) return -1;
+ if (mux == bt->mux) return 0;
+ bt->mux = mux;
+ /* propagate_changes(bt); */ /* no dependencies */
+ btwrite_iform(bt);
+ btwrite_control(bt);
+ btwrite_adc(bt);
+ return 0;
+}
+
+void bt829_SetBrightness(BT829Ptr bt, int brightness)
+{
+ brightness = LIMIT(brightness,-1000,999); /* ensure -128 <= brightness <= 127 below */
+ brightness = (128*brightness)/1000;
+ if (brightness == bt->brightness) return;
+ bt->brightness = brightness;
+ /* propagate_changes(bt); */ /* no dependencies */
+ btwrite_bright(bt);
+}
+
+void bt829_SetContrast(BT829Ptr bt, int contrast)
+{
+ contrast = LIMIT(contrast,-1000,1000);
+ contrast = (216*(contrast+1000))/1000;
+ if (contrast == bt->contrast) return;
+ bt->contrast = contrast;
+ /* propagate_changes(bt); */ /* no dependencies */
+ btwrite_control(bt);
+ btwrite_contrast_lo(bt);
+}
+
+void bt829_SetSaturation(BT829Ptr bt, int saturation)
+{
+ CARD16 sat_u, sat_v;
+
+ saturation = LIMIT(saturation,-1000,1000);
+ sat_u = (254*(saturation+1000))/1000;
+ sat_v = (180*(saturation+1000))/1000;
+ if ((sat_u == bt->sat_u) && (sat_v == bt->sat_v)) return;
+ bt->sat_u = sat_u;
+ bt->sat_v = sat_v;
+ /* propagate_changes(bt); */ /* no dependencies */
+ btwrite_control(bt);
+ btwrite_sat_u_lo(bt);
+ btwrite_sat_v_lo(bt);
+}
+
+void bt829_SetTint(BT829Ptr bt, int hue)
+{
+ hue = LIMIT(hue,-1000,999); /* ensure -128 <= hue <= 127 below */
+ hue = (128*hue)/1000;
+ if (hue == bt->hue) return;
+ bt->hue = hue;
+ /* propagate_changes(bt); */ /* no dependencies */
+ btwrite_hue(bt);
+}
+
+int bt829_SetCaptSize(BT829Ptr bt, int width, int height)
+{
+ if ((width > bt->htotal - 2 * HCROP) ||
+ (16 * width < bt->htotal - 32 * HCROP)) return -1;
+ if ((height > bt->vactive) || (16 * height < bt->vactive)) return -1;
+ if ((width == bt->width) && (height == bt->height)) return 0;
+ bt->width = width;
+ bt->height = height;
+ propagate_changes(bt);
+ btwrite_crop(bt);
+ btwrite_hactive_lo(bt);
+ btwrite_control(bt);
+ btwrite_vtc(bt);
+ return 0;
+}
+
+int bt829_SetCC(BT829Ptr bt) /* FIXME: should take ccmode as a parameter */
+{
+ if (BTVERSION < BT827) return -1; /* can't do it */
+ /* propagate_changes(bt); */ /* no dependencies */
+ btwrite_cc_status(bt);
+ /* we write to STATUS to reset the CCVALID flag */
+ if (bt->ccmode != 0) btwrite_status(bt);
+ return 0;
+}
+
+void bt829_SetOUT_EN(BT829Ptr bt, BOOL out_en)
+{
+ out_en = (out_en != 0);
+ if (out_en == bt->out_en) return;
+ bt->out_en = out_en;
+ /* propagate_changes(bt); */ /* no dependencies */
+ btwrite_vpole(bt);
+}
+
+void bt829_SetP_IO(BT829Ptr bt, CARD8 p_io)
+{
+ if (p_io == bt->p_io) return;
+ bt->p_io = p_io;
+ /* propagate_changes(bt); */ /* no dependencies */
+ btwrite_p_io(bt);
+}
+
+#define BTREAD(R) btread(bt,(R))
+
+#if 0
+
+void bt829_getCCdata(BT829Ptr bt,struct CCdata *data)
+{
+ CARD8 status;
+ data->num_valid=0;
+ /* wait for buffer to be half full (means 8/16 bytes)
+ * either 4 (one of CC/EDS) or 2 (both CC/EDS) frames */
+ if(!(BTREAD(STATUS)&0x04)) return; /* could comment this line */
+ for(;data->num_valid<CC_FIFO_SIZE;data->num_valid++) {
+ status=BTREAD(CC_STATUS);
+ if(!(status&0x04)) break;
+ data->data[data->num_valid]= BTREAD(CC_DATA)&0x7f;
+ /* stripped high bit (parity) */
+ data->status[data->num_valid]= (CCS_EDS*((status&0x02)>>1)) |
+ (CCS_HIGH*(status&0x01)) |
+ (CCS_OVER*((status&0x08)>>3)) |
+ (CCS_PAR*((status&0x80)>>7)) ; }
+ btwrite(bt,STATUS,0x00); /* Reset CCVALID status bit */
+ return;
+}
+
+#endif
+
+/* ------------------------------------------------------------------------ */
+/* Debug and report routines */
+
+#define DUMPREG(REG) \
+ xf86DrvMsg(bt->d.pI2CBus->scrnIndex,X_INFO," %-12s (0x%02X) = 0x%02X\n", \
+ #REG,REG,BTREAD(REG))
+
+/*static void bt829_dumpregs(BT829Ptr bt)
+{
+ DUMPREG(STATUS);
+ DUMPREG(IFORM);
+ DUMPREG(TDEC);
+ DUMPREG(CROP);
+ DUMPREG(VDELAY_LO);
+ DUMPREG(VACTIVE_LO);
+ DUMPREG(HDELAY_LO);
+ DUMPREG(HACTIVE_LO);
+ DUMPREG(HSCALE_HI);
+ DUMPREG(HSCALE_LO);
+ DUMPREG(BRIGHT);
+ DUMPREG(CONTROL);
+ DUMPREG(CONTRAST_LO);
+ DUMPREG(SAT_U_LO);
+ DUMPREG(SAT_V_LO);
+ DUMPREG(HUE);
+ if (BTVERSION >= BT827) {
+ DUMPREG(SCLOOP);
+ DUMPREG(WC_UP) ; }
+ DUMPREG(OFORM);
+ DUMPREG(VSCALE_HI);
+ DUMPREG(VSCALE_LO);
+ DUMPREG(TEST);
+ DUMPREG(VPOLE);
+ DUMPREG(IDCODE);
+ DUMPREG(ADELAY);
+ DUMPREG(BDELAY);
+ DUMPREG(ADC);
+ if (BTVERSION >= BT827) {
+ DUMPREG(VTC);
+ DUMPREG(CC_STATUS);
+ DUMPREG(CC_DATA);
+ DUMPREG(WC_DN);
+ DUMPREG(P_IO) ; }
+}*/
diff --git a/xorg-server/hw/xfree86/i2c/fi1236.c b/xorg-server/hw/xfree86/i2c/fi1236.c
index 61224eaa5..531b64aed 100644
--- a/xorg-server/hw/xfree86/i2c/fi1236.c
+++ b/xorg-server/hw/xfree86/i2c/fi1236.c
@@ -1,605 +1,605 @@
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
-#include "xf86.h"
-#include "xf86i2c.h"
-#include "fi1236.h"
-#include "tda9885.h"
-#include "i2c_def.h"
-
-#define NUM_TUNERS 8
-
-const FI1236_parameters tuner_parms[NUM_TUNERS] =
-{
- /* 0 - FI1236 */
- { 733 ,884 ,12820 ,2516 ,7220 ,0xA2 ,0x94, 0x34, 0x8e },
- /* !!!based on documentation - it should be:
- {733 ,16*55.25 ,16*801.25 ,16*160 ,16*454 ,0xA0 ,0x90, 0x30, 0x8e},*/
-
- /* 1 - FI1216 */
- { 623 ,16*48.75 ,16*855.25 ,16*170 ,16*450 ,0xA0 ,0x90, 0x30, 0x8e },
- /* 2 - TEMIC FN5AL */
- { 623 ,16*45.75 ,16*855.25 ,16*169 ,16*454 ,0xA0 ,0x90, 0x30, 0x8e },
- /* 3 - MT2032.. */
- { 733 ,768 ,13760 , 0 , 0 , 0 , 0, 0, 0 },
- /* 4 - FI1246 */
- { 623 ,16*45.75 ,16*855.25 ,16*170 ,16*450 ,0xA0 ,0x90, 0x30, 0x8e },
- /* 5 - FI1256 */
- { 623 ,16*49.75 ,16*863.25 ,16*170 ,16*450 ,0xA0 ,0x90, 0x30, 0x8e },
- /* 6 - FI1236W */
- /*{ 733 ,884 ,12820 ,2516 ,7220 ,0x1 ,0x2, 0x4, 0x8e },*/
- { 732, 16*55.25, 16*801.25, 16*160, 16*442, 0x1, 0x2, 0x4, 0x8e },
- /* 7 - FM1216ME */
- { 623 ,16*48.25 ,16*863.25 ,16*158.00 ,16*442.00 ,0x1 ,0x2, 0x4, 0x8e }
-};
-
-
-FI1236Ptr Detect_FI1236(I2CBusPtr b, I2CSlaveAddr addr)
-{
- FI1236Ptr f;
- I2CByte a;
-
- f = xcalloc(1,sizeof(FI1236Rec));
- if(f == NULL) return NULL;
- f->d.DevName = strdup("FI12xx Tuner");
- f->d.SlaveAddr = addr;
- f->d.pI2CBus = b;
- f->d.NextDev = NULL;
- f->d.StartTimeout = b->StartTimeout;
- f->d.BitTimeout = b->BitTimeout;
- f->d.AcknTimeout = b->AcknTimeout;
- f->d.ByteTimeout = b->ByteTimeout;
- f->type=TUNER_TYPE_FI1236;
- f->afc_timer_installed=FALSE;
- f->last_afc_hint=TUNER_OFF;
- f->video_if=45.7812;
-
- if(!I2C_WriteRead(&(f->d), NULL, 0, &a, 1))
- {
- free(f);
- return NULL;
- }
- FI1236_set_tuner_type(f, TUNER_TYPE_FI1236);
- if(!I2CDevInit(&(f->d)))
- {
- free(f);
- return NULL;
- }
- return f;
-}
-
-static void MT2032_dump_parameters(FI1236Ptr f, MT2032_parameters *m)
-{
-xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: input f_rf=%g f_if1=%g f_if2=%g f_ref=%g f_ifbw=%g f_step=%g\n",
- m->f_rf, m->f_if1, m->f_if2, m->f_ref, m->f_ifbw, m->f_step);
-
-xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: computed f_lo1=%g f_lo2=%g LO1I=%d LO2I=%d SEL=%d STEP=%d NUM=%d\n",
- m->f_lo1, m->f_lo2, m->LO1I, m->LO2I, m->SEL, m->STEP, m->NUM);
-}
-
-
-static void MT2032_getid(FI1236Ptr f)
-{
-CARD8 out[4];
-CARD8 in;
-
-in=0x11;
-I2C_WriteRead(&(f->d), (I2CByte *)&in, 1, out, 4);
-xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: Company code 0x%02x%02x, part code 0x%02x, revision code 0x%02x\n",
- out[0], out[1], out[2], out[3]);
-
-}
-
-/* might be buggy */
-#if 0
-static void MT2032_shutdown(FI1236Ptr f)
-{
-CARD8 data[10];
-
-data[0]=0x00; /* start with register 0x00 */
-data[1]=0x1A;
-data[2]=0x44;
-data[3]=0x20;
-
-I2C_WriteRead(&(f->d), (I2CByte *)data, 4, NULL, 0);
-
-data[0]=0x05; /* now start with register 0x05 */
-data[1]=0xD7;
-data[2]=0x14;
-data[3]=0x05;
-I2C_WriteRead(&(f->d), (I2CByte *)data, 4, NULL, 0);
-
-data[0]=0x0B; /* now start with register 0x05 */
-data[1]=0x8F;
-data[2]=0x07;
-data[3]=0x43;
-I2C_WriteRead(&(f->d), (I2CByte *)data, 4, NULL, 0);
-
-usleep(15000);
-}
-#endif
-
-static void MT2032_dump_status(FI1236Ptr f);
-
-static void MT2032_init(FI1236Ptr f)
-{
-CARD8 data[10];
-CARD8 value;
-CARD8 xogc = 0x00;
-
-MT2032_getid(f);
-
-data[0]=0x02; /* start with register 0x02 */
-data[1]=0xFF;
-data[2]=0x0F;
-data[3]=0x1F;
-
-I2C_WriteRead(&(f->d), (I2CByte *)data, 4, NULL, 0);
-
-data[0]=0x06; /* now start with register 0x06 */
-data[1]=0xE4;
-data[2]=0x8F;
-data[3]=0xC3;
-data[4]=0x4E;
-data[5]=0xEC;
-I2C_WriteRead(&(f->d), (I2CByte *)data, 6, NULL, 0);
-
-data[0]=0x0d; /* now start with register 0x0d */
-data[1]=0x32;
-I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0);
-
-while(1) {
- usleep(15000); /* wait 15 milliseconds */
-
- data[0]=0x0e; /* register number 7, status */
- value=0xFF;
- if(!I2C_WriteRead(&(f->d), (I2CByte *)data, 1, &value, 1))
- xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: failed to read XOK\n");
- xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: XOK=%d\n", value & 0x01);
- if(value & 1) break;
-
- data[0]=0x07;
- if(!I2C_WriteRead(&(f->d), (I2CByte *)data, 1, &value, 1))
- xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: failed to read XOGC\n");
-
- xogc=value & 0x7;
- if(xogc==4){
- break; /* XOGC has reached 4.. stop */
- }
- xogc--;
- xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: try XOGC=%d\n", xogc);
- usleep(15000);
- data[0]=0x07; /* register number 7, control byte 2 */
- data[1]=0x08 | xogc;
- I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0);
- }
-f->xogc=xogc;
-/* wait before continuing */
-usleep(15000); /* wait 50 milliseconds */
-MT2032_dump_status(f);
-}
-
-static int MT2032_no_spur_in_band(MT2032_parameters *m)
-{
-int n_max, n1, n2;
-double f_test;
-n_max=5;
-n1=1;
-while(1){
- n2=-n1;
- f_test=n1*(m->f_lo1-m->f_lo2);
- while(1){
- n2--;
- f_test=f_test-m->f_lo2;
- xf86DrvMsg(0, X_INFO, "testing f_test=%g n1=%d n2=%d f_lo1=%g f_lo2=%g f_if2=%g\n", f_test, n1, n2, m->f_lo1, m->f_lo2, m->f_if2);
- xf86DrvMsg(0, X_INFO, "d_f=%g f_ifbw=%g\n",fabs(fabs(f_test)-m->f_if2), m->f_ifbw);
- if((fabs(fabs(f_test)-m->f_if2)*2.0)<=m->f_ifbw)return 0;
- if(n2<=-n_max)break;
- /* this line in the manual is bogus. I say it is faster
- and more correct to go over all harmonics.. */
- #if 0
- if(f_test<(m->f_lo2-m->f_if2-m->f_ifbw))break;
- #endif
- }
- n1++;
- if(n1>=n_max)return 1;
- }
-
-}
-
-static void MT2032_calculate_register_settings(MT2032_parameters *m, double f_rf, double f_if1, double f_if2, double f_ref, double f_ifbw, double f_step)
-{
-int n;
-m->f_rf=f_rf;
-m->f_if1=f_if1;
-m->f_if2=f_if2;
-m->f_ref=f_ref;
-m->f_ifbw=f_ifbw;
-m->f_step=f_step;
-
-m->f_lo1=f_rf+f_if1;
-m->LO1I=lrint(m->f_lo1/f_ref);
-m->f_lo1=f_ref*m->LO1I;
-
-m->f_lo2=m->f_lo1-f_rf-f_if2;
-
-/* check for spurs */
-n=1;
-while(n<3){
- if(MT2032_no_spur_in_band(m))break;
- if(m->f_lo1<(f_rf+f_if1)){
- m->LO1I+=n;
- } else {
- m->LO1I-=n;
- }
- m->f_lo1=m->LO1I*f_ref;
- m->f_lo2=m->f_lo1-f_rf-f_if2;
- n++;
- }
-/* xf86DrvMsg(0, X_INFO, "MT2032: n=%d\n", n); */
-/* select VCO */
-
-/* m->f_lo1>1100.0 */
-if(m->f_lo1<1370.0)m->SEL=4;
- else
-if(m->f_lo1<1530.0)m->SEL=3;
- else
-if(m->f_lo1<1720.0)m->SEL=2;
- else
-if(m->f_lo1<1890.0)m->SEL=1;
- else /* m->f_lo1 < 1958.0 */
- m->SEL=0;
-
-/* calculate the rest of the registers */
-m->LO2I=floor(m->f_lo2/f_ref);
-m->STEP=floor(3780.0*f_step/f_ref);
-m->NUM=floor(3780.0*(m->f_lo2/f_ref-m->LO2I));
-m->NUM=m->STEP*lrint((1.0*m->NUM)/(1.0*m->STEP));
-}
-
-static int MT2032_wait_for_lock(FI1236Ptr f)
-{
-int n;
-CARD8 data[10];
-CARD8 value;
-
-n=12;
-while(1){
- data[0]=0x0e; /* register number 7, status */
- I2C_WriteRead(&(f->d), (I2CByte *)data, 1, &value, 1);
-/* xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: LO1LK=%d LO2LK=%d\n", (value & 0x04)>>2, (value & 0x02)>>1); */
- if((value & 6)==6) break;
- usleep(1500);
- n--;
- if(n<0)break;
- }
-if(n<0){
- xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: failed to set frequency\n");
- return 0;
- }
-return 1;
-}
-
-static void MT2032_implement_settings(FI1236Ptr f, MT2032_parameters *m)
-{
-CARD8 data[10];
-CARD8 value;
-
-data[0]=0x00; /* start with register 0x00 */
-data[1]=(m->LO1I>>3)-1;
-data[2]=(m->SEL<<4)|(m->LO1I & 0x7);
-data[3]=0x86;
-I2C_WriteRead(&(f->d), (I2CByte *)data, 4, NULL, 0);
-
-data[0]=0x05; /* start with register 0x05 */
-data[1]=((m->LO2I & 0x7)<<5)|((m->LO2I>>3)-1);
-if(m->f_rf<400.0)data[2]=0xe4;
- else data[2]=0xf4;
-I2C_WriteRead(&(f->d), (I2CByte *)data, 3, NULL, 0);
-
-data[0]=0x07; /* register number 7, control byte 2 */
-I2C_WriteRead(&(f->d), (I2CByte *)data, 1, &value, 1);
-xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: using XOGC=%d\n", (value & 0x07));
-data[1]=8 | (value & 0x7);
-I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0);
-
-data[0]=0x0b; /* start with register 0x0b */
-data[1]=m->NUM & 0xff;
-data[2]=(1<<7)|((m->NUM >> 8) & 0x0f);
-I2C_WriteRead(&(f->d), (I2CByte *)data, 3, NULL, 0);
-
-MT2032_wait_for_lock(f);
-}
-
-static void MT2032_optimize_VCO(FI1236Ptr f, MT2032_parameters *m)
-{
-CARD8 data[10];
-CARD8 value;
-CARD8 TAD1;
-
-data[0]=0x0f; /* register number 7, status */
-I2C_WriteRead(&(f->d), (I2CByte *)data, 1, &value, 1);
-TAD1=value & 0x07;
-xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: TAD1=%d SEL=%d\n", TAD1, m->SEL);
-if(TAD1 < 2)return;
-if(TAD1==2){
- if(m->SEL==0)return;
- m->SEL--;
- } else {
- if(m->SEL>=4)return;
- m->SEL++;
- }
-data[0]=0x01; /* start with register 1 */
-data[1]=(m->SEL<<4)|(m->LO1I & 0x7);
-I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0);
-
-}
-
-static int FI1236_get_afc_hint(FI1236Ptr f)
-{
- CARD8 out;
- CARD8 AFC;
-
- if ((f->type == TUNER_TYPE_FM1216ME) || (f->type == TUNER_TYPE_FI1236W))
- {
- TDA9885Ptr t = (TDA9885Ptr)f->afc_source;
- if (t == NULL)
- return TUNER_OFF;
-
- tda9885_getstatus(t);
- tda9885_dumpstatus(t);
- AFC = t->afc_status & 0x0f;
-
- xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC: FI1236_get_afc_hint: %i\n", AFC);
- if (AFC == 0) return TUNER_TUNED;
- else if (AFC <= 0x07)return TUNER_JUST_BELOW;
- else if (AFC < 0x0f )return TUNER_JUST_ABOVE;
- else if (AFC == 0x0f)return TUNER_TUNED;
- }
- else
- {
- I2C_WriteRead(&(f->d), NULL, 0, &out, 1);
- AFC=out & 0x7;
- xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC: FI1236_get_afc_hint: %i\n", AFC);
- if(AFC==2)return TUNER_TUNED;
- if(AFC==3)return TUNER_JUST_BELOW;
- if(AFC==1)return TUNER_JUST_ABOVE;
- return TUNER_OFF;
- }
- return TUNER_OFF;
-}
-
-static int MT2032_get_afc_hint(FI1236Ptr f)
-{
-CARD8 in;
-CARD8 out[2];
-CARD8 AFC;
-in=0x0e;
-I2C_WriteRead(&(f->d), (I2CByte *)&in, 1, out, 2);
-AFC=(out[0]>>4) & 0x7;
-#if 0
-xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC=%d TAD1=%d TAD2=%d\n", AFC, out[1] & 0x7, (out[1]>>4)& 0x07);
-#endif
-if(AFC==2)return TUNER_TUNED;
-if(AFC==3)return TUNER_JUST_BELOW;
-if(AFC==1)return TUNER_JUST_ABOVE;
-return TUNER_OFF;
-}
-
-/* this function is for external use only */
-int TUNER_get_afc_hint(FI1236Ptr f)
-{
-if(f->afc_timer_installed)return TUNER_STILL_TUNING;
-return f->last_afc_hint;
-}
-
-static void MT2032_dump_status(FI1236Ptr f)
-{
-CARD8 in;
-CARD8 out[2];
-CARD8 AFC;
-CARD8 LDONrb;
-CARD8 LO1LK, LO2LK, XOK;
-CARD8 TAD2, TAD1;
-
-in=0x0e;
-I2C_WriteRead(&(f->d), (I2CByte *)&in, 1, out, 2);
-XOK=out[0] & 1;
-LO1LK=(out[0]>>2) &1;
-LO2LK=(out[0]>>1) &1;
-LDONrb=(out[0]>>3) &1;
-
-AFC=(out[0]>>4) & 0x7;
-
-TAD1=(out[1] & 0x7);
-TAD2=(out[1]>>4) & 0x7;
-
-xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: status: XOK=%d LO1LK=%d LO2LK=%d LDONrb=%d AFC=%d TAD1=%d TAD2=%d\n",
- XOK, LO1LK, LO2LK, LDONrb, AFC, TAD1, TAD2);
-xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: status: OSCILLATOR:%s PLL1:%s PLL2:%s\n",
- XOK ? "ok":"off", LO1LK ? "locked" : "off" , LO2LK ? "locked" : "off");
-
-}
-
-static void MT2032_tune(FI1236Ptr f, double freq, double step)
-{
-MT2032_parameters m;
-CARD8 data[10];
-int i;
-/* NTSC IF is 44mhz.. but 733/16=45.8125 and all TDAXXXX docs mention
- 45.75, 39, 58.75 and 30. */
-#if 0
-MT2032_calculate_register_settings(&m, freq, 1090.0, 45.125, 5.25, 6.0, step);
-MT2032_calculate_register_settings(&m, freq, 1090.0, 45.74, 5.25, 6.0, step);
-#endif
-MT2032_calculate_register_settings(&m, freq, 1090.0, f->video_if, 5.25, 3.0, step);
-MT2032_dump_parameters(f, &m);
-MT2032_implement_settings(f, &m);
-/* MT2032_dump_parameters(f, &m); */
-for(i=0;i<3;i++){
- MT2032_optimize_VCO(f, &m);
- if(MT2032_wait_for_lock(f)){
- data[0]=0x02; /* LO Gain control register 0x02 */
- data[1]=0x20;
- I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0);
- return;
- }
- data[0]=0x07;
- data[1]=0x88|f->xogc;
- I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0);
- usleep(15000);
- data[1]=0x08|f->xogc;
- I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0);
- }
-xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: failed to set frequency\n");
-}
-
-void FI1236_set_tuner_type(FI1236Ptr f, int type)
-{
-f->type=type;
-if(type>=NUM_TUNERS)type = NUM_TUNERS-1;
-if(type<0)type = 0;
-memcpy(&(f->parm), &(tuner_parms[type]), sizeof(FI1236_parameters));
-f->original_frequency=f->parm.min_freq;
-f->afc_delta=0;
-if(type==TUNER_TYPE_MT2032){
- MT2032_init(f);
- return;
- }
-}
-
-
-static CARD32 AFC_TimerCallback(OsTimerPtr timer, CARD32 time, pointer data){
-FI1236Ptr f=(FI1236Ptr)data;
-if(FI1236_AFC(f))return 150;
- else {
- f->afc_timer_installed=FALSE;
- f->afc_count=0;
- return 0;
- }
-}
-
-void FI1236_tune(FI1236Ptr f, CARD32 frequency)
-{
- CARD16 divider;
- CARD8 data;
-
- if(frequency < f->parm.min_freq) frequency = f->parm.min_freq;
- if(frequency > f->parm.max_freq) frequency = f->parm.max_freq;
-
- divider = (f->parm.fcar+(CARD16)frequency) & 0x7fff;
- f->tuner_data.div1 = (CARD8)((divider>>8)&0x7f);
- f->tuner_data.div2 = (CARD8)(divider & 0xff);
- f->tuner_data.control = f->parm.control;
-
- if(frequency < f->parm.threshold1)
- {
- f->tuner_data.band = f->parm.band_low;
- }
- else if (frequency < f->parm.threshold2)
- {
- f->tuner_data.band = f->parm.band_mid;
- }
- else
- {
- f->tuner_data.band = f->parm.band_high;
- }
-
- xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "Setting tuner band to %d\n", f->tuner_data.band);
-
- xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "Setting tuner frequency to %d\n", (int)frequency);
-
- if ((f->type == TUNER_TYPE_FM1216ME) || (f->type == TUNER_TYPE_FI1236W))
- {
- f->tuner_data.aux = 0x20;
- I2C_WriteRead(&(f->d), (I2CByte *)&(f->tuner_data), 5, NULL, 0);
- I2C_WriteRead(&(f->d), NULL, 0, &data, 1);
- xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "Tuner status %x\n", data);
-
- }
- else
- I2C_WriteRead(&(f->d), (I2CByte *)&(f->tuner_data), 4, NULL, 0);
-}
-
-void TUNER_set_frequency(FI1236Ptr f, CARD32 frequency)
-{
- if(frequency < f->parm.min_freq) frequency = f->parm.min_freq;
- if(frequency > f->parm.max_freq) frequency = f->parm.max_freq;
-
- f->afc_delta=0;
- f->original_frequency=frequency;
-
- if(f->type==TUNER_TYPE_MT2032)
- {
- MT2032_tune(f, (1.0*frequency)/16.0, 0.0625);
- } else
- {
- FI1236_tune(f, frequency);
- }
-
- if(!f->afc_timer_installed)
- {
- f->afc_timer_installed=TRUE;
-/* RegisterBlockAndWakeupHandlers(FI1236_BlockHandler, AFCWakeup, f); */
- TimerSet(NULL, 0, 300, AFC_TimerCallback, f);
- }
-
-}
-
-
-int FI1236_AFC(FI1236Ptr f)
-{
- #if 0
- xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC: f=%p f->count=%d f->original_frequency=%d f->afc_delta=%d\n", f, f->afc_count, f->original_frequency, f->afc_delta);
- #endif
- f->afc_count++;
- if(f->type==TUNER_TYPE_MT2032)
- {
- f->last_afc_hint=MT2032_get_afc_hint(f);
- xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC: afc_hint=%d\n", f->last_afc_hint);
- if(f->last_afc_hint==TUNER_TUNED)return 0;
- if(f->afc_count>3)f->last_afc_hint=TUNER_OFF;
- if(f->last_afc_hint==TUNER_OFF)
- {
- f->afc_delta=0;
- } else
- f->afc_delta+=f->last_afc_hint;
- xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC: Setting tuner frequency to %g\n", (0.5*(2*f->original_frequency+f->afc_delta))/16.0);
- MT2032_tune(f, (1.0*f->original_frequency+0.5*f->afc_delta)/16.0, 0.03125);
- if(f->last_afc_hint==TUNER_OFF)return 0;
- return 1; /* call me again */
- } else
- {
- f->last_afc_hint=FI1236_get_afc_hint(f);
- if(f->last_afc_hint==TUNER_TUNED)
- {
- xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC: TUNER_TUNNED\n");
- return 0;
- }
- if(f->afc_count>3)f->last_afc_hint=TUNER_OFF;
- if(f->last_afc_hint==TUNER_OFF)
- {
- f->afc_delta=0;
- } else
- f->afc_delta+=f->last_afc_hint;
- xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC: Setting tuner frequency to %g\n", (0.5*(2*f->original_frequency+f->afc_delta))/16.0);
- FI1236_tune(f, f->original_frequency+f->afc_delta);
- if(f->last_afc_hint==TUNER_OFF)return 0;
- return 1; /* call me again */
- }
- return 0; /* done */
-}
-
-void fi1236_dump_status(FI1236Ptr f)
-{
-if(f->type==TUNER_TYPE_MT2032){
- MT2032_dump_status(f);
- }
-}
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "xf86.h"
+#include "xf86i2c.h"
+#include "fi1236.h"
+#include "tda9885.h"
+#include "i2c_def.h"
+
+#define NUM_TUNERS 8
+
+const FI1236_parameters tuner_parms[NUM_TUNERS] =
+{
+ /* 0 - FI1236 */
+ { 733 ,884 ,12820 ,2516 ,7220 ,0xA2 ,0x94, 0x34, 0x8e },
+ /* !!!based on documentation - it should be:
+ {733 ,16*55.25 ,16*801.25 ,16*160 ,16*454 ,0xA0 ,0x90, 0x30, 0x8e},*/
+
+ /* 1 - FI1216 */
+ { 623 ,16*48.75 ,16*855.25 ,16*170 ,16*450 ,0xA0 ,0x90, 0x30, 0x8e },
+ /* 2 - TEMIC FN5AL */
+ { 623 ,16*45.75 ,16*855.25 ,16*169 ,16*454 ,0xA0 ,0x90, 0x30, 0x8e },
+ /* 3 - MT2032.. */
+ { 733 ,768 ,13760 , 0 , 0 , 0 , 0, 0, 0 },
+ /* 4 - FI1246 */
+ { 623 ,16*45.75 ,16*855.25 ,16*170 ,16*450 ,0xA0 ,0x90, 0x30, 0x8e },
+ /* 5 - FI1256 */
+ { 623 ,16*49.75 ,16*863.25 ,16*170 ,16*450 ,0xA0 ,0x90, 0x30, 0x8e },
+ /* 6 - FI1236W */
+ /*{ 733 ,884 ,12820 ,2516 ,7220 ,0x1 ,0x2, 0x4, 0x8e },*/
+ { 732, 16*55.25, 16*801.25, 16*160, 16*442, 0x1, 0x2, 0x4, 0x8e },
+ /* 7 - FM1216ME */
+ { 623 ,16*48.25 ,16*863.25 ,16*158.00 ,16*442.00 ,0x1 ,0x2, 0x4, 0x8e }
+};
+
+
+FI1236Ptr Detect_FI1236(I2CBusPtr b, I2CSlaveAddr addr)
+{
+ FI1236Ptr f;
+ I2CByte a;
+
+ f = calloc(1,sizeof(FI1236Rec));
+ if(f == NULL) return NULL;
+ f->d.DevName = strdup("FI12xx Tuner");
+ f->d.SlaveAddr = addr;
+ f->d.pI2CBus = b;
+ f->d.NextDev = NULL;
+ f->d.StartTimeout = b->StartTimeout;
+ f->d.BitTimeout = b->BitTimeout;
+ f->d.AcknTimeout = b->AcknTimeout;
+ f->d.ByteTimeout = b->ByteTimeout;
+ f->type=TUNER_TYPE_FI1236;
+ f->afc_timer_installed=FALSE;
+ f->last_afc_hint=TUNER_OFF;
+ f->video_if=45.7812;
+
+ if(!I2C_WriteRead(&(f->d), NULL, 0, &a, 1))
+ {
+ free(f);
+ return NULL;
+ }
+ FI1236_set_tuner_type(f, TUNER_TYPE_FI1236);
+ if(!I2CDevInit(&(f->d)))
+ {
+ free(f);
+ return NULL;
+ }
+ return f;
+}
+
+static void MT2032_dump_parameters(FI1236Ptr f, MT2032_parameters *m)
+{
+xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: input f_rf=%g f_if1=%g f_if2=%g f_ref=%g f_ifbw=%g f_step=%g\n",
+ m->f_rf, m->f_if1, m->f_if2, m->f_ref, m->f_ifbw, m->f_step);
+
+xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: computed f_lo1=%g f_lo2=%g LO1I=%d LO2I=%d SEL=%d STEP=%d NUM=%d\n",
+ m->f_lo1, m->f_lo2, m->LO1I, m->LO2I, m->SEL, m->STEP, m->NUM);
+}
+
+
+static void MT2032_getid(FI1236Ptr f)
+{
+CARD8 out[4];
+CARD8 in;
+
+in=0x11;
+I2C_WriteRead(&(f->d), (I2CByte *)&in, 1, out, 4);
+xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: Company code 0x%02x%02x, part code 0x%02x, revision code 0x%02x\n",
+ out[0], out[1], out[2], out[3]);
+
+}
+
+/* might be buggy */
+#if 0
+static void MT2032_shutdown(FI1236Ptr f)
+{
+CARD8 data[10];
+
+data[0]=0x00; /* start with register 0x00 */
+data[1]=0x1A;
+data[2]=0x44;
+data[3]=0x20;
+
+I2C_WriteRead(&(f->d), (I2CByte *)data, 4, NULL, 0);
+
+data[0]=0x05; /* now start with register 0x05 */
+data[1]=0xD7;
+data[2]=0x14;
+data[3]=0x05;
+I2C_WriteRead(&(f->d), (I2CByte *)data, 4, NULL, 0);
+
+data[0]=0x0B; /* now start with register 0x05 */
+data[1]=0x8F;
+data[2]=0x07;
+data[3]=0x43;
+I2C_WriteRead(&(f->d), (I2CByte *)data, 4, NULL, 0);
+
+usleep(15000);
+}
+#endif
+
+static void MT2032_dump_status(FI1236Ptr f);
+
+static void MT2032_init(FI1236Ptr f)
+{
+CARD8 data[10];
+CARD8 value;
+CARD8 xogc = 0x00;
+
+MT2032_getid(f);
+
+data[0]=0x02; /* start with register 0x02 */
+data[1]=0xFF;
+data[2]=0x0F;
+data[3]=0x1F;
+
+I2C_WriteRead(&(f->d), (I2CByte *)data, 4, NULL, 0);
+
+data[0]=0x06; /* now start with register 0x06 */
+data[1]=0xE4;
+data[2]=0x8F;
+data[3]=0xC3;
+data[4]=0x4E;
+data[5]=0xEC;
+I2C_WriteRead(&(f->d), (I2CByte *)data, 6, NULL, 0);
+
+data[0]=0x0d; /* now start with register 0x0d */
+data[1]=0x32;
+I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0);
+
+while(1) {
+ usleep(15000); /* wait 15 milliseconds */
+
+ data[0]=0x0e; /* register number 7, status */
+ value=0xFF;
+ if(!I2C_WriteRead(&(f->d), (I2CByte *)data, 1, &value, 1))
+ xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: failed to read XOK\n");
+ xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: XOK=%d\n", value & 0x01);
+ if(value & 1) break;
+
+ data[0]=0x07;
+ if(!I2C_WriteRead(&(f->d), (I2CByte *)data, 1, &value, 1))
+ xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: failed to read XOGC\n");
+
+ xogc=value & 0x7;
+ if(xogc==4){
+ break; /* XOGC has reached 4.. stop */
+ }
+ xogc--;
+ xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: try XOGC=%d\n", xogc);
+ usleep(15000);
+ data[0]=0x07; /* register number 7, control byte 2 */
+ data[1]=0x08 | xogc;
+ I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0);
+ }
+f->xogc=xogc;
+/* wait before continuing */
+usleep(15000); /* wait 50 milliseconds */
+MT2032_dump_status(f);
+}
+
+static int MT2032_no_spur_in_band(MT2032_parameters *m)
+{
+int n_max, n1, n2;
+double f_test;
+n_max=5;
+n1=1;
+while(1){
+ n2=-n1;
+ f_test=n1*(m->f_lo1-m->f_lo2);
+ while(1){
+ n2--;
+ f_test=f_test-m->f_lo2;
+ xf86DrvMsg(0, X_INFO, "testing f_test=%g n1=%d n2=%d f_lo1=%g f_lo2=%g f_if2=%g\n", f_test, n1, n2, m->f_lo1, m->f_lo2, m->f_if2);
+ xf86DrvMsg(0, X_INFO, "d_f=%g f_ifbw=%g\n",fabs(fabs(f_test)-m->f_if2), m->f_ifbw);
+ if((fabs(fabs(f_test)-m->f_if2)*2.0)<=m->f_ifbw)return 0;
+ if(n2<=-n_max)break;
+ /* this line in the manual is bogus. I say it is faster
+ and more correct to go over all harmonics.. */
+ #if 0
+ if(f_test<(m->f_lo2-m->f_if2-m->f_ifbw))break;
+ #endif
+ }
+ n1++;
+ if(n1>=n_max)return 1;
+ }
+
+}
+
+static void MT2032_calculate_register_settings(MT2032_parameters *m, double f_rf, double f_if1, double f_if2, double f_ref, double f_ifbw, double f_step)
+{
+int n;
+m->f_rf=f_rf;
+m->f_if1=f_if1;
+m->f_if2=f_if2;
+m->f_ref=f_ref;
+m->f_ifbw=f_ifbw;
+m->f_step=f_step;
+
+m->f_lo1=f_rf+f_if1;
+m->LO1I=lrint(m->f_lo1/f_ref);
+m->f_lo1=f_ref*m->LO1I;
+
+m->f_lo2=m->f_lo1-f_rf-f_if2;
+
+/* check for spurs */
+n=1;
+while(n<3){
+ if(MT2032_no_spur_in_band(m))break;
+ if(m->f_lo1<(f_rf+f_if1)){
+ m->LO1I+=n;
+ } else {
+ m->LO1I-=n;
+ }
+ m->f_lo1=m->LO1I*f_ref;
+ m->f_lo2=m->f_lo1-f_rf-f_if2;
+ n++;
+ }
+/* xf86DrvMsg(0, X_INFO, "MT2032: n=%d\n", n); */
+/* select VCO */
+
+/* m->f_lo1>1100.0 */
+if(m->f_lo1<1370.0)m->SEL=4;
+ else
+if(m->f_lo1<1530.0)m->SEL=3;
+ else
+if(m->f_lo1<1720.0)m->SEL=2;
+ else
+if(m->f_lo1<1890.0)m->SEL=1;
+ else /* m->f_lo1 < 1958.0 */
+ m->SEL=0;
+
+/* calculate the rest of the registers */
+m->LO2I=floor(m->f_lo2/f_ref);
+m->STEP=floor(3780.0*f_step/f_ref);
+m->NUM=floor(3780.0*(m->f_lo2/f_ref-m->LO2I));
+m->NUM=m->STEP*lrint((1.0*m->NUM)/(1.0*m->STEP));
+}
+
+static int MT2032_wait_for_lock(FI1236Ptr f)
+{
+int n;
+CARD8 data[10];
+CARD8 value;
+
+n=12;
+while(1){
+ data[0]=0x0e; /* register number 7, status */
+ I2C_WriteRead(&(f->d), (I2CByte *)data, 1, &value, 1);
+/* xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: LO1LK=%d LO2LK=%d\n", (value & 0x04)>>2, (value & 0x02)>>1); */
+ if((value & 6)==6) break;
+ usleep(1500);
+ n--;
+ if(n<0)break;
+ }
+if(n<0){
+ xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: failed to set frequency\n");
+ return 0;
+ }
+return 1;
+}
+
+static void MT2032_implement_settings(FI1236Ptr f, MT2032_parameters *m)
+{
+CARD8 data[10];
+CARD8 value;
+
+data[0]=0x00; /* start with register 0x00 */
+data[1]=(m->LO1I>>3)-1;
+data[2]=(m->SEL<<4)|(m->LO1I & 0x7);
+data[3]=0x86;
+I2C_WriteRead(&(f->d), (I2CByte *)data, 4, NULL, 0);
+
+data[0]=0x05; /* start with register 0x05 */
+data[1]=((m->LO2I & 0x7)<<5)|((m->LO2I>>3)-1);
+if(m->f_rf<400.0)data[2]=0xe4;
+ else data[2]=0xf4;
+I2C_WriteRead(&(f->d), (I2CByte *)data, 3, NULL, 0);
+
+data[0]=0x07; /* register number 7, control byte 2 */
+I2C_WriteRead(&(f->d), (I2CByte *)data, 1, &value, 1);
+xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: using XOGC=%d\n", (value & 0x07));
+data[1]=8 | (value & 0x7);
+I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0);
+
+data[0]=0x0b; /* start with register 0x0b */
+data[1]=m->NUM & 0xff;
+data[2]=(1<<7)|((m->NUM >> 8) & 0x0f);
+I2C_WriteRead(&(f->d), (I2CByte *)data, 3, NULL, 0);
+
+MT2032_wait_for_lock(f);
+}
+
+static void MT2032_optimize_VCO(FI1236Ptr f, MT2032_parameters *m)
+{
+CARD8 data[10];
+CARD8 value;
+CARD8 TAD1;
+
+data[0]=0x0f; /* register number 7, status */
+I2C_WriteRead(&(f->d), (I2CByte *)data, 1, &value, 1);
+TAD1=value & 0x07;
+xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: TAD1=%d SEL=%d\n", TAD1, m->SEL);
+if(TAD1 < 2)return;
+if(TAD1==2){
+ if(m->SEL==0)return;
+ m->SEL--;
+ } else {
+ if(m->SEL>=4)return;
+ m->SEL++;
+ }
+data[0]=0x01; /* start with register 1 */
+data[1]=(m->SEL<<4)|(m->LO1I & 0x7);
+I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0);
+
+}
+
+static int FI1236_get_afc_hint(FI1236Ptr f)
+{
+ CARD8 out;
+ CARD8 AFC;
+
+ if ((f->type == TUNER_TYPE_FM1216ME) || (f->type == TUNER_TYPE_FI1236W))
+ {
+ TDA9885Ptr t = (TDA9885Ptr)f->afc_source;
+ if (t == NULL)
+ return TUNER_OFF;
+
+ tda9885_getstatus(t);
+ tda9885_dumpstatus(t);
+ AFC = t->afc_status & 0x0f;
+
+ xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC: FI1236_get_afc_hint: %i\n", AFC);
+ if (AFC == 0) return TUNER_TUNED;
+ else if (AFC <= 0x07)return TUNER_JUST_BELOW;
+ else if (AFC < 0x0f )return TUNER_JUST_ABOVE;
+ else if (AFC == 0x0f)return TUNER_TUNED;
+ }
+ else
+ {
+ I2C_WriteRead(&(f->d), NULL, 0, &out, 1);
+ AFC=out & 0x7;
+ xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC: FI1236_get_afc_hint: %i\n", AFC);
+ if(AFC==2)return TUNER_TUNED;
+ if(AFC==3)return TUNER_JUST_BELOW;
+ if(AFC==1)return TUNER_JUST_ABOVE;
+ return TUNER_OFF;
+ }
+ return TUNER_OFF;
+}
+
+static int MT2032_get_afc_hint(FI1236Ptr f)
+{
+CARD8 in;
+CARD8 out[2];
+CARD8 AFC;
+in=0x0e;
+I2C_WriteRead(&(f->d), (I2CByte *)&in, 1, out, 2);
+AFC=(out[0]>>4) & 0x7;
+#if 0
+xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC=%d TAD1=%d TAD2=%d\n", AFC, out[1] & 0x7, (out[1]>>4)& 0x07);
+#endif
+if(AFC==2)return TUNER_TUNED;
+if(AFC==3)return TUNER_JUST_BELOW;
+if(AFC==1)return TUNER_JUST_ABOVE;
+return TUNER_OFF;
+}
+
+/* this function is for external use only */
+int TUNER_get_afc_hint(FI1236Ptr f)
+{
+if(f->afc_timer_installed)return TUNER_STILL_TUNING;
+return f->last_afc_hint;
+}
+
+static void MT2032_dump_status(FI1236Ptr f)
+{
+CARD8 in;
+CARD8 out[2];
+CARD8 AFC;
+CARD8 LDONrb;
+CARD8 LO1LK, LO2LK, XOK;
+CARD8 TAD2, TAD1;
+
+in=0x0e;
+I2C_WriteRead(&(f->d), (I2CByte *)&in, 1, out, 2);
+XOK=out[0] & 1;
+LO1LK=(out[0]>>2) &1;
+LO2LK=(out[0]>>1) &1;
+LDONrb=(out[0]>>3) &1;
+
+AFC=(out[0]>>4) & 0x7;
+
+TAD1=(out[1] & 0x7);
+TAD2=(out[1]>>4) & 0x7;
+
+xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: status: XOK=%d LO1LK=%d LO2LK=%d LDONrb=%d AFC=%d TAD1=%d TAD2=%d\n",
+ XOK, LO1LK, LO2LK, LDONrb, AFC, TAD1, TAD2);
+xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: status: OSCILLATOR:%s PLL1:%s PLL2:%s\n",
+ XOK ? "ok":"off", LO1LK ? "locked" : "off" , LO2LK ? "locked" : "off");
+
+}
+
+static void MT2032_tune(FI1236Ptr f, double freq, double step)
+{
+MT2032_parameters m;
+CARD8 data[10];
+int i;
+/* NTSC IF is 44mhz.. but 733/16=45.8125 and all TDAXXXX docs mention
+ 45.75, 39, 58.75 and 30. */
+#if 0
+MT2032_calculate_register_settings(&m, freq, 1090.0, 45.125, 5.25, 6.0, step);
+MT2032_calculate_register_settings(&m, freq, 1090.0, 45.74, 5.25, 6.0, step);
+#endif
+MT2032_calculate_register_settings(&m, freq, 1090.0, f->video_if, 5.25, 3.0, step);
+MT2032_dump_parameters(f, &m);
+MT2032_implement_settings(f, &m);
+/* MT2032_dump_parameters(f, &m); */
+for(i=0;i<3;i++){
+ MT2032_optimize_VCO(f, &m);
+ if(MT2032_wait_for_lock(f)){
+ data[0]=0x02; /* LO Gain control register 0x02 */
+ data[1]=0x20;
+ I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0);
+ return;
+ }
+ data[0]=0x07;
+ data[1]=0x88|f->xogc;
+ I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0);
+ usleep(15000);
+ data[1]=0x08|f->xogc;
+ I2C_WriteRead(&(f->d), (I2CByte *)data, 2, NULL, 0);
+ }
+xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "MT2032: failed to set frequency\n");
+}
+
+void FI1236_set_tuner_type(FI1236Ptr f, int type)
+{
+f->type=type;
+if(type>=NUM_TUNERS)type = NUM_TUNERS-1;
+if(type<0)type = 0;
+memcpy(&(f->parm), &(tuner_parms[type]), sizeof(FI1236_parameters));
+f->original_frequency=f->parm.min_freq;
+f->afc_delta=0;
+if(type==TUNER_TYPE_MT2032){
+ MT2032_init(f);
+ return;
+ }
+}
+
+
+static CARD32 AFC_TimerCallback(OsTimerPtr timer, CARD32 time, pointer data){
+FI1236Ptr f=(FI1236Ptr)data;
+if(FI1236_AFC(f))return 150;
+ else {
+ f->afc_timer_installed=FALSE;
+ f->afc_count=0;
+ return 0;
+ }
+}
+
+void FI1236_tune(FI1236Ptr f, CARD32 frequency)
+{
+ CARD16 divider;
+ CARD8 data;
+
+ if(frequency < f->parm.min_freq) frequency = f->parm.min_freq;
+ if(frequency > f->parm.max_freq) frequency = f->parm.max_freq;
+
+ divider = (f->parm.fcar+(CARD16)frequency) & 0x7fff;
+ f->tuner_data.div1 = (CARD8)((divider>>8)&0x7f);
+ f->tuner_data.div2 = (CARD8)(divider & 0xff);
+ f->tuner_data.control = f->parm.control;
+
+ if(frequency < f->parm.threshold1)
+ {
+ f->tuner_data.band = f->parm.band_low;
+ }
+ else if (frequency < f->parm.threshold2)
+ {
+ f->tuner_data.band = f->parm.band_mid;
+ }
+ else
+ {
+ f->tuner_data.band = f->parm.band_high;
+ }
+
+ xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "Setting tuner band to %d\n", f->tuner_data.band);
+
+ xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "Setting tuner frequency to %d\n", (int)frequency);
+
+ if ((f->type == TUNER_TYPE_FM1216ME) || (f->type == TUNER_TYPE_FI1236W))
+ {
+ f->tuner_data.aux = 0x20;
+ I2C_WriteRead(&(f->d), (I2CByte *)&(f->tuner_data), 5, NULL, 0);
+ I2C_WriteRead(&(f->d), NULL, 0, &data, 1);
+ xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "Tuner status %x\n", data);
+
+ }
+ else
+ I2C_WriteRead(&(f->d), (I2CByte *)&(f->tuner_data), 4, NULL, 0);
+}
+
+void TUNER_set_frequency(FI1236Ptr f, CARD32 frequency)
+{
+ if(frequency < f->parm.min_freq) frequency = f->parm.min_freq;
+ if(frequency > f->parm.max_freq) frequency = f->parm.max_freq;
+
+ f->afc_delta=0;
+ f->original_frequency=frequency;
+
+ if(f->type==TUNER_TYPE_MT2032)
+ {
+ MT2032_tune(f, (1.0*frequency)/16.0, 0.0625);
+ } else
+ {
+ FI1236_tune(f, frequency);
+ }
+
+ if(!f->afc_timer_installed)
+ {
+ f->afc_timer_installed=TRUE;
+/* RegisterBlockAndWakeupHandlers(FI1236_BlockHandler, AFCWakeup, f); */
+ TimerSet(NULL, 0, 300, AFC_TimerCallback, f);
+ }
+
+}
+
+
+int FI1236_AFC(FI1236Ptr f)
+{
+ #if 0
+ xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC: f=%p f->count=%d f->original_frequency=%d f->afc_delta=%d\n", f, f->afc_count, f->original_frequency, f->afc_delta);
+ #endif
+ f->afc_count++;
+ if(f->type==TUNER_TYPE_MT2032)
+ {
+ f->last_afc_hint=MT2032_get_afc_hint(f);
+ xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC: afc_hint=%d\n", f->last_afc_hint);
+ if(f->last_afc_hint==TUNER_TUNED)return 0;
+ if(f->afc_count>3)f->last_afc_hint=TUNER_OFF;
+ if(f->last_afc_hint==TUNER_OFF)
+ {
+ f->afc_delta=0;
+ } else
+ f->afc_delta+=f->last_afc_hint;
+ xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC: Setting tuner frequency to %g\n", (0.5*(2*f->original_frequency+f->afc_delta))/16.0);
+ MT2032_tune(f, (1.0*f->original_frequency+0.5*f->afc_delta)/16.0, 0.03125);
+ if(f->last_afc_hint==TUNER_OFF)return 0;
+ return 1; /* call me again */
+ } else
+ {
+ f->last_afc_hint=FI1236_get_afc_hint(f);
+ if(f->last_afc_hint==TUNER_TUNED)
+ {
+ xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC: TUNER_TUNNED\n");
+ return 0;
+ }
+ if(f->afc_count>3)f->last_afc_hint=TUNER_OFF;
+ if(f->last_afc_hint==TUNER_OFF)
+ {
+ f->afc_delta=0;
+ } else
+ f->afc_delta+=f->last_afc_hint;
+ xf86DrvMsg(f->d.pI2CBus->scrnIndex, X_INFO, "AFC: Setting tuner frequency to %g\n", (0.5*(2*f->original_frequency+f->afc_delta))/16.0);
+ FI1236_tune(f, f->original_frequency+f->afc_delta);
+ if(f->last_afc_hint==TUNER_OFF)return 0;
+ return 1; /* call me again */
+ }
+ return 0; /* done */
+}
+
+void fi1236_dump_status(FI1236Ptr f)
+{
+if(f->type==TUNER_TYPE_MT2032){
+ MT2032_dump_status(f);
+ }
+}
diff --git a/xorg-server/hw/xfree86/i2c/msp3430.c b/xorg-server/hw/xfree86/i2c/msp3430.c
index 4bd3a7187..b58c3f09c 100644
--- a/xorg-server/hw/xfree86/i2c/msp3430.c
+++ b/xorg-server/hw/xfree86/i2c/msp3430.c
@@ -1,726 +1,726 @@
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <string.h>
-#include <unistd.h>
-
-#include "xf86.h"
-#include "xf86i2c.h"
-#include "msp3430.h"
-#include "i2c_def.h"
-
-#define CONTROL 0x00
-#define WR_DEM 0x10
-#define RD_DEM 0x11
-#define WR_DSP 0x12
-#define RD_DSP 0x13
-
-
-void InitMSP34xxG(MSP3430Ptr m);
-void InitMSP34x5D(MSP3430Ptr m);
-void CheckModeMSP34x5D(MSP3430Ptr m);
-char *MSP_getProductName (CARD16 product_id);
-void mpause(int milliseconds);
-
-#define __MSPDEBUG__ 0
-
-#if __MSPDEBUG__ > 3
-
-void MSPBeep(MSP3430Ptr m, CARD8 freq);
-#define __MSPBEEP MSPBeep(m,0x14);
-
-#else
-
-#define __MSPBEEP
-#endif
-
-static void SetMSP3430Control(MSP3430Ptr m, CARD8 RegAddress, CARD8 RegValueHigh, CARD8 RegValueLow)
-{
- I2CByte data[3];
-
- data[0]=RegAddress;
- data[1]=RegValueHigh;
- data[2]=RegValueLow;
-
- I2C_WriteRead(&(m->d),data,3,NULL,0);
-}
-
-static void SetMSP3430Data(MSP3430Ptr m, CARD8 RegAddress, CARD8 RegSubAddressHigh, CARD8 RegSubAddressLow,
- CARD8 RegValueHigh, CARD8 RegValueLow)
-{
- I2CByte data[5];
-#ifdef MSP_DEBUG
- if(!m->registers_present[RegSubAddressLow]){
- xf86DrvMsg(m->d.pI2CBus->scrnIndex,X_ERROR, "Attempt to access non-existent register in MSP34xxX: 0x%02x 0x%02x 0x%02x <- 0x%02x 0x%02x\n",
- RegAddress, RegSubAddressHigh, RegSubAddressLow, RegValueHigh, RegValueLow);
- }
-#endif
-
- data[0] = RegAddress;
- data[1] = RegSubAddressHigh;
- data[2] = RegSubAddressLow;
- data[3] = RegValueHigh;
- data[4] = RegValueLow;
-
- I2C_WriteRead(&(m->d),data,5,NULL,0);
-}
-
-static void GetMSP3430Data(MSP3430Ptr m, CARD8 RegAddress, CARD8 RegSubAddressHigh, CARD8 RegSubAddressLow,
- CARD8 *RegValueHigh, CARD8 *RegValueLow)
-{
- I2CByte send[3];
- I2CByte receive[2];
-
- send[0] = RegAddress;
- send[1] = RegSubAddressHigh;
- send[2] = RegSubAddressLow;
-
- I2C_WriteRead(&(m->d), send, 3, receive, 2);
-
- *RegValueHigh = receive[0];
- *RegValueLow = receive[1];
-}
-
-#if __MSPDEBUG__ > 2
-static void MSP3430DumpStatus(MSP3430Ptr m)
-{
-CARD8 status_hi, status_lo;
-CARD8 subaddr, data[2];
-
-GetMSP3430Data(m, RD_DEM, 0x02, 0x00, &status_hi, &status_lo);
-xf86DrvMsg(m->d.pI2CBus->scrnIndex, X_INFO, "MSP34xx: SAP(8)=%d mono/NICAM(7)=%d stereo=%d %s O_1=%d O_0=%d 2nd car=%d 1st car=%d\n",
- status_hi & 1, (status_lo>>7) & 1, (status_lo>>6)&1,
- (status_lo>>5)? ( (status_hi>>1)&1? "bad NICAM reception" : "NICAM" ) :
- ((status_hi>>1)&1 ? "bogus" : "ANALOG FM/AM") ,
- (status_lo>>4)&1, (status_lo>>3)&1,!( (status_lo>>2)&1), !((status_lo>>1)&1));
-
-GetMSP3430Data(m, RD_DEM, 0x00, 0x7E, &status_hi, &status_lo);
-xf86DrvMsg(m->d.pI2CBus->scrnIndex, X_INFO, "MSP34xx: standard result=0x%02x%02x\n",
- status_hi, status_lo);
-subaddr=0x0;
-I2C_WriteRead(&(m->d), &subaddr, 1, data, 2);
-xf86DrvMsg(m->d.pI2CBus->scrnIndex, X_INFO, "MSP34xx: control=0x%02x%02x\n",
- data[1], data[0]);
-}
-#endif
-
-/* wrapper */
-void InitMSP3430(MSP3430Ptr m)
-{
- #if __MSPDEBUG__ > 1
- xf86DrvMsg(m->d.pI2CBus->scrnIndex,X_INFO,"InitMSP3430(m->connector=%d, m->standard=%d, m->chip_family=%d)\n",
- m->connector, m->standard, m->chip_family);
- #endif
- switch (m->chip_family) {
- case MSPFAMILY_34x0G:
- InitMSP34xxG(m);
- break;
- case MSPFAMILY_34x5G:
- InitMSP34xxG(m);
- break;
- case MSPFAMILY_34x5D:
- InitMSP34x5D(m);
- break;
- }
-}
-
-/*-----------------------------------------------------------------
-| common functions for all MSP34xx chips
-|----------------------------------------------------------------*/
-
-MSP3430Ptr DetectMSP3430(I2CBusPtr b, I2CSlaveAddr addr)
-{
- MSP3430Ptr m;
- I2CByte a;
- CARD8 hardware_version, major_revision, product_code, rom_version;
- Bool supported;
-
- m = xcalloc(1,sizeof(MSP3430Rec));
- if(m == NULL)return NULL;
- m->d.DevName = strdup("MSP34xx");
- m->d.SlaveAddr = addr;
- m->d.pI2CBus = b;
- m->d.NextDev = NULL;
- m->d.StartTimeout = b->StartTimeout;
- m->d.BitTimeout = b->BitTimeout;
- m->d.AcknTimeout = b->AcknTimeout;
- m->d.ByteTimeout = b->ByteTimeout;
-
- if(!I2C_WriteRead(&(m->d), NULL, 0, &a, 1))
- {
- xfree(m->d.DevName);
- xfree(m);
- return NULL;
- }
-
-
- m->standard=MSP3430_NTSC;
- m->connector=MSP3430_CONNECTOR_1;
- m->mode=MSPMODE_STEREO_A; /*stereo or chanel A if avail. */
- m->c_format=MSPFORMAT_UNKNOWN;
- m->c_standard=MSPSTANDARD_UNKNOWN;
- m->c_matrix=m->c_fmmatrix=m->c_source=0;
- m->volume=0;
- m->recheck=FALSE;
-
- GetMSP3430Data(m, RD_DSP, 0x00, 0x1E, &hardware_version, &major_revision);
- GetMSP3430Data(m, RD_DSP, 0x00, 0x1F, &product_code, &rom_version);
- m->hardware_version=hardware_version;
- m->major_revision=major_revision;
- m->product_code=product_code;
- m->rom_version=rom_version;
-
- m->chip_id=((major_revision << 8) | product_code);
-
- supported=FALSE;
- switch (major_revision) {
- case 4: /* 34xxD */
- switch (product_code) {
- case 0x05: /* 3405D */
- case 0x0A: /* 3410D */
- case 0x0F: /* 3415D */
- m->chip_family=MSPFAMILY_34x5D;
- m->recheck=TRUE;
- supported=TRUE;
- break;
- default:
- m->chip_family=MSPFAMILY_34x0D;
- }
- break;
- case 7: /* 34xxG */
- switch(product_code){
- case 0x00:
- case 0x0A:
- case 0x1E:
- case 0x28:
- case 0x32:
- m->chip_family=MSPFAMILY_34x0G;
- supported=TRUE;
- break;
- case 0x0f:
- case 0x19:
- case 0x2d:
- case 0x37:
- case 0x41:
- m->chip_family=MSPFAMILY_34x5G;
- supported=TRUE;
- #ifdef MSP_DEBUG
- memset(m->registers_present, 0, 256);
- #define A(num) m->registers_present[(num)]=1;
- #define B(num1, num2) memset(&(m->registers_present[num1]), 1, num2-num1);
- A(0x20)
- A(0x30)
- A(0x40)
- A(0x00)
- B(0x01, 0x08)
- B(0x0B, 0x0E)
- A(0x10)
- B(0x12,0x14)
- A(0x16)
- A(0x29)
- #undef B
- #undef A
- #endif
- break;
- default:
- m->chip_family=MSPFAMILY_UNKNOWN;
- }
- break;
- default:
- m->chip_family=MSPFAMILY_UNKNOWN;
- }
-
- xf86DrvMsg(m->d.pI2CBus->scrnIndex, X_INFO, "Found %s%s, rom version 0x%02x, chip_id=0x%04x\n",
- MSP_getProductName(m->chip_id), supported?"":" (unsupported)", rom_version, m->chip_id);
-
- if (!supported) {
- xfree(m->d.DevName);
- xfree(m);
- return NULL;
- }
- if(!I2CDevInit(&(m->d)))
- {
- xfree(m->d.DevName);
- xfree(m);
- return NULL;
- }
-
- return m;
-}
-
-void ResetMSP3430(MSP3430Ptr m)
-{
- /* Reset the MSP3430 */
- SetMSP3430Control(m, 0x00, 0x80, 0x00);
- /* Set it back to normal operation */
- SetMSP3430Control(m, 0x00, 0x00, 0x00);
-
- m->c_format=MSPFORMAT_UNKNOWN;
- m->c_standard=MSPSTANDARD_UNKNOWN;
- m->c_matrix=m->c_fmmatrix=m->c_source=0;
- m->volume=0;
-}
-
-void MSP3430SetVolume (MSP3430Ptr m, CARD8 value)
-{
- CARD8 result;
-#if 0
- CARD8 old_volume;
- GetMSP3430Data(m, RD_DSP, 0x00, 0x00, &old_volume, &result);
- xf86DrvMsg(m->d.pI2CBus->scrnIndex, X_INFO, "MSP3430 result 0x%02x\n", result);
-#endif
- /* save an extra Get call */
- result=0;
-
- SetMSP3430Data(m, WR_DSP, 0x00, 0x00, value, result);
-
- SetMSP3430Data(m, WR_DSP, 0x00, 0x07, value, 0);
- m->volume=value;
-
-#if __MSPDEBUG__ > 2
- MSP3430DumpStatus(m);
- __MSPBEEP
- GetMSP3430Data(m, RD_DSP, 0x00, 0x00, &old_volume, &result);
- xf86DrvMsg(m->d.pI2CBus->scrnIndex, X_INFO, "MSP3430 volume 0x%02x\n",value);
-#endif
-}
-
-
-void MSP3430SetSAP (MSP3430Ptr m, int mode)
-{
- xf86DrvMsg(m->d.pI2CBus->scrnIndex, X_INFO, "Put actual code to change SAP here\n");
-
- SetMSP3430Data(m, WR_DSP, 0x00, 0x08, mode & 0xff, 0x20);
-}
-
-
-#if 0
-void MSP3430SetSource(MSP3430Ptr m, CARD8 value)
-{
- /* Write to DSP, register 0x0008, (loudspeaker channel source/matrix) */
- /* This sets the source to the TV tuner, for stereo operation */
- SetMSP3430Data(m, WR_DSP, 0x00, 0x08, value, 0x20);
-}
-#endif
-
-
-char *MSP_getProductName (CARD16 product_id)
-{
- switch (product_id) {
- case 0x0400: return "MSP3400D";
- case 0x040a: return "MSP3410D";
- case 0x0405: return "MSP3405D";
- case 0x040f: return "MSP3415D";
- case 0x0700: return "MSP3400G";
- case 0x070a: return "MSP3410G";
- case 0x071e: return "MSP3430G";
- case 0x0728: return "MSP3440G";
- case 0x0732: return "MSP3450G";
- case 0x070f: return "MSP3415G";
- case 0x0719: return "MSP3425G";
- case 0x072d: return "MSP3445G";
- case 0x0737: return "MSP3455G";
- case 0x0741: return "MSP3465G";
- }
- return "MSP - unknown type";
-}
-
-#if __MSPDEBUG__ > 2
-/*puts beep in MSP output
- freq = 0x01 - 16Hz ... 0x40 - 1kHz ... 0xff - 4kHz
-*/
-void MSPBeep(MSP3430Ptr m, CARD8 freq) {
- SetMSP3430Data (m, WR_DSP, 0x00, freq, 0x7f, 0x40);
- mpause(100);
- SetMSP3430Data (m, WR_DSP, 0x00, 0x14, 0x00, 0x00);
-}
-#endif
-
-void mpause(int milliseconds) {
- int i,m;
- m=milliseconds/20;
- for (i=0;i<m;i++) usleep(20000);
-}
-
-/*-----------------------------------------------------------------
-| specific functions for all MSP34xxG chips
-|----------------------------------------------------------------*/
-
-void InitMSP34xxG(MSP3430Ptr m)
-{
-
- #if __MSPDEBUG__ > 1
- xf86DrvMsg(m->d.pI2CBus->scrnIndex,X_INFO,"InitMSP34xxG(m->connector=%d, m->standard=%d, m->chip_family=%d)\n",
- m->connector, m->standard, m->chip_family);
- #endif
- /* Reset MSP3430 */
- SetMSP3430Control(m, 0x00, 0x80, 0x00);
- /* Set it back to normal operation */
- SetMSP3430Control(m, 0x00, 0x00, 0x00);
-
- /*set MODUS register */
- /* bits: 0 - automatic sound detection */
- /* 1 - enable STATUS change */
- /* 12 - detect 6.5 Mhz carrier as D/K1, D/K2 or D/K NICAM (does not seem to work ) */
- /* 13 - detect 4.5 Mhz carrier as BTSC */
- if ( (m->standard & 0xff) == MSP3430_PAL )
- {
- SetMSP3430Data(m, WR_DEM, 0x00, 0x30, 0x30, 0x03|0x08); /* make O_ pins tristate */
- /* PAL standard */
- SetMSP3430Data(m, WR_DEM, 0x00, 0x20, 0x00, 0x01); /* possibly wrong */
- } else {
- SetMSP3430Data(m, WR_DEM, 0x00, 0x30, 0x20, 0x03|0x08);
- /* standard selection is M-BTSC-Stereo */
- SetMSP3430Data(m, WR_DEM, 0x00, 0x20, 0x00, 0x20);
- }
-
- switch(m->connector){
- case MSP3430_CONNECTOR_1:
- SetMSP3430Data(m, WR_DSP, 0x00, 0x08, 0x03, 0x20);
- break;
- case MSP3430_CONNECTOR_2:
- /* this has not been checked yet.. could be bogus */
- /* SCART Input Prescale: 0 dB gain */
- SetMSP3430Data(m, WR_DSP, 0x00, 0x0d, 0x19, 0x00);
- SetMSP3430Data(m, WR_DSP, 0x00, 0x08, 0x02, 0x20);
- break;
- case MSP3430_CONNECTOR_3:
- default:
- /* SCART Input Prescale: 0 dB gain */
- SetMSP3430Data(m, WR_DSP, 0x00, 0x0d, 0x19, 0x00);
-
- SetMSP3430Data(m, WR_DSP, 0x00, 0x08, 0x02, 0x20);
- break;
- }
-
- switch(m->standard){
- case MSP3430_PAL:
- SetMSP3430Data(m, WR_DSP, 0x00, 0x0e, 0x24, 0x03);
- SetMSP3430Data(m, WR_DSP, 0x00, 0x10, 0x00, 0x5a);
- SetMSP3430Data(m, WR_DEM, 0x00, 0x20, 0x00, 0x03);
- /* Set volume to FAST_MUTE. */
- SetMSP3430Data(m, WR_DSP, 0x00, 0x00, 0xFF, 0x00);
- break;
- case MSP3430_PAL_DK1:
- SetMSP3430Data(m, WR_DSP, 0x00, 0x0e, 0x24, 0x03);
- SetMSP3430Data(m, WR_DSP, 0x00, 0x10, 0x00, 0x5a);
- SetMSP3430Data(m, WR_DEM, 0x00, 0x20, 0x00, 0x04);
- /* Set volume to FAST_MUTE. */
- SetMSP3430Data(m, WR_DSP, 0x00, 0x00, 0xFF, 0x00);
- break;
- case MSP3430_SECAM: /* is this right ? */
- case MSP3430_NTSC:
- /* Write to DSP, register 0x000E, (prescale FM/FM matrix) */
- SetMSP3430Data(m, WR_DSP, 0x00, 0x0e, 0x24, 0x03);
-
- /* Set volume to FAST_MUTE. */
- SetMSP3430Data(m, WR_DSP, 0x00, 0x00, 0xFF, 0x00);
- break;
- }
-
-}
-
-/*-----------------------------------------------------------------
-| specific functions for all MSP34x5D chips
-|----------------------------------------------------------------*/
-
-void InitMSP34x5D(MSP3430Ptr m)
-{
-int count;
-CARD8 high,low;
-CARD16 result,standard;
-CARD16 peak;
-
-
-if (m->c_format==MSPFORMAT_UNKNOWN) ResetMSP3430(m);
-else {
- /*mute volume*/
- SetMSP3430Data (m, WR_DSP, 0x00, 0x00, 0x00, 0x00);
-}
-
-
-
- switch(m->connector){
- case MSP3430_CONNECTOR_2:
- case MSP3430_CONNECTOR_3:
- if (m->c_format!=MSPFORMAT_SCART) {
- /* SCART Input Prescale: 0 dB gain */
- SetMSP3430Data (m, WR_DSP, 0x00, 0x0d, 0x19, 0x00);
- /* this has not been checked yet.. could be bogus */
- m->c_format=MSPFORMAT_SCART; /*stereo*/
- }
- break;
- case MSP3430_CONNECTOR_1:
- default:
-
- switch ( m->standard & 0x00ff ) {
- case MSP3430_PAL:
- switch( m->standard ) {
- case MSP3430_PAL_DK1:
- standard=MSPSTANDARD_FM_DK1;
- break;
-/* case MSP3430_PAL_DK2:
- standard=MSPSTANDARD_FM_DK2;
- break;
- case MSP3430_PAL_BG:
- may be FM stereo (Germany) or FM NICAM (Scandinavia,spain)
- standard=MSPSTANDARD_AUTO;
- break;
-*/
- default:
- standard=MSPSTANDARD_AUTO;
- }
- break;
- case MSP3430_SECAM:
- standard=MSPSTANDARD_AUTO;
- case MSP3430_NTSC:
- /* Only MSP34x5 supported format - Korean NTSC-M*/
- standard=MSPSTANDARD_FM_M;
- default:
- standard=MSPSTANDARD_AUTO;
- }
-
- /*no NICAM support in MSP3410D - force to autodetect*/
- if ((m->chip_id==0x405) && (standard>=MSPSTANDARD_NICAM_BG))
- standard=MSPSTANDARD_AUTO;
-
- if (m->c_standard != standard) {
-
- SetMSP3430Data (m, WR_DEM, 0x00, 0x20, standard>>8, standard & 0xFF);
- if (standard==MSPSTANDARD_AUTO) {
- count = 50; /* time shouldn't exceed 1s, just in case */
- do {
- usleep(20000);
- GetMSP3430Data (m, RD_DEM, 0x00, 0x7e, &high, &low);
- result = ( high << 8 ) | low;
- --count;
- } while( result > 0x07ff && count > 0 );
-
- if ((result > MSPSTANDARD_AUTO))
- standard=result;
- else standard=MSPSTANDARD_UNKNOWN;
-#if __MSPDEBUG__ > 1
- xf86DrvMsg(m->d.pI2CBus->scrnIndex,X_INFO,"Detected audio standard: %d\n",result);
-#endif
- /* result = MSPSTANDARD_NICAM_L can be one of:
- SECAM_L - MSPSTANDARD_NICAM_L
- D/K1 - MSPSTANDARD_FM_DK1
- D/K2 - MSPSTANDARD_FM_DK2
- D/K-NICAM - MSPSTANDARD_NICAM_DK*/
- if( standard == MSPSTANDARD_NICAM_L ) {
- if ((m->standard & 0x00ff)==MSP3430_PAL) {
- /* force PAL D/K */
- standard=MSPSTANDARD_FM_DK1;
- SetMSP3430Data (m, WR_DEM, 0x00, 0x20, standard>>8, standard & 0xFF);
-#if __MSPDEBUG__ > 1
- xf86DrvMsg(m->d.pI2CBus->scrnIndex,X_INFO, "Detected 6.5MHz carrier - forced to D/K1 !!!\n" );
-#endif
- }
- }
- }
- m->c_standard=standard;
- } /*end - standard changed*/
- else {
- if (standard<MSPSTANDARD_NICAM_BG) {
- /* get old value of ident. mode register*/
- GetMSP3430Data (m, RD_DSP, 0x00, 0x15, &high, &low);
- /* reset Ident-Filter */
- SetMSP3430Data (m, WR_DSP, 0x00, 0x14, 0x00, 0x3F);
- /* put back old value to ident. mode register*/
- SetMSP3430Data (m, WR_DSP, 0x00, 0x14, 0x00, low);
- }
- }
-
- if (standard<=MSPSTANDARD_AUTO) {
- m->c_format=MSPFORMAT_1xFM;
- }
- else if (standard<MSPSTANDARD_NICAM_BG) {
- /* set FM prescale */
- SetMSP3430Data (m, WR_DSP, 0x00, 0x0e, 0x30, 0);
- /* set FM deemphasis*/
- SetMSP3430Data (m, WR_DSP, 0x00, 0x0f, ((standard==MSPSTANDARD_FM_M)?0:1), 0);
-
- /* check if FM2 carrier is present */
- /*turn off FM DC Notch*/
- SetMSP3430Data (m, WR_DSP, 0x00, 0x17, 0x00, 0x3f);
- /*matrix source for Quasi-Peak Detector - stereo: ch2->L ch1->R*/
- SetMSP3430Data (m, WR_DSP, 0x00, 0x0c, 0x00, 0x20);
-
- mpause(250);
- GetMSP3430Data (m, RD_DSP, 0x00, 0x1A, &high, &low);
- peak = (high << 8) | low;
-#if __MSPDEBUG__ > 1
- xf86DrvMsg(m->d.pI2CBus->scrnIndex,X_INFO,"Second carrier Quasi-Peak detection: %d\n",peak);
-#endif
- /*turn on FM DC Notch*/
- SetMSP3430Data (m, WR_DSP, 0x00, 0x17, 0x00, 0x00);
-
- if (peak<5) {
- /* if second carrier not detected - only mono from first carrier*/
- m->c_format=MSPFORMAT_1xFM;
- }
- else {
- m->c_format=MSPFORMAT_2xFM;
- /*start of FM identification process - FM_WAIT
- wait at least 0.5s - used 1s - gives beter resolution*/
- mpause(1000);
- }
- }
- else {
- if (standard==MSPSTANDARD_NICAM_L) {
- m->c_format=MSPFORMAT_NICAM_AM;
- /* set AM prescale */
- SetMSP3430Data (m, WR_DSP, 0x00, 0x0e, 0x7C, 0);
- }
- else {
- m->c_format=MSPFORMAT_NICAM_FM;
- /* set FM prescale */
- SetMSP3430Data (m, WR_DSP, 0x00, 0x0e, 0x30, 0);
- }
- /* set FM deemphasis*/
- SetMSP3430Data (m, WR_DSP, 0x00, 0x0f, 0x00, 0);
- /* set NICAM prescale to 0dB */
- SetMSP3430Data (m, WR_DSP, 0x00, 0x10, 0x20, 0);
- }
-
- break;
- } /*end - case conector*/
-
- CheckModeMSP34x5D(m);
-
- /* Set volume to FAST_MUTE. */
- /*SetMSP3430Data(m, WR_DSP, 0x00, 0x00, 0xFF, 0x00);*/
- /*set volume*/
- MSP3430SetVolume(m,m->volume);
-
- __MSPBEEP
-
-
-} /* EnableMSP34x5D ()... */
-
-
-
-
-void CheckModeMSP34x5D(MSP3430Ptr m) {
- const char stereo_on=25;
- const char stereo_off=20;
- const char dual_on=-stereo_on;
- const char dual_off=-stereo_off;
- char detect;
- CARD8 matrix, fmmatrix, source, high, low;
-
- fmmatrix=0; /*no matrix*/
- source=0; /*FM*/
- switch (m->c_format) {
- case MSPFORMAT_NICAM_FM:
- case MSPFORMAT_NICAM_AM:
- case MSPFORMAT_SCART:
- source=( (m->c_format == MSPFORMAT_SCART)?2:1 );
- switch (m->mode) {
- case MSPMODE_MONO:
- matrix=0x30; /*MONO*/
- break;
- case MSPMODE_A:
- matrix=0x00; /*A*/
- break;
- case MSPMODE_B:
- matrix=0x10; /*B*/
- break;
- default:
- matrix=0x20; /*STEREO*/
- break;
- }
- break;
- default:
- case MSPFORMAT_1xFM:
- matrix=0x00; /*A*/
- break;
- case MSPFORMAT_2xFM:
- switch (m->mode) {
- case MSPMODE_MONO:
- matrix=0x30; /*MONO*/
- break;
- case MSPMODE_STEREO:
- matrix=0x20; /*STEREO*/
- fmmatrix=((m->c_standard==MSPSTANDARD_FM_M)?2:1);
- break;
- case MSPMODE_AB:
- matrix=0x20; /*STEREO*/
- break;
- case MSPMODE_A:
- matrix=0x00; /*A*/
- break;
- case MSPMODE_B:
- matrix=0x10; /*B*/
- break;
- default:
- /*FM_IDENT_CHECK*/
- GetMSP3430Data (m, RD_DSP, 0x00, 0x18, &high, &low);
- detect=(char)high;
-#if __MSPDEBUG__ > 1
- xf86DrvMsg(m->d.pI2CBus->scrnIndex,X_INFO,"Stereo Detection Register: %d\n",detect);
-#endif
- if (detect>=((m->c_mode==MSPMODE_STEREO)?stereo_off:stereo_on)) {
- m->c_mode=MSPMODE_STEREO;
- matrix=0x20; /*STEREO*/
- fmmatrix=((m->c_standard==MSPSTANDARD_FM_M)?2:1);
- }
- else if (detect<=((m->c_mode==MSPMODE_AB)?dual_off:dual_on)) {
- m->c_mode=MSPMODE_AB;
- switch (m->mode) {
- case MSPMODE_STEREO_AB: matrix=0x20; break;
- case MSPMODE_STEREO_B: matrix=0x10; break;
- default:
- case MSPMODE_A: matrix=0x00; break;
- }
- }
- else {
- m->c_mode=MSPMODE_MONO;
- matrix=0x30; /*MONO*/
- }
- break;
- } /* end - case mode*/
- break;
- }
-
- if (m->c_fmmatrix != fmmatrix) {
- GetMSP3430Data (m, RD_DSP, 0x00, 0x0e, &high, &low);
- SetMSP3430Data (m, WR_DSP, 0x00, 0x0e, high, fmmatrix);
- m->c_fmmatrix = fmmatrix;
- }
-
- if ((m->c_matrix != matrix) || (m->c_source != source)) {
- /*set chanel source and matrix for loudspeaker*/
- SetMSP3430Data (m, WR_DSP, 0x00, 0x08, source, matrix);
-
- m->c_matrix = matrix;
- m->c_source = source;
- }
-
- if ( ((m->c_format) & 0xF0) == MSPFORMAT_NICAM)
- SetMSP3430Data (m, WR_DEM, 0x00, 0x21, 0, 1);
-
-#if __MSPDEBUG__ > 0
- char *msg;
- switch (matrix) {
- case 0x30: /*MONO*/
- msg="MONO";
- break;
- case 0x00: /*LEFT*/
- msg="MONO/CHANNEL_1";
- break;
- case 0x10: /*RIGHT*/
- msg="MONO/CHANNEL_2";
- break;
- case 0x20: /*LEFT*/
- msg="STEREO";
- break;
- default:
- msg="unknown";
- break;
- }
- xf86DrvMsg(m->d.pI2CBus->scrnIndex,X_INFO,"Audio mode set to: %s\n",msg);
-#endif
-}
-
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <string.h>
+#include <unistd.h>
+
+#include "xf86.h"
+#include "xf86i2c.h"
+#include "msp3430.h"
+#include "i2c_def.h"
+
+#define CONTROL 0x00
+#define WR_DEM 0x10
+#define RD_DEM 0x11
+#define WR_DSP 0x12
+#define RD_DSP 0x13
+
+
+void InitMSP34xxG(MSP3430Ptr m);
+void InitMSP34x5D(MSP3430Ptr m);
+void CheckModeMSP34x5D(MSP3430Ptr m);
+char *MSP_getProductName (CARD16 product_id);
+void mpause(int milliseconds);
+
+#define __MSPDEBUG__ 0
+
+#if __MSPDEBUG__ > 3
+
+void MSPBeep(MSP3430Ptr m, CARD8 freq);
+#define __MSPBEEP MSPBeep(m,0x14);
+
+#else
+
+#define __MSPBEEP
+#endif
+
+static void SetMSP3430Control(MSP3430Ptr m, CARD8 RegAddress, CARD8 RegValueHigh, CARD8 RegValueLow)
+{
+ I2CByte data[3];
+
+ data[0]=RegAddress;
+ data[1]=RegValueHigh;
+ data[2]=RegValueLow;
+
+ I2C_WriteRead(&(m->d),data,3,NULL,0);
+}
+
+static void SetMSP3430Data(MSP3430Ptr m, CARD8 RegAddress, CARD8 RegSubAddressHigh, CARD8 RegSubAddressLow,
+ CARD8 RegValueHigh, CARD8 RegValueLow)
+{
+ I2CByte data[5];
+#ifdef MSP_DEBUG
+ if(!m->registers_present[RegSubAddressLow]){
+ xf86DrvMsg(m->d.pI2CBus->scrnIndex,X_ERROR, "Attempt to access non-existent register in MSP34xxX: 0x%02x 0x%02x 0x%02x <- 0x%02x 0x%02x\n",
+ RegAddress, RegSubAddressHigh, RegSubAddressLow, RegValueHigh, RegValueLow);
+ }
+#endif
+
+ data[0] = RegAddress;
+ data[1] = RegSubAddressHigh;
+ data[2] = RegSubAddressLow;
+ data[3] = RegValueHigh;
+ data[4] = RegValueLow;
+
+ I2C_WriteRead(&(m->d),data,5,NULL,0);
+}
+
+static void GetMSP3430Data(MSP3430Ptr m, CARD8 RegAddress, CARD8 RegSubAddressHigh, CARD8 RegSubAddressLow,
+ CARD8 *RegValueHigh, CARD8 *RegValueLow)
+{
+ I2CByte send[3];
+ I2CByte receive[2];
+
+ send[0] = RegAddress;
+ send[1] = RegSubAddressHigh;
+ send[2] = RegSubAddressLow;
+
+ I2C_WriteRead(&(m->d), send, 3, receive, 2);
+
+ *RegValueHigh = receive[0];
+ *RegValueLow = receive[1];
+}
+
+#if __MSPDEBUG__ > 2
+static void MSP3430DumpStatus(MSP3430Ptr m)
+{
+CARD8 status_hi, status_lo;
+CARD8 subaddr, data[2];
+
+GetMSP3430Data(m, RD_DEM, 0x02, 0x00, &status_hi, &status_lo);
+xf86DrvMsg(m->d.pI2CBus->scrnIndex, X_INFO, "MSP34xx: SAP(8)=%d mono/NICAM(7)=%d stereo=%d %s O_1=%d O_0=%d 2nd car=%d 1st car=%d\n",
+ status_hi & 1, (status_lo>>7) & 1, (status_lo>>6)&1,
+ (status_lo>>5)? ( (status_hi>>1)&1? "bad NICAM reception" : "NICAM" ) :
+ ((status_hi>>1)&1 ? "bogus" : "ANALOG FM/AM") ,
+ (status_lo>>4)&1, (status_lo>>3)&1,!( (status_lo>>2)&1), !((status_lo>>1)&1));
+
+GetMSP3430Data(m, RD_DEM, 0x00, 0x7E, &status_hi, &status_lo);
+xf86DrvMsg(m->d.pI2CBus->scrnIndex, X_INFO, "MSP34xx: standard result=0x%02x%02x\n",
+ status_hi, status_lo);
+subaddr=0x0;
+I2C_WriteRead(&(m->d), &subaddr, 1, data, 2);
+xf86DrvMsg(m->d.pI2CBus->scrnIndex, X_INFO, "MSP34xx: control=0x%02x%02x\n",
+ data[1], data[0]);
+}
+#endif
+
+/* wrapper */
+void InitMSP3430(MSP3430Ptr m)
+{
+ #if __MSPDEBUG__ > 1
+ xf86DrvMsg(m->d.pI2CBus->scrnIndex,X_INFO,"InitMSP3430(m->connector=%d, m->standard=%d, m->chip_family=%d)\n",
+ m->connector, m->standard, m->chip_family);
+ #endif
+ switch (m->chip_family) {
+ case MSPFAMILY_34x0G:
+ InitMSP34xxG(m);
+ break;
+ case MSPFAMILY_34x5G:
+ InitMSP34xxG(m);
+ break;
+ case MSPFAMILY_34x5D:
+ InitMSP34x5D(m);
+ break;
+ }
+}
+
+/*-----------------------------------------------------------------
+| common functions for all MSP34xx chips
+|----------------------------------------------------------------*/
+
+MSP3430Ptr DetectMSP3430(I2CBusPtr b, I2CSlaveAddr addr)
+{
+ MSP3430Ptr m;
+ I2CByte a;
+ CARD8 hardware_version, major_revision, product_code, rom_version;
+ Bool supported;
+
+ m = calloc(1,sizeof(MSP3430Rec));
+ if(m == NULL)return NULL;
+ m->d.DevName = strdup("MSP34xx");
+ m->d.SlaveAddr = addr;
+ m->d.pI2CBus = b;
+ m->d.NextDev = NULL;
+ m->d.StartTimeout = b->StartTimeout;
+ m->d.BitTimeout = b->BitTimeout;
+ m->d.AcknTimeout = b->AcknTimeout;
+ m->d.ByteTimeout = b->ByteTimeout;
+
+ if(!I2C_WriteRead(&(m->d), NULL, 0, &a, 1))
+ {
+ free(m->d.DevName);
+ free(m);
+ return NULL;
+ }
+
+
+ m->standard=MSP3430_NTSC;
+ m->connector=MSP3430_CONNECTOR_1;
+ m->mode=MSPMODE_STEREO_A; /*stereo or chanel A if avail. */
+ m->c_format=MSPFORMAT_UNKNOWN;
+ m->c_standard=MSPSTANDARD_UNKNOWN;
+ m->c_matrix=m->c_fmmatrix=m->c_source=0;
+ m->volume=0;
+ m->recheck=FALSE;
+
+ GetMSP3430Data(m, RD_DSP, 0x00, 0x1E, &hardware_version, &major_revision);
+ GetMSP3430Data(m, RD_DSP, 0x00, 0x1F, &product_code, &rom_version);
+ m->hardware_version=hardware_version;
+ m->major_revision=major_revision;
+ m->product_code=product_code;
+ m->rom_version=rom_version;
+
+ m->chip_id=((major_revision << 8) | product_code);
+
+ supported=FALSE;
+ switch (major_revision) {
+ case 4: /* 34xxD */
+ switch (product_code) {
+ case 0x05: /* 3405D */
+ case 0x0A: /* 3410D */
+ case 0x0F: /* 3415D */
+ m->chip_family=MSPFAMILY_34x5D;
+ m->recheck=TRUE;
+ supported=TRUE;
+ break;
+ default:
+ m->chip_family=MSPFAMILY_34x0D;
+ }
+ break;
+ case 7: /* 34xxG */
+ switch(product_code){
+ case 0x00:
+ case 0x0A:
+ case 0x1E:
+ case 0x28:
+ case 0x32:
+ m->chip_family=MSPFAMILY_34x0G;
+ supported=TRUE;
+ break;
+ case 0x0f:
+ case 0x19:
+ case 0x2d:
+ case 0x37:
+ case 0x41:
+ m->chip_family=MSPFAMILY_34x5G;
+ supported=TRUE;
+ #ifdef MSP_DEBUG
+ memset(m->registers_present, 0, 256);
+ #define A(num) m->registers_present[(num)]=1;
+ #define B(num1, num2) memset(&(m->registers_present[num1]), 1, num2-num1);
+ A(0x20)
+ A(0x30)
+ A(0x40)
+ A(0x00)
+ B(0x01, 0x08)
+ B(0x0B, 0x0E)
+ A(0x10)
+ B(0x12,0x14)
+ A(0x16)
+ A(0x29)
+ #undef B
+ #undef A
+ #endif
+ break;
+ default:
+ m->chip_family=MSPFAMILY_UNKNOWN;
+ }
+ break;
+ default:
+ m->chip_family=MSPFAMILY_UNKNOWN;
+ }
+
+ xf86DrvMsg(m->d.pI2CBus->scrnIndex, X_INFO, "Found %s%s, rom version 0x%02x, chip_id=0x%04x\n",
+ MSP_getProductName(m->chip_id), supported?"":" (unsupported)", rom_version, m->chip_id);
+
+ if (!supported) {
+ free(m->d.DevName);
+ free(m);
+ return NULL;
+ }
+ if(!I2CDevInit(&(m->d)))
+ {
+ free(m->d.DevName);
+ free(m);
+ return NULL;
+ }
+
+ return m;
+}
+
+void ResetMSP3430(MSP3430Ptr m)
+{
+ /* Reset the MSP3430 */
+ SetMSP3430Control(m, 0x00, 0x80, 0x00);
+ /* Set it back to normal operation */
+ SetMSP3430Control(m, 0x00, 0x00, 0x00);
+
+ m->c_format=MSPFORMAT_UNKNOWN;
+ m->c_standard=MSPSTANDARD_UNKNOWN;
+ m->c_matrix=m->c_fmmatrix=m->c_source=0;
+ m->volume=0;
+}
+
+void MSP3430SetVolume (MSP3430Ptr m, CARD8 value)
+{
+ CARD8 result;
+#if 0
+ CARD8 old_volume;
+ GetMSP3430Data(m, RD_DSP, 0x00, 0x00, &old_volume, &result);
+ xf86DrvMsg(m->d.pI2CBus->scrnIndex, X_INFO, "MSP3430 result 0x%02x\n", result);
+#endif
+ /* save an extra Get call */
+ result=0;
+
+ SetMSP3430Data(m, WR_DSP, 0x00, 0x00, value, result);
+
+ SetMSP3430Data(m, WR_DSP, 0x00, 0x07, value, 0);
+ m->volume=value;
+
+#if __MSPDEBUG__ > 2
+ MSP3430DumpStatus(m);
+ __MSPBEEP
+ GetMSP3430Data(m, RD_DSP, 0x00, 0x00, &old_volume, &result);
+ xf86DrvMsg(m->d.pI2CBus->scrnIndex, X_INFO, "MSP3430 volume 0x%02x\n",value);
+#endif
+}
+
+
+void MSP3430SetSAP (MSP3430Ptr m, int mode)
+{
+ xf86DrvMsg(m->d.pI2CBus->scrnIndex, X_INFO, "Put actual code to change SAP here\n");
+
+ SetMSP3430Data(m, WR_DSP, 0x00, 0x08, mode & 0xff, 0x20);
+}
+
+
+#if 0
+void MSP3430SetSource(MSP3430Ptr m, CARD8 value)
+{
+ /* Write to DSP, register 0x0008, (loudspeaker channel source/matrix) */
+ /* This sets the source to the TV tuner, for stereo operation */
+ SetMSP3430Data(m, WR_DSP, 0x00, 0x08, value, 0x20);
+}
+#endif
+
+
+char *MSP_getProductName (CARD16 product_id)
+{
+ switch (product_id) {
+ case 0x0400: return "MSP3400D";
+ case 0x040a: return "MSP3410D";
+ case 0x0405: return "MSP3405D";
+ case 0x040f: return "MSP3415D";
+ case 0x0700: return "MSP3400G";
+ case 0x070a: return "MSP3410G";
+ case 0x071e: return "MSP3430G";
+ case 0x0728: return "MSP3440G";
+ case 0x0732: return "MSP3450G";
+ case 0x070f: return "MSP3415G";
+ case 0x0719: return "MSP3425G";
+ case 0x072d: return "MSP3445G";
+ case 0x0737: return "MSP3455G";
+ case 0x0741: return "MSP3465G";
+ }
+ return "MSP - unknown type";
+}
+
+#if __MSPDEBUG__ > 2
+/*puts beep in MSP output
+ freq = 0x01 - 16Hz ... 0x40 - 1kHz ... 0xff - 4kHz
+*/
+void MSPBeep(MSP3430Ptr m, CARD8 freq) {
+ SetMSP3430Data (m, WR_DSP, 0x00, freq, 0x7f, 0x40);
+ mpause(100);
+ SetMSP3430Data (m, WR_DSP, 0x00, 0x14, 0x00, 0x00);
+}
+#endif
+
+void mpause(int milliseconds) {
+ int i,m;
+ m=milliseconds/20;
+ for (i=0;i<m;i++) usleep(20000);
+}
+
+/*-----------------------------------------------------------------
+| specific functions for all MSP34xxG chips
+|----------------------------------------------------------------*/
+
+void InitMSP34xxG(MSP3430Ptr m)
+{
+
+ #if __MSPDEBUG__ > 1
+ xf86DrvMsg(m->d.pI2CBus->scrnIndex,X_INFO,"InitMSP34xxG(m->connector=%d, m->standard=%d, m->chip_family=%d)\n",
+ m->connector, m->standard, m->chip_family);
+ #endif
+ /* Reset MSP3430 */
+ SetMSP3430Control(m, 0x00, 0x80, 0x00);
+ /* Set it back to normal operation */
+ SetMSP3430Control(m, 0x00, 0x00, 0x00);
+
+ /*set MODUS register */
+ /* bits: 0 - automatic sound detection */
+ /* 1 - enable STATUS change */
+ /* 12 - detect 6.5 Mhz carrier as D/K1, D/K2 or D/K NICAM (does not seem to work ) */
+ /* 13 - detect 4.5 Mhz carrier as BTSC */
+ if ( (m->standard & 0xff) == MSP3430_PAL )
+ {
+ SetMSP3430Data(m, WR_DEM, 0x00, 0x30, 0x30, 0x03|0x08); /* make O_ pins tristate */
+ /* PAL standard */
+ SetMSP3430Data(m, WR_DEM, 0x00, 0x20, 0x00, 0x01); /* possibly wrong */
+ } else {
+ SetMSP3430Data(m, WR_DEM, 0x00, 0x30, 0x20, 0x03|0x08);
+ /* standard selection is M-BTSC-Stereo */
+ SetMSP3430Data(m, WR_DEM, 0x00, 0x20, 0x00, 0x20);
+ }
+
+ switch(m->connector){
+ case MSP3430_CONNECTOR_1:
+ SetMSP3430Data(m, WR_DSP, 0x00, 0x08, 0x03, 0x20);
+ break;
+ case MSP3430_CONNECTOR_2:
+ /* this has not been checked yet.. could be bogus */
+ /* SCART Input Prescale: 0 dB gain */
+ SetMSP3430Data(m, WR_DSP, 0x00, 0x0d, 0x19, 0x00);
+ SetMSP3430Data(m, WR_DSP, 0x00, 0x08, 0x02, 0x20);
+ break;
+ case MSP3430_CONNECTOR_3:
+ default:
+ /* SCART Input Prescale: 0 dB gain */
+ SetMSP3430Data(m, WR_DSP, 0x00, 0x0d, 0x19, 0x00);
+
+ SetMSP3430Data(m, WR_DSP, 0x00, 0x08, 0x02, 0x20);
+ break;
+ }
+
+ switch(m->standard){
+ case MSP3430_PAL:
+ SetMSP3430Data(m, WR_DSP, 0x00, 0x0e, 0x24, 0x03);
+ SetMSP3430Data(m, WR_DSP, 0x00, 0x10, 0x00, 0x5a);
+ SetMSP3430Data(m, WR_DEM, 0x00, 0x20, 0x00, 0x03);
+ /* Set volume to FAST_MUTE. */
+ SetMSP3430Data(m, WR_DSP, 0x00, 0x00, 0xFF, 0x00);
+ break;
+ case MSP3430_PAL_DK1:
+ SetMSP3430Data(m, WR_DSP, 0x00, 0x0e, 0x24, 0x03);
+ SetMSP3430Data(m, WR_DSP, 0x00, 0x10, 0x00, 0x5a);
+ SetMSP3430Data(m, WR_DEM, 0x00, 0x20, 0x00, 0x04);
+ /* Set volume to FAST_MUTE. */
+ SetMSP3430Data(m, WR_DSP, 0x00, 0x00, 0xFF, 0x00);
+ break;
+ case MSP3430_SECAM: /* is this right ? */
+ case MSP3430_NTSC:
+ /* Write to DSP, register 0x000E, (prescale FM/FM matrix) */
+ SetMSP3430Data(m, WR_DSP, 0x00, 0x0e, 0x24, 0x03);
+
+ /* Set volume to FAST_MUTE. */
+ SetMSP3430Data(m, WR_DSP, 0x00, 0x00, 0xFF, 0x00);
+ break;
+ }
+
+}
+
+/*-----------------------------------------------------------------
+| specific functions for all MSP34x5D chips
+|----------------------------------------------------------------*/
+
+void InitMSP34x5D(MSP3430Ptr m)
+{
+int count;
+CARD8 high,low;
+CARD16 result,standard;
+CARD16 peak;
+
+
+if (m->c_format==MSPFORMAT_UNKNOWN) ResetMSP3430(m);
+else {
+ /*mute volume*/
+ SetMSP3430Data (m, WR_DSP, 0x00, 0x00, 0x00, 0x00);
+}
+
+
+
+ switch(m->connector){
+ case MSP3430_CONNECTOR_2:
+ case MSP3430_CONNECTOR_3:
+ if (m->c_format!=MSPFORMAT_SCART) {
+ /* SCART Input Prescale: 0 dB gain */
+ SetMSP3430Data (m, WR_DSP, 0x00, 0x0d, 0x19, 0x00);
+ /* this has not been checked yet.. could be bogus */
+ m->c_format=MSPFORMAT_SCART; /*stereo*/
+ }
+ break;
+ case MSP3430_CONNECTOR_1:
+ default:
+
+ switch ( m->standard & 0x00ff ) {
+ case MSP3430_PAL:
+ switch( m->standard ) {
+ case MSP3430_PAL_DK1:
+ standard=MSPSTANDARD_FM_DK1;
+ break;
+/* case MSP3430_PAL_DK2:
+ standard=MSPSTANDARD_FM_DK2;
+ break;
+ case MSP3430_PAL_BG:
+ may be FM stereo (Germany) or FM NICAM (Scandinavia,spain)
+ standard=MSPSTANDARD_AUTO;
+ break;
+*/
+ default:
+ standard=MSPSTANDARD_AUTO;
+ }
+ break;
+ case MSP3430_SECAM:
+ standard=MSPSTANDARD_AUTO;
+ case MSP3430_NTSC:
+ /* Only MSP34x5 supported format - Korean NTSC-M*/
+ standard=MSPSTANDARD_FM_M;
+ default:
+ standard=MSPSTANDARD_AUTO;
+ }
+
+ /*no NICAM support in MSP3410D - force to autodetect*/
+ if ((m->chip_id==0x405) && (standard>=MSPSTANDARD_NICAM_BG))
+ standard=MSPSTANDARD_AUTO;
+
+ if (m->c_standard != standard) {
+
+ SetMSP3430Data (m, WR_DEM, 0x00, 0x20, standard>>8, standard & 0xFF);
+ if (standard==MSPSTANDARD_AUTO) {
+ count = 50; /* time shouldn't exceed 1s, just in case */
+ do {
+ usleep(20000);
+ GetMSP3430Data (m, RD_DEM, 0x00, 0x7e, &high, &low);
+ result = ( high << 8 ) | low;
+ --count;
+ } while( result > 0x07ff && count > 0 );
+
+ if ((result > MSPSTANDARD_AUTO))
+ standard=result;
+ else standard=MSPSTANDARD_UNKNOWN;
+#if __MSPDEBUG__ > 1
+ xf86DrvMsg(m->d.pI2CBus->scrnIndex,X_INFO,"Detected audio standard: %d\n",result);
+#endif
+ /* result = MSPSTANDARD_NICAM_L can be one of:
+ SECAM_L - MSPSTANDARD_NICAM_L
+ D/K1 - MSPSTANDARD_FM_DK1
+ D/K2 - MSPSTANDARD_FM_DK2
+ D/K-NICAM - MSPSTANDARD_NICAM_DK*/
+ if( standard == MSPSTANDARD_NICAM_L ) {
+ if ((m->standard & 0x00ff)==MSP3430_PAL) {
+ /* force PAL D/K */
+ standard=MSPSTANDARD_FM_DK1;
+ SetMSP3430Data (m, WR_DEM, 0x00, 0x20, standard>>8, standard & 0xFF);
+#if __MSPDEBUG__ > 1
+ xf86DrvMsg(m->d.pI2CBus->scrnIndex,X_INFO, "Detected 6.5MHz carrier - forced to D/K1 !!!\n" );
+#endif
+ }
+ }
+ }
+ m->c_standard=standard;
+ } /*end - standard changed*/
+ else {
+ if (standard<MSPSTANDARD_NICAM_BG) {
+ /* get old value of ident. mode register*/
+ GetMSP3430Data (m, RD_DSP, 0x00, 0x15, &high, &low);
+ /* reset Ident-Filter */
+ SetMSP3430Data (m, WR_DSP, 0x00, 0x14, 0x00, 0x3F);
+ /* put back old value to ident. mode register*/
+ SetMSP3430Data (m, WR_DSP, 0x00, 0x14, 0x00, low);
+ }
+ }
+
+ if (standard<=MSPSTANDARD_AUTO) {
+ m->c_format=MSPFORMAT_1xFM;
+ }
+ else if (standard<MSPSTANDARD_NICAM_BG) {
+ /* set FM prescale */
+ SetMSP3430Data (m, WR_DSP, 0x00, 0x0e, 0x30, 0);
+ /* set FM deemphasis*/
+ SetMSP3430Data (m, WR_DSP, 0x00, 0x0f, ((standard==MSPSTANDARD_FM_M)?0:1), 0);
+
+ /* check if FM2 carrier is present */
+ /*turn off FM DC Notch*/
+ SetMSP3430Data (m, WR_DSP, 0x00, 0x17, 0x00, 0x3f);
+ /*matrix source for Quasi-Peak Detector - stereo: ch2->L ch1->R*/
+ SetMSP3430Data (m, WR_DSP, 0x00, 0x0c, 0x00, 0x20);
+
+ mpause(250);
+ GetMSP3430Data (m, RD_DSP, 0x00, 0x1A, &high, &low);
+ peak = (high << 8) | low;
+#if __MSPDEBUG__ > 1
+ xf86DrvMsg(m->d.pI2CBus->scrnIndex,X_INFO,"Second carrier Quasi-Peak detection: %d\n",peak);
+#endif
+ /*turn on FM DC Notch*/
+ SetMSP3430Data (m, WR_DSP, 0x00, 0x17, 0x00, 0x00);
+
+ if (peak<5) {
+ /* if second carrier not detected - only mono from first carrier*/
+ m->c_format=MSPFORMAT_1xFM;
+ }
+ else {
+ m->c_format=MSPFORMAT_2xFM;
+ /*start of FM identification process - FM_WAIT
+ wait at least 0.5s - used 1s - gives beter resolution*/
+ mpause(1000);
+ }
+ }
+ else {
+ if (standard==MSPSTANDARD_NICAM_L) {
+ m->c_format=MSPFORMAT_NICAM_AM;
+ /* set AM prescale */
+ SetMSP3430Data (m, WR_DSP, 0x00, 0x0e, 0x7C, 0);
+ }
+ else {
+ m->c_format=MSPFORMAT_NICAM_FM;
+ /* set FM prescale */
+ SetMSP3430Data (m, WR_DSP, 0x00, 0x0e, 0x30, 0);
+ }
+ /* set FM deemphasis*/
+ SetMSP3430Data (m, WR_DSP, 0x00, 0x0f, 0x00, 0);
+ /* set NICAM prescale to 0dB */
+ SetMSP3430Data (m, WR_DSP, 0x00, 0x10, 0x20, 0);
+ }
+
+ break;
+ } /*end - case conector*/
+
+ CheckModeMSP34x5D(m);
+
+ /* Set volume to FAST_MUTE. */
+ /*SetMSP3430Data(m, WR_DSP, 0x00, 0x00, 0xFF, 0x00);*/
+ /*set volume*/
+ MSP3430SetVolume(m,m->volume);
+
+ __MSPBEEP
+
+
+} /* EnableMSP34x5D ()... */
+
+
+
+
+void CheckModeMSP34x5D(MSP3430Ptr m) {
+ const char stereo_on=25;
+ const char stereo_off=20;
+ const char dual_on=-stereo_on;
+ const char dual_off=-stereo_off;
+ char detect;
+ CARD8 matrix, fmmatrix, source, high, low;
+
+ fmmatrix=0; /*no matrix*/
+ source=0; /*FM*/
+ switch (m->c_format) {
+ case MSPFORMAT_NICAM_FM:
+ case MSPFORMAT_NICAM_AM:
+ case MSPFORMAT_SCART:
+ source=( (m->c_format == MSPFORMAT_SCART)?2:1 );
+ switch (m->mode) {
+ case MSPMODE_MONO:
+ matrix=0x30; /*MONO*/
+ break;
+ case MSPMODE_A:
+ matrix=0x00; /*A*/
+ break;
+ case MSPMODE_B:
+ matrix=0x10; /*B*/
+ break;
+ default:
+ matrix=0x20; /*STEREO*/
+ break;
+ }
+ break;
+ default:
+ case MSPFORMAT_1xFM:
+ matrix=0x00; /*A*/
+ break;
+ case MSPFORMAT_2xFM:
+ switch (m->mode) {
+ case MSPMODE_MONO:
+ matrix=0x30; /*MONO*/
+ break;
+ case MSPMODE_STEREO:
+ matrix=0x20; /*STEREO*/
+ fmmatrix=((m->c_standard==MSPSTANDARD_FM_M)?2:1);
+ break;
+ case MSPMODE_AB:
+ matrix=0x20; /*STEREO*/
+ break;
+ case MSPMODE_A:
+ matrix=0x00; /*A*/
+ break;
+ case MSPMODE_B:
+ matrix=0x10; /*B*/
+ break;
+ default:
+ /*FM_IDENT_CHECK*/
+ GetMSP3430Data (m, RD_DSP, 0x00, 0x18, &high, &low);
+ detect=(char)high;
+#if __MSPDEBUG__ > 1
+ xf86DrvMsg(m->d.pI2CBus->scrnIndex,X_INFO,"Stereo Detection Register: %d\n",detect);
+#endif
+ if (detect>=((m->c_mode==MSPMODE_STEREO)?stereo_off:stereo_on)) {
+ m->c_mode=MSPMODE_STEREO;
+ matrix=0x20; /*STEREO*/
+ fmmatrix=((m->c_standard==MSPSTANDARD_FM_M)?2:1);
+ }
+ else if (detect<=((m->c_mode==MSPMODE_AB)?dual_off:dual_on)) {
+ m->c_mode=MSPMODE_AB;
+ switch (m->mode) {
+ case MSPMODE_STEREO_AB: matrix=0x20; break;
+ case MSPMODE_STEREO_B: matrix=0x10; break;
+ default:
+ case MSPMODE_A: matrix=0x00; break;
+ }
+ }
+ else {
+ m->c_mode=MSPMODE_MONO;
+ matrix=0x30; /*MONO*/
+ }
+ break;
+ } /* end - case mode*/
+ break;
+ }
+
+ if (m->c_fmmatrix != fmmatrix) {
+ GetMSP3430Data (m, RD_DSP, 0x00, 0x0e, &high, &low);
+ SetMSP3430Data (m, WR_DSP, 0x00, 0x0e, high, fmmatrix);
+ m->c_fmmatrix = fmmatrix;
+ }
+
+ if ((m->c_matrix != matrix) || (m->c_source != source)) {
+ /*set chanel source and matrix for loudspeaker*/
+ SetMSP3430Data (m, WR_DSP, 0x00, 0x08, source, matrix);
+
+ m->c_matrix = matrix;
+ m->c_source = source;
+ }
+
+ if ( ((m->c_format) & 0xF0) == MSPFORMAT_NICAM)
+ SetMSP3430Data (m, WR_DEM, 0x00, 0x21, 0, 1);
+
+#if __MSPDEBUG__ > 0
+ char *msg;
+ switch (matrix) {
+ case 0x30: /*MONO*/
+ msg="MONO";
+ break;
+ case 0x00: /*LEFT*/
+ msg="MONO/CHANNEL_1";
+ break;
+ case 0x10: /*RIGHT*/
+ msg="MONO/CHANNEL_2";
+ break;
+ case 0x20: /*LEFT*/
+ msg="STEREO";
+ break;
+ default:
+ msg="unknown";
+ break;
+ }
+ xf86DrvMsg(m->d.pI2CBus->scrnIndex,X_INFO,"Audio mode set to: %s\n",msg);
+#endif
+}
+
diff --git a/xorg-server/hw/xfree86/i2c/tda8425.c b/xorg-server/hw/xfree86/i2c/tda8425.c
index 7631a0863..abbbb2a03 100644
--- a/xorg-server/hw/xfree86/i2c/tda8425.c
+++ b/xorg-server/hw/xfree86/i2c/tda8425.c
@@ -1,78 +1,78 @@
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "xf86.h"
-#include "xf86i2c.h"
-#include "tda8425.h"
-#include "i2c_def.h"
-
-#define TDA8425(a,b) { \
- data[0]=a; \
- data[1]=b; \
- I2C_WriteRead(&(t->d), data, 2, NULL, 0); \
- }
-
-TDA8425Ptr Detect_tda8425(I2CBusPtr b, I2CSlaveAddr addr, Bool force)
-{
- TDA8425Ptr t;
-
- t = xcalloc(1, sizeof(TDA8425Rec));
- if(t == NULL) return NULL;
- t->d.DevName = "TDA8425 BTSC Stereo Audio Processor";
- t->d.SlaveAddr = addr;
- t->d.pI2CBus = b;
- t->d.NextDev = NULL;
- t->d.StartTimeout = b->StartTimeout;
- t->d.BitTimeout = b->BitTimeout;
- t->d.AcknTimeout = b->AcknTimeout;
- t->d.ByteTimeout = b->ByteTimeout;
-
- if(!force && !I2CProbeAddress(b, addr))
- {
- xfree(t);
- return NULL;
- }
-
- /* set default parameters */
- if(!I2CDevInit(&(t->d)))
- {
- xfree(t);
- return NULL;
- }
-
- return t;
-}
-
-Bool tda8425_init(TDA8425Ptr t)
-{
- t->stereo = 3; /* 3 = Spacial 2 = Linear 1 = Pseudo 0 = Forced mono */
- t->v_left = 0xFF; /* FF - C0 */
- t->v_right = 0xFF; /* FF - C0 */
- t->bass = 0xF6; /* 0xFF - 0xF0 */
- t->treble = 0xF6; /* 0xFF - 0xF0 */
- t->src_sel = 3; /* 3 - stereo */
- t->mute = TRUE;
- t->mux = 0; /* 0 - source one, 1 -source 2 */
-
- tda8425_setaudio(t);
- return TRUE;
-}
-
-void tda8425_setaudio(TDA8425Ptr t)
-{
- I2CByte data[2];
-
- TDA8425(0x00, t->v_left );
- TDA8425(0x01, t->v_right );
- TDA8425(0x02, t->bass );
- TDA8425(0x03, t->treble );
- TDA8425(0x08, 0xC0 | (t->mute ? 0x20 : 0x0) | (t->stereo << 3) | (t->src_sel << 1) |
- t->mux);
-}
-
-void tda8425_mute(TDA8425Ptr t, Bool mute)
-{
- t->mute = mute;
- tda8425_setaudio(t);
-}
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "xf86.h"
+#include "xf86i2c.h"
+#include "tda8425.h"
+#include "i2c_def.h"
+
+#define TDA8425(a,b) { \
+ data[0]=a; \
+ data[1]=b; \
+ I2C_WriteRead(&(t->d), data, 2, NULL, 0); \
+ }
+
+TDA8425Ptr Detect_tda8425(I2CBusPtr b, I2CSlaveAddr addr, Bool force)
+{
+ TDA8425Ptr t;
+
+ t = calloc(1, sizeof(TDA8425Rec));
+ if(t == NULL) return NULL;
+ t->d.DevName = "TDA8425 BTSC Stereo Audio Processor";
+ t->d.SlaveAddr = addr;
+ t->d.pI2CBus = b;
+ t->d.NextDev = NULL;
+ t->d.StartTimeout = b->StartTimeout;
+ t->d.BitTimeout = b->BitTimeout;
+ t->d.AcknTimeout = b->AcknTimeout;
+ t->d.ByteTimeout = b->ByteTimeout;
+
+ if(!force && !I2CProbeAddress(b, addr))
+ {
+ free(t);
+ return NULL;
+ }
+
+ /* set default parameters */
+ if(!I2CDevInit(&(t->d)))
+ {
+ free(t);
+ return NULL;
+ }
+
+ return t;
+}
+
+Bool tda8425_init(TDA8425Ptr t)
+{
+ t->stereo = 3; /* 3 = Spacial 2 = Linear 1 = Pseudo 0 = Forced mono */
+ t->v_left = 0xFF; /* FF - C0 */
+ t->v_right = 0xFF; /* FF - C0 */
+ t->bass = 0xF6; /* 0xFF - 0xF0 */
+ t->treble = 0xF6; /* 0xFF - 0xF0 */
+ t->src_sel = 3; /* 3 - stereo */
+ t->mute = TRUE;
+ t->mux = 0; /* 0 - source one, 1 -source 2 */
+
+ tda8425_setaudio(t);
+ return TRUE;
+}
+
+void tda8425_setaudio(TDA8425Ptr t)
+{
+ I2CByte data[2];
+
+ TDA8425(0x00, t->v_left );
+ TDA8425(0x01, t->v_right );
+ TDA8425(0x02, t->bass );
+ TDA8425(0x03, t->treble );
+ TDA8425(0x08, 0xC0 | (t->mute ? 0x20 : 0x0) | (t->stereo << 3) | (t->src_sel << 1) |
+ t->mux);
+}
+
+void tda8425_mute(TDA8425Ptr t, Bool mute)
+{
+ t->mute = mute;
+ tda8425_setaudio(t);
+}
diff --git a/xorg-server/hw/xfree86/i2c/tda9850.c b/xorg-server/hw/xfree86/i2c/tda9850.c
index 5b0c581ed..5d794dfe5 100644
--- a/xorg-server/hw/xfree86/i2c/tda9850.c
+++ b/xorg-server/hw/xfree86/i2c/tda9850.c
@@ -1,112 +1,112 @@
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "xf86.h"
-#include "xf86i2c.h"
-#include "tda9850.h"
-#include "i2c_def.h"
-
-#define TDA9850(a,b) { \
- data[0]=a; \
- data[1]=b; \
- I2C_WriteRead(&(t->d), data, 2, NULL, 0); \
- }
-
-TDA9850Ptr Detect_tda9850(I2CBusPtr b, I2CSlaveAddr addr)
-{
- TDA9850Ptr t;
- I2CByte a;
-
- t = xcalloc(1, sizeof(TDA9850Rec));
- if(t == NULL) return NULL;
- switch(addr)
- {
- case TDA9850_ADDR_1:
- t->d.DevName = "TDA9850 BTSC Stereo+SAP Audio Processor";
- break;
- default:
- t->d.DevName = "Generic TDAxxxx";
- break;
- }
- t->d.SlaveAddr = addr;
- t->d.pI2CBus = b;
- t->d.NextDev = NULL;
- t->d.StartTimeout = b->StartTimeout;
- t->d.BitTimeout = b->BitTimeout;
- t->d.AcknTimeout = b->AcknTimeout;
- t->d.ByteTimeout = b->ByteTimeout;
-
- if(!I2C_WriteRead(&(t->d), NULL, 0, &a, 1))
- {
- xfree(t);
- return NULL;
- }
-
- /* set default parameters */
- if(!I2CDevInit(&(t->d)))
- {
- xfree(t);
- return NULL;
- }
-
- return t;
-}
-
-Bool tda9850_init(TDA9850Ptr t)
-{
- t->stereo = 1;
- t->sap = 0;
- t->mute = TRUE;
- t->sap_mute = TRUE;
- tda9850_setaudio(t);
- return TRUE;
-}
-
-void tda9850_setaudio(TDA9850Ptr t)
-{
-CARD8 data[2];
-
-if(t->mux==2)
-{
- TDA9850(0x04,0x0F); TDA9850(0x05,0x0F); TDA9850(0x06, 0x58);
- TDA9850(0x07,0x07); TDA9850(0x08,0x00);
- TDA9850(0x09,0x00); TDA9850(0x0A,0x03);
-} else
-{
- TDA9850(0x04,0x07); TDA9850(0x05,0x07);
- TDA9850(0x06,0x58); TDA9850(0x07,0x07);
- TDA9850(0x08,0x10); TDA9850(0x09,0x10);
- TDA9850(0x0A,0x03);
-}
-
-TDA9850(0x06,(t->stereo<<6)|(t->sap<<7)|(t->mute?0x8:0)|(t->sap_mute?0x10:0x0));
-}
-
-void tda9850_mute(TDA9850Ptr t, Bool mute)
-{
-CARD8 data[2];
-
-xf86DrvMsg(t->d.pI2CBus->scrnIndex, X_INFO, "tda9850_mute %s\n", mute ? "on" : "off");
-t->mute = mute;
-
-TDA9850(0x06,(t->stereo<<6)|(t->sap<<7)|(t->mute?0x8:0x0)|(t->sap_mute?0x10:0x0));
-}
-
-void tda9850_sap_mute(TDA9850Ptr t, Bool sap_mute)
-{
-CARD8 data[2];
-
-xf86DrvMsg(t->d.pI2CBus->scrnIndex, X_INFO, "tda9850_sap_mute %s\n", sap_mute ? "on" : "off");
-t->sap_mute = sap_mute;
-
-TDA9850(0x06,(t->stereo<<6)|(t->sap<<7)|(t->mute?0x8:0x0)|(t->sap_mute?0x10:0x0));
-}
-
-CARD16 tda9850_getstatus(TDA9850Ptr t)
-{
-CARD16 status;
-
-I2C_WriteRead(&(t->d), NULL, 0, (I2CByte *)&status, 2);
-return status;
-}
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "xf86.h"
+#include "xf86i2c.h"
+#include "tda9850.h"
+#include "i2c_def.h"
+
+#define TDA9850(a,b) { \
+ data[0]=a; \
+ data[1]=b; \
+ I2C_WriteRead(&(t->d), data, 2, NULL, 0); \
+ }
+
+TDA9850Ptr Detect_tda9850(I2CBusPtr b, I2CSlaveAddr addr)
+{
+ TDA9850Ptr t;
+ I2CByte a;
+
+ t = calloc(1, sizeof(TDA9850Rec));
+ if(t == NULL) return NULL;
+ switch(addr)
+ {
+ case TDA9850_ADDR_1:
+ t->d.DevName = "TDA9850 BTSC Stereo+SAP Audio Processor";
+ break;
+ default:
+ t->d.DevName = "Generic TDAxxxx";
+ break;
+ }
+ t->d.SlaveAddr = addr;
+ t->d.pI2CBus = b;
+ t->d.NextDev = NULL;
+ t->d.StartTimeout = b->StartTimeout;
+ t->d.BitTimeout = b->BitTimeout;
+ t->d.AcknTimeout = b->AcknTimeout;
+ t->d.ByteTimeout = b->ByteTimeout;
+
+ if(!I2C_WriteRead(&(t->d), NULL, 0, &a, 1))
+ {
+ free(t);
+ return NULL;
+ }
+
+ /* set default parameters */
+ if(!I2CDevInit(&(t->d)))
+ {
+ free(t);
+ return NULL;
+ }
+
+ return t;
+}
+
+Bool tda9850_init(TDA9850Ptr t)
+{
+ t->stereo = 1;
+ t->sap = 0;
+ t->mute = TRUE;
+ t->sap_mute = TRUE;
+ tda9850_setaudio(t);
+ return TRUE;
+}
+
+void tda9850_setaudio(TDA9850Ptr t)
+{
+CARD8 data[2];
+
+if(t->mux==2)
+{
+ TDA9850(0x04,0x0F); TDA9850(0x05,0x0F); TDA9850(0x06, 0x58);
+ TDA9850(0x07,0x07); TDA9850(0x08,0x00);
+ TDA9850(0x09,0x00); TDA9850(0x0A,0x03);
+} else
+{
+ TDA9850(0x04,0x07); TDA9850(0x05,0x07);
+ TDA9850(0x06,0x58); TDA9850(0x07,0x07);
+ TDA9850(0x08,0x10); TDA9850(0x09,0x10);
+ TDA9850(0x0A,0x03);
+}
+
+TDA9850(0x06,(t->stereo<<6)|(t->sap<<7)|(t->mute?0x8:0)|(t->sap_mute?0x10:0x0));
+}
+
+void tda9850_mute(TDA9850Ptr t, Bool mute)
+{
+CARD8 data[2];
+
+xf86DrvMsg(t->d.pI2CBus->scrnIndex, X_INFO, "tda9850_mute %s\n", mute ? "on" : "off");
+t->mute = mute;
+
+TDA9850(0x06,(t->stereo<<6)|(t->sap<<7)|(t->mute?0x8:0x0)|(t->sap_mute?0x10:0x0));
+}
+
+void tda9850_sap_mute(TDA9850Ptr t, Bool sap_mute)
+{
+CARD8 data[2];
+
+xf86DrvMsg(t->d.pI2CBus->scrnIndex, X_INFO, "tda9850_sap_mute %s\n", sap_mute ? "on" : "off");
+t->sap_mute = sap_mute;
+
+TDA9850(0x06,(t->stereo<<6)|(t->sap<<7)|(t->mute?0x8:0x0)|(t->sap_mute?0x10:0x0));
+}
+
+CARD16 tda9850_getstatus(TDA9850Ptr t)
+{
+CARD16 status;
+
+I2C_WriteRead(&(t->d), NULL, 0, (I2CByte *)&status, 2);
+return status;
+}
diff --git a/xorg-server/hw/xfree86/i2c/tda9885.c b/xorg-server/hw/xfree86/i2c/tda9885.c
index 4147dfdd7..f22233995 100644
--- a/xorg-server/hw/xfree86/i2c/tda9885.c
+++ b/xorg-server/hw/xfree86/i2c/tda9885.c
@@ -1,104 +1,104 @@
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "xf86.h"
-#include "xf86i2c.h"
-#include "tda9885.h"
-#include "i2c_def.h"
-
-
-TDA9885Ptr Detect_tda9885(I2CBusPtr b, I2CSlaveAddr addr)
-{
- TDA9885Ptr t;
- I2CByte a;
-
- t = xcalloc(1, sizeof(TDA9885Rec));
- if(t == NULL) return NULL;
- switch(addr)
- {
- case TDA9885_ADDR_1:
- case TDA9885_ADDR_2:
- case TDA9885_ADDR_3:
- case TDA9885_ADDR_4:
- t->d.DevName = "TDA9885 Alignment-free IF-PLL";
- break;
- default:
- t->d.DevName = "Generic TDAxxxx";
- break;
- }
- t->d.SlaveAddr = addr;
- t->d.pI2CBus = b;
- t->d.NextDev = NULL;
- t->d.StartTimeout = b->StartTimeout;
- t->d.BitTimeout = b->BitTimeout;
- t->d.AcknTimeout = b->AcknTimeout;
- t->d.ByteTimeout = b->ByteTimeout;
-
- if(!I2C_WriteRead(&(t->d), NULL, 0, &a, 1))
- {
- xfree(t);
- return NULL;
- }
-
- /* set default parameters */
- if(!I2CDevInit(&(t->d)))
- {
- xfree(t);
- return NULL;
- }
-
- return t;
-}
-
-Bool tda9885_init(TDA9885Ptr t)
-{
- t->forced_mute_audio=1;
- return TRUE;
-}
-
-void tda9885_getstatus(TDA9885Ptr t)
-{
-CARD8 value;
-
-I2C_WriteRead(&(t->d), NULL, 0, &value, 1);
-t->after_reset=value & 1;
-t->afc_status=(value >> 1) & 0xf;
-t->fm_carrier=(value>>5)& 1;
-t->vif_level=(value >>6) & 1;
-t->afc_win=(value >> 7)&1;
-}
-
-void tda9885_setparameters(TDA9885Ptr t)
-{
-CARD8 data[4];
-
-data[0]=0; /* start with subaddress 0 */
-data[1]=(t->sound_trap & 1) |
- ((t->auto_mute_fm &1)<<1) |
- ((t->carrier_mode &1)<<2) |
- ((t->modulation &3)<<3) |
- ((t->forced_mute_audio &1)<<5) |
- ((t->port1 & 1)<<6) |
- ((t->port2 &1)<<7); /* B data */
-data[2]=(t->top_adjustment & 0x1f) |
- ((t->deemphasis & 0x3)<<5) |
- ((t->audio_gain & 1) << 7); /* C data */
-data[3]=(t->standard_sound_carrier & 0x3) |
- ((t->standard_video_if & 0x07)<<2) |
- ((t->minimum_gain & 0x01)<<5) |
- ((t->gating & 0x01)<<6) |
- ((t->vif_agc & 0x01)<<7); /* E data */
-
-I2C_WriteRead(&(t->d), data, 4, NULL, 0);
-
-xf86DrvMsg(t->d.pI2CBus->scrnIndex,X_INFO,"TDA9885 setparam: B data: %x, C data: %x, E data: %x\n", data[1], data[2], data[3]);
-}
-
-void tda9885_dumpstatus(TDA9885Ptr t)
-{
-xf86DrvMsg(t->d.pI2CBus->scrnIndex,X_INFO,"TDA9885 status: after_reset=%d afc_status=%d (%3.1f kHz off) fm_carrier=%d vif_level=%d afc_win=%d %s\n",
- t->after_reset, t->afc_status,
- (t->afc_status<8)?-12.5-t->afc_status*25.0:-12.5+(16-t->afc_status)*25.0,
- t->fm_carrier, t->vif_level, t->afc_win, t->afc_win?"VCO in": "VCO out");
-}
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "xf86.h"
+#include "xf86i2c.h"
+#include "tda9885.h"
+#include "i2c_def.h"
+
+
+TDA9885Ptr Detect_tda9885(I2CBusPtr b, I2CSlaveAddr addr)
+{
+ TDA9885Ptr t;
+ I2CByte a;
+
+ t = calloc(1, sizeof(TDA9885Rec));
+ if(t == NULL) return NULL;
+ switch(addr)
+ {
+ case TDA9885_ADDR_1:
+ case TDA9885_ADDR_2:
+ case TDA9885_ADDR_3:
+ case TDA9885_ADDR_4:
+ t->d.DevName = "TDA9885 Alignment-free IF-PLL";
+ break;
+ default:
+ t->d.DevName = "Generic TDAxxxx";
+ break;
+ }
+ t->d.SlaveAddr = addr;
+ t->d.pI2CBus = b;
+ t->d.NextDev = NULL;
+ t->d.StartTimeout = b->StartTimeout;
+ t->d.BitTimeout = b->BitTimeout;
+ t->d.AcknTimeout = b->AcknTimeout;
+ t->d.ByteTimeout = b->ByteTimeout;
+
+ if(!I2C_WriteRead(&(t->d), NULL, 0, &a, 1))
+ {
+ free(t);
+ return NULL;
+ }
+
+ /* set default parameters */
+ if(!I2CDevInit(&(t->d)))
+ {
+ free(t);
+ return NULL;
+ }
+
+ return t;
+}
+
+Bool tda9885_init(TDA9885Ptr t)
+{
+ t->forced_mute_audio=1;
+ return TRUE;
+}
+
+void tda9885_getstatus(TDA9885Ptr t)
+{
+CARD8 value;
+
+I2C_WriteRead(&(t->d), NULL, 0, &value, 1);
+t->after_reset=value & 1;
+t->afc_status=(value >> 1) & 0xf;
+t->fm_carrier=(value>>5)& 1;
+t->vif_level=(value >>6) & 1;
+t->afc_win=(value >> 7)&1;
+}
+
+void tda9885_setparameters(TDA9885Ptr t)
+{
+CARD8 data[4];
+
+data[0]=0; /* start with subaddress 0 */
+data[1]=(t->sound_trap & 1) |
+ ((t->auto_mute_fm &1)<<1) |
+ ((t->carrier_mode &1)<<2) |
+ ((t->modulation &3)<<3) |
+ ((t->forced_mute_audio &1)<<5) |
+ ((t->port1 & 1)<<6) |
+ ((t->port2 &1)<<7); /* B data */
+data[2]=(t->top_adjustment & 0x1f) |
+ ((t->deemphasis & 0x3)<<5) |
+ ((t->audio_gain & 1) << 7); /* C data */
+data[3]=(t->standard_sound_carrier & 0x3) |
+ ((t->standard_video_if & 0x07)<<2) |
+ ((t->minimum_gain & 0x01)<<5) |
+ ((t->gating & 0x01)<<6) |
+ ((t->vif_agc & 0x01)<<7); /* E data */
+
+I2C_WriteRead(&(t->d), data, 4, NULL, 0);
+
+xf86DrvMsg(t->d.pI2CBus->scrnIndex,X_INFO,"TDA9885 setparam: B data: %x, C data: %x, E data: %x\n", data[1], data[2], data[3]);
+}
+
+void tda9885_dumpstatus(TDA9885Ptr t)
+{
+xf86DrvMsg(t->d.pI2CBus->scrnIndex,X_INFO,"TDA9885 status: after_reset=%d afc_status=%d (%3.1f kHz off) fm_carrier=%d vif_level=%d afc_win=%d %s\n",
+ t->after_reset, t->afc_status,
+ (t->afc_status<8)?-12.5-t->afc_status*25.0:-12.5+(16-t->afc_status)*25.0,
+ t->fm_carrier, t->vif_level, t->afc_win, t->afc_win?"VCO in": "VCO out");
+}
diff --git a/xorg-server/hw/xfree86/i2c/uda1380.c b/xorg-server/hw/xfree86/i2c/uda1380.c
index defda3cdc..eebe127ed 100644
--- a/xorg-server/hw/xfree86/i2c/uda1380.c
+++ b/xorg-server/hw/xfree86/i2c/uda1380.c
@@ -1,183 +1,183 @@
-/*************************************************************************************
- * Copyright (C) 2005 Bogdan D. bogdand@users.sourceforge.net
- *
- * 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 AUTHOR 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 author 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 author.
- *
- ************************************************************************************/
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "xf86.h"
-#include "xf86i2c.h"
-#include "uda1380.h"
-#include "i2c_def.h"
-
-UDA1380Ptr Detect_uda1380(I2CBusPtr b, I2CSlaveAddr addr)
-{
- UDA1380Ptr t;
- I2CByte a;
-
- t = xcalloc(1, sizeof(UDA1380Rec));
- if(t == NULL) return NULL;
- switch(addr)
- {
- case UDA1380_ADDR_1:
- case UDA1380_ADDR_2:
- t->d.DevName = "UDA1380 Stereo audion coder-decoder";
- break;
- default:
- t->d.DevName = "Generic UDAxxxx";
- break;
- }
- t->d.SlaveAddr = addr;
- t->d.pI2CBus = b;
- t->d.NextDev = NULL;
- t->d.StartTimeout = b->StartTimeout;
- t->d.BitTimeout = b->BitTimeout;
- t->d.AcknTimeout = b->AcknTimeout;
- t->d.ByteTimeout = b->ByteTimeout;
-
- if(!I2C_WriteRead(&(t->d), NULL, 0, &a, 1))
- {
- xfree(t);
- return NULL;
- }
-
- /* set default parameters */
- if(!I2CDevInit(&(t->d)))
- {
- xfree(t);
- return NULL;
- }
-
- xf86DrvMsg(t->d.pI2CBus->scrnIndex,X_INFO,"UDA1380 stereo coder-decoder detected\n");
-
- return t;
-}
-
-Bool uda1380_init(UDA1380Ptr t)
-{
- CARD8 data[3];
- CARD16 tmp;
- Bool ret;
-
- /* Power control */
- data[0] = 0x02;
- tmp = (1 << 13) | (1 << 10) | ( 1 << 8) | (1 << 7) | (1 << 6) | (1 << 3) | (1 << 1);
- data[1] = (CARD8)((tmp >> 8) & 0xff);
- data[2] = (CARD8)(tmp & 0xff);
- ret = I2C_WriteRead(&(t->d), data, 3, NULL, 0);
- if (ret == FALSE)
- {
- xf86DrvMsg(t->d.pI2CBus->scrnIndex,X_INFO,"UDA1380 failed to initialize\n");
- return FALSE;
- }
-
- /* Analog mixer (AVC) */
- data[0] = 0x03;
- /* the analog mixer is muted initially */
- data[1] = 0x3f;
- data[2] = 0x3f;
- ret = I2C_WriteRead(&(t->d), data, 3, NULL, 0);
- if (ret == FALSE)
- {
- xf86DrvMsg(t->d.pI2CBus->scrnIndex,X_INFO,"UDA1380 failed to initialize\n");
- return FALSE;
- }
-
- xf86DrvMsg(t->d.pI2CBus->scrnIndex,X_INFO,"UDA1380 initialized\n");
-
- return TRUE;
-}
-
-void uda1380_shutdown(UDA1380Ptr t)
-{
- CARD8 data[3];
- Bool ret;
-
- /* Power control */
- data[0] = 0x02;
- data[1] = 0;
- data[2] = 0;
- ret = I2C_WriteRead(&(t->d), data, 3, NULL, 0);
- if (ret == FALSE)
- xf86DrvMsg(t->d.pI2CBus->scrnIndex,X_INFO,"UDA1380 failed to shutdown\n");
-}
-
-void uda1380_setvolume(UDA1380Ptr t, INT32 value)
-{
- CARD8 data[3];
- /*
- * We have to scale the value ranging from -1000 to 1000 to 0x2c to 0
- */
- CARD8 volume = 47 - (CARD8)((value + 1000) * 47 / 2000);
- Bool ret;
-
- t->analog_mixer_settings = ((volume << 8) & 0x3f00) | (volume & 0x3f);
-
- /* Analog mixer (AVC) */
- data[0] = 0x03;
- data[1] = volume & 0x3f;
- data[2] = volume & 0x3f;
- ret = I2C_WriteRead(&(t->d), data, 3, NULL, 0);
- if (ret == FALSE)
- xf86DrvMsg(t->d.pI2CBus->scrnIndex,X_INFO,"UDA1380 failed to set volume\n");
-}
-
-void uda1380_mute(UDA1380Ptr t, Bool mute)
-{
- CARD8 data[3];
- Bool ret;
-
- if (mute == TRUE)
- {
- /* Analog mixer (AVC) */
- data[0] = 0x03;
- data[1] = 0xff;
- data[2] = 0xff;
- ret = I2C_WriteRead(&(t->d), data, 3, NULL, 0);
- if (ret == FALSE)
- xf86DrvMsg(t->d.pI2CBus->scrnIndex,X_INFO,"UDA1380 failed to mute\n");
- }
- else
- {
- /* Analog mixer (AVC) */
- data[0] = 0x03;
- data[1] = (CARD8)((t->analog_mixer_settings >> 8) & 0x3f);
- data[2] = (CARD8)(t->analog_mixer_settings & 0x3f);
- ret = I2C_WriteRead(&(t->d), data, 3, NULL, 0);
- if (ret == FALSE)
- xf86DrvMsg(t->d.pI2CBus->scrnIndex,X_INFO,"UDA1380 failed to unmute\n");
- }
-}
-
-void uda1380_getstatus(UDA1380Ptr t)
-{
-}
-
-void uda1380_setparameters(UDA1380Ptr t)
-{
-}
-
-void uda1380_dumpstatus(UDA1380Ptr t)
-{
-}
+/*************************************************************************************
+ * Copyright (C) 2005 Bogdan D. bogdand@users.sourceforge.net
+ *
+ * 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 AUTHOR 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 author 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 author.
+ *
+ ************************************************************************************/
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "xf86.h"
+#include "xf86i2c.h"
+#include "uda1380.h"
+#include "i2c_def.h"
+
+UDA1380Ptr Detect_uda1380(I2CBusPtr b, I2CSlaveAddr addr)
+{
+ UDA1380Ptr t;
+ I2CByte a;
+
+ t = calloc(1, sizeof(UDA1380Rec));
+ if(t == NULL) return NULL;
+ switch(addr)
+ {
+ case UDA1380_ADDR_1:
+ case UDA1380_ADDR_2:
+ t->d.DevName = "UDA1380 Stereo audion coder-decoder";
+ break;
+ default:
+ t->d.DevName = "Generic UDAxxxx";
+ break;
+ }
+ t->d.SlaveAddr = addr;
+ t->d.pI2CBus = b;
+ t->d.NextDev = NULL;
+ t->d.StartTimeout = b->StartTimeout;
+ t->d.BitTimeout = b->BitTimeout;
+ t->d.AcknTimeout = b->AcknTimeout;
+ t->d.ByteTimeout = b->ByteTimeout;
+
+ if(!I2C_WriteRead(&(t->d), NULL, 0, &a, 1))
+ {
+ free(t);
+ return NULL;
+ }
+
+ /* set default parameters */
+ if(!I2CDevInit(&(t->d)))
+ {
+ free(t);
+ return NULL;
+ }
+
+ xf86DrvMsg(t->d.pI2CBus->scrnIndex,X_INFO,"UDA1380 stereo coder-decoder detected\n");
+
+ return t;
+}
+
+Bool uda1380_init(UDA1380Ptr t)
+{
+ CARD8 data[3];
+ CARD16 tmp;
+ Bool ret;
+
+ /* Power control */
+ data[0] = 0x02;
+ tmp = (1 << 13) | (1 << 10) | ( 1 << 8) | (1 << 7) | (1 << 6) | (1 << 3) | (1 << 1);
+ data[1] = (CARD8)((tmp >> 8) & 0xff);
+ data[2] = (CARD8)(tmp & 0xff);
+ ret = I2C_WriteRead(&(t->d), data, 3, NULL, 0);
+ if (ret == FALSE)
+ {
+ xf86DrvMsg(t->d.pI2CBus->scrnIndex,X_INFO,"UDA1380 failed to initialize\n");
+ return FALSE;
+ }
+
+ /* Analog mixer (AVC) */
+ data[0] = 0x03;
+ /* the analog mixer is muted initially */
+ data[1] = 0x3f;
+ data[2] = 0x3f;
+ ret = I2C_WriteRead(&(t->d), data, 3, NULL, 0);
+ if (ret == FALSE)
+ {
+ xf86DrvMsg(t->d.pI2CBus->scrnIndex,X_INFO,"UDA1380 failed to initialize\n");
+ return FALSE;
+ }
+
+ xf86DrvMsg(t->d.pI2CBus->scrnIndex,X_INFO,"UDA1380 initialized\n");
+
+ return TRUE;
+}
+
+void uda1380_shutdown(UDA1380Ptr t)
+{
+ CARD8 data[3];
+ Bool ret;
+
+ /* Power control */
+ data[0] = 0x02;
+ data[1] = 0;
+ data[2] = 0;
+ ret = I2C_WriteRead(&(t->d), data, 3, NULL, 0);
+ if (ret == FALSE)
+ xf86DrvMsg(t->d.pI2CBus->scrnIndex,X_INFO,"UDA1380 failed to shutdown\n");
+}
+
+void uda1380_setvolume(UDA1380Ptr t, INT32 value)
+{
+ CARD8 data[3];
+ /*
+ * We have to scale the value ranging from -1000 to 1000 to 0x2c to 0
+ */
+ CARD8 volume = 47 - (CARD8)((value + 1000) * 47 / 2000);
+ Bool ret;
+
+ t->analog_mixer_settings = ((volume << 8) & 0x3f00) | (volume & 0x3f);
+
+ /* Analog mixer (AVC) */
+ data[0] = 0x03;
+ data[1] = volume & 0x3f;
+ data[2] = volume & 0x3f;
+ ret = I2C_WriteRead(&(t->d), data, 3, NULL, 0);
+ if (ret == FALSE)
+ xf86DrvMsg(t->d.pI2CBus->scrnIndex,X_INFO,"UDA1380 failed to set volume\n");
+}
+
+void uda1380_mute(UDA1380Ptr t, Bool mute)
+{
+ CARD8 data[3];
+ Bool ret;
+
+ if (mute == TRUE)
+ {
+ /* Analog mixer (AVC) */
+ data[0] = 0x03;
+ data[1] = 0xff;
+ data[2] = 0xff;
+ ret = I2C_WriteRead(&(t->d), data, 3, NULL, 0);
+ if (ret == FALSE)
+ xf86DrvMsg(t->d.pI2CBus->scrnIndex,X_INFO,"UDA1380 failed to mute\n");
+ }
+ else
+ {
+ /* Analog mixer (AVC) */
+ data[0] = 0x03;
+ data[1] = (CARD8)((t->analog_mixer_settings >> 8) & 0x3f);
+ data[2] = (CARD8)(t->analog_mixer_settings & 0x3f);
+ ret = I2C_WriteRead(&(t->d), data, 3, NULL, 0);
+ if (ret == FALSE)
+ xf86DrvMsg(t->d.pI2CBus->scrnIndex,X_INFO,"UDA1380 failed to unmute\n");
+ }
+}
+
+void uda1380_getstatus(UDA1380Ptr t)
+{
+}
+
+void uda1380_setparameters(UDA1380Ptr t)
+{
+}
+
+void uda1380_dumpstatus(UDA1380Ptr t)
+{
+}
diff --git a/xorg-server/hw/xfree86/i2c/xf86i2c.c b/xorg-server/hw/xfree86/i2c/xf86i2c.c
index 59832d6f9..488b6815f 100644
--- a/xorg-server/hw/xfree86/i2c/xf86i2c.c
+++ b/xorg-server/hw/xfree86/i2c/xf86i2c.c
@@ -1,866 +1,866 @@
-/*
- * Copyright (C) 1998 Itai Nahshon, Michael Schimek
- *
- * The original code was derived from and inspired by
- * the I2C driver from the Linux kernel.
- * (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
- */
-
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <sys/time.h>
-#include <string.h>
-
-#include "misc.h"
-#include "xf86.h"
-#include "xf86_OSproc.h"
-
-#include <X11/X.h>
-#include <X11/Xos.h>
-#include <X11/Xproto.h>
-#include "scrnintstr.h"
-#include "regionstr.h"
-#include "windowstr.h"
-#include "pixmapstr.h"
-#include "validate.h"
-#include "resource.h"
-#include "gcstruct.h"
-#include "dixstruct.h"
-
-#include "xf86i2c.h"
-
-#define I2C_TIMEOUT(x) /*(x)*/ /* Report timeouts */
-#define I2C_TRACE(x) /*(x)*/ /* Report progress */
-
-/* This is the default I2CUDelay function if not supplied by the driver.
- * High level I2C interfaces implementing the bus protocol in hardware
- * should supply this function too.
- *
- * Delay execution at least usec microseconds.
- * All values 0 to 1e6 inclusive must be expected.
- */
-
-static void
-I2CUDelay(I2CBusPtr b, int usec)
-{
- struct timeval begin, cur;
- long d_secs, d_usecs;
- long diff;
-
- if (usec > 0) {
- X_GETTIMEOFDAY(&begin);
- do {
- /* It would be nice to use {xf86}usleep,
- * but usleep (1) takes >10000 usec !
- */
- X_GETTIMEOFDAY(&cur);
- d_secs = (cur.tv_sec - begin.tv_sec);
- d_usecs = (cur.tv_usec - begin.tv_usec);
- diff = d_secs*1000000 + d_usecs;
- } while (diff>=0 && diff< (usec + 1));
- }
-}
-
-/* Most drivers will register just with GetBits/PutBits functions.
- * The following functions implement a software I2C protocol
- * by using the promitive functions given by the driver.
- * ================================================================
- *
- * It is assumed that there is just one master on the I2C bus, therefore
- * there is no explicit test for conflits.
- */
-
-#define RISEFALLTIME 2 /* usec, actually 300 to 1000 ns according to the i2c specs */
-
-/* Some devices will hold SCL low to slow down the bus or until
- * ready for transmission.
- *
- * This condition will be noticed when the master tries to raise
- * the SCL line. You can set the timeout to zero if the slave device
- * does not support this clock synchronization.
- */
-
-static Bool
-I2CRaiseSCL(I2CBusPtr b, int sda, int timeout)
-{
- int i, scl;
-
- b->I2CPutBits(b, 1, sda);
- b->I2CUDelay(b, b->RiseFallTime);
-
- for (i = timeout; i > 0; i -= b->RiseFallTime) {
- b->I2CGetBits(b, &scl, &sda);
- if (scl) break;
- b->I2CUDelay(b, b->RiseFallTime);
- }
-
- if (i <= 0) {
- I2C_TIMEOUT(ErrorF("[I2CRaiseSCL(<%s>, %d, %d) timeout]", b->BusName, sda, timeout));
- return FALSE;
- }
-
- return TRUE;
-}
-
-/* Send a start signal on the I2C bus. The start signal notifies
- * devices that a new transaction is initiated by the bus master.
- *
- * The start signal is always followed by a slave address.
- * Slave addresses are 8+ bits. The first 7 bits identify the
- * device and the last bit signals if this is a read (1) or
- * write (0) operation.
- *
- * There may be more than one start signal on one transaction.
- * This happens for example on some devices that allow reading
- * of registers. First send a start bit followed by the device
- * address (with the last bit 0) and the register number. Then send
- * a new start bit with the device address (with the last bit 1)
- * and then read the value from the device.
- *
- * Note this is function does not implement a multiple master
- * arbitration procedure.
- */
-
-static Bool
-I2CStart(I2CBusPtr b, int timeout)
-{
- if (!I2CRaiseSCL(b, 1, timeout))
- return FALSE;
-
- b->I2CPutBits(b, 1, 0);
- b->I2CUDelay(b, b->HoldTime);
- b->I2CPutBits(b, 0, 0);
- b->I2CUDelay(b, b->HoldTime);
-
- I2C_TRACE(ErrorF("\ni2c: <"));
-
- return TRUE;
-}
-
-/* This is the default I2CStop function if not supplied by the driver.
- *
- * Signal devices on the I2C bus that a transaction on the
- * bus has finished. There may be more than one start signal
- * on a transaction but only one stop signal.
- */
-
-static void
-I2CStop(I2CDevPtr d)
-{
- I2CBusPtr b = d->pI2CBus;
-
- b->I2CPutBits(b, 0, 0);
- b->I2CUDelay(b, b->RiseFallTime);
-
- b->I2CPutBits(b, 1, 0);
- b->I2CUDelay(b, b->HoldTime);
- b->I2CPutBits(b, 1, 1);
- b->I2CUDelay(b, b->HoldTime);
-
- I2C_TRACE(ErrorF(">\n"));
-}
-
-/* Write/Read a single bit to/from a device.
- * Return FALSE if a timeout occurs.
- */
-
-static Bool
-I2CWriteBit(I2CBusPtr b, int sda, int timeout)
-{
- Bool r;
-
- b->I2CPutBits(b, 0, sda);
- b->I2CUDelay(b, b->RiseFallTime);
-
- r = I2CRaiseSCL(b, sda, timeout);
- b->I2CUDelay(b, b->HoldTime);
-
- b->I2CPutBits(b, 0, sda);
- b->I2CUDelay(b, b->HoldTime);
-
- return r;
-}
-
-static Bool
-I2CReadBit(I2CBusPtr b, int *psda, int timeout)
-{
- Bool r;
- int scl;
-
- r = I2CRaiseSCL(b, 1, timeout);
- b->I2CUDelay(b, b->HoldTime);
-
- b->I2CGetBits(b, &scl, psda);
-
- b->I2CPutBits(b, 0, 1);
- b->I2CUDelay(b, b->HoldTime);
-
- return r;
-}
-
-/* This is the default I2CPutByte function if not supplied by the driver.
- *
- * A single byte is sent to the device.
- * The function returns FALSE if a timeout occurs, you should send
- * a stop condition afterwards to reset the bus.
- *
- * A timeout occurs,
- * if the slave pulls SCL to slow down the bus more than ByteTimeout usecs,
- * or slows down the bus for more than BitTimeout usecs for each bit,
- * or does not send an ACK bit (0) to acknowledge the transmission within
- * AcknTimeout usecs, but a NACK (1) bit.
- *
- * AcknTimeout must be at least b->HoldTime, the other timeouts can be
- * zero according to the comment on I2CRaiseSCL.
- */
-
-static Bool
-I2CPutByte(I2CDevPtr d, I2CByte data)
-{
- Bool r;
- int i, scl, sda;
- I2CBusPtr b = d->pI2CBus;
-
- if (!I2CWriteBit(b, (data >> 7) & 1, d->ByteTimeout))
- return FALSE;
-
- for (i = 6; i >= 0; i--)
- if (!I2CWriteBit(b, (data >> i) & 1, d->BitTimeout))
- return FALSE;
-
- b->I2CPutBits(b, 0, 1);
- b->I2CUDelay(b, b->RiseFallTime);
-
- r = I2CRaiseSCL(b, 1, b->HoldTime);
-
- if (r) {
- for (i = d->AcknTimeout; i > 0; i -= b->HoldTime) {
- b->I2CUDelay(b, b->HoldTime);
- b->I2CGetBits(b, &scl, &sda);
- if (sda == 0) break;
- }
-
- if (i <= 0) {
- I2C_TIMEOUT(ErrorF("[I2CPutByte(<%s>, 0x%02x, %d, %d, %d) timeout]",
- b->BusName, data, d->BitTimeout,
- d->ByteTimeout, d->AcknTimeout));
- r = FALSE;
- }
-
- I2C_TRACE(ErrorF("W%02x%c ", (int) data, sda ? '-' : '+'));
- }
-
- b->I2CPutBits(b, 0, 1);
- b->I2CUDelay(b, b->HoldTime);
-
- return r;
-}
-
-/* This is the default I2CGetByte function if not supplied by the driver.
- *
- * A single byte is read from the device.
- * The function returns FALSE if a timeout occurs, you should send
- * a stop condition afterwards to reset the bus.
- *
- * A timeout occurs,
- * if the slave pulls SCL to slow down the bus more than ByteTimeout usecs,
- * or slows down the bus for more than b->BitTimeout usecs for each bit.
- *
- * ByteTimeout must be at least b->HoldTime, the other timeouts can be
- * zero according to the comment on I2CRaiseSCL.
- *
- * For the <last> byte in a sequence the acknowledge bit NACK (1),
- * otherwise ACK (0) will be sent.
- */
-
-static Bool
-I2CGetByte(I2CDevPtr d, I2CByte *data, Bool last)
-{
- int i, sda;
- I2CBusPtr b = d->pI2CBus;
-
- b->I2CPutBits(b, 0, 1);
- b->I2CUDelay(b, b->RiseFallTime);
-
- if (!I2CReadBit(b, &sda, d->ByteTimeout))
- return FALSE;
-
- *data = (sda > 0) << 7;
-
- for (i = 6; i >= 0; i--)
- if (!I2CReadBit(b, &sda, d->BitTimeout))
- return FALSE;
- else
- *data |= (sda > 0) << i;
-
- if (!I2CWriteBit(b, last ? 1 : 0, d->BitTimeout))
- return FALSE;
-
- I2C_TRACE(ErrorF("R%02x%c ", (int) *data, last ? '+' : '-'));
-
- return TRUE;
-}
-
-/* This is the default I2CAddress function if not supplied by the driver.
- *
- * It creates the start condition, followed by the d->SlaveAddr.
- * Higher level functions must call this routine rather than
- * I2CStart/PutByte because a hardware I2C master may not be able
- * to send a slave address without a start condition.
- *
- * The same timeouts apply as with I2CPutByte and additional a
- * StartTimeout, similar to the ByteTimeout but for the start
- * condition.
- *
- * In case of a timeout, the bus is left in a clean idle condition.
- * I. e. you *must not* send a Stop. If this function succeeds, you *must*.
- *
- * The slave address format is 16 bit, with the legacy _8_bit_ slave address
- * in the least significant byte. This is, the slave address must include the
- * R/_W flag as least significant bit.
- *
- * The most significant byte of the address will be sent _after_ the LSB,
- * but only if the LSB indicates:
- * a) an 11 bit address, this is LSB = 1111 0xxx.
- * b) a 'general call address', this is LSB = 0000 000x - see the I2C specs
- * for more.
- */
-
-static Bool
-I2CAddress(I2CDevPtr d, I2CSlaveAddr addr)
-{
- if (I2CStart(d->pI2CBus, d->StartTimeout)) {
- if (I2CPutByte(d, addr & 0xFF)) {
- if ((addr & 0xF8) != 0xF0 &&
- (addr & 0xFE) != 0x00)
- return TRUE;
-
- if (I2CPutByte(d, (addr >> 8) & 0xFF))
- return TRUE;
- }
-
- I2CStop(d);
- }
-
- return FALSE;
-}
-
-/* These are the hardware independent I2C helper functions.
- * ========================================================
- */
-
-/* Function for probing. Just send the slave address
- * and return true if the device responds. The slave address
- * must have the lsb set to reflect a read (1) or write (0) access.
- * Don't expect a read- or write-only device will respond otherwise.
- */
-
-Bool
-xf86I2CProbeAddress(I2CBusPtr b, I2CSlaveAddr addr)
-{
- int r;
- I2CDevRec d;
-
- d.DevName = "Probing";
- d.BitTimeout = b->BitTimeout;
- d.ByteTimeout = b->ByteTimeout;
- d.AcknTimeout = b->AcknTimeout;
- d.StartTimeout = b->StartTimeout;
- d.SlaveAddr = addr;
- d.pI2CBus = b;
- d.NextDev = NULL;
-
- r = b->I2CAddress(&d, addr);
-
- if (r) b->I2CStop(&d);
-
- return r;
-}
-
-/* All functions below are related to devices and take the
- * slave address and timeout values from an I2CDevRec. They
- * return FALSE in case of an error (presumably a timeout).
- */
-
-/* General purpose read and write function.
- *
- * 1st, if nWrite > 0
- * Send a start condition
- * Send the slave address (1 or 2 bytes) with write flag
- * Write n bytes from WriteBuffer
- * 2nd, if nRead > 0
- * Send a start condition [again]
- * Send the slave address (1 or 2 bytes) with read flag
- * Read n bytes to ReadBuffer
- * 3rd, if a Start condition has been successfully sent,
- * Send a Stop condition.
- *
- * The functions exits immediately when an error occures,
- * not proceeding any data left. However, step 3 will
- * be executed anyway to leave the bus in clean idle state.
- */
-
-static Bool
-I2CWriteRead(I2CDevPtr d,
- I2CByte *WriteBuffer, int nWrite,
- I2CByte *ReadBuffer, int nRead)
-{
- Bool r = TRUE;
- I2CBusPtr b = d->pI2CBus;
- int s = 0;
-
- if (r && nWrite > 0) {
- r = b->I2CAddress(d, d->SlaveAddr & ~1);
- if (r) {
- for (; nWrite > 0; WriteBuffer++, nWrite--)
- if (!(r = b->I2CPutByte(d, *WriteBuffer)))
- break;
- s++;
- }
- }
-
- if (r && nRead > 0) {
- r = b->I2CAddress(d, d->SlaveAddr | 1);
- if (r) {
- for (; nRead > 0; ReadBuffer++, nRead--)
- if (!(r = b->I2CGetByte(d, ReadBuffer, nRead == 1)))
- break;
- s++;
- }
- }
-
- if (s) b->I2CStop(d);
-
- return r;
-}
-
-/* wrapper - for compatibility and convinience */
-
-Bool
-xf86I2CWriteRead(I2CDevPtr d,
- I2CByte *WriteBuffer, int nWrite,
- I2CByte *ReadBuffer, int nRead)
-{
- I2CBusPtr b = d->pI2CBus;
- return b->I2CWriteRead(d,WriteBuffer,nWrite,ReadBuffer,nRead);
-}
-
-/* Read a byte, the only readable register of a device.
- */
-
-Bool
-xf86I2CReadStatus(I2CDevPtr d, I2CByte *pbyte)
-{
- return xf86I2CWriteRead(d, NULL, 0, pbyte, 1);
-}
-
-/* Read a byte from one of the registers determined by its sub-address.
- */
-
-Bool
-xf86I2CReadByte(I2CDevPtr d, I2CByte subaddr, I2CByte *pbyte)
-{
- return xf86I2CWriteRead(d, &subaddr, 1, pbyte, 1);
-}
-
-/* Read bytes from subsequent registers determined by the
- * sub-address of the first register.
- */
-
-Bool
-xf86I2CReadBytes(I2CDevPtr d, I2CByte subaddr, I2CByte *pbyte, int n)
-{
- return xf86I2CWriteRead(d, &subaddr, 1, pbyte, n);
-}
-
-/* Read a word (high byte, then low byte) from one of the registers
- * determined by its sub-address.
- */
-
-Bool
-xf86I2CReadWord(I2CDevPtr d, I2CByte subaddr, unsigned short *pword)
-{
- I2CByte rb[2];
-
- if (!xf86I2CWriteRead(d, &subaddr, 1, rb, 2)) return FALSE;
-
- *pword = (rb[0] << 8) | rb[1];
-
- return TRUE;
-}
-
-/* Write a byte to one of the registers determined by its sub-address.
- */
-
-Bool
-xf86I2CWriteByte(I2CDevPtr d, I2CByte subaddr, I2CByte byte)
-{
- I2CByte wb[2];
-
- wb[0] = subaddr;
- wb[1] = byte;
-
- return xf86I2CWriteRead(d, wb, 2, NULL, 0);
-}
-
-/* Write bytes to subsequent registers determined by the
- * sub-address of the first register.
- */
-
-Bool
-xf86I2CWriteBytes(I2CDevPtr d, I2CByte subaddr,
- I2CByte *WriteBuffer, int nWrite)
-{
- I2CBusPtr b = d->pI2CBus;
- Bool r = TRUE;
-
- if (nWrite > 0) {
- r = b->I2CAddress(d, d->SlaveAddr & ~1);
- if (r){
- if ((r = b->I2CPutByte(d, subaddr)))
- for (; nWrite > 0; WriteBuffer++, nWrite--)
- if (!(r = b->I2CPutByte(d, *WriteBuffer)))
- break;
-
- b->I2CStop(d);
- }
- }
-
- return r;
-}
-
-/* Write a word (high byte, then low byte) to one of the registers
- * determined by its sub-address.
- */
-
-Bool
-xf86I2CWriteWord(I2CDevPtr d, I2CByte subaddr, unsigned short word)
-{
- I2CByte wb[3];
-
- wb[0] = subaddr;
- wb[1] = word >> 8;
- wb[2] = word & 0xFF;
-
- return xf86I2CWriteRead(d, wb, 3, NULL, 0);
-}
-
-/* Write a vector of bytes to not adjacent registers. This vector is,
- * 1st byte sub-address, 2nd byte value, 3rd byte sub-address asf.
- * This function is intended to initialize devices. Note this function
- * exits immediately when an error occurs, some registers may
- * remain uninitialized.
- */
-
-Bool
-xf86I2CWriteVec(I2CDevPtr d, I2CByte *vec, int nValues)
-{
- I2CBusPtr b = d->pI2CBus;
- Bool r = TRUE;
- int s = 0;
-
- if (nValues > 0) {
- for (; nValues > 0; nValues--, vec += 2) {
- if (!(r = b->I2CAddress(d, d->SlaveAddr & ~1)))
- break;
-
- s++;
-
- if (!(r = b->I2CPutByte(d, vec[0])))
- break;
-
- if (!(r = b->I2CPutByte(d, vec[1])))
- break;
- }
-
- if (s > 0) b->I2CStop(d);
- }
-
- return r;
-}
-
-/* Administrative functions.
- * =========================
- */
-
-/* Allocates an I2CDevRec for you and initializes with propper defaults
- * you may modify before calling xf86I2CDevInit. Your I2CDevRec must
- * contain at least a SlaveAddr, and a pI2CBus pointer to the bus this
- * device shall be linked to.
- *
- * See function I2CAddress for the slave address format. Always set
- * the least significant bit, indicating a read or write access, to zero.
- */
-
-I2CDevPtr
-xf86CreateI2CDevRec(void)
-{
- return xcalloc(1, sizeof(I2CDevRec));
-}
-
-/* Unlink an I2C device. If you got the I2CDevRec from xf86CreateI2CDevRec
- * you should set <unalloc> to free it.
- */
-
-void
-xf86DestroyI2CDevRec(I2CDevPtr d, Bool unalloc)
-{
- if (d) {
- I2CDevPtr *p;
-
- /* Remove this from the list of active I2C devices. */
-
- for (p = &d->pI2CBus->FirstDev; *p != NULL; p = &(*p)->NextDev)
- if (*p == d) {
- *p = (*p)->NextDev;
- break;
- }
-
- xf86DrvMsg(d->pI2CBus->scrnIndex, X_INFO,
- "I2C device \"%s:%s\" removed.\n",
- d->pI2CBus->BusName, d->DevName);
-
- if (unalloc) xfree(d);
- }
-}
-
-/* I2C transmissions are related to an I2CDevRec you must link to a
- * previously registered bus (see xf86I2CBusInit) before attempting
- * to read and write data. You may call xf86I2CProbeAddress first to
- * see if the device in question is present on this bus.
- *
- * xf86I2CDevInit will not allocate an I2CBusRec for you, instead you
- * may enter a pointer to a statically allocated I2CDevRec or the (modified)
- * result of xf86CreateI2CDevRec.
- *
- * If you don't specify timeouts for the device (n <= 0), it will inherit
- * the bus-wide defaults. The function returns TRUE on success.
- */
-
-Bool
-xf86I2CDevInit(I2CDevPtr d)
-{
- I2CBusPtr b;
-
- if (d == NULL ||
- (b = d->pI2CBus) == NULL ||
- (d->SlaveAddr & 1) ||
- xf86I2CFindDev(b, d->SlaveAddr) != NULL)
- return FALSE;
-
- if (d->BitTimeout <= 0) d->BitTimeout = b->BitTimeout;
- if (d->ByteTimeout <= 0) d->ByteTimeout = b->ByteTimeout;
- if (d->AcknTimeout <= 0) d->AcknTimeout = b->AcknTimeout;
- if (d->StartTimeout <= 0) d->StartTimeout = b->StartTimeout;
-
- d->NextDev = b->FirstDev;
- b->FirstDev = d;
-
- xf86DrvMsg(b->scrnIndex, X_INFO,
- "I2C device \"%s:%s\" registered at address 0x%02X.\n",
- b->BusName, d->DevName, d->SlaveAddr);
-
- return TRUE;
-}
-
-I2CDevPtr
-xf86I2CFindDev(I2CBusPtr b, I2CSlaveAddr addr)
-{
- I2CDevPtr d;
-
- if (b) {
- for (d = b->FirstDev; d != NULL; d = d->NextDev)
- if (d->SlaveAddr == addr)
- return d;
- }
-
- return NULL;
-}
-
-static I2CBusPtr I2CBusList;
-
-/* Allocates an I2CBusRec for you and initializes with propper defaults
- * you may modify before calling xf86I2CBusInit. Your I2CBusRec must
- * contain at least a BusName, a scrnIndex (or -1), and a complete set
- * of either high or low level I2C function pointers. You may pass
- * bus-wide timeouts, otherwise inplausible values will be replaced
- * with safe defaults.
- */
-
-I2CBusPtr
-xf86CreateI2CBusRec(void)
-{
- I2CBusPtr b;
-
- b = (I2CBusPtr) xcalloc(1, sizeof(I2CBusRec));
-
- if (b != NULL) {
- b->scrnIndex = -1;
- b->HoldTime = 5; /* 100 kHz bus */
- b->BitTimeout = 5;
- b->ByteTimeout = 5;
- b->AcknTimeout = 5;
- b->StartTimeout = 5;
- b->RiseFallTime = RISEFALLTIME;
- }
-
- return b;
-}
-
-/* Unregister an I2C bus. If you got the I2CBusRec from xf86CreateI2CBusRec
- * you should set <unalloc> to free it. If you set <devs_too>, the function
- * xf86DestroyI2CDevRec will be called for all devices linked to the bus
- * first, passing down the <unalloc> option.
- */
-
-void
-xf86DestroyI2CBusRec(I2CBusPtr b, Bool unalloc, Bool devs_too)
-{
- if (b) {
- I2CBusPtr *p;
-
- /* Remove this from the list of active I2C buses */
-
- for (p = &I2CBusList; *p != NULL; p = &(*p)->NextBus)
- if (*p == b) {
- *p = (*p)->NextBus;
- break;
- }
-
- if (b->FirstDev != NULL) {
- if (devs_too) {
- I2CDevPtr d;
-
- while ((d = b->FirstDev) != NULL) {
- b->FirstDev = d->NextDev;
- xf86DestroyI2CDevRec(d, unalloc);
- }
- } else {
- if (unalloc) {
- xf86Msg(X_ERROR, "i2c bug: Attempt to remove I2C bus \"%s\", "
- "but device list is not empty.\n",
- b->BusName);
- return;
- }
- }
- }
-
- xf86DrvMsg(b->scrnIndex, X_INFO, "I2C bus \"%s\" removed.\n",
- b->BusName);
-
- if (unalloc) xfree(b);
- }
-}
-
-/* I2C masters have to register themselves using this function.
- * It will not allocate an I2CBusRec for you, instead you may enter
- * a pointer to a statically allocated I2CBusRec or the (modified)
- * result of xf86CreateI2CBusRec. Returns TRUE on success.
- *
- * At this point there won't be any traffic on the I2C bus.
- */
-
-Bool
-xf86I2CBusInit(I2CBusPtr b)
-{
- /* I2C buses must be identified by a unique scrnIndex
- * and name. If scrnIndex is unspecified (a negative value),
- * then the name must be unique throughout the server.
- */
-
- if (b->BusName == NULL ||
- xf86I2CFindBus(b->scrnIndex, b->BusName) != NULL)
- return FALSE;
-
- /* If the high level functions are not
- * supplied, use the generic functions.
- * In this case we need the low-level
- * function.
- */
- if (b->I2CWriteRead == NULL)
- {
- b->I2CWriteRead=I2CWriteRead;
-
- if (b->I2CPutBits == NULL ||
- b->I2CGetBits == NULL)
- {
- if (b->I2CPutByte == NULL ||
- b->I2CGetByte == NULL ||
- b->I2CAddress == NULL ||
- b->I2CStart == NULL ||
- b->I2CStop == NULL)
- return FALSE;
- } else {
- b->I2CPutByte = I2CPutByte;
- b->I2CGetByte = I2CGetByte;
- b->I2CAddress = I2CAddress;
- b->I2CStop = I2CStop;
- b->I2CStart = I2CStart;
- }
- }
-
- if (b->I2CUDelay == NULL)
- b->I2CUDelay = I2CUDelay;
-
- if (b->HoldTime < 2) b->HoldTime = 5;
- if (b->BitTimeout <= 0) b->BitTimeout = b->HoldTime;
- if (b->ByteTimeout <= 0) b->ByteTimeout = b->HoldTime;
- if (b->AcknTimeout <= 0) b->AcknTimeout = b->HoldTime;
- if (b->StartTimeout <= 0) b->StartTimeout = b->HoldTime;
-
- /* Put new bus on list. */
-
- b->NextBus = I2CBusList;
- I2CBusList = b;
-
- xf86DrvMsg(b->scrnIndex, X_INFO, "I2C bus \"%s\" initialized.\n",
- b->BusName);
-
- return TRUE;
-}
-
-I2CBusPtr
-xf86I2CFindBus(int scrnIndex, char *name)
-{
- I2CBusPtr p;
-
- if (name != NULL)
- for (p = I2CBusList; p != NULL; p = p->NextBus)
- if (scrnIndex < 0 || p->scrnIndex == scrnIndex)
- if (!strcmp(p->BusName, name))
- return p;
-
- return NULL;
-}
-
-/*
- * Return an array of I2CBusPtr's related to a screen. The caller is
- * responsible for freeing the array.
- */
-int
-xf86I2CGetScreenBuses(int scrnIndex, I2CBusPtr **pppI2CBus)
-{
- I2CBusPtr pI2CBus;
- int n = 0;
-
- if (pppI2CBus)
- *pppI2CBus = NULL;
-
- for (pI2CBus = I2CBusList; pI2CBus; pI2CBus = pI2CBus->NextBus) {
- if ((pI2CBus->scrnIndex >= 0) && (pI2CBus->scrnIndex != scrnIndex))
- continue;
-
- n++;
-
- if (!pppI2CBus)
- continue;
-
- *pppI2CBus = xnfrealloc(*pppI2CBus, n * sizeof(I2CBusPtr));
- (*pppI2CBus)[n - 1] = pI2CBus;
- }
-
- return n;
-}
+/*
+ * Copyright (C) 1998 Itai Nahshon, Michael Schimek
+ *
+ * The original code was derived from and inspired by
+ * the I2C driver from the Linux kernel.
+ * (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
+ */
+
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <sys/time.h>
+#include <string.h>
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include <X11/X.h>
+#include <X11/Xos.h>
+#include <X11/Xproto.h>
+#include "scrnintstr.h"
+#include "regionstr.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "validate.h"
+#include "resource.h"
+#include "gcstruct.h"
+#include "dixstruct.h"
+
+#include "xf86i2c.h"
+
+#define I2C_TIMEOUT(x) /*(x)*/ /* Report timeouts */
+#define I2C_TRACE(x) /*(x)*/ /* Report progress */
+
+/* This is the default I2CUDelay function if not supplied by the driver.
+ * High level I2C interfaces implementing the bus protocol in hardware
+ * should supply this function too.
+ *
+ * Delay execution at least usec microseconds.
+ * All values 0 to 1e6 inclusive must be expected.
+ */
+
+static void
+I2CUDelay(I2CBusPtr b, int usec)
+{
+ struct timeval begin, cur;
+ long d_secs, d_usecs;
+ long diff;
+
+ if (usec > 0) {
+ X_GETTIMEOFDAY(&begin);
+ do {
+ /* It would be nice to use {xf86}usleep,
+ * but usleep (1) takes >10000 usec !
+ */
+ X_GETTIMEOFDAY(&cur);
+ d_secs = (cur.tv_sec - begin.tv_sec);
+ d_usecs = (cur.tv_usec - begin.tv_usec);
+ diff = d_secs*1000000 + d_usecs;
+ } while (diff>=0 && diff< (usec + 1));
+ }
+}
+
+/* Most drivers will register just with GetBits/PutBits functions.
+ * The following functions implement a software I2C protocol
+ * by using the promitive functions given by the driver.
+ * ================================================================
+ *
+ * It is assumed that there is just one master on the I2C bus, therefore
+ * there is no explicit test for conflits.
+ */
+
+#define RISEFALLTIME 2 /* usec, actually 300 to 1000 ns according to the i2c specs */
+
+/* Some devices will hold SCL low to slow down the bus or until
+ * ready for transmission.
+ *
+ * This condition will be noticed when the master tries to raise
+ * the SCL line. You can set the timeout to zero if the slave device
+ * does not support this clock synchronization.
+ */
+
+static Bool
+I2CRaiseSCL(I2CBusPtr b, int sda, int timeout)
+{
+ int i, scl;
+
+ b->I2CPutBits(b, 1, sda);
+ b->I2CUDelay(b, b->RiseFallTime);
+
+ for (i = timeout; i > 0; i -= b->RiseFallTime) {
+ b->I2CGetBits(b, &scl, &sda);
+ if (scl) break;
+ b->I2CUDelay(b, b->RiseFallTime);
+ }
+
+ if (i <= 0) {
+ I2C_TIMEOUT(ErrorF("[I2CRaiseSCL(<%s>, %d, %d) timeout]", b->BusName, sda, timeout));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Send a start signal on the I2C bus. The start signal notifies
+ * devices that a new transaction is initiated by the bus master.
+ *
+ * The start signal is always followed by a slave address.
+ * Slave addresses are 8+ bits. The first 7 bits identify the
+ * device and the last bit signals if this is a read (1) or
+ * write (0) operation.
+ *
+ * There may be more than one start signal on one transaction.
+ * This happens for example on some devices that allow reading
+ * of registers. First send a start bit followed by the device
+ * address (with the last bit 0) and the register number. Then send
+ * a new start bit with the device address (with the last bit 1)
+ * and then read the value from the device.
+ *
+ * Note this is function does not implement a multiple master
+ * arbitration procedure.
+ */
+
+static Bool
+I2CStart(I2CBusPtr b, int timeout)
+{
+ if (!I2CRaiseSCL(b, 1, timeout))
+ return FALSE;
+
+ b->I2CPutBits(b, 1, 0);
+ b->I2CUDelay(b, b->HoldTime);
+ b->I2CPutBits(b, 0, 0);
+ b->I2CUDelay(b, b->HoldTime);
+
+ I2C_TRACE(ErrorF("\ni2c: <"));
+
+ return TRUE;
+}
+
+/* This is the default I2CStop function if not supplied by the driver.
+ *
+ * Signal devices on the I2C bus that a transaction on the
+ * bus has finished. There may be more than one start signal
+ * on a transaction but only one stop signal.
+ */
+
+static void
+I2CStop(I2CDevPtr d)
+{
+ I2CBusPtr b = d->pI2CBus;
+
+ b->I2CPutBits(b, 0, 0);
+ b->I2CUDelay(b, b->RiseFallTime);
+
+ b->I2CPutBits(b, 1, 0);
+ b->I2CUDelay(b, b->HoldTime);
+ b->I2CPutBits(b, 1, 1);
+ b->I2CUDelay(b, b->HoldTime);
+
+ I2C_TRACE(ErrorF(">\n"));
+}
+
+/* Write/Read a single bit to/from a device.
+ * Return FALSE if a timeout occurs.
+ */
+
+static Bool
+I2CWriteBit(I2CBusPtr b, int sda, int timeout)
+{
+ Bool r;
+
+ b->I2CPutBits(b, 0, sda);
+ b->I2CUDelay(b, b->RiseFallTime);
+
+ r = I2CRaiseSCL(b, sda, timeout);
+ b->I2CUDelay(b, b->HoldTime);
+
+ b->I2CPutBits(b, 0, sda);
+ b->I2CUDelay(b, b->HoldTime);
+
+ return r;
+}
+
+static Bool
+I2CReadBit(I2CBusPtr b, int *psda, int timeout)
+{
+ Bool r;
+ int scl;
+
+ r = I2CRaiseSCL(b, 1, timeout);
+ b->I2CUDelay(b, b->HoldTime);
+
+ b->I2CGetBits(b, &scl, psda);
+
+ b->I2CPutBits(b, 0, 1);
+ b->I2CUDelay(b, b->HoldTime);
+
+ return r;
+}
+
+/* This is the default I2CPutByte function if not supplied by the driver.
+ *
+ * A single byte is sent to the device.
+ * The function returns FALSE if a timeout occurs, you should send
+ * a stop condition afterwards to reset the bus.
+ *
+ * A timeout occurs,
+ * if the slave pulls SCL to slow down the bus more than ByteTimeout usecs,
+ * or slows down the bus for more than BitTimeout usecs for each bit,
+ * or does not send an ACK bit (0) to acknowledge the transmission within
+ * AcknTimeout usecs, but a NACK (1) bit.
+ *
+ * AcknTimeout must be at least b->HoldTime, the other timeouts can be
+ * zero according to the comment on I2CRaiseSCL.
+ */
+
+static Bool
+I2CPutByte(I2CDevPtr d, I2CByte data)
+{
+ Bool r;
+ int i, scl, sda;
+ I2CBusPtr b = d->pI2CBus;
+
+ if (!I2CWriteBit(b, (data >> 7) & 1, d->ByteTimeout))
+ return FALSE;
+
+ for (i = 6; i >= 0; i--)
+ if (!I2CWriteBit(b, (data >> i) & 1, d->BitTimeout))
+ return FALSE;
+
+ b->I2CPutBits(b, 0, 1);
+ b->I2CUDelay(b, b->RiseFallTime);
+
+ r = I2CRaiseSCL(b, 1, b->HoldTime);
+
+ if (r) {
+ for (i = d->AcknTimeout; i > 0; i -= b->HoldTime) {
+ b->I2CUDelay(b, b->HoldTime);
+ b->I2CGetBits(b, &scl, &sda);
+ if (sda == 0) break;
+ }
+
+ if (i <= 0) {
+ I2C_TIMEOUT(ErrorF("[I2CPutByte(<%s>, 0x%02x, %d, %d, %d) timeout]",
+ b->BusName, data, d->BitTimeout,
+ d->ByteTimeout, d->AcknTimeout));
+ r = FALSE;
+ }
+
+ I2C_TRACE(ErrorF("W%02x%c ", (int) data, sda ? '-' : '+'));
+ }
+
+ b->I2CPutBits(b, 0, 1);
+ b->I2CUDelay(b, b->HoldTime);
+
+ return r;
+}
+
+/* This is the default I2CGetByte function if not supplied by the driver.
+ *
+ * A single byte is read from the device.
+ * The function returns FALSE if a timeout occurs, you should send
+ * a stop condition afterwards to reset the bus.
+ *
+ * A timeout occurs,
+ * if the slave pulls SCL to slow down the bus more than ByteTimeout usecs,
+ * or slows down the bus for more than b->BitTimeout usecs for each bit.
+ *
+ * ByteTimeout must be at least b->HoldTime, the other timeouts can be
+ * zero according to the comment on I2CRaiseSCL.
+ *
+ * For the <last> byte in a sequence the acknowledge bit NACK (1),
+ * otherwise ACK (0) will be sent.
+ */
+
+static Bool
+I2CGetByte(I2CDevPtr d, I2CByte *data, Bool last)
+{
+ int i, sda;
+ I2CBusPtr b = d->pI2CBus;
+
+ b->I2CPutBits(b, 0, 1);
+ b->I2CUDelay(b, b->RiseFallTime);
+
+ if (!I2CReadBit(b, &sda, d->ByteTimeout))
+ return FALSE;
+
+ *data = (sda > 0) << 7;
+
+ for (i = 6; i >= 0; i--)
+ if (!I2CReadBit(b, &sda, d->BitTimeout))
+ return FALSE;
+ else
+ *data |= (sda > 0) << i;
+
+ if (!I2CWriteBit(b, last ? 1 : 0, d->BitTimeout))
+ return FALSE;
+
+ I2C_TRACE(ErrorF("R%02x%c ", (int) *data, last ? '+' : '-'));
+
+ return TRUE;
+}
+
+/* This is the default I2CAddress function if not supplied by the driver.
+ *
+ * It creates the start condition, followed by the d->SlaveAddr.
+ * Higher level functions must call this routine rather than
+ * I2CStart/PutByte because a hardware I2C master may not be able
+ * to send a slave address without a start condition.
+ *
+ * The same timeouts apply as with I2CPutByte and additional a
+ * StartTimeout, similar to the ByteTimeout but for the start
+ * condition.
+ *
+ * In case of a timeout, the bus is left in a clean idle condition.
+ * I. e. you *must not* send a Stop. If this function succeeds, you *must*.
+ *
+ * The slave address format is 16 bit, with the legacy _8_bit_ slave address
+ * in the least significant byte. This is, the slave address must include the
+ * R/_W flag as least significant bit.
+ *
+ * The most significant byte of the address will be sent _after_ the LSB,
+ * but only if the LSB indicates:
+ * a) an 11 bit address, this is LSB = 1111 0xxx.
+ * b) a 'general call address', this is LSB = 0000 000x - see the I2C specs
+ * for more.
+ */
+
+static Bool
+I2CAddress(I2CDevPtr d, I2CSlaveAddr addr)
+{
+ if (I2CStart(d->pI2CBus, d->StartTimeout)) {
+ if (I2CPutByte(d, addr & 0xFF)) {
+ if ((addr & 0xF8) != 0xF0 &&
+ (addr & 0xFE) != 0x00)
+ return TRUE;
+
+ if (I2CPutByte(d, (addr >> 8) & 0xFF))
+ return TRUE;
+ }
+
+ I2CStop(d);
+ }
+
+ return FALSE;
+}
+
+/* These are the hardware independent I2C helper functions.
+ * ========================================================
+ */
+
+/* Function for probing. Just send the slave address
+ * and return true if the device responds. The slave address
+ * must have the lsb set to reflect a read (1) or write (0) access.
+ * Don't expect a read- or write-only device will respond otherwise.
+ */
+
+Bool
+xf86I2CProbeAddress(I2CBusPtr b, I2CSlaveAddr addr)
+{
+ int r;
+ I2CDevRec d;
+
+ d.DevName = "Probing";
+ d.BitTimeout = b->BitTimeout;
+ d.ByteTimeout = b->ByteTimeout;
+ d.AcknTimeout = b->AcknTimeout;
+ d.StartTimeout = b->StartTimeout;
+ d.SlaveAddr = addr;
+ d.pI2CBus = b;
+ d.NextDev = NULL;
+
+ r = b->I2CAddress(&d, addr);
+
+ if (r) b->I2CStop(&d);
+
+ return r;
+}
+
+/* All functions below are related to devices and take the
+ * slave address and timeout values from an I2CDevRec. They
+ * return FALSE in case of an error (presumably a timeout).
+ */
+
+/* General purpose read and write function.
+ *
+ * 1st, if nWrite > 0
+ * Send a start condition
+ * Send the slave address (1 or 2 bytes) with write flag
+ * Write n bytes from WriteBuffer
+ * 2nd, if nRead > 0
+ * Send a start condition [again]
+ * Send the slave address (1 or 2 bytes) with read flag
+ * Read n bytes to ReadBuffer
+ * 3rd, if a Start condition has been successfully sent,
+ * Send a Stop condition.
+ *
+ * The functions exits immediately when an error occures,
+ * not proceeding any data left. However, step 3 will
+ * be executed anyway to leave the bus in clean idle state.
+ */
+
+static Bool
+I2CWriteRead(I2CDevPtr d,
+ I2CByte *WriteBuffer, int nWrite,
+ I2CByte *ReadBuffer, int nRead)
+{
+ Bool r = TRUE;
+ I2CBusPtr b = d->pI2CBus;
+ int s = 0;
+
+ if (r && nWrite > 0) {
+ r = b->I2CAddress(d, d->SlaveAddr & ~1);
+ if (r) {
+ for (; nWrite > 0; WriteBuffer++, nWrite--)
+ if (!(r = b->I2CPutByte(d, *WriteBuffer)))
+ break;
+ s++;
+ }
+ }
+
+ if (r && nRead > 0) {
+ r = b->I2CAddress(d, d->SlaveAddr | 1);
+ if (r) {
+ for (; nRead > 0; ReadBuffer++, nRead--)
+ if (!(r = b->I2CGetByte(d, ReadBuffer, nRead == 1)))
+ break;
+ s++;
+ }
+ }
+
+ if (s) b->I2CStop(d);
+
+ return r;
+}
+
+/* wrapper - for compatibility and convinience */
+
+Bool
+xf86I2CWriteRead(I2CDevPtr d,
+ I2CByte *WriteBuffer, int nWrite,
+ I2CByte *ReadBuffer, int nRead)
+{
+ I2CBusPtr b = d->pI2CBus;
+ return b->I2CWriteRead(d,WriteBuffer,nWrite,ReadBuffer,nRead);
+}
+
+/* Read a byte, the only readable register of a device.
+ */
+
+Bool
+xf86I2CReadStatus(I2CDevPtr d, I2CByte *pbyte)
+{
+ return xf86I2CWriteRead(d, NULL, 0, pbyte, 1);
+}
+
+/* Read a byte from one of the registers determined by its sub-address.
+ */
+
+Bool
+xf86I2CReadByte(I2CDevPtr d, I2CByte subaddr, I2CByte *pbyte)
+{
+ return xf86I2CWriteRead(d, &subaddr, 1, pbyte, 1);
+}
+
+/* Read bytes from subsequent registers determined by the
+ * sub-address of the first register.
+ */
+
+Bool
+xf86I2CReadBytes(I2CDevPtr d, I2CByte subaddr, I2CByte *pbyte, int n)
+{
+ return xf86I2CWriteRead(d, &subaddr, 1, pbyte, n);
+}
+
+/* Read a word (high byte, then low byte) from one of the registers
+ * determined by its sub-address.
+ */
+
+Bool
+xf86I2CReadWord(I2CDevPtr d, I2CByte subaddr, unsigned short *pword)
+{
+ I2CByte rb[2];
+
+ if (!xf86I2CWriteRead(d, &subaddr, 1, rb, 2)) return FALSE;
+
+ *pword = (rb[0] << 8) | rb[1];
+
+ return TRUE;
+}
+
+/* Write a byte to one of the registers determined by its sub-address.
+ */
+
+Bool
+xf86I2CWriteByte(I2CDevPtr d, I2CByte subaddr, I2CByte byte)
+{
+ I2CByte wb[2];
+
+ wb[0] = subaddr;
+ wb[1] = byte;
+
+ return xf86I2CWriteRead(d, wb, 2, NULL, 0);
+}
+
+/* Write bytes to subsequent registers determined by the
+ * sub-address of the first register.
+ */
+
+Bool
+xf86I2CWriteBytes(I2CDevPtr d, I2CByte subaddr,
+ I2CByte *WriteBuffer, int nWrite)
+{
+ I2CBusPtr b = d->pI2CBus;
+ Bool r = TRUE;
+
+ if (nWrite > 0) {
+ r = b->I2CAddress(d, d->SlaveAddr & ~1);
+ if (r){
+ if ((r = b->I2CPutByte(d, subaddr)))
+ for (; nWrite > 0; WriteBuffer++, nWrite--)
+ if (!(r = b->I2CPutByte(d, *WriteBuffer)))
+ break;
+
+ b->I2CStop(d);
+ }
+ }
+
+ return r;
+}
+
+/* Write a word (high byte, then low byte) to one of the registers
+ * determined by its sub-address.
+ */
+
+Bool
+xf86I2CWriteWord(I2CDevPtr d, I2CByte subaddr, unsigned short word)
+{
+ I2CByte wb[3];
+
+ wb[0] = subaddr;
+ wb[1] = word >> 8;
+ wb[2] = word & 0xFF;
+
+ return xf86I2CWriteRead(d, wb, 3, NULL, 0);
+}
+
+/* Write a vector of bytes to not adjacent registers. This vector is,
+ * 1st byte sub-address, 2nd byte value, 3rd byte sub-address asf.
+ * This function is intended to initialize devices. Note this function
+ * exits immediately when an error occurs, some registers may
+ * remain uninitialized.
+ */
+
+Bool
+xf86I2CWriteVec(I2CDevPtr d, I2CByte *vec, int nValues)
+{
+ I2CBusPtr b = d->pI2CBus;
+ Bool r = TRUE;
+ int s = 0;
+
+ if (nValues > 0) {
+ for (; nValues > 0; nValues--, vec += 2) {
+ if (!(r = b->I2CAddress(d, d->SlaveAddr & ~1)))
+ break;
+
+ s++;
+
+ if (!(r = b->I2CPutByte(d, vec[0])))
+ break;
+
+ if (!(r = b->I2CPutByte(d, vec[1])))
+ break;
+ }
+
+ if (s > 0) b->I2CStop(d);
+ }
+
+ return r;
+}
+
+/* Administrative functions.
+ * =========================
+ */
+
+/* Allocates an I2CDevRec for you and initializes with propper defaults
+ * you may modify before calling xf86I2CDevInit. Your I2CDevRec must
+ * contain at least a SlaveAddr, and a pI2CBus pointer to the bus this
+ * device shall be linked to.
+ *
+ * See function I2CAddress for the slave address format. Always set
+ * the least significant bit, indicating a read or write access, to zero.
+ */
+
+I2CDevPtr
+xf86CreateI2CDevRec(void)
+{
+ return calloc(1, sizeof(I2CDevRec));
+}
+
+/* Unlink an I2C device. If you got the I2CDevRec from xf86CreateI2CDevRec
+ * you should set <unalloc> to free it.
+ */
+
+void
+xf86DestroyI2CDevRec(I2CDevPtr d, Bool unalloc)
+{
+ if (d) {
+ I2CDevPtr *p;
+
+ /* Remove this from the list of active I2C devices. */
+
+ for (p = &d->pI2CBus->FirstDev; *p != NULL; p = &(*p)->NextDev)
+ if (*p == d) {
+ *p = (*p)->NextDev;
+ break;
+ }
+
+ xf86DrvMsg(d->pI2CBus->scrnIndex, X_INFO,
+ "I2C device \"%s:%s\" removed.\n",
+ d->pI2CBus->BusName, d->DevName);
+
+ if (unalloc) free(d);
+ }
+}
+
+/* I2C transmissions are related to an I2CDevRec you must link to a
+ * previously registered bus (see xf86I2CBusInit) before attempting
+ * to read and write data. You may call xf86I2CProbeAddress first to
+ * see if the device in question is present on this bus.
+ *
+ * xf86I2CDevInit will not allocate an I2CBusRec for you, instead you
+ * may enter a pointer to a statically allocated I2CDevRec or the (modified)
+ * result of xf86CreateI2CDevRec.
+ *
+ * If you don't specify timeouts for the device (n <= 0), it will inherit
+ * the bus-wide defaults. The function returns TRUE on success.
+ */
+
+Bool
+xf86I2CDevInit(I2CDevPtr d)
+{
+ I2CBusPtr b;
+
+ if (d == NULL ||
+ (b = d->pI2CBus) == NULL ||
+ (d->SlaveAddr & 1) ||
+ xf86I2CFindDev(b, d->SlaveAddr) != NULL)
+ return FALSE;
+
+ if (d->BitTimeout <= 0) d->BitTimeout = b->BitTimeout;
+ if (d->ByteTimeout <= 0) d->ByteTimeout = b->ByteTimeout;
+ if (d->AcknTimeout <= 0) d->AcknTimeout = b->AcknTimeout;
+ if (d->StartTimeout <= 0) d->StartTimeout = b->StartTimeout;
+
+ d->NextDev = b->FirstDev;
+ b->FirstDev = d;
+
+ xf86DrvMsg(b->scrnIndex, X_INFO,
+ "I2C device \"%s:%s\" registered at address 0x%02X.\n",
+ b->BusName, d->DevName, d->SlaveAddr);
+
+ return TRUE;
+}
+
+I2CDevPtr
+xf86I2CFindDev(I2CBusPtr b, I2CSlaveAddr addr)
+{
+ I2CDevPtr d;
+
+ if (b) {
+ for (d = b->FirstDev; d != NULL; d = d->NextDev)
+ if (d->SlaveAddr == addr)
+ return d;
+ }
+
+ return NULL;
+}
+
+static I2CBusPtr I2CBusList;
+
+/* Allocates an I2CBusRec for you and initializes with propper defaults
+ * you may modify before calling xf86I2CBusInit. Your I2CBusRec must
+ * contain at least a BusName, a scrnIndex (or -1), and a complete set
+ * of either high or low level I2C function pointers. You may pass
+ * bus-wide timeouts, otherwise inplausible values will be replaced
+ * with safe defaults.
+ */
+
+I2CBusPtr
+xf86CreateI2CBusRec(void)
+{
+ I2CBusPtr b;
+
+ b = (I2CBusPtr) calloc(1, sizeof(I2CBusRec));
+
+ if (b != NULL) {
+ b->scrnIndex = -1;
+ b->HoldTime = 5; /* 100 kHz bus */
+ b->BitTimeout = 5;
+ b->ByteTimeout = 5;
+ b->AcknTimeout = 5;
+ b->StartTimeout = 5;
+ b->RiseFallTime = RISEFALLTIME;
+ }
+
+ return b;
+}
+
+/* Unregister an I2C bus. If you got the I2CBusRec from xf86CreateI2CBusRec
+ * you should set <unalloc> to free it. If you set <devs_too>, the function
+ * xf86DestroyI2CDevRec will be called for all devices linked to the bus
+ * first, passing down the <unalloc> option.
+ */
+
+void
+xf86DestroyI2CBusRec(I2CBusPtr b, Bool unalloc, Bool devs_too)
+{
+ if (b) {
+ I2CBusPtr *p;
+
+ /* Remove this from the list of active I2C buses */
+
+ for (p = &I2CBusList; *p != NULL; p = &(*p)->NextBus)
+ if (*p == b) {
+ *p = (*p)->NextBus;
+ break;
+ }
+
+ if (b->FirstDev != NULL) {
+ if (devs_too) {
+ I2CDevPtr d;
+
+ while ((d = b->FirstDev) != NULL) {
+ b->FirstDev = d->NextDev;
+ xf86DestroyI2CDevRec(d, unalloc);
+ }
+ } else {
+ if (unalloc) {
+ xf86Msg(X_ERROR, "i2c bug: Attempt to remove I2C bus \"%s\", "
+ "but device list is not empty.\n",
+ b->BusName);
+ return;
+ }
+ }
+ }
+
+ xf86DrvMsg(b->scrnIndex, X_INFO, "I2C bus \"%s\" removed.\n",
+ b->BusName);
+
+ if (unalloc) free(b);
+ }
+}
+
+/* I2C masters have to register themselves using this function.
+ * It will not allocate an I2CBusRec for you, instead you may enter
+ * a pointer to a statically allocated I2CBusRec or the (modified)
+ * result of xf86CreateI2CBusRec. Returns TRUE on success.
+ *
+ * At this point there won't be any traffic on the I2C bus.
+ */
+
+Bool
+xf86I2CBusInit(I2CBusPtr b)
+{
+ /* I2C buses must be identified by a unique scrnIndex
+ * and name. If scrnIndex is unspecified (a negative value),
+ * then the name must be unique throughout the server.
+ */
+
+ if (b->BusName == NULL ||
+ xf86I2CFindBus(b->scrnIndex, b->BusName) != NULL)
+ return FALSE;
+
+ /* If the high level functions are not
+ * supplied, use the generic functions.
+ * In this case we need the low-level
+ * function.
+ */
+ if (b->I2CWriteRead == NULL)
+ {
+ b->I2CWriteRead=I2CWriteRead;
+
+ if (b->I2CPutBits == NULL ||
+ b->I2CGetBits == NULL)
+ {
+ if (b->I2CPutByte == NULL ||
+ b->I2CGetByte == NULL ||
+ b->I2CAddress == NULL ||
+ b->I2CStart == NULL ||
+ b->I2CStop == NULL)
+ return FALSE;
+ } else {
+ b->I2CPutByte = I2CPutByte;
+ b->I2CGetByte = I2CGetByte;
+ b->I2CAddress = I2CAddress;
+ b->I2CStop = I2CStop;
+ b->I2CStart = I2CStart;
+ }
+ }
+
+ if (b->I2CUDelay == NULL)
+ b->I2CUDelay = I2CUDelay;
+
+ if (b->HoldTime < 2) b->HoldTime = 5;
+ if (b->BitTimeout <= 0) b->BitTimeout = b->HoldTime;
+ if (b->ByteTimeout <= 0) b->ByteTimeout = b->HoldTime;
+ if (b->AcknTimeout <= 0) b->AcknTimeout = b->HoldTime;
+ if (b->StartTimeout <= 0) b->StartTimeout = b->HoldTime;
+
+ /* Put new bus on list. */
+
+ b->NextBus = I2CBusList;
+ I2CBusList = b;
+
+ xf86DrvMsg(b->scrnIndex, X_INFO, "I2C bus \"%s\" initialized.\n",
+ b->BusName);
+
+ return TRUE;
+}
+
+I2CBusPtr
+xf86I2CFindBus(int scrnIndex, char *name)
+{
+ I2CBusPtr p;
+
+ if (name != NULL)
+ for (p = I2CBusList; p != NULL; p = p->NextBus)
+ if (scrnIndex < 0 || p->scrnIndex == scrnIndex)
+ if (!strcmp(p->BusName, name))
+ return p;
+
+ return NULL;
+}
+
+/*
+ * Return an array of I2CBusPtr's related to a screen. The caller is
+ * responsible for freeing the array.
+ */
+int
+xf86I2CGetScreenBuses(int scrnIndex, I2CBusPtr **pppI2CBus)
+{
+ I2CBusPtr pI2CBus;
+ int n = 0;
+
+ if (pppI2CBus)
+ *pppI2CBus = NULL;
+
+ for (pI2CBus = I2CBusList; pI2CBus; pI2CBus = pI2CBus->NextBus) {
+ if ((pI2CBus->scrnIndex >= 0) && (pI2CBus->scrnIndex != scrnIndex))
+ continue;
+
+ n++;
+
+ if (!pppI2CBus)
+ continue;
+
+ *pppI2CBus = xnfrealloc(*pppI2CBus, n * sizeof(I2CBusPtr));
+ (*pppI2CBus)[n - 1] = pI2CBus;
+ }
+
+ return n;
+}
diff --git a/xorg-server/hw/xfree86/int10/generic.c b/xorg-server/hw/xfree86/int10/generic.c
index 9d39e99b0..c242405cc 100644
--- a/xorg-server/hw/xfree86/int10/generic.c
+++ b/xorg-server/hw/xfree86/int10/generic.c
@@ -1,494 +1,494 @@
-/*
- * XFree86 int10 module
- * execute BIOS int 10h calls in x86 real mode environment
- * Copyright 1999 Egbert Eich
- */
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <string.h>
-#include <unistd.h>
-
-#include "xf86.h"
-#include "xf86_OSproc.h"
-#include "compiler.h"
-#define _INT10_PRIVATE
-#include "xf86int10.h"
-#include "int10Defines.h"
-#include "Pci.h"
-
-#define ALLOC_ENTRIES(x) ((V_RAM / x) - 1)
-
-static CARD8 read_b(xf86Int10InfoPtr pInt,int addr);
-static CARD16 read_w(xf86Int10InfoPtr pInt,int addr);
-static CARD32 read_l(xf86Int10InfoPtr pInt,int addr);
-static void write_b(xf86Int10InfoPtr pInt,int addr, CARD8 val);
-static void write_w(xf86Int10InfoPtr pInt,int addr, CARD16 val);
-static void write_l(xf86Int10InfoPtr pInt,int addr, CARD32 val);
-
-/*
- * the emulator cannot pass a pointer to the current xf86Int10InfoRec
- * to the memory access functions therefore store it here.
- */
-
-typedef struct {
- int shift;
- int entries;
- void* base;
- void* vRam;
- int highMemory;
- void* sysMem;
- char* alloc;
-} genericInt10Priv;
-
-#define INTPriv(x) ((genericInt10Priv*)x->private)
-
-int10MemRec genericMem = {
- read_b,
- read_w,
- read_l,
- write_b,
- write_w,
- write_l
-};
-
-static void MapVRam(xf86Int10InfoPtr pInt);
-static void UnmapVRam(xf86Int10InfoPtr pInt);
-#ifdef _PC
-#define GET_HIGH_BASE(x) (((V_BIOS + (x) + getpagesize() - 1)/getpagesize()) \
- * getpagesize())
-#endif
-
-static void *sysMem = NULL;
-
-/**
- * Read legacy VGA video BIOS associated with specified domain.
- *
- * Attempts to read up to 128KiB of legacy VGA video BIOS.
- *
- * \return
- * The number of bytes read on success or -1 on failure.
- *
- * \bug
- * PCI ROMs can contain multiple BIOS images (e.g., OpenFirmware, x86 VGA,
- * etc.). How do we know that \c pci_device_read_rom will return the
- * legacy VGA BIOS image?
- */
-#ifndef _PC
-static int
-read_legacy_video_BIOS(struct pci_device *dev, unsigned char *Buf)
-{
- const ADDRESS Base = 0xC0000;
- const int Len = 0x10000 * 2;
- const int pagemask = getpagesize() - 1;
- const ADDRESS offset = Base & ~pagemask;
- const unsigned long size = ((Base + Len + pagemask) & ~pagemask) - offset;
- unsigned char *ptr, *src;
- int len;
-
-
- /* Try to use the civilized PCI interface first.
- */
- if (pci_device_read_rom(dev, Buf) == 0) {
- return dev->rom_size;
- }
-
- ptr = xf86MapDomainMemory(-1, VIDMEM_READONLY, dev, offset, size);
-
- if (!ptr)
- return -1;
-
- /* Using memcpy() here can hang the system */
- src = ptr + (Base - offset);
- for (len = 0; len < (Len / 2); len++) {
- Buf[len] = src[len];
- }
-
- if ((Buf[0] == 0x55) && (Buf[1] == 0xAA) && (Buf[2] > 0x80)) {
- for ( /* empty */ ; len < Len; len++) {
- Buf[len] = src[len];
- }
- }
-
- xf86UnMapVidMem(-1, ptr, size);
-
- return Len;
-}
-#endif /* _PC */
-
-
-xf86Int10InfoPtr
-xf86ExtendedInitInt10(int entityIndex, int Flags)
-{
- xf86Int10InfoPtr pInt;
- void* base = 0;
- void* vbiosMem = 0;
- void* options = NULL;
- int screen;
- legacyVGARec vga;
-
-#if 0
- CARD32 cs;
-#endif
-
- screen = (xf86FindScreenForEntity(entityIndex))->scrnIndex;
-
- options = xf86HandleInt10Options(xf86Screens[screen],entityIndex);
-
- if (int10skip(options)) {
- xfree(options);
- return NULL;
- }
-
- pInt = (xf86Int10InfoPtr)xnfcalloc(1, sizeof(xf86Int10InfoRec));
- pInt->entityIndex = entityIndex;
- if (!xf86Int10ExecSetup(pInt))
- goto error0;
- pInt->mem = &genericMem;
- pInt->private = (pointer)xnfcalloc(1, sizeof(genericInt10Priv));
- INTPriv(pInt)->alloc = (pointer)xnfcalloc(1, ALLOC_ENTRIES(getpagesize()));
- pInt->scrnIndex = screen;
- base = INTPriv(pInt)->base = xnfalloc(SYS_BIOS);
-
- /* FIXME: Shouldn't this be a failure case? Leaving dev as NULL seems like
- * FIXME: an error
- */
- pInt->dev = xf86GetPciInfoForEntity(entityIndex);
-
- /*
- * we need to map video RAM MMIO as some chipsets map mmio
- * registers into this range.
- */
- MapVRam(pInt);
-#ifdef _PC
- if (!sysMem)
- sysMem = xf86MapVidMem(screen, VIDMEM_MMIO, V_BIOS,
- BIOS_SIZE + SYS_BIOS - V_BIOS);
- INTPriv(pInt)->sysMem = sysMem;
-
- if (xf86ReadBIOS(0, 0, base, LOW_PAGE_SIZE) < 0) {
- xf86DrvMsg(screen, X_ERROR, "Cannot read int vect\n");
- goto error1;
- }
-
- /*
- * Retrieve everything between V_BIOS and SYS_BIOS as some system BIOSes
- * have executable code there. Note that xf86ReadBIOS() can only read in
- * 64kB at a time.
- */
- memset((char *)base + V_BIOS, 0, SYS_BIOS - V_BIOS);
-#if 0
- for (cs = V_BIOS; cs < SYS_BIOS; cs += V_BIOS_SIZE)
- if (xf86ReadBIOS(cs, 0, (unsigned char *)base + cs, V_BIOS_SIZE) <
- V_BIOS_SIZE)
- xf86DrvMsg(screen, X_WARNING,
- "Unable to retrieve all of segment 0x%06X.\n", cs);
-#endif
- INTPriv(pInt)->highMemory = V_BIOS;
-
- if (xf86IsEntityPrimary(entityIndex) && !(initPrimary(options))) {
- if (!xf86int10GetBiosSegment(pInt, (unsigned char *)sysMem - V_BIOS))
- goto error1;
-
- set_return_trap(pInt);
-
- pInt->Flags = Flags & (SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH);
- if (! (pInt->Flags & SET_BIOS_SCRATCH))
- pInt->Flags &= ~RESTORE_BIOS_SCRATCH;
- xf86Int10SaveRestoreBIOSVars(pInt, TRUE);
-
- } else {
- const BusType location_type = xf86int10GetBiosLocationType(pInt);
- int bios_location = V_BIOS;
-
- reset_int_vect(pInt);
- set_return_trap(pInt);
-
- switch (location_type) {
- case BUS_PCI: {
- int err;
- struct pci_device *rom_device =
- xf86GetPciInfoForEntity(pInt->entityIndex);
-
- vbiosMem = (unsigned char *)base + bios_location;
- err = pci_device_read_rom(rom_device, vbiosMem);
- if (err) {
- xf86DrvMsg(screen,X_ERROR,"Cannot read V_BIOS (3) %s\n",
- strerror(err));
- goto error1;
- }
- INTPriv(pInt)->highMemory = GET_HIGH_BASE(rom_device->rom_size);
- break;
- }
- default:
- goto error1;
- }
- pInt->BIOSseg = V_BIOS >> 4;
- pInt->num = 0xe6;
- LockLegacyVGA(pInt, &vga);
- xf86ExecX86int10(pInt);
- UnlockLegacyVGA(pInt, &vga);
- }
-#else
- if (!sysMem) {
- sysMem = xnfalloc(BIOS_SIZE);
- setup_system_bios(sysMem);
- }
- INTPriv(pInt)->sysMem = sysMem;
- setup_int_vect(pInt);
- set_return_trap(pInt);
-
- /* Retrieve the entire legacy video BIOS segment. This can be upto
- * 128KiB.
- */
- vbiosMem = (char *)base + V_BIOS;
- memset(vbiosMem, 0, 2 * V_BIOS_SIZE);
- if (read_legacy_video_BIOS(pInt->dev, vbiosMem) < V_BIOS_SIZE) {
- xf86DrvMsg(screen, X_WARNING,
- "Unable to retrieve all of segment 0x0C0000.\n");
- }
-
- /*
- * If this adapter is the primary, use its post-init BIOS (if we can find
- * it).
- */
- {
- int bios_location = V_BIOS;
- Bool done = FALSE;
- vbiosMem = (unsigned char *)base + bios_location;
-
- if (xf86IsEntityPrimary(entityIndex)) {
- if (int10_check_bios(screen, bios_location >> 4, vbiosMem))
- done = TRUE;
- else
- xf86DrvMsg(screen,X_INFO,
- "No legacy BIOS found -- trying PCI\n");
- }
- if (!done) {
- int err;
- struct pci_device *rom_device =
- xf86GetPciInfoForEntity(pInt->entityIndex);
-
- err = pci_device_read_rom(rom_device, vbiosMem);
- if (err) {
- xf86DrvMsg(screen,X_ERROR,"Cannot read V_BIOS (5) %s\n",
- strerror(err));
- goto error1;
- }
- }
- }
-
- pInt->BIOSseg = V_BIOS >> 4;
- pInt->num = 0xe6;
- LockLegacyVGA(pInt, &vga);
- xf86ExecX86int10(pInt);
- UnlockLegacyVGA(pInt, &vga);
-#endif
- xfree(options);
- return pInt;
-
- error1:
- xfree(base);
- UnmapVRam(pInt);
- xfree(INTPriv(pInt)->alloc);
- xfree(pInt->private);
- error0:
- xfree(pInt);
- xfree(options);
-
- return NULL;
-}
-
-static void
-MapVRam(xf86Int10InfoPtr pInt)
-{
- int pagesize = getpagesize();
- int size = ((VRAM_SIZE + pagesize - 1) / pagesize) * pagesize;
-
- INTPriv(pInt)->vRam = xf86MapDomainMemory(pInt->scrnIndex, VIDMEM_MMIO,
- pInt->dev, V_RAM, size);
-
- pInt->ioBase = xf86Screens[pInt->scrnIndex]->domainIOBase;
-}
-
-static void
-UnmapVRam(xf86Int10InfoPtr pInt)
-{
- int screen = pInt->scrnIndex;
- int pagesize = getpagesize();
- int size = ((VRAM_SIZE + pagesize - 1)/pagesize) * pagesize;
-
- xf86UnMapVidMem(screen, INTPriv(pInt)->vRam, size);
-}
-
-Bool
-MapCurrentInt10(xf86Int10InfoPtr pInt)
-{
- /* nothing to do here */
- return TRUE;
-}
-
-void
-xf86FreeInt10(xf86Int10InfoPtr pInt)
-{
- if (!pInt)
- return;
-#if defined (_PC)
- xf86Int10SaveRestoreBIOSVars(pInt, FALSE);
-#endif
- if (Int10Current == pInt)
- Int10Current = NULL;
- xfree(INTPriv(pInt)->base);
- UnmapVRam(pInt);
- xfree(INTPriv(pInt)->alloc);
- xfree(pInt->private);
- xfree(pInt);
-}
-
-void *
-xf86Int10AllocPages(xf86Int10InfoPtr pInt, int num, int *off)
-{
- int pagesize = getpagesize();
- int num_pages = ALLOC_ENTRIES(pagesize);
- int i,j;
-
- for (i = 0; i < (num_pages - num); i++) {
- if (INTPriv(pInt)->alloc[i] == 0) {
- for (j = i; j < (num + i); j++)
- if (INTPriv(pInt)->alloc[j] != 0)
- break;
- if (j == (num + i))
- break;
- i += num;
- }
- }
- if (i == (num_pages - num))
- return NULL;
-
- for (j = i; j < (i + num); j++)
- INTPriv(pInt)->alloc[j] = 1;
-
- *off = (i + 1) * pagesize;
-
- return (char *)INTPriv(pInt)->base + *off;
-}
-
-void
-xf86Int10FreePages(xf86Int10InfoPtr pInt, void *pbase, int num)
-{
- int pagesize = getpagesize();
- int first = (((char *)pbase - (char *)INTPriv(pInt)->base) / pagesize) - 1;
- int i;
-
- for (i = first; i < (first + num); i++)
- INTPriv(pInt)->alloc[i] = 0;
-}
-
-#define OFF(addr) ((addr) & 0xffff)
-#if defined _PC
-# define HIGH_OFFSET (INTPriv(pInt)->highMemory)
-# define HIGH_BASE V_BIOS
-#else
-# define HIGH_OFFSET SYS_BIOS
-# define HIGH_BASE SYS_BIOS
-#endif
-# define SYS(addr) ((addr) >= HIGH_OFFSET)
-#define V_ADDR(addr) \
- (SYS(addr) ? ((char*)INTPriv(pInt)->sysMem) + (addr - HIGH_BASE) \
- : (((char*)(INTPriv(pInt)->base) + addr)))
-#define VRAM_ADDR(addr) (addr - V_RAM)
-#define VRAM_BASE (INTPriv(pInt)->vRam)
-
-#define VRAM(addr) ((addr >= V_RAM) && (addr < (V_RAM + VRAM_SIZE)))
-#define V_ADDR_RB(addr) \
- (VRAM(addr)) ? MMIO_IN8((CARD8*)VRAM_BASE,VRAM_ADDR(addr)) \
- : *(CARD8*) V_ADDR(addr)
-#define V_ADDR_RW(addr) \
- (VRAM(addr)) ? MMIO_IN16((CARD16*)VRAM_BASE,VRAM_ADDR(addr)) \
- : ldw_u((pointer)V_ADDR(addr))
-#define V_ADDR_RL(addr) \
- (VRAM(addr)) ? MMIO_IN32((CARD32*)VRAM_BASE,VRAM_ADDR(addr)) \
- : ldl_u((pointer)V_ADDR(addr))
-
-#define V_ADDR_WB(addr,val) \
- if(VRAM(addr)) \
- MMIO_OUT8((CARD8*)VRAM_BASE,VRAM_ADDR(addr),val); \
- else \
- *(CARD8*) V_ADDR(addr) = val;
-#define V_ADDR_WW(addr,val) \
- if(VRAM(addr)) \
- MMIO_OUT16((CARD16*)VRAM_BASE,VRAM_ADDR(addr),val); \
- else \
- stw_u((val),(pointer)(V_ADDR(addr)));
-
-#define V_ADDR_WL(addr,val) \
- if (VRAM(addr)) \
- MMIO_OUT32((CARD32*)VRAM_BASE,VRAM_ADDR(addr),val); \
- else \
- stl_u(val,(pointer)(V_ADDR(addr)));
-
-static CARD8
-read_b(xf86Int10InfoPtr pInt, int addr)
-{
- return V_ADDR_RB(addr);
-}
-
-static CARD16
-read_w(xf86Int10InfoPtr pInt, int addr)
-{
-#if X_BYTE_ORDER == X_LITTLE_ENDIAN
- if (OFF(addr + 1) > 0)
- return V_ADDR_RW(addr);
-#endif
- return V_ADDR_RB(addr) | (V_ADDR_RB(addr + 1) << 8);
-}
-
-static CARD32
-read_l(xf86Int10InfoPtr pInt, int addr)
-{
-#if X_BYTE_ORDER == X_LITTLE_ENDIAN
- if (OFF(addr + 3) > 2)
- return V_ADDR_RL(addr);
-#endif
- return V_ADDR_RB(addr) |
- (V_ADDR_RB(addr + 1) << 8) |
- (V_ADDR_RB(addr + 2) << 16) |
- (V_ADDR_RB(addr + 3) << 24);
-}
-
-static void
-write_b(xf86Int10InfoPtr pInt, int addr, CARD8 val)
-{
- V_ADDR_WB(addr,val);
-}
-
-static void
-write_w(xf86Int10InfoPtr pInt, int addr, CARD16 val)
-{
-#if X_BYTE_ORDER == X_LITTLE_ENDIAN
- if (OFF(addr + 1) > 0)
- { V_ADDR_WW(addr, val); }
-#endif
- V_ADDR_WB(addr, val);
- V_ADDR_WB(addr + 1, val >> 8);
-}
-
-static void
-write_l(xf86Int10InfoPtr pInt, int addr, CARD32 val)
-{
-#if X_BYTE_ORDER == X_LITTLE_ENDIAN
- if (OFF(addr + 3) > 2)
- { V_ADDR_WL(addr, val); }
-#endif
- V_ADDR_WB(addr, val);
- V_ADDR_WB(addr + 1, val >> 8);
- V_ADDR_WB(addr + 2, val >> 16);
- V_ADDR_WB(addr + 3, val >> 24);
-}
-
-pointer
-xf86int10Addr(xf86Int10InfoPtr pInt, CARD32 addr)
-{
- return V_ADDR(addr);
-}
+/*
+ * XFree86 int10 module
+ * execute BIOS int 10h calls in x86 real mode environment
+ * Copyright 1999 Egbert Eich
+ */
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <string.h>
+#include <unistd.h>
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "compiler.h"
+#define _INT10_PRIVATE
+#include "xf86int10.h"
+#include "int10Defines.h"
+#include "Pci.h"
+
+#define ALLOC_ENTRIES(x) ((V_RAM / x) - 1)
+
+static CARD8 read_b(xf86Int10InfoPtr pInt,int addr);
+static CARD16 read_w(xf86Int10InfoPtr pInt,int addr);
+static CARD32 read_l(xf86Int10InfoPtr pInt,int addr);
+static void write_b(xf86Int10InfoPtr pInt,int addr, CARD8 val);
+static void write_w(xf86Int10InfoPtr pInt,int addr, CARD16 val);
+static void write_l(xf86Int10InfoPtr pInt,int addr, CARD32 val);
+
+/*
+ * the emulator cannot pass a pointer to the current xf86Int10InfoRec
+ * to the memory access functions therefore store it here.
+ */
+
+typedef struct {
+ int shift;
+ int entries;
+ void* base;
+ void* vRam;
+ int highMemory;
+ void* sysMem;
+ char* alloc;
+} genericInt10Priv;
+
+#define INTPriv(x) ((genericInt10Priv*)x->private)
+
+int10MemRec genericMem = {
+ read_b,
+ read_w,
+ read_l,
+ write_b,
+ write_w,
+ write_l
+};
+
+static void MapVRam(xf86Int10InfoPtr pInt);
+static void UnmapVRam(xf86Int10InfoPtr pInt);
+#ifdef _PC
+#define GET_HIGH_BASE(x) (((V_BIOS + (x) + getpagesize() - 1)/getpagesize()) \
+ * getpagesize())
+#endif
+
+static void *sysMem = NULL;
+
+/**
+ * Read legacy VGA video BIOS associated with specified domain.
+ *
+ * Attempts to read up to 128KiB of legacy VGA video BIOS.
+ *
+ * \return
+ * The number of bytes read on success or -1 on failure.
+ *
+ * \bug
+ * PCI ROMs can contain multiple BIOS images (e.g., OpenFirmware, x86 VGA,
+ * etc.). How do we know that \c pci_device_read_rom will return the
+ * legacy VGA BIOS image?
+ */
+#ifndef _PC
+static int
+read_legacy_video_BIOS(struct pci_device *dev, unsigned char *Buf)
+{
+ const ADDRESS Base = 0xC0000;
+ const int Len = 0x10000 * 2;
+ const int pagemask = getpagesize() - 1;
+ const ADDRESS offset = Base & ~pagemask;
+ const unsigned long size = ((Base + Len + pagemask) & ~pagemask) - offset;
+ unsigned char *ptr, *src;
+ int len;
+
+
+ /* Try to use the civilized PCI interface first.
+ */
+ if (pci_device_read_rom(dev, Buf) == 0) {
+ return dev->rom_size;
+ }
+
+ ptr = xf86MapDomainMemory(-1, VIDMEM_READONLY, dev, offset, size);
+
+ if (!ptr)
+ return -1;
+
+ /* Using memcpy() here can hang the system */
+ src = ptr + (Base - offset);
+ for (len = 0; len < (Len / 2); len++) {
+ Buf[len] = src[len];
+ }
+
+ if ((Buf[0] == 0x55) && (Buf[1] == 0xAA) && (Buf[2] > 0x80)) {
+ for ( /* empty */ ; len < Len; len++) {
+ Buf[len] = src[len];
+ }
+ }
+
+ xf86UnMapVidMem(-1, ptr, size);
+
+ return Len;
+}
+#endif /* _PC */
+
+
+xf86Int10InfoPtr
+xf86ExtendedInitInt10(int entityIndex, int Flags)
+{
+ xf86Int10InfoPtr pInt;
+ void* base = 0;
+ void* vbiosMem = 0;
+ void* options = NULL;
+ int screen;
+ legacyVGARec vga;
+
+#if 0
+ CARD32 cs;
+#endif
+
+ screen = (xf86FindScreenForEntity(entityIndex))->scrnIndex;
+
+ options = xf86HandleInt10Options(xf86Screens[screen],entityIndex);
+
+ if (int10skip(options)) {
+ free(options);
+ return NULL;
+ }
+
+ pInt = (xf86Int10InfoPtr)xnfcalloc(1, sizeof(xf86Int10InfoRec));
+ pInt->entityIndex = entityIndex;
+ if (!xf86Int10ExecSetup(pInt))
+ goto error0;
+ pInt->mem = &genericMem;
+ pInt->private = (pointer)xnfcalloc(1, sizeof(genericInt10Priv));
+ INTPriv(pInt)->alloc = (pointer)xnfcalloc(1, ALLOC_ENTRIES(getpagesize()));
+ pInt->scrnIndex = screen;
+ base = INTPriv(pInt)->base = xnfalloc(SYS_BIOS);
+
+ /* FIXME: Shouldn't this be a failure case? Leaving dev as NULL seems like
+ * FIXME: an error
+ */
+ pInt->dev = xf86GetPciInfoForEntity(entityIndex);
+
+ /*
+ * we need to map video RAM MMIO as some chipsets map mmio
+ * registers into this range.
+ */
+ MapVRam(pInt);
+#ifdef _PC
+ if (!sysMem)
+ sysMem = xf86MapVidMem(screen, VIDMEM_MMIO, V_BIOS,
+ BIOS_SIZE + SYS_BIOS - V_BIOS);
+ INTPriv(pInt)->sysMem = sysMem;
+
+ if (xf86ReadBIOS(0, 0, base, LOW_PAGE_SIZE) < 0) {
+ xf86DrvMsg(screen, X_ERROR, "Cannot read int vect\n");
+ goto error1;
+ }
+
+ /*
+ * Retrieve everything between V_BIOS and SYS_BIOS as some system BIOSes
+ * have executable code there. Note that xf86ReadBIOS() can only read in
+ * 64kB at a time.
+ */
+ memset((char *)base + V_BIOS, 0, SYS_BIOS - V_BIOS);
+#if 0
+ for (cs = V_BIOS; cs < SYS_BIOS; cs += V_BIOS_SIZE)
+ if (xf86ReadBIOS(cs, 0, (unsigned char *)base + cs, V_BIOS_SIZE) <
+ V_BIOS_SIZE)
+ xf86DrvMsg(screen, X_WARNING,
+ "Unable to retrieve all of segment 0x%06X.\n", cs);
+#endif
+ INTPriv(pInt)->highMemory = V_BIOS;
+
+ if (xf86IsEntityPrimary(entityIndex) && !(initPrimary(options))) {
+ if (!xf86int10GetBiosSegment(pInt, (unsigned char *)sysMem - V_BIOS))
+ goto error1;
+
+ set_return_trap(pInt);
+
+ pInt->Flags = Flags & (SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH);
+ if (! (pInt->Flags & SET_BIOS_SCRATCH))
+ pInt->Flags &= ~RESTORE_BIOS_SCRATCH;
+ xf86Int10SaveRestoreBIOSVars(pInt, TRUE);
+
+ } else {
+ const BusType location_type = xf86int10GetBiosLocationType(pInt);
+ int bios_location = V_BIOS;
+
+ reset_int_vect(pInt);
+ set_return_trap(pInt);
+
+ switch (location_type) {
+ case BUS_PCI: {
+ int err;
+ struct pci_device *rom_device =
+ xf86GetPciInfoForEntity(pInt->entityIndex);
+
+ vbiosMem = (unsigned char *)base + bios_location;
+ err = pci_device_read_rom(rom_device, vbiosMem);
+ if (err) {
+ xf86DrvMsg(screen,X_ERROR,"Cannot read V_BIOS (3) %s\n",
+ strerror(err));
+ goto error1;
+ }
+ INTPriv(pInt)->highMemory = GET_HIGH_BASE(rom_device->rom_size);
+ break;
+ }
+ default:
+ goto error1;
+ }
+ pInt->BIOSseg = V_BIOS >> 4;
+ pInt->num = 0xe6;
+ LockLegacyVGA(pInt, &vga);
+ xf86ExecX86int10(pInt);
+ UnlockLegacyVGA(pInt, &vga);
+ }
+#else
+ if (!sysMem) {
+ sysMem = xnfalloc(BIOS_SIZE);
+ setup_system_bios(sysMem);
+ }
+ INTPriv(pInt)->sysMem = sysMem;
+ setup_int_vect(pInt);
+ set_return_trap(pInt);
+
+ /* Retrieve the entire legacy video BIOS segment. This can be upto
+ * 128KiB.
+ */
+ vbiosMem = (char *)base + V_BIOS;
+ memset(vbiosMem, 0, 2 * V_BIOS_SIZE);
+ if (read_legacy_video_BIOS(pInt->dev, vbiosMem) < V_BIOS_SIZE) {
+ xf86DrvMsg(screen, X_WARNING,
+ "Unable to retrieve all of segment 0x0C0000.\n");
+ }
+
+ /*
+ * If this adapter is the primary, use its post-init BIOS (if we can find
+ * it).
+ */
+ {
+ int bios_location = V_BIOS;
+ Bool done = FALSE;
+ vbiosMem = (unsigned char *)base + bios_location;
+
+ if (xf86IsEntityPrimary(entityIndex)) {
+ if (int10_check_bios(screen, bios_location >> 4, vbiosMem))
+ done = TRUE;
+ else
+ xf86DrvMsg(screen,X_INFO,
+ "No legacy BIOS found -- trying PCI\n");
+ }
+ if (!done) {
+ int err;
+ struct pci_device *rom_device =
+ xf86GetPciInfoForEntity(pInt->entityIndex);
+
+ err = pci_device_read_rom(rom_device, vbiosMem);
+ if (err) {
+ xf86DrvMsg(screen,X_ERROR,"Cannot read V_BIOS (5) %s\n",
+ strerror(err));
+ goto error1;
+ }
+ }
+ }
+
+ pInt->BIOSseg = V_BIOS >> 4;
+ pInt->num = 0xe6;
+ LockLegacyVGA(pInt, &vga);
+ xf86ExecX86int10(pInt);
+ UnlockLegacyVGA(pInt, &vga);
+#endif
+ free(options);
+ return pInt;
+
+ error1:
+ free(base);
+ UnmapVRam(pInt);
+ free(INTPriv(pInt)->alloc);
+ free(pInt->private);
+ error0:
+ free(pInt);
+ free(options);
+
+ return NULL;
+}
+
+static void
+MapVRam(xf86Int10InfoPtr pInt)
+{
+ int pagesize = getpagesize();
+ int size = ((VRAM_SIZE + pagesize - 1) / pagesize) * pagesize;
+
+ INTPriv(pInt)->vRam = xf86MapDomainMemory(pInt->scrnIndex, VIDMEM_MMIO,
+ pInt->dev, V_RAM, size);
+
+ pInt->ioBase = xf86Screens[pInt->scrnIndex]->domainIOBase;
+}
+
+static void
+UnmapVRam(xf86Int10InfoPtr pInt)
+{
+ int screen = pInt->scrnIndex;
+ int pagesize = getpagesize();
+ int size = ((VRAM_SIZE + pagesize - 1)/pagesize) * pagesize;
+
+ xf86UnMapVidMem(screen, INTPriv(pInt)->vRam, size);
+}
+
+Bool
+MapCurrentInt10(xf86Int10InfoPtr pInt)
+{
+ /* nothing to do here */
+ return TRUE;
+}
+
+void
+xf86FreeInt10(xf86Int10InfoPtr pInt)
+{
+ if (!pInt)
+ return;
+#if defined (_PC)
+ xf86Int10SaveRestoreBIOSVars(pInt, FALSE);
+#endif
+ if (Int10Current == pInt)
+ Int10Current = NULL;
+ free(INTPriv(pInt)->base);
+ UnmapVRam(pInt);
+ free(INTPriv(pInt)->alloc);
+ free(pInt->private);
+ free(pInt);
+}
+
+void *
+xf86Int10AllocPages(xf86Int10InfoPtr pInt, int num, int *off)
+{
+ int pagesize = getpagesize();
+ int num_pages = ALLOC_ENTRIES(pagesize);
+ int i,j;
+
+ for (i = 0; i < (num_pages - num); i++) {
+ if (INTPriv(pInt)->alloc[i] == 0) {
+ for (j = i; j < (num + i); j++)
+ if (INTPriv(pInt)->alloc[j] != 0)
+ break;
+ if (j == (num + i))
+ break;
+ i += num;
+ }
+ }
+ if (i == (num_pages - num))
+ return NULL;
+
+ for (j = i; j < (i + num); j++)
+ INTPriv(pInt)->alloc[j] = 1;
+
+ *off = (i + 1) * pagesize;
+
+ return (char *)INTPriv(pInt)->base + *off;
+}
+
+void
+xf86Int10FreePages(xf86Int10InfoPtr pInt, void *pbase, int num)
+{
+ int pagesize = getpagesize();
+ int first = (((char *)pbase - (char *)INTPriv(pInt)->base) / pagesize) - 1;
+ int i;
+
+ for (i = first; i < (first + num); i++)
+ INTPriv(pInt)->alloc[i] = 0;
+}
+
+#define OFF(addr) ((addr) & 0xffff)
+#if defined _PC
+# define HIGH_OFFSET (INTPriv(pInt)->highMemory)
+# define HIGH_BASE V_BIOS
+#else
+# define HIGH_OFFSET SYS_BIOS
+# define HIGH_BASE SYS_BIOS
+#endif
+# define SYS(addr) ((addr) >= HIGH_OFFSET)
+#define V_ADDR(addr) \
+ (SYS(addr) ? ((char*)INTPriv(pInt)->sysMem) + (addr - HIGH_BASE) \
+ : (((char*)(INTPriv(pInt)->base) + addr)))
+#define VRAM_ADDR(addr) (addr - V_RAM)
+#define VRAM_BASE (INTPriv(pInt)->vRam)
+
+#define VRAM(addr) ((addr >= V_RAM) && (addr < (V_RAM + VRAM_SIZE)))
+#define V_ADDR_RB(addr) \
+ (VRAM(addr)) ? MMIO_IN8((CARD8*)VRAM_BASE,VRAM_ADDR(addr)) \
+ : *(CARD8*) V_ADDR(addr)
+#define V_ADDR_RW(addr) \
+ (VRAM(addr)) ? MMIO_IN16((CARD16*)VRAM_BASE,VRAM_ADDR(addr)) \
+ : ldw_u((pointer)V_ADDR(addr))
+#define V_ADDR_RL(addr) \
+ (VRAM(addr)) ? MMIO_IN32((CARD32*)VRAM_BASE,VRAM_ADDR(addr)) \
+ : ldl_u((pointer)V_ADDR(addr))
+
+#define V_ADDR_WB(addr,val) \
+ if(VRAM(addr)) \
+ MMIO_OUT8((CARD8*)VRAM_BASE,VRAM_ADDR(addr),val); \
+ else \
+ *(CARD8*) V_ADDR(addr) = val;
+#define V_ADDR_WW(addr,val) \
+ if(VRAM(addr)) \
+ MMIO_OUT16((CARD16*)VRAM_BASE,VRAM_ADDR(addr),val); \
+ else \
+ stw_u((val),(pointer)(V_ADDR(addr)));
+
+#define V_ADDR_WL(addr,val) \
+ if (VRAM(addr)) \
+ MMIO_OUT32((CARD32*)VRAM_BASE,VRAM_ADDR(addr),val); \
+ else \
+ stl_u(val,(pointer)(V_ADDR(addr)));
+
+static CARD8
+read_b(xf86Int10InfoPtr pInt, int addr)
+{
+ return V_ADDR_RB(addr);
+}
+
+static CARD16
+read_w(xf86Int10InfoPtr pInt, int addr)
+{
+#if X_BYTE_ORDER == X_LITTLE_ENDIAN
+ if (OFF(addr + 1) > 0)
+ return V_ADDR_RW(addr);
+#endif
+ return V_ADDR_RB(addr) | (V_ADDR_RB(addr + 1) << 8);
+}
+
+static CARD32
+read_l(xf86Int10InfoPtr pInt, int addr)
+{
+#if X_BYTE_ORDER == X_LITTLE_ENDIAN
+ if (OFF(addr + 3) > 2)
+ return V_ADDR_RL(addr);
+#endif
+ return V_ADDR_RB(addr) |
+ (V_ADDR_RB(addr + 1) << 8) |
+ (V_ADDR_RB(addr + 2) << 16) |
+ (V_ADDR_RB(addr + 3) << 24);
+}
+
+static void
+write_b(xf86Int10InfoPtr pInt, int addr, CARD8 val)
+{
+ V_ADDR_WB(addr,val);
+}
+
+static void
+write_w(xf86Int10InfoPtr pInt, int addr, CARD16 val)
+{
+#if X_BYTE_ORDER == X_LITTLE_ENDIAN
+ if (OFF(addr + 1) > 0)
+ { V_ADDR_WW(addr, val); }
+#endif
+ V_ADDR_WB(addr, val);
+ V_ADDR_WB(addr + 1, val >> 8);
+}
+
+static void
+write_l(xf86Int10InfoPtr pInt, int addr, CARD32 val)
+{
+#if X_BYTE_ORDER == X_LITTLE_ENDIAN
+ if (OFF(addr + 3) > 2)
+ { V_ADDR_WL(addr, val); }
+#endif
+ V_ADDR_WB(addr, val);
+ V_ADDR_WB(addr + 1, val >> 8);
+ V_ADDR_WB(addr + 2, val >> 16);
+ V_ADDR_WB(addr + 3, val >> 24);
+}
+
+pointer
+xf86int10Addr(xf86Int10InfoPtr pInt, CARD32 addr)
+{
+ return V_ADDR(addr);
+}
diff --git a/xorg-server/hw/xfree86/int10/helper_exec.c b/xorg-server/hw/xfree86/int10/helper_exec.c
index 6ba647f89..5b6253646 100644
--- a/xorg-server/hw/xfree86/int10/helper_exec.c
+++ b/xorg-server/hw/xfree86/int10/helper_exec.c
@@ -1,727 +1,727 @@
-/*
- * XFree86 int10 module
- * execute BIOS int 10h calls in x86 real mode environment
- * Copyright 1999 Egbert Eich
- *
- * Part of this code was inspired by the VBIOS POSTing code in DOSEMU
- * developed by the "DOSEMU-Development-Team"
- */
-
-/*
- * To debug port accesses define PRINT_PORT to 1.
- * Note! You also have to comment out ioperm()
- * in xf86EnableIO(). Otherwise we won't trap
- * on PIO.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#define PRINT_PORT 0
-
-#include <unistd.h>
-
-#include <X11/Xos.h>
-#include "xf86.h"
-#include "xf86_OSproc.h"
-#include "compiler.h"
-#define _INT10_PRIVATE
-#include "int10Defines.h"
-#include "xf86int10.h"
-#include "Pci.h"
-#ifdef _X86EMU
-#include "x86emu/x86emui.h"
-#else
-#define DEBUG_IO_TRACE() 0
-#endif
-#include <pciaccess.h>
-
-static int pciCfg1in(CARD16 addr, CARD32 *val);
-static int pciCfg1out(CARD16 addr, CARD32 val);
-static int pciCfg1inw(CARD16 addr, CARD16 *val);
-static int pciCfg1outw(CARD16 addr, CARD16 val);
-static int pciCfg1inb(CARD16 addr, CARD8 *val);
-static int pciCfg1outb(CARD16 addr, CARD8 val);
-#if defined (_PC)
-static void SetResetBIOSVars(xf86Int10InfoPtr pInt, Bool set);
-#endif
-
-#define REG pInt
-
-int
-setup_int(xf86Int10InfoPtr pInt)
-{
- if (pInt != Int10Current) {
- if (!MapCurrentInt10(pInt))
- return -1;
- Int10Current = pInt;
- }
- X86_EAX = (CARD32) pInt->ax;
- X86_EBX = (CARD32) pInt->bx;
- X86_ECX = (CARD32) pInt->cx;
- X86_EDX = (CARD32) pInt->dx;
- X86_ESI = (CARD32) pInt->si;
- X86_EDI = (CARD32) pInt->di;
- X86_EBP = (CARD32) pInt->bp;
- X86_ESP = 0x1000; X86_SS = pInt->stackseg >> 4;
- X86_EIP = 0x0600; X86_CS = 0x0; /* address of 'hlt' */
- X86_DS = 0x40; /* standard pc ds */
- X86_ES = pInt->es;
- X86_FS = 0;
- X86_GS = 0;
- X86_EFLAGS = X86_IF_MASK | X86_IOPL_MASK;
-#if defined (_PC)
- if (pInt->Flags & SET_BIOS_SCRATCH)
- SetResetBIOSVars(pInt, TRUE);
-#endif
- return xf86BlockSIGIO();
-}
-
-void
-finish_int(xf86Int10InfoPtr pInt, int sig)
-{
- xf86UnblockSIGIO(sig);
- pInt->ax = (CARD32) X86_EAX;
- pInt->bx = (CARD32) X86_EBX;
- pInt->cx = (CARD32) X86_ECX;
- pInt->dx = (CARD32) X86_EDX;
- pInt->si = (CARD32) X86_ESI;
- pInt->di = (CARD32) X86_EDI;
- pInt->es = (CARD16) X86_ES;
- pInt->bp = (CARD32) X86_EBP;
- pInt->flags = (CARD32) X86_FLAGS;
-#if defined (_PC)
- if (pInt->Flags & RESTORE_BIOS_SCRATCH)
- SetResetBIOSVars(pInt, FALSE);
-#endif
-}
-
-/* general software interrupt handler */
-CARD32
-getIntVect(xf86Int10InfoPtr pInt,int num)
-{
- return MEM_RW(pInt, num << 2) + (MEM_RW(pInt, (num << 2) + 2) << 4);
-}
-
-void
-pushw(xf86Int10InfoPtr pInt, CARD16 val)
-{
- X86_ESP -= 2;
- MEM_WW(pInt, ((CARD32) X86_SS << 4) + X86_SP, val);
-}
-
-int
-run_bios_int(int num, xf86Int10InfoPtr pInt)
-{
- CARD32 eflags;
-#ifndef _PC
- /* check if bios vector is initialized */
- if (MEM_RW(pInt, (num << 2) + 2) == (SYS_BIOS >> 4)) { /* SYS_BIOS_SEG ?*/
-
- if (num == 21 && X86_AH == 0x4e) {
- xf86DrvMsg(pInt->scrnIndex, X_NOTICE,
- "Failing Find-Matching-File on non-PC"
- " (int 21, func 4e)\n");
- X86_AX = 2;
- SET_FLAG(F_CF);
- return 1;
- } else {
- xf86DrvMsgVerb(pInt->scrnIndex, X_NOT_IMPLEMENTED, 2,
- "Ignoring int 0x%02x call\n", num);
- if (xf86GetVerbosity() > 3) {
- dump_registers(pInt);
- stack_trace(pInt);
- }
- return 1;
- }
- }
-#endif
-#ifdef PRINT_INT
- ErrorF("calling card BIOS at: ");
-#endif
- eflags = X86_EFLAGS;
-#if 0
- eflags = eflags | IF_MASK;
- X86_EFLAGS = X86_EFLAGS & ~(VIF_MASK | TF_MASK | IF_MASK | NT_MASK);
-#endif
- pushw(pInt, eflags);
- pushw(pInt, X86_CS);
- pushw(pInt, X86_IP);
- X86_CS = MEM_RW(pInt, (num << 2) + 2);
- X86_IP = MEM_RW(pInt, num << 2);
-#ifdef PRINT_INT
- ErrorF("0x%x:%lx\n", X86_CS, X86_EIP);
-#endif
- return 1;
-}
-
-/* Debugging stuff */
-void
-dump_code(xf86Int10InfoPtr pInt)
-{
- int i;
- unsigned long lina = SEG_ADR((CARD32), X86_CS, IP);
-
- xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3, "code at 0x%8.8lx:\n", lina);
- for (i=0; i<0x10; i++)
- xf86ErrorFVerb(3, " %2.2x", MEM_RB(pInt, lina + i));
- xf86ErrorFVerb(3, "\n");
- for (; i<0x20; i++)
- xf86ErrorFVerb(3, " %2.2x", MEM_RB(pInt, lina + i));
- xf86ErrorFVerb(3, "\n");
-}
-
-void
-dump_registers(xf86Int10InfoPtr pInt)
-{
- xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3,
- "EAX=0x%8.8lx, EBX=0x%8.8lx, ECX=0x%8.8lx, EDX=0x%8.8lx\n",
- (unsigned long)X86_EAX, (unsigned long)X86_EBX,
- (unsigned long)X86_ECX, (unsigned long)X86_EDX);
- xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3,
- "ESP=0x%8.8lx, EBP=0x%8.8lx, ESI=0x%8.8lx, EDI=0x%8.8lx\n",
- (unsigned long)X86_ESP, (unsigned long)X86_EBP,
- (unsigned long)X86_ESI, (unsigned long)X86_EDI);
- xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3,
- "CS=0x%4.4x, SS=0x%4.4x,"
- " DS=0x%4.4x, ES=0x%4.4x, FS=0x%4.4x, GS=0x%4.4x\n",
- X86_CS, X86_SS, X86_DS, X86_ES, X86_FS, X86_GS);
- xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3,
- "EIP=0x%8.8lx, EFLAGS=0x%8.8lx\n",
- (unsigned long)X86_EIP, (unsigned long)X86_EFLAGS);
-}
-
-void
-stack_trace(xf86Int10InfoPtr pInt)
-{
- int i = 0;
- unsigned long stack = SEG_ADR((CARD32), X86_SS, SP);
- unsigned long tail = (CARD32)((X86_SS << 4) + 0x1000);
-
- if (stack >= tail) return;
-
- xf86MsgVerb(X_INFO, 3, "stack at 0x%8.8lx:\n", stack);
- for (; stack < tail; stack++) {
- xf86ErrorFVerb(3, " %2.2x", MEM_RB(pInt, stack));
- i = (i + 1) % 0x10;
- if (!i)
- xf86ErrorFVerb(3, "\n");
- }
- if (i)
- xf86ErrorFVerb(3, "\n");
-}
-
-int
-port_rep_inb(xf86Int10InfoPtr pInt,
- CARD16 port, CARD32 base, int d_f, CARD32 count)
-{
- register int inc = d_f ? -1 : 1;
- CARD32 dst = base;
- if (PRINT_PORT && DEBUG_IO_TRACE())
- ErrorF(" rep_insb(%#x) %ld bytes at %8.8lx %s\n",
- port, count, base, d_f ? "up" : "down");
- while (count--) {
- MEM_WB(pInt, dst, x_inb(port));
- dst += inc;
- }
- return dst - base;
-}
-
-int
-port_rep_inw(xf86Int10InfoPtr pInt,
- CARD16 port, CARD32 base, int d_f, CARD32 count)
-{
- register int inc = d_f ? -2 : 2;
- CARD32 dst = base;
- if (PRINT_PORT && DEBUG_IO_TRACE())
- ErrorF(" rep_insw(%#x) %ld bytes at %8.8lx %s\n",
- port, count, base, d_f ? "up" : "down");
- while (count--) {
- MEM_WW(pInt, dst, x_inw(port));
- dst += inc;
- }
- return dst - base;
-}
-
-int
-port_rep_inl(xf86Int10InfoPtr pInt,
- CARD16 port, CARD32 base, int d_f, CARD32 count)
-{
- register int inc = d_f ? -4 : 4;
- CARD32 dst = base;
- if (PRINT_PORT && DEBUG_IO_TRACE())
- ErrorF(" rep_insl(%#x) %ld bytes at %8.8lx %s\n",
- port, count, base, d_f ? "up" : "down");
- while (count--) {
- MEM_WL(pInt, dst, x_inl(port));
- dst += inc;
- }
- return dst - base;
-}
-
-int
-port_rep_outb(xf86Int10InfoPtr pInt,
- CARD16 port, CARD32 base, int d_f, CARD32 count)
-{
- register int inc = d_f ? -1 : 1;
- CARD32 dst = base;
- if (PRINT_PORT && DEBUG_IO_TRACE())
- ErrorF(" rep_outb(%#x) %ld bytes at %8.8lx %s\n",
- port, count, base, d_f ? "up" : "down");
- while (count--) {
- x_outb(port, MEM_RB(pInt, dst));
- dst += inc;
- }
- return dst - base;
-}
-
-int
-port_rep_outw(xf86Int10InfoPtr pInt,
- CARD16 port, CARD32 base, int d_f, CARD32 count)
-{
- register int inc = d_f ? -2 : 2;
- CARD32 dst = base;
- if (PRINT_PORT && DEBUG_IO_TRACE())
- ErrorF(" rep_outw(%#x) %ld bytes at %8.8lx %s\n",
- port, count, base, d_f ? "up" : "down");
- while (count--) {
- x_outw(port, MEM_RW(pInt, dst));
- dst += inc;
- }
- return dst - base;
-}
-
-int
-port_rep_outl(xf86Int10InfoPtr pInt,
- CARD16 port, CARD32 base, int d_f, CARD32 count)
-{
- register int inc = d_f ? -4 : 4;
- CARD32 dst = base;
- if (PRINT_PORT && DEBUG_IO_TRACE())
- ErrorF(" rep_outl(%#x) %ld bytes at %8.8lx %s\n",
- port, count, base, d_f ? "up" : "down");
- while (count--) {
- x_outl(port, MEM_RL(pInt, dst));
- dst += inc;
- }
- return dst - base;
-}
-
-CARD8
-x_inb(CARD16 port)
-{
- CARD8 val;
-
- if (port == 0x40) {
- Int10Current->inb40time++;
- val = (CARD8)(Int10Current->inb40time >>
- ((Int10Current->inb40time & 1) << 3));
- if (PRINT_PORT && DEBUG_IO_TRACE())
- ErrorF(" inb(%#x) = %2.2x\n", port, val);
-#ifdef __NOT_YET__
- } else if (port < 0x0100) { /* Don't interfere with mainboard */
- val = 0;
- xf86DrvMsgVerb(Int10Current->scrnIndex, X_NOT_IMPLEMENTED, 2,
- "inb 0x%4.4x\n", port);
- if (xf86GetVerbosity() > 3) {
- dump_registers(Int10Current);
- stack_trace(Int10Current);
- }
-#endif /* __NOT_YET__ */
- } else if (!pciCfg1inb(port, &val)) {
- val = inb(Int10Current->ioBase + port);
- if (PRINT_PORT && DEBUG_IO_TRACE())
- ErrorF(" inb(%#x) = %2.2x\n", port, val);
- }
- return val;
-}
-
-CARD16
-x_inw(CARD16 port)
-{
- CARD16 val;
-
- if (port == 0x5c) {
- struct timeval tv;
-
- /*
- * Emulate a PC98's timer. Typical resolution is 3.26 usec.
- * Approximate this by dividing by 3.
- */
- X_GETTIMEOFDAY(&tv);
- val = (CARD16)(tv.tv_usec / 3);
- } else if (!pciCfg1inw(port, &val)) {
- val = inw(Int10Current->ioBase + port);
- if (PRINT_PORT && DEBUG_IO_TRACE())
- ErrorF(" inw(%#x) = %4.4x\n", port, val);
- }
- return val;
-}
-
-void
-x_outb(CARD16 port, CARD8 val)
-{
- if ((port == 0x43) && (val == 0)) {
- struct timeval tv;
- /*
- * Emulate a PC's timer 0. Such timers typically have a resolution of
- * some .838 usec per tick, but this can only provide 1 usec per tick.
- * (Not that this matters much, given inherent emulation delays.) Use
- * the bottom bit as a byte select. See inb(0x40) above.
- */
- X_GETTIMEOFDAY(&tv);
- Int10Current->inb40time = (CARD16)(tv.tv_usec | 1);
- if (PRINT_PORT && DEBUG_IO_TRACE())
- ErrorF(" outb(%#x, %2.2x)\n", port, val);
-#ifdef __NOT_YET__
- } else if (port < 0x0100) { /* Don't interfere with mainboard */
- xf86DrvMsgVerb(Int10Current->scrnIndex, X_NOT_IMPLEMENTED, 2,
- "outb 0x%4.4x,0x%2.2x\n", port, val);
- if (xf86GetVerbosity() > 3) {
- dump_registers(Int10Current);
- stack_trace(Int10Current);
- }
-#endif /* __NOT_YET__ */
- } else if (!pciCfg1outb(port, val)) {
- if (PRINT_PORT && DEBUG_IO_TRACE())
- ErrorF(" outb(%#x, %2.2x)\n", port, val);
- outb(Int10Current->ioBase + port, val);
- }
-}
-
-void
-x_outw(CARD16 port, CARD16 val)
-{
-
- if (!pciCfg1outw(port, val)) {
- if (PRINT_PORT && DEBUG_IO_TRACE())
- ErrorF(" outw(%#x, %4.4x)\n", port, val);
- outw(Int10Current->ioBase + port, val);
- }
-}
-
-CARD32
-x_inl(CARD16 port)
-{
- CARD32 val;
-
- if (!pciCfg1in(port, &val)) {
- val = inl(Int10Current->ioBase + port);
- if (PRINT_PORT && DEBUG_IO_TRACE())
- ErrorF(" inl(%#x) = %8.8lx\n", port, val);
- }
- return val;
-}
-
-void
-x_outl(CARD16 port, CARD32 val)
-{
- if (!pciCfg1out(port, val)) {
- if (PRINT_PORT && DEBUG_IO_TRACE())
- ErrorF(" outl(%#x, %8.8lx)\n", port, val);
- outl(Int10Current->ioBase + port, val);
- }
-}
-
-CARD8
-Mem_rb(CARD32 addr)
-{
- return (*Int10Current->mem->rb)(Int10Current, addr);
-}
-
-CARD16
-Mem_rw(CARD32 addr)
-{
- return (*Int10Current->mem->rw)(Int10Current, addr);
-}
-
-CARD32
-Mem_rl(CARD32 addr)
-{
- return (*Int10Current->mem->rl)(Int10Current, addr);
-}
-
-void
-Mem_wb(CARD32 addr, CARD8 val)
-{
- (*Int10Current->mem->wb)(Int10Current, addr, val);
-}
-
-void
-Mem_ww(CARD32 addr, CARD16 val)
-{
- (*Int10Current->mem->ww)(Int10Current, addr, val);
-}
-
-void
-Mem_wl(CARD32 addr, CARD32 val)
-{
- (*Int10Current->mem->wl)(Int10Current, addr, val);
-}
-
-static CARD32 PciCfg1Addr = 0;
-
-#define PCI_OFFSET(x) ((x) & 0x000000ff)
-#define PCI_TAG(x) ((x) & 0x7fffff00)
-
-static struct pci_device*
-pci_device_for_cfg_address (CARD32 addr)
-{
- struct pci_device *dev = NULL;
- PCITAG tag = PCI_TAG(addr);
- struct pci_slot_match slot_match = {
- .domain = PCI_DOM_FROM_TAG(tag),
- .bus = PCI_BUS_NO_DOMAIN(PCI_BUS_FROM_TAG(tag)),
- .dev = PCI_DEV_FROM_TAG(tag),
- .func = PCI_FUNC_FROM_TAG(tag),
- .match_data = 0
- };
-
- struct pci_device_iterator *iter =
- pci_slot_match_iterator_create (&slot_match);
-
- if (iter)
- dev = pci_device_next(iter);
-
- pci_iterator_destroy(iter);
-
- return dev;
-}
-
-static int
-pciCfg1in(CARD16 addr, CARD32 *val)
-{
- if (addr == 0xCF8) {
- *val = PciCfg1Addr;
- return 1;
- }
- if (addr == 0xCFC) {
- pci_device_cfg_read_u32(pci_device_for_cfg_address(PciCfg1Addr),
- val, PCI_OFFSET(PciCfg1Addr));
- if (PRINT_PORT && DEBUG_IO_TRACE())
- ErrorF(" cfg_inl(%#lx) = %8.8lx\n", PciCfg1Addr, *val);
- return 1;
- }
- return 0;
-}
-
-static int
-pciCfg1out(CARD16 addr, CARD32 val)
-{
- if (addr == 0xCF8) {
- PciCfg1Addr = val;
- return 1;
- }
- if (addr == 0xCFC) {
- if (PRINT_PORT && DEBUG_IO_TRACE())
- ErrorF(" cfg_outl(%#lx, %8.8lx)\n", PciCfg1Addr, val);
- pci_device_cfg_write_u32(pci_device_for_cfg_address(PciCfg1Addr),
- val, PCI_OFFSET(PciCfg1Addr));
- return 1;
- }
- return 0;
-}
-
-static int
-pciCfg1inw(CARD16 addr, CARD16 *val)
-{
- int shift;
-
- if ((addr >= 0xCF8) && (addr <= 0xCFB)) {
- shift = (addr - 0xCF8) * 8;
- *val = (PciCfg1Addr >> shift) & 0xffff;
- return 1;
- }
- if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
- const unsigned offset = addr - 0xCFC;
-
- pci_device_cfg_read_u16(pci_device_for_cfg_address(PciCfg1Addr),
- val, PCI_OFFSET(PciCfg1Addr) + offset);
- if (PRINT_PORT && DEBUG_IO_TRACE())
- ErrorF(" cfg_inw(%#lx) = %4.4x\n", PciCfg1Addr + offset, *val);
- return 1;
- }
- return 0;
-}
-
-static int
-pciCfg1outw(CARD16 addr, CARD16 val)
-{
- int shift;
-
- if ((addr >= 0xCF8) && (addr <= 0xCFB)) {
- shift = (addr - 0xCF8) * 8;
- PciCfg1Addr &= ~(0xffff << shift);
- PciCfg1Addr |= ((CARD32) val) << shift;
- return 1;
- }
- if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
- const unsigned offset = addr - 0xCFC;
-
- if (PRINT_PORT && DEBUG_IO_TRACE())
- ErrorF(" cfg_outw(%#lx, %4.4x)\n", PciCfg1Addr + offset, val);
- pci_device_cfg_write_u16(pci_device_for_cfg_address(PciCfg1Addr),
- val, PCI_OFFSET(PciCfg1Addr) + offset);
- return 1;
- }
- return 0;
-}
-
-static int
-pciCfg1inb(CARD16 addr, CARD8 *val)
-{
- int shift;
-
- if ((addr >= 0xCF8) && (addr <= 0xCFB)) {
- shift = (addr - 0xCF8) * 8;
- *val = (PciCfg1Addr >> shift) & 0xff;
- return 1;
- }
- if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
- const unsigned offset = addr - 0xCFC;
-
- pci_device_cfg_read_u8(pci_device_for_cfg_address(PciCfg1Addr),
- val, PCI_OFFSET(PciCfg1Addr) + offset);
- if (PRINT_PORT && DEBUG_IO_TRACE())
- ErrorF(" cfg_inb(%#lx) = %2.2x\n", PciCfg1Addr + offset, *val);
- return 1;
- }
- return 0;
-}
-
-static int
-pciCfg1outb(CARD16 addr, CARD8 val)
-{
- int shift;
-
- if ((addr >= 0xCF8) && (addr <= 0xCFB)) {
- shift = (addr - 0xCF8) * 8;
- PciCfg1Addr &= ~(0xff << shift);
- PciCfg1Addr |= ((CARD32) val) << shift;
- return 1;
- }
- if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
- const unsigned offset = addr - 0xCFC;
-
- if (PRINT_PORT && DEBUG_IO_TRACE())
- ErrorF(" cfg_outb(%#lx, %2.2x)\n", PciCfg1Addr + offset, val);
- pci_device_cfg_write_u8(pci_device_for_cfg_address(PciCfg1Addr),
- val, PCI_OFFSET(PciCfg1Addr) + offset);
- return 1;
- }
- return 0;
-}
-
-CARD8
-bios_checksum(const CARD8 *start, int size)
-{
- CARD8 sum = 0;
-
- while (size-- > 0)
- sum += *start++;
- return sum;
-}
-
-/*
- * Lock/Unlock legacy VGA. Some Bioses try to be very clever and make
- * an attempt to detect a legacy ISA card. If they find one they might
- * act very strange: for example they might configure the card as a
- * monochrome card. This might cause some drivers to choke.
- * To avoid this we attempt legacy VGA by writing to all know VGA
- * disable registers before we call the BIOS initialization and
- * restore the original values afterwards. In beween we hold our
- * breath. To get to a (possibly exising) ISA card need to disable
- * our current PCI card.
- */
-/*
- * This is just for booting: we just want to catch pure
- * legacy vga therefore we don't worry about mmio etc.
- * This stuff should really go into vgaHW.c. However then
- * the driver would have to load the vga-module prior to
- * doing int10.
- */
-void
-LockLegacyVGA(xf86Int10InfoPtr pInt, legacyVGAPtr vga)
-{
- vga->save_msr = inb(pInt->ioBase + 0x03CC);
- vga->save_vse = inb(pInt->ioBase + 0x03C3);
-#ifndef __ia64__
- vga->save_46e8 = inb(pInt->ioBase + 0x46E8);
-#endif
- vga->save_pos102 = inb(pInt->ioBase + 0x0102);
- outb(pInt->ioBase + 0x03C2, ~(CARD8)0x03 & vga->save_msr);
- outb(pInt->ioBase + 0x03C3, ~(CARD8)0x01 & vga->save_vse);
-#ifndef __ia64__
- outb(pInt->ioBase + 0x46E8, ~(CARD8)0x08 & vga->save_46e8);
-#endif
- outb(pInt->ioBase + 0x0102, ~(CARD8)0x01 & vga->save_pos102);
-}
-
-void
-UnlockLegacyVGA(xf86Int10InfoPtr pInt, legacyVGAPtr vga)
-{
- outb(pInt->ioBase + 0x0102, vga->save_pos102);
-#ifndef __ia64__
- outb(pInt->ioBase + 0x46E8, vga->save_46e8);
-#endif
- outb(pInt->ioBase + 0x03C3, vga->save_vse);
- outb(pInt->ioBase + 0x03C2, vga->save_msr);
-}
-
-#if defined (_PC)
-static void
-SetResetBIOSVars(xf86Int10InfoPtr pInt, Bool set)
-{
- int pagesize = getpagesize();
- unsigned char* base = xf86MapVidMem(pInt->scrnIndex,
- VIDMEM_MMIO, 0, pagesize);
- int i;
-
- if (set) {
- for (i = BIOS_SCRATCH_OFF; i < BIOS_SCRATCH_END; i++)
- MEM_WW(pInt, i, *(base + i));
- } else {
- for (i = BIOS_SCRATCH_OFF; i < BIOS_SCRATCH_END; i++)
- *(base + i) = MEM_RW(pInt, i);
- }
-
- xf86UnMapVidMem(pInt->scrnIndex,base,pagesize);
-}
-
-void
-xf86Int10SaveRestoreBIOSVars(xf86Int10InfoPtr pInt, Bool save)
-{
- int pagesize = getpagesize();
- unsigned char* base;
- int i;
-
- if (!xf86IsEntityPrimary(pInt->entityIndex)
- || (!save && !pInt->BIOSScratch))
- return;
-
- base = xf86MapVidMem(pInt->scrnIndex, VIDMEM_MMIO, 0, pagesize);
- base += BIOS_SCRATCH_OFF;
- if (save) {
- if ((pInt->BIOSScratch
- = xnfalloc(BIOS_SCRATCH_LEN)))
- for (i = 0; i < BIOS_SCRATCH_LEN; i++)
- *(((char*)pInt->BIOSScratch + i)) = *(base + i);
- } else {
- if (pInt->BIOSScratch) {
- for (i = 0; i < BIOS_SCRATCH_LEN; i++)
- *(base + i) = *(pInt->BIOSScratch + i);
- xfree(pInt->BIOSScratch);
- pInt->BIOSScratch = NULL;
- }
- }
-
- xf86UnMapVidMem(pInt->scrnIndex,base - BIOS_SCRATCH_OFF ,pagesize);
-}
-#endif
-
-xf86Int10InfoPtr
-xf86InitInt10(int entityIndex)
-{
- return xf86ExtendedInitInt10(entityIndex, 0);
-}
+/*
+ * XFree86 int10 module
+ * execute BIOS int 10h calls in x86 real mode environment
+ * Copyright 1999 Egbert Eich
+ *
+ * Part of this code was inspired by the VBIOS POSTing code in DOSEMU
+ * developed by the "DOSEMU-Development-Team"
+ */
+
+/*
+ * To debug port accesses define PRINT_PORT to 1.
+ * Note! You also have to comment out ioperm()
+ * in xf86EnableIO(). Otherwise we won't trap
+ * on PIO.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#define PRINT_PORT 0
+
+#include <unistd.h>
+
+#include <X11/Xos.h>
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "compiler.h"
+#define _INT10_PRIVATE
+#include "int10Defines.h"
+#include "xf86int10.h"
+#include "Pci.h"
+#ifdef _X86EMU
+#include "x86emu/x86emui.h"
+#else
+#define DEBUG_IO_TRACE() 0
+#endif
+#include <pciaccess.h>
+
+static int pciCfg1in(CARD16 addr, CARD32 *val);
+static int pciCfg1out(CARD16 addr, CARD32 val);
+static int pciCfg1inw(CARD16 addr, CARD16 *val);
+static int pciCfg1outw(CARD16 addr, CARD16 val);
+static int pciCfg1inb(CARD16 addr, CARD8 *val);
+static int pciCfg1outb(CARD16 addr, CARD8 val);
+#if defined (_PC)
+static void SetResetBIOSVars(xf86Int10InfoPtr pInt, Bool set);
+#endif
+
+#define REG pInt
+
+int
+setup_int(xf86Int10InfoPtr pInt)
+{
+ if (pInt != Int10Current) {
+ if (!MapCurrentInt10(pInt))
+ return -1;
+ Int10Current = pInt;
+ }
+ X86_EAX = (CARD32) pInt->ax;
+ X86_EBX = (CARD32) pInt->bx;
+ X86_ECX = (CARD32) pInt->cx;
+ X86_EDX = (CARD32) pInt->dx;
+ X86_ESI = (CARD32) pInt->si;
+ X86_EDI = (CARD32) pInt->di;
+ X86_EBP = (CARD32) pInt->bp;
+ X86_ESP = 0x1000; X86_SS = pInt->stackseg >> 4;
+ X86_EIP = 0x0600; X86_CS = 0x0; /* address of 'hlt' */
+ X86_DS = 0x40; /* standard pc ds */
+ X86_ES = pInt->es;
+ X86_FS = 0;
+ X86_GS = 0;
+ X86_EFLAGS = X86_IF_MASK | X86_IOPL_MASK;
+#if defined (_PC)
+ if (pInt->Flags & SET_BIOS_SCRATCH)
+ SetResetBIOSVars(pInt, TRUE);
+#endif
+ return xf86BlockSIGIO();
+}
+
+void
+finish_int(xf86Int10InfoPtr pInt, int sig)
+{
+ xf86UnblockSIGIO(sig);
+ pInt->ax = (CARD32) X86_EAX;
+ pInt->bx = (CARD32) X86_EBX;
+ pInt->cx = (CARD32) X86_ECX;
+ pInt->dx = (CARD32) X86_EDX;
+ pInt->si = (CARD32) X86_ESI;
+ pInt->di = (CARD32) X86_EDI;
+ pInt->es = (CARD16) X86_ES;
+ pInt->bp = (CARD32) X86_EBP;
+ pInt->flags = (CARD32) X86_FLAGS;
+#if defined (_PC)
+ if (pInt->Flags & RESTORE_BIOS_SCRATCH)
+ SetResetBIOSVars(pInt, FALSE);
+#endif
+}
+
+/* general software interrupt handler */
+CARD32
+getIntVect(xf86Int10InfoPtr pInt,int num)
+{
+ return MEM_RW(pInt, num << 2) + (MEM_RW(pInt, (num << 2) + 2) << 4);
+}
+
+void
+pushw(xf86Int10InfoPtr pInt, CARD16 val)
+{
+ X86_ESP -= 2;
+ MEM_WW(pInt, ((CARD32) X86_SS << 4) + X86_SP, val);
+}
+
+int
+run_bios_int(int num, xf86Int10InfoPtr pInt)
+{
+ CARD32 eflags;
+#ifndef _PC
+ /* check if bios vector is initialized */
+ if (MEM_RW(pInt, (num << 2) + 2) == (SYS_BIOS >> 4)) { /* SYS_BIOS_SEG ?*/
+
+ if (num == 21 && X86_AH == 0x4e) {
+ xf86DrvMsg(pInt->scrnIndex, X_NOTICE,
+ "Failing Find-Matching-File on non-PC"
+ " (int 21, func 4e)\n");
+ X86_AX = 2;
+ SET_FLAG(F_CF);
+ return 1;
+ } else {
+ xf86DrvMsgVerb(pInt->scrnIndex, X_NOT_IMPLEMENTED, 2,
+ "Ignoring int 0x%02x call\n", num);
+ if (xf86GetVerbosity() > 3) {
+ dump_registers(pInt);
+ stack_trace(pInt);
+ }
+ return 1;
+ }
+ }
+#endif
+#ifdef PRINT_INT
+ ErrorF("calling card BIOS at: ");
+#endif
+ eflags = X86_EFLAGS;
+#if 0
+ eflags = eflags | IF_MASK;
+ X86_EFLAGS = X86_EFLAGS & ~(VIF_MASK | TF_MASK | IF_MASK | NT_MASK);
+#endif
+ pushw(pInt, eflags);
+ pushw(pInt, X86_CS);
+ pushw(pInt, X86_IP);
+ X86_CS = MEM_RW(pInt, (num << 2) + 2);
+ X86_IP = MEM_RW(pInt, num << 2);
+#ifdef PRINT_INT
+ ErrorF("0x%x:%lx\n", X86_CS, X86_EIP);
+#endif
+ return 1;
+}
+
+/* Debugging stuff */
+void
+dump_code(xf86Int10InfoPtr pInt)
+{
+ int i;
+ unsigned long lina = SEG_ADR((CARD32), X86_CS, IP);
+
+ xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3, "code at 0x%8.8lx:\n", lina);
+ for (i=0; i<0x10; i++)
+ xf86ErrorFVerb(3, " %2.2x", MEM_RB(pInt, lina + i));
+ xf86ErrorFVerb(3, "\n");
+ for (; i<0x20; i++)
+ xf86ErrorFVerb(3, " %2.2x", MEM_RB(pInt, lina + i));
+ xf86ErrorFVerb(3, "\n");
+}
+
+void
+dump_registers(xf86Int10InfoPtr pInt)
+{
+ xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3,
+ "EAX=0x%8.8lx, EBX=0x%8.8lx, ECX=0x%8.8lx, EDX=0x%8.8lx\n",
+ (unsigned long)X86_EAX, (unsigned long)X86_EBX,
+ (unsigned long)X86_ECX, (unsigned long)X86_EDX);
+ xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3,
+ "ESP=0x%8.8lx, EBP=0x%8.8lx, ESI=0x%8.8lx, EDI=0x%8.8lx\n",
+ (unsigned long)X86_ESP, (unsigned long)X86_EBP,
+ (unsigned long)X86_ESI, (unsigned long)X86_EDI);
+ xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3,
+ "CS=0x%4.4x, SS=0x%4.4x,"
+ " DS=0x%4.4x, ES=0x%4.4x, FS=0x%4.4x, GS=0x%4.4x\n",
+ X86_CS, X86_SS, X86_DS, X86_ES, X86_FS, X86_GS);
+ xf86DrvMsgVerb(pInt->scrnIndex, X_INFO, 3,
+ "EIP=0x%8.8lx, EFLAGS=0x%8.8lx\n",
+ (unsigned long)X86_EIP, (unsigned long)X86_EFLAGS);
+}
+
+void
+stack_trace(xf86Int10InfoPtr pInt)
+{
+ int i = 0;
+ unsigned long stack = SEG_ADR((CARD32), X86_SS, SP);
+ unsigned long tail = (CARD32)((X86_SS << 4) + 0x1000);
+
+ if (stack >= tail) return;
+
+ xf86MsgVerb(X_INFO, 3, "stack at 0x%8.8lx:\n", stack);
+ for (; stack < tail; stack++) {
+ xf86ErrorFVerb(3, " %2.2x", MEM_RB(pInt, stack));
+ i = (i + 1) % 0x10;
+ if (!i)
+ xf86ErrorFVerb(3, "\n");
+ }
+ if (i)
+ xf86ErrorFVerb(3, "\n");
+}
+
+int
+port_rep_inb(xf86Int10InfoPtr pInt,
+ CARD16 port, CARD32 base, int d_f, CARD32 count)
+{
+ register int inc = d_f ? -1 : 1;
+ CARD32 dst = base;
+ if (PRINT_PORT && DEBUG_IO_TRACE())
+ ErrorF(" rep_insb(%#x) %ld bytes at %8.8lx %s\n",
+ port, count, base, d_f ? "up" : "down");
+ while (count--) {
+ MEM_WB(pInt, dst, x_inb(port));
+ dst += inc;
+ }
+ return dst - base;
+}
+
+int
+port_rep_inw(xf86Int10InfoPtr pInt,
+ CARD16 port, CARD32 base, int d_f, CARD32 count)
+{
+ register int inc = d_f ? -2 : 2;
+ CARD32 dst = base;
+ if (PRINT_PORT && DEBUG_IO_TRACE())
+ ErrorF(" rep_insw(%#x) %ld bytes at %8.8lx %s\n",
+ port, count, base, d_f ? "up" : "down");
+ while (count--) {
+ MEM_WW(pInt, dst, x_inw(port));
+ dst += inc;
+ }
+ return dst - base;
+}
+
+int
+port_rep_inl(xf86Int10InfoPtr pInt,
+ CARD16 port, CARD32 base, int d_f, CARD32 count)
+{
+ register int inc = d_f ? -4 : 4;
+ CARD32 dst = base;
+ if (PRINT_PORT && DEBUG_IO_TRACE())
+ ErrorF(" rep_insl(%#x) %ld bytes at %8.8lx %s\n",
+ port, count, base, d_f ? "up" : "down");
+ while (count--) {
+ MEM_WL(pInt, dst, x_inl(port));
+ dst += inc;
+ }
+ return dst - base;
+}
+
+int
+port_rep_outb(xf86Int10InfoPtr pInt,
+ CARD16 port, CARD32 base, int d_f, CARD32 count)
+{
+ register int inc = d_f ? -1 : 1;
+ CARD32 dst = base;
+ if (PRINT_PORT && DEBUG_IO_TRACE())
+ ErrorF(" rep_outb(%#x) %ld bytes at %8.8lx %s\n",
+ port, count, base, d_f ? "up" : "down");
+ while (count--) {
+ x_outb(port, MEM_RB(pInt, dst));
+ dst += inc;
+ }
+ return dst - base;
+}
+
+int
+port_rep_outw(xf86Int10InfoPtr pInt,
+ CARD16 port, CARD32 base, int d_f, CARD32 count)
+{
+ register int inc = d_f ? -2 : 2;
+ CARD32 dst = base;
+ if (PRINT_PORT && DEBUG_IO_TRACE())
+ ErrorF(" rep_outw(%#x) %ld bytes at %8.8lx %s\n",
+ port, count, base, d_f ? "up" : "down");
+ while (count--) {
+ x_outw(port, MEM_RW(pInt, dst));
+ dst += inc;
+ }
+ return dst - base;
+}
+
+int
+port_rep_outl(xf86Int10InfoPtr pInt,
+ CARD16 port, CARD32 base, int d_f, CARD32 count)
+{
+ register int inc = d_f ? -4 : 4;
+ CARD32 dst = base;
+ if (PRINT_PORT && DEBUG_IO_TRACE())
+ ErrorF(" rep_outl(%#x) %ld bytes at %8.8lx %s\n",
+ port, count, base, d_f ? "up" : "down");
+ while (count--) {
+ x_outl(port, MEM_RL(pInt, dst));
+ dst += inc;
+ }
+ return dst - base;
+}
+
+CARD8
+x_inb(CARD16 port)
+{
+ CARD8 val;
+
+ if (port == 0x40) {
+ Int10Current->inb40time++;
+ val = (CARD8)(Int10Current->inb40time >>
+ ((Int10Current->inb40time & 1) << 3));
+ if (PRINT_PORT && DEBUG_IO_TRACE())
+ ErrorF(" inb(%#x) = %2.2x\n", port, val);
+#ifdef __NOT_YET__
+ } else if (port < 0x0100) { /* Don't interfere with mainboard */
+ val = 0;
+ xf86DrvMsgVerb(Int10Current->scrnIndex, X_NOT_IMPLEMENTED, 2,
+ "inb 0x%4.4x\n", port);
+ if (xf86GetVerbosity() > 3) {
+ dump_registers(Int10Current);
+ stack_trace(Int10Current);
+ }
+#endif /* __NOT_YET__ */
+ } else if (!pciCfg1inb(port, &val)) {
+ val = inb(Int10Current->ioBase + port);
+ if (PRINT_PORT && DEBUG_IO_TRACE())
+ ErrorF(" inb(%#x) = %2.2x\n", port, val);
+ }
+ return val;
+}
+
+CARD16
+x_inw(CARD16 port)
+{
+ CARD16 val;
+
+ if (port == 0x5c) {
+ struct timeval tv;
+
+ /*
+ * Emulate a PC98's timer. Typical resolution is 3.26 usec.
+ * Approximate this by dividing by 3.
+ */
+ X_GETTIMEOFDAY(&tv);
+ val = (CARD16)(tv.tv_usec / 3);
+ } else if (!pciCfg1inw(port, &val)) {
+ val = inw(Int10Current->ioBase + port);
+ if (PRINT_PORT && DEBUG_IO_TRACE())
+ ErrorF(" inw(%#x) = %4.4x\n", port, val);
+ }
+ return val;
+}
+
+void
+x_outb(CARD16 port, CARD8 val)
+{
+ if ((port == 0x43) && (val == 0)) {
+ struct timeval tv;
+ /*
+ * Emulate a PC's timer 0. Such timers typically have a resolution of
+ * some .838 usec per tick, but this can only provide 1 usec per tick.
+ * (Not that this matters much, given inherent emulation delays.) Use
+ * the bottom bit as a byte select. See inb(0x40) above.
+ */
+ X_GETTIMEOFDAY(&tv);
+ Int10Current->inb40time = (CARD16)(tv.tv_usec | 1);
+ if (PRINT_PORT && DEBUG_IO_TRACE())
+ ErrorF(" outb(%#x, %2.2x)\n", port, val);
+#ifdef __NOT_YET__
+ } else if (port < 0x0100) { /* Don't interfere with mainboard */
+ xf86DrvMsgVerb(Int10Current->scrnIndex, X_NOT_IMPLEMENTED, 2,
+ "outb 0x%4.4x,0x%2.2x\n", port, val);
+ if (xf86GetVerbosity() > 3) {
+ dump_registers(Int10Current);
+ stack_trace(Int10Current);
+ }
+#endif /* __NOT_YET__ */
+ } else if (!pciCfg1outb(port, val)) {
+ if (PRINT_PORT && DEBUG_IO_TRACE())
+ ErrorF(" outb(%#x, %2.2x)\n", port, val);
+ outb(Int10Current->ioBase + port, val);
+ }
+}
+
+void
+x_outw(CARD16 port, CARD16 val)
+{
+
+ if (!pciCfg1outw(port, val)) {
+ if (PRINT_PORT && DEBUG_IO_TRACE())
+ ErrorF(" outw(%#x, %4.4x)\n", port, val);
+ outw(Int10Current->ioBase + port, val);
+ }
+}
+
+CARD32
+x_inl(CARD16 port)
+{
+ CARD32 val;
+
+ if (!pciCfg1in(port, &val)) {
+ val = inl(Int10Current->ioBase + port);
+ if (PRINT_PORT && DEBUG_IO_TRACE())
+ ErrorF(" inl(%#x) = %8.8lx\n", port, val);
+ }
+ return val;
+}
+
+void
+x_outl(CARD16 port, CARD32 val)
+{
+ if (!pciCfg1out(port, val)) {
+ if (PRINT_PORT && DEBUG_IO_TRACE())
+ ErrorF(" outl(%#x, %8.8lx)\n", port, val);
+ outl(Int10Current->ioBase + port, val);
+ }
+}
+
+CARD8
+Mem_rb(CARD32 addr)
+{
+ return (*Int10Current->mem->rb)(Int10Current, addr);
+}
+
+CARD16
+Mem_rw(CARD32 addr)
+{
+ return (*Int10Current->mem->rw)(Int10Current, addr);
+}
+
+CARD32
+Mem_rl(CARD32 addr)
+{
+ return (*Int10Current->mem->rl)(Int10Current, addr);
+}
+
+void
+Mem_wb(CARD32 addr, CARD8 val)
+{
+ (*Int10Current->mem->wb)(Int10Current, addr, val);
+}
+
+void
+Mem_ww(CARD32 addr, CARD16 val)
+{
+ (*Int10Current->mem->ww)(Int10Current, addr, val);
+}
+
+void
+Mem_wl(CARD32 addr, CARD32 val)
+{
+ (*Int10Current->mem->wl)(Int10Current, addr, val);
+}
+
+static CARD32 PciCfg1Addr = 0;
+
+#define PCI_OFFSET(x) ((x) & 0x000000ff)
+#define PCI_TAG(x) ((x) & 0x7fffff00)
+
+static struct pci_device*
+pci_device_for_cfg_address (CARD32 addr)
+{
+ struct pci_device *dev = NULL;
+ PCITAG tag = PCI_TAG(addr);
+ struct pci_slot_match slot_match = {
+ .domain = PCI_DOM_FROM_TAG(tag),
+ .bus = PCI_BUS_NO_DOMAIN(PCI_BUS_FROM_TAG(tag)),
+ .dev = PCI_DEV_FROM_TAG(tag),
+ .func = PCI_FUNC_FROM_TAG(tag),
+ .match_data = 0
+ };
+
+ struct pci_device_iterator *iter =
+ pci_slot_match_iterator_create (&slot_match);
+
+ if (iter)
+ dev = pci_device_next(iter);
+
+ pci_iterator_destroy(iter);
+
+ return dev;
+}
+
+static int
+pciCfg1in(CARD16 addr, CARD32 *val)
+{
+ if (addr == 0xCF8) {
+ *val = PciCfg1Addr;
+ return 1;
+ }
+ if (addr == 0xCFC) {
+ pci_device_cfg_read_u32(pci_device_for_cfg_address(PciCfg1Addr),
+ val, PCI_OFFSET(PciCfg1Addr));
+ if (PRINT_PORT && DEBUG_IO_TRACE())
+ ErrorF(" cfg_inl(%#lx) = %8.8lx\n", PciCfg1Addr, *val);
+ return 1;
+ }
+ return 0;
+}
+
+static int
+pciCfg1out(CARD16 addr, CARD32 val)
+{
+ if (addr == 0xCF8) {
+ PciCfg1Addr = val;
+ return 1;
+ }
+ if (addr == 0xCFC) {
+ if (PRINT_PORT && DEBUG_IO_TRACE())
+ ErrorF(" cfg_outl(%#lx, %8.8lx)\n", PciCfg1Addr, val);
+ pci_device_cfg_write_u32(pci_device_for_cfg_address(PciCfg1Addr),
+ val, PCI_OFFSET(PciCfg1Addr));
+ return 1;
+ }
+ return 0;
+}
+
+static int
+pciCfg1inw(CARD16 addr, CARD16 *val)
+{
+ int shift;
+
+ if ((addr >= 0xCF8) && (addr <= 0xCFB)) {
+ shift = (addr - 0xCF8) * 8;
+ *val = (PciCfg1Addr >> shift) & 0xffff;
+ return 1;
+ }
+ if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
+ const unsigned offset = addr - 0xCFC;
+
+ pci_device_cfg_read_u16(pci_device_for_cfg_address(PciCfg1Addr),
+ val, PCI_OFFSET(PciCfg1Addr) + offset);
+ if (PRINT_PORT && DEBUG_IO_TRACE())
+ ErrorF(" cfg_inw(%#lx) = %4.4x\n", PciCfg1Addr + offset, *val);
+ return 1;
+ }
+ return 0;
+}
+
+static int
+pciCfg1outw(CARD16 addr, CARD16 val)
+{
+ int shift;
+
+ if ((addr >= 0xCF8) && (addr <= 0xCFB)) {
+ shift = (addr - 0xCF8) * 8;
+ PciCfg1Addr &= ~(0xffff << shift);
+ PciCfg1Addr |= ((CARD32) val) << shift;
+ return 1;
+ }
+ if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
+ const unsigned offset = addr - 0xCFC;
+
+ if (PRINT_PORT && DEBUG_IO_TRACE())
+ ErrorF(" cfg_outw(%#lx, %4.4x)\n", PciCfg1Addr + offset, val);
+ pci_device_cfg_write_u16(pci_device_for_cfg_address(PciCfg1Addr),
+ val, PCI_OFFSET(PciCfg1Addr) + offset);
+ return 1;
+ }
+ return 0;
+}
+
+static int
+pciCfg1inb(CARD16 addr, CARD8 *val)
+{
+ int shift;
+
+ if ((addr >= 0xCF8) && (addr <= 0xCFB)) {
+ shift = (addr - 0xCF8) * 8;
+ *val = (PciCfg1Addr >> shift) & 0xff;
+ return 1;
+ }
+ if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
+ const unsigned offset = addr - 0xCFC;
+
+ pci_device_cfg_read_u8(pci_device_for_cfg_address(PciCfg1Addr),
+ val, PCI_OFFSET(PciCfg1Addr) + offset);
+ if (PRINT_PORT && DEBUG_IO_TRACE())
+ ErrorF(" cfg_inb(%#lx) = %2.2x\n", PciCfg1Addr + offset, *val);
+ return 1;
+ }
+ return 0;
+}
+
+static int
+pciCfg1outb(CARD16 addr, CARD8 val)
+{
+ int shift;
+
+ if ((addr >= 0xCF8) && (addr <= 0xCFB)) {
+ shift = (addr - 0xCF8) * 8;
+ PciCfg1Addr &= ~(0xff << shift);
+ PciCfg1Addr |= ((CARD32) val) << shift;
+ return 1;
+ }
+ if ((addr >= 0xCFC) && (addr <= 0xCFF)) {
+ const unsigned offset = addr - 0xCFC;
+
+ if (PRINT_PORT && DEBUG_IO_TRACE())
+ ErrorF(" cfg_outb(%#lx, %2.2x)\n", PciCfg1Addr + offset, val);
+ pci_device_cfg_write_u8(pci_device_for_cfg_address(PciCfg1Addr),
+ val, PCI_OFFSET(PciCfg1Addr) + offset);
+ return 1;
+ }
+ return 0;
+}
+
+CARD8
+bios_checksum(const CARD8 *start, int size)
+{
+ CARD8 sum = 0;
+
+ while (size-- > 0)
+ sum += *start++;
+ return sum;
+}
+
+/*
+ * Lock/Unlock legacy VGA. Some Bioses try to be very clever and make
+ * an attempt to detect a legacy ISA card. If they find one they might
+ * act very strange: for example they might configure the card as a
+ * monochrome card. This might cause some drivers to choke.
+ * To avoid this we attempt legacy VGA by writing to all know VGA
+ * disable registers before we call the BIOS initialization and
+ * restore the original values afterwards. In beween we hold our
+ * breath. To get to a (possibly exising) ISA card need to disable
+ * our current PCI card.
+ */
+/*
+ * This is just for booting: we just want to catch pure
+ * legacy vga therefore we don't worry about mmio etc.
+ * This stuff should really go into vgaHW.c. However then
+ * the driver would have to load the vga-module prior to
+ * doing int10.
+ */
+void
+LockLegacyVGA(xf86Int10InfoPtr pInt, legacyVGAPtr vga)
+{
+ vga->save_msr = inb(pInt->ioBase + 0x03CC);
+ vga->save_vse = inb(pInt->ioBase + 0x03C3);
+#ifndef __ia64__
+ vga->save_46e8 = inb(pInt->ioBase + 0x46E8);
+#endif
+ vga->save_pos102 = inb(pInt->ioBase + 0x0102);
+ outb(pInt->ioBase + 0x03C2, ~(CARD8)0x03 & vga->save_msr);
+ outb(pInt->ioBase + 0x03C3, ~(CARD8)0x01 & vga->save_vse);
+#ifndef __ia64__
+ outb(pInt->ioBase + 0x46E8, ~(CARD8)0x08 & vga->save_46e8);
+#endif
+ outb(pInt->ioBase + 0x0102, ~(CARD8)0x01 & vga->save_pos102);
+}
+
+void
+UnlockLegacyVGA(xf86Int10InfoPtr pInt, legacyVGAPtr vga)
+{
+ outb(pInt->ioBase + 0x0102, vga->save_pos102);
+#ifndef __ia64__
+ outb(pInt->ioBase + 0x46E8, vga->save_46e8);
+#endif
+ outb(pInt->ioBase + 0x03C3, vga->save_vse);
+ outb(pInt->ioBase + 0x03C2, vga->save_msr);
+}
+
+#if defined (_PC)
+static void
+SetResetBIOSVars(xf86Int10InfoPtr pInt, Bool set)
+{
+ int pagesize = getpagesize();
+ unsigned char* base = xf86MapVidMem(pInt->scrnIndex,
+ VIDMEM_MMIO, 0, pagesize);
+ int i;
+
+ if (set) {
+ for (i = BIOS_SCRATCH_OFF; i < BIOS_SCRATCH_END; i++)
+ MEM_WW(pInt, i, *(base + i));
+ } else {
+ for (i = BIOS_SCRATCH_OFF; i < BIOS_SCRATCH_END; i++)
+ *(base + i) = MEM_RW(pInt, i);
+ }
+
+ xf86UnMapVidMem(pInt->scrnIndex,base,pagesize);
+}
+
+void
+xf86Int10SaveRestoreBIOSVars(xf86Int10InfoPtr pInt, Bool save)
+{
+ int pagesize = getpagesize();
+ unsigned char* base;
+ int i;
+
+ if (!xf86IsEntityPrimary(pInt->entityIndex)
+ || (!save && !pInt->BIOSScratch))
+ return;
+
+ base = xf86MapVidMem(pInt->scrnIndex, VIDMEM_MMIO, 0, pagesize);
+ base += BIOS_SCRATCH_OFF;
+ if (save) {
+ if ((pInt->BIOSScratch
+ = xnfalloc(BIOS_SCRATCH_LEN)))
+ for (i = 0; i < BIOS_SCRATCH_LEN; i++)
+ *(((char*)pInt->BIOSScratch + i)) = *(base + i);
+ } else {
+ if (pInt->BIOSScratch) {
+ for (i = 0; i < BIOS_SCRATCH_LEN; i++)
+ *(base + i) = *(pInt->BIOSScratch + i);
+ free(pInt->BIOSScratch);
+ pInt->BIOSScratch = NULL;
+ }
+ }
+
+ xf86UnMapVidMem(pInt->scrnIndex,base - BIOS_SCRATCH_OFF ,pagesize);
+}
+#endif
+
+xf86Int10InfoPtr
+xf86InitInt10(int entityIndex)
+{
+ return xf86ExtendedInitInt10(entityIndex, 0);
+}
diff --git a/xorg-server/hw/xfree86/int10/helper_mem.c b/xorg-server/hw/xfree86/int10/helper_mem.c
index 6f6ecc2b3..b95b56a93 100644
--- a/xorg-server/hw/xfree86/int10/helper_mem.c
+++ b/xorg-server/hw/xfree86/int10/helper_mem.c
@@ -1,330 +1,330 @@
-/*
- * XFree86 int10 module
- * execute BIOS int 10h calls in x86 real mode environment
- * Copyright 1999 Egbert Eich
- */
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <string.h>
-#include <stdlib.h>
-
-#include "xf86.h"
-#include "xf86_OSproc.h"
-#include "compiler.h"
-#include "xf86Pci.h"
-#define _INT10_PRIVATE
-#if 0
-#include "int10Defines.h"
-#endif
-#include "xf86int10.h"
-
-#define REG pInt
-
-typedef enum {
- OPT_NOINT10,
- OPT_INIT_PRIMARY,
-} INT10Opts;
-
-static const OptionInfoRec INT10Options[] = {
- {OPT_NOINT10, "NoINT10", OPTV_BOOLEAN, {0}, FALSE },
- {OPT_INIT_PRIMARY, "InitPrimary", OPTV_BOOLEAN, {0}, FALSE },
- { -1, NULL, OPTV_NONE, {0}, FALSE },
-};
-
-#ifdef DEBUG
-void
-dprint(unsigned long start, unsigned long size)
-{
- int i,j;
- char *c = (char *)start;
-
- for (j = 0; j < (size >> 4); j++) {
- char *d = c;
- ErrorF("\n0x%lx: ",(unsigned long)c);
- for (i = 0; i<16; i++)
- ErrorF("%2.2x ",(unsigned char) (*(c++)));
- c = d;
- for (i = 0; i<16; i++) {
- ErrorF("%c",((((CARD8)(*c)) > 32) && (((CARD8)(*c)) < 128)) ?
- (unsigned char) (*(c)): '.');
- c++;
- }
- }
- ErrorF("\n");
-}
-#endif
-
-#ifndef _PC
-/*
- * here we are really paranoid about faking a "real"
- * BIOS. Most of this information was pulled from
- * dosemu.
- */
-void
-setup_int_vect(xf86Int10InfoPtr pInt)
-{
- int i;
-
- /* let the int vects point to the SYS_BIOS seg */
- for (i = 0; i < 0x80; i++) {
- MEM_WW(pInt, i << 2, 0);
- MEM_WW(pInt, (i << 2) + 2, SYS_BIOS >> 4);
- }
-
- reset_int_vect(pInt);
- /* font tables default location (int 1F) */
- MEM_WW(pInt,0x1f<<2,0xfa6e);
-
- /* int 11 default location (Get Equipment Configuration) */
- MEM_WW(pInt, 0x11 << 2, 0xf84d);
- /* int 12 default location (Get Conventional Memory Size) */
- MEM_WW(pInt, 0x12 << 2, 0xf841);
- /* int 15 default location (I/O System Extensions) */
- MEM_WW(pInt, 0x15 << 2, 0xf859);
- /* int 1A default location (RTC, PCI and others) */
- MEM_WW(pInt, 0x1a << 2, 0xff6e);
- /* int 05 default location (Bound Exceeded) */
- MEM_WW(pInt, 0x05 << 2, 0xff54);
- /* int 08 default location (Double Fault) */
- MEM_WW(pInt, 0x08 << 2, 0xfea5);
- /* int 13 default location (Disk) */
- MEM_WW(pInt, 0x13 << 2, 0xec59);
- /* int 0E default location (Page Fault) */
- MEM_WW(pInt, 0x0e << 2, 0xef57);
- /* int 17 default location (Parallel Port) */
- MEM_WW(pInt, 0x17 << 2, 0xefd2);
- /* fdd table default location (int 1e) */
- MEM_WW(pInt, 0x1e << 2, 0xefc7);
-
- /* Set Equipment flag to VGA */
- i = MEM_RB(pInt, 0x0410) & 0xCF;
- MEM_WB(pInt, 0x0410, i);
- /* XXX Perhaps setup more of the BDA here. See also int42(0x00). */
-}
-#endif
-
-int
-setup_system_bios(void *base_addr)
-{
- char *base = (char *) base_addr;
-
- /*
- * we trap the "industry standard entry points" to the BIOS
- * and all other locations by filling them with "hlt"
- * TODO: implement hlt-handler for these
- */
- memset(base, 0xf4, 0x10000);
-
- /* set bios date */
- strcpy(base + 0x0FFF5, "06/11/99");
- /* set up eisa ident string */
- strcpy(base + 0x0FFD9, "PCI_ISA");
- /* write system model id for IBM-AT */
- *((unsigned char *)(base + 0x0FFFE)) = 0xfc;
-
- return 1;
-}
-
-void
-reset_int_vect(xf86Int10InfoPtr pInt)
-{
- /*
- * This table is normally located at 0xF000:0xF0A4. However, int 0x42,
- * function 0 (Mode Set) expects it (or a copy) somewhere in the bottom
- * 64kB. Note that because this data doesn't survive POST, int 0x42 should
- * only be used during EGA/VGA BIOS initialisation.
- */
- static const CARD8 VideoParms[] = {
- /* Timing for modes 0x00 & 0x01 */
- 0x38, 0x28, 0x2d, 0x0a, 0x1f, 0x06, 0x19, 0x1c,
- 0x02, 0x07, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
- /* Timing for modes 0x02 & 0x03 */
- 0x71, 0x50, 0x5a, 0x0a, 0x1f, 0x06, 0x19, 0x1c,
- 0x02, 0x07, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
- /* Timing for modes 0x04, 0x05 & 0x06 */
- 0x38, 0x28, 0x2d, 0x0a, 0x7f, 0x06, 0x64, 0x70,
- 0x02, 0x01, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
- /* Timing for mode 0x07 */
- 0x61, 0x50, 0x52, 0x0f, 0x19, 0x06, 0x19, 0x19,
- 0x02, 0x0d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00,
- /* Display page lengths in little endian order */
- 0x00, 0x08, /* Modes 0x00 and 0x01 */
- 0x00, 0x10, /* Modes 0x02 and 0x03 */
- 0x00, 0x40, /* Modes 0x04 and 0x05 */
- 0x00, 0x40, /* Modes 0x06 and 0x07 */
- /* Number of columns for each mode */
- 40, 40, 80, 80, 40, 40, 80, 80,
- /* CGA Mode register value for each mode */
- 0x2c, 0x28, 0x2d, 0x29, 0x2a, 0x2e, 0x1e, 0x29,
- /* Padding */
- 0x00, 0x00, 0x00, 0x00
- };
- int i;
-
- for (i = 0; i < sizeof(VideoParms); i++)
- MEM_WB(pInt, i + (0x1000 - sizeof(VideoParms)), VideoParms[i]);
- MEM_WW(pInt, 0x1d << 2, 0x1000 - sizeof(VideoParms));
- MEM_WW(pInt, (0x1d << 2) + 2, 0);
-
- MEM_WW(pInt, 0x10 << 2, 0xf065);
- MEM_WW(pInt, (0x10 << 2) + 2, SYS_BIOS >> 4);
- MEM_WW(pInt, 0x42 << 2, 0xf065);
- MEM_WW(pInt, (0x42 << 2) + 2, SYS_BIOS >> 4);
- MEM_WW(pInt, 0x6D << 2, 0xf065);
- MEM_WW(pInt, (0x6D << 2) + 2, SYS_BIOS >> 4);
-}
-
-void
-set_return_trap(xf86Int10InfoPtr pInt)
-{
- /*
- * Here we set the exit condition: We return when we encounter
- * 'hlt' (=0xf4), which we locate at address 0x600 in x86 memory.
- */
- MEM_WB(pInt, 0x0600, 0xf4);
-
- /*
- * Allocate a segment for the stack
- */
- xf86Int10AllocPages(pInt, 1, &pInt->stackseg);
-}
-
-void *
-xf86HandleInt10Options(ScrnInfoPtr pScrn, int entityIndex)
-{
- EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex);
- OptionInfoPtr options = NULL;
-
- if (pEnt->device) {
- pointer configOptions = NULL;
-
- /* Check if xf86CollectOptions() has already been called */
- if (((pEnt->index < 0) ||
- !pScrn ||
- !(configOptions = pScrn->options)) &&
- pEnt->device)
- configOptions = pEnt->device->options;
-
- if (configOptions) {
- if (!(options = (OptionInfoPtr) xalloc(sizeof(INT10Options))))
- return NULL;
-
- (void)memcpy(options, INT10Options, sizeof(INT10Options));
- xf86ProcessOptions(pScrn->scrnIndex, configOptions, options);
- }
- }
- xfree(pEnt);
-
- return options;
-}
-
-Bool
-int10skip(const void* options)
-{
- Bool noint10 = FALSE;
-
- if (!options) return FALSE;
-
- xf86GetOptValBool(options, OPT_NOINT10, &noint10);
- return noint10;
-}
-
-Bool
-int10_check_bios(int scrnIndex, int codeSeg, const unsigned char* vbiosMem)
-{
- int size;
-
- if ((codeSeg & 0x1f) || /* Not 512-byte aligned otherwise */
- ((codeSeg << 4) < V_BIOS) ||
- ((codeSeg << 4) >= SYS_SIZE))
- return FALSE;
-
- if (xf86IsPc98())
- return FALSE;
-
- if ((*vbiosMem != 0x55) || (*(vbiosMem+1) != 0xAA) || !*(vbiosMem+2))
- return FALSE;
-
- size = *(vbiosMem + 2) * 512;
-
- if ((size + (codeSeg << 4)) > SYS_SIZE)
- return FALSE;
-
- if (bios_checksum(vbiosMem, size))
- xf86DrvMsg(scrnIndex, X_INFO, "Bad V_BIOS checksum\n");
-
- return TRUE;
-}
-
-Bool
-initPrimary(const void* options)
-{
- Bool initPrimary = FALSE;
-
- if (!options) return FALSE;
-
- xf86GetOptValBool(options, OPT_INIT_PRIMARY, &initPrimary);
- return initPrimary;
-}
-
-BusType
-xf86int10GetBiosLocationType(const xf86Int10InfoPtr pInt)
-{
- BusType location_type;
-
- EntityInfoPtr pEnt = xf86GetEntityInfo(pInt->entityIndex);
- location_type = pEnt->location.type;
- xfree(pEnt);
-
- return location_type;
-}
-
-
-#define CHECK_V_SEGMENT_RANGE(x) \
- if (((x) << 4) < V_BIOS) { \
- xf86DrvMsg(pInt->scrnIndex, X_ERROR, \
- "V_BIOS address 0x%lx out of range\n", \
- (unsigned long)(x) << 4); \
- return FALSE; \
- }
-
-Bool
-xf86int10GetBiosSegment(xf86Int10InfoPtr pInt, void *base)
-{
- unsigned i;
- int cs = ~0;
- int segments[4];
- const char * format;
-
- segments[0] = MEM_RW(pInt, (0x10 << 2) + 2);
- segments[1] = MEM_RW(pInt, (0x42 << 2) + 2);
- segments[2] = V_BIOS >> 4;
- segments[3] = ~0;
-
- format = "No V_BIOS found\n";
-
- for (i = 0; segments[i] != ~0; i++) {
- unsigned char * vbiosMem;
-
- cs = segments[i];
-
- CHECK_V_SEGMENT_RANGE(cs);
- vbiosMem = (unsigned char *)base + (cs << 4);
- if (int10_check_bios(pInt->scrnIndex, cs, vbiosMem)) {
- break;
- }
- }
-
- if (segments[i] == ~0) {
- xf86DrvMsg(pInt->scrnIndex, X_ERROR, format, (unsigned long)cs << 4);
- return FALSE;
- }
-
- xf86DrvMsg(pInt->scrnIndex, X_INFO, "Primary V_BIOS segment is: 0x%lx\n",
- (unsigned long)cs);
-
- pInt->BIOSseg = cs;
- return TRUE;
-}
+/*
+ * XFree86 int10 module
+ * execute BIOS int 10h calls in x86 real mode environment
+ * Copyright 1999 Egbert Eich
+ */
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "compiler.h"
+#include "xf86Pci.h"
+#define _INT10_PRIVATE
+#if 0
+#include "int10Defines.h"
+#endif
+#include "xf86int10.h"
+
+#define REG pInt
+
+typedef enum {
+ OPT_NOINT10,
+ OPT_INIT_PRIMARY,
+} INT10Opts;
+
+static const OptionInfoRec INT10Options[] = {
+ {OPT_NOINT10, "NoINT10", OPTV_BOOLEAN, {0}, FALSE },
+ {OPT_INIT_PRIMARY, "InitPrimary", OPTV_BOOLEAN, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE },
+};
+
+#ifdef DEBUG
+void
+dprint(unsigned long start, unsigned long size)
+{
+ int i,j;
+ char *c = (char *)start;
+
+ for (j = 0; j < (size >> 4); j++) {
+ char *d = c;
+ ErrorF("\n0x%lx: ",(unsigned long)c);
+ for (i = 0; i<16; i++)
+ ErrorF("%2.2x ",(unsigned char) (*(c++)));
+ c = d;
+ for (i = 0; i<16; i++) {
+ ErrorF("%c",((((CARD8)(*c)) > 32) && (((CARD8)(*c)) < 128)) ?
+ (unsigned char) (*(c)): '.');
+ c++;
+ }
+ }
+ ErrorF("\n");
+}
+#endif
+
+#ifndef _PC
+/*
+ * here we are really paranoid about faking a "real"
+ * BIOS. Most of this information was pulled from
+ * dosemu.
+ */
+void
+setup_int_vect(xf86Int10InfoPtr pInt)
+{
+ int i;
+
+ /* let the int vects point to the SYS_BIOS seg */
+ for (i = 0; i < 0x80; i++) {
+ MEM_WW(pInt, i << 2, 0);
+ MEM_WW(pInt, (i << 2) + 2, SYS_BIOS >> 4);
+ }
+
+ reset_int_vect(pInt);
+ /* font tables default location (int 1F) */
+ MEM_WW(pInt,0x1f<<2,0xfa6e);
+
+ /* int 11 default location (Get Equipment Configuration) */
+ MEM_WW(pInt, 0x11 << 2, 0xf84d);
+ /* int 12 default location (Get Conventional Memory Size) */
+ MEM_WW(pInt, 0x12 << 2, 0xf841);
+ /* int 15 default location (I/O System Extensions) */
+ MEM_WW(pInt, 0x15 << 2, 0xf859);
+ /* int 1A default location (RTC, PCI and others) */
+ MEM_WW(pInt, 0x1a << 2, 0xff6e);
+ /* int 05 default location (Bound Exceeded) */
+ MEM_WW(pInt, 0x05 << 2, 0xff54);
+ /* int 08 default location (Double Fault) */
+ MEM_WW(pInt, 0x08 << 2, 0xfea5);
+ /* int 13 default location (Disk) */
+ MEM_WW(pInt, 0x13 << 2, 0xec59);
+ /* int 0E default location (Page Fault) */
+ MEM_WW(pInt, 0x0e << 2, 0xef57);
+ /* int 17 default location (Parallel Port) */
+ MEM_WW(pInt, 0x17 << 2, 0xefd2);
+ /* fdd table default location (int 1e) */
+ MEM_WW(pInt, 0x1e << 2, 0xefc7);
+
+ /* Set Equipment flag to VGA */
+ i = MEM_RB(pInt, 0x0410) & 0xCF;
+ MEM_WB(pInt, 0x0410, i);
+ /* XXX Perhaps setup more of the BDA here. See also int42(0x00). */
+}
+#endif
+
+int
+setup_system_bios(void *base_addr)
+{
+ char *base = (char *) base_addr;
+
+ /*
+ * we trap the "industry standard entry points" to the BIOS
+ * and all other locations by filling them with "hlt"
+ * TODO: implement hlt-handler for these
+ */
+ memset(base, 0xf4, 0x10000);
+
+ /* set bios date */
+ strcpy(base + 0x0FFF5, "06/11/99");
+ /* set up eisa ident string */
+ strcpy(base + 0x0FFD9, "PCI_ISA");
+ /* write system model id for IBM-AT */
+ *((unsigned char *)(base + 0x0FFFE)) = 0xfc;
+
+ return 1;
+}
+
+void
+reset_int_vect(xf86Int10InfoPtr pInt)
+{
+ /*
+ * This table is normally located at 0xF000:0xF0A4. However, int 0x42,
+ * function 0 (Mode Set) expects it (or a copy) somewhere in the bottom
+ * 64kB. Note that because this data doesn't survive POST, int 0x42 should
+ * only be used during EGA/VGA BIOS initialisation.
+ */
+ static const CARD8 VideoParms[] = {
+ /* Timing for modes 0x00 & 0x01 */
+ 0x38, 0x28, 0x2d, 0x0a, 0x1f, 0x06, 0x19, 0x1c,
+ 0x02, 0x07, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
+ /* Timing for modes 0x02 & 0x03 */
+ 0x71, 0x50, 0x5a, 0x0a, 0x1f, 0x06, 0x19, 0x1c,
+ 0x02, 0x07, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
+ /* Timing for modes 0x04, 0x05 & 0x06 */
+ 0x38, 0x28, 0x2d, 0x0a, 0x7f, 0x06, 0x64, 0x70,
+ 0x02, 0x01, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
+ /* Timing for mode 0x07 */
+ 0x61, 0x50, 0x52, 0x0f, 0x19, 0x06, 0x19, 0x19,
+ 0x02, 0x0d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00,
+ /* Display page lengths in little endian order */
+ 0x00, 0x08, /* Modes 0x00 and 0x01 */
+ 0x00, 0x10, /* Modes 0x02 and 0x03 */
+ 0x00, 0x40, /* Modes 0x04 and 0x05 */
+ 0x00, 0x40, /* Modes 0x06 and 0x07 */
+ /* Number of columns for each mode */
+ 40, 40, 80, 80, 40, 40, 80, 80,
+ /* CGA Mode register value for each mode */
+ 0x2c, 0x28, 0x2d, 0x29, 0x2a, 0x2e, 0x1e, 0x29,
+ /* Padding */
+ 0x00, 0x00, 0x00, 0x00
+ };
+ int i;
+
+ for (i = 0; i < sizeof(VideoParms); i++)
+ MEM_WB(pInt, i + (0x1000 - sizeof(VideoParms)), VideoParms[i]);
+ MEM_WW(pInt, 0x1d << 2, 0x1000 - sizeof(VideoParms));
+ MEM_WW(pInt, (0x1d << 2) + 2, 0);
+
+ MEM_WW(pInt, 0x10 << 2, 0xf065);
+ MEM_WW(pInt, (0x10 << 2) + 2, SYS_BIOS >> 4);
+ MEM_WW(pInt, 0x42 << 2, 0xf065);
+ MEM_WW(pInt, (0x42 << 2) + 2, SYS_BIOS >> 4);
+ MEM_WW(pInt, 0x6D << 2, 0xf065);
+ MEM_WW(pInt, (0x6D << 2) + 2, SYS_BIOS >> 4);
+}
+
+void
+set_return_trap(xf86Int10InfoPtr pInt)
+{
+ /*
+ * Here we set the exit condition: We return when we encounter
+ * 'hlt' (=0xf4), which we locate at address 0x600 in x86 memory.
+ */
+ MEM_WB(pInt, 0x0600, 0xf4);
+
+ /*
+ * Allocate a segment for the stack
+ */
+ xf86Int10AllocPages(pInt, 1, &pInt->stackseg);
+}
+
+void *
+xf86HandleInt10Options(ScrnInfoPtr pScrn, int entityIndex)
+{
+ EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex);
+ OptionInfoPtr options = NULL;
+
+ if (pEnt->device) {
+ pointer configOptions = NULL;
+
+ /* Check if xf86CollectOptions() has already been called */
+ if (((pEnt->index < 0) ||
+ !pScrn ||
+ !(configOptions = pScrn->options)) &&
+ pEnt->device)
+ configOptions = pEnt->device->options;
+
+ if (configOptions) {
+ if (!(options = (OptionInfoPtr) malloc(sizeof(INT10Options))))
+ return NULL;
+
+ (void)memcpy(options, INT10Options, sizeof(INT10Options));
+ xf86ProcessOptions(pScrn->scrnIndex, configOptions, options);
+ }
+ }
+ free(pEnt);
+
+ return options;
+}
+
+Bool
+int10skip(const void* options)
+{
+ Bool noint10 = FALSE;
+
+ if (!options) return FALSE;
+
+ xf86GetOptValBool(options, OPT_NOINT10, &noint10);
+ return noint10;
+}
+
+Bool
+int10_check_bios(int scrnIndex, int codeSeg, const unsigned char* vbiosMem)
+{
+ int size;
+
+ if ((codeSeg & 0x1f) || /* Not 512-byte aligned otherwise */
+ ((codeSeg << 4) < V_BIOS) ||
+ ((codeSeg << 4) >= SYS_SIZE))
+ return FALSE;
+
+ if (xf86IsPc98())
+ return FALSE;
+
+ if ((*vbiosMem != 0x55) || (*(vbiosMem+1) != 0xAA) || !*(vbiosMem+2))
+ return FALSE;
+
+ size = *(vbiosMem + 2) * 512;
+
+ if ((size + (codeSeg << 4)) > SYS_SIZE)
+ return FALSE;
+
+ if (bios_checksum(vbiosMem, size))
+ xf86DrvMsg(scrnIndex, X_INFO, "Bad V_BIOS checksum\n");
+
+ return TRUE;
+}
+
+Bool
+initPrimary(const void* options)
+{
+ Bool initPrimary = FALSE;
+
+ if (!options) return FALSE;
+
+ xf86GetOptValBool(options, OPT_INIT_PRIMARY, &initPrimary);
+ return initPrimary;
+}
+
+BusType
+xf86int10GetBiosLocationType(const xf86Int10InfoPtr pInt)
+{
+ BusType location_type;
+
+ EntityInfoPtr pEnt = xf86GetEntityInfo(pInt->entityIndex);
+ location_type = pEnt->location.type;
+ free(pEnt);
+
+ return location_type;
+}
+
+
+#define CHECK_V_SEGMENT_RANGE(x) \
+ if (((x) << 4) < V_BIOS) { \
+ xf86DrvMsg(pInt->scrnIndex, X_ERROR, \
+ "V_BIOS address 0x%lx out of range\n", \
+ (unsigned long)(x) << 4); \
+ return FALSE; \
+ }
+
+Bool
+xf86int10GetBiosSegment(xf86Int10InfoPtr pInt, void *base)
+{
+ unsigned i;
+ int cs = ~0;
+ int segments[4];
+ const char * format;
+
+ segments[0] = MEM_RW(pInt, (0x10 << 2) + 2);
+ segments[1] = MEM_RW(pInt, (0x42 << 2) + 2);
+ segments[2] = V_BIOS >> 4;
+ segments[3] = ~0;
+
+ format = "No V_BIOS found\n";
+
+ for (i = 0; segments[i] != ~0; i++) {
+ unsigned char * vbiosMem;
+
+ cs = segments[i];
+
+ CHECK_V_SEGMENT_RANGE(cs);
+ vbiosMem = (unsigned char *)base + (cs << 4);
+ if (int10_check_bios(pInt->scrnIndex, cs, vbiosMem)) {
+ break;
+ }
+ }
+
+ if (segments[i] == ~0) {
+ xf86DrvMsg(pInt->scrnIndex, X_ERROR, format, (unsigned long)cs << 4);
+ return FALSE;
+ }
+
+ xf86DrvMsg(pInt->scrnIndex, X_INFO, "Primary V_BIOS segment is: 0x%lx\n",
+ (unsigned long)cs);
+
+ pInt->BIOSseg = cs;
+ return TRUE;
+}
diff --git a/xorg-server/hw/xfree86/loader/loadext.c b/xorg-server/hw/xfree86/loader/loadext.c
index 29cdaf1ac..26066856d 100644
--- a/xorg-server/hw/xfree86/loader/loadext.c
+++ b/xorg-server/hw/xfree86/loader/loadext.c
@@ -1,442 +1,442 @@
-/*
- * Copyright (c) 2000 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).
- */
-
-/* Maybe this file belongs elsewhere? */
-
-#define LOADERDECLARATIONS
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "loaderProcs.h"
-#include "misc.h"
-#include "xf86.h"
-
-/*
- * This should be static, but miinitext wants it. FIXME: make extension
- * initialization not completely terrible.
- */
-ExtensionModule *ExtensionModuleList = NULL;
-static int numExtensionModules = 0;
-
-static ExtensionModule *
-NewExtensionModule(void)
-{
- ExtensionModule *save = ExtensionModuleList;
- int n;
-
- /* Sanity check */
- if (!ExtensionModuleList)
- numExtensionModules = 0;
-
- n = numExtensionModules + 1;
- ExtensionModuleList = xrealloc(ExtensionModuleList,
- (n + 1) * sizeof(ExtensionModule));
- if (ExtensionModuleList == NULL) {
- ExtensionModuleList = save;
- return NULL;
- } else {
- numExtensionModules++;
- ExtensionModuleList[numExtensionModules].name = NULL;
- return ExtensionModuleList + (numExtensionModules - 1);
- }
-}
-
-void
-LoadExtension(ExtensionModule * e, Bool builtin)
-{
- ExtensionModule *newext;
-
- if (e == NULL || e->name == NULL)
- return;
-
- if (!(newext = NewExtensionModule()))
- return;
-
- if (builtin)
- xf86MsgVerb(X_INFO, 2, "Initializing built-in extension %s\n",
- e->name);
- else
- xf86MsgVerb(X_INFO, 2, "Loading extension %s\n", e->name);
-
- newext->name = e->name;
- newext->initFunc = e->initFunc;
- newext->disablePtr = e->disablePtr;
- newext->setupFunc = e->setupFunc;
- newext->initDependencies = e->initDependencies;
-
- if (e->setupFunc != NULL)
- e->setupFunc();
-}
-
-/*
- * Sort ExtensionModuleList according to the initialisation order
- * dependencies. The code for this is taken from BSD's tsort,
- * and carries the following copyright/license:
- *
- *
- * Copyright (c) 1989, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Michael Rendell of Memorial University of Newfoundland.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#define NF_MARK 0x1 /* marker for cycle detection */
-#define NF_ACYCLIC 0x2 /* this node is cycle free */
-#define NF_NODEST 0x4 /* Unreachable */
-
-typedef struct node_str NODE;
-struct node_str {
- NODE **n_prevp; /* pointer to previous node's n_next */
- NODE *n_next; /* next node in graph */
- NODE **n_arcs; /* array of arcs to other nodes */
- int n_narcs; /* number of arcs in n_arcs[] */
- int n_arcsize; /* size of n_arcs[] array */
- int n_refcnt; /* # of arcs pointing to this node */
- int n_flags; /* NF_* */
- const char *n_name; /* name of this node */
-};
-
-static NODE *graph = NULL, **cycle_buf = NULL, **longest_cycle = NULL;
-static int longest = 0;
-static NODE *sorted = NULL, *last = NULL;
-
-/* Find a node in the graph (insert if not found) and return a pointer to it. */
-static NODE *
-get_node(const char *name)
-{
- NODE *n;
-
- for (n = graph; n && n->n_name && strcmp(n->n_name, name);
- n = n->n_next) ;
- if (n)
- return (n);
-
- n = xnfalloc(sizeof(NODE));
-
- n->n_narcs = 0;
- n->n_arcsize = 0;
- n->n_arcs = NULL;
- n->n_refcnt = 0;
- n->n_flags = 0;
- n->n_name = name;
-
- /* Add to linked list. */
- if ((n->n_next = graph) != NULL)
- graph->n_prevp = &n->n_next;
- n->n_prevp = &graph;
- graph = n;
-
- return (n);
-}
-
-/*
- * add an arc from node s1 to node s2 in the graph. If s1 or s2 are not in
- * the graph, then add them.
- */
-static void
-add_arc(const char *s1, const char *s2)
-{
- NODE *n1;
- NODE *n2;
- int bsize, i;
-
- n1 = get_node(s1);
-
- if (!strcmp(s1, s2))
- return;
-
- n2 = get_node(s2);
-
- /*
- * Check if this arc is already here.
- */
- for (i = 0; i < n1->n_narcs; i++)
- if (n1->n_arcs[i] == n2)
- return;
- /*
- * Add it.
- */
- if (n1->n_narcs == n1->n_arcsize) {
- if (!n1->n_arcsize)
- n1->n_arcsize = 10;
- bsize = n1->n_arcsize * sizeof(*n1->n_arcs) * 2;
- n1->n_arcs = xnfrealloc(n1->n_arcs, bsize);
- n1->n_arcsize = bsize / sizeof(*n1->n_arcs);
- }
- n1->n_arcs[n1->n_narcs++] = n2;
- ++n2->n_refcnt;
-}
-
-/*
- * Clear the NODEST flag from all nodes.
- */
-static void
-clear_cycle(void)
-{
- NODE *n;
-
- for (n = graph; n != NULL; n = n->n_next)
- n->n_flags &= ~NF_NODEST;
-}
-
-/* print node and remove from graph (does not actually free node) */
-static void
-remove_node(NODE * n)
-{
- NODE **np;
- NODE *newnode;
- int i;
-
-#ifdef DEBUG
- ErrorF("%s\n", n->n_name);
-#endif
- newnode = xnfalloc(sizeof(NODE));
- memcpy(newnode, n, sizeof(NODE));
- if (last)
- last->n_next = newnode;
- else
- sorted = newnode;
- last = newnode;
- newnode->n_next = NULL;
-
- for (np = n->n_arcs, i = n->n_narcs; --i >= 0; np++)
- --(*np)->n_refcnt;
- n->n_narcs = 0;
- *n->n_prevp = n->n_next;
- if (n->n_next)
- n->n_next->n_prevp = n->n_prevp;
-}
-
-static void
-free_nodes(NODE * nodelist)
-{
- NODE *n, *nextnode;
-
- for (n = nodelist; n;) {
- nextnode = n->n_next;
- xfree(n);
- n = nextnode;
- }
-}
-
-/* look for the longest? cycle from node from to node to. */
-static int
-find_cycle(NODE * from, NODE * to, int longest_len, int depth)
-{
- NODE **np;
- int i, len;
-
- /*
- * avoid infinite loops and ignore portions of the graph known
- * to be acyclic
- */
- if (from->n_flags & (NF_NODEST | NF_MARK | NF_ACYCLIC))
- return (0);
- from->n_flags |= NF_MARK;
-
- for (np = from->n_arcs, i = from->n_narcs; --i >= 0; np++) {
- cycle_buf[depth] = *np;
- if (*np == to) {
- if (depth + 1 > longest_len) {
- longest_len = depth + 1;
- memcpy((char *)longest_cycle,
- (char *)cycle_buf, longest_len * sizeof(NODE *));
- }
- } else {
- if ((*np)->n_flags & (NF_MARK | NF_ACYCLIC | NF_NODEST))
- continue;
- len = find_cycle(*np, to, longest_len, depth + 1);
-
-#ifdef DEBUG
- ErrorF("%*s %s->%s %d\n", depth, "",
- from->n_name, to->n_name, len);
-#endif
-
- if (len == 0)
- (*np)->n_flags |= NF_NODEST;
-
- if (len > longest_len)
- longest_len = len;
-
- if (len > 0 && !longest)
- break;
- }
- }
- from->n_flags &= ~NF_MARK;
- return (longest_len);
-}
-
-/* do topological sort on graph */
-static void
-tsort(void)
-{
- NODE *n, *next;
- int cnt, i;
-
- while (graph != NULL) {
- /*
- * Keep getting rid of simple cases until there are none left,
- * if there are any nodes still in the graph, then there is
- * a cycle in it.
- */
- do {
- for (cnt = 0, n = graph; n != NULL; n = next) {
- next = n->n_next;
- if (n->n_refcnt == 0) {
- remove_node(n);
- ++cnt;
- }
- }
- } while (graph != NULL && cnt);
-
- if (graph == NULL)
- break;
-
- if (!cycle_buf) {
- /*
- * Allocate space for two cycle logs - one to be used
- * as scratch space, the other to save the longest
- * cycle.
- */
- for (cnt = 0, n = graph; n != NULL; n = n->n_next)
- ++cnt;
- cycle_buf = xnfalloc(sizeof(NODE *) * cnt);
- longest_cycle = xnfalloc(sizeof(NODE *) * cnt);
- if (cycle_buf == NULL || longest_cycle == NULL)
- return;
- }
- for (n = graph; n != NULL; n = n->n_next)
- if (!(n->n_flags & NF_ACYCLIC)) {
- if ((cnt = find_cycle(n, n, 0, 0))) {
- ErrorF("tsort: cycle in data");
- for (i = 0; i < cnt; i++)
- ErrorF("%s", longest_cycle[i]->n_name);
- remove_node(n);
- clear_cycle();
- break;
- } else {
- /* to avoid further checks */
- n->n_flags |= NF_ACYCLIC;
- clear_cycle();
- }
- }
-
- if (n == NULL)
- ErrorF("tsort: internal error -- could not find cycle");
- }
- if (cycle_buf)
- xfree(cycle_buf);
- if (longest_cycle)
- xfree(longest_cycle);
- if (graph)
- free_nodes(graph);
-}
-
-void
-LoaderSortExtensions(void)
-{
- int i, j;
- ExtensionModule *ext, *newList;
- NODE *node;
-
- graph = NULL;
- longest = 0;
- sorted = NULL;
- last = NULL;
- cycle_buf = NULL;
- longest_cycle = NULL;
-
- /*
- * Parse list and build the graph. Enter them in reverse order
- * because tsort() will reverse those that have no depedencies.
- */
- for (i = numExtensionModules - 1; i >= 0; i--) {
- ext = &ExtensionModuleList[i];
- add_arc(ext->name, ext->name);
-#ifdef DEBUG
- ErrorF("Extension %s:\n", ext->name);
-#endif
- if (ext->initDependencies)
- for (j = 0; ext->initDependencies[j]; j++) {
- add_arc(ext->initDependencies[j], ext->name);
-#ifdef DEBUG
- ErrorF("\t%s\n", ext->initDependencies[j]);
-#endif
- }
- }
- tsort();
- newList = xnfalloc((numExtensionModules + 1) * sizeof(ExtensionModule));
- i = 0;
- for (node = sorted; node; node = node->n_next) {
- for (j = 0; j < numExtensionModules; j++)
- if (!strcmp(node->n_name, ExtensionModuleList[j].name))
- break;
- if (j != numExtensionModules)
- newList[i++] = ExtensionModuleList[j];
- }
- if (sorted)
- free_nodes(sorted);
- if (graph)
- free_nodes(graph);
- newList[i].name = NULL;
- xfree(ExtensionModuleList);
- ExtensionModuleList = newList;
-#ifdef DEBUG
- for (i = 0; ExtensionModuleList[i].name; i++)
- ErrorF("Extension %s\n", ExtensionModuleList[i].name);
-#endif
-}
+/*
+ * Copyright (c) 2000 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).
+ */
+
+/* Maybe this file belongs elsewhere? */
+
+#define LOADERDECLARATIONS
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "loaderProcs.h"
+#include "misc.h"
+#include "xf86.h"
+
+/*
+ * This should be static, but miinitext wants it. FIXME: make extension
+ * initialization not completely terrible.
+ */
+ExtensionModule *ExtensionModuleList = NULL;
+static int numExtensionModules = 0;
+
+static ExtensionModule *
+NewExtensionModule(void)
+{
+ ExtensionModule *save = ExtensionModuleList;
+ int n;
+
+ /* Sanity check */
+ if (!ExtensionModuleList)
+ numExtensionModules = 0;
+
+ n = numExtensionModules + 1;
+ ExtensionModuleList = realloc(ExtensionModuleList,
+ (n + 1) * sizeof(ExtensionModule));
+ if (ExtensionModuleList == NULL) {
+ ExtensionModuleList = save;
+ return NULL;
+ } else {
+ numExtensionModules++;
+ ExtensionModuleList[numExtensionModules].name = NULL;
+ return ExtensionModuleList + (numExtensionModules - 1);
+ }
+}
+
+void
+LoadExtension(ExtensionModule * e, Bool builtin)
+{
+ ExtensionModule *newext;
+
+ if (e == NULL || e->name == NULL)
+ return;
+
+ if (!(newext = NewExtensionModule()))
+ return;
+
+ if (builtin)
+ xf86MsgVerb(X_INFO, 2, "Initializing built-in extension %s\n",
+ e->name);
+ else
+ xf86MsgVerb(X_INFO, 2, "Loading extension %s\n", e->name);
+
+ newext->name = e->name;
+ newext->initFunc = e->initFunc;
+ newext->disablePtr = e->disablePtr;
+ newext->setupFunc = e->setupFunc;
+ newext->initDependencies = e->initDependencies;
+
+ if (e->setupFunc != NULL)
+ e->setupFunc();
+}
+
+/*
+ * Sort ExtensionModuleList according to the initialisation order
+ * dependencies. The code for this is taken from BSD's tsort,
+ * and carries the following copyright/license:
+ *
+ *
+ * Copyright (c) 1989, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Michael Rendell of Memorial University of Newfoundland.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#define NF_MARK 0x1 /* marker for cycle detection */
+#define NF_ACYCLIC 0x2 /* this node is cycle free */
+#define NF_NODEST 0x4 /* Unreachable */
+
+typedef struct node_str NODE;
+struct node_str {
+ NODE **n_prevp; /* pointer to previous node's n_next */
+ NODE *n_next; /* next node in graph */
+ NODE **n_arcs; /* array of arcs to other nodes */
+ int n_narcs; /* number of arcs in n_arcs[] */
+ int n_arcsize; /* size of n_arcs[] array */
+ int n_refcnt; /* # of arcs pointing to this node */
+ int n_flags; /* NF_* */
+ const char *n_name; /* name of this node */
+};
+
+static NODE *graph = NULL, **cycle_buf = NULL, **longest_cycle = NULL;
+static int longest = 0;
+static NODE *sorted = NULL, *last = NULL;
+
+/* Find a node in the graph (insert if not found) and return a pointer to it. */
+static NODE *
+get_node(const char *name)
+{
+ NODE *n;
+
+ for (n = graph; n && n->n_name && strcmp(n->n_name, name);
+ n = n->n_next) ;
+ if (n)
+ return (n);
+
+ n = xnfalloc(sizeof(NODE));
+
+ n->n_narcs = 0;
+ n->n_arcsize = 0;
+ n->n_arcs = NULL;
+ n->n_refcnt = 0;
+ n->n_flags = 0;
+ n->n_name = name;
+
+ /* Add to linked list. */
+ if ((n->n_next = graph) != NULL)
+ graph->n_prevp = &n->n_next;
+ n->n_prevp = &graph;
+ graph = n;
+
+ return (n);
+}
+
+/*
+ * add an arc from node s1 to node s2 in the graph. If s1 or s2 are not in
+ * the graph, then add them.
+ */
+static void
+add_arc(const char *s1, const char *s2)
+{
+ NODE *n1;
+ NODE *n2;
+ int bsize, i;
+
+ n1 = get_node(s1);
+
+ if (!strcmp(s1, s2))
+ return;
+
+ n2 = get_node(s2);
+
+ /*
+ * Check if this arc is already here.
+ */
+ for (i = 0; i < n1->n_narcs; i++)
+ if (n1->n_arcs[i] == n2)
+ return;
+ /*
+ * Add it.
+ */
+ if (n1->n_narcs == n1->n_arcsize) {
+ if (!n1->n_arcsize)
+ n1->n_arcsize = 10;
+ bsize = n1->n_arcsize * sizeof(*n1->n_arcs) * 2;
+ n1->n_arcs = xnfrealloc(n1->n_arcs, bsize);
+ n1->n_arcsize = bsize / sizeof(*n1->n_arcs);
+ }
+ n1->n_arcs[n1->n_narcs++] = n2;
+ ++n2->n_refcnt;
+}
+
+/*
+ * Clear the NODEST flag from all nodes.
+ */
+static void
+clear_cycle(void)
+{
+ NODE *n;
+
+ for (n = graph; n != NULL; n = n->n_next)
+ n->n_flags &= ~NF_NODEST;
+}
+
+/* print node and remove from graph (does not actually free node) */
+static void
+remove_node(NODE * n)
+{
+ NODE **np;
+ NODE *newnode;
+ int i;
+
+#ifdef DEBUG
+ ErrorF("%s\n", n->n_name);
+#endif
+ newnode = xnfalloc(sizeof(NODE));
+ memcpy(newnode, n, sizeof(NODE));
+ if (last)
+ last->n_next = newnode;
+ else
+ sorted = newnode;
+ last = newnode;
+ newnode->n_next = NULL;
+
+ for (np = n->n_arcs, i = n->n_narcs; --i >= 0; np++)
+ --(*np)->n_refcnt;
+ n->n_narcs = 0;
+ *n->n_prevp = n->n_next;
+ if (n->n_next)
+ n->n_next->n_prevp = n->n_prevp;
+}
+
+static void
+free_nodes(NODE * nodelist)
+{
+ NODE *n, *nextnode;
+
+ for (n = nodelist; n;) {
+ nextnode = n->n_next;
+ free(n);
+ n = nextnode;
+ }
+}
+
+/* look for the longest? cycle from node from to node to. */
+static int
+find_cycle(NODE * from, NODE * to, int longest_len, int depth)
+{
+ NODE **np;
+ int i, len;
+
+ /*
+ * avoid infinite loops and ignore portions of the graph known
+ * to be acyclic
+ */
+ if (from->n_flags & (NF_NODEST | NF_MARK | NF_ACYCLIC))
+ return (0);
+ from->n_flags |= NF_MARK;
+
+ for (np = from->n_arcs, i = from->n_narcs; --i >= 0; np++) {
+ cycle_buf[depth] = *np;
+ if (*np == to) {
+ if (depth + 1 > longest_len) {
+ longest_len = depth + 1;
+ memcpy((char *)longest_cycle,
+ (char *)cycle_buf, longest_len * sizeof(NODE *));
+ }
+ } else {
+ if ((*np)->n_flags & (NF_MARK | NF_ACYCLIC | NF_NODEST))
+ continue;
+ len = find_cycle(*np, to, longest_len, depth + 1);
+
+#ifdef DEBUG
+ ErrorF("%*s %s->%s %d\n", depth, "",
+ from->n_name, to->n_name, len);
+#endif
+
+ if (len == 0)
+ (*np)->n_flags |= NF_NODEST;
+
+ if (len > longest_len)
+ longest_len = len;
+
+ if (len > 0 && !longest)
+ break;
+ }
+ }
+ from->n_flags &= ~NF_MARK;
+ return (longest_len);
+}
+
+/* do topological sort on graph */
+static void
+tsort(void)
+{
+ NODE *n, *next;
+ int cnt, i;
+
+ while (graph != NULL) {
+ /*
+ * Keep getting rid of simple cases until there are none left,
+ * if there are any nodes still in the graph, then there is
+ * a cycle in it.
+ */
+ do {
+ for (cnt = 0, n = graph; n != NULL; n = next) {
+ next = n->n_next;
+ if (n->n_refcnt == 0) {
+ remove_node(n);
+ ++cnt;
+ }
+ }
+ } while (graph != NULL && cnt);
+
+ if (graph == NULL)
+ break;
+
+ if (!cycle_buf) {
+ /*
+ * Allocate space for two cycle logs - one to be used
+ * as scratch space, the other to save the longest
+ * cycle.
+ */
+ for (cnt = 0, n = graph; n != NULL; n = n->n_next)
+ ++cnt;
+ cycle_buf = xnfalloc(sizeof(NODE *) * cnt);
+ longest_cycle = xnfalloc(sizeof(NODE *) * cnt);
+ if (cycle_buf == NULL || longest_cycle == NULL)
+ return;
+ }
+ for (n = graph; n != NULL; n = n->n_next)
+ if (!(n->n_flags & NF_ACYCLIC)) {
+ if ((cnt = find_cycle(n, n, 0, 0))) {
+ ErrorF("tsort: cycle in data");
+ for (i = 0; i < cnt; i++)
+ ErrorF("%s", longest_cycle[i]->n_name);
+ remove_node(n);
+ clear_cycle();
+ break;
+ } else {
+ /* to avoid further checks */
+ n->n_flags |= NF_ACYCLIC;
+ clear_cycle();
+ }
+ }
+
+ if (n == NULL)
+ ErrorF("tsort: internal error -- could not find cycle");
+ }
+ if (cycle_buf)
+ free(cycle_buf);
+ if (longest_cycle)
+ free(longest_cycle);
+ if (graph)
+ free_nodes(graph);
+}
+
+void
+LoaderSortExtensions(void)
+{
+ int i, j;
+ ExtensionModule *ext, *newList;
+ NODE *node;
+
+ graph = NULL;
+ longest = 0;
+ sorted = NULL;
+ last = NULL;
+ cycle_buf = NULL;
+ longest_cycle = NULL;
+
+ /*
+ * Parse list and build the graph. Enter them in reverse order
+ * because tsort() will reverse those that have no depedencies.
+ */
+ for (i = numExtensionModules - 1; i >= 0; i--) {
+ ext = &ExtensionModuleList[i];
+ add_arc(ext->name, ext->name);
+#ifdef DEBUG
+ ErrorF("Extension %s:\n", ext->name);
+#endif
+ if (ext->initDependencies)
+ for (j = 0; ext->initDependencies[j]; j++) {
+ add_arc(ext->initDependencies[j], ext->name);
+#ifdef DEBUG
+ ErrorF("\t%s\n", ext->initDependencies[j]);
+#endif
+ }
+ }
+ tsort();
+ newList = xnfalloc((numExtensionModules + 1) * sizeof(ExtensionModule));
+ i = 0;
+ for (node = sorted; node; node = node->n_next) {
+ for (j = 0; j < numExtensionModules; j++)
+ if (!strcmp(node->n_name, ExtensionModuleList[j].name))
+ break;
+ if (j != numExtensionModules)
+ newList[i++] = ExtensionModuleList[j];
+ }
+ if (sorted)
+ free_nodes(sorted);
+ if (graph)
+ free_nodes(graph);
+ newList[i].name = NULL;
+ free(ExtensionModuleList);
+ ExtensionModuleList = newList;
+#ifdef DEBUG
+ for (i = 0; ExtensionModuleList[i].name; i++)
+ ErrorF("Extension %s\n", ExtensionModuleList[i].name);
+#endif
+}
diff --git a/xorg-server/hw/xfree86/loader/loadmod.c b/xorg-server/hw/xfree86/loader/loadmod.c
index 5b175a546..e75ec8f69 100644
--- a/xorg-server/hw/xfree86/loader/loadmod.c
+++ b/xorg-server/hw/xfree86/loader/loadmod.c
@@ -1,1268 +1,1268 @@
-/*
- * Copyright 1995-1998 by Metro Link, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Metro Link, Inc. not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Metro Link, Inc. makes no
- * representations about the suitability of this software for any purpose.
- * It is provided "as is" without express or implied warranty.
- *
- * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL METRO LINK, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-/*
- * Copyright (c) 1997-2002 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "os.h"
-/* For stat() and related stuff */
-#define NO_OSLIB_PROTOTYPES
-#include "xf86_OSlib.h"
-#define LOADERDECLARATIONS
-#include "loaderProcs.h"
-#include "misc.h"
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86Xinput.h"
-#include "loader.h"
-#include "xf86Optrec.h"
-
-#include <sys/types.h>
-#include <regex.h>
-#include <dirent.h>
-#include <limits.h>
-
-typedef struct _pattern {
- const char *pattern;
- regex_t rex;
-} PatternRec, *PatternPtr;
-
-/* Prototypes for static functions */
-static char *FindModule(const char *, const char *, const char **,
- PatternPtr);
-static Bool CheckVersion(const char *, XF86ModuleVersionInfo *,
- const XF86ModReqInfo *);
-static void UnloadModuleOrDriver(ModuleDescPtr mod);
-static char *LoaderGetCanonicalName(const char *, PatternPtr);
-static void RemoveChild(ModuleDescPtr);
-static ModuleDescPtr doLoadModule(const char *, const char *, const char **,
- const char **, pointer,
- const XF86ModReqInfo *, int *, int *,
- int flags);
-
-const ModuleVersions LoaderVersionInfo = {
- XORG_VERSION_CURRENT,
- ABI_ANSIC_VERSION,
- ABI_VIDEODRV_VERSION,
- ABI_XINPUT_VERSION,
- ABI_EXTENSION_VERSION,
- ABI_FONT_VERSION
-};
-
-static void
-FreeStringList(char **paths)
-{
- char **p;
-
- if (!paths)
- return;
-
- for (p = paths; *p; p++)
- xfree(*p);
-
- xfree(paths);
-}
-
-static char **defaultPathList = NULL;
-
-static Bool
-PathIsAbsolute(const char *path)
-{
- return (*path == '/');
-}
-
-/*
- * Convert a comma-separated path into a NULL-terminated array of path
- * elements, rejecting any that are not full absolute paths, and appending
- * a '/' when it isn't already present.
- */
-static char **
-InitPathList(const char *path)
-{
- char *fullpath = NULL;
- char *elem = NULL;
- char **list = NULL, **save = NULL;
- int len;
- int addslash;
- int n = 0;
-
- if (!path)
- return defaultPathList;
-
- fullpath = xstrdup(path);
- if (!fullpath)
- return NULL;
- elem = strtok(fullpath, ",");
- while (elem) {
- if (PathIsAbsolute(elem))
- {
- len = strlen(elem);
- addslash = (elem[len - 1] != '/');
- if (addslash)
- len++;
- save = list;
- list = xrealloc(list, (n + 2) * sizeof(char *));
- if (!list) {
- if (save) {
- save[n] = NULL;
- FreeStringList(save);
- }
- xfree(fullpath);
- return NULL;
- }
- list[n] = xalloc(len + 1);
- if (!list[n]) {
- FreeStringList(list);
- xfree(fullpath);
- return NULL;
- }
- strcpy(list[n], elem);
- if (addslash) {
- list[n][len - 1] = '/';
- list[n][len] = '\0';
- }
- n++;
- }
- elem = strtok(NULL, ",");
- }
- if (list)
- list[n] = NULL;
- xfree(fullpath);
- return list;
-}
-
-static void
-FreePathList(char **pathlist)
-{
- if (pathlist && pathlist != defaultPathList)
- FreeStringList(pathlist);
-}
-
-void
-LoaderSetPath(const char *path)
-{
- if (!path)
- return;
-
- defaultPathList = InitPathList(path);
-}
-
-/* Standard set of module subdirectories to search, in order of preference */
-static const char *stdSubdirs[] = {
- "",
- "input/",
- "drivers/",
- "multimedia/",
- "extensions/",
- "internal/",
- NULL
-};
-
-/*
- * Standard set of module name patterns to check, in order of preference
- * These are regular expressions (suitable for use with POSIX regex(3)).
- *
- * This list assumes that you're an ELFish platform and therefore your
- * shared libraries are named something.so. If we're ever nuts enough
- * to port this DDX to, say, Darwin, we'll need to fix this.
- */
-static PatternRec stdPatterns[] = {
- {"^lib(.*)\\.so$",},
- {"(.*)_drv\\.so$",},
- {"(.*)\\.so$",},
- {NULL,}
-};
-
-static PatternPtr
-InitPatterns(const char **patternlist)
-{
- char errmsg[80];
- int i, e;
- PatternPtr patterns = NULL;
- PatternPtr p = NULL;
- static int firstTime = 1;
- const char **s;
-
- if (firstTime) {
- /* precompile stdPatterns */
- firstTime = 0;
- for (p = stdPatterns; p->pattern; p++)
- if ((e = regcomp(&p->rex, p->pattern, REG_EXTENDED)) != 0) {
- regerror(e, &p->rex, errmsg, sizeof(errmsg));
- FatalError("InitPatterns: regcomp error for `%s': %s\n",
- p->pattern, errmsg);
- }
- }
-
- if (patternlist) {
- for (i = 0, s = patternlist; *s; i++, s++)
- if (*s == DEFAULT_LIST)
- i += sizeof(stdPatterns) / sizeof(stdPatterns[0]) - 1 - 1;
- patterns = xalloc((i + 1) * sizeof(PatternRec));
- if (!patterns) {
- return NULL;
- }
- for (i = 0, s = patternlist; *s; i++, s++)
- if (*s != DEFAULT_LIST) {
- p = patterns + i;
- p->pattern = *s;
- if ((e = regcomp(&p->rex, p->pattern, REG_EXTENDED)) != 0) {
- regerror(e, &p->rex, errmsg, sizeof(errmsg));
- ErrorF("InitPatterns: regcomp error for `%s': %s\n",
- p->pattern, errmsg);
- i--;
- }
- } else {
- for (p = stdPatterns; p->pattern; p++, i++)
- patterns[i] = *p;
- if (p != stdPatterns)
- i--;
- }
- patterns[i].pattern = NULL;
- } else
- patterns = stdPatterns;
- return patterns;
-}
-
-static void
-FreePatterns(PatternPtr patterns)
-{
- if (patterns && patterns != stdPatterns)
- xfree(patterns);
-}
-
-static const char **
-InitSubdirs(const char **subdirlist)
-{
- int i;
- const char **tmp_subdirlist = NULL;
- char **subdirs = NULL;
- const char **s, **stmp = NULL;
- const char *osname;
- const char *slash;
- int oslen = 0, len;
- Bool indefault;
-
- if (subdirlist == NULL) {
- subdirlist = tmp_subdirlist = xalloc(2 * sizeof(char *));
- if (subdirlist == NULL)
- return NULL;
- subdirlist[0] = DEFAULT_LIST;
- subdirlist[1] = NULL;
- }
-
- LoaderGetOS(&osname, NULL, NULL, NULL);
- oslen = strlen(osname);
-
- {
- /* Count number of entries and check for invalid paths */
- for (i = 0, s = subdirlist; *s; i++, s++) {
- if (*s == DEFAULT_LIST) {
- i += sizeof(stdSubdirs) / sizeof(stdSubdirs[0]) - 1 - 1;
- } else {
- /*
- * Path validity check. Don't allow absolute paths, or
- * paths containing "..". To catch absolute paths on
- * platforms that use driver letters, don't allow the ':'
- * character to appear at all.
- */
- if (**s == '/' || **s == '\\' || strchr(*s, ':') ||
- strstr(*s, "..")) {
- xf86Msg(X_ERROR, "InitSubdirs: Bad subdir: \"%s\"\n", *s);
- if (tmp_subdirlist)
- xfree(tmp_subdirlist);
- return NULL;
- }
- }
- }
- subdirs = xalloc((i * 2 + 1) * sizeof(char *));
- if (!subdirs) {
- if (tmp_subdirlist)
- xfree(tmp_subdirlist);
- return NULL;
- }
- i = 0;
- s = subdirlist;
- indefault = FALSE;
- while (*s) {
- if (*s == DEFAULT_LIST) {
- /* Divert to the default list */
- indefault = TRUE;
- stmp = ++s;
- s = stdSubdirs;
- }
- len = strlen(*s);
- if (**s && (*s)[len - 1] != '/') {
- slash = "/";
- len++;
- } else
- slash = "";
- len += oslen + 2;
- if (!(subdirs[i] = xalloc(len))) {
- while (--i >= 0)
- xfree(subdirs[i]);
- xfree(subdirs);
- if (tmp_subdirlist)
- xfree(tmp_subdirlist);
- return NULL;
- }
- /* tack on the OS name */
- sprintf(subdirs[i], "%s%s%s/", *s, slash, osname);
- i++;
- /* path as given */
- subdirs[i] = xstrdup(*s);
- i++;
- s++;
- if (indefault && !s) {
- /* revert back to the main list */
- indefault = FALSE;
- s = stmp;
- }
- }
- subdirs[i] = NULL;
- }
- if (tmp_subdirlist)
- xfree(tmp_subdirlist);
- return (const char **)subdirs;
-}
-
-static void
-FreeSubdirs(const char **subdirs)
-{
- const char **s;
-
- if (subdirs) {
- for (s = subdirs; *s; s++)
- xfree(*s);
- xfree(subdirs);
- }
-}
-
-static char *
-FindModuleInSubdir(const char *dirpath, const char *module)
-{
- struct dirent *direntry = NULL;
- DIR *dir = NULL;
- char *ret = NULL, tmpBuf[PATH_MAX];
- struct stat stat_buf;
-
- dir = opendir(dirpath);
- if (!dir)
- return NULL;
-
- while ((direntry = readdir(dir))) {
- if (direntry->d_name[0] == '.')
- continue;
- snprintf(tmpBuf, PATH_MAX, "%s%s/", dirpath, direntry->d_name);
- /* the stat with the appended / fails for normal files,
- and works for sub dirs fine, looks a bit strange in strace
- but does seem to work */
- if ((stat(tmpBuf, &stat_buf) == 0) && S_ISDIR(stat_buf.st_mode)) {
- if ((ret = FindModuleInSubdir(tmpBuf, module)))
- break;
- continue;
- }
-
- snprintf(tmpBuf, PATH_MAX, "lib%s.so", module);
- if (strcmp(direntry->d_name, tmpBuf) == 0) {
- ret = malloc(strlen(tmpBuf) + strlen(dirpath) + 2);
- sprintf(ret, "%s%s", dirpath, tmpBuf);
- break;
- }
-
- snprintf(tmpBuf, PATH_MAX, "%s_drv.so", module);
- if (strcmp(direntry->d_name, tmpBuf) == 0) {
- ret = malloc(strlen(tmpBuf) + strlen(dirpath) + 2);
- sprintf(ret, "%s%s", dirpath, tmpBuf);
- break;
- }
-
- snprintf(tmpBuf, PATH_MAX, "%s.so", module);
- if (strcmp(direntry->d_name, tmpBuf) == 0) {
- ret = malloc(strlen(tmpBuf) + strlen(dirpath) + 2);
- sprintf(ret, "%s%s", dirpath, tmpBuf);
- break;
- }
- }
-
- closedir(dir);
- return ret;
-}
-
-static char *
-FindModule(const char *module, const char *dirname, const char **subdirlist,
- PatternPtr patterns)
-{
- char buf[PATH_MAX + 1];
- char *dirpath = NULL;
- char *name = NULL;
- int dirlen;
- const char **subdirs = NULL;
- const char **s;
-
- dirpath = (char *)dirname;
- if (strlen(dirpath) > PATH_MAX)
- return NULL;
-
- subdirs = InitSubdirs(subdirlist);
- if (!subdirs)
- return NULL;
-
- for (s = subdirs; *s; s++) {
- if ((dirlen = strlen(dirpath) + strlen(*s)) > PATH_MAX)
- continue;
- strcpy(buf, dirpath);
- strcat(buf, *s);
- if ((name = FindModuleInSubdir(buf, module)))
- break;
- }
-
- FreeSubdirs(subdirs);
- if (dirpath != dirname)
- xfree(dirpath);
-
- return name;
-}
-
-char **
-LoaderListDirs(const char **subdirlist, const char **patternlist)
-{
- char buf[PATH_MAX + 1];
- char **pathlist;
- char **elem;
- const char **subdirs;
- const char **s;
- PatternPtr patterns;
- PatternPtr p;
- DIR *d;
- struct dirent *dp;
- regmatch_t match[2];
- struct stat stat_buf;
- int len, dirlen;
- char *fp;
- char **listing = NULL;
- char **save;
- int n = 0;
-
- if (!(pathlist = InitPathList(NULL)))
- return NULL;
- if (!(subdirs = InitSubdirs(subdirlist))) {
- FreePathList(pathlist);
- return NULL;
- }
- if (!(patterns = InitPatterns(patternlist))) {
- FreePathList(pathlist);
- FreeSubdirs(subdirs);
- return NULL;
- }
-
- for (elem = pathlist; *elem; elem++) {
- for (s = subdirs; *s; s++) {
- if ((dirlen = strlen(*elem) + strlen(*s)) > PATH_MAX)
- continue;
- strcpy(buf, *elem);
- strcat(buf, *s);
- fp = buf + dirlen;
- if (stat(buf, &stat_buf) == 0 && S_ISDIR(stat_buf.st_mode) &&
- (d = opendir(buf))) {
- if (buf[dirlen - 1] != '/') {
- buf[dirlen++] = '/';
- fp++;
- }
- while ((dp = readdir(d))) {
- if (dirlen + strlen(dp->d_name) > PATH_MAX)
- continue;
- strcpy(fp, dp->d_name);
- if (!(stat(buf, &stat_buf) == 0 &&
- S_ISREG(stat_buf.st_mode)))
- continue;
- for (p = patterns; p->pattern; p++) {
- if (regexec(&p->rex, dp->d_name, 2, match, 0) == 0 &&
- match[1].rm_so != -1) {
- len = match[1].rm_eo - match[1].rm_so;
- save = listing;
- listing = xrealloc(listing,
- (n + 2) * sizeof(char *));
- if (!listing) {
- if (save) {
- save[n] = NULL;
- FreeStringList(save);
- }
- FreePathList(pathlist);
- FreeSubdirs(subdirs);
- FreePatterns(patterns);
- return NULL;
- }
- listing[n] = xalloc(len + 1);
- if (!listing[n]) {
- FreeStringList(listing);
- FreePathList(pathlist);
- FreeSubdirs(subdirs);
- FreePatterns(patterns);
- return NULL;
- }
- strncpy(listing[n], dp->d_name + match[1].rm_so,
- len);
- listing[n][len] = '\0';
- n++;
- break;
- }
- }
- }
- closedir(d);
- }
- }
- }
- if (listing)
- listing[n] = NULL;
- return listing;
-}
-
-void
-LoaderFreeDirList(char **list)
-{
- FreeStringList(list);
-}
-
-static Bool
-CheckVersion(const char *module, XF86ModuleVersionInfo * data,
- const XF86ModReqInfo * req)
-{
- int vercode[4];
- char verstr[4];
- long ver = data->xf86version;
- MessageType errtype;
-
- xf86Msg(X_INFO, "Module %s: vendor=\"%s\"\n",
- data->modname ? data->modname : "UNKNOWN!",
- data->vendor ? data->vendor : "UNKNOWN!");
-
- /* Check for the different scheme used in XFree86 4.0.x releases:
- * ((((((((major << 7) | minor) << 7) | subminor) << 5) | beta) << 5) | alpha)
- * Since it wasn't used in 4.1.0 or later, limit to versions in the 4.0.x
- * range, which limits the overlap with the new version scheme to conflicts
- * with 6.71.8.764 through 6.72.39.934.
- */
- if ((ver > (4 << 24)) && (ver < ( (4 << 24) + (1 << 17)))) {
- /* 4.0.x and earlier */
- verstr[1] = verstr[3] = 0;
- verstr[2] = (ver & 0x1f) ? (ver & 0x1f) + 'a' - 1 : 0;
- ver >>= 5;
- verstr[0] = (ver & 0x1f) ? (ver & 0x1f) + 'A' - 1 : 0;
- ver >>= 5;
- vercode[2] = ver & 0x7f;
- ver >>= 7;
- vercode[1] = ver & 0x7f;
- ver >>= 7;
- vercode[0] = ver;
- xf86ErrorF("\tcompiled for %d.%d", vercode[0], vercode[1]);
- if (vercode[2] != 0)
- xf86ErrorF(".%d", vercode[2]);
- xf86ErrorF("%s%s, module version = %d.%d.%d\n", verstr, verstr + 2,
- data->majorversion, data->minorversion, data->patchlevel);
- } else {
- vercode[0] = ver / 10000000;
- vercode[1] = (ver / 100000) % 100;
- vercode[2] = (ver / 1000) % 100;
- vercode[3] = ver % 1000;
- xf86ErrorF("\tcompiled for %d.%d.%d", vercode[0], vercode[1],
- vercode[2]);
- if (vercode[3] != 0)
- xf86ErrorF(".%d", vercode[3]);
- xf86ErrorF(", module version = %d.%d.%d\n", data->majorversion,
- data->minorversion, data->patchlevel);
- }
-
- if (data->moduleclass)
- xf86ErrorFVerb(2, "\tModule class: %s\n", data->moduleclass);
-
- ver = -1;
- if (data->abiclass) {
- int abimaj, abimin;
- int vermaj, vermin;
-
- if (!strcmp(data->abiclass, ABI_CLASS_ANSIC))
- ver = LoaderVersionInfo.ansicVersion;
- else if (!strcmp(data->abiclass, ABI_CLASS_VIDEODRV))
- ver = LoaderVersionInfo.videodrvVersion;
- else if (!strcmp(data->abiclass, ABI_CLASS_XINPUT))
- ver = LoaderVersionInfo.xinputVersion;
- else if (!strcmp(data->abiclass, ABI_CLASS_EXTENSION))
- ver = LoaderVersionInfo.extensionVersion;
- else if (!strcmp(data->abiclass, ABI_CLASS_FONT))
- ver = LoaderVersionInfo.fontVersion;
-
- abimaj = GET_ABI_MAJOR(data->abiversion);
- abimin = GET_ABI_MINOR(data->abiversion);
- xf86ErrorFVerb(2, "\tABI class: %s, version %d.%d\n",
- data->abiclass, abimaj, abimin);
- if (ver != -1) {
- vermaj = GET_ABI_MAJOR(ver);
- vermin = GET_ABI_MINOR(ver);
- if (abimaj != vermaj) {
- if (LoaderOptions & LDR_OPT_ABI_MISMATCH_NONFATAL)
- errtype = X_WARNING;
- else
- errtype = X_ERROR;
- xf86MsgVerb(errtype, 0,
- "module ABI major version (%d) doesn't"
- " match the server's version (%d)\n",
- abimaj, vermaj);
- if (!(LoaderOptions & LDR_OPT_ABI_MISMATCH_NONFATAL))
- return FALSE;
- } else if (abimin > vermin) {
- if (LoaderOptions & LDR_OPT_ABI_MISMATCH_NONFATAL)
- errtype = X_WARNING;
- else
- errtype = X_ERROR;
- xf86MsgVerb(errtype, 0,
- "module ABI minor version (%d) is "
- "newer than the server's version "
- "(%d)\n", abimin, vermin);
- if (!(LoaderOptions & LDR_OPT_ABI_MISMATCH_NONFATAL))
- return FALSE;
- }
- }
- }
-
- /* Check against requirements that the caller has specified */
- if (req) {
- if (req->majorversion != MAJOR_UNSPEC) {
- if (data->majorversion != req->majorversion) {
- xf86MsgVerb(X_WARNING, 2, "module major version (%d) "
- "doesn't match required major version (%d)\n",
- data->majorversion, req->majorversion);
- return FALSE;
- } else if (req->minorversion != MINOR_UNSPEC) {
- if (data->minorversion < req->minorversion) {
- xf86MsgVerb(X_WARNING, 2, "module minor version (%d) "
- "is less than the required minor version (%d)\n",
- data->minorversion, req->minorversion);
- return FALSE;
- } else if (data->minorversion == req->minorversion &&
- req->patchlevel != PATCH_UNSPEC) {
- if (data->patchlevel < req->patchlevel) {
- xf86MsgVerb(X_WARNING, 2, "module patch level (%d) "
- "is less than the required patch level (%d)\n",
- data->patchlevel, req->patchlevel);
- return FALSE;
- }
- }
- }
- }
- if (req->moduleclass) {
- if (!data->moduleclass ||
- strcmp(req->moduleclass, data->moduleclass)) {
- xf86MsgVerb(X_WARNING, 2, "Module class (%s) doesn't match "
- "the required class (%s)\n",
- data->moduleclass ? data->moduleclass : "<NONE>",
- req->moduleclass);
- return FALSE;
- }
- } else if (req->abiclass != ABI_CLASS_NONE) {
- if (!data->abiclass || strcmp(req->abiclass, data->abiclass)) {
- xf86MsgVerb(X_WARNING, 2, "ABI class (%s) doesn't match the "
- "required ABI class (%s)\n",
- data->abiclass ? data->abiclass : "<NONE>",
- req->abiclass);
- return FALSE;
- }
- }
- if ((req->abiclass != ABI_CLASS_NONE) &&
- req->abiversion != ABI_VERS_UNSPEC) {
- int reqmaj, reqmin, maj, min;
-
- reqmaj = GET_ABI_MAJOR(req->abiversion);
- reqmin = GET_ABI_MINOR(req->abiversion);
- maj = GET_ABI_MAJOR(data->abiversion);
- min = GET_ABI_MINOR(data->abiversion);
- if (maj != reqmaj) {
- xf86MsgVerb(X_WARNING, 2, "ABI major version (%d) doesn't "
- "match the required ABI major version (%d)\n",
- maj, reqmaj);
- return FALSE;
- }
- /* XXX Maybe this should be the other way around? */
- if (min > reqmin) {
- xf86MsgVerb(X_WARNING, 2, "module ABI minor version (%d) "
- "is newer than that available (%d)\n", min, reqmin);
- return FALSE;
- }
- }
- }
- return TRUE;
-}
-
-static ModuleDescPtr
-AddSibling(ModuleDescPtr head, ModuleDescPtr new)
-{
- new->sib = head;
- return (new);
-}
-
-pointer
-LoadSubModule(pointer _parent, const char *module,
- const char **subdirlist, const char **patternlist,
- pointer options, const XF86ModReqInfo * modreq,
- int *errmaj, int *errmin)
-{
- ModuleDescPtr submod;
- ModuleDescPtr parent = (ModuleDescPtr)_parent;
-
- xf86MsgVerb(X_INFO, 3, "Loading sub module \"%s\"\n", module);
-
- if (PathIsAbsolute(module)) {
- xf86Msg(X_ERROR,
- "LoadSubModule: Absolute module path not permitted: \"%s\"\n",
- module);
- if (errmaj)
- *errmaj = LDR_BADUSAGE;
- if (errmin)
- *errmin = 0;
- return NULL;
- }
-
- submod = doLoadModule(module, NULL, subdirlist, patternlist, options,
- modreq, errmaj, errmin, LD_FLAG_GLOBAL);
- if (submod && submod != (ModuleDescPtr) 1) {
- parent->child = AddSibling(parent->child, submod);
- submod->parent = parent;
- }
- return submod;
-}
-
-static ModuleDescPtr
-NewModuleDesc(const char *name)
-{
- ModuleDescPtr mdp = xalloc(sizeof(ModuleDesc));
-
- if (mdp) {
- mdp->child = NULL;
- mdp->sib = NULL;
- mdp->parent = NULL;
- mdp->name = xstrdup(name);
- mdp->handle = -1;
- mdp->SetupProc = NULL;
- mdp->TearDownProc = NULL;
- mdp->TearDownData = NULL;
- }
-
- return (mdp);
-}
-
-ModuleDescPtr
-DuplicateModule(ModuleDescPtr mod, ModuleDescPtr parent)
-{
- ModuleDescPtr ret;
-
- if (!mod)
- return NULL;
-
- ret = NewModuleDesc(mod->name);
- if (ret == NULL)
- return NULL;
-
- if (LoaderHandleOpen(mod->handle) == -1)
- return NULL;
-
- ret->handle = mod->handle;
- ret->SetupProc = mod->SetupProc;
- ret->TearDownProc = mod->TearDownProc;
- ret->TearDownData = NULL;
- ret->child = DuplicateModule(mod->child, ret);
- ret->sib = DuplicateModule(mod->sib, parent);
- ret->parent = parent;
- ret->VersionInfo = mod->VersionInfo;
-
- return ret;
-}
-
-static const char *compiled_in_modules[] = {
- "ddc",
- "i2c",
- "ramdac",
- NULL
-};
-
-static ModuleDescPtr
-doLoadModule(const char *module, const char *path, const char **subdirlist,
- const char **patternlist, pointer options,
- const XF86ModReqInfo * modreq,
- int *errmaj, int *errmin, int flags)
-{
- XF86ModuleData *initdata = NULL;
- char **pathlist = NULL;
- char *found = NULL;
- char *name = NULL;
- char **path_elem = NULL;
- char *p = NULL;
- ModuleDescPtr ret = NULL;
- int wasLoaded = 0;
- PatternPtr patterns = NULL;
- int noncanonical = 0;
- char *m = NULL;
- const char **cim;
-
- xf86MsgVerb(X_INFO, 3, "LoadModule: \"%s\"", module);
-
- patterns = InitPatterns(patternlist);
- name = LoaderGetCanonicalName(module, patterns);
- noncanonical = (name && strcmp(module, name) != 0);
- if (noncanonical) {
- xf86ErrorFVerb(3, " (%s)\n", name);
- xf86MsgVerb(X_WARNING, 1,
- "LoadModule: given non-canonical module name \"%s\"\n",
- module);
- m = name;
- } else {
- xf86ErrorFVerb(3, "\n");
- m = (char *)module;
- }
-
- for (cim = compiled_in_modules; *cim; cim++)
- if (!strcmp (m, *cim))
- {
- xf86MsgVerb(X_INFO, 3, "Module \"%s\" already built-in\n", m);
- ret = (ModuleDescPtr) 1;
- goto LoadModule_exit;
- }
-
- if (!name) {
- if (errmaj)
- *errmaj = LDR_BADUSAGE;
- if (errmin)
- *errmin = 0;
- goto LoadModule_fail;
- }
- ret = NewModuleDesc(name);
- if (!ret) {
- if (errmaj)
- *errmaj = LDR_NOMEM;
- if (errmin)
- *errmin = 0;
- goto LoadModule_fail;
- }
-
- pathlist = InitPathList(path);
- if (!pathlist) {
- /* This could be a malloc failure too */
- if (errmaj)
- *errmaj = LDR_BADUSAGE;
- if (errmin)
- *errmin = 1;
- goto LoadModule_fail;
- }
-
- /*
- * if the module name is not a full pathname, we need to
- * check the elements in the path
- */
- if (PathIsAbsolute(module))
- found = xstrdup(module);
- path_elem = pathlist;
- while (!found && *path_elem != NULL) {
- found = FindModule(m, *path_elem, subdirlist, patterns);
- path_elem++;
- /*
- * When the module name isn't the canonical name, search for the
- * former if no match was found for the latter.
- */
- if (!*path_elem && m == name) {
- path_elem = pathlist;
- m = (char *)module;
- }
- }
-
- /*
- * did we find the module?
- */
- if (!found) {
- xf86Msg(X_WARNING, "Warning, couldn't open module %s\n", module);
- if (errmaj)
- *errmaj = LDR_NOENT;
- if (errmin)
- *errmin = 0;
- goto LoadModule_fail;
- }
- ret->handle = LoaderOpen(found, name, 0,
- errmaj, errmin, &wasLoaded, flags);
- if (ret->handle < 0)
- goto LoadModule_fail;
-
- /* drop any explicit suffix from the module name */
- p = strchr(name, '.');
- if (p)
- *p = '\0';
-
- /*
- * now check if the special data object <modulename>ModuleData is
- * present.
- */
- p = xalloc(strlen(name) + strlen("ModuleData") + 1);
- if (!p) {
- if (errmaj)
- *errmaj = LDR_NOMEM;
- if (errmin)
- *errmin = 0;
- goto LoadModule_fail;
- }
- strcpy(p, name);
- strcat(p, "ModuleData");
- initdata = LoaderSymbol(p);
- if (initdata) {
- ModuleSetupProc setup;
- ModuleTearDownProc teardown;
- XF86ModuleVersionInfo *vers;
-
- vers = initdata->vers;
- setup = initdata->setup;
- teardown = initdata->teardown;
-
- if (!wasLoaded) {
- if (vers) {
- if (!CheckVersion(module, vers, modreq)) {
- if (errmaj)
- *errmaj = LDR_MISMATCH;
- if (errmin)
- *errmin = 0;
- goto LoadModule_fail;
- }
- } else {
- xf86Msg(X_ERROR,
- "LoadModule: Module %s does not supply"
- " version information\n", module);
- if (errmaj)
- *errmaj = LDR_INVALID;
- if (errmin)
- *errmin = 0;
- goto LoadModule_fail;
- }
- }
- if (setup)
- ret->SetupProc = setup;
- if (teardown)
- ret->TearDownProc = teardown;
- ret->VersionInfo = vers;
- } else {
- /* No initdata is OK for external modules */
- if (options == EXTERN_MODULE)
- goto LoadModule_exit;
-
- /* no initdata, fail the load */
- xf86Msg(X_ERROR, "LoadModule: Module %s does not have a %s "
- "data object.\n", module, p);
- if (errmaj)
- *errmaj = LDR_INVALID;
- if (errmin)
- *errmin = 0;
- goto LoadModule_fail;
- }
- if (ret->SetupProc) {
- ret->TearDownData = ret->SetupProc(ret, options, errmaj, errmin);
- if (!ret->TearDownData) {
- goto LoadModule_fail;
- }
- } else if (options) {
- xf86Msg(X_WARNING, "Module Options present, but no SetupProc "
- "available for %s\n", module);
- }
- goto LoadModule_exit;
-
- LoadModule_fail:
- UnloadModule(ret);
- ret = NULL;
-
- LoadModule_exit:
- FreePathList(pathlist);
- FreePatterns(patterns);
- xfree(found);
- xfree(name);
- xfree(p);
-
- return ret;
-}
-
-/*
- * LoadModule: load a module
- *
- * module The module name. Normally this is not a filename but the
- * module's "canonical name. A full pathname is, however,
- * also accepted.
- * path A comma separated list of module directories.
- * subdirlist A NULL terminated list of subdirectories to search. When
- * NULL, the default "stdSubdirs" list is used. The default
- * list is also substituted for entries with value DEFAULT_LIST.
- * patternlist A NULL terminated list of regular expressions used to find
- * module filenames. Each regex should contain exactly one
- * subexpression that corresponds to the canonical module name.
- * When NULL, the default "stdPatterns" list is used. The
- * default list is also substituted for entries with value
- * DEFAULT_LIST.
- * options A NULL terminated list of Options that are passed to the
- * module's SetupProc function.
- * modreq An optional XF86ModReqInfo* containing
- * version/ABI/vendor-ABI requirements to check for when
- * loading the module. The following fields of the
- * XF86ModReqInfo struct are checked:
- * majorversion - must match the module's majorversion exactly
- * minorversion - the module's minorversion must be >= this
- * patchlevel - the module's minorversion.patchlevel must be
- * >= this. Patchlevel is ignored when
- * minorversion is not set.
- * abiclass - (string) must match the module's abiclass
- * abiversion - must be consistent with the module's
- * abiversion (major equal, minor no older)
- * moduleclass - string must match the module's moduleclass
- * string
- * "don't care" values are ~0 for numbers, and NULL for strings
- * errmaj Major error return.
- * errmin Minor error return.
- *
- */
-ModuleDescPtr
-LoadModule(const char *module, const char *path, const char **subdirlist,
- const char **patternlist, pointer options,
- const XF86ModReqInfo * modreq, int *errmaj, int *errmin)
-{
- return doLoadModule(module, path, subdirlist, patternlist, options,
- modreq, errmaj, errmin, LD_FLAG_GLOBAL);
-}
-
-void
-UnloadModule(pointer mod)
-{
- UnloadModuleOrDriver((ModuleDescPtr)mod);
-}
-
-static void
-UnloadModuleOrDriver(ModuleDescPtr mod)
-{
- if (mod == (ModuleDescPtr) 1)
- return;
-
- if (mod == NULL || mod->name == NULL)
- return;
-
- xf86MsgVerb(X_INFO, 3, "UnloadModule: \"%s\"\n", mod->name);
-
- if ((mod->TearDownProc) && (mod->TearDownData))
- mod->TearDownProc(mod->TearDownData);
- LoaderUnload(mod->handle);
-
- if (mod->child)
- UnloadModuleOrDriver(mod->child);
- if (mod->sib)
- UnloadModuleOrDriver(mod->sib);
- xfree(mod->name);
- xfree(mod);
-}
-
-void
-UnloadSubModule(pointer _mod)
-{
- ModuleDescPtr mod = (ModuleDescPtr)_mod;
-
- if (mod == NULL || mod->name == NULL)
- return;
-
- xf86MsgVerb(X_INFO, 3, "UnloadSubModule: \"%s\"\n", mod->name);
-
- if ((mod->TearDownProc) && (mod->TearDownData))
- mod->TearDownProc(mod->TearDownData);
- LoaderUnload(mod->handle);
-
- RemoveChild(mod);
-
- if (mod->child)
- UnloadModuleOrDriver(mod->child);
-
- xfree(mod->name);
- xfree(mod);
-}
-
-static void
-RemoveChild(ModuleDescPtr child)
-{
- ModuleDescPtr mdp;
- ModuleDescPtr prevsib;
- ModuleDescPtr parent;
-
- if (!child->parent)
- return;
-
- parent = child->parent;
- if (parent->child == child) {
- parent->child = child->sib;
- return;
- }
-
- prevsib = parent->child;
- mdp = prevsib->sib;
- while (mdp && mdp != child) {
- prevsib = mdp;
- mdp = mdp->sib;
- }
- if (mdp == child)
- prevsib->sib = child->sib;
- return;
-}
-
-void
-LoaderErrorMsg(const char *name, const char *modname, int errmaj, int errmin)
-{
- const char *msg;
- MessageType type = X_ERROR;
-
- switch (errmaj) {
- case LDR_NOERROR:
- msg = "no error";
- break;
- case LDR_NOMEM:
- msg = "out of memory";
- break;
- case LDR_NOENT:
- msg = "module does not exist";
- break;
- case LDR_NOSUBENT:
- msg = "a required submodule could not be loaded";
- break;
- case LDR_NOSPACE:
- msg = "too many modules";
- break;
- case LDR_NOMODOPEN:
- msg = "open failed";
- break;
- case LDR_UNKTYPE:
- msg = "unknown module type";
- break;
- case LDR_NOLOAD:
- msg = "loader failed";
- break;
- case LDR_ONCEONLY:
- msg = "already loaded";
- type = X_INFO;
- break;
- case LDR_NOPORTOPEN:
- msg = "port open failed";
- break;
- case LDR_NOHARDWARE:
- msg = "no hardware found";
- break;
- case LDR_MISMATCH:
- msg = "module requirement mismatch";
- break;
- case LDR_BADUSAGE:
- msg = "invalid argument(s) to LoadModule()";
- break;
- case LDR_INVALID:
- msg = "invalid module";
- break;
- case LDR_BADOS:
- msg = "module doesn't support this OS";
- break;
- case LDR_MODSPECIFIC:
- msg = "module-specific error";
- break;
- default:
- msg = "unknown error";
- }
- if (name)
- xf86Msg(type, "%s: Failed to load module \"%s\" (%s, %d)\n",
- name, modname, msg, errmin);
- else
- xf86Msg(type, "Failed to load module \"%s\" (%s, %d)\n",
- modname, msg, errmin);
-}
-
-/* Given a module path or file name, return the module's canonical name */
-static char *
-LoaderGetCanonicalName(const char *modname, PatternPtr patterns)
-{
- char *str;
- const char *s;
- int len;
- PatternPtr p;
- regmatch_t match[2];
-
- /* Strip off any leading path */
- s = strrchr(modname, '/');
- if (s == NULL)
- s = modname;
- else
- s++;
-
- /* Find the first regex that is matched */
- for (p = patterns; p->pattern; p++)
- if (regexec(&p->rex, s, 2, match, 0) == 0 && match[1].rm_so != -1) {
- len = match[1].rm_eo - match[1].rm_so;
- str = xalloc(len + 1);
- if (!str)
- return NULL;
- strncpy(str, s + match[1].rm_so, len);
- str[len] = '\0';
- return str;
- }
-
- /* If there is no match, return the whole name minus the leading path */
- return xstrdup(s);
-}
-
-/*
- * Return the module version information.
- */
-unsigned long
-LoaderGetModuleVersion(ModuleDescPtr mod)
-{
- if (!mod || mod == (ModuleDescPtr) 1 || !mod->VersionInfo)
- return 0;
-
- return MODULE_VERSION_NUMERIC(mod->VersionInfo->majorversion,
- mod->VersionInfo->minorversion,
- mod->VersionInfo->patchlevel);
-}
+/*
+ * Copyright 1995-1998 by Metro Link, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Metro Link, Inc. not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Metro Link, Inc. makes no
+ * representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ * METRO LINK, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL METRO LINK, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+/*
+ * Copyright (c) 1997-2002 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "os.h"
+/* For stat() and related stuff */
+#define NO_OSLIB_PROTOTYPES
+#include "xf86_OSlib.h"
+#define LOADERDECLARATIONS
+#include "loaderProcs.h"
+#include "misc.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86Xinput.h"
+#include "loader.h"
+#include "xf86Optrec.h"
+
+#include <sys/types.h>
+#include <regex.h>
+#include <dirent.h>
+#include <limits.h>
+
+typedef struct _pattern {
+ const char *pattern;
+ regex_t rex;
+} PatternRec, *PatternPtr;
+
+/* Prototypes for static functions */
+static char *FindModule(const char *, const char *, const char **,
+ PatternPtr);
+static Bool CheckVersion(const char *, XF86ModuleVersionInfo *,
+ const XF86ModReqInfo *);
+static void UnloadModuleOrDriver(ModuleDescPtr mod);
+static char *LoaderGetCanonicalName(const char *, PatternPtr);
+static void RemoveChild(ModuleDescPtr);
+static ModuleDescPtr doLoadModule(const char *, const char *, const char **,
+ const char **, pointer,
+ const XF86ModReqInfo *, int *, int *,
+ int flags);
+
+const ModuleVersions LoaderVersionInfo = {
+ XORG_VERSION_CURRENT,
+ ABI_ANSIC_VERSION,
+ ABI_VIDEODRV_VERSION,
+ ABI_XINPUT_VERSION,
+ ABI_EXTENSION_VERSION,
+ ABI_FONT_VERSION
+};
+
+static void
+FreeStringList(char **paths)
+{
+ char **p;
+
+ if (!paths)
+ return;
+
+ for (p = paths; *p; p++)
+ free(*p);
+
+ free(paths);
+}
+
+static char **defaultPathList = NULL;
+
+static Bool
+PathIsAbsolute(const char *path)
+{
+ return (*path == '/');
+}
+
+/*
+ * Convert a comma-separated path into a NULL-terminated array of path
+ * elements, rejecting any that are not full absolute paths, and appending
+ * a '/' when it isn't already present.
+ */
+static char **
+InitPathList(const char *path)
+{
+ char *fullpath = NULL;
+ char *elem = NULL;
+ char **list = NULL, **save = NULL;
+ int len;
+ int addslash;
+ int n = 0;
+
+ if (!path)
+ return defaultPathList;
+
+ fullpath = xstrdup(path);
+ if (!fullpath)
+ return NULL;
+ elem = strtok(fullpath, ",");
+ while (elem) {
+ if (PathIsAbsolute(elem))
+ {
+ len = strlen(elem);
+ addslash = (elem[len - 1] != '/');
+ if (addslash)
+ len++;
+ save = list;
+ list = realloc(list, (n + 2) * sizeof(char *));
+ if (!list) {
+ if (save) {
+ save[n] = NULL;
+ FreeStringList(save);
+ }
+ free(fullpath);
+ return NULL;
+ }
+ list[n] = malloc(len + 1);
+ if (!list[n]) {
+ FreeStringList(list);
+ free(fullpath);
+ return NULL;
+ }
+ strcpy(list[n], elem);
+ if (addslash) {
+ list[n][len - 1] = '/';
+ list[n][len] = '\0';
+ }
+ n++;
+ }
+ elem = strtok(NULL, ",");
+ }
+ if (list)
+ list[n] = NULL;
+ free(fullpath);
+ return list;
+}
+
+static void
+FreePathList(char **pathlist)
+{
+ if (pathlist && pathlist != defaultPathList)
+ FreeStringList(pathlist);
+}
+
+void
+LoaderSetPath(const char *path)
+{
+ if (!path)
+ return;
+
+ defaultPathList = InitPathList(path);
+}
+
+/* Standard set of module subdirectories to search, in order of preference */
+static const char *stdSubdirs[] = {
+ "",
+ "input/",
+ "drivers/",
+ "multimedia/",
+ "extensions/",
+ "internal/",
+ NULL
+};
+
+/*
+ * Standard set of module name patterns to check, in order of preference
+ * These are regular expressions (suitable for use with POSIX regex(3)).
+ *
+ * This list assumes that you're an ELFish platform and therefore your
+ * shared libraries are named something.so. If we're ever nuts enough
+ * to port this DDX to, say, Darwin, we'll need to fix this.
+ */
+static PatternRec stdPatterns[] = {
+ {"^lib(.*)\\.so$",},
+ {"(.*)_drv\\.so$",},
+ {"(.*)\\.so$",},
+ {NULL,}
+};
+
+static PatternPtr
+InitPatterns(const char **patternlist)
+{
+ char errmsg[80];
+ int i, e;
+ PatternPtr patterns = NULL;
+ PatternPtr p = NULL;
+ static int firstTime = 1;
+ const char **s;
+
+ if (firstTime) {
+ /* precompile stdPatterns */
+ firstTime = 0;
+ for (p = stdPatterns; p->pattern; p++)
+ if ((e = regcomp(&p->rex, p->pattern, REG_EXTENDED)) != 0) {
+ regerror(e, &p->rex, errmsg, sizeof(errmsg));
+ FatalError("InitPatterns: regcomp error for `%s': %s\n",
+ p->pattern, errmsg);
+ }
+ }
+
+ if (patternlist) {
+ for (i = 0, s = patternlist; *s; i++, s++)
+ if (*s == DEFAULT_LIST)
+ i += sizeof(stdPatterns) / sizeof(stdPatterns[0]) - 1 - 1;
+ patterns = malloc((i + 1) * sizeof(PatternRec));
+ if (!patterns) {
+ return NULL;
+ }
+ for (i = 0, s = patternlist; *s; i++, s++)
+ if (*s != DEFAULT_LIST) {
+ p = patterns + i;
+ p->pattern = *s;
+ if ((e = regcomp(&p->rex, p->pattern, REG_EXTENDED)) != 0) {
+ regerror(e, &p->rex, errmsg, sizeof(errmsg));
+ ErrorF("InitPatterns: regcomp error for `%s': %s\n",
+ p->pattern, errmsg);
+ i--;
+ }
+ } else {
+ for (p = stdPatterns; p->pattern; p++, i++)
+ patterns[i] = *p;
+ if (p != stdPatterns)
+ i--;
+ }
+ patterns[i].pattern = NULL;
+ } else
+ patterns = stdPatterns;
+ return patterns;
+}
+
+static void
+FreePatterns(PatternPtr patterns)
+{
+ if (patterns && patterns != stdPatterns)
+ free(patterns);
+}
+
+static const char **
+InitSubdirs(const char **subdirlist)
+{
+ int i;
+ const char **tmp_subdirlist = NULL;
+ char **subdirs = NULL;
+ const char **s, **stmp = NULL;
+ const char *osname;
+ const char *slash;
+ int oslen = 0, len;
+ Bool indefault;
+
+ if (subdirlist == NULL) {
+ subdirlist = tmp_subdirlist = malloc(2 * sizeof(char *));
+ if (subdirlist == NULL)
+ return NULL;
+ subdirlist[0] = DEFAULT_LIST;
+ subdirlist[1] = NULL;
+ }
+
+ LoaderGetOS(&osname, NULL, NULL, NULL);
+ oslen = strlen(osname);
+
+ {
+ /* Count number of entries and check for invalid paths */
+ for (i = 0, s = subdirlist; *s; i++, s++) {
+ if (*s == DEFAULT_LIST) {
+ i += sizeof(stdSubdirs) / sizeof(stdSubdirs[0]) - 1 - 1;
+ } else {
+ /*
+ * Path validity check. Don't allow absolute paths, or
+ * paths containing "..". To catch absolute paths on
+ * platforms that use driver letters, don't allow the ':'
+ * character to appear at all.
+ */
+ if (**s == '/' || **s == '\\' || strchr(*s, ':') ||
+ strstr(*s, "..")) {
+ xf86Msg(X_ERROR, "InitSubdirs: Bad subdir: \"%s\"\n", *s);
+ if (tmp_subdirlist)
+ free(tmp_subdirlist);
+ return NULL;
+ }
+ }
+ }
+ subdirs = malloc((i * 2 + 1) * sizeof(char *));
+ if (!subdirs) {
+ if (tmp_subdirlist)
+ free(tmp_subdirlist);
+ return NULL;
+ }
+ i = 0;
+ s = subdirlist;
+ indefault = FALSE;
+ while (*s) {
+ if (*s == DEFAULT_LIST) {
+ /* Divert to the default list */
+ indefault = TRUE;
+ stmp = ++s;
+ s = stdSubdirs;
+ }
+ len = strlen(*s);
+ if (**s && (*s)[len - 1] != '/') {
+ slash = "/";
+ len++;
+ } else
+ slash = "";
+ len += oslen + 2;
+ if (!(subdirs[i] = malloc(len))) {
+ while (--i >= 0)
+ free(subdirs[i]);
+ free(subdirs);
+ if (tmp_subdirlist)
+ free(tmp_subdirlist);
+ return NULL;
+ }
+ /* tack on the OS name */
+ sprintf(subdirs[i], "%s%s%s/", *s, slash, osname);
+ i++;
+ /* path as given */
+ subdirs[i] = xstrdup(*s);
+ i++;
+ s++;
+ if (indefault && !s) {
+ /* revert back to the main list */
+ indefault = FALSE;
+ s = stmp;
+ }
+ }
+ subdirs[i] = NULL;
+ }
+ if (tmp_subdirlist)
+ free(tmp_subdirlist);
+ return (const char **)subdirs;
+}
+
+static void
+FreeSubdirs(const char **subdirs)
+{
+ const char **s;
+
+ if (subdirs) {
+ for (s = subdirs; *s; s++)
+ free(*s);
+ free(subdirs);
+ }
+}
+
+static char *
+FindModuleInSubdir(const char *dirpath, const char *module)
+{
+ struct dirent *direntry = NULL;
+ DIR *dir = NULL;
+ char *ret = NULL, tmpBuf[PATH_MAX];
+ struct stat stat_buf;
+
+ dir = opendir(dirpath);
+ if (!dir)
+ return NULL;
+
+ while ((direntry = readdir(dir))) {
+ if (direntry->d_name[0] == '.')
+ continue;
+ snprintf(tmpBuf, PATH_MAX, "%s%s/", dirpath, direntry->d_name);
+ /* the stat with the appended / fails for normal files,
+ and works for sub dirs fine, looks a bit strange in strace
+ but does seem to work */
+ if ((stat(tmpBuf, &stat_buf) == 0) && S_ISDIR(stat_buf.st_mode)) {
+ if ((ret = FindModuleInSubdir(tmpBuf, module)))
+ break;
+ continue;
+ }
+
+ snprintf(tmpBuf, PATH_MAX, "lib%s.so", module);
+ if (strcmp(direntry->d_name, tmpBuf) == 0) {
+ ret = malloc(strlen(tmpBuf) + strlen(dirpath) + 2);
+ sprintf(ret, "%s%s", dirpath, tmpBuf);
+ break;
+ }
+
+ snprintf(tmpBuf, PATH_MAX, "%s_drv.so", module);
+ if (strcmp(direntry->d_name, tmpBuf) == 0) {
+ ret = malloc(strlen(tmpBuf) + strlen(dirpath) + 2);
+ sprintf(ret, "%s%s", dirpath, tmpBuf);
+ break;
+ }
+
+ snprintf(tmpBuf, PATH_MAX, "%s.so", module);
+ if (strcmp(direntry->d_name, tmpBuf) == 0) {
+ ret = malloc(strlen(tmpBuf) + strlen(dirpath) + 2);
+ sprintf(ret, "%s%s", dirpath, tmpBuf);
+ break;
+ }
+ }
+
+ closedir(dir);
+ return ret;
+}
+
+static char *
+FindModule(const char *module, const char *dirname, const char **subdirlist,
+ PatternPtr patterns)
+{
+ char buf[PATH_MAX + 1];
+ char *dirpath = NULL;
+ char *name = NULL;
+ int dirlen;
+ const char **subdirs = NULL;
+ const char **s;
+
+ dirpath = (char *)dirname;
+ if (strlen(dirpath) > PATH_MAX)
+ return NULL;
+
+ subdirs = InitSubdirs(subdirlist);
+ if (!subdirs)
+ return NULL;
+
+ for (s = subdirs; *s; s++) {
+ if ((dirlen = strlen(dirpath) + strlen(*s)) > PATH_MAX)
+ continue;
+ strcpy(buf, dirpath);
+ strcat(buf, *s);
+ if ((name = FindModuleInSubdir(buf, module)))
+ break;
+ }
+
+ FreeSubdirs(subdirs);
+ if (dirpath != dirname)
+ free(dirpath);
+
+ return name;
+}
+
+char **
+LoaderListDirs(const char **subdirlist, const char **patternlist)
+{
+ char buf[PATH_MAX + 1];
+ char **pathlist;
+ char **elem;
+ const char **subdirs;
+ const char **s;
+ PatternPtr patterns;
+ PatternPtr p;
+ DIR *d;
+ struct dirent *dp;
+ regmatch_t match[2];
+ struct stat stat_buf;
+ int len, dirlen;
+ char *fp;
+ char **listing = NULL;
+ char **save;
+ int n = 0;
+
+ if (!(pathlist = InitPathList(NULL)))
+ return NULL;
+ if (!(subdirs = InitSubdirs(subdirlist))) {
+ FreePathList(pathlist);
+ return NULL;
+ }
+ if (!(patterns = InitPatterns(patternlist))) {
+ FreePathList(pathlist);
+ FreeSubdirs(subdirs);
+ return NULL;
+ }
+
+ for (elem = pathlist; *elem; elem++) {
+ for (s = subdirs; *s; s++) {
+ if ((dirlen = strlen(*elem) + strlen(*s)) > PATH_MAX)
+ continue;
+ strcpy(buf, *elem);
+ strcat(buf, *s);
+ fp = buf + dirlen;
+ if (stat(buf, &stat_buf) == 0 && S_ISDIR(stat_buf.st_mode) &&
+ (d = opendir(buf))) {
+ if (buf[dirlen - 1] != '/') {
+ buf[dirlen++] = '/';
+ fp++;
+ }
+ while ((dp = readdir(d))) {
+ if (dirlen + strlen(dp->d_name) > PATH_MAX)
+ continue;
+ strcpy(fp, dp->d_name);
+ if (!(stat(buf, &stat_buf) == 0 &&
+ S_ISREG(stat_buf.st_mode)))
+ continue;
+ for (p = patterns; p->pattern; p++) {
+ if (regexec(&p->rex, dp->d_name, 2, match, 0) == 0 &&
+ match[1].rm_so != -1) {
+ len = match[1].rm_eo - match[1].rm_so;
+ save = listing;
+ listing = realloc(listing,
+ (n + 2) * sizeof(char *));
+ if (!listing) {
+ if (save) {
+ save[n] = NULL;
+ FreeStringList(save);
+ }
+ FreePathList(pathlist);
+ FreeSubdirs(subdirs);
+ FreePatterns(patterns);
+ return NULL;
+ }
+ listing[n] = malloc(len + 1);
+ if (!listing[n]) {
+ FreeStringList(listing);
+ FreePathList(pathlist);
+ FreeSubdirs(subdirs);
+ FreePatterns(patterns);
+ return NULL;
+ }
+ strncpy(listing[n], dp->d_name + match[1].rm_so,
+ len);
+ listing[n][len] = '\0';
+ n++;
+ break;
+ }
+ }
+ }
+ closedir(d);
+ }
+ }
+ }
+ if (listing)
+ listing[n] = NULL;
+ return listing;
+}
+
+void
+LoaderFreeDirList(char **list)
+{
+ FreeStringList(list);
+}
+
+static Bool
+CheckVersion(const char *module, XF86ModuleVersionInfo * data,
+ const XF86ModReqInfo * req)
+{
+ int vercode[4];
+ char verstr[4];
+ long ver = data->xf86version;
+ MessageType errtype;
+
+ xf86Msg(X_INFO, "Module %s: vendor=\"%s\"\n",
+ data->modname ? data->modname : "UNKNOWN!",
+ data->vendor ? data->vendor : "UNKNOWN!");
+
+ /* Check for the different scheme used in XFree86 4.0.x releases:
+ * ((((((((major << 7) | minor) << 7) | subminor) << 5) | beta) << 5) | alpha)
+ * Since it wasn't used in 4.1.0 or later, limit to versions in the 4.0.x
+ * range, which limits the overlap with the new version scheme to conflicts
+ * with 6.71.8.764 through 6.72.39.934.
+ */
+ if ((ver > (4 << 24)) && (ver < ( (4 << 24) + (1 << 17)))) {
+ /* 4.0.x and earlier */
+ verstr[1] = verstr[3] = 0;
+ verstr[2] = (ver & 0x1f) ? (ver & 0x1f) + 'a' - 1 : 0;
+ ver >>= 5;
+ verstr[0] = (ver & 0x1f) ? (ver & 0x1f) + 'A' - 1 : 0;
+ ver >>= 5;
+ vercode[2] = ver & 0x7f;
+ ver >>= 7;
+ vercode[1] = ver & 0x7f;
+ ver >>= 7;
+ vercode[0] = ver;
+ xf86ErrorF("\tcompiled for %d.%d", vercode[0], vercode[1]);
+ if (vercode[2] != 0)
+ xf86ErrorF(".%d", vercode[2]);
+ xf86ErrorF("%s%s, module version = %d.%d.%d\n", verstr, verstr + 2,
+ data->majorversion, data->minorversion, data->patchlevel);
+ } else {
+ vercode[0] = ver / 10000000;
+ vercode[1] = (ver / 100000) % 100;
+ vercode[2] = (ver / 1000) % 100;
+ vercode[3] = ver % 1000;
+ xf86ErrorF("\tcompiled for %d.%d.%d", vercode[0], vercode[1],
+ vercode[2]);
+ if (vercode[3] != 0)
+ xf86ErrorF(".%d", vercode[3]);
+ xf86ErrorF(", module version = %d.%d.%d\n", data->majorversion,
+ data->minorversion, data->patchlevel);
+ }
+
+ if (data->moduleclass)
+ xf86ErrorFVerb(2, "\tModule class: %s\n", data->moduleclass);
+
+ ver = -1;
+ if (data->abiclass) {
+ int abimaj, abimin;
+ int vermaj, vermin;
+
+ if (!strcmp(data->abiclass, ABI_CLASS_ANSIC))
+ ver = LoaderVersionInfo.ansicVersion;
+ else if (!strcmp(data->abiclass, ABI_CLASS_VIDEODRV))
+ ver = LoaderVersionInfo.videodrvVersion;
+ else if (!strcmp(data->abiclass, ABI_CLASS_XINPUT))
+ ver = LoaderVersionInfo.xinputVersion;
+ else if (!strcmp(data->abiclass, ABI_CLASS_EXTENSION))
+ ver = LoaderVersionInfo.extensionVersion;
+ else if (!strcmp(data->abiclass, ABI_CLASS_FONT))
+ ver = LoaderVersionInfo.fontVersion;
+
+ abimaj = GET_ABI_MAJOR(data->abiversion);
+ abimin = GET_ABI_MINOR(data->abiversion);
+ xf86ErrorFVerb(2, "\tABI class: %s, version %d.%d\n",
+ data->abiclass, abimaj, abimin);
+ if (ver != -1) {
+ vermaj = GET_ABI_MAJOR(ver);
+ vermin = GET_ABI_MINOR(ver);
+ if (abimaj != vermaj) {
+ if (LoaderOptions & LDR_OPT_ABI_MISMATCH_NONFATAL)
+ errtype = X_WARNING;
+ else
+ errtype = X_ERROR;
+ xf86MsgVerb(errtype, 0,
+ "module ABI major version (%d) doesn't"
+ " match the server's version (%d)\n",
+ abimaj, vermaj);
+ if (!(LoaderOptions & LDR_OPT_ABI_MISMATCH_NONFATAL))
+ return FALSE;
+ } else if (abimin > vermin) {
+ if (LoaderOptions & LDR_OPT_ABI_MISMATCH_NONFATAL)
+ errtype = X_WARNING;
+ else
+ errtype = X_ERROR;
+ xf86MsgVerb(errtype, 0,
+ "module ABI minor version (%d) is "
+ "newer than the server's version "
+ "(%d)\n", abimin, vermin);
+ if (!(LoaderOptions & LDR_OPT_ABI_MISMATCH_NONFATAL))
+ return FALSE;
+ }
+ }
+ }
+
+ /* Check against requirements that the caller has specified */
+ if (req) {
+ if (req->majorversion != MAJOR_UNSPEC) {
+ if (data->majorversion != req->majorversion) {
+ xf86MsgVerb(X_WARNING, 2, "module major version (%d) "
+ "doesn't match required major version (%d)\n",
+ data->majorversion, req->majorversion);
+ return FALSE;
+ } else if (req->minorversion != MINOR_UNSPEC) {
+ if (data->minorversion < req->minorversion) {
+ xf86MsgVerb(X_WARNING, 2, "module minor version (%d) "
+ "is less than the required minor version (%d)\n",
+ data->minorversion, req->minorversion);
+ return FALSE;
+ } else if (data->minorversion == req->minorversion &&
+ req->patchlevel != PATCH_UNSPEC) {
+ if (data->patchlevel < req->patchlevel) {
+ xf86MsgVerb(X_WARNING, 2, "module patch level (%d) "
+ "is less than the required patch level (%d)\n",
+ data->patchlevel, req->patchlevel);
+ return FALSE;
+ }
+ }
+ }
+ }
+ if (req->moduleclass) {
+ if (!data->moduleclass ||
+ strcmp(req->moduleclass, data->moduleclass)) {
+ xf86MsgVerb(X_WARNING, 2, "Module class (%s) doesn't match "
+ "the required class (%s)\n",
+ data->moduleclass ? data->moduleclass : "<NONE>",
+ req->moduleclass);
+ return FALSE;
+ }
+ } else if (req->abiclass != ABI_CLASS_NONE) {
+ if (!data->abiclass || strcmp(req->abiclass, data->abiclass)) {
+ xf86MsgVerb(X_WARNING, 2, "ABI class (%s) doesn't match the "
+ "required ABI class (%s)\n",
+ data->abiclass ? data->abiclass : "<NONE>",
+ req->abiclass);
+ return FALSE;
+ }
+ }
+ if ((req->abiclass != ABI_CLASS_NONE) &&
+ req->abiversion != ABI_VERS_UNSPEC) {
+ int reqmaj, reqmin, maj, min;
+
+ reqmaj = GET_ABI_MAJOR(req->abiversion);
+ reqmin = GET_ABI_MINOR(req->abiversion);
+ maj = GET_ABI_MAJOR(data->abiversion);
+ min = GET_ABI_MINOR(data->abiversion);
+ if (maj != reqmaj) {
+ xf86MsgVerb(X_WARNING, 2, "ABI major version (%d) doesn't "
+ "match the required ABI major version (%d)\n",
+ maj, reqmaj);
+ return FALSE;
+ }
+ /* XXX Maybe this should be the other way around? */
+ if (min > reqmin) {
+ xf86MsgVerb(X_WARNING, 2, "module ABI minor version (%d) "
+ "is newer than that available (%d)\n", min, reqmin);
+ return FALSE;
+ }
+ }
+ }
+ return TRUE;
+}
+
+static ModuleDescPtr
+AddSibling(ModuleDescPtr head, ModuleDescPtr new)
+{
+ new->sib = head;
+ return (new);
+}
+
+pointer
+LoadSubModule(pointer _parent, const char *module,
+ const char **subdirlist, const char **patternlist,
+ pointer options, const XF86ModReqInfo * modreq,
+ int *errmaj, int *errmin)
+{
+ ModuleDescPtr submod;
+ ModuleDescPtr parent = (ModuleDescPtr)_parent;
+
+ xf86MsgVerb(X_INFO, 3, "Loading sub module \"%s\"\n", module);
+
+ if (PathIsAbsolute(module)) {
+ xf86Msg(X_ERROR,
+ "LoadSubModule: Absolute module path not permitted: \"%s\"\n",
+ module);
+ if (errmaj)
+ *errmaj = LDR_BADUSAGE;
+ if (errmin)
+ *errmin = 0;
+ return NULL;
+ }
+
+ submod = doLoadModule(module, NULL, subdirlist, patternlist, options,
+ modreq, errmaj, errmin, LD_FLAG_GLOBAL);
+ if (submod && submod != (ModuleDescPtr) 1) {
+ parent->child = AddSibling(parent->child, submod);
+ submod->parent = parent;
+ }
+ return submod;
+}
+
+static ModuleDescPtr
+NewModuleDesc(const char *name)
+{
+ ModuleDescPtr mdp = malloc(sizeof(ModuleDesc));
+
+ if (mdp) {
+ mdp->child = NULL;
+ mdp->sib = NULL;
+ mdp->parent = NULL;
+ mdp->name = xstrdup(name);
+ mdp->handle = -1;
+ mdp->SetupProc = NULL;
+ mdp->TearDownProc = NULL;
+ mdp->TearDownData = NULL;
+ }
+
+ return (mdp);
+}
+
+ModuleDescPtr
+DuplicateModule(ModuleDescPtr mod, ModuleDescPtr parent)
+{
+ ModuleDescPtr ret;
+
+ if (!mod)
+ return NULL;
+
+ ret = NewModuleDesc(mod->name);
+ if (ret == NULL)
+ return NULL;
+
+ if (LoaderHandleOpen(mod->handle) == -1)
+ return NULL;
+
+ ret->handle = mod->handle;
+ ret->SetupProc = mod->SetupProc;
+ ret->TearDownProc = mod->TearDownProc;
+ ret->TearDownData = NULL;
+ ret->child = DuplicateModule(mod->child, ret);
+ ret->sib = DuplicateModule(mod->sib, parent);
+ ret->parent = parent;
+ ret->VersionInfo = mod->VersionInfo;
+
+ return ret;
+}
+
+static const char *compiled_in_modules[] = {
+ "ddc",
+ "i2c",
+ "ramdac",
+ NULL
+};
+
+static ModuleDescPtr
+doLoadModule(const char *module, const char *path, const char **subdirlist,
+ const char **patternlist, pointer options,
+ const XF86ModReqInfo * modreq,
+ int *errmaj, int *errmin, int flags)
+{
+ XF86ModuleData *initdata = NULL;
+ char **pathlist = NULL;
+ char *found = NULL;
+ char *name = NULL;
+ char **path_elem = NULL;
+ char *p = NULL;
+ ModuleDescPtr ret = NULL;
+ int wasLoaded = 0;
+ PatternPtr patterns = NULL;
+ int noncanonical = 0;
+ char *m = NULL;
+ const char **cim;
+
+ xf86MsgVerb(X_INFO, 3, "LoadModule: \"%s\"", module);
+
+ patterns = InitPatterns(patternlist);
+ name = LoaderGetCanonicalName(module, patterns);
+ noncanonical = (name && strcmp(module, name) != 0);
+ if (noncanonical) {
+ xf86ErrorFVerb(3, " (%s)\n", name);
+ xf86MsgVerb(X_WARNING, 1,
+ "LoadModule: given non-canonical module name \"%s\"\n",
+ module);
+ m = name;
+ } else {
+ xf86ErrorFVerb(3, "\n");
+ m = (char *)module;
+ }
+
+ for (cim = compiled_in_modules; *cim; cim++)
+ if (!strcmp (m, *cim))
+ {
+ xf86MsgVerb(X_INFO, 3, "Module \"%s\" already built-in\n", m);
+ ret = (ModuleDescPtr) 1;
+ goto LoadModule_exit;
+ }
+
+ if (!name) {
+ if (errmaj)
+ *errmaj = LDR_BADUSAGE;
+ if (errmin)
+ *errmin = 0;
+ goto LoadModule_fail;
+ }
+ ret = NewModuleDesc(name);
+ if (!ret) {
+ if (errmaj)
+ *errmaj = LDR_NOMEM;
+ if (errmin)
+ *errmin = 0;
+ goto LoadModule_fail;
+ }
+
+ pathlist = InitPathList(path);
+ if (!pathlist) {
+ /* This could be a malloc failure too */
+ if (errmaj)
+ *errmaj = LDR_BADUSAGE;
+ if (errmin)
+ *errmin = 1;
+ goto LoadModule_fail;
+ }
+
+ /*
+ * if the module name is not a full pathname, we need to
+ * check the elements in the path
+ */
+ if (PathIsAbsolute(module))
+ found = xstrdup(module);
+ path_elem = pathlist;
+ while (!found && *path_elem != NULL) {
+ found = FindModule(m, *path_elem, subdirlist, patterns);
+ path_elem++;
+ /*
+ * When the module name isn't the canonical name, search for the
+ * former if no match was found for the latter.
+ */
+ if (!*path_elem && m == name) {
+ path_elem = pathlist;
+ m = (char *)module;
+ }
+ }
+
+ /*
+ * did we find the module?
+ */
+ if (!found) {
+ xf86Msg(X_WARNING, "Warning, couldn't open module %s\n", module);
+ if (errmaj)
+ *errmaj = LDR_NOENT;
+ if (errmin)
+ *errmin = 0;
+ goto LoadModule_fail;
+ }
+ ret->handle = LoaderOpen(found, name, 0,
+ errmaj, errmin, &wasLoaded, flags);
+ if (ret->handle < 0)
+ goto LoadModule_fail;
+
+ /* drop any explicit suffix from the module name */
+ p = strchr(name, '.');
+ if (p)
+ *p = '\0';
+
+ /*
+ * now check if the special data object <modulename>ModuleData is
+ * present.
+ */
+ p = malloc(strlen(name) + strlen("ModuleData") + 1);
+ if (!p) {
+ if (errmaj)
+ *errmaj = LDR_NOMEM;
+ if (errmin)
+ *errmin = 0;
+ goto LoadModule_fail;
+ }
+ strcpy(p, name);
+ strcat(p, "ModuleData");
+ initdata = LoaderSymbol(p);
+ if (initdata) {
+ ModuleSetupProc setup;
+ ModuleTearDownProc teardown;
+ XF86ModuleVersionInfo *vers;
+
+ vers = initdata->vers;
+ setup = initdata->setup;
+ teardown = initdata->teardown;
+
+ if (!wasLoaded) {
+ if (vers) {
+ if (!CheckVersion(module, vers, modreq)) {
+ if (errmaj)
+ *errmaj = LDR_MISMATCH;
+ if (errmin)
+ *errmin = 0;
+ goto LoadModule_fail;
+ }
+ } else {
+ xf86Msg(X_ERROR,
+ "LoadModule: Module %s does not supply"
+ " version information\n", module);
+ if (errmaj)
+ *errmaj = LDR_INVALID;
+ if (errmin)
+ *errmin = 0;
+ goto LoadModule_fail;
+ }
+ }
+ if (setup)
+ ret->SetupProc = setup;
+ if (teardown)
+ ret->TearDownProc = teardown;
+ ret->VersionInfo = vers;
+ } else {
+ /* No initdata is OK for external modules */
+ if (options == EXTERN_MODULE)
+ goto LoadModule_exit;
+
+ /* no initdata, fail the load */
+ xf86Msg(X_ERROR, "LoadModule: Module %s does not have a %s "
+ "data object.\n", module, p);
+ if (errmaj)
+ *errmaj = LDR_INVALID;
+ if (errmin)
+ *errmin = 0;
+ goto LoadModule_fail;
+ }
+ if (ret->SetupProc) {
+ ret->TearDownData = ret->SetupProc(ret, options, errmaj, errmin);
+ if (!ret->TearDownData) {
+ goto LoadModule_fail;
+ }
+ } else if (options) {
+ xf86Msg(X_WARNING, "Module Options present, but no SetupProc "
+ "available for %s\n", module);
+ }
+ goto LoadModule_exit;
+
+ LoadModule_fail:
+ UnloadModule(ret);
+ ret = NULL;
+
+ LoadModule_exit:
+ FreePathList(pathlist);
+ FreePatterns(patterns);
+ free(found);
+ free(name);
+ free(p);
+
+ return ret;
+}
+
+/*
+ * LoadModule: load a module
+ *
+ * module The module name. Normally this is not a filename but the
+ * module's "canonical name. A full pathname is, however,
+ * also accepted.
+ * path A comma separated list of module directories.
+ * subdirlist A NULL terminated list of subdirectories to search. When
+ * NULL, the default "stdSubdirs" list is used. The default
+ * list is also substituted for entries with value DEFAULT_LIST.
+ * patternlist A NULL terminated list of regular expressions used to find
+ * module filenames. Each regex should contain exactly one
+ * subexpression that corresponds to the canonical module name.
+ * When NULL, the default "stdPatterns" list is used. The
+ * default list is also substituted for entries with value
+ * DEFAULT_LIST.
+ * options A NULL terminated list of Options that are passed to the
+ * module's SetupProc function.
+ * modreq An optional XF86ModReqInfo* containing
+ * version/ABI/vendor-ABI requirements to check for when
+ * loading the module. The following fields of the
+ * XF86ModReqInfo struct are checked:
+ * majorversion - must match the module's majorversion exactly
+ * minorversion - the module's minorversion must be >= this
+ * patchlevel - the module's minorversion.patchlevel must be
+ * >= this. Patchlevel is ignored when
+ * minorversion is not set.
+ * abiclass - (string) must match the module's abiclass
+ * abiversion - must be consistent with the module's
+ * abiversion (major equal, minor no older)
+ * moduleclass - string must match the module's moduleclass
+ * string
+ * "don't care" values are ~0 for numbers, and NULL for strings
+ * errmaj Major error return.
+ * errmin Minor error return.
+ *
+ */
+ModuleDescPtr
+LoadModule(const char *module, const char *path, const char **subdirlist,
+ const char **patternlist, pointer options,
+ const XF86ModReqInfo * modreq, int *errmaj, int *errmin)
+{
+ return doLoadModule(module, path, subdirlist, patternlist, options,
+ modreq, errmaj, errmin, LD_FLAG_GLOBAL);
+}
+
+void
+UnloadModule(pointer mod)
+{
+ UnloadModuleOrDriver((ModuleDescPtr)mod);
+}
+
+static void
+UnloadModuleOrDriver(ModuleDescPtr mod)
+{
+ if (mod == (ModuleDescPtr) 1)
+ return;
+
+ if (mod == NULL || mod->name == NULL)
+ return;
+
+ xf86MsgVerb(X_INFO, 3, "UnloadModule: \"%s\"\n", mod->name);
+
+ if ((mod->TearDownProc) && (mod->TearDownData))
+ mod->TearDownProc(mod->TearDownData);
+ LoaderUnload(mod->handle);
+
+ if (mod->child)
+ UnloadModuleOrDriver(mod->child);
+ if (mod->sib)
+ UnloadModuleOrDriver(mod->sib);
+ free(mod->name);
+ free(mod);
+}
+
+void
+UnloadSubModule(pointer _mod)
+{
+ ModuleDescPtr mod = (ModuleDescPtr)_mod;
+
+ if (mod == NULL || mod->name == NULL)
+ return;
+
+ xf86MsgVerb(X_INFO, 3, "UnloadSubModule: \"%s\"\n", mod->name);
+
+ if ((mod->TearDownProc) && (mod->TearDownData))
+ mod->TearDownProc(mod->TearDownData);
+ LoaderUnload(mod->handle);
+
+ RemoveChild(mod);
+
+ if (mod->child)
+ UnloadModuleOrDriver(mod->child);
+
+ free(mod->name);
+ free(mod);
+}
+
+static void
+RemoveChild(ModuleDescPtr child)
+{
+ ModuleDescPtr mdp;
+ ModuleDescPtr prevsib;
+ ModuleDescPtr parent;
+
+ if (!child->parent)
+ return;
+
+ parent = child->parent;
+ if (parent->child == child) {
+ parent->child = child->sib;
+ return;
+ }
+
+ prevsib = parent->child;
+ mdp = prevsib->sib;
+ while (mdp && mdp != child) {
+ prevsib = mdp;
+ mdp = mdp->sib;
+ }
+ if (mdp == child)
+ prevsib->sib = child->sib;
+ return;
+}
+
+void
+LoaderErrorMsg(const char *name, const char *modname, int errmaj, int errmin)
+{
+ const char *msg;
+ MessageType type = X_ERROR;
+
+ switch (errmaj) {
+ case LDR_NOERROR:
+ msg = "no error";
+ break;
+ case LDR_NOMEM:
+ msg = "out of memory";
+ break;
+ case LDR_NOENT:
+ msg = "module does not exist";
+ break;
+ case LDR_NOSUBENT:
+ msg = "a required submodule could not be loaded";
+ break;
+ case LDR_NOSPACE:
+ msg = "too many modules";
+ break;
+ case LDR_NOMODOPEN:
+ msg = "open failed";
+ break;
+ case LDR_UNKTYPE:
+ msg = "unknown module type";
+ break;
+ case LDR_NOLOAD:
+ msg = "loader failed";
+ break;
+ case LDR_ONCEONLY:
+ msg = "already loaded";
+ type = X_INFO;
+ break;
+ case LDR_NOPORTOPEN:
+ msg = "port open failed";
+ break;
+ case LDR_NOHARDWARE:
+ msg = "no hardware found";
+ break;
+ case LDR_MISMATCH:
+ msg = "module requirement mismatch";
+ break;
+ case LDR_BADUSAGE:
+ msg = "invalid argument(s) to LoadModule()";
+ break;
+ case LDR_INVALID:
+ msg = "invalid module";
+ break;
+ case LDR_BADOS:
+ msg = "module doesn't support this OS";
+ break;
+ case LDR_MODSPECIFIC:
+ msg = "module-specific error";
+ break;
+ default:
+ msg = "unknown error";
+ }
+ if (name)
+ xf86Msg(type, "%s: Failed to load module \"%s\" (%s, %d)\n",
+ name, modname, msg, errmin);
+ else
+ xf86Msg(type, "Failed to load module \"%s\" (%s, %d)\n",
+ modname, msg, errmin);
+}
+
+/* Given a module path or file name, return the module's canonical name */
+static char *
+LoaderGetCanonicalName(const char *modname, PatternPtr patterns)
+{
+ char *str;
+ const char *s;
+ int len;
+ PatternPtr p;
+ regmatch_t match[2];
+
+ /* Strip off any leading path */
+ s = strrchr(modname, '/');
+ if (s == NULL)
+ s = modname;
+ else
+ s++;
+
+ /* Find the first regex that is matched */
+ for (p = patterns; p->pattern; p++)
+ if (regexec(&p->rex, s, 2, match, 0) == 0 && match[1].rm_so != -1) {
+ len = match[1].rm_eo - match[1].rm_so;
+ str = malloc(len + 1);
+ if (!str)
+ return NULL;
+ strncpy(str, s + match[1].rm_so, len);
+ str[len] = '\0';
+ return str;
+ }
+
+ /* If there is no match, return the whole name minus the leading path */
+ return xstrdup(s);
+}
+
+/*
+ * Return the module version information.
+ */
+unsigned long
+LoaderGetModuleVersion(ModuleDescPtr mod)
+{
+ if (!mod || mod == (ModuleDescPtr) 1 || !mod->VersionInfo)
+ return 0;
+
+ return MODULE_VERSION_NUMERIC(mod->VersionInfo->majorversion,
+ mod->VersionInfo->minorversion,
+ mod->VersionInfo->patchlevel);
+}
diff --git a/xorg-server/hw/xfree86/modes/xf86Crtc.c b/xorg-server/hw/xfree86/modes/xf86Crtc.c
index 1ccaffc10..9dbeea8a5 100644
--- a/xorg-server/hw/xfree86/modes/xf86Crtc.c
+++ b/xorg-server/hw/xfree86/modes/xf86Crtc.c
@@ -1,3201 +1,3201 @@
-/*
- * Copyright © 2006 Keith Packard
- * Copyright © 2008 Red Hat, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. The copyright holders make no representations
- * about the suitability of this software for any purpose. It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS 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>
-#else
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#endif
-
-#include <stddef.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "xf86.h"
-#include "xf86DDC.h"
-#include "xf86Crtc.h"
-#include "xf86Modes.h"
-#include "xf86Priv.h"
-#include "xf86RandR12.h"
-#include "X11/extensions/render.h"
-#include "X11/extensions/dpmsconst.h"
-#include "X11/Xatom.h"
-#include "picturestr.h"
-
-#include "xf86xv.h"
-
-/*
- * Initialize xf86CrtcConfig structure
- */
-
-int xf86CrtcConfigPrivateIndex = -1;
-
-void
-xf86CrtcConfigInit (ScrnInfoPtr scrn,
- const xf86CrtcConfigFuncsRec *funcs)
-{
- xf86CrtcConfigPtr config;
-
- if (xf86CrtcConfigPrivateIndex == -1)
- xf86CrtcConfigPrivateIndex = xf86AllocateScrnInfoPrivateIndex();
- config = xnfcalloc (1, sizeof (xf86CrtcConfigRec));
-
- config->funcs = funcs;
-
- scrn->privates[xf86CrtcConfigPrivateIndex].ptr = config;
-}
-
-void
-xf86CrtcSetSizeRange (ScrnInfoPtr scrn,
- int minWidth, int minHeight,
- int maxWidth, int maxHeight)
-{
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
-
- config->minWidth = minWidth;
- config->minHeight = minHeight;
- config->maxWidth = maxWidth;
- config->maxHeight = maxHeight;
-}
-
-/*
- * Crtc functions
- */
-xf86CrtcPtr
-xf86CrtcCreate (ScrnInfoPtr scrn,
- const xf86CrtcFuncsRec *funcs)
-{
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
- xf86CrtcPtr crtc, *crtcs;
-
- crtc = xcalloc (sizeof (xf86CrtcRec), 1);
- if (!crtc)
- return NULL;
- crtc->version = XF86_CRTC_VERSION;
- crtc->scrn = scrn;
- crtc->funcs = funcs;
-#ifdef RANDR_12_INTERFACE
- crtc->randr_crtc = NULL;
-#endif
- crtc->rotation = RR_Rotate_0;
- crtc->desiredRotation = RR_Rotate_0;
- pixman_transform_init_identity (&crtc->crtc_to_framebuffer);
- pixman_f_transform_init_identity (&crtc->f_crtc_to_framebuffer);
- pixman_f_transform_init_identity (&crtc->f_framebuffer_to_crtc);
- crtc->filter = NULL;
- crtc->params = NULL;
- crtc->nparams = 0;
- crtc->filter_width = 0;
- crtc->filter_height = 0;
- crtc->transform_in_use = FALSE;
- crtc->transformPresent = FALSE;
- crtc->desiredTransformPresent = FALSE;
- memset (&crtc->bounds, '\0', sizeof (crtc->bounds));
-
- /* Preallocate gamma at a sensible size. */
- crtc->gamma_size = 256;
- crtc->gamma_red = malloc(3 * crtc->gamma_size * sizeof (CARD16));
- if (!crtc->gamma_red) {
- xfree (crtc);
- return NULL;
- }
- crtc->gamma_green = crtc->gamma_red + crtc->gamma_size;
- crtc->gamma_blue = crtc->gamma_green + crtc->gamma_size;
-
- if (xf86_config->crtc)
- crtcs = xrealloc (xf86_config->crtc,
- (xf86_config->num_crtc + 1) * sizeof (xf86CrtcPtr));
- else
- crtcs = xalloc ((xf86_config->num_crtc + 1) * sizeof (xf86CrtcPtr));
- if (!crtcs)
- {
- xfree (crtc);
- return NULL;
- }
- xf86_config->crtc = crtcs;
- xf86_config->crtc[xf86_config->num_crtc++] = crtc;
- return crtc;
-}
-
-void
-xf86CrtcDestroy (xf86CrtcPtr crtc)
-{
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
- int c;
-
- (*crtc->funcs->destroy) (crtc);
- for (c = 0; c < xf86_config->num_crtc; c++)
- if (xf86_config->crtc[c] == crtc)
- {
- memmove (&xf86_config->crtc[c],
- &xf86_config->crtc[c+1],
- ((xf86_config->num_crtc - (c + 1)) * sizeof(void*)));
- xf86_config->num_crtc--;
- break;
- }
- if (crtc->params)
- xfree (crtc->params);
- free(crtc->gamma_red);
- xfree (crtc);
-}
-
-
-/**
- * Return whether any outputs are connected to the specified pipe
- */
-
-Bool
-xf86CrtcInUse (xf86CrtcPtr crtc)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- int o;
-
- for (o = 0; o < xf86_config->num_output; o++)
- if (xf86_config->output[o]->crtc == crtc)
- return TRUE;
- return FALSE;
-}
-
-void
-xf86CrtcSetScreenSubpixelOrder (ScreenPtr pScreen)
-{
- int subpixel_order = SubPixelUnknown;
- Bool has_none = FALSE;
- ScrnInfoPtr scrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
- int c, o;
-
- for (c = 0; c < xf86_config->num_crtc; c++)
- {
- xf86CrtcPtr crtc = xf86_config->crtc[c];
-
- for (o = 0; o < xf86_config->num_output; o++)
- {
- xf86OutputPtr output = xf86_config->output[o];
-
- if (output->crtc == crtc)
- {
- switch (output->subpixel_order) {
- case SubPixelNone:
- has_none = TRUE;
- break;
- case SubPixelUnknown:
- break;
- default:
- subpixel_order = output->subpixel_order;
- break;
- }
- }
- if (subpixel_order != SubPixelUnknown)
- break;
- }
- if (subpixel_order != SubPixelUnknown)
- {
- static const int circle[4] = {
- SubPixelHorizontalRGB,
- SubPixelVerticalRGB,
- SubPixelHorizontalBGR,
- SubPixelVerticalBGR,
- };
- int rotate;
- int c;
- for (rotate = 0; rotate < 4; rotate++)
- if (crtc->rotation & (1 << rotate))
- break;
- for (c = 0; c < 4; c++)
- if (circle[c] == subpixel_order)
- break;
- c = (c + rotate) & 0x3;
- if ((crtc->rotation & RR_Reflect_X) && !(c & 1))
- c ^= 2;
- if ((crtc->rotation & RR_Reflect_Y) && (c & 1))
- c ^= 2;
- subpixel_order = circle[c];
- break;
- }
- }
- if (subpixel_order == SubPixelUnknown && has_none)
- subpixel_order = SubPixelNone;
- PictureSetSubpixelOrder (pScreen, subpixel_order);
-}
-
-/**
- * Sets the given video mode on the given crtc
- */
-Bool
-xf86CrtcSetModeTransform (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
- RRTransformPtr transform, int x, int y)
-{
- ScrnInfoPtr scrn = crtc->scrn;
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
- int i;
- Bool ret = FALSE;
- Bool didLock = FALSE;
- DisplayModePtr adjusted_mode;
- DisplayModeRec saved_mode;
- int saved_x, saved_y;
- Rotation saved_rotation;
- RRTransformRec saved_transform;
- Bool saved_transform_present;
-
- crtc->enabled = xf86CrtcInUse (crtc);
-
- /* We only hit this if someone explicitly sends a "disabled" modeset. */
- if (!crtc->enabled)
- {
- /* Check everything for stuff that should be off. */
- xf86DisableUnusedFunctions(scrn);
- return TRUE;
- }
-
- adjusted_mode = xf86DuplicateMode(mode);
-
-
- saved_mode = crtc->mode;
- saved_x = crtc->x;
- saved_y = crtc->y;
- saved_rotation = crtc->rotation;
- if (crtc->transformPresent) {
- RRTransformInit (&saved_transform);
- RRTransformCopy (&saved_transform, &crtc->transform);
- }
- saved_transform_present = crtc->transformPresent;
-
- /* Update crtc values up front so the driver can rely on them for mode
- * setting.
- */
- crtc->mode = *mode;
- crtc->x = x;
- crtc->y = y;
- crtc->rotation = rotation;
- if (transform) {
- RRTransformCopy (&crtc->transform, transform);
- crtc->transformPresent = TRUE;
- } else
- crtc->transformPresent = FALSE;
-
- if (crtc->funcs->set_mode_major) {
- ret = crtc->funcs->set_mode_major(crtc, mode, rotation, x, y);
- goto done;
- }
-
- didLock = crtc->funcs->lock (crtc);
- /* Pass our mode to the outputs and the CRTC to give them a chance to
- * adjust it according to limitations or output properties, and also
- * a chance to reject the mode entirely.
- */
- for (i = 0; i < xf86_config->num_output; i++) {
- xf86OutputPtr output = xf86_config->output[i];
-
- if (output->crtc != crtc)
- continue;
-
- if (!output->funcs->mode_fixup(output, mode, adjusted_mode)) {
- goto done;
- }
- }
-
- if (!crtc->funcs->mode_fixup(crtc, mode, adjusted_mode)) {
- goto done;
- }
-
- if (!xf86CrtcRotate (crtc))
- goto done;
-
- /* Prepare the outputs and CRTCs before setting the mode. */
- for (i = 0; i < xf86_config->num_output; i++) {
- xf86OutputPtr output = xf86_config->output[i];
-
- if (output->crtc != crtc)
- continue;
-
- /* Disable the output as the first thing we do. */
- output->funcs->prepare(output);
- }
-
- crtc->funcs->prepare(crtc);
-
- /* Set up the DPLL and any output state that needs to adjust or depend
- * on the DPLL.
- */
- crtc->funcs->mode_set(crtc, mode, adjusted_mode, crtc->x, crtc->y);
- for (i = 0; i < xf86_config->num_output; i++)
- {
- xf86OutputPtr output = xf86_config->output[i];
- if (output->crtc == crtc)
- output->funcs->mode_set(output, mode, adjusted_mode);
- }
-
- /* Only upload when needed, to avoid unneeded delays. */
- if (!crtc->active && crtc->funcs->gamma_set)
- crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green,
- crtc->gamma_blue, crtc->gamma_size);
-
- /* Now, enable the clocks, plane, pipe, and outputs that we set up. */
- crtc->funcs->commit(crtc);
- for (i = 0; i < xf86_config->num_output; i++)
- {
- xf86OutputPtr output = xf86_config->output[i];
- if (output->crtc == crtc)
- output->funcs->commit(output);
- }
-
- ret = TRUE;
-
-done:
- if (ret) {
- crtc->active = TRUE;
- if (scrn->pScreen)
- xf86CrtcSetScreenSubpixelOrder (scrn->pScreen);
- } else {
- crtc->x = saved_x;
- crtc->y = saved_y;
- crtc->rotation = saved_rotation;
- crtc->mode = saved_mode;
- if (saved_transform_present)
- RRTransformCopy (&crtc->transform, &saved_transform);
- crtc->transformPresent = saved_transform_present;
- }
-
- if (adjusted_mode->name)
- xfree(adjusted_mode->name);
- xfree(adjusted_mode);
-
- if (didLock)
- crtc->funcs->unlock (crtc);
-
- return ret;
-}
-
-/**
- * Sets the given video mode on the given crtc, but without providing
- * a transform
- */
-Bool
-xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
- int x, int y)
-{
- return xf86CrtcSetModeTransform (crtc, mode, rotation, NULL, x, y);
-}
-
-/**
- * Pans the screen, does not change the mode
- */
-void
-xf86CrtcSetOrigin (xf86CrtcPtr crtc, int x, int y)
-{
- crtc->x = x;
- crtc->y = y;
- if (crtc->funcs->set_origin) {
- if (!xf86CrtcRotate (crtc))
- return;
- crtc->funcs->set_origin (crtc, x, y);
- }
- else
- xf86CrtcSetMode (crtc, &crtc->mode, crtc->rotation, x, y);
-}
-
-/*
- * Output functions
- */
-
-extern XF86ConfigPtr xf86configptr;
-
-typedef enum {
- OPTION_PREFERRED_MODE,
- OPTION_POSITION,
- OPTION_BELOW,
- OPTION_RIGHT_OF,
- OPTION_ABOVE,
- OPTION_LEFT_OF,
- OPTION_ENABLE,
- OPTION_DISABLE,
- OPTION_MIN_CLOCK,
- OPTION_MAX_CLOCK,
- OPTION_IGNORE,
- OPTION_ROTATE,
- OPTION_PANNING,
- OPTION_PRIMARY,
-} OutputOpts;
-
-static OptionInfoRec xf86OutputOptions[] = {
- {OPTION_PREFERRED_MODE, "PreferredMode", OPTV_STRING, {0}, FALSE },
- {OPTION_POSITION, "Position", OPTV_STRING, {0}, FALSE },
- {OPTION_BELOW, "Below", OPTV_STRING, {0}, FALSE },
- {OPTION_RIGHT_OF, "RightOf", OPTV_STRING, {0}, FALSE },
- {OPTION_ABOVE, "Above", OPTV_STRING, {0}, FALSE },
- {OPTION_LEFT_OF, "LeftOf", OPTV_STRING, {0}, FALSE },
- {OPTION_ENABLE, "Enable", OPTV_BOOLEAN, {0}, FALSE },
- {OPTION_DISABLE, "Disable", OPTV_BOOLEAN, {0}, FALSE },
- {OPTION_MIN_CLOCK, "MinClock", OPTV_FREQ, {0}, FALSE },
- {OPTION_MAX_CLOCK, "MaxClock", OPTV_FREQ, {0}, FALSE },
- {OPTION_IGNORE, "Ignore", OPTV_BOOLEAN, {0}, FALSE },
- {OPTION_ROTATE, "Rotate", OPTV_STRING, {0}, FALSE },
- {OPTION_PANNING, "Panning", OPTV_STRING, {0}, FALSE },
- {OPTION_PRIMARY, "Primary", OPTV_BOOLEAN, {0}, FALSE },
- {-1, NULL, OPTV_NONE, {0}, FALSE },
-};
-
-enum {
- OPTION_MODEDEBUG,
-};
-
-static OptionInfoRec xf86DeviceOptions[] = {
- {OPTION_MODEDEBUG, "ModeDebug", OPTV_BOOLEAN, {0}, FALSE },
- {-1, NULL, OPTV_NONE, {0}, FALSE },
-};
-
-static void
-xf86OutputSetMonitor (xf86OutputPtr output)
-{
- char *option_name;
- static const char monitor_prefix[] = "monitor-";
- char *monitor;
-
- if (!output->name)
- return;
-
- if (output->options)
- xfree (output->options);
-
- output->options = xnfalloc (sizeof (xf86OutputOptions));
- memcpy (output->options, xf86OutputOptions, sizeof (xf86OutputOptions));
-
- option_name = xnfalloc (strlen (monitor_prefix) +
- strlen (output->name) + 1);
- strcpy (option_name, monitor_prefix);
- strcat (option_name, output->name);
- monitor = xf86findOptionValue (output->scrn->options, option_name);
- if (!monitor)
- monitor = output->name;
- else
- xf86MarkOptionUsedByName (output->scrn->options, option_name);
- xfree (option_name);
- output->conf_monitor = xf86findMonitor (monitor,
- xf86configptr->conf_monitor_lst);
- /*
- * Find the monitor section of the screen and use that
- */
- if (!output->conf_monitor && output->use_screen_monitor)
- output->conf_monitor = xf86findMonitor (output->scrn->monitor->id,
- xf86configptr->conf_monitor_lst);
- if (output->conf_monitor)
- {
- xf86DrvMsg (output->scrn->scrnIndex, X_INFO,
- "Output %s using monitor section %s\n",
- output->name, output->conf_monitor->mon_identifier);
- xf86ProcessOptions (output->scrn->scrnIndex,
- output->conf_monitor->mon_option_lst,
- output->options);
- }
- else
- xf86DrvMsg (output->scrn->scrnIndex, X_INFO,
- "Output %s has no monitor section\n",
- output->name);
-}
-
-static Bool
-xf86OutputEnabled (xf86OutputPtr output, Bool strict)
-{
- Bool enable, disable;
-
- /* check to see if this output was enabled in the config file */
- if (xf86GetOptValBool (output->options, OPTION_ENABLE, &enable) && enable)
- {
- xf86DrvMsg (output->scrn->scrnIndex, X_INFO,
- "Output %s enabled by config file\n", output->name);
- return TRUE;
- }
- /* or if this output was disabled in the config file */
- if (xf86GetOptValBool (output->options, OPTION_DISABLE, &disable) && disable)
- {
- xf86DrvMsg (output->scrn->scrnIndex, X_INFO,
- "Output %s disabled by config file\n", output->name);
- return FALSE;
- }
-
- /* If not, try to only light up the ones we know are connected */
- if (strict) {
- enable = output->status == XF86OutputStatusConnected;
- }
- /* But if that fails, try to light up even outputs we're unsure of */
- else {
- enable = output->status != XF86OutputStatusDisconnected;
- }
-
- xf86DrvMsg (output->scrn->scrnIndex, X_INFO,
- "Output %s %sconnected\n", output->name, enable ? "" : "dis");
- return enable;
-}
-
-static Bool
-xf86OutputIgnored (xf86OutputPtr output)
-{
- return xf86ReturnOptValBool (output->options, OPTION_IGNORE, FALSE);
-}
-
-static char *direction[4] = {
- "normal",
- "left",
- "inverted",
- "right"
-};
-
-static Rotation
-xf86OutputInitialRotation (xf86OutputPtr output)
-{
- char *rotate_name = xf86GetOptValString (output->options,
- OPTION_ROTATE);
- int i;
-
- if (!rotate_name)
- return RR_Rotate_0;
-
- for (i = 0; i < 4; i++)
- if (xf86nameCompare (direction[i], rotate_name) == 0)
- return (1 << i);
- return RR_Rotate_0;
-}
-
-xf86OutputPtr
-xf86OutputCreate (ScrnInfoPtr scrn,
- const xf86OutputFuncsRec *funcs,
- const char *name)
-{
- xf86OutputPtr output, *outputs;
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
- int len;
- Bool primary;
-
- if (name)
- len = strlen (name) + 1;
- else
- len = 0;
-
- output = xcalloc (sizeof (xf86OutputRec) + len, 1);
- if (!output)
- return NULL;
- output->scrn = scrn;
- output->funcs = funcs;
- if (name)
- {
- output->name = (char *) (output + 1);
- strcpy (output->name, name);
- }
- output->subpixel_order = SubPixelUnknown;
- /*
- * Use the old per-screen monitor section for the first output
- */
- output->use_screen_monitor = (xf86_config->num_output == 0);
-#ifdef RANDR_12_INTERFACE
- output->randr_output = NULL;
-#endif
- if (name)
- {
- xf86OutputSetMonitor (output);
- if (xf86OutputIgnored (output))
- {
- xfree (output);
- return FALSE;
- }
- }
-
-
- if (xf86_config->output)
- outputs = xrealloc (xf86_config->output,
- (xf86_config->num_output + 1) * sizeof (xf86OutputPtr));
- else
- outputs = xalloc ((xf86_config->num_output + 1) * sizeof (xf86OutputPtr));
- if (!outputs)
- {
- xfree (output);
- return NULL;
- }
-
- xf86_config->output = outputs;
-
- if (xf86GetOptValBool (output->options, OPTION_PRIMARY, &primary) && primary)
- {
- memmove(xf86_config->output + 1, xf86_config->output,
- xf86_config->num_output * sizeof (xf86OutputPtr));
- xf86_config->output[0] = output;
- }
- else
- {
- xf86_config->output[xf86_config->num_output] = output;
- }
-
- xf86_config->num_output++;
-
- return output;
-}
-
-Bool
-xf86OutputRename (xf86OutputPtr output, const char *name)
-{
- int len = strlen(name) + 1;
- char *newname = xalloc (len);
-
- if (!newname)
- return FALSE; /* so sorry... */
-
- strcpy (newname, name);
- if (output->name && output->name != (char *) (output + 1))
- xfree (output->name);
- output->name = newname;
- xf86OutputSetMonitor (output);
- if (xf86OutputIgnored (output))
- return FALSE;
- return TRUE;
-}
-
-void
-xf86OutputUseScreenMonitor (xf86OutputPtr output, Bool use_screen_monitor)
-{
- if (use_screen_monitor != output->use_screen_monitor)
- {
- output->use_screen_monitor = use_screen_monitor;
- xf86OutputSetMonitor (output);
- }
-}
-
-void
-xf86OutputDestroy (xf86OutputPtr output)
-{
- ScrnInfoPtr scrn = output->scrn;
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
- int o;
-
- (*output->funcs->destroy) (output);
- while (output->probed_modes)
- xf86DeleteMode (&output->probed_modes, output->probed_modes);
- for (o = 0; o < xf86_config->num_output; o++)
- if (xf86_config->output[o] == output)
- {
- memmove (&xf86_config->output[o],
- &xf86_config->output[o+1],
- ((xf86_config->num_output - (o + 1)) * sizeof(void*)));
- xf86_config->num_output--;
- break;
- }
- if (output->name && output->name != (char *) (output + 1))
- xfree (output->name);
- xfree (output);
-}
-
-/*
- * Called during CreateScreenResources to hook up RandR
- */
-static Bool
-xf86CrtcCreateScreenResources (ScreenPtr screen)
-{
- ScrnInfoPtr scrn = xf86Screens[screen->myNum];
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
-
- screen->CreateScreenResources = config->CreateScreenResources;
-
- if (!(*screen->CreateScreenResources)(screen))
- return FALSE;
-
- if (!xf86RandR12CreateScreenResources (screen))
- return FALSE;
-
- return TRUE;
-}
-
-/*
- * Clean up config on server reset
- */
-static Bool
-xf86CrtcCloseScreen (int index, ScreenPtr screen)
-{
- ScrnInfoPtr scrn = xf86Screens[screen->myNum];
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
- int o, c;
-
- screen->CloseScreen = config->CloseScreen;
-
- xf86RotateCloseScreen (screen);
-
- for (o = 0; o < config->num_output; o++)
- {
- xf86OutputPtr output = config->output[o];
-
- output->randr_output = NULL;
- }
- for (c = 0; c < config->num_crtc; c++)
- {
- xf86CrtcPtr crtc = config->crtc[c];
-
- crtc->randr_crtc = NULL;
- }
- return screen->CloseScreen (index, screen);
-}
-
-/*
- * Called at ScreenInit time to set up
- */
-#ifdef RANDR_13_INTERFACE
-int
-#else
-Bool
-#endif
-xf86CrtcScreenInit (ScreenPtr screen)
-{
- ScrnInfoPtr scrn = xf86Screens[screen->myNum];
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
- int c;
-
- /* Rotation */
- xf86DrvMsg(scrn->scrnIndex, X_INFO, "RandR 1.2 enabled, ignore the following RandR disabled message.\n");
- xf86DisableRandR(); /* Disable old RandR extension support */
- xf86RandR12Init (screen);
-
- /* support all rotations if every crtc has the shadow alloc funcs */
- for (c = 0; c < config->num_crtc; c++)
- {
- xf86CrtcPtr crtc = config->crtc[c];
- if (!crtc->funcs->shadow_allocate || !crtc->funcs->shadow_create)
- break;
- }
- if (c == config->num_crtc)
- {
- xf86RandR12SetRotations (screen, RR_Rotate_0 | RR_Rotate_90 |
- RR_Rotate_180 | RR_Rotate_270 |
- RR_Reflect_X | RR_Reflect_Y);
- xf86RandR12SetTransformSupport (screen, TRUE);
- }
- else
- {
- xf86RandR12SetRotations (screen, RR_Rotate_0);
- xf86RandR12SetTransformSupport (screen, FALSE);
- }
-
- /* Wrap CreateScreenResources so we can initialize the RandR code */
- config->CreateScreenResources = screen->CreateScreenResources;
- screen->CreateScreenResources = xf86CrtcCreateScreenResources;
-
- config->CloseScreen = screen->CloseScreen;
- screen->CloseScreen = xf86CrtcCloseScreen;
-
-#ifdef XFreeXDGA
- _xf86_di_dga_init_internal(screen);
-#endif
-#ifdef RANDR_13_INTERFACE
- return RANDR_INTERFACE_VERSION;
-#else
- return TRUE;
-#endif
-}
-
-static DisplayModePtr
-xf86DefaultMode (xf86OutputPtr output, int width, int height)
-{
- DisplayModePtr target_mode = NULL;
- DisplayModePtr mode;
- int target_diff = 0;
- int target_preferred = 0;
- int mm_height;
-
- mm_height = output->mm_height;
- if (!mm_height)
- mm_height = (768 * 25.4) / DEFAULT_DPI;
- /*
- * Pick a mode closest to DEFAULT_DPI
- */
- for (mode = output->probed_modes; mode; mode = mode->next)
- {
- int dpi;
- int preferred = (((mode->type & M_T_PREFERRED) != 0) +
- ((mode->type & M_T_USERPREF) != 0));
- int diff;
-
- if (xf86ModeWidth (mode, output->initial_rotation) > width ||
- xf86ModeHeight (mode, output->initial_rotation) > height)
- continue;
-
- /* yes, use VDisplay here, not xf86ModeHeight */
- dpi = (mode->VDisplay * 254) / (mm_height * 10);
- diff = dpi - DEFAULT_DPI;
- diff = diff < 0 ? -diff : diff;
- if (target_mode == NULL || (preferred > target_preferred) ||
- (preferred == target_preferred && diff < target_diff))
- {
- target_mode = mode;
- target_diff = diff;
- target_preferred = preferred;
- }
- }
- return target_mode;
-}
-
-static DisplayModePtr
-xf86ClosestMode (xf86OutputPtr output,
- DisplayModePtr match, Rotation match_rotation,
- int width, int height)
-{
- DisplayModePtr target_mode = NULL;
- DisplayModePtr mode;
- int target_diff = 0;
-
- /*
- * Pick a mode closest to the specified mode
- */
- for (mode = output->probed_modes; mode; mode = mode->next)
- {
- int dx, dy;
- int diff;
-
- if (xf86ModeWidth (mode, output->initial_rotation) > width ||
- xf86ModeHeight (mode, output->initial_rotation) > height)
- continue;
-
- /* exact matches are preferred */
- if (output->initial_rotation == match_rotation &&
- xf86ModesEqual (mode, match))
- return mode;
-
- dx = xf86ModeWidth (match, match_rotation) - xf86ModeWidth (mode, output->initial_rotation);
- dy = xf86ModeHeight (match, match_rotation) - xf86ModeHeight (mode, output->initial_rotation);
- diff = dx * dx + dy * dy;
- if (target_mode == NULL || diff < target_diff)
- {
- target_mode = mode;
- target_diff = diff;
- }
- }
- return target_mode;
-}
-
-static DisplayModePtr
-xf86OutputHasPreferredMode (xf86OutputPtr output, int width, int height)
-{
- DisplayModePtr mode;
-
- for (mode = output->probed_modes; mode; mode = mode->next)
- {
- if (xf86ModeWidth (mode, output->initial_rotation) > width ||
- xf86ModeHeight (mode, output->initial_rotation) > height)
- continue;
-
- if (mode->type & M_T_PREFERRED)
- return mode;
- }
- return NULL;
-}
-
-static DisplayModePtr
-xf86OutputHasUserPreferredMode (xf86OutputPtr output)
-{
- DisplayModePtr mode, first = output->probed_modes;
-
- for (mode = first; mode && mode->next != first; mode = mode->next)
- if (mode->type & M_T_USERPREF)
- return mode;
-
- return NULL;
-}
-
-static int
-xf86PickCrtcs (ScrnInfoPtr scrn,
- xf86CrtcPtr *best_crtcs,
- DisplayModePtr *modes,
- int n,
- int width,
- int height)
-{
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
- int c, o;
- xf86OutputPtr output;
- xf86CrtcPtr crtc;
- xf86CrtcPtr *crtcs;
- xf86CrtcPtr best_crtc;
- int best_score;
- int score;
- int my_score;
-
- if (n == config->num_output)
- return 0;
- output = config->output[n];
-
- /*
- * Compute score with this output disabled
- */
- best_crtcs[n] = NULL;
- best_crtc = NULL;
- best_score = xf86PickCrtcs (scrn, best_crtcs, modes, n+1, width, height);
- if (modes[n] == NULL)
- return best_score;
-
- crtcs = xalloc (config->num_output * sizeof (xf86CrtcPtr));
- if (!crtcs)
- return best_score;
-
- my_score = 1;
- /* Score outputs that are known to be connected higher */
- if (output->status == XF86OutputStatusConnected)
- my_score++;
- /* Score outputs with preferred modes higher */
- if (xf86OutputHasPreferredMode (output, width, height))
- my_score++;
- /*
- * Select a crtc for this output and
- * then attempt to configure the remaining
- * outputs
- */
- for (c = 0; c < config->num_crtc; c++)
- {
- if ((output->possible_crtcs & (1 << c)) == 0)
- continue;
-
- crtc = config->crtc[c];
- /*
- * Check to see if some other output is
- * using this crtc
- */
- for (o = 0; o < n; o++)
- if (best_crtcs[o] == crtc)
- break;
- if (o < n)
- {
- /*
- * If the two outputs desire the same mode,
- * see if they can be cloned
- */
- if (xf86ModesEqual (modes[o], modes[n]) &&
- config->output[o]->initial_rotation == config->output[n]->initial_rotation &&
- config->output[o]->initial_x == config->output[n]->initial_x &&
- config->output[o]->initial_y == config->output[n]->initial_y)
- {
- if ((output->possible_clones & (1 << o)) == 0)
- continue; /* nope, try next CRTC */
- }
- else
- continue; /* different modes, can't clone */
- }
- crtcs[n] = crtc;
- memcpy (crtcs, best_crtcs, n * sizeof (xf86CrtcPtr));
- score = my_score + xf86PickCrtcs (scrn, crtcs, modes, n+1, width, height);
- if (score > best_score)
- {
- best_crtc = crtc;
- best_score = score;
- memcpy (best_crtcs, crtcs, config->num_output * sizeof (xf86CrtcPtr));
- }
- }
- xfree (crtcs);
- return best_score;
-}
-
-
-/*
- * Compute the virtual size necessary to place all of the available
- * crtcs in the specified configuration.
- *
- * canGrow indicates that the driver can make the screen larger than its initial
- * configuration. If FALSE, this function will enlarge the screen to include
- * the largest available mode.
- */
-
-static void
-xf86DefaultScreenLimits (ScrnInfoPtr scrn, int *widthp, int *heightp,
- Bool canGrow)
-{
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
- int width = 0, height = 0;
- int o;
- int c;
- int s;
-
- for (c = 0; c < config->num_crtc; c++)
- {
- int crtc_width = 0, crtc_height = 0;
- xf86CrtcPtr crtc = config->crtc[c];
-
- if (crtc->enabled)
- {
- crtc_width = crtc->x + xf86ModeWidth (&crtc->desiredMode, crtc->desiredRotation);
- crtc_height = crtc->y + xf86ModeHeight (&crtc->desiredMode, crtc->desiredRotation);
- }
- if (!canGrow) {
- for (o = 0; o < config->num_output; o++)
- {
- xf86OutputPtr output = config->output[o];
-
- for (s = 0; s < config->num_crtc; s++)
- if (output->possible_crtcs & (1 << s))
- {
- DisplayModePtr mode;
- for (mode = output->probed_modes; mode; mode = mode->next)
- {
- if (mode->HDisplay > crtc_width)
- crtc_width = mode->HDisplay;
- if (mode->VDisplay > crtc_width)
- crtc_width = mode->VDisplay;
- if (mode->VDisplay > crtc_height)
- crtc_height = mode->VDisplay;
- if (mode->HDisplay > crtc_height)
- crtc_height = mode->HDisplay;
- }
- }
- }
- }
- if (crtc_width > width)
- width = crtc_width;
- if (crtc_height > height)
- height = crtc_height;
- }
- if (config->maxWidth && width > config->maxWidth) width = config->maxWidth;
- if (config->maxHeight && height > config->maxHeight) height = config->maxHeight;
- if (config->minWidth && width < config->minWidth) width = config->minWidth;
- if (config->minHeight && height < config->minHeight) height = config->minHeight;
- *widthp = width;
- *heightp = height;
-}
-
-#define POSITION_UNSET -100000
-
-/*
- * check if the user configured any outputs at all
- * with either a position or a relative setting or a mode.
- */
-static Bool
-xf86UserConfiguredOutputs(ScrnInfoPtr scrn, DisplayModePtr *modes)
-{
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
- int o;
- Bool user_conf = FALSE;
-
- for (o = 0; o < config->num_output; o++)
- {
- xf86OutputPtr output = config->output[o];
- char *position;
- char *relative_name;
- OutputOpts relation;
- int r;
- static const OutputOpts relations[] = {
- OPTION_BELOW, OPTION_RIGHT_OF, OPTION_ABOVE, OPTION_LEFT_OF
- };
-
- position = xf86GetOptValString (output->options,
- OPTION_POSITION);
- if (position)
- user_conf = TRUE;
-
- relation = 0;
- relative_name = NULL;
- for (r = 0; r < 4; r++)
- {
- relation = relations[r];
- relative_name = xf86GetOptValString (output->options,
- relation);
- if (relative_name)
- break;
- }
- if (relative_name)
- user_conf = TRUE;
-
- modes[o] = xf86OutputHasUserPreferredMode(output);
- if (modes[o])
- user_conf = TRUE;
- }
-
- return user_conf;
-}
-
-static Bool
-xf86InitialOutputPositions (ScrnInfoPtr scrn, DisplayModePtr *modes)
-{
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
- int o;
- int min_x, min_y;
-
- for (o = 0; o < config->num_output; o++)
- {
- xf86OutputPtr output = config->output[o];
-
- output->initial_x = output->initial_y = POSITION_UNSET;
- }
-
- /*
- * Loop until all outputs are set
- */
- for (;;)
- {
- Bool any_set = FALSE;
- Bool keep_going = FALSE;
-
- for (o = 0; o < config->num_output; o++)
- {
- static const OutputOpts relations[] = {
- OPTION_BELOW, OPTION_RIGHT_OF, OPTION_ABOVE, OPTION_LEFT_OF
- };
- xf86OutputPtr output = config->output[o];
- xf86OutputPtr relative;
- char *relative_name;
- char *position;
- OutputOpts relation;
- int r;
-
- if (output->initial_x != POSITION_UNSET)
- continue;
- position = xf86GetOptValString (output->options,
- OPTION_POSITION);
- /*
- * Absolute position wins
- */
- if (position)
- {
- int x, y;
- if (sscanf (position, "%d %d", &x, &y) == 2)
- {
- output->initial_x = x;
- output->initial_y = y;
- }
- else
- {
- xf86DrvMsg (scrn->scrnIndex, X_ERROR,
- "Output %s position not of form \"x y\"\n",
- output->name);
- output->initial_x = output->initial_y = 0;
- }
- any_set = TRUE;
- continue;
- }
- /*
- * Next comes relative positions
- */
- relation = 0;
- relative_name = NULL;
- for (r = 0; r < 4; r++)
- {
- relation = relations[r];
- relative_name = xf86GetOptValString (output->options,
- relation);
- if (relative_name)
- break;
- }
- if (relative_name)
- {
- int or;
- relative = NULL;
- for (or = 0; or < config->num_output; or++)
- {
- xf86OutputPtr out_rel = config->output[or];
- XF86ConfMonitorPtr rel_mon = out_rel->conf_monitor;
-
- if (rel_mon)
- {
- if (xf86nameCompare (rel_mon->mon_identifier,
- relative_name) == 0)
- {
- relative = config->output[or];
- break;
- }
- }
- if (strcmp (out_rel->name, relative_name) == 0)
- {
- relative = config->output[or];
- break;
- }
- }
- if (!relative)
- {
- xf86DrvMsg (scrn->scrnIndex, X_ERROR,
- "Cannot position output %s relative to unknown output %s\n",
- output->name, relative_name);
- output->initial_x = 0;
- output->initial_y = 0;
- any_set = TRUE;
- continue;
- }
- if (!modes[or])
- {
- xf86DrvMsg (scrn->scrnIndex, X_ERROR,
- "Cannot position output %s relative to output %s without modes\n",
- output->name, relative_name);
- output->initial_x = 0;
- output->initial_y = 0;
- any_set = TRUE;
- continue;
- }
- if (relative->initial_x == POSITION_UNSET)
- {
- keep_going = TRUE;
- continue;
- }
- output->initial_x = relative->initial_x;
- output->initial_y = relative->initial_y;
- switch (relation) {
- case OPTION_BELOW:
- output->initial_y += xf86ModeHeight (modes[or], relative->initial_rotation);
- break;
- case OPTION_RIGHT_OF:
- output->initial_x += xf86ModeWidth (modes[or], relative->initial_rotation);
- break;
- case OPTION_ABOVE:
- if (modes[o])
- output->initial_y -= xf86ModeHeight (modes[o], output->initial_rotation);
- break;
- case OPTION_LEFT_OF:
- if (modes[o])
- output->initial_x -= xf86ModeWidth (modes[o], output->initial_rotation);
- break;
- default:
- break;
- }
- any_set = TRUE;
- continue;
- }
-
- /* Nothing set, just stick them at 0,0 */
- output->initial_x = 0;
- output->initial_y = 0;
- any_set = TRUE;
- }
- if (!keep_going)
- break;
- if (!any_set)
- {
- for (o = 0; o < config->num_output; o++)
- {
- xf86OutputPtr output = config->output[o];
- if (output->initial_x == POSITION_UNSET)
- {
- xf86DrvMsg (scrn->scrnIndex, X_ERROR,
- "Output position loop. Moving %s to 0,0\n",
- output->name);
- output->initial_x = output->initial_y = 0;
- break;
- }
- }
- }
- }
-
- /*
- * normalize positions
- */
- min_x = 1000000;
- min_y = 1000000;
- for (o = 0; o < config->num_output; o++)
- {
- xf86OutputPtr output = config->output[o];
-
- if (output->initial_x < min_x)
- min_x = output->initial_x;
- if (output->initial_y < min_y)
- min_y = output->initial_y;
- }
-
- for (o = 0; o < config->num_output; o++)
- {
- xf86OutputPtr output = config->output[o];
-
- output->initial_x -= min_x;
- output->initial_y -= min_y;
- }
- return TRUE;
-}
-
-static void
-xf86InitialPanning (ScrnInfoPtr scrn)
-{
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
- int o;
-
- for (o = 0; o < config->num_output; o++)
- {
- xf86OutputPtr output = config->output[o];
- char *panning = xf86GetOptValString (output->options, OPTION_PANNING);
- int width, height, left, top;
- int track_width, track_height, track_left, track_top;
- int brdr[4];
-
- memset (&output->initialTotalArea, 0, sizeof(BoxRec));
- memset (&output->initialTrackingArea, 0, sizeof(BoxRec));
- memset (output->initialBorder, 0, 4*sizeof(INT16));
-
- if (! panning)
- continue;
-
- switch (sscanf (panning, "%dx%d+%d+%d/%dx%d+%d+%d/%d/%d/%d/%d",
- &width, &height, &left, &top,
- &track_width, &track_height, &track_left, &track_top,
- &brdr[0], &brdr[1], &brdr[2], &brdr[3])) {
- case 12:
- output->initialBorder[0] = brdr[0];
- output->initialBorder[1] = brdr[1];
- output->initialBorder[2] = brdr[2];
- output->initialBorder[3] = brdr[3];
- /* fall through */
- case 8:
- output->initialTrackingArea.x1 = track_left;
- output->initialTrackingArea.y1 = track_top;
- output->initialTrackingArea.x2 = track_left + track_width;
- output->initialTrackingArea.y2 = track_top + track_height;
- /* fall through */
- case 4:
- output->initialTotalArea.x1 = left;
- output->initialTotalArea.y1 = top;
- /* fall through */
- case 2:
- output->initialTotalArea.x2 = output->initialTotalArea.x1 + width;
- output->initialTotalArea.y2 = output->initialTotalArea.y1 + height;
- break;
- default:
- xf86DrvMsg (scrn->scrnIndex, X_ERROR,
- "Broken panning specification '%s' for output %s in config file\n",
- panning, output->name);
- }
- }
-}
-
-/** Return - 0 + if a should be earlier, same or later than b in list
- */
-static int
-xf86ModeCompare (DisplayModePtr a, DisplayModePtr b)
-{
- int diff;
-
- diff = ((b->type & M_T_PREFERRED) != 0) - ((a->type & M_T_PREFERRED) != 0);
- if (diff)
- return diff;
- diff = b->HDisplay * b->VDisplay - a->HDisplay * a->VDisplay;
- if (diff)
- return diff;
- diff = b->Clock - a->Clock;
- return diff;
-}
-
-/**
- * Insertion sort input in-place and return the resulting head
- */
-static DisplayModePtr
-xf86SortModes (DisplayModePtr input)
-{
- DisplayModePtr output = NULL, i, o, n, *op, prev;
-
- /* sort by preferred status and pixel area */
- while (input)
- {
- i = input;
- input = input->next;
- for (op = &output; (o = *op); op = &o->next)
- if (xf86ModeCompare (o, i) > 0)
- break;
- i->next = *op;
- *op = i;
- }
- /* prune identical modes */
- for (o = output; o && (n = o->next); o = n)
- {
- if (!strcmp (o->name, n->name) && xf86ModesEqual (o, n))
- {
- o->next = n->next;
- xfree (n->name);
- xfree (n);
- n = o;
- }
- }
- /* hook up backward links */
- prev = NULL;
- for (o = output; o; o = o->next)
- {
- o->prev = prev;
- prev = o;
- }
- return output;
-}
-
-static char *
-preferredMode(ScrnInfoPtr pScrn, xf86OutputPtr output)
-{
- char *preferred_mode = NULL;
-
- /* Check for a configured preference for a particular mode */
- preferred_mode = xf86GetOptValString (output->options,
- OPTION_PREFERRED_MODE);
- if (preferred_mode)
- return preferred_mode;
-
- if (pScrn->display->modes && *pScrn->display->modes)
- preferred_mode = *pScrn->display->modes;
-
- return preferred_mode;
-}
-
-static void
-GuessRangeFromModes(MonPtr mon, DisplayModePtr mode)
-{
- if (!mon || !mode)
- return;
-
- mon->nHsync = 1;
- mon->hsync[0].lo = 1024.0;
- mon->hsync[0].hi = 0.0;
-
- mon->nVrefresh = 1;
- mon->vrefresh[0].lo = 1024.0;
- mon->vrefresh[0].hi = 0.0;
-
- while (mode) {
- if (!mode->HSync)
- mode->HSync = ((float) mode->Clock ) / ((float) mode->HTotal);
-
- if (!mode->VRefresh)
- mode->VRefresh = (1000.0 * ((float) mode->Clock)) /
- ((float) (mode->HTotal * mode->VTotal));
-
- if (mode->HSync < mon->hsync[0].lo)
- mon->hsync[0].lo = mode->HSync;
-
- if (mode->HSync > mon->hsync[0].hi)
- mon->hsync[0].hi = mode->HSync;
-
- if (mode->VRefresh < mon->vrefresh[0].lo)
- mon->vrefresh[0].lo = mode->VRefresh;
-
- if (mode->VRefresh > mon->vrefresh[0].hi)
- mon->vrefresh[0].hi = mode->VRefresh;
-
- mode = mode->next;
- }
-
- /* stretch out the bottom to fit 640x480@60 */
- if (mon->hsync[0].lo > 31.0)
- mon->hsync[0].lo = 31.0;
- if (mon->vrefresh[0].lo > 58.0)
- mon->vrefresh[0].lo = 58.0;
-}
-
-enum det_monrec_source {
- sync_config, sync_edid, sync_default
-};
-
-struct det_monrec_parameter {
- MonRec *mon_rec;
- int *max_clock;
- Bool set_hsync;
- Bool set_vrefresh;
- enum det_monrec_source *sync_source;
-};
-
-static void handle_detailed_monrec(struct detailed_monitor_section *det_mon,
- void *data)
-{
- enum { sync_config, sync_edid, sync_default };
- struct det_monrec_parameter *p;
- p = (struct det_monrec_parameter *)data;
-
- if (det_mon->type == DS_RANGES) {
- struct monitor_ranges *ranges = &det_mon->section.ranges;
- if (p->set_hsync && ranges->max_h) {
- p->mon_rec->hsync[p->mon_rec->nHsync].lo = ranges->min_h;
- p->mon_rec->hsync[p->mon_rec->nHsync].hi = ranges->max_h;
- p->mon_rec->nHsync++;
- if (*p->sync_source == sync_default)
- *p->sync_source = sync_edid;
- }
- if (p->set_vrefresh && ranges->max_v) {
- p->mon_rec->vrefresh[p->mon_rec->nVrefresh].lo = ranges->min_v;
- p->mon_rec->vrefresh[p->mon_rec->nVrefresh].hi = ranges->max_v;
- p->mon_rec->nVrefresh++;
- if (*p->sync_source == sync_default)
- *p->sync_source = sync_edid;
- }
- if (ranges->max_clock * 1000 > *p->max_clock)
- *p->max_clock = ranges->max_clock * 1000;
- }
-}
-
-void
-xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
-{
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
- int o;
-
- /* When canGrow was TRUE in the initial configuration we have to
- * compare against the maximum values so that we don't drop modes.
- * When canGrow was FALSE, the maximum values would have been clamped
- * anyway.
- */
- if (maxX == 0 || maxY == 0) {
- maxX = config->maxWidth;
- maxY = config->maxHeight;
- }
-
- /* Probe the list of modes for each output. */
- for (o = 0; o < config->num_output; o++)
- {
- xf86OutputPtr output = config->output[o];
- DisplayModePtr mode;
- DisplayModePtr config_modes = NULL, output_modes, default_modes = NULL;
- char *preferred_mode;
- xf86MonPtr edid_monitor;
- XF86ConfMonitorPtr conf_monitor;
- MonRec mon_rec;
- int min_clock = 0;
- int max_clock = 0;
- double clock;
- Bool add_default_modes = TRUE;
- Bool debug_modes = config->debug_modes ||
- xf86Initialising;
- enum det_monrec_source sync_source = sync_default;
-
- while (output->probed_modes != NULL)
- xf86DeleteMode(&output->probed_modes, output->probed_modes);
-
- /*
- * Check connection status
- */
- output->status = (*output->funcs->detect)(output);
-
- if (output->status == XF86OutputStatusDisconnected &&
- !xf86ReturnOptValBool(output->options, OPTION_ENABLE, FALSE))
- {
- xf86OutputSetEDID (output, NULL);
- continue;
- }
-
- memset (&mon_rec, '\0', sizeof (mon_rec));
-
- conf_monitor = output->conf_monitor;
-
- if (conf_monitor)
- {
- int i;
-
- for (i = 0; i < conf_monitor->mon_n_hsync; i++)
- {
- mon_rec.hsync[mon_rec.nHsync].lo = conf_monitor->mon_hsync[i].lo;
- mon_rec.hsync[mon_rec.nHsync].hi = conf_monitor->mon_hsync[i].hi;
- mon_rec.nHsync++;
- sync_source = sync_config;
- }
- for (i = 0; i < conf_monitor->mon_n_vrefresh; i++)
- {
- mon_rec.vrefresh[mon_rec.nVrefresh].lo = conf_monitor->mon_vrefresh[i].lo;
- mon_rec.vrefresh[mon_rec.nVrefresh].hi = conf_monitor->mon_vrefresh[i].hi;
- mon_rec.nVrefresh++;
- sync_source = sync_config;
- }
- config_modes = xf86GetMonitorModes (scrn, conf_monitor);
- }
-
- output_modes = (*output->funcs->get_modes) (output);
-
- edid_monitor = output->MonInfo;
-
- if (edid_monitor)
- {
- struct det_monrec_parameter p;
- struct disp_features *features = &edid_monitor->features;
-
- /* if display is not continuous-frequency, don't add default modes */
- if (!GTF_SUPPORTED(features->msc))
- add_default_modes = FALSE;
-
- p.mon_rec = &mon_rec;
- p.max_clock = &max_clock;
- p.set_hsync = mon_rec.nHsync == 0;
- p.set_vrefresh = mon_rec.nVrefresh == 0;
- p.sync_source = &sync_source;
-
- xf86ForEachDetailedBlock(edid_monitor,
- handle_detailed_monrec,
- &p);
- }
-
- if (xf86GetOptValFreq (output->options, OPTION_MIN_CLOCK,
- OPTUNITS_KHZ, &clock))
- min_clock = (int) clock;
- if (xf86GetOptValFreq (output->options, OPTION_MAX_CLOCK,
- OPTUNITS_KHZ, &clock))
- max_clock = (int) clock;
-
- /* If we still don't have a sync range, guess wildly */
- if (!mon_rec.nHsync || !mon_rec.nVrefresh)
- GuessRangeFromModes(&mon_rec, output_modes);
-
- /*
- * These limits will end up setting a 1024x768@60Hz mode by default,
- * which seems like a fairly good mode to use when nothing else is
- * specified
- */
- if (mon_rec.nHsync == 0)
- {
- mon_rec.hsync[0].lo = 31.0;
- mon_rec.hsync[0].hi = 55.0;
- mon_rec.nHsync = 1;
- }
- if (mon_rec.nVrefresh == 0)
- {
- mon_rec.vrefresh[0].lo = 58.0;
- mon_rec.vrefresh[0].hi = 62.0;
- mon_rec.nVrefresh = 1;
- }
-
- if (add_default_modes)
- default_modes = xf86GetDefaultModes ();
-
- /*
- * If this is not an RB monitor, remove RB modes from the default
- * pool. RB modes from the config or the monitor itself are fine.
- */
- if (!mon_rec.reducedblanking)
- xf86ValidateModesReducedBlanking (scrn, default_modes);
-
- if (sync_source == sync_config)
- {
- /*
- * Check output and config modes against sync range from config file
- */
- xf86ValidateModesSync (scrn, output_modes, &mon_rec);
- xf86ValidateModesSync (scrn, config_modes, &mon_rec);
- }
- /*
- * Check default modes against sync range
- */
- xf86ValidateModesSync (scrn, default_modes, &mon_rec);
- /*
- * Check default modes against monitor max clock
- */
- if (max_clock) {
- xf86ValidateModesClocks(scrn, default_modes,
- &min_clock, &max_clock, 1);
- xf86ValidateModesClocks(scrn, output_modes,
- &min_clock, &max_clock, 1);
- }
-
- output->probed_modes = NULL;
- output->probed_modes = xf86ModesAdd (output->probed_modes, config_modes);
- output->probed_modes = xf86ModesAdd (output->probed_modes, output_modes);
- output->probed_modes = xf86ModesAdd (output->probed_modes, default_modes);
-
- /*
- * Check all modes against max size, interlace, and doublescan
- */
- if (maxX && maxY)
- xf86ValidateModesSize (scrn, output->probed_modes,
- maxX, maxY, 0);
-
- {
- int flags = (output->interlaceAllowed ? V_INTERLACE : 0) |
- (output->doubleScanAllowed ? V_DBLSCAN : 0);
- xf86ValidateModesFlags (scrn, output->probed_modes, flags);
- }
-
- /*
- * Check all modes against output
- */
- for (mode = output->probed_modes; mode != NULL; mode = mode->next)
- if (mode->status == MODE_OK)
- mode->status = (*output->funcs->mode_valid)(output, mode);
-
- xf86PruneInvalidModes(scrn, &output->probed_modes, debug_modes);
-
- output->probed_modes = xf86SortModes (output->probed_modes);
-
- /* Check for a configured preference for a particular mode */
- preferred_mode = preferredMode(scrn, output);
-
- if (preferred_mode)
- {
- for (mode = output->probed_modes; mode; mode = mode->next)
- {
- if (!strcmp (preferred_mode, mode->name))
- {
- if (mode != output->probed_modes)
- {
- if (mode->prev)
- mode->prev->next = mode->next;
- if (mode->next)
- mode->next->prev = mode->prev;
- mode->next = output->probed_modes;
- output->probed_modes->prev = mode;
- mode->prev = NULL;
- output->probed_modes = mode;
- }
- mode->type |= (M_T_PREFERRED|M_T_USERPREF);
- break;
- }
- }
- }
-
- output->initial_rotation = xf86OutputInitialRotation (output);
-
- if (debug_modes) {
- if (output->probed_modes != NULL) {
- xf86DrvMsg(scrn->scrnIndex, X_INFO,
- "Printing probed modes for output %s\n",
- output->name);
- } else {
- xf86DrvMsg(scrn->scrnIndex, X_INFO,
- "No remaining probed modes for output %s\n",
- output->name);
- }
- }
- for (mode = output->probed_modes; mode != NULL; mode = mode->next)
- {
- /* The code to choose the best mode per pipe later on will require
- * VRefresh to be set.
- */
- mode->VRefresh = xf86ModeVRefresh(mode);
- xf86SetModeCrtc(mode, INTERLACE_HALVE_V);
-
- if (debug_modes)
- xf86PrintModeline(scrn->scrnIndex, mode);
- }
- }
-}
-
-
-/**
- * Copy one of the output mode lists to the ScrnInfo record
- */
-
-/* XXX where does this function belong? Here? */
-void
-xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr scrn, int *x, int *y);
-
-static DisplayModePtr
-biggestMode(DisplayModePtr a, DisplayModePtr b)
-{
- int A, B;
-
- if (!a)
- return b;
- if (!b)
- return a;
-
- A = a->HDisplay * a->VDisplay;
- B = b->HDisplay * b->VDisplay;
-
- if (A > B)
- return a;
-
- return b;
-}
-
-static xf86OutputPtr
-SetCompatOutput(xf86CrtcConfigPtr config)
-{
- xf86OutputPtr output = NULL, test = NULL;
- DisplayModePtr maxmode = NULL, testmode, mode;
- int o, compat = -1, count, mincount = 0;
-
- /* Look for one that's definitely connected */
- for (o = 0; o < config->num_output; o++)
- {
- test = config->output[o];
- if (!test->crtc)
- continue;
- if (test->status != XF86OutputStatusConnected)
- continue;
- if (!test->probed_modes)
- continue;
-
- testmode = mode = test->probed_modes;
- for (count = 0; mode; mode = mode->next, count++)
- testmode = biggestMode(testmode, mode);
-
- if (!output) {
- output = test;
- compat = o;
- maxmode = testmode;
- mincount = count;
- } else if (maxmode == biggestMode(maxmode, testmode)) {
- output = test;
- compat = o;
- maxmode = testmode;
- mincount = count;
- } else if ((maxmode->HDisplay == testmode->HDisplay) &&
- (maxmode->VDisplay == testmode->VDisplay) &&
- count <= mincount) {
- output = test;
- compat = o;
- maxmode = testmode;
- mincount = count;
- }
- }
-
- /* If we didn't find one, take anything we can get */
- if (!output)
- {
- for (o = 0; o < config->num_output; o++)
- {
- test = config->output[o];
- if (!test->crtc)
- continue;
- if (!test->probed_modes)
- continue;
-
- if (!output) {
- output = test;
- compat = o;
- } else if (test->probed_modes->HDisplay < output->probed_modes->HDisplay) {
- output = test;
- compat = o;
- }
- }
- }
-
- if (compat >= 0) {
- config->compat_output = compat;
- } else {
- /* Don't change the compat output when no valid outputs found */
- output = config->output[config->compat_output];
- }
-
- return output;
-}
-
-void
-xf86SetScrnInfoModes (ScrnInfoPtr scrn)
-{
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
- xf86OutputPtr output;
- xf86CrtcPtr crtc;
- DisplayModePtr last, mode = NULL;
-
- output = SetCompatOutput(config);
-
- if (!output)
- return; /* punt */
-
- crtc = output->crtc;
-
- /* Clear any existing modes from scrn->modes */
- while (scrn->modes != NULL)
- xf86DeleteMode(&scrn->modes, scrn->modes);
-
- /* Set scrn->modes to the mode list for the 'compat' output */
- scrn->modes = xf86DuplicateModes(scrn, output->probed_modes);
-
- if (crtc) {
- for (mode = scrn->modes; mode; mode = mode->next)
- if (xf86ModesEqual (mode, &crtc->desiredMode))
- break;
- }
-
- if (scrn->modes != NULL) {
- /* For some reason, scrn->modes is circular, unlike the other mode
- * lists. How great is that?
- */
- for (last = scrn->modes; last && last->next; last = last->next)
- ;
- last->next = scrn->modes;
- scrn->modes->prev = last;
- if (mode) {
- while (scrn->modes != mode)
- scrn->modes = scrn->modes->next;
- }
- }
- scrn->currentMode = scrn->modes;
-#ifdef XFreeXDGA
- if (scrn->pScreen)
- _xf86_di_dga_reinit_internal(scrn->pScreen);
-#endif
-}
-
-static void
-xf86CollectEnabledOutputs(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
- Bool *enabled)
-{
- Bool any_enabled = FALSE;
- int o;
-
- for (o = 0; o < config->num_output; o++)
- any_enabled |= enabled[o] = xf86OutputEnabled(config->output[o], TRUE);
-
- if (!any_enabled) {
- xf86DrvMsg(scrn->scrnIndex, X_WARNING,
- "No outputs definitely connected, trying again...\n");
-
- for (o = 0; o < config->num_output; o++)
- enabled[o] = xf86OutputEnabled(config->output[o], FALSE);
- }
-}
-
-static Bool
-nextEnabledOutput(xf86CrtcConfigPtr config, Bool *enabled, int *index)
-{
- int o = *index;
-
- for (o++; o < config->num_output; o++) {
- if (enabled[o]) {
- *index = o;
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-static Bool
-aspectMatch(float a, float b)
-{
- return fabs(1 - (a / b)) < 0.05;
-}
-
-static DisplayModePtr
-nextAspectMode(xf86OutputPtr o, DisplayModePtr last, float aspect)
-{
- DisplayModePtr m = NULL;
-
- if (!o)
- return NULL;
-
- if (!last)
- m = o->probed_modes;
- else
- m = last->next;
-
- for (; m; m = m->next)
- if (aspectMatch(aspect, (float)m->HDisplay / (float)m->VDisplay))
- return m;
-
- return NULL;
-}
-
-static DisplayModePtr
-bestModeForAspect(xf86CrtcConfigPtr config, Bool *enabled, float aspect)
-{
- int o = -1, p;
- DisplayModePtr mode = NULL, test = NULL, match = NULL;
-
- if (!nextEnabledOutput(config, enabled, &o))
- return NULL;
- while ((mode = nextAspectMode(config->output[o], mode, aspect))) {
- test = mode;
- for (p = o; nextEnabledOutput(config, enabled, &p); ) {
- test = xf86OutputFindClosestMode(config->output[p], mode);
- if (!test)
- break;
- if (test->HDisplay != mode->HDisplay ||
- test->VDisplay != mode->VDisplay) {
- test = NULL;
- break;
- }
- }
-
- /* if we didn't match it on all outputs, try the next one */
- if (!test)
- continue;
-
- /* if it's bigger than the last one, save it */
- if (!match || (test->HDisplay > match->HDisplay))
- match = test;
- }
-
- /* return the biggest one found */
- return match;
-}
-
-static Bool
-xf86TargetPreferred(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
- DisplayModePtr *modes, Bool *enabled,
- int width, int height)
-{
- int o, p;
- int max_pref_width = 0, max_pref_height = 0;
- DisplayModePtr *preferred, *preferred_match;
- Bool ret = FALSE;
-
- preferred = xnfcalloc(config->num_output, sizeof(DisplayModePtr));
- preferred_match = xnfcalloc(config->num_output, sizeof(DisplayModePtr));
-
- /* Check if the preferred mode is available on all outputs */
- for (p = -1; nextEnabledOutput(config, enabled, &p); ) {
- Rotation r = config->output[p]->initial_rotation;
- DisplayModePtr mode;
- if ((preferred[p] = xf86OutputHasPreferredMode(config->output[p],
- width, height))) {
- int pref_width = xf86ModeWidth(preferred[p], r);
- int pref_height = xf86ModeHeight(preferred[p], r);
- Bool all_match = TRUE;
-
- for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
- Bool match = FALSE;
- xf86OutputPtr output = config->output[o];
- if (o == p)
- continue;
-
- for (mode = output->probed_modes; mode; mode = mode->next) {
- Rotation r = output->initial_rotation;
- if (xf86ModeWidth(mode, r) == pref_width &&
- xf86ModeHeight(mode, r) == pref_height) {
- preferred[o] = mode;
- match = TRUE;
- }
- }
-
- all_match &= match;
- }
-
- if (all_match &&
- (pref_width*pref_height > max_pref_width*max_pref_height)) {
- for (o = -1; nextEnabledOutput(config, enabled, &o); )
- preferred_match[o] = preferred[o];
- max_pref_width = pref_width;
- max_pref_height = pref_height;
- ret = TRUE;
- }
- }
- }
-
- /*
- * If there's no preferred mode, but only one monitor, pick the
- * biggest mode for its aspect ratio, assuming one exists.
- */
- if (!ret) do {
- int i = 0;
- float aspect = 0.0;
-
- /* count the number of enabled outputs */
- for (i = 0, p = -1; nextEnabledOutput(config, enabled, &p); i++) ;
-
- if (i != 1)
- break;
-
- p = -1;
- nextEnabledOutput(config, enabled, &p);
- if (config->output[p]->mm_height)
- aspect = (float)config->output[p]->mm_width /
- (float)config->output[p]->mm_height;
-
- if (aspect)
- preferred_match[p] = bestModeForAspect(config, enabled, aspect);
-
- if (preferred_match[p])
- ret = TRUE;
-
- } while (0);
-
- if (ret) {
- /* oh good, there is a match. stash the selected modes and return. */
- memcpy(modes, preferred_match,
- config->num_output * sizeof(DisplayModePtr));
- }
-
- xfree(preferred);
- xfree(preferred_match);
- return ret;
-}
-
-static Bool
-xf86TargetAspect(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
- DisplayModePtr *modes, Bool *enabled,
- int width, int height)
-{
- int o;
- float aspect = 0.0, *aspects;
- xf86OutputPtr output;
- Bool ret = FALSE;
- DisplayModePtr guess = NULL, aspect_guess = NULL, base_guess = NULL;
-
- aspects = xnfcalloc(config->num_output, sizeof(float));
-
- /* collect the aspect ratios */
- for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
- output = config->output[o];
- if (output->mm_height)
- aspects[o] = (float)output->mm_width / (float)output->mm_height;
- else
- aspects[o] = 4.0 / 3.0;
- }
-
- /* check that they're all the same */
- for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
- output = config->output[o];
- if (!aspect) {
- aspect = aspects[o];
- } else if (!aspectMatch(aspect, aspects[o])) {
- goto no_aspect_match;
- }
- }
-
- /* if they're all 4:3, just skip ahead and save effort */
- if (!aspectMatch(aspect, 4.0/3.0))
- aspect_guess = bestModeForAspect(config, enabled, aspect);
-
-no_aspect_match:
- base_guess = bestModeForAspect(config, enabled, 4.0/3.0);
-
- guess = biggestMode(base_guess, aspect_guess);
-
- if (!guess)
- goto out;
-
- /* found a mode that works everywhere, now apply it */
- for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
- modes[o] = xf86OutputFindClosestMode(config->output[o], guess);
- }
- ret = TRUE;
-
-out:
- xfree(aspects);
- return ret;
-}
-
-static Bool
-xf86TargetFallback(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
- DisplayModePtr *modes, Bool *enabled,
- int width, int height)
-{
- DisplayModePtr target_mode = NULL;
- Rotation target_rotation = RR_Rotate_0;
- DisplayModePtr default_mode;
- int default_preferred, target_preferred = 0, o;
-
- /* User preferred > preferred > other modes */
- for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
- default_mode = xf86DefaultMode (config->output[o], width, height);
- if (!default_mode)
- continue;
-
- default_preferred = (((default_mode->type & M_T_PREFERRED) != 0) +
- ((default_mode->type & M_T_USERPREF) != 0));
-
- if (default_preferred > target_preferred || !target_mode) {
- target_mode = default_mode;
- target_preferred = default_preferred;
- target_rotation = config->output[o]->initial_rotation;
- config->compat_output = o;
- }
- }
-
- if (target_mode)
- modes[config->compat_output] = target_mode;
-
- /* Fill in other output modes */
- for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
- if (!modes[o])
- modes[o] = xf86ClosestMode(config->output[o], target_mode,
- target_rotation, width, height);
- }
-
- return (target_mode != NULL);
-}
-
-static Bool
-xf86TargetUserpref(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
- DisplayModePtr *modes, Bool *enabled,
- int width, int height)
-{
- int o;
-
- if (xf86UserConfiguredOutputs(scrn, modes))
- return xf86TargetFallback(scrn, config, modes, enabled, width, height);
-
- for (o = -1; nextEnabledOutput(config, enabled, &o); )
- if (xf86OutputHasUserPreferredMode(config->output[o]))
- return
- xf86TargetFallback(scrn, config, modes, enabled, width, height);
-
- return FALSE;
-}
-
-static Bool
-xf86CrtcSetInitialGamma(xf86CrtcPtr crtc, float gamma_red, float gamma_green,
- float gamma_blue)
-{
- int i, size = 256;
- CARD16 *red, *green, *blue;
-
- red = malloc(3 * size * sizeof(CARD16));
- green = red + size;
- blue = green + size;
-
- /* Only cause warning if user wanted gamma to be set. */
- if (!crtc->funcs->gamma_set && (gamma_red != 1.0 || gamma_green != 1.0 || gamma_blue != 1.0)) {
- free(red);
- return FALSE;
- } else if (!crtc->funcs->gamma_set) {
- free(red);
- return TRUE;
- }
-
- /* At this early stage none of the randr-interface stuff is up.
- * So take the default gamma size for lack of something better.
- */
- for (i = 0; i < size; i++) {
- if (gamma_red == 1.0)
- red[i] = i << 8;
- else
- red[i] = (CARD16)(pow((double)i/(double)(size - 1),
- 1. / (double)gamma_red) * (double)(size - 1) * 256);
-
- if (gamma_green == 1.0)
- green[i] = i << 8;
- else
- green[i] = (CARD16)(pow((double)i/(double)(size - 1),
- 1. / (double)gamma_green) * (double)(size - 1) * 256);
-
- if (gamma_blue == 1.0)
- blue[i] = i << 8;
- else
- blue[i] = (CARD16)(pow((double)i/(double)(size - 1),
- 1. / (double)gamma_blue) * (double)(size - 1) * 256);
- }
-
- /* Default size is 256, so anything else is failure. */
- if (size != crtc->gamma_size) {
- free(red);
- return FALSE;
- }
-
- crtc->gamma_size = size;
- memcpy (crtc->gamma_red, red, crtc->gamma_size * sizeof (CARD16));
- memcpy (crtc->gamma_green, green, crtc->gamma_size * sizeof (CARD16));
- memcpy (crtc->gamma_blue, blue, crtc->gamma_size * sizeof (CARD16));
-
- /* Do not set gamma now, delay until the crtc is activated. */
-
- free(red);
-
- return TRUE;
-}
-
-static Bool
-xf86OutputSetInitialGamma(xf86OutputPtr output)
-{
- XF86ConfMonitorPtr mon = output->conf_monitor;
- float gamma_red = 1.0, gamma_green = 1.0, gamma_blue = 1.0;
-
- if (!mon)
- return TRUE;
-
- if (!output->crtc)
- return FALSE;
-
- /* Get configured values, where they exist. */
- if (mon->mon_gamma_red >= GAMMA_MIN &&
- mon->mon_gamma_red <= GAMMA_MAX)
- gamma_red = mon->mon_gamma_red;
-
- if (mon->mon_gamma_green >= GAMMA_MIN &&
- mon->mon_gamma_green <= GAMMA_MAX)
- gamma_green = mon->mon_gamma_green;
-
- if (mon->mon_gamma_blue >= GAMMA_MIN &&
- mon->mon_gamma_blue <= GAMMA_MAX)
- gamma_blue = mon->mon_gamma_blue;
-
- /* This avoids setting gamma 1.0 in case another cloned output on this crtc has a specific gamma. */
- if (gamma_red != 1.0 || gamma_green != 1.0 || gamma_blue != 1.0) {
- xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "Output %s wants gamma correction (%.1f, %.1f, %.1f)\n", output->name, gamma_red, gamma_green, gamma_blue);
- return xf86CrtcSetInitialGamma(output->crtc, gamma_red, gamma_green, gamma_blue);
- }else
- return TRUE;
-}
-
-/**
- * Construct default screen configuration
- *
- * Given auto-detected (and, eventually, configured) values,
- * construct a usable configuration for the system
- *
- * canGrow indicates that the driver can resize the screen to larger than its
- * initially configured size via the config->funcs->resize hook. If TRUE, this
- * function will set virtualX and virtualY to match the initial configuration
- * and leave config->max{Width,Height} alone. If FALSE, it will bloat
- * virtual[XY] to include the largest modes and set config->max{Width,Height}
- * accordingly.
- */
-
-Bool
-xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow)
-{
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
- int o, c;
- xf86CrtcPtr *crtcs;
- DisplayModePtr *modes;
- Bool *enabled;
- int width, height;
- int i = scrn->scrnIndex;
-
- /* Set up the device options */
- config->options = xnfalloc (sizeof (xf86DeviceOptions));
- memcpy (config->options, xf86DeviceOptions, sizeof (xf86DeviceOptions));
- xf86ProcessOptions (scrn->scrnIndex,
- scrn->options,
- config->options);
- config->debug_modes = xf86ReturnOptValBool (config->options,
- OPTION_MODEDEBUG, FALSE);
-
- if (scrn->display->virtualX)
- width = scrn->display->virtualX;
- else
- width = config->maxWidth;
- if (scrn->display->virtualY)
- height = scrn->display->virtualY;
- else
- height = config->maxHeight;
-
- xf86ProbeOutputModes (scrn, width, height);
-
- crtcs = xnfcalloc (config->num_output, sizeof (xf86CrtcPtr));
- modes = xnfcalloc (config->num_output, sizeof (DisplayModePtr));
- enabled = xnfcalloc (config->num_output, sizeof (Bool));
-
- xf86CollectEnabledOutputs(scrn, config, enabled);
-
- if (xf86TargetUserpref(scrn, config, modes, enabled, width, height))
- xf86DrvMsg(i, X_INFO, "Using user preference for initial modes\n");
- else if (xf86TargetPreferred(scrn, config, modes, enabled, width, height))
- xf86DrvMsg(i, X_INFO, "Using exact sizes for initial modes\n");
- else if (xf86TargetAspect(scrn, config, modes, enabled, width, height))
- xf86DrvMsg(i, X_INFO, "Using fuzzy aspect match for initial modes\n");
- else if (xf86TargetFallback(scrn, config, modes, enabled, width, height))
- xf86DrvMsg(i, X_INFO, "Using sloppy heuristic for initial modes\n");
- else
- xf86DrvMsg(i, X_WARNING, "Unable to find initial modes\n");
-
- for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
- if (!modes[o])
- xf86DrvMsg (scrn->scrnIndex, X_ERROR,
- "Output %s enabled but has no modes\n",
- config->output[o]->name);
- else
- xf86DrvMsg (scrn->scrnIndex, X_INFO,
- "Output %s using initial mode %s\n",
- config->output[o]->name, modes[o]->name);
- }
-
- /*
- * Set the position of each output
- */
- if (!xf86InitialOutputPositions (scrn, modes))
- {
- xfree (crtcs);
- xfree (modes);
- return FALSE;
- }
-
- /*
- * Set initial panning of each output
- */
- xf86InitialPanning (scrn);
-
- /*
- * Assign CRTCs to fit output configuration
- */
- if (!xf86PickCrtcs (scrn, crtcs, modes, 0, width, height))
- {
- xfree (crtcs);
- xfree (modes);
- return FALSE;
- }
-
- /* XXX override xf86 common frame computation code */
-
- scrn->display->frameX0 = 0;
- scrn->display->frameY0 = 0;
-
- for (c = 0; c < config->num_crtc; c++)
- {
- xf86CrtcPtr crtc = config->crtc[c];
-
- crtc->enabled = FALSE;
- memset (&crtc->desiredMode, '\0', sizeof (crtc->desiredMode));
- /* Set default gamma for all crtc's. */
- /* This is done to avoid problems later on with cloned outputs. */
- xf86CrtcSetInitialGamma(crtc, 1.0, 1.0, 1.0);
- }
-
- if (xf86_crtc_supports_gamma(scrn))
- xf86DrvMsg(scrn->scrnIndex, X_INFO, "Using default gamma of (1.0, 1.0, 1.0) unless otherwise stated.\n");
-
- /*
- * Set initial configuration
- */
- for (o = 0; o < config->num_output; o++)
- {
- xf86OutputPtr output = config->output[o];
- DisplayModePtr mode = modes[o];
- xf86CrtcPtr crtc = crtcs[o];
-
- if (mode && crtc)
- {
- crtc->desiredMode = *mode;
- crtc->desiredRotation = output->initial_rotation;
- crtc->desiredX = output->initial_x;
- crtc->desiredY = output->initial_y;
- crtc->desiredTransformPresent = FALSE;
- crtc->enabled = TRUE;
- memcpy (&crtc->panningTotalArea, &output->initialTotalArea, sizeof(BoxRec));
- memcpy (&crtc->panningTrackingArea, &output->initialTrackingArea, sizeof(BoxRec));
- memcpy (crtc->panningBorder, output->initialBorder, 4*sizeof(INT16));
- output->crtc = crtc;
- if (!xf86OutputSetInitialGamma(output))
- xf86DrvMsg (scrn->scrnIndex, X_WARNING, "Initial gamma correction for output %s: failed.\n", output->name);
- } else {
- output->crtc = NULL;
- }
- }
-
- if (scrn->display->virtualX == 0)
- {
- /*
- * Expand virtual size to cover the current config and potential mode
- * switches, if the driver can't enlarge the screen later.
- */
- xf86DefaultScreenLimits (scrn, &width, &height, canGrow);
-
- scrn->display->virtualX = width;
- scrn->display->virtualY = height;
- }
-
- if (width > scrn->virtualX)
- scrn->virtualX = width;
- if (height > scrn->virtualY)
- scrn->virtualY = height;
-
- /*
- * Make sure the configuration isn't too small.
- */
- if (width < config->minWidth || height < config->minHeight)
- return FALSE;
-
- /*
- * Limit the crtc config to virtual[XY] if the driver can't grow the
- * desktop.
- */
- if (!canGrow)
- {
- xf86CrtcSetSizeRange (scrn, config->minWidth, config->minHeight,
- width, height);
- }
-
- /* Mirror output modes to scrn mode list */
- xf86SetScrnInfoModes (scrn);
-
- xfree (crtcs);
- xfree (modes);
- return TRUE;
-}
-
-/*
- * Check the CRTC we're going to map each output to vs. it's current
- * CRTC. If they don't match, we have to disable the output and the CRTC
- * since the driver will have to re-route things.
- */
-static void
-xf86PrepareOutputs (ScrnInfoPtr scrn)
-{
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
- int o;
-
- for (o = 0; o < config->num_output; o++) {
- xf86OutputPtr output = config->output[o];
-#if RANDR_GET_CRTC_INTERFACE
- /* Disable outputs that are unused or will be re-routed */
- if (!output->funcs->get_crtc ||
- output->crtc != (*output->funcs->get_crtc)(output) ||
- output->crtc == NULL)
-#endif
- (*output->funcs->dpms)(output, DPMSModeOff);
- }
-}
-
-static void
-xf86PrepareCrtcs (ScrnInfoPtr scrn)
-{
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
- int c;
-
- for (c = 0; c < config->num_crtc; c++) {
-#if RANDR_GET_CRTC_INTERFACE
- xf86CrtcPtr crtc = config->crtc[c];
- xf86OutputPtr output = NULL;
- uint32_t desired_outputs = 0, current_outputs = 0;
- int o;
-
- for (o = 0; o < config->num_output; o++) {
- output = config->output[o];
- if (output->crtc == crtc)
- desired_outputs |= (1<<o);
- /* If we can't tell where it's mapped, force it off */
- if (!output->funcs->get_crtc) {
- desired_outputs = 0;
- break;
- }
- if ((*output->funcs->get_crtc)(output) == crtc)
- current_outputs |= (1<<o);
- }
-
- /*
- * If mappings are different or the CRTC is unused,
- * we need to disable it
- */
- if (desired_outputs != current_outputs ||
- !desired_outputs)
- (*crtc->funcs->dpms)(crtc, DPMSModeOff);
-#else
- (*crtc->funcs->dpms)(crtc, DPMSModeOff);
-#endif
- }
-}
-
-/*
- * Using the desired mode information in each crtc, set
- * modes (used in EnterVT functions, or at server startup)
- */
-
-Bool
-xf86SetDesiredModes (ScrnInfoPtr scrn)
-{
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
- xf86CrtcPtr crtc = config->crtc[0];
- int c;
-
- /* A driver with this hook will take care of this */
- if (!crtc->funcs->set_mode_major) {
- xf86PrepareOutputs(scrn);
- xf86PrepareCrtcs(scrn);
- }
-
- for (c = 0; c < config->num_crtc; c++)
- {
- xf86OutputPtr output = NULL;
- int o;
- RRTransformPtr transform;
-
- crtc = config->crtc[c];
-
- /* Skip disabled CRTCs */
- if (!crtc->enabled)
- continue;
-
- if (xf86CompatOutput(scrn) && xf86CompatCrtc(scrn) == crtc)
- output = xf86CompatOutput(scrn);
- else
- {
- for (o = 0; o < config->num_output; o++)
- if (config->output[o]->crtc == crtc)
- {
- output = config->output[o];
- break;
- }
- }
- /* paranoia */
- if (!output)
- continue;
-
- /* Mark that we'll need to re-set the mode for sure */
- memset(&crtc->mode, 0, sizeof(crtc->mode));
- if (!crtc->desiredMode.CrtcHDisplay)
- {
- DisplayModePtr mode = xf86OutputFindClosestMode (output, scrn->currentMode);
-
- if (!mode)
- return FALSE;
- crtc->desiredMode = *mode;
- crtc->desiredRotation = RR_Rotate_0;
- crtc->desiredTransformPresent = FALSE;
- crtc->desiredX = 0;
- crtc->desiredY = 0;
- }
-
- if (crtc->desiredTransformPresent)
- transform = &crtc->desiredTransform;
- else
- transform = NULL;
- if (!xf86CrtcSetModeTransform (crtc, &crtc->desiredMode, crtc->desiredRotation,
- transform, crtc->desiredX, crtc->desiredY))
- return FALSE;
- }
-
- xf86DisableUnusedFunctions(scrn);
- return TRUE;
-}
-
-/**
- * In the current world order, there are lists of modes per output, which may
- * or may not include the mode that was asked to be set by XFree86's mode
- * selection. Find the closest one, in the following preference order:
- *
- * - Equality
- * - Closer in size to the requested mode, but no larger
- * - Closer in refresh rate to the requested mode.
- */
-
-DisplayModePtr
-xf86OutputFindClosestMode (xf86OutputPtr output, DisplayModePtr desired)
-{
- DisplayModePtr best = NULL, scan = NULL;
-
- for (scan = output->probed_modes; scan != NULL; scan = scan->next)
- {
- /* If there's an exact match, we're done. */
- if (xf86ModesEqual(scan, desired)) {
- best = desired;
- break;
- }
-
- /* Reject if it's larger than the desired mode. */
- if (scan->HDisplay > desired->HDisplay ||
- scan->VDisplay > desired->VDisplay)
- {
- continue;
- }
-
- /*
- * If we haven't picked a best mode yet, use the first
- * one in the size range
- */
- if (best == NULL)
- {
- best = scan;
- continue;
- }
-
- /* Find if it's closer to the right size than the current best
- * option.
- */
- if ((scan->HDisplay > best->HDisplay &&
- scan->VDisplay >= best->VDisplay) ||
- (scan->HDisplay >= best->HDisplay &&
- scan->VDisplay > best->VDisplay))
- {
- best = scan;
- continue;
- }
-
- /* Find if it's still closer to the right refresh than the current
- * best resolution.
- */
- if (scan->HDisplay == best->HDisplay &&
- scan->VDisplay == best->VDisplay &&
- (fabs(scan->VRefresh - desired->VRefresh) <
- fabs(best->VRefresh - desired->VRefresh))) {
- best = scan;
- }
- }
- return best;
-}
-
-/**
- * When setting a mode through XFree86-VidModeExtension or XFree86-DGA,
- * take the specified mode and apply it to the crtc connected to the compat
- * output. Then, find similar modes for the other outputs, as with the
- * InitialConfiguration code above. The goal is to clone the desired
- * mode across all outputs that are currently active.
- */
-
-Bool
-xf86SetSingleMode (ScrnInfoPtr pScrn, DisplayModePtr desired, Rotation rotation)
-{
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- Bool ok = TRUE;
- xf86OutputPtr compat_output;
- DisplayModePtr compat_mode = NULL;
- int c;
-
- /*
- * Let the compat output drive the final mode selection
- */
- compat_output = xf86CompatOutput(pScrn);
- if (compat_output)
- compat_mode = xf86OutputFindClosestMode (compat_output, desired);
- if (compat_mode)
- desired = compat_mode;
-
- for (c = 0; c < config->num_crtc; c++)
- {
- xf86CrtcPtr crtc = config->crtc[c];
- DisplayModePtr crtc_mode = NULL;
- int o;
-
- if (!crtc->enabled)
- continue;
-
- for (o = 0; o < config->num_output; o++)
- {
- xf86OutputPtr output = config->output[o];
- DisplayModePtr output_mode;
-
- /* skip outputs not on this crtc */
- if (output->crtc != crtc)
- continue;
-
- if (crtc_mode)
- {
- output_mode = xf86OutputFindClosestMode (output, crtc_mode);
- if (output_mode != crtc_mode)
- output->crtc = NULL;
- }
- else
- crtc_mode = xf86OutputFindClosestMode (output, desired);
- }
- if (!crtc_mode)
- {
- crtc->enabled = FALSE;
- continue;
- }
- if (!xf86CrtcSetModeTransform (crtc, crtc_mode, rotation, NULL, 0, 0))
- ok = FALSE;
- else
- {
- crtc->desiredMode = *crtc_mode;
- crtc->desiredRotation = rotation;
- crtc->desiredTransformPresent = FALSE;
- crtc->desiredX = 0;
- crtc->desiredY = 0;
- }
- }
- xf86DisableUnusedFunctions(pScrn);
-#ifdef RANDR_12_INTERFACE
- xf86RandR12TellChanged (pScrn->pScreen);
-#endif
- return ok;
-}
-
-
-/**
- * Set the DPMS power mode of all outputs and CRTCs.
- *
- * If the new mode is off, it will turn off outputs and then CRTCs.
- * Otherwise, it will affect CRTCs before outputs.
- */
-void
-xf86DPMSSet(ScrnInfoPtr scrn, int mode, int flags)
-{
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
- int i;
-
- if (!scrn->vtSema)
- return;
-
- if (mode == DPMSModeOff) {
- for (i = 0; i < config->num_output; i++) {
- xf86OutputPtr output = config->output[i];
- if (output->crtc != NULL)
- (*output->funcs->dpms) (output, mode);
- }
- }
-
- for (i = 0; i < config->num_crtc; i++) {
- xf86CrtcPtr crtc = config->crtc[i];
- if (crtc->enabled)
- (*crtc->funcs->dpms) (crtc, mode);
- }
-
- if (mode != DPMSModeOff) {
- for (i = 0; i < config->num_output; i++) {
- xf86OutputPtr output = config->output[i];
- if (output->crtc != NULL)
- (*output->funcs->dpms) (output, mode);
- }
- }
-}
-
-/**
- * Implement the screensaver by just calling down into the driver DPMS hooks.
- *
- * Even for monitors with no DPMS support, by the definition of our DPMS hooks,
- * the outputs will still get disabled (blanked).
- */
-Bool
-xf86SaveScreen(ScreenPtr pScreen, int mode)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-
- if (xf86IsUnblank(mode))
- xf86DPMSSet(pScrn, DPMSModeOn, 0);
- else
- xf86DPMSSet(pScrn, DPMSModeOff, 0);
-
- return TRUE;
-}
-
-/**
- * Disable all inactive crtcs and outputs
- */
-void
-xf86DisableUnusedFunctions(ScrnInfoPtr pScrn)
-{
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- int o, c;
-
- for (o = 0; o < xf86_config->num_output; o++)
- {
- xf86OutputPtr output = xf86_config->output[o];
- if (!output->crtc)
- (*output->funcs->dpms)(output, DPMSModeOff);
- }
-
- for (c = 0; c < xf86_config->num_crtc; c++)
- {
- xf86CrtcPtr crtc = xf86_config->crtc[c];
-
- if (!crtc->enabled)
- {
- crtc->funcs->dpms(crtc, DPMSModeOff);
- memset(&crtc->mode, 0, sizeof(crtc->mode));
- xf86RotateDestroy(crtc);
- crtc->active = FALSE;
- }
- }
- if (pScrn->pScreen)
- xf86_crtc_notify(pScrn->pScreen);
-}
-
-#ifdef RANDR_12_INTERFACE
-
-#define EDID_ATOM_NAME "EDID"
-
-/**
- * Set the RandR EDID property
- */
-static void
-xf86OutputSetEDIDProperty (xf86OutputPtr output, void *data, int data_len)
-{
- Atom edid_atom = MakeAtom(EDID_ATOM_NAME, sizeof(EDID_ATOM_NAME) - 1, TRUE);
-
- /* This may get called before the RandR resources have been created */
- if (output->randr_output == NULL)
- return;
-
- if (data_len != 0) {
- RRChangeOutputProperty(output->randr_output, edid_atom, XA_INTEGER, 8,
- PropModeReplace, data_len, data, FALSE, TRUE);
- } else {
- RRDeleteOutputProperty(output->randr_output, edid_atom);
- }
-}
-
-#endif
-
-/* Pull out a phyiscal size from a detailed timing if available. */
-struct det_phySize_parameter {
- xf86OutputPtr output;
- ddc_quirk_t quirks;
- Bool ret;
-};
-
-static void handle_detailed_physical_size(struct detailed_monitor_section
- *det_mon, void *data)
-{
- struct det_phySize_parameter *p;
- p = (struct det_phySize_parameter *)data;
-
- if (p->ret == TRUE )
- return ;
-
- xf86DetTimingApplyQuirks(det_mon, p->quirks,
- p->output->MonInfo->features.hsize,
- p->output->MonInfo->features.vsize);
- if (det_mon->type == DT &&
- det_mon->section.d_timings.h_size != 0 &&
- det_mon->section.d_timings.v_size != 0) {
-
- p->output->mm_width = det_mon->section.d_timings.h_size;
- p->output->mm_height = det_mon->section.d_timings.v_size;
- p->ret = TRUE;
- }
-}
-
-/**
- * Set the EDID information for the specified output
- */
-void
-xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon)
-{
- ScrnInfoPtr scrn = output->scrn;
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
- Bool debug_modes = config->debug_modes || xf86Initialising;
-#ifdef RANDR_12_INTERFACE
- int size;
-#endif
-
- if (output->MonInfo != NULL)
- xfree(output->MonInfo);
-
- output->MonInfo = edid_mon;
-
- if (debug_modes) {
- xf86DrvMsg(scrn->scrnIndex, X_INFO, "EDID for output %s\n",
- output->name);
- xf86PrintEDID(edid_mon);
- }
-
- /* Set the DDC properties for the 'compat' output */
- if (output == xf86CompatOutput(scrn))
- xf86SetDDCproperties(scrn, edid_mon);
-
-#ifdef RANDR_12_INTERFACE
- /* Set the RandR output properties */
- size = 0;
- if (edid_mon)
- {
- if (edid_mon->ver.version == 1) {
- size = 128;
- if (edid_mon->flags & EDID_COMPLETE_RAWDATA)
- size += edid_mon->no_sections * 128;
- } else if (edid_mon->ver.version == 2)
- size = 256;
- }
- xf86OutputSetEDIDProperty (output, edid_mon ? edid_mon->rawData : NULL, size);
-#endif
-
- if (edid_mon) {
-
- struct det_phySize_parameter p;
- p.output = output;
- p.quirks = xf86DDCDetectQuirks(scrn->scrnIndex,edid_mon, FALSE);
- p.ret = FALSE;
- xf86ForEachDetailedBlock(edid_mon,
- handle_detailed_physical_size, &p);
-
- /* if no mm size is available from a detailed timing, check the max size field */
- if ((!output->mm_width || !output->mm_height) &&
- (edid_mon->features.hsize && edid_mon->features.vsize))
- {
- output->mm_width = edid_mon->features.hsize * 10;
- output->mm_height = edid_mon->features.vsize * 10;
- }
- }
-}
-
-/**
- * Return the list of modes supported by the EDID information
- * stored in 'output'
- */
-DisplayModePtr
-xf86OutputGetEDIDModes (xf86OutputPtr output)
-{
- ScrnInfoPtr scrn = output->scrn;
- xf86MonPtr edid_mon = output->MonInfo;
-
- if (!edid_mon)
- return NULL;
- return xf86DDCGetModes(scrn->scrnIndex, edid_mon);
-}
-
-/* maybe we should care about DDC1? meh. */
-xf86MonPtr
-xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus)
-{
- ScrnInfoPtr scrn = output->scrn;
- xf86MonPtr mon;
-
- mon = xf86DoEEDID(scrn->scrnIndex, pDDCBus, TRUE);
- if (mon)
- xf86DDCApplyQuirks(scrn->scrnIndex, mon);
-
- return mon;
-}
-
-static char *_xf86ConnectorNames[] = {
- "None", "VGA", "DVI-I", "DVI-D",
- "DVI-A", "Composite", "S-Video",
- "Component", "LFP", "Proprietary",
- "HDMI", "DisplayPort",
- };
-char *
-xf86ConnectorGetName(xf86ConnectorType connector)
-{
- return _xf86ConnectorNames[connector];
-}
-
-static void
-x86_crtc_box_intersect(BoxPtr dest, BoxPtr a, BoxPtr b)
-{
- dest->x1 = a->x1 > b->x1 ? a->x1 : b->x1;
- dest->x2 = a->x2 < b->x2 ? a->x2 : b->x2;
- dest->y1 = a->y1 > b->y1 ? a->y1 : b->y1;
- dest->y2 = a->y2 < b->y2 ? a->y2 : b->y2;
-
- if (dest->x1 >= dest->x2 || dest->y1 >= dest->y2)
- dest->x1 = dest->x2 = dest->y1 = dest->y2 = 0;
-}
-
-static void
-x86_crtc_box(xf86CrtcPtr crtc, BoxPtr crtc_box)
-{
- if (crtc->enabled) {
- crtc_box->x1 = crtc->x;
- crtc_box->x2 = crtc->x + xf86ModeWidth(&crtc->mode, crtc->rotation);
- crtc_box->y1 = crtc->y;
- crtc_box->y2 = crtc->y + xf86ModeHeight(&crtc->mode, crtc->rotation);
- } else
- crtc_box->x1 = crtc_box->x2 = crtc_box->y1 = crtc_box->y2 = 0;
-}
-
-static int
-xf86_crtc_box_area(BoxPtr box)
-{
- return (int) (box->x2 - box->x1) * (int) (box->y2 - box->y1);
-}
-
-/*
- * Return the crtc covering 'box'. If two crtcs cover a portion of
- * 'box', then prefer 'desired'. If 'desired' is NULL, then prefer the crtc
- * with greater coverage
- */
-
-static xf86CrtcPtr
-xf86_covering_crtc(ScrnInfoPtr pScrn,
- BoxPtr box,
- xf86CrtcPtr desired,
- BoxPtr crtc_box_ret)
-{
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- xf86CrtcPtr crtc, best_crtc;
- int coverage, best_coverage;
- int c;
- BoxRec crtc_box, cover_box;
-
- best_crtc = NULL;
- best_coverage = 0;
- crtc_box_ret->x1 = 0;
- crtc_box_ret->x2 = 0;
- crtc_box_ret->y1 = 0;
- crtc_box_ret->y2 = 0;
- for (c = 0; c < xf86_config->num_crtc; c++) {
- crtc = xf86_config->crtc[c];
- x86_crtc_box(crtc, &crtc_box);
- x86_crtc_box_intersect(&cover_box, &crtc_box, box);
- coverage = xf86_crtc_box_area(&cover_box);
- if (coverage && crtc == desired) {
- *crtc_box_ret = crtc_box;
- return crtc;
- } else if (coverage > best_coverage) {
- *crtc_box_ret = crtc_box;
- best_crtc = crtc;
- best_coverage = coverage;
- }
- }
- return best_crtc;
-}
-
-/*
- * For overlay video, compute the relevant CRTC and
- * clip video to that.
- *
- * returning FALSE means there was a memory failure of some kind,
- * not that the video shouldn't be displayed
- */
-
-Bool
-xf86_crtc_clip_video_helper(ScrnInfoPtr pScrn,
- xf86CrtcPtr *crtc_ret,
- xf86CrtcPtr desired_crtc,
- BoxPtr dst,
- INT32 *xa,
- INT32 *xb,
- INT32 *ya,
- INT32 *yb,
- RegionPtr reg,
- INT32 width,
- INT32 height)
-{
- Bool ret;
- RegionRec crtc_region_local;
- RegionPtr crtc_region = reg;
-
- if (crtc_ret) {
- BoxRec crtc_box;
- xf86CrtcPtr crtc = xf86_covering_crtc(pScrn, dst,
- desired_crtc,
- &crtc_box);
-
- if (crtc) {
- REGION_INIT (pScreen, &crtc_region_local, &crtc_box, 1);
- crtc_region = &crtc_region_local;
- REGION_INTERSECT (pScreen, crtc_region, crtc_region, reg);
- }
- *crtc_ret = crtc;
- }
-
- ret = xf86XVClipVideoHelper(dst, xa, xb, ya, yb,
- crtc_region, width, height);
-
- if (crtc_region != reg)
- REGION_UNINIT (pScreen, &crtc_region_local);
-
- return ret;
-}
-
-xf86_crtc_notify_proc_ptr
-xf86_wrap_crtc_notify (ScreenPtr screen, xf86_crtc_notify_proc_ptr new)
-{
- if (xf86CrtcConfigPrivateIndex != -1)
- {
- ScrnInfoPtr scrn = xf86Screens[screen->myNum];
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
- xf86_crtc_notify_proc_ptr old;
-
- old = config->xf86_crtc_notify;
- config->xf86_crtc_notify = new;
- return old;
- }
- return NULL;
-}
-
-void
-xf86_unwrap_crtc_notify(ScreenPtr screen, xf86_crtc_notify_proc_ptr old)
-{
- if (xf86CrtcConfigPrivateIndex != -1)
- {
- ScrnInfoPtr scrn = xf86Screens[screen->myNum];
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
-
- config->xf86_crtc_notify = old;
- }
-}
-
-void
-xf86_crtc_notify(ScreenPtr screen)
-{
- ScrnInfoPtr scrn = xf86Screens[screen->myNum];
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
-
- if (config->xf86_crtc_notify)
- config->xf86_crtc_notify(screen);
-}
-
-Bool
-xf86_crtc_supports_gamma(ScrnInfoPtr pScrn)
-{
- if (xf86CrtcConfigPrivateIndex != -1) {
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- xf86CrtcPtr crtc;
-
- /* for multiple drivers loaded we need this */
- if (!xf86_config)
- return FALSE;
- if (xf86_config->num_crtc == 0)
- return FALSE;
- crtc = xf86_config->crtc[0];
-
- return (crtc->funcs->gamma_set != NULL);
- }
-
- return FALSE;
-}
+/*
+ * Copyright © 2006 Keith Packard
+ * Copyright © 2008 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS 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>
+#else
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#endif
+
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "xf86.h"
+#include "xf86DDC.h"
+#include "xf86Crtc.h"
+#include "xf86Modes.h"
+#include "xf86Priv.h"
+#include "xf86RandR12.h"
+#include "X11/extensions/render.h"
+#include "X11/extensions/dpmsconst.h"
+#include "X11/Xatom.h"
+#include "picturestr.h"
+
+#include "xf86xv.h"
+
+/*
+ * Initialize xf86CrtcConfig structure
+ */
+
+int xf86CrtcConfigPrivateIndex = -1;
+
+void
+xf86CrtcConfigInit (ScrnInfoPtr scrn,
+ const xf86CrtcConfigFuncsRec *funcs)
+{
+ xf86CrtcConfigPtr config;
+
+ if (xf86CrtcConfigPrivateIndex == -1)
+ xf86CrtcConfigPrivateIndex = xf86AllocateScrnInfoPrivateIndex();
+ config = xnfcalloc (1, sizeof (xf86CrtcConfigRec));
+
+ config->funcs = funcs;
+
+ scrn->privates[xf86CrtcConfigPrivateIndex].ptr = config;
+}
+
+void
+xf86CrtcSetSizeRange (ScrnInfoPtr scrn,
+ int minWidth, int minHeight,
+ int maxWidth, int maxHeight)
+{
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+
+ config->minWidth = minWidth;
+ config->minHeight = minHeight;
+ config->maxWidth = maxWidth;
+ config->maxHeight = maxHeight;
+}
+
+/*
+ * Crtc functions
+ */
+xf86CrtcPtr
+xf86CrtcCreate (ScrnInfoPtr scrn,
+ const xf86CrtcFuncsRec *funcs)
+{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ xf86CrtcPtr crtc, *crtcs;
+
+ crtc = calloc(sizeof (xf86CrtcRec), 1);
+ if (!crtc)
+ return NULL;
+ crtc->version = XF86_CRTC_VERSION;
+ crtc->scrn = scrn;
+ crtc->funcs = funcs;
+#ifdef RANDR_12_INTERFACE
+ crtc->randr_crtc = NULL;
+#endif
+ crtc->rotation = RR_Rotate_0;
+ crtc->desiredRotation = RR_Rotate_0;
+ pixman_transform_init_identity (&crtc->crtc_to_framebuffer);
+ pixman_f_transform_init_identity (&crtc->f_crtc_to_framebuffer);
+ pixman_f_transform_init_identity (&crtc->f_framebuffer_to_crtc);
+ crtc->filter = NULL;
+ crtc->params = NULL;
+ crtc->nparams = 0;
+ crtc->filter_width = 0;
+ crtc->filter_height = 0;
+ crtc->transform_in_use = FALSE;
+ crtc->transformPresent = FALSE;
+ crtc->desiredTransformPresent = FALSE;
+ memset (&crtc->bounds, '\0', sizeof (crtc->bounds));
+
+ /* Preallocate gamma at a sensible size. */
+ crtc->gamma_size = 256;
+ crtc->gamma_red = malloc(3 * crtc->gamma_size * sizeof (CARD16));
+ if (!crtc->gamma_red) {
+ free(crtc);
+ return NULL;
+ }
+ crtc->gamma_green = crtc->gamma_red + crtc->gamma_size;
+ crtc->gamma_blue = crtc->gamma_green + crtc->gamma_size;
+
+ if (xf86_config->crtc)
+ crtcs = realloc(xf86_config->crtc,
+ (xf86_config->num_crtc + 1) * sizeof (xf86CrtcPtr));
+ else
+ crtcs = malloc((xf86_config->num_crtc + 1) * sizeof (xf86CrtcPtr));
+ if (!crtcs)
+ {
+ free(crtc);
+ return NULL;
+ }
+ xf86_config->crtc = crtcs;
+ xf86_config->crtc[xf86_config->num_crtc++] = crtc;
+ return crtc;
+}
+
+void
+xf86CrtcDestroy (xf86CrtcPtr crtc)
+{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
+ int c;
+
+ (*crtc->funcs->destroy) (crtc);
+ for (c = 0; c < xf86_config->num_crtc; c++)
+ if (xf86_config->crtc[c] == crtc)
+ {
+ memmove (&xf86_config->crtc[c],
+ &xf86_config->crtc[c+1],
+ ((xf86_config->num_crtc - (c + 1)) * sizeof(void*)));
+ xf86_config->num_crtc--;
+ break;
+ }
+ if (crtc->params)
+ free(crtc->params);
+ free(crtc->gamma_red);
+ free(crtc);
+}
+
+
+/**
+ * Return whether any outputs are connected to the specified pipe
+ */
+
+Bool
+xf86CrtcInUse (xf86CrtcPtr crtc)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int o;
+
+ for (o = 0; o < xf86_config->num_output; o++)
+ if (xf86_config->output[o]->crtc == crtc)
+ return TRUE;
+ return FALSE;
+}
+
+void
+xf86CrtcSetScreenSubpixelOrder (ScreenPtr pScreen)
+{
+ int subpixel_order = SubPixelUnknown;
+ Bool has_none = FALSE;
+ ScrnInfoPtr scrn = xf86Screens[pScreen->myNum];
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ int c, o;
+
+ for (c = 0; c < xf86_config->num_crtc; c++)
+ {
+ xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+ for (o = 0; o < xf86_config->num_output; o++)
+ {
+ xf86OutputPtr output = xf86_config->output[o];
+
+ if (output->crtc == crtc)
+ {
+ switch (output->subpixel_order) {
+ case SubPixelNone:
+ has_none = TRUE;
+ break;
+ case SubPixelUnknown:
+ break;
+ default:
+ subpixel_order = output->subpixel_order;
+ break;
+ }
+ }
+ if (subpixel_order != SubPixelUnknown)
+ break;
+ }
+ if (subpixel_order != SubPixelUnknown)
+ {
+ static const int circle[4] = {
+ SubPixelHorizontalRGB,
+ SubPixelVerticalRGB,
+ SubPixelHorizontalBGR,
+ SubPixelVerticalBGR,
+ };
+ int rotate;
+ int c;
+ for (rotate = 0; rotate < 4; rotate++)
+ if (crtc->rotation & (1 << rotate))
+ break;
+ for (c = 0; c < 4; c++)
+ if (circle[c] == subpixel_order)
+ break;
+ c = (c + rotate) & 0x3;
+ if ((crtc->rotation & RR_Reflect_X) && !(c & 1))
+ c ^= 2;
+ if ((crtc->rotation & RR_Reflect_Y) && (c & 1))
+ c ^= 2;
+ subpixel_order = circle[c];
+ break;
+ }
+ }
+ if (subpixel_order == SubPixelUnknown && has_none)
+ subpixel_order = SubPixelNone;
+ PictureSetSubpixelOrder (pScreen, subpixel_order);
+}
+
+/**
+ * Sets the given video mode on the given crtc
+ */
+Bool
+xf86CrtcSetModeTransform (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
+ RRTransformPtr transform, int x, int y)
+{
+ ScrnInfoPtr scrn = crtc->scrn;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ int i;
+ Bool ret = FALSE;
+ Bool didLock = FALSE;
+ DisplayModePtr adjusted_mode;
+ DisplayModeRec saved_mode;
+ int saved_x, saved_y;
+ Rotation saved_rotation;
+ RRTransformRec saved_transform;
+ Bool saved_transform_present;
+
+ crtc->enabled = xf86CrtcInUse (crtc);
+
+ /* We only hit this if someone explicitly sends a "disabled" modeset. */
+ if (!crtc->enabled)
+ {
+ /* Check everything for stuff that should be off. */
+ xf86DisableUnusedFunctions(scrn);
+ return TRUE;
+ }
+
+ adjusted_mode = xf86DuplicateMode(mode);
+
+
+ saved_mode = crtc->mode;
+ saved_x = crtc->x;
+ saved_y = crtc->y;
+ saved_rotation = crtc->rotation;
+ if (crtc->transformPresent) {
+ RRTransformInit (&saved_transform);
+ RRTransformCopy (&saved_transform, &crtc->transform);
+ }
+ saved_transform_present = crtc->transformPresent;
+
+ /* Update crtc values up front so the driver can rely on them for mode
+ * setting.
+ */
+ crtc->mode = *mode;
+ crtc->x = x;
+ crtc->y = y;
+ crtc->rotation = rotation;
+ if (transform) {
+ RRTransformCopy (&crtc->transform, transform);
+ crtc->transformPresent = TRUE;
+ } else
+ crtc->transformPresent = FALSE;
+
+ if (crtc->funcs->set_mode_major) {
+ ret = crtc->funcs->set_mode_major(crtc, mode, rotation, x, y);
+ goto done;
+ }
+
+ didLock = crtc->funcs->lock (crtc);
+ /* Pass our mode to the outputs and the CRTC to give them a chance to
+ * adjust it according to limitations or output properties, and also
+ * a chance to reject the mode entirely.
+ */
+ for (i = 0; i < xf86_config->num_output; i++) {
+ xf86OutputPtr output = xf86_config->output[i];
+
+ if (output->crtc != crtc)
+ continue;
+
+ if (!output->funcs->mode_fixup(output, mode, adjusted_mode)) {
+ goto done;
+ }
+ }
+
+ if (!crtc->funcs->mode_fixup(crtc, mode, adjusted_mode)) {
+ goto done;
+ }
+
+ if (!xf86CrtcRotate (crtc))
+ goto done;
+
+ /* Prepare the outputs and CRTCs before setting the mode. */
+ for (i = 0; i < xf86_config->num_output; i++) {
+ xf86OutputPtr output = xf86_config->output[i];
+
+ if (output->crtc != crtc)
+ continue;
+
+ /* Disable the output as the first thing we do. */
+ output->funcs->prepare(output);
+ }
+
+ crtc->funcs->prepare(crtc);
+
+ /* Set up the DPLL and any output state that needs to adjust or depend
+ * on the DPLL.
+ */
+ crtc->funcs->mode_set(crtc, mode, adjusted_mode, crtc->x, crtc->y);
+ for (i = 0; i < xf86_config->num_output; i++)
+ {
+ xf86OutputPtr output = xf86_config->output[i];
+ if (output->crtc == crtc)
+ output->funcs->mode_set(output, mode, adjusted_mode);
+ }
+
+ /* Only upload when needed, to avoid unneeded delays. */
+ if (!crtc->active && crtc->funcs->gamma_set)
+ crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green,
+ crtc->gamma_blue, crtc->gamma_size);
+
+ /* Now, enable the clocks, plane, pipe, and outputs that we set up. */
+ crtc->funcs->commit(crtc);
+ for (i = 0; i < xf86_config->num_output; i++)
+ {
+ xf86OutputPtr output = xf86_config->output[i];
+ if (output->crtc == crtc)
+ output->funcs->commit(output);
+ }
+
+ ret = TRUE;
+
+done:
+ if (ret) {
+ crtc->active = TRUE;
+ if (scrn->pScreen)
+ xf86CrtcSetScreenSubpixelOrder (scrn->pScreen);
+ } else {
+ crtc->x = saved_x;
+ crtc->y = saved_y;
+ crtc->rotation = saved_rotation;
+ crtc->mode = saved_mode;
+ if (saved_transform_present)
+ RRTransformCopy (&crtc->transform, &saved_transform);
+ crtc->transformPresent = saved_transform_present;
+ }
+
+ if (adjusted_mode->name)
+ free(adjusted_mode->name);
+ free(adjusted_mode);
+
+ if (didLock)
+ crtc->funcs->unlock (crtc);
+
+ return ret;
+}
+
+/**
+ * Sets the given video mode on the given crtc, but without providing
+ * a transform
+ */
+Bool
+xf86CrtcSetMode (xf86CrtcPtr crtc, DisplayModePtr mode, Rotation rotation,
+ int x, int y)
+{
+ return xf86CrtcSetModeTransform (crtc, mode, rotation, NULL, x, y);
+}
+
+/**
+ * Pans the screen, does not change the mode
+ */
+void
+xf86CrtcSetOrigin (xf86CrtcPtr crtc, int x, int y)
+{
+ crtc->x = x;
+ crtc->y = y;
+ if (crtc->funcs->set_origin) {
+ if (!xf86CrtcRotate (crtc))
+ return;
+ crtc->funcs->set_origin (crtc, x, y);
+ }
+ else
+ xf86CrtcSetMode (crtc, &crtc->mode, crtc->rotation, x, y);
+}
+
+/*
+ * Output functions
+ */
+
+extern XF86ConfigPtr xf86configptr;
+
+typedef enum {
+ OPTION_PREFERRED_MODE,
+ OPTION_POSITION,
+ OPTION_BELOW,
+ OPTION_RIGHT_OF,
+ OPTION_ABOVE,
+ OPTION_LEFT_OF,
+ OPTION_ENABLE,
+ OPTION_DISABLE,
+ OPTION_MIN_CLOCK,
+ OPTION_MAX_CLOCK,
+ OPTION_IGNORE,
+ OPTION_ROTATE,
+ OPTION_PANNING,
+ OPTION_PRIMARY,
+} OutputOpts;
+
+static OptionInfoRec xf86OutputOptions[] = {
+ {OPTION_PREFERRED_MODE, "PreferredMode", OPTV_STRING, {0}, FALSE },
+ {OPTION_POSITION, "Position", OPTV_STRING, {0}, FALSE },
+ {OPTION_BELOW, "Below", OPTV_STRING, {0}, FALSE },
+ {OPTION_RIGHT_OF, "RightOf", OPTV_STRING, {0}, FALSE },
+ {OPTION_ABOVE, "Above", OPTV_STRING, {0}, FALSE },
+ {OPTION_LEFT_OF, "LeftOf", OPTV_STRING, {0}, FALSE },
+ {OPTION_ENABLE, "Enable", OPTV_BOOLEAN, {0}, FALSE },
+ {OPTION_DISABLE, "Disable", OPTV_BOOLEAN, {0}, FALSE },
+ {OPTION_MIN_CLOCK, "MinClock", OPTV_FREQ, {0}, FALSE },
+ {OPTION_MAX_CLOCK, "MaxClock", OPTV_FREQ, {0}, FALSE },
+ {OPTION_IGNORE, "Ignore", OPTV_BOOLEAN, {0}, FALSE },
+ {OPTION_ROTATE, "Rotate", OPTV_STRING, {0}, FALSE },
+ {OPTION_PANNING, "Panning", OPTV_STRING, {0}, FALSE },
+ {OPTION_PRIMARY, "Primary", OPTV_BOOLEAN, {0}, FALSE },
+ {-1, NULL, OPTV_NONE, {0}, FALSE },
+};
+
+enum {
+ OPTION_MODEDEBUG,
+};
+
+static OptionInfoRec xf86DeviceOptions[] = {
+ {OPTION_MODEDEBUG, "ModeDebug", OPTV_BOOLEAN, {0}, FALSE },
+ {-1, NULL, OPTV_NONE, {0}, FALSE },
+};
+
+static void
+xf86OutputSetMonitor (xf86OutputPtr output)
+{
+ char *option_name;
+ static const char monitor_prefix[] = "monitor-";
+ char *monitor;
+
+ if (!output->name)
+ return;
+
+ if (output->options)
+ free(output->options);
+
+ output->options = xnfalloc (sizeof (xf86OutputOptions));
+ memcpy (output->options, xf86OutputOptions, sizeof (xf86OutputOptions));
+
+ option_name = xnfalloc (strlen (monitor_prefix) +
+ strlen (output->name) + 1);
+ strcpy (option_name, monitor_prefix);
+ strcat (option_name, output->name);
+ monitor = xf86findOptionValue (output->scrn->options, option_name);
+ if (!monitor)
+ monitor = output->name;
+ else
+ xf86MarkOptionUsedByName (output->scrn->options, option_name);
+ free(option_name);
+ output->conf_monitor = xf86findMonitor (monitor,
+ xf86configptr->conf_monitor_lst);
+ /*
+ * Find the monitor section of the screen and use that
+ */
+ if (!output->conf_monitor && output->use_screen_monitor)
+ output->conf_monitor = xf86findMonitor (output->scrn->monitor->id,
+ xf86configptr->conf_monitor_lst);
+ if (output->conf_monitor)
+ {
+ xf86DrvMsg (output->scrn->scrnIndex, X_INFO,
+ "Output %s using monitor section %s\n",
+ output->name, output->conf_monitor->mon_identifier);
+ xf86ProcessOptions (output->scrn->scrnIndex,
+ output->conf_monitor->mon_option_lst,
+ output->options);
+ }
+ else
+ xf86DrvMsg (output->scrn->scrnIndex, X_INFO,
+ "Output %s has no monitor section\n",
+ output->name);
+}
+
+static Bool
+xf86OutputEnabled (xf86OutputPtr output, Bool strict)
+{
+ Bool enable, disable;
+
+ /* check to see if this output was enabled in the config file */
+ if (xf86GetOptValBool (output->options, OPTION_ENABLE, &enable) && enable)
+ {
+ xf86DrvMsg (output->scrn->scrnIndex, X_INFO,
+ "Output %s enabled by config file\n", output->name);
+ return TRUE;
+ }
+ /* or if this output was disabled in the config file */
+ if (xf86GetOptValBool (output->options, OPTION_DISABLE, &disable) && disable)
+ {
+ xf86DrvMsg (output->scrn->scrnIndex, X_INFO,
+ "Output %s disabled by config file\n", output->name);
+ return FALSE;
+ }
+
+ /* If not, try to only light up the ones we know are connected */
+ if (strict) {
+ enable = output->status == XF86OutputStatusConnected;
+ }
+ /* But if that fails, try to light up even outputs we're unsure of */
+ else {
+ enable = output->status != XF86OutputStatusDisconnected;
+ }
+
+ xf86DrvMsg (output->scrn->scrnIndex, X_INFO,
+ "Output %s %sconnected\n", output->name, enable ? "" : "dis");
+ return enable;
+}
+
+static Bool
+xf86OutputIgnored (xf86OutputPtr output)
+{
+ return xf86ReturnOptValBool (output->options, OPTION_IGNORE, FALSE);
+}
+
+static char *direction[4] = {
+ "normal",
+ "left",
+ "inverted",
+ "right"
+};
+
+static Rotation
+xf86OutputInitialRotation (xf86OutputPtr output)
+{
+ char *rotate_name = xf86GetOptValString (output->options,
+ OPTION_ROTATE);
+ int i;
+
+ if (!rotate_name)
+ return RR_Rotate_0;
+
+ for (i = 0; i < 4; i++)
+ if (xf86nameCompare (direction[i], rotate_name) == 0)
+ return (1 << i);
+ return RR_Rotate_0;
+}
+
+xf86OutputPtr
+xf86OutputCreate (ScrnInfoPtr scrn,
+ const xf86OutputFuncsRec *funcs,
+ const char *name)
+{
+ xf86OutputPtr output, *outputs;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ int len;
+ Bool primary;
+
+ if (name)
+ len = strlen (name) + 1;
+ else
+ len = 0;
+
+ output = calloc(sizeof (xf86OutputRec) + len, 1);
+ if (!output)
+ return NULL;
+ output->scrn = scrn;
+ output->funcs = funcs;
+ if (name)
+ {
+ output->name = (char *) (output + 1);
+ strcpy (output->name, name);
+ }
+ output->subpixel_order = SubPixelUnknown;
+ /*
+ * Use the old per-screen monitor section for the first output
+ */
+ output->use_screen_monitor = (xf86_config->num_output == 0);
+#ifdef RANDR_12_INTERFACE
+ output->randr_output = NULL;
+#endif
+ if (name)
+ {
+ xf86OutputSetMonitor (output);
+ if (xf86OutputIgnored (output))
+ {
+ free(output);
+ return FALSE;
+ }
+ }
+
+
+ if (xf86_config->output)
+ outputs = realloc(xf86_config->output,
+ (xf86_config->num_output + 1) * sizeof (xf86OutputPtr));
+ else
+ outputs = malloc((xf86_config->num_output + 1) * sizeof (xf86OutputPtr));
+ if (!outputs)
+ {
+ free(output);
+ return NULL;
+ }
+
+ xf86_config->output = outputs;
+
+ if (xf86GetOptValBool (output->options, OPTION_PRIMARY, &primary) && primary)
+ {
+ memmove(xf86_config->output + 1, xf86_config->output,
+ xf86_config->num_output * sizeof (xf86OutputPtr));
+ xf86_config->output[0] = output;
+ }
+ else
+ {
+ xf86_config->output[xf86_config->num_output] = output;
+ }
+
+ xf86_config->num_output++;
+
+ return output;
+}
+
+Bool
+xf86OutputRename (xf86OutputPtr output, const char *name)
+{
+ int len = strlen(name) + 1;
+ char *newname = malloc(len);
+
+ if (!newname)
+ return FALSE; /* so sorry... */
+
+ strcpy (newname, name);
+ if (output->name && output->name != (char *) (output + 1))
+ free(output->name);
+ output->name = newname;
+ xf86OutputSetMonitor (output);
+ if (xf86OutputIgnored (output))
+ return FALSE;
+ return TRUE;
+}
+
+void
+xf86OutputUseScreenMonitor (xf86OutputPtr output, Bool use_screen_monitor)
+{
+ if (use_screen_monitor != output->use_screen_monitor)
+ {
+ output->use_screen_monitor = use_screen_monitor;
+ xf86OutputSetMonitor (output);
+ }
+}
+
+void
+xf86OutputDestroy (xf86OutputPtr output)
+{
+ ScrnInfoPtr scrn = output->scrn;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ int o;
+
+ (*output->funcs->destroy) (output);
+ while (output->probed_modes)
+ xf86DeleteMode (&output->probed_modes, output->probed_modes);
+ for (o = 0; o < xf86_config->num_output; o++)
+ if (xf86_config->output[o] == output)
+ {
+ memmove (&xf86_config->output[o],
+ &xf86_config->output[o+1],
+ ((xf86_config->num_output - (o + 1)) * sizeof(void*)));
+ xf86_config->num_output--;
+ break;
+ }
+ if (output->name && output->name != (char *) (output + 1))
+ free(output->name);
+ free(output);
+}
+
+/*
+ * Called during CreateScreenResources to hook up RandR
+ */
+static Bool
+xf86CrtcCreateScreenResources (ScreenPtr screen)
+{
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+
+ screen->CreateScreenResources = config->CreateScreenResources;
+
+ if (!(*screen->CreateScreenResources)(screen))
+ return FALSE;
+
+ if (!xf86RandR12CreateScreenResources (screen))
+ return FALSE;
+
+ return TRUE;
+}
+
+/*
+ * Clean up config on server reset
+ */
+static Bool
+xf86CrtcCloseScreen (int index, ScreenPtr screen)
+{
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+ int o, c;
+
+ screen->CloseScreen = config->CloseScreen;
+
+ xf86RotateCloseScreen (screen);
+
+ for (o = 0; o < config->num_output; o++)
+ {
+ xf86OutputPtr output = config->output[o];
+
+ output->randr_output = NULL;
+ }
+ for (c = 0; c < config->num_crtc; c++)
+ {
+ xf86CrtcPtr crtc = config->crtc[c];
+
+ crtc->randr_crtc = NULL;
+ }
+ return screen->CloseScreen (index, screen);
+}
+
+/*
+ * Called at ScreenInit time to set up
+ */
+#ifdef RANDR_13_INTERFACE
+int
+#else
+Bool
+#endif
+xf86CrtcScreenInit (ScreenPtr screen)
+{
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+ int c;
+
+ /* Rotation */
+ xf86DrvMsg(scrn->scrnIndex, X_INFO, "RandR 1.2 enabled, ignore the following RandR disabled message.\n");
+ xf86DisableRandR(); /* Disable old RandR extension support */
+ xf86RandR12Init (screen);
+
+ /* support all rotations if every crtc has the shadow alloc funcs */
+ for (c = 0; c < config->num_crtc; c++)
+ {
+ xf86CrtcPtr crtc = config->crtc[c];
+ if (!crtc->funcs->shadow_allocate || !crtc->funcs->shadow_create)
+ break;
+ }
+ if (c == config->num_crtc)
+ {
+ xf86RandR12SetRotations (screen, RR_Rotate_0 | RR_Rotate_90 |
+ RR_Rotate_180 | RR_Rotate_270 |
+ RR_Reflect_X | RR_Reflect_Y);
+ xf86RandR12SetTransformSupport (screen, TRUE);
+ }
+ else
+ {
+ xf86RandR12SetRotations (screen, RR_Rotate_0);
+ xf86RandR12SetTransformSupport (screen, FALSE);
+ }
+
+ /* Wrap CreateScreenResources so we can initialize the RandR code */
+ config->CreateScreenResources = screen->CreateScreenResources;
+ screen->CreateScreenResources = xf86CrtcCreateScreenResources;
+
+ config->CloseScreen = screen->CloseScreen;
+ screen->CloseScreen = xf86CrtcCloseScreen;
+
+#ifdef XFreeXDGA
+ _xf86_di_dga_init_internal(screen);
+#endif
+#ifdef RANDR_13_INTERFACE
+ return RANDR_INTERFACE_VERSION;
+#else
+ return TRUE;
+#endif
+}
+
+static DisplayModePtr
+xf86DefaultMode (xf86OutputPtr output, int width, int height)
+{
+ DisplayModePtr target_mode = NULL;
+ DisplayModePtr mode;
+ int target_diff = 0;
+ int target_preferred = 0;
+ int mm_height;
+
+ mm_height = output->mm_height;
+ if (!mm_height)
+ mm_height = (768 * 25.4) / DEFAULT_DPI;
+ /*
+ * Pick a mode closest to DEFAULT_DPI
+ */
+ for (mode = output->probed_modes; mode; mode = mode->next)
+ {
+ int dpi;
+ int preferred = (((mode->type & M_T_PREFERRED) != 0) +
+ ((mode->type & M_T_USERPREF) != 0));
+ int diff;
+
+ if (xf86ModeWidth (mode, output->initial_rotation) > width ||
+ xf86ModeHeight (mode, output->initial_rotation) > height)
+ continue;
+
+ /* yes, use VDisplay here, not xf86ModeHeight */
+ dpi = (mode->VDisplay * 254) / (mm_height * 10);
+ diff = dpi - DEFAULT_DPI;
+ diff = diff < 0 ? -diff : diff;
+ if (target_mode == NULL || (preferred > target_preferred) ||
+ (preferred == target_preferred && diff < target_diff))
+ {
+ target_mode = mode;
+ target_diff = diff;
+ target_preferred = preferred;
+ }
+ }
+ return target_mode;
+}
+
+static DisplayModePtr
+xf86ClosestMode (xf86OutputPtr output,
+ DisplayModePtr match, Rotation match_rotation,
+ int width, int height)
+{
+ DisplayModePtr target_mode = NULL;
+ DisplayModePtr mode;
+ int target_diff = 0;
+
+ /*
+ * Pick a mode closest to the specified mode
+ */
+ for (mode = output->probed_modes; mode; mode = mode->next)
+ {
+ int dx, dy;
+ int diff;
+
+ if (xf86ModeWidth (mode, output->initial_rotation) > width ||
+ xf86ModeHeight (mode, output->initial_rotation) > height)
+ continue;
+
+ /* exact matches are preferred */
+ if (output->initial_rotation == match_rotation &&
+ xf86ModesEqual (mode, match))
+ return mode;
+
+ dx = xf86ModeWidth (match, match_rotation) - xf86ModeWidth (mode, output->initial_rotation);
+ dy = xf86ModeHeight (match, match_rotation) - xf86ModeHeight (mode, output->initial_rotation);
+ diff = dx * dx + dy * dy;
+ if (target_mode == NULL || diff < target_diff)
+ {
+ target_mode = mode;
+ target_diff = diff;
+ }
+ }
+ return target_mode;
+}
+
+static DisplayModePtr
+xf86OutputHasPreferredMode (xf86OutputPtr output, int width, int height)
+{
+ DisplayModePtr mode;
+
+ for (mode = output->probed_modes; mode; mode = mode->next)
+ {
+ if (xf86ModeWidth (mode, output->initial_rotation) > width ||
+ xf86ModeHeight (mode, output->initial_rotation) > height)
+ continue;
+
+ if (mode->type & M_T_PREFERRED)
+ return mode;
+ }
+ return NULL;
+}
+
+static DisplayModePtr
+xf86OutputHasUserPreferredMode (xf86OutputPtr output)
+{
+ DisplayModePtr mode, first = output->probed_modes;
+
+ for (mode = first; mode && mode->next != first; mode = mode->next)
+ if (mode->type & M_T_USERPREF)
+ return mode;
+
+ return NULL;
+}
+
+static int
+xf86PickCrtcs (ScrnInfoPtr scrn,
+ xf86CrtcPtr *best_crtcs,
+ DisplayModePtr *modes,
+ int n,
+ int width,
+ int height)
+{
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+ int c, o;
+ xf86OutputPtr output;
+ xf86CrtcPtr crtc;
+ xf86CrtcPtr *crtcs;
+ xf86CrtcPtr best_crtc;
+ int best_score;
+ int score;
+ int my_score;
+
+ if (n == config->num_output)
+ return 0;
+ output = config->output[n];
+
+ /*
+ * Compute score with this output disabled
+ */
+ best_crtcs[n] = NULL;
+ best_crtc = NULL;
+ best_score = xf86PickCrtcs (scrn, best_crtcs, modes, n+1, width, height);
+ if (modes[n] == NULL)
+ return best_score;
+
+ crtcs = malloc(config->num_output * sizeof (xf86CrtcPtr));
+ if (!crtcs)
+ return best_score;
+
+ my_score = 1;
+ /* Score outputs that are known to be connected higher */
+ if (output->status == XF86OutputStatusConnected)
+ my_score++;
+ /* Score outputs with preferred modes higher */
+ if (xf86OutputHasPreferredMode (output, width, height))
+ my_score++;
+ /*
+ * Select a crtc for this output and
+ * then attempt to configure the remaining
+ * outputs
+ */
+ for (c = 0; c < config->num_crtc; c++)
+ {
+ if ((output->possible_crtcs & (1 << c)) == 0)
+ continue;
+
+ crtc = config->crtc[c];
+ /*
+ * Check to see if some other output is
+ * using this crtc
+ */
+ for (o = 0; o < n; o++)
+ if (best_crtcs[o] == crtc)
+ break;
+ if (o < n)
+ {
+ /*
+ * If the two outputs desire the same mode,
+ * see if they can be cloned
+ */
+ if (xf86ModesEqual (modes[o], modes[n]) &&
+ config->output[o]->initial_rotation == config->output[n]->initial_rotation &&
+ config->output[o]->initial_x == config->output[n]->initial_x &&
+ config->output[o]->initial_y == config->output[n]->initial_y)
+ {
+ if ((output->possible_clones & (1 << o)) == 0)
+ continue; /* nope, try next CRTC */
+ }
+ else
+ continue; /* different modes, can't clone */
+ }
+ crtcs[n] = crtc;
+ memcpy (crtcs, best_crtcs, n * sizeof (xf86CrtcPtr));
+ score = my_score + xf86PickCrtcs (scrn, crtcs, modes, n+1, width, height);
+ if (score > best_score)
+ {
+ best_crtc = crtc;
+ best_score = score;
+ memcpy (best_crtcs, crtcs, config->num_output * sizeof (xf86CrtcPtr));
+ }
+ }
+ free(crtcs);
+ return best_score;
+}
+
+
+/*
+ * Compute the virtual size necessary to place all of the available
+ * crtcs in the specified configuration.
+ *
+ * canGrow indicates that the driver can make the screen larger than its initial
+ * configuration. If FALSE, this function will enlarge the screen to include
+ * the largest available mode.
+ */
+
+static void
+xf86DefaultScreenLimits (ScrnInfoPtr scrn, int *widthp, int *heightp,
+ Bool canGrow)
+{
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+ int width = 0, height = 0;
+ int o;
+ int c;
+ int s;
+
+ for (c = 0; c < config->num_crtc; c++)
+ {
+ int crtc_width = 0, crtc_height = 0;
+ xf86CrtcPtr crtc = config->crtc[c];
+
+ if (crtc->enabled)
+ {
+ crtc_width = crtc->x + xf86ModeWidth (&crtc->desiredMode, crtc->desiredRotation);
+ crtc_height = crtc->y + xf86ModeHeight (&crtc->desiredMode, crtc->desiredRotation);
+ }
+ if (!canGrow) {
+ for (o = 0; o < config->num_output; o++)
+ {
+ xf86OutputPtr output = config->output[o];
+
+ for (s = 0; s < config->num_crtc; s++)
+ if (output->possible_crtcs & (1 << s))
+ {
+ DisplayModePtr mode;
+ for (mode = output->probed_modes; mode; mode = mode->next)
+ {
+ if (mode->HDisplay > crtc_width)
+ crtc_width = mode->HDisplay;
+ if (mode->VDisplay > crtc_width)
+ crtc_width = mode->VDisplay;
+ if (mode->VDisplay > crtc_height)
+ crtc_height = mode->VDisplay;
+ if (mode->HDisplay > crtc_height)
+ crtc_height = mode->HDisplay;
+ }
+ }
+ }
+ }
+ if (crtc_width > width)
+ width = crtc_width;
+ if (crtc_height > height)
+ height = crtc_height;
+ }
+ if (config->maxWidth && width > config->maxWidth) width = config->maxWidth;
+ if (config->maxHeight && height > config->maxHeight) height = config->maxHeight;
+ if (config->minWidth && width < config->minWidth) width = config->minWidth;
+ if (config->minHeight && height < config->minHeight) height = config->minHeight;
+ *widthp = width;
+ *heightp = height;
+}
+
+#define POSITION_UNSET -100000
+
+/*
+ * check if the user configured any outputs at all
+ * with either a position or a relative setting or a mode.
+ */
+static Bool
+xf86UserConfiguredOutputs(ScrnInfoPtr scrn, DisplayModePtr *modes)
+{
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+ int o;
+ Bool user_conf = FALSE;
+
+ for (o = 0; o < config->num_output; o++)
+ {
+ xf86OutputPtr output = config->output[o];
+ char *position;
+ char *relative_name;
+ OutputOpts relation;
+ int r;
+ static const OutputOpts relations[] = {
+ OPTION_BELOW, OPTION_RIGHT_OF, OPTION_ABOVE, OPTION_LEFT_OF
+ };
+
+ position = xf86GetOptValString (output->options,
+ OPTION_POSITION);
+ if (position)
+ user_conf = TRUE;
+
+ relation = 0;
+ relative_name = NULL;
+ for (r = 0; r < 4; r++)
+ {
+ relation = relations[r];
+ relative_name = xf86GetOptValString (output->options,
+ relation);
+ if (relative_name)
+ break;
+ }
+ if (relative_name)
+ user_conf = TRUE;
+
+ modes[o] = xf86OutputHasUserPreferredMode(output);
+ if (modes[o])
+ user_conf = TRUE;
+ }
+
+ return user_conf;
+}
+
+static Bool
+xf86InitialOutputPositions (ScrnInfoPtr scrn, DisplayModePtr *modes)
+{
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+ int o;
+ int min_x, min_y;
+
+ for (o = 0; o < config->num_output; o++)
+ {
+ xf86OutputPtr output = config->output[o];
+
+ output->initial_x = output->initial_y = POSITION_UNSET;
+ }
+
+ /*
+ * Loop until all outputs are set
+ */
+ for (;;)
+ {
+ Bool any_set = FALSE;
+ Bool keep_going = FALSE;
+
+ for (o = 0; o < config->num_output; o++)
+ {
+ static const OutputOpts relations[] = {
+ OPTION_BELOW, OPTION_RIGHT_OF, OPTION_ABOVE, OPTION_LEFT_OF
+ };
+ xf86OutputPtr output = config->output[o];
+ xf86OutputPtr relative;
+ char *relative_name;
+ char *position;
+ OutputOpts relation;
+ int r;
+
+ if (output->initial_x != POSITION_UNSET)
+ continue;
+ position = xf86GetOptValString (output->options,
+ OPTION_POSITION);
+ /*
+ * Absolute position wins
+ */
+ if (position)
+ {
+ int x, y;
+ if (sscanf (position, "%d %d", &x, &y) == 2)
+ {
+ output->initial_x = x;
+ output->initial_y = y;
+ }
+ else
+ {
+ xf86DrvMsg (scrn->scrnIndex, X_ERROR,
+ "Output %s position not of form \"x y\"\n",
+ output->name);
+ output->initial_x = output->initial_y = 0;
+ }
+ any_set = TRUE;
+ continue;
+ }
+ /*
+ * Next comes relative positions
+ */
+ relation = 0;
+ relative_name = NULL;
+ for (r = 0; r < 4; r++)
+ {
+ relation = relations[r];
+ relative_name = xf86GetOptValString (output->options,
+ relation);
+ if (relative_name)
+ break;
+ }
+ if (relative_name)
+ {
+ int or;
+ relative = NULL;
+ for (or = 0; or < config->num_output; or++)
+ {
+ xf86OutputPtr out_rel = config->output[or];
+ XF86ConfMonitorPtr rel_mon = out_rel->conf_monitor;
+
+ if (rel_mon)
+ {
+ if (xf86nameCompare (rel_mon->mon_identifier,
+ relative_name) == 0)
+ {
+ relative = config->output[or];
+ break;
+ }
+ }
+ if (strcmp (out_rel->name, relative_name) == 0)
+ {
+ relative = config->output[or];
+ break;
+ }
+ }
+ if (!relative)
+ {
+ xf86DrvMsg (scrn->scrnIndex, X_ERROR,
+ "Cannot position output %s relative to unknown output %s\n",
+ output->name, relative_name);
+ output->initial_x = 0;
+ output->initial_y = 0;
+ any_set = TRUE;
+ continue;
+ }
+ if (!modes[or])
+ {
+ xf86DrvMsg (scrn->scrnIndex, X_ERROR,
+ "Cannot position output %s relative to output %s without modes\n",
+ output->name, relative_name);
+ output->initial_x = 0;
+ output->initial_y = 0;
+ any_set = TRUE;
+ continue;
+ }
+ if (relative->initial_x == POSITION_UNSET)
+ {
+ keep_going = TRUE;
+ continue;
+ }
+ output->initial_x = relative->initial_x;
+ output->initial_y = relative->initial_y;
+ switch (relation) {
+ case OPTION_BELOW:
+ output->initial_y += xf86ModeHeight (modes[or], relative->initial_rotation);
+ break;
+ case OPTION_RIGHT_OF:
+ output->initial_x += xf86ModeWidth (modes[or], relative->initial_rotation);
+ break;
+ case OPTION_ABOVE:
+ if (modes[o])
+ output->initial_y -= xf86ModeHeight (modes[o], output->initial_rotation);
+ break;
+ case OPTION_LEFT_OF:
+ if (modes[o])
+ output->initial_x -= xf86ModeWidth (modes[o], output->initial_rotation);
+ break;
+ default:
+ break;
+ }
+ any_set = TRUE;
+ continue;
+ }
+
+ /* Nothing set, just stick them at 0,0 */
+ output->initial_x = 0;
+ output->initial_y = 0;
+ any_set = TRUE;
+ }
+ if (!keep_going)
+ break;
+ if (!any_set)
+ {
+ for (o = 0; o < config->num_output; o++)
+ {
+ xf86OutputPtr output = config->output[o];
+ if (output->initial_x == POSITION_UNSET)
+ {
+ xf86DrvMsg (scrn->scrnIndex, X_ERROR,
+ "Output position loop. Moving %s to 0,0\n",
+ output->name);
+ output->initial_x = output->initial_y = 0;
+ break;
+ }
+ }
+ }
+ }
+
+ /*
+ * normalize positions
+ */
+ min_x = 1000000;
+ min_y = 1000000;
+ for (o = 0; o < config->num_output; o++)
+ {
+ xf86OutputPtr output = config->output[o];
+
+ if (output->initial_x < min_x)
+ min_x = output->initial_x;
+ if (output->initial_y < min_y)
+ min_y = output->initial_y;
+ }
+
+ for (o = 0; o < config->num_output; o++)
+ {
+ xf86OutputPtr output = config->output[o];
+
+ output->initial_x -= min_x;
+ output->initial_y -= min_y;
+ }
+ return TRUE;
+}
+
+static void
+xf86InitialPanning (ScrnInfoPtr scrn)
+{
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+ int o;
+
+ for (o = 0; o < config->num_output; o++)
+ {
+ xf86OutputPtr output = config->output[o];
+ char *panning = xf86GetOptValString (output->options, OPTION_PANNING);
+ int width, height, left, top;
+ int track_width, track_height, track_left, track_top;
+ int brdr[4];
+
+ memset (&output->initialTotalArea, 0, sizeof(BoxRec));
+ memset (&output->initialTrackingArea, 0, sizeof(BoxRec));
+ memset (output->initialBorder, 0, 4*sizeof(INT16));
+
+ if (! panning)
+ continue;
+
+ switch (sscanf (panning, "%dx%d+%d+%d/%dx%d+%d+%d/%d/%d/%d/%d",
+ &width, &height, &left, &top,
+ &track_width, &track_height, &track_left, &track_top,
+ &brdr[0], &brdr[1], &brdr[2], &brdr[3])) {
+ case 12:
+ output->initialBorder[0] = brdr[0];
+ output->initialBorder[1] = brdr[1];
+ output->initialBorder[2] = brdr[2];
+ output->initialBorder[3] = brdr[3];
+ /* fall through */
+ case 8:
+ output->initialTrackingArea.x1 = track_left;
+ output->initialTrackingArea.y1 = track_top;
+ output->initialTrackingArea.x2 = track_left + track_width;
+ output->initialTrackingArea.y2 = track_top + track_height;
+ /* fall through */
+ case 4:
+ output->initialTotalArea.x1 = left;
+ output->initialTotalArea.y1 = top;
+ /* fall through */
+ case 2:
+ output->initialTotalArea.x2 = output->initialTotalArea.x1 + width;
+ output->initialTotalArea.y2 = output->initialTotalArea.y1 + height;
+ break;
+ default:
+ xf86DrvMsg (scrn->scrnIndex, X_ERROR,
+ "Broken panning specification '%s' for output %s in config file\n",
+ panning, output->name);
+ }
+ }
+}
+
+/** Return - 0 + if a should be earlier, same or later than b in list
+ */
+static int
+xf86ModeCompare (DisplayModePtr a, DisplayModePtr b)
+{
+ int diff;
+
+ diff = ((b->type & M_T_PREFERRED) != 0) - ((a->type & M_T_PREFERRED) != 0);
+ if (diff)
+ return diff;
+ diff = b->HDisplay * b->VDisplay - a->HDisplay * a->VDisplay;
+ if (diff)
+ return diff;
+ diff = b->Clock - a->Clock;
+ return diff;
+}
+
+/**
+ * Insertion sort input in-place and return the resulting head
+ */
+static DisplayModePtr
+xf86SortModes (DisplayModePtr input)
+{
+ DisplayModePtr output = NULL, i, o, n, *op, prev;
+
+ /* sort by preferred status and pixel area */
+ while (input)
+ {
+ i = input;
+ input = input->next;
+ for (op = &output; (o = *op); op = &o->next)
+ if (xf86ModeCompare (o, i) > 0)
+ break;
+ i->next = *op;
+ *op = i;
+ }
+ /* prune identical modes */
+ for (o = output; o && (n = o->next); o = n)
+ {
+ if (!strcmp (o->name, n->name) && xf86ModesEqual (o, n))
+ {
+ o->next = n->next;
+ free(n->name);
+ free(n);
+ n = o;
+ }
+ }
+ /* hook up backward links */
+ prev = NULL;
+ for (o = output; o; o = o->next)
+ {
+ o->prev = prev;
+ prev = o;
+ }
+ return output;
+}
+
+static char *
+preferredMode(ScrnInfoPtr pScrn, xf86OutputPtr output)
+{
+ char *preferred_mode = NULL;
+
+ /* Check for a configured preference for a particular mode */
+ preferred_mode = xf86GetOptValString (output->options,
+ OPTION_PREFERRED_MODE);
+ if (preferred_mode)
+ return preferred_mode;
+
+ if (pScrn->display->modes && *pScrn->display->modes)
+ preferred_mode = *pScrn->display->modes;
+
+ return preferred_mode;
+}
+
+static void
+GuessRangeFromModes(MonPtr mon, DisplayModePtr mode)
+{
+ if (!mon || !mode)
+ return;
+
+ mon->nHsync = 1;
+ mon->hsync[0].lo = 1024.0;
+ mon->hsync[0].hi = 0.0;
+
+ mon->nVrefresh = 1;
+ mon->vrefresh[0].lo = 1024.0;
+ mon->vrefresh[0].hi = 0.0;
+
+ while (mode) {
+ if (!mode->HSync)
+ mode->HSync = ((float) mode->Clock ) / ((float) mode->HTotal);
+
+ if (!mode->VRefresh)
+ mode->VRefresh = (1000.0 * ((float) mode->Clock)) /
+ ((float) (mode->HTotal * mode->VTotal));
+
+ if (mode->HSync < mon->hsync[0].lo)
+ mon->hsync[0].lo = mode->HSync;
+
+ if (mode->HSync > mon->hsync[0].hi)
+ mon->hsync[0].hi = mode->HSync;
+
+ if (mode->VRefresh < mon->vrefresh[0].lo)
+ mon->vrefresh[0].lo = mode->VRefresh;
+
+ if (mode->VRefresh > mon->vrefresh[0].hi)
+ mon->vrefresh[0].hi = mode->VRefresh;
+
+ mode = mode->next;
+ }
+
+ /* stretch out the bottom to fit 640x480@60 */
+ if (mon->hsync[0].lo > 31.0)
+ mon->hsync[0].lo = 31.0;
+ if (mon->vrefresh[0].lo > 58.0)
+ mon->vrefresh[0].lo = 58.0;
+}
+
+enum det_monrec_source {
+ sync_config, sync_edid, sync_default
+};
+
+struct det_monrec_parameter {
+ MonRec *mon_rec;
+ int *max_clock;
+ Bool set_hsync;
+ Bool set_vrefresh;
+ enum det_monrec_source *sync_source;
+};
+
+static void handle_detailed_monrec(struct detailed_monitor_section *det_mon,
+ void *data)
+{
+ enum { sync_config, sync_edid, sync_default };
+ struct det_monrec_parameter *p;
+ p = (struct det_monrec_parameter *)data;
+
+ if (det_mon->type == DS_RANGES) {
+ struct monitor_ranges *ranges = &det_mon->section.ranges;
+ if (p->set_hsync && ranges->max_h) {
+ p->mon_rec->hsync[p->mon_rec->nHsync].lo = ranges->min_h;
+ p->mon_rec->hsync[p->mon_rec->nHsync].hi = ranges->max_h;
+ p->mon_rec->nHsync++;
+ if (*p->sync_source == sync_default)
+ *p->sync_source = sync_edid;
+ }
+ if (p->set_vrefresh && ranges->max_v) {
+ p->mon_rec->vrefresh[p->mon_rec->nVrefresh].lo = ranges->min_v;
+ p->mon_rec->vrefresh[p->mon_rec->nVrefresh].hi = ranges->max_v;
+ p->mon_rec->nVrefresh++;
+ if (*p->sync_source == sync_default)
+ *p->sync_source = sync_edid;
+ }
+ if (ranges->max_clock * 1000 > *p->max_clock)
+ *p->max_clock = ranges->max_clock * 1000;
+ }
+}
+
+void
+xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
+{
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+ int o;
+
+ /* When canGrow was TRUE in the initial configuration we have to
+ * compare against the maximum values so that we don't drop modes.
+ * When canGrow was FALSE, the maximum values would have been clamped
+ * anyway.
+ */
+ if (maxX == 0 || maxY == 0) {
+ maxX = config->maxWidth;
+ maxY = config->maxHeight;
+ }
+
+ /* Probe the list of modes for each output. */
+ for (o = 0; o < config->num_output; o++)
+ {
+ xf86OutputPtr output = config->output[o];
+ DisplayModePtr mode;
+ DisplayModePtr config_modes = NULL, output_modes, default_modes = NULL;
+ char *preferred_mode;
+ xf86MonPtr edid_monitor;
+ XF86ConfMonitorPtr conf_monitor;
+ MonRec mon_rec;
+ int min_clock = 0;
+ int max_clock = 0;
+ double clock;
+ Bool add_default_modes = TRUE;
+ Bool debug_modes = config->debug_modes ||
+ xf86Initialising;
+ enum det_monrec_source sync_source = sync_default;
+
+ while (output->probed_modes != NULL)
+ xf86DeleteMode(&output->probed_modes, output->probed_modes);
+
+ /*
+ * Check connection status
+ */
+ output->status = (*output->funcs->detect)(output);
+
+ if (output->status == XF86OutputStatusDisconnected &&
+ !xf86ReturnOptValBool(output->options, OPTION_ENABLE, FALSE))
+ {
+ xf86OutputSetEDID (output, NULL);
+ continue;
+ }
+
+ memset (&mon_rec, '\0', sizeof (mon_rec));
+
+ conf_monitor = output->conf_monitor;
+
+ if (conf_monitor)
+ {
+ int i;
+
+ for (i = 0; i < conf_monitor->mon_n_hsync; i++)
+ {
+ mon_rec.hsync[mon_rec.nHsync].lo = conf_monitor->mon_hsync[i].lo;
+ mon_rec.hsync[mon_rec.nHsync].hi = conf_monitor->mon_hsync[i].hi;
+ mon_rec.nHsync++;
+ sync_source = sync_config;
+ }
+ for (i = 0; i < conf_monitor->mon_n_vrefresh; i++)
+ {
+ mon_rec.vrefresh[mon_rec.nVrefresh].lo = conf_monitor->mon_vrefresh[i].lo;
+ mon_rec.vrefresh[mon_rec.nVrefresh].hi = conf_monitor->mon_vrefresh[i].hi;
+ mon_rec.nVrefresh++;
+ sync_source = sync_config;
+ }
+ config_modes = xf86GetMonitorModes (scrn, conf_monitor);
+ }
+
+ output_modes = (*output->funcs->get_modes) (output);
+
+ edid_monitor = output->MonInfo;
+
+ if (edid_monitor)
+ {
+ struct det_monrec_parameter p;
+ struct disp_features *features = &edid_monitor->features;
+
+ /* if display is not continuous-frequency, don't add default modes */
+ if (!GTF_SUPPORTED(features->msc))
+ add_default_modes = FALSE;
+
+ p.mon_rec = &mon_rec;
+ p.max_clock = &max_clock;
+ p.set_hsync = mon_rec.nHsync == 0;
+ p.set_vrefresh = mon_rec.nVrefresh == 0;
+ p.sync_source = &sync_source;
+
+ xf86ForEachDetailedBlock(edid_monitor,
+ handle_detailed_monrec,
+ &p);
+ }
+
+ if (xf86GetOptValFreq (output->options, OPTION_MIN_CLOCK,
+ OPTUNITS_KHZ, &clock))
+ min_clock = (int) clock;
+ if (xf86GetOptValFreq (output->options, OPTION_MAX_CLOCK,
+ OPTUNITS_KHZ, &clock))
+ max_clock = (int) clock;
+
+ /* If we still don't have a sync range, guess wildly */
+ if (!mon_rec.nHsync || !mon_rec.nVrefresh)
+ GuessRangeFromModes(&mon_rec, output_modes);
+
+ /*
+ * These limits will end up setting a 1024x768@60Hz mode by default,
+ * which seems like a fairly good mode to use when nothing else is
+ * specified
+ */
+ if (mon_rec.nHsync == 0)
+ {
+ mon_rec.hsync[0].lo = 31.0;
+ mon_rec.hsync[0].hi = 55.0;
+ mon_rec.nHsync = 1;
+ }
+ if (mon_rec.nVrefresh == 0)
+ {
+ mon_rec.vrefresh[0].lo = 58.0;
+ mon_rec.vrefresh[0].hi = 62.0;
+ mon_rec.nVrefresh = 1;
+ }
+
+ if (add_default_modes)
+ default_modes = xf86GetDefaultModes ();
+
+ /*
+ * If this is not an RB monitor, remove RB modes from the default
+ * pool. RB modes from the config or the monitor itself are fine.
+ */
+ if (!mon_rec.reducedblanking)
+ xf86ValidateModesReducedBlanking (scrn, default_modes);
+
+ if (sync_source == sync_config)
+ {
+ /*
+ * Check output and config modes against sync range from config file
+ */
+ xf86ValidateModesSync (scrn, output_modes, &mon_rec);
+ xf86ValidateModesSync (scrn, config_modes, &mon_rec);
+ }
+ /*
+ * Check default modes against sync range
+ */
+ xf86ValidateModesSync (scrn, default_modes, &mon_rec);
+ /*
+ * Check default modes against monitor max clock
+ */
+ if (max_clock) {
+ xf86ValidateModesClocks(scrn, default_modes,
+ &min_clock, &max_clock, 1);
+ xf86ValidateModesClocks(scrn, output_modes,
+ &min_clock, &max_clock, 1);
+ }
+
+ output->probed_modes = NULL;
+ output->probed_modes = xf86ModesAdd (output->probed_modes, config_modes);
+ output->probed_modes = xf86ModesAdd (output->probed_modes, output_modes);
+ output->probed_modes = xf86ModesAdd (output->probed_modes, default_modes);
+
+ /*
+ * Check all modes against max size, interlace, and doublescan
+ */
+ if (maxX && maxY)
+ xf86ValidateModesSize (scrn, output->probed_modes,
+ maxX, maxY, 0);
+
+ {
+ int flags = (output->interlaceAllowed ? V_INTERLACE : 0) |
+ (output->doubleScanAllowed ? V_DBLSCAN : 0);
+ xf86ValidateModesFlags (scrn, output->probed_modes, flags);
+ }
+
+ /*
+ * Check all modes against output
+ */
+ for (mode = output->probed_modes; mode != NULL; mode = mode->next)
+ if (mode->status == MODE_OK)
+ mode->status = (*output->funcs->mode_valid)(output, mode);
+
+ xf86PruneInvalidModes(scrn, &output->probed_modes, debug_modes);
+
+ output->probed_modes = xf86SortModes (output->probed_modes);
+
+ /* Check for a configured preference for a particular mode */
+ preferred_mode = preferredMode(scrn, output);
+
+ if (preferred_mode)
+ {
+ for (mode = output->probed_modes; mode; mode = mode->next)
+ {
+ if (!strcmp (preferred_mode, mode->name))
+ {
+ if (mode != output->probed_modes)
+ {
+ if (mode->prev)
+ mode->prev->next = mode->next;
+ if (mode->next)
+ mode->next->prev = mode->prev;
+ mode->next = output->probed_modes;
+ output->probed_modes->prev = mode;
+ mode->prev = NULL;
+ output->probed_modes = mode;
+ }
+ mode->type |= (M_T_PREFERRED|M_T_USERPREF);
+ break;
+ }
+ }
+ }
+
+ output->initial_rotation = xf86OutputInitialRotation (output);
+
+ if (debug_modes) {
+ if (output->probed_modes != NULL) {
+ xf86DrvMsg(scrn->scrnIndex, X_INFO,
+ "Printing probed modes for output %s\n",
+ output->name);
+ } else {
+ xf86DrvMsg(scrn->scrnIndex, X_INFO,
+ "No remaining probed modes for output %s\n",
+ output->name);
+ }
+ }
+ for (mode = output->probed_modes; mode != NULL; mode = mode->next)
+ {
+ /* The code to choose the best mode per pipe later on will require
+ * VRefresh to be set.
+ */
+ mode->VRefresh = xf86ModeVRefresh(mode);
+ xf86SetModeCrtc(mode, INTERLACE_HALVE_V);
+
+ if (debug_modes)
+ xf86PrintModeline(scrn->scrnIndex, mode);
+ }
+ }
+}
+
+
+/**
+ * Copy one of the output mode lists to the ScrnInfo record
+ */
+
+/* XXX where does this function belong? Here? */
+void
+xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr scrn, int *x, int *y);
+
+static DisplayModePtr
+biggestMode(DisplayModePtr a, DisplayModePtr b)
+{
+ int A, B;
+
+ if (!a)
+ return b;
+ if (!b)
+ return a;
+
+ A = a->HDisplay * a->VDisplay;
+ B = b->HDisplay * b->VDisplay;
+
+ if (A > B)
+ return a;
+
+ return b;
+}
+
+static xf86OutputPtr
+SetCompatOutput(xf86CrtcConfigPtr config)
+{
+ xf86OutputPtr output = NULL, test = NULL;
+ DisplayModePtr maxmode = NULL, testmode, mode;
+ int o, compat = -1, count, mincount = 0;
+
+ /* Look for one that's definitely connected */
+ for (o = 0; o < config->num_output; o++)
+ {
+ test = config->output[o];
+ if (!test->crtc)
+ continue;
+ if (test->status != XF86OutputStatusConnected)
+ continue;
+ if (!test->probed_modes)
+ continue;
+
+ testmode = mode = test->probed_modes;
+ for (count = 0; mode; mode = mode->next, count++)
+ testmode = biggestMode(testmode, mode);
+
+ if (!output) {
+ output = test;
+ compat = o;
+ maxmode = testmode;
+ mincount = count;
+ } else if (maxmode == biggestMode(maxmode, testmode)) {
+ output = test;
+ compat = o;
+ maxmode = testmode;
+ mincount = count;
+ } else if ((maxmode->HDisplay == testmode->HDisplay) &&
+ (maxmode->VDisplay == testmode->VDisplay) &&
+ count <= mincount) {
+ output = test;
+ compat = o;
+ maxmode = testmode;
+ mincount = count;
+ }
+ }
+
+ /* If we didn't find one, take anything we can get */
+ if (!output)
+ {
+ for (o = 0; o < config->num_output; o++)
+ {
+ test = config->output[o];
+ if (!test->crtc)
+ continue;
+ if (!test->probed_modes)
+ continue;
+
+ if (!output) {
+ output = test;
+ compat = o;
+ } else if (test->probed_modes->HDisplay < output->probed_modes->HDisplay) {
+ output = test;
+ compat = o;
+ }
+ }
+ }
+
+ if (compat >= 0) {
+ config->compat_output = compat;
+ } else {
+ /* Don't change the compat output when no valid outputs found */
+ output = config->output[config->compat_output];
+ }
+
+ return output;
+}
+
+void
+xf86SetScrnInfoModes (ScrnInfoPtr scrn)
+{
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+ xf86OutputPtr output;
+ xf86CrtcPtr crtc;
+ DisplayModePtr last, mode = NULL;
+
+ output = SetCompatOutput(config);
+
+ if (!output)
+ return; /* punt */
+
+ crtc = output->crtc;
+
+ /* Clear any existing modes from scrn->modes */
+ while (scrn->modes != NULL)
+ xf86DeleteMode(&scrn->modes, scrn->modes);
+
+ /* Set scrn->modes to the mode list for the 'compat' output */
+ scrn->modes = xf86DuplicateModes(scrn, output->probed_modes);
+
+ if (crtc) {
+ for (mode = scrn->modes; mode; mode = mode->next)
+ if (xf86ModesEqual (mode, &crtc->desiredMode))
+ break;
+ }
+
+ if (scrn->modes != NULL) {
+ /* For some reason, scrn->modes is circular, unlike the other mode
+ * lists. How great is that?
+ */
+ for (last = scrn->modes; last && last->next; last = last->next)
+ ;
+ last->next = scrn->modes;
+ scrn->modes->prev = last;
+ if (mode) {
+ while (scrn->modes != mode)
+ scrn->modes = scrn->modes->next;
+ }
+ }
+ scrn->currentMode = scrn->modes;
+#ifdef XFreeXDGA
+ if (scrn->pScreen)
+ _xf86_di_dga_reinit_internal(scrn->pScreen);
+#endif
+}
+
+static void
+xf86CollectEnabledOutputs(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
+ Bool *enabled)
+{
+ Bool any_enabled = FALSE;
+ int o;
+
+ for (o = 0; o < config->num_output; o++)
+ any_enabled |= enabled[o] = xf86OutputEnabled(config->output[o], TRUE);
+
+ if (!any_enabled) {
+ xf86DrvMsg(scrn->scrnIndex, X_WARNING,
+ "No outputs definitely connected, trying again...\n");
+
+ for (o = 0; o < config->num_output; o++)
+ enabled[o] = xf86OutputEnabled(config->output[o], FALSE);
+ }
+}
+
+static Bool
+nextEnabledOutput(xf86CrtcConfigPtr config, Bool *enabled, int *index)
+{
+ int o = *index;
+
+ for (o++; o < config->num_output; o++) {
+ if (enabled[o]) {
+ *index = o;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+static Bool
+aspectMatch(float a, float b)
+{
+ return fabs(1 - (a / b)) < 0.05;
+}
+
+static DisplayModePtr
+nextAspectMode(xf86OutputPtr o, DisplayModePtr last, float aspect)
+{
+ DisplayModePtr m = NULL;
+
+ if (!o)
+ return NULL;
+
+ if (!last)
+ m = o->probed_modes;
+ else
+ m = last->next;
+
+ for (; m; m = m->next)
+ if (aspectMatch(aspect, (float)m->HDisplay / (float)m->VDisplay))
+ return m;
+
+ return NULL;
+}
+
+static DisplayModePtr
+bestModeForAspect(xf86CrtcConfigPtr config, Bool *enabled, float aspect)
+{
+ int o = -1, p;
+ DisplayModePtr mode = NULL, test = NULL, match = NULL;
+
+ if (!nextEnabledOutput(config, enabled, &o))
+ return NULL;
+ while ((mode = nextAspectMode(config->output[o], mode, aspect))) {
+ test = mode;
+ for (p = o; nextEnabledOutput(config, enabled, &p); ) {
+ test = xf86OutputFindClosestMode(config->output[p], mode);
+ if (!test)
+ break;
+ if (test->HDisplay != mode->HDisplay ||
+ test->VDisplay != mode->VDisplay) {
+ test = NULL;
+ break;
+ }
+ }
+
+ /* if we didn't match it on all outputs, try the next one */
+ if (!test)
+ continue;
+
+ /* if it's bigger than the last one, save it */
+ if (!match || (test->HDisplay > match->HDisplay))
+ match = test;
+ }
+
+ /* return the biggest one found */
+ return match;
+}
+
+static Bool
+xf86TargetPreferred(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
+ DisplayModePtr *modes, Bool *enabled,
+ int width, int height)
+{
+ int o, p;
+ int max_pref_width = 0, max_pref_height = 0;
+ DisplayModePtr *preferred, *preferred_match;
+ Bool ret = FALSE;
+
+ preferred = xnfcalloc(config->num_output, sizeof(DisplayModePtr));
+ preferred_match = xnfcalloc(config->num_output, sizeof(DisplayModePtr));
+
+ /* Check if the preferred mode is available on all outputs */
+ for (p = -1; nextEnabledOutput(config, enabled, &p); ) {
+ Rotation r = config->output[p]->initial_rotation;
+ DisplayModePtr mode;
+ if ((preferred[p] = xf86OutputHasPreferredMode(config->output[p],
+ width, height))) {
+ int pref_width = xf86ModeWidth(preferred[p], r);
+ int pref_height = xf86ModeHeight(preferred[p], r);
+ Bool all_match = TRUE;
+
+ for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
+ Bool match = FALSE;
+ xf86OutputPtr output = config->output[o];
+ if (o == p)
+ continue;
+
+ for (mode = output->probed_modes; mode; mode = mode->next) {
+ Rotation r = output->initial_rotation;
+ if (xf86ModeWidth(mode, r) == pref_width &&
+ xf86ModeHeight(mode, r) == pref_height) {
+ preferred[o] = mode;
+ match = TRUE;
+ }
+ }
+
+ all_match &= match;
+ }
+
+ if (all_match &&
+ (pref_width*pref_height > max_pref_width*max_pref_height)) {
+ for (o = -1; nextEnabledOutput(config, enabled, &o); )
+ preferred_match[o] = preferred[o];
+ max_pref_width = pref_width;
+ max_pref_height = pref_height;
+ ret = TRUE;
+ }
+ }
+ }
+
+ /*
+ * If there's no preferred mode, but only one monitor, pick the
+ * biggest mode for its aspect ratio, assuming one exists.
+ */
+ if (!ret) do {
+ int i = 0;
+ float aspect = 0.0;
+
+ /* count the number of enabled outputs */
+ for (i = 0, p = -1; nextEnabledOutput(config, enabled, &p); i++) ;
+
+ if (i != 1)
+ break;
+
+ p = -1;
+ nextEnabledOutput(config, enabled, &p);
+ if (config->output[p]->mm_height)
+ aspect = (float)config->output[p]->mm_width /
+ (float)config->output[p]->mm_height;
+
+ if (aspect)
+ preferred_match[p] = bestModeForAspect(config, enabled, aspect);
+
+ if (preferred_match[p])
+ ret = TRUE;
+
+ } while (0);
+
+ if (ret) {
+ /* oh good, there is a match. stash the selected modes and return. */
+ memcpy(modes, preferred_match,
+ config->num_output * sizeof(DisplayModePtr));
+ }
+
+ free(preferred);
+ free(preferred_match);
+ return ret;
+}
+
+static Bool
+xf86TargetAspect(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
+ DisplayModePtr *modes, Bool *enabled,
+ int width, int height)
+{
+ int o;
+ float aspect = 0.0, *aspects;
+ xf86OutputPtr output;
+ Bool ret = FALSE;
+ DisplayModePtr guess = NULL, aspect_guess = NULL, base_guess = NULL;
+
+ aspects = xnfcalloc(config->num_output, sizeof(float));
+
+ /* collect the aspect ratios */
+ for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
+ output = config->output[o];
+ if (output->mm_height)
+ aspects[o] = (float)output->mm_width / (float)output->mm_height;
+ else
+ aspects[o] = 4.0 / 3.0;
+ }
+
+ /* check that they're all the same */
+ for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
+ output = config->output[o];
+ if (!aspect) {
+ aspect = aspects[o];
+ } else if (!aspectMatch(aspect, aspects[o])) {
+ goto no_aspect_match;
+ }
+ }
+
+ /* if they're all 4:3, just skip ahead and save effort */
+ if (!aspectMatch(aspect, 4.0/3.0))
+ aspect_guess = bestModeForAspect(config, enabled, aspect);
+
+no_aspect_match:
+ base_guess = bestModeForAspect(config, enabled, 4.0/3.0);
+
+ guess = biggestMode(base_guess, aspect_guess);
+
+ if (!guess)
+ goto out;
+
+ /* found a mode that works everywhere, now apply it */
+ for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
+ modes[o] = xf86OutputFindClosestMode(config->output[o], guess);
+ }
+ ret = TRUE;
+
+out:
+ free(aspects);
+ return ret;
+}
+
+static Bool
+xf86TargetFallback(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
+ DisplayModePtr *modes, Bool *enabled,
+ int width, int height)
+{
+ DisplayModePtr target_mode = NULL;
+ Rotation target_rotation = RR_Rotate_0;
+ DisplayModePtr default_mode;
+ int default_preferred, target_preferred = 0, o;
+
+ /* User preferred > preferred > other modes */
+ for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
+ default_mode = xf86DefaultMode (config->output[o], width, height);
+ if (!default_mode)
+ continue;
+
+ default_preferred = (((default_mode->type & M_T_PREFERRED) != 0) +
+ ((default_mode->type & M_T_USERPREF) != 0));
+
+ if (default_preferred > target_preferred || !target_mode) {
+ target_mode = default_mode;
+ target_preferred = default_preferred;
+ target_rotation = config->output[o]->initial_rotation;
+ config->compat_output = o;
+ }
+ }
+
+ if (target_mode)
+ modes[config->compat_output] = target_mode;
+
+ /* Fill in other output modes */
+ for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
+ if (!modes[o])
+ modes[o] = xf86ClosestMode(config->output[o], target_mode,
+ target_rotation, width, height);
+ }
+
+ return (target_mode != NULL);
+}
+
+static Bool
+xf86TargetUserpref(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
+ DisplayModePtr *modes, Bool *enabled,
+ int width, int height)
+{
+ int o;
+
+ if (xf86UserConfiguredOutputs(scrn, modes))
+ return xf86TargetFallback(scrn, config, modes, enabled, width, height);
+
+ for (o = -1; nextEnabledOutput(config, enabled, &o); )
+ if (xf86OutputHasUserPreferredMode(config->output[o]))
+ return
+ xf86TargetFallback(scrn, config, modes, enabled, width, height);
+
+ return FALSE;
+}
+
+static Bool
+xf86CrtcSetInitialGamma(xf86CrtcPtr crtc, float gamma_red, float gamma_green,
+ float gamma_blue)
+{
+ int i, size = 256;
+ CARD16 *red, *green, *blue;
+
+ red = malloc(3 * size * sizeof(CARD16));
+ green = red + size;
+ blue = green + size;
+
+ /* Only cause warning if user wanted gamma to be set. */
+ if (!crtc->funcs->gamma_set && (gamma_red != 1.0 || gamma_green != 1.0 || gamma_blue != 1.0)) {
+ free(red);
+ return FALSE;
+ } else if (!crtc->funcs->gamma_set) {
+ free(red);
+ return TRUE;
+ }
+
+ /* At this early stage none of the randr-interface stuff is up.
+ * So take the default gamma size for lack of something better.
+ */
+ for (i = 0; i < size; i++) {
+ if (gamma_red == 1.0)
+ red[i] = i << 8;
+ else
+ red[i] = (CARD16)(pow((double)i/(double)(size - 1),
+ 1. / (double)gamma_red) * (double)(size - 1) * 256);
+
+ if (gamma_green == 1.0)
+ green[i] = i << 8;
+ else
+ green[i] = (CARD16)(pow((double)i/(double)(size - 1),
+ 1. / (double)gamma_green) * (double)(size - 1) * 256);
+
+ if (gamma_blue == 1.0)
+ blue[i] = i << 8;
+ else
+ blue[i] = (CARD16)(pow((double)i/(double)(size - 1),
+ 1. / (double)gamma_blue) * (double)(size - 1) * 256);
+ }
+
+ /* Default size is 256, so anything else is failure. */
+ if (size != crtc->gamma_size) {
+ free(red);
+ return FALSE;
+ }
+
+ crtc->gamma_size = size;
+ memcpy (crtc->gamma_red, red, crtc->gamma_size * sizeof (CARD16));
+ memcpy (crtc->gamma_green, green, crtc->gamma_size * sizeof (CARD16));
+ memcpy (crtc->gamma_blue, blue, crtc->gamma_size * sizeof (CARD16));
+
+ /* Do not set gamma now, delay until the crtc is activated. */
+
+ free(red);
+
+ return TRUE;
+}
+
+static Bool
+xf86OutputSetInitialGamma(xf86OutputPtr output)
+{
+ XF86ConfMonitorPtr mon = output->conf_monitor;
+ float gamma_red = 1.0, gamma_green = 1.0, gamma_blue = 1.0;
+
+ if (!mon)
+ return TRUE;
+
+ if (!output->crtc)
+ return FALSE;
+
+ /* Get configured values, where they exist. */
+ if (mon->mon_gamma_red >= GAMMA_MIN &&
+ mon->mon_gamma_red <= GAMMA_MAX)
+ gamma_red = mon->mon_gamma_red;
+
+ if (mon->mon_gamma_green >= GAMMA_MIN &&
+ mon->mon_gamma_green <= GAMMA_MAX)
+ gamma_green = mon->mon_gamma_green;
+
+ if (mon->mon_gamma_blue >= GAMMA_MIN &&
+ mon->mon_gamma_blue <= GAMMA_MAX)
+ gamma_blue = mon->mon_gamma_blue;
+
+ /* This avoids setting gamma 1.0 in case another cloned output on this crtc has a specific gamma. */
+ if (gamma_red != 1.0 || gamma_green != 1.0 || gamma_blue != 1.0) {
+ xf86DrvMsg(output->scrn->scrnIndex, X_INFO, "Output %s wants gamma correction (%.1f, %.1f, %.1f)\n", output->name, gamma_red, gamma_green, gamma_blue);
+ return xf86CrtcSetInitialGamma(output->crtc, gamma_red, gamma_green, gamma_blue);
+ }else
+ return TRUE;
+}
+
+/**
+ * Construct default screen configuration
+ *
+ * Given auto-detected (and, eventually, configured) values,
+ * construct a usable configuration for the system
+ *
+ * canGrow indicates that the driver can resize the screen to larger than its
+ * initially configured size via the config->funcs->resize hook. If TRUE, this
+ * function will set virtualX and virtualY to match the initial configuration
+ * and leave config->max{Width,Height} alone. If FALSE, it will bloat
+ * virtual[XY] to include the largest modes and set config->max{Width,Height}
+ * accordingly.
+ */
+
+Bool
+xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow)
+{
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+ int o, c;
+ xf86CrtcPtr *crtcs;
+ DisplayModePtr *modes;
+ Bool *enabled;
+ int width, height;
+ int i = scrn->scrnIndex;
+
+ /* Set up the device options */
+ config->options = xnfalloc (sizeof (xf86DeviceOptions));
+ memcpy (config->options, xf86DeviceOptions, sizeof (xf86DeviceOptions));
+ xf86ProcessOptions (scrn->scrnIndex,
+ scrn->options,
+ config->options);
+ config->debug_modes = xf86ReturnOptValBool (config->options,
+ OPTION_MODEDEBUG, FALSE);
+
+ if (scrn->display->virtualX)
+ width = scrn->display->virtualX;
+ else
+ width = config->maxWidth;
+ if (scrn->display->virtualY)
+ height = scrn->display->virtualY;
+ else
+ height = config->maxHeight;
+
+ xf86ProbeOutputModes (scrn, width, height);
+
+ crtcs = xnfcalloc (config->num_output, sizeof (xf86CrtcPtr));
+ modes = xnfcalloc (config->num_output, sizeof (DisplayModePtr));
+ enabled = xnfcalloc (config->num_output, sizeof (Bool));
+
+ xf86CollectEnabledOutputs(scrn, config, enabled);
+
+ if (xf86TargetUserpref(scrn, config, modes, enabled, width, height))
+ xf86DrvMsg(i, X_INFO, "Using user preference for initial modes\n");
+ else if (xf86TargetPreferred(scrn, config, modes, enabled, width, height))
+ xf86DrvMsg(i, X_INFO, "Using exact sizes for initial modes\n");
+ else if (xf86TargetAspect(scrn, config, modes, enabled, width, height))
+ xf86DrvMsg(i, X_INFO, "Using fuzzy aspect match for initial modes\n");
+ else if (xf86TargetFallback(scrn, config, modes, enabled, width, height))
+ xf86DrvMsg(i, X_INFO, "Using sloppy heuristic for initial modes\n");
+ else
+ xf86DrvMsg(i, X_WARNING, "Unable to find initial modes\n");
+
+ for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
+ if (!modes[o])
+ xf86DrvMsg (scrn->scrnIndex, X_ERROR,
+ "Output %s enabled but has no modes\n",
+ config->output[o]->name);
+ else
+ xf86DrvMsg (scrn->scrnIndex, X_INFO,
+ "Output %s using initial mode %s\n",
+ config->output[o]->name, modes[o]->name);
+ }
+
+ /*
+ * Set the position of each output
+ */
+ if (!xf86InitialOutputPositions (scrn, modes))
+ {
+ free(crtcs);
+ free(modes);
+ return FALSE;
+ }
+
+ /*
+ * Set initial panning of each output
+ */
+ xf86InitialPanning (scrn);
+
+ /*
+ * Assign CRTCs to fit output configuration
+ */
+ if (!xf86PickCrtcs (scrn, crtcs, modes, 0, width, height))
+ {
+ free(crtcs);
+ free(modes);
+ return FALSE;
+ }
+
+ /* XXX override xf86 common frame computation code */
+
+ scrn->display->frameX0 = 0;
+ scrn->display->frameY0 = 0;
+
+ for (c = 0; c < config->num_crtc; c++)
+ {
+ xf86CrtcPtr crtc = config->crtc[c];
+
+ crtc->enabled = FALSE;
+ memset (&crtc->desiredMode, '\0', sizeof (crtc->desiredMode));
+ /* Set default gamma for all crtc's. */
+ /* This is done to avoid problems later on with cloned outputs. */
+ xf86CrtcSetInitialGamma(crtc, 1.0, 1.0, 1.0);
+ }
+
+ if (xf86_crtc_supports_gamma(scrn))
+ xf86DrvMsg(scrn->scrnIndex, X_INFO, "Using default gamma of (1.0, 1.0, 1.0) unless otherwise stated.\n");
+
+ /*
+ * Set initial configuration
+ */
+ for (o = 0; o < config->num_output; o++)
+ {
+ xf86OutputPtr output = config->output[o];
+ DisplayModePtr mode = modes[o];
+ xf86CrtcPtr crtc = crtcs[o];
+
+ if (mode && crtc)
+ {
+ crtc->desiredMode = *mode;
+ crtc->desiredRotation = output->initial_rotation;
+ crtc->desiredX = output->initial_x;
+ crtc->desiredY = output->initial_y;
+ crtc->desiredTransformPresent = FALSE;
+ crtc->enabled = TRUE;
+ memcpy (&crtc->panningTotalArea, &output->initialTotalArea, sizeof(BoxRec));
+ memcpy (&crtc->panningTrackingArea, &output->initialTrackingArea, sizeof(BoxRec));
+ memcpy (crtc->panningBorder, output->initialBorder, 4*sizeof(INT16));
+ output->crtc = crtc;
+ if (!xf86OutputSetInitialGamma(output))
+ xf86DrvMsg (scrn->scrnIndex, X_WARNING, "Initial gamma correction for output %s: failed.\n", output->name);
+ } else {
+ output->crtc = NULL;
+ }
+ }
+
+ if (scrn->display->virtualX == 0)
+ {
+ /*
+ * Expand virtual size to cover the current config and potential mode
+ * switches, if the driver can't enlarge the screen later.
+ */
+ xf86DefaultScreenLimits (scrn, &width, &height, canGrow);
+
+ scrn->display->virtualX = width;
+ scrn->display->virtualY = height;
+ }
+
+ if (width > scrn->virtualX)
+ scrn->virtualX = width;
+ if (height > scrn->virtualY)
+ scrn->virtualY = height;
+
+ /*
+ * Make sure the configuration isn't too small.
+ */
+ if (width < config->minWidth || height < config->minHeight)
+ return FALSE;
+
+ /*
+ * Limit the crtc config to virtual[XY] if the driver can't grow the
+ * desktop.
+ */
+ if (!canGrow)
+ {
+ xf86CrtcSetSizeRange (scrn, config->minWidth, config->minHeight,
+ width, height);
+ }
+
+ /* Mirror output modes to scrn mode list */
+ xf86SetScrnInfoModes (scrn);
+
+ free(crtcs);
+ free(modes);
+ return TRUE;
+}
+
+/*
+ * Check the CRTC we're going to map each output to vs. it's current
+ * CRTC. If they don't match, we have to disable the output and the CRTC
+ * since the driver will have to re-route things.
+ */
+static void
+xf86PrepareOutputs (ScrnInfoPtr scrn)
+{
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+ int o;
+
+ for (o = 0; o < config->num_output; o++) {
+ xf86OutputPtr output = config->output[o];
+#if RANDR_GET_CRTC_INTERFACE
+ /* Disable outputs that are unused or will be re-routed */
+ if (!output->funcs->get_crtc ||
+ output->crtc != (*output->funcs->get_crtc)(output) ||
+ output->crtc == NULL)
+#endif
+ (*output->funcs->dpms)(output, DPMSModeOff);
+ }
+}
+
+static void
+xf86PrepareCrtcs (ScrnInfoPtr scrn)
+{
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+ int c;
+
+ for (c = 0; c < config->num_crtc; c++) {
+#if RANDR_GET_CRTC_INTERFACE
+ xf86CrtcPtr crtc = config->crtc[c];
+ xf86OutputPtr output = NULL;
+ uint32_t desired_outputs = 0, current_outputs = 0;
+ int o;
+
+ for (o = 0; o < config->num_output; o++) {
+ output = config->output[o];
+ if (output->crtc == crtc)
+ desired_outputs |= (1<<o);
+ /* If we can't tell where it's mapped, force it off */
+ if (!output->funcs->get_crtc) {
+ desired_outputs = 0;
+ break;
+ }
+ if ((*output->funcs->get_crtc)(output) == crtc)
+ current_outputs |= (1<<o);
+ }
+
+ /*
+ * If mappings are different or the CRTC is unused,
+ * we need to disable it
+ */
+ if (desired_outputs != current_outputs ||
+ !desired_outputs)
+ (*crtc->funcs->dpms)(crtc, DPMSModeOff);
+#else
+ (*crtc->funcs->dpms)(crtc, DPMSModeOff);
+#endif
+ }
+}
+
+/*
+ * Using the desired mode information in each crtc, set
+ * modes (used in EnterVT functions, or at server startup)
+ */
+
+Bool
+xf86SetDesiredModes (ScrnInfoPtr scrn)
+{
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+ xf86CrtcPtr crtc = config->crtc[0];
+ int c;
+
+ /* A driver with this hook will take care of this */
+ if (!crtc->funcs->set_mode_major) {
+ xf86PrepareOutputs(scrn);
+ xf86PrepareCrtcs(scrn);
+ }
+
+ for (c = 0; c < config->num_crtc; c++)
+ {
+ xf86OutputPtr output = NULL;
+ int o;
+ RRTransformPtr transform;
+
+ crtc = config->crtc[c];
+
+ /* Skip disabled CRTCs */
+ if (!crtc->enabled)
+ continue;
+
+ if (xf86CompatOutput(scrn) && xf86CompatCrtc(scrn) == crtc)
+ output = xf86CompatOutput(scrn);
+ else
+ {
+ for (o = 0; o < config->num_output; o++)
+ if (config->output[o]->crtc == crtc)
+ {
+ output = config->output[o];
+ break;
+ }
+ }
+ /* paranoia */
+ if (!output)
+ continue;
+
+ /* Mark that we'll need to re-set the mode for sure */
+ memset(&crtc->mode, 0, sizeof(crtc->mode));
+ if (!crtc->desiredMode.CrtcHDisplay)
+ {
+ DisplayModePtr mode = xf86OutputFindClosestMode (output, scrn->currentMode);
+
+ if (!mode)
+ return FALSE;
+ crtc->desiredMode = *mode;
+ crtc->desiredRotation = RR_Rotate_0;
+ crtc->desiredTransformPresent = FALSE;
+ crtc->desiredX = 0;
+ crtc->desiredY = 0;
+ }
+
+ if (crtc->desiredTransformPresent)
+ transform = &crtc->desiredTransform;
+ else
+ transform = NULL;
+ if (!xf86CrtcSetModeTransform (crtc, &crtc->desiredMode, crtc->desiredRotation,
+ transform, crtc->desiredX, crtc->desiredY))
+ return FALSE;
+ }
+
+ xf86DisableUnusedFunctions(scrn);
+ return TRUE;
+}
+
+/**
+ * In the current world order, there are lists of modes per output, which may
+ * or may not include the mode that was asked to be set by XFree86's mode
+ * selection. Find the closest one, in the following preference order:
+ *
+ * - Equality
+ * - Closer in size to the requested mode, but no larger
+ * - Closer in refresh rate to the requested mode.
+ */
+
+DisplayModePtr
+xf86OutputFindClosestMode (xf86OutputPtr output, DisplayModePtr desired)
+{
+ DisplayModePtr best = NULL, scan = NULL;
+
+ for (scan = output->probed_modes; scan != NULL; scan = scan->next)
+ {
+ /* If there's an exact match, we're done. */
+ if (xf86ModesEqual(scan, desired)) {
+ best = desired;
+ break;
+ }
+
+ /* Reject if it's larger than the desired mode. */
+ if (scan->HDisplay > desired->HDisplay ||
+ scan->VDisplay > desired->VDisplay)
+ {
+ continue;
+ }
+
+ /*
+ * If we haven't picked a best mode yet, use the first
+ * one in the size range
+ */
+ if (best == NULL)
+ {
+ best = scan;
+ continue;
+ }
+
+ /* Find if it's closer to the right size than the current best
+ * option.
+ */
+ if ((scan->HDisplay > best->HDisplay &&
+ scan->VDisplay >= best->VDisplay) ||
+ (scan->HDisplay >= best->HDisplay &&
+ scan->VDisplay > best->VDisplay))
+ {
+ best = scan;
+ continue;
+ }
+
+ /* Find if it's still closer to the right refresh than the current
+ * best resolution.
+ */
+ if (scan->HDisplay == best->HDisplay &&
+ scan->VDisplay == best->VDisplay &&
+ (fabs(scan->VRefresh - desired->VRefresh) <
+ fabs(best->VRefresh - desired->VRefresh))) {
+ best = scan;
+ }
+ }
+ return best;
+}
+
+/**
+ * When setting a mode through XFree86-VidModeExtension or XFree86-DGA,
+ * take the specified mode and apply it to the crtc connected to the compat
+ * output. Then, find similar modes for the other outputs, as with the
+ * InitialConfiguration code above. The goal is to clone the desired
+ * mode across all outputs that are currently active.
+ */
+
+Bool
+xf86SetSingleMode (ScrnInfoPtr pScrn, DisplayModePtr desired, Rotation rotation)
+{
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ Bool ok = TRUE;
+ xf86OutputPtr compat_output;
+ DisplayModePtr compat_mode = NULL;
+ int c;
+
+ /*
+ * Let the compat output drive the final mode selection
+ */
+ compat_output = xf86CompatOutput(pScrn);
+ if (compat_output)
+ compat_mode = xf86OutputFindClosestMode (compat_output, desired);
+ if (compat_mode)
+ desired = compat_mode;
+
+ for (c = 0; c < config->num_crtc; c++)
+ {
+ xf86CrtcPtr crtc = config->crtc[c];
+ DisplayModePtr crtc_mode = NULL;
+ int o;
+
+ if (!crtc->enabled)
+ continue;
+
+ for (o = 0; o < config->num_output; o++)
+ {
+ xf86OutputPtr output = config->output[o];
+ DisplayModePtr output_mode;
+
+ /* skip outputs not on this crtc */
+ if (output->crtc != crtc)
+ continue;
+
+ if (crtc_mode)
+ {
+ output_mode = xf86OutputFindClosestMode (output, crtc_mode);
+ if (output_mode != crtc_mode)
+ output->crtc = NULL;
+ }
+ else
+ crtc_mode = xf86OutputFindClosestMode (output, desired);
+ }
+ if (!crtc_mode)
+ {
+ crtc->enabled = FALSE;
+ continue;
+ }
+ if (!xf86CrtcSetModeTransform (crtc, crtc_mode, rotation, NULL, 0, 0))
+ ok = FALSE;
+ else
+ {
+ crtc->desiredMode = *crtc_mode;
+ crtc->desiredRotation = rotation;
+ crtc->desiredTransformPresent = FALSE;
+ crtc->desiredX = 0;
+ crtc->desiredY = 0;
+ }
+ }
+ xf86DisableUnusedFunctions(pScrn);
+#ifdef RANDR_12_INTERFACE
+ xf86RandR12TellChanged (pScrn->pScreen);
+#endif
+ return ok;
+}
+
+
+/**
+ * Set the DPMS power mode of all outputs and CRTCs.
+ *
+ * If the new mode is off, it will turn off outputs and then CRTCs.
+ * Otherwise, it will affect CRTCs before outputs.
+ */
+void
+xf86DPMSSet(ScrnInfoPtr scrn, int mode, int flags)
+{
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+ int i;
+
+ if (!scrn->vtSema)
+ return;
+
+ if (mode == DPMSModeOff) {
+ for (i = 0; i < config->num_output; i++) {
+ xf86OutputPtr output = config->output[i];
+ if (output->crtc != NULL)
+ (*output->funcs->dpms) (output, mode);
+ }
+ }
+
+ for (i = 0; i < config->num_crtc; i++) {
+ xf86CrtcPtr crtc = config->crtc[i];
+ if (crtc->enabled)
+ (*crtc->funcs->dpms) (crtc, mode);
+ }
+
+ if (mode != DPMSModeOff) {
+ for (i = 0; i < config->num_output; i++) {
+ xf86OutputPtr output = config->output[i];
+ if (output->crtc != NULL)
+ (*output->funcs->dpms) (output, mode);
+ }
+ }
+}
+
+/**
+ * Implement the screensaver by just calling down into the driver DPMS hooks.
+ *
+ * Even for monitors with no DPMS support, by the definition of our DPMS hooks,
+ * the outputs will still get disabled (blanked).
+ */
+Bool
+xf86SaveScreen(ScreenPtr pScreen, int mode)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+
+ if (xf86IsUnblank(mode))
+ xf86DPMSSet(pScrn, DPMSModeOn, 0);
+ else
+ xf86DPMSSet(pScrn, DPMSModeOff, 0);
+
+ return TRUE;
+}
+
+/**
+ * Disable all inactive crtcs and outputs
+ */
+void
+xf86DisableUnusedFunctions(ScrnInfoPtr pScrn)
+{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int o, c;
+
+ for (o = 0; o < xf86_config->num_output; o++)
+ {
+ xf86OutputPtr output = xf86_config->output[o];
+ if (!output->crtc)
+ (*output->funcs->dpms)(output, DPMSModeOff);
+ }
+
+ for (c = 0; c < xf86_config->num_crtc; c++)
+ {
+ xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+ if (!crtc->enabled)
+ {
+ crtc->funcs->dpms(crtc, DPMSModeOff);
+ memset(&crtc->mode, 0, sizeof(crtc->mode));
+ xf86RotateDestroy(crtc);
+ crtc->active = FALSE;
+ }
+ }
+ if (pScrn->pScreen)
+ xf86_crtc_notify(pScrn->pScreen);
+}
+
+#ifdef RANDR_12_INTERFACE
+
+#define EDID_ATOM_NAME "EDID"
+
+/**
+ * Set the RandR EDID property
+ */
+static void
+xf86OutputSetEDIDProperty (xf86OutputPtr output, void *data, int data_len)
+{
+ Atom edid_atom = MakeAtom(EDID_ATOM_NAME, sizeof(EDID_ATOM_NAME) - 1, TRUE);
+
+ /* This may get called before the RandR resources have been created */
+ if (output->randr_output == NULL)
+ return;
+
+ if (data_len != 0) {
+ RRChangeOutputProperty(output->randr_output, edid_atom, XA_INTEGER, 8,
+ PropModeReplace, data_len, data, FALSE, TRUE);
+ } else {
+ RRDeleteOutputProperty(output->randr_output, edid_atom);
+ }
+}
+
+#endif
+
+/* Pull out a phyiscal size from a detailed timing if available. */
+struct det_phySize_parameter {
+ xf86OutputPtr output;
+ ddc_quirk_t quirks;
+ Bool ret;
+};
+
+static void handle_detailed_physical_size(struct detailed_monitor_section
+ *det_mon, void *data)
+{
+ struct det_phySize_parameter *p;
+ p = (struct det_phySize_parameter *)data;
+
+ if (p->ret == TRUE )
+ return ;
+
+ xf86DetTimingApplyQuirks(det_mon, p->quirks,
+ p->output->MonInfo->features.hsize,
+ p->output->MonInfo->features.vsize);
+ if (det_mon->type == DT &&
+ det_mon->section.d_timings.h_size != 0 &&
+ det_mon->section.d_timings.v_size != 0) {
+
+ p->output->mm_width = det_mon->section.d_timings.h_size;
+ p->output->mm_height = det_mon->section.d_timings.v_size;
+ p->ret = TRUE;
+ }
+}
+
+/**
+ * Set the EDID information for the specified output
+ */
+void
+xf86OutputSetEDID (xf86OutputPtr output, xf86MonPtr edid_mon)
+{
+ ScrnInfoPtr scrn = output->scrn;
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+ Bool debug_modes = config->debug_modes || xf86Initialising;
+#ifdef RANDR_12_INTERFACE
+ int size;
+#endif
+
+ if (output->MonInfo != NULL)
+ free(output->MonInfo);
+
+ output->MonInfo = edid_mon;
+
+ if (debug_modes) {
+ xf86DrvMsg(scrn->scrnIndex, X_INFO, "EDID for output %s\n",
+ output->name);
+ xf86PrintEDID(edid_mon);
+ }
+
+ /* Set the DDC properties for the 'compat' output */
+ if (output == xf86CompatOutput(scrn))
+ xf86SetDDCproperties(scrn, edid_mon);
+
+#ifdef RANDR_12_INTERFACE
+ /* Set the RandR output properties */
+ size = 0;
+ if (edid_mon)
+ {
+ if (edid_mon->ver.version == 1) {
+ size = 128;
+ if (edid_mon->flags & EDID_COMPLETE_RAWDATA)
+ size += edid_mon->no_sections * 128;
+ } else if (edid_mon->ver.version == 2)
+ size = 256;
+ }
+ xf86OutputSetEDIDProperty (output, edid_mon ? edid_mon->rawData : NULL, size);
+#endif
+
+ if (edid_mon) {
+
+ struct det_phySize_parameter p;
+ p.output = output;
+ p.quirks = xf86DDCDetectQuirks(scrn->scrnIndex,edid_mon, FALSE);
+ p.ret = FALSE;
+ xf86ForEachDetailedBlock(edid_mon,
+ handle_detailed_physical_size, &p);
+
+ /* if no mm size is available from a detailed timing, check the max size field */
+ if ((!output->mm_width || !output->mm_height) &&
+ (edid_mon->features.hsize && edid_mon->features.vsize))
+ {
+ output->mm_width = edid_mon->features.hsize * 10;
+ output->mm_height = edid_mon->features.vsize * 10;
+ }
+ }
+}
+
+/**
+ * Return the list of modes supported by the EDID information
+ * stored in 'output'
+ */
+DisplayModePtr
+xf86OutputGetEDIDModes (xf86OutputPtr output)
+{
+ ScrnInfoPtr scrn = output->scrn;
+ xf86MonPtr edid_mon = output->MonInfo;
+
+ if (!edid_mon)
+ return NULL;
+ return xf86DDCGetModes(scrn->scrnIndex, edid_mon);
+}
+
+/* maybe we should care about DDC1? meh. */
+xf86MonPtr
+xf86OutputGetEDID (xf86OutputPtr output, I2CBusPtr pDDCBus)
+{
+ ScrnInfoPtr scrn = output->scrn;
+ xf86MonPtr mon;
+
+ mon = xf86DoEEDID(scrn->scrnIndex, pDDCBus, TRUE);
+ if (mon)
+ xf86DDCApplyQuirks(scrn->scrnIndex, mon);
+
+ return mon;
+}
+
+static char *_xf86ConnectorNames[] = {
+ "None", "VGA", "DVI-I", "DVI-D",
+ "DVI-A", "Composite", "S-Video",
+ "Component", "LFP", "Proprietary",
+ "HDMI", "DisplayPort",
+ };
+char *
+xf86ConnectorGetName(xf86ConnectorType connector)
+{
+ return _xf86ConnectorNames[connector];
+}
+
+static void
+x86_crtc_box_intersect(BoxPtr dest, BoxPtr a, BoxPtr b)
+{
+ dest->x1 = a->x1 > b->x1 ? a->x1 : b->x1;
+ dest->x2 = a->x2 < b->x2 ? a->x2 : b->x2;
+ dest->y1 = a->y1 > b->y1 ? a->y1 : b->y1;
+ dest->y2 = a->y2 < b->y2 ? a->y2 : b->y2;
+
+ if (dest->x1 >= dest->x2 || dest->y1 >= dest->y2)
+ dest->x1 = dest->x2 = dest->y1 = dest->y2 = 0;
+}
+
+static void
+x86_crtc_box(xf86CrtcPtr crtc, BoxPtr crtc_box)
+{
+ if (crtc->enabled) {
+ crtc_box->x1 = crtc->x;
+ crtc_box->x2 = crtc->x + xf86ModeWidth(&crtc->mode, crtc->rotation);
+ crtc_box->y1 = crtc->y;
+ crtc_box->y2 = crtc->y + xf86ModeHeight(&crtc->mode, crtc->rotation);
+ } else
+ crtc_box->x1 = crtc_box->x2 = crtc_box->y1 = crtc_box->y2 = 0;
+}
+
+static int
+xf86_crtc_box_area(BoxPtr box)
+{
+ return (int) (box->x2 - box->x1) * (int) (box->y2 - box->y1);
+}
+
+/*
+ * Return the crtc covering 'box'. If two crtcs cover a portion of
+ * 'box', then prefer 'desired'. If 'desired' is NULL, then prefer the crtc
+ * with greater coverage
+ */
+
+static xf86CrtcPtr
+xf86_covering_crtc(ScrnInfoPtr pScrn,
+ BoxPtr box,
+ xf86CrtcPtr desired,
+ BoxPtr crtc_box_ret)
+{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ xf86CrtcPtr crtc, best_crtc;
+ int coverage, best_coverage;
+ int c;
+ BoxRec crtc_box, cover_box;
+
+ best_crtc = NULL;
+ best_coverage = 0;
+ crtc_box_ret->x1 = 0;
+ crtc_box_ret->x2 = 0;
+ crtc_box_ret->y1 = 0;
+ crtc_box_ret->y2 = 0;
+ for (c = 0; c < xf86_config->num_crtc; c++) {
+ crtc = xf86_config->crtc[c];
+ x86_crtc_box(crtc, &crtc_box);
+ x86_crtc_box_intersect(&cover_box, &crtc_box, box);
+ coverage = xf86_crtc_box_area(&cover_box);
+ if (coverage && crtc == desired) {
+ *crtc_box_ret = crtc_box;
+ return crtc;
+ } else if (coverage > best_coverage) {
+ *crtc_box_ret = crtc_box;
+ best_crtc = crtc;
+ best_coverage = coverage;
+ }
+ }
+ return best_crtc;
+}
+
+/*
+ * For overlay video, compute the relevant CRTC and
+ * clip video to that.
+ *
+ * returning FALSE means there was a memory failure of some kind,
+ * not that the video shouldn't be displayed
+ */
+
+Bool
+xf86_crtc_clip_video_helper(ScrnInfoPtr pScrn,
+ xf86CrtcPtr *crtc_ret,
+ xf86CrtcPtr desired_crtc,
+ BoxPtr dst,
+ INT32 *xa,
+ INT32 *xb,
+ INT32 *ya,
+ INT32 *yb,
+ RegionPtr reg,
+ INT32 width,
+ INT32 height)
+{
+ Bool ret;
+ RegionRec crtc_region_local;
+ RegionPtr crtc_region = reg;
+
+ if (crtc_ret) {
+ BoxRec crtc_box;
+ xf86CrtcPtr crtc = xf86_covering_crtc(pScrn, dst,
+ desired_crtc,
+ &crtc_box);
+
+ if (crtc) {
+ REGION_INIT (pScreen, &crtc_region_local, &crtc_box, 1);
+ crtc_region = &crtc_region_local;
+ REGION_INTERSECT (pScreen, crtc_region, crtc_region, reg);
+ }
+ *crtc_ret = crtc;
+ }
+
+ ret = xf86XVClipVideoHelper(dst, xa, xb, ya, yb,
+ crtc_region, width, height);
+
+ if (crtc_region != reg)
+ REGION_UNINIT (pScreen, &crtc_region_local);
+
+ return ret;
+}
+
+xf86_crtc_notify_proc_ptr
+xf86_wrap_crtc_notify (ScreenPtr screen, xf86_crtc_notify_proc_ptr new)
+{
+ if (xf86CrtcConfigPrivateIndex != -1)
+ {
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+ xf86_crtc_notify_proc_ptr old;
+
+ old = config->xf86_crtc_notify;
+ config->xf86_crtc_notify = new;
+ return old;
+ }
+ return NULL;
+}
+
+void
+xf86_unwrap_crtc_notify(ScreenPtr screen, xf86_crtc_notify_proc_ptr old)
+{
+ if (xf86CrtcConfigPrivateIndex != -1)
+ {
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+
+ config->xf86_crtc_notify = old;
+ }
+}
+
+void
+xf86_crtc_notify(ScreenPtr screen)
+{
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
+
+ if (config->xf86_crtc_notify)
+ config->xf86_crtc_notify(screen);
+}
+
+Bool
+xf86_crtc_supports_gamma(ScrnInfoPtr pScrn)
+{
+ if (xf86CrtcConfigPrivateIndex != -1) {
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ xf86CrtcPtr crtc;
+
+ /* for multiple drivers loaded we need this */
+ if (!xf86_config)
+ return FALSE;
+ if (xf86_config->num_crtc == 0)
+ return FALSE;
+ crtc = xf86_config->crtc[0];
+
+ return (crtc->funcs->gamma_set != NULL);
+ }
+
+ return FALSE;
+}
diff --git a/xorg-server/hw/xfree86/modes/xf86Cursors.c b/xorg-server/hw/xfree86/modes/xf86Cursors.c
index 3e765e6ff..e9770f8b9 100644
--- a/xorg-server/hw/xfree86/modes/xf86Cursors.c
+++ b/xorg-server/hw/xfree86/modes/xf86Cursors.c
@@ -551,7 +551,7 @@ xf86_cursors_init (ScreenPtr screen, int max_width, int max_height, int flags)
if (!cursor_info)
return FALSE;
- xf86_config->cursor_image = xalloc (max_width * max_height * 4);
+ xf86_config->cursor_image = malloc(max_width * max_height * 4);
if (!xf86_config->cursor_image)
{
@@ -661,7 +661,7 @@ xf86_cursors_fini (ScreenPtr screen)
}
if (xf86_config->cursor_image)
{
- xfree (xf86_config->cursor_image);
+ free(xf86_config->cursor_image);
xf86_config->cursor_image = NULL;
}
if (xf86_config->cursor)
diff --git a/xorg-server/hw/xfree86/modes/xf86DiDGA.c b/xorg-server/hw/xfree86/modes/xf86DiDGA.c
index 60fbdbf05..61c779edc 100644
--- a/xorg-server/hw/xfree86/modes/xf86DiDGA.c
+++ b/xorg-server/hw/xfree86/modes/xf86DiDGA.c
@@ -1,218 +1,218 @@
-/*
- * Copyright © 2006 Keith Packard
- *
- * 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 the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. The copyright holders make no representations
- * about the suitability of this software for any purpose. It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS 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>
-#else
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#endif
-
-#include "xf86.h"
-#include "xf86DDC.h"
-#include "xf86_OSproc.h"
-#include "dgaproc.h"
-#include "xf86Crtc.h"
-#include "xf86Modes.h"
-#include "gcstruct.h"
-#include "scrnintstr.h"
-#include "windowstr.h"
-
-static Bool
-xf86_dga_get_modes (ScreenPtr pScreen)
-{
- ScrnInfoPtr scrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
- DGAModePtr modes, mode;
- DisplayModePtr display_mode;
- int bpp = scrn->bitsPerPixel >> 3;
- int num;
-
- num = 0;
- display_mode = scrn->modes;
- while (display_mode)
- {
- num++;
- display_mode = display_mode->next;
- if (display_mode == scrn->modes)
- break;
- }
-
- if (!num)
- return FALSE;
-
- modes = xalloc(num * sizeof(DGAModeRec));
- if (!modes)
- return FALSE;
-
- num = 0;
- display_mode = scrn->modes;
- while (display_mode)
- {
- mode = modes + num++;
-
- mode->mode = display_mode;
- mode->flags = DGA_CONCURRENT_ACCESS;
- if (display_mode->Flags & V_DBLSCAN)
- mode->flags |= DGA_DOUBLESCAN;
- if (display_mode->Flags & V_INTERLACE)
- mode->flags |= DGA_INTERLACED;
- mode->byteOrder = scrn->imageByteOrder;
- mode->depth = scrn->depth;
- mode->bitsPerPixel = scrn->bitsPerPixel;
- mode->red_mask = scrn->mask.red;
- mode->green_mask = scrn->mask.green;
- mode->blue_mask = scrn->mask.blue;
- mode->visualClass = (bpp == 1) ? PseudoColor : TrueColor;
- mode->viewportWidth = display_mode->HDisplay;
- mode->viewportHeight = display_mode->VDisplay;
- mode->xViewportStep = (bpp == 3) ? 2 : 1;
- mode->yViewportStep = 1;
- mode->viewportFlags = DGA_FLIP_RETRACE;
- mode->offset = 0;
- mode->address = 0;
- mode->imageWidth = mode->viewportWidth;
- mode->imageHeight = mode->viewportHeight;
- mode->bytesPerScanline = (mode->imageWidth * scrn->bitsPerPixel) >> 3;
- mode->pixmapWidth = mode->imageWidth;
- mode->pixmapHeight = mode->imageHeight;
- mode->maxViewportX = 0;
- mode->maxViewportY = 0;
-
- display_mode = display_mode->next;
- if (display_mode == scrn->modes)
- break;
- }
- if (xf86_config->dga_modes)
- xfree (xf86_config->dga_modes);
- xf86_config->dga_nmode = num;
- xf86_config->dga_modes = modes;
- return TRUE;
-}
-
-static Bool
-xf86_dga_set_mode(ScrnInfoPtr scrn, DGAModePtr display_mode)
-{
- ScreenPtr pScreen = scrn->pScreen;
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-
- if (!display_mode)
- {
- if (xf86_config->dga_save_mode)
- {
- xf86SwitchMode(pScreen, xf86_config->dga_save_mode);
- xf86_config->dga_save_mode = NULL;
- }
- }
- else
- {
- if (!xf86_config->dga_save_mode)
- {
- xf86_config->dga_save_mode = scrn->currentMode;
- xf86SwitchMode(pScreen, display_mode->mode);
- }
- }
- return TRUE;
-}
-
-static int
-xf86_dga_get_viewport(ScrnInfoPtr scrn)
-{
- return 0;
-}
-
-static void
-xf86_dga_set_viewport(ScrnInfoPtr scrn, int x, int y, int flags)
-{
- scrn->AdjustFrame(scrn->pScreen->myNum, x, y, flags);
-}
-
-static Bool
-xf86_dga_open_framebuffer(ScrnInfoPtr scrn,
- char **name,
- unsigned char **mem, int *size, int *offset, int *flags)
-{
- return FALSE;
-}
-
-static void
-xf86_dga_close_framebuffer(ScrnInfoPtr scrn)
-{
-}
-
-static DGAFunctionRec xf86_dga_funcs = {
- xf86_dga_open_framebuffer,
- xf86_dga_close_framebuffer,
- xf86_dga_set_mode,
- xf86_dga_set_viewport,
- xf86_dga_get_viewport,
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-Bool
-xf86DiDGAReInit (ScreenPtr pScreen)
-{
- return TRUE;
-}
-
-Bool
-_xf86_di_dga_reinit_internal (ScreenPtr pScreen)
-{
- ScrnInfoPtr scrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-
- if (!DGAAvailable(pScreen->myNum))
- return TRUE;
-
- if (!xf86_dga_get_modes (pScreen))
- return FALSE;
-
- return DGAReInitModes (pScreen, xf86_config->dga_modes, xf86_config->dga_nmode);
-}
-
-Bool
-xf86DiDGAInit (ScreenPtr pScreen, unsigned long dga_address)
-{
- return TRUE;
-}
-
-Bool
-_xf86_di_dga_init_internal (ScreenPtr pScreen)
-{
- ScrnInfoPtr scrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
-
- xf86_config->dga_flags = 0;
- xf86_config->dga_address = 0;
- xf86_config->dga_width = 0;
- xf86_config->dga_height = 0;
- xf86_config->dga_stride = 0;
-
- if (!xf86_dga_get_modes (pScreen))
- return FALSE;
-
- return DGAInit(pScreen, &xf86_dga_funcs, xf86_config->dga_modes, xf86_config->dga_nmode);
-}
+/*
+ * Copyright © 2006 Keith Packard
+ *
+ * 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 the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS 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>
+#else
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#endif
+
+#include "xf86.h"
+#include "xf86DDC.h"
+#include "xf86_OSproc.h"
+#include "dgaproc.h"
+#include "xf86Crtc.h"
+#include "xf86Modes.h"
+#include "gcstruct.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+
+static Bool
+xf86_dga_get_modes (ScreenPtr pScreen)
+{
+ ScrnInfoPtr scrn = xf86Screens[pScreen->myNum];
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ DGAModePtr modes, mode;
+ DisplayModePtr display_mode;
+ int bpp = scrn->bitsPerPixel >> 3;
+ int num;
+
+ num = 0;
+ display_mode = scrn->modes;
+ while (display_mode)
+ {
+ num++;
+ display_mode = display_mode->next;
+ if (display_mode == scrn->modes)
+ break;
+ }
+
+ if (!num)
+ return FALSE;
+
+ modes = malloc(num * sizeof(DGAModeRec));
+ if (!modes)
+ return FALSE;
+
+ num = 0;
+ display_mode = scrn->modes;
+ while (display_mode)
+ {
+ mode = modes + num++;
+
+ mode->mode = display_mode;
+ mode->flags = DGA_CONCURRENT_ACCESS;
+ if (display_mode->Flags & V_DBLSCAN)
+ mode->flags |= DGA_DOUBLESCAN;
+ if (display_mode->Flags & V_INTERLACE)
+ mode->flags |= DGA_INTERLACED;
+ mode->byteOrder = scrn->imageByteOrder;
+ mode->depth = scrn->depth;
+ mode->bitsPerPixel = scrn->bitsPerPixel;
+ mode->red_mask = scrn->mask.red;
+ mode->green_mask = scrn->mask.green;
+ mode->blue_mask = scrn->mask.blue;
+ mode->visualClass = (bpp == 1) ? PseudoColor : TrueColor;
+ mode->viewportWidth = display_mode->HDisplay;
+ mode->viewportHeight = display_mode->VDisplay;
+ mode->xViewportStep = (bpp == 3) ? 2 : 1;
+ mode->yViewportStep = 1;
+ mode->viewportFlags = DGA_FLIP_RETRACE;
+ mode->offset = 0;
+ mode->address = 0;
+ mode->imageWidth = mode->viewportWidth;
+ mode->imageHeight = mode->viewportHeight;
+ mode->bytesPerScanline = (mode->imageWidth * scrn->bitsPerPixel) >> 3;
+ mode->pixmapWidth = mode->imageWidth;
+ mode->pixmapHeight = mode->imageHeight;
+ mode->maxViewportX = 0;
+ mode->maxViewportY = 0;
+
+ display_mode = display_mode->next;
+ if (display_mode == scrn->modes)
+ break;
+ }
+ if (xf86_config->dga_modes)
+ free(xf86_config->dga_modes);
+ xf86_config->dga_nmode = num;
+ xf86_config->dga_modes = modes;
+ return TRUE;
+}
+
+static Bool
+xf86_dga_set_mode(ScrnInfoPtr scrn, DGAModePtr display_mode)
+{
+ ScreenPtr pScreen = scrn->pScreen;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+
+ if (!display_mode)
+ {
+ if (xf86_config->dga_save_mode)
+ {
+ xf86SwitchMode(pScreen, xf86_config->dga_save_mode);
+ xf86_config->dga_save_mode = NULL;
+ }
+ }
+ else
+ {
+ if (!xf86_config->dga_save_mode)
+ {
+ xf86_config->dga_save_mode = scrn->currentMode;
+ xf86SwitchMode(pScreen, display_mode->mode);
+ }
+ }
+ return TRUE;
+}
+
+static int
+xf86_dga_get_viewport(ScrnInfoPtr scrn)
+{
+ return 0;
+}
+
+static void
+xf86_dga_set_viewport(ScrnInfoPtr scrn, int x, int y, int flags)
+{
+ scrn->AdjustFrame(scrn->pScreen->myNum, x, y, flags);
+}
+
+static Bool
+xf86_dga_open_framebuffer(ScrnInfoPtr scrn,
+ char **name,
+ unsigned char **mem, int *size, int *offset, int *flags)
+{
+ return FALSE;
+}
+
+static void
+xf86_dga_close_framebuffer(ScrnInfoPtr scrn)
+{
+}
+
+static DGAFunctionRec xf86_dga_funcs = {
+ xf86_dga_open_framebuffer,
+ xf86_dga_close_framebuffer,
+ xf86_dga_set_mode,
+ xf86_dga_set_viewport,
+ xf86_dga_get_viewport,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+Bool
+xf86DiDGAReInit (ScreenPtr pScreen)
+{
+ return TRUE;
+}
+
+Bool
+_xf86_di_dga_reinit_internal (ScreenPtr pScreen)
+{
+ ScrnInfoPtr scrn = xf86Screens[pScreen->myNum];
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+
+ if (!DGAAvailable(pScreen->myNum))
+ return TRUE;
+
+ if (!xf86_dga_get_modes (pScreen))
+ return FALSE;
+
+ return DGAReInitModes (pScreen, xf86_config->dga_modes, xf86_config->dga_nmode);
+}
+
+Bool
+xf86DiDGAInit (ScreenPtr pScreen, unsigned long dga_address)
+{
+ return TRUE;
+}
+
+Bool
+_xf86_di_dga_init_internal (ScreenPtr pScreen)
+{
+ ScrnInfoPtr scrn = xf86Screens[pScreen->myNum];
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+
+ xf86_config->dga_flags = 0;
+ xf86_config->dga_address = 0;
+ xf86_config->dga_width = 0;
+ xf86_config->dga_height = 0;
+ xf86_config->dga_stride = 0;
+
+ if (!xf86_dga_get_modes (pScreen))
+ return FALSE;
+
+ return DGAInit(pScreen, &xf86_dga_funcs, xf86_config->dga_modes, xf86_config->dga_nmode);
+}
diff --git a/xorg-server/hw/xfree86/modes/xf86DisplayIDModes.c b/xorg-server/hw/xfree86/modes/xf86DisplayIDModes.c
index 182d43e0e..d507e3b14 100644
--- a/xorg-server/hw/xfree86/modes/xf86DisplayIDModes.c
+++ b/xorg-server/hw/xfree86/modes/xf86DisplayIDModes.c
@@ -1,437 +1,437 @@
-/*
- * Copyright 2009 Red Hat, 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
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * them Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) 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 MERCHANTIBILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS 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.
- *
- * Authors:
- * Adam Jackson <ajax@redhat.com>
- */
-
-#include "xorg-config.h"
-#include "xf86.h"
-#include "xf86str.h"
-#include "edid.h"
-#include "xf86DDC.h"
-
-typedef void (*did_proc)(int scrnIndex, unsigned char *data, void *closure);
-
-#define DID_PRODUCT_ID 0x00
-#define DID_DISPLAY_PARAMETERS 0x01
-#define DID_COLOR_INFO 0x02
-#define DID_TIMING_1_DETAILED 0x03
-#define DID_TIMING_2_DETAILED 0x04
-#define DID_TIMING_3_SHORT 0x05
-#define DID_TIMING_4_DMT 0x06
-#define DID_TIMING_VESA 0x07
-#define DID_TIMING_CEA 0x08
-#define DID_TIMING_RANGE_LIMITS 0x09
-#define DID_PRODUCT_SERIAL 0x0A
-#define DID_ASCII_STRING 0x0B
-#define DID_DISPLAY_DEVICE 0x0C
-#define DID_POWER_SEQUENCING 0x0D
-#define DID_TRANSFER_INFO 0x0E
-#define DID_DISPLAY_INTERFACE 0x0F
-#define DID_STEREO 0x10
-#define DID_VENDOR 0x7F
-
-#define extract_le16(x, i) ((x[i+1] << 8) + (x[i]))
-#define extract_le24(x, i) ((x[i+2] << 16) + (x[i+1] << 8) + (x[i]))
-
-static DisplayModePtr
-modeCalloc(void)
-{
- return xcalloc(1, sizeof(DisplayModeRec));
-}
-
-/*
- * How awesome is it to have two detailed timing formats, neither of which
- * are compatible with the format in EDID? So awesome.
- */
-
-static void
-didDetailedTiming1(int i, unsigned char *x, MonPtr mon)
-{
- DisplayModePtr m = modeCalloc();
-
- if (!m)
- return;
-
- m->Clock = extract_le24(x, 0);
-
- m->HDisplay = extract_le16(x, 4);
- m->HSyncStart = m->HDisplay + (extract_le16(x, 8) & 0x7f);
- m->HSyncEnd = m->HSyncStart + extract_le16(x, 10);
- m->HTotal = m->HDisplay + extract_le16(x, 6);
- m->Flags |= (x[9] & 0x80) ? V_PHSYNC : V_NHSYNC;
-
- m->VDisplay = extract_le16(x, 12);
- m->VSyncStart = m->VDisplay + (extract_le16(x, 16) & 0x7f);
- m->VSyncEnd = m->VSyncStart + extract_le16(x, 18);
- m->VTotal = m->VDisplay + extract_le16(x, 14);
- m->Flags |= (x[17] & 0x80) ? V_PVSYNC : V_NVSYNC;
-
- m->type = M_T_DRIVER;
- if (x[3] & 0x80)
- m->type |= M_T_PREFERRED;
-
- /* XXX double check handling of this */
- if (x[3] & 0x10)
- m->Flags |= V_INTERLACE;
-
- mon->Modes = xf86ModesAdd(mon->Modes, m);
-}
-
-/* XXX no sync bits. what to do? */
-static void
-didDetailedTiming2(int i, unsigned char *x, MonPtr mon)
-{
- DisplayModePtr mode = modeCalloc();
-
- if (!mode)
- return;
-
- mode->Clock = extract_le24(x, 0);
-
- /* horiz sizes are in character cells, not pixels, hence * 8 */
- mode->HDisplay = ((extract_le16(x, 4) & 0x01ff) + 1) * 8;
- mode->HSyncStart = mode->HDisplay + (((x[6] & 0xf0) >> 4) + 1) * 8;
- mode->HSyncEnd = mode->HSyncStart + ((x[6] & 0x0f) + 1) * 8;
- mode->HTotal = mode->HDisplay + ((x[5] >> 1) + 1) * 8;
-
- mode->VDisplay = extract_le16(x, 7) & 0x07ff;
- mode->VSyncStart = mode->VDisplay + (x[10] >> 4) + 1;
- mode->VSyncEnd = mode->VSyncStart + (x[10] & 0x0f) + 1;
- mode->VTotal = mode->VDisplay + x[9];
-
- mode->status = M_T_DRIVER;
- if (x[3] & 0x80)
- mode->status |= M_T_PREFERRED;
-
- /* XXX double check handling of this */
- if (x[3] & 0x10)
- mode->Flags |= V_INTERLACE;
-
- mon->Modes = xf86ModesAdd(mon->Modes, mode);
-}
-
-static void
-didShortTiming(int i, unsigned char *x, MonPtr mon)
-{
- DisplayModePtr m;
- int w, h, r;
-
- w = (x[1] + 1) * 8;
- switch (x[0] & 0x0f) {
- case 0:
- h = w;
- break;
- case 1:
- h = (w * 4) / 5;
- break;
- case 2:
- h = (w * 3) / 4;
- break;
- case 3:
- h = (w * 9) / 15;
- break;
- case 4:
- h = (w * 9) / 16;
- break;
- case 5:
- h = (w * 10) / 16;
- break;
- default:
- return;
- }
- r = (x[2] & 0x7f) + 1;
-
- m = xf86CVTMode(w, h, r, !!(x[0] & 0x10), !!(x[2] & 0x80));
-
- m->type = M_T_DRIVER;
- if (x[0] & 0x80)
- m->type |= M_T_PREFERRED;
-
- mon->Modes = xf86ModesAdd(mon->Modes, m);
-}
-
-static void
-didDMTTiming(int i, unsigned char *x, void *closure)
-{
- MonPtr mon = closure;
-
- mon->Modes = xf86ModesAdd(mon->Modes,
- xf86DuplicateMode(DMTModes + *x));
-}
-
-#define RB 1
-#define INT 2
-static const struct did_dmt {
- short w, h, r, f;
-} did_dmt[] = {
- /* byte 3 */
- { 640, 350, 85, 0 },
- { 640, 400, 85, 0 },
- { 720, 400, 85, 0 },
- { 640, 480, 60, 0 },
- { 640, 480, 72, 0 },
- { 640, 480, 75, 0 },
- { 640, 480, 85, 0 },
- { 800, 600, 56, 0 },
- /* byte 4 */
- { 800, 600, 60, 0 },
- { 800, 600, 72, 0 },
- { 800, 600, 75, 0 },
- { 800, 600, 85, 0 },
- { 800, 600, 120, RB },
- { 848, 480, 60, 0 },
- { 1024, 768, 43, INT },
- { 1024, 768, 60, 0 },
- /* byte 5 */
- { 1024, 768, 70, 0 },
- { 1024, 768, 75, 0 },
- { 1024, 768, 85, 0 },
- { 1024, 768, 120, RB },
- { 1152, 864, 75, 0 },
- { 1280, 768, 60, RB },
- { 1280, 768, 60, 0 },
- { 1280, 768, 75, 0 },
- /* byte 6 */
- { 1280, 768, 85, 0 },
- { 1280, 768, 120, RB },
- { 1280, 800, 60, RB },
- { 1280, 800, 60, 0 },
- { 1280, 800, 75, 0 },
- { 1280, 800, 85, 0 },
- { 1280, 800, 120, RB },
- { 1280, 960, 60, 0 },
- /* byte 7 */
- { 1280, 960, 85, 0 },
- { 1280, 960, 120, RB },
- { 1280, 1024, 60, 0 },
- { 1280, 1024, 75, 0 },
- { 1280, 1024, 85, 0 },
- { 1280, 1024, 120, RB },
- { 1360, 768, 60, 0 },
- { 1360, 768, 120, RB },
- /* byte 8 */
- { 1400, 1050, 60, RB },
- { 1400, 1050, 60, 0 },
- { 1400, 1050, 75, 0 },
- { 1400, 1050, 85, 0 },
- { 1400, 1050, 120, RB },
- { 1440, 900, 60, RB },
- { 1440, 900, 60, 0 },
- { 1440, 900, 75, 0 },
- /* byte 9 */
- { 1440, 900, 85, 0 },
- { 1440, 900, 120, RB },
- { 1600, 1200, 60, 0 },
- { 1600, 1200, 65, 0 },
- { 1600, 1200, 70, 0 },
- { 1600, 1200, 75, 0 },
- { 1600, 1200, 85, 0 },
- { 1600, 1200, 120, RB },
- /* byte a */
- { 1680, 1050, 60, RB },
- { 1680, 1050, 60, 0 },
- { 1680, 1050, 75, 0 },
- { 1680, 1050, 85, 0 },
- { 1680, 1050, 120, RB },
- { 1792, 1344, 60, 0 },
- { 1792, 1344, 75, 0 },
- { 1792, 1344, 120, RB },
- /* byte b */
- { 1856, 1392, 60, 0 },
- { 1856, 1392, 75, 0 },
- { 1856, 1392, 120, RB },
- { 1920, 1200, 60, RB },
- { 1920, 1200, 60, 0 },
- { 1920, 1200, 75, 0 },
- { 1920, 1200, 85, 0 },
- { 1920, 1200, 120, RB },
- /* byte c */
- { 1920, 1440, 60, 0 },
- { 1920, 1440, 75, 0 },
- { 1920, 1440, 120, RB },
- { 2560, 1600, 60, RB },
- { 2560, 1600, 60, 0 },
- { 2560, 1600, 75, 0 },
- { 2560, 1600, 85, 0 },
- { 2560, 1600, 120, RB },
-};
-
-static void
-didVesaTiming(int scrn, unsigned char *x, MonPtr mon)
-{
- int i, j;
-
- x += 3;
-
- for (i = 0; i < 10; i++)
- for (j = 0; j < 8; j++)
- if (x[i] & (1 << j)) {
- const struct did_dmt *d = &(did_dmt[i * 8 + j]);
- if (d->f == INT)
- continue;
- mon->Modes = xf86ModesAdd(mon->Modes,
- FindDMTMode(d->w, d->h, d->r,
- d->f == RB));
- }
-
-}
-
-static void
-handleDisplayIDBlock(int scrnIndex, unsigned char *x, void *closure)
-{
- MonPtr mon = closure;
-
- switch (x[0]) {
- case DID_DISPLAY_PARAMETERS:
- /* w/h are in decimillimeters */
- mon->widthmm = (extract_le16(x, 3) + 5) / 10;
- mon->heightmm = (extract_le16(x, 5) + 5) / 10;
- /* XXX pixel count, feature flags, gamma, aspect, color depth */
- break;
-
- case DID_TIMING_RANGE_LIMITS:
- {
- int n;
-
- mon->maxPixClock = max(mon->maxPixClock, extract_le24(x, 6) * 10);
-
- n = mon->nHsync++;
- if (n < MAX_HSYNC) {
- mon->hsync[n].lo = x[9];
- mon->hsync[n].hi = x[10];
- } else {
- n = MAX_HSYNC;
- }
- n = mon->nVrefresh++;
- if (n < MAX_VREFRESH) {
- mon->vrefresh[n].lo = x[13];
- mon->vrefresh[n].hi = x[14];
- } else {
- n = MAX_VREFRESH;
- }
- break;
- }
-
- case DID_TIMING_1_DETAILED:
- {
- int i;
- for (i = 0; i < x[2]; i += 20)
- didDetailedTiming1(scrnIndex, x + i + 3, mon);
- break;
- }
-
- case DID_TIMING_2_DETAILED:
- {
- int i;
- for (i = 0; i < x[2]; i += 11)
- didDetailedTiming2(scrnIndex, x + i + 3, mon);
- break;
- }
-
- case DID_TIMING_3_SHORT:
- {
- int i;
- for (i = 0; i < x[2]; i += 3)
- didShortTiming(scrnIndex, x + i + 3, mon);
- break;
- }
-
- case DID_TIMING_4_DMT:
- {
- int i;
- for (i = 0; i < x[2]; i++)
- didDMTTiming(scrnIndex, x + i + 3, mon);
- break;
- }
-
- case DID_TIMING_VESA:
- didVesaTiming(scrnIndex, x, mon);
- break;
-
- /* XXX pixel format, ar, orientation, subpixel, dot pitch, bit depth */
- case DID_DISPLAY_DEVICE:
-
- /* XXX interface, links, color encoding, ss, drm */
- case DID_DISPLAY_INTERFACE:
-
- /* XXX stereo */
- case DID_STEREO:
-
- /* nothing interesting in these */
- case DID_COLOR_INFO:
- case DID_PRODUCT_SERIAL:
- case DID_ASCII_STRING:
- case DID_POWER_SEQUENCING:
- case DID_TRANSFER_INFO:
- case DID_VENDOR:
- break;
-
- /* warn about anything else */
- default:
- xf86DrvMsg(scrnIndex, X_WARNING,
- "Unknown DisplayID block type %hx\n", x[0]);
- break;
- }
-}
-
-static void
-forEachDisplayIDBlock(int scrnIndex, unsigned char *did, did_proc proc,
- void *closure)
-{
- int num_extensions = did[3];
- int section_size = did[1];
- unsigned char *block;
-
- do {
- if ((did[0] & 0xf0) != 0x10) /* not 1.x, abort */
- return;
- /* XXX also, checksum */
-
- block = did + 4;
-
- while (section_size > 0) {
- int block_size = (block[2] + 2);
-
- proc(scrnIndex, block, closure);
-
- section_size -= block_size;
- block += block_size;
- }
-
- did += (did[1] + 5);
- } while (num_extensions--);
-}
-
-/*
- * Fill out MonPtr with xf86MonPtr information.
- */
-void
-xf86DisplayIDMonitorSet(int scrnIndex, MonPtr mon, xf86MonPtr DDC)
-{
- if (!mon || !DDC)
- return;
-
- mon->DDC = DDC;
-
- forEachDisplayIDBlock(scrnIndex, DDC->rawData, handleDisplayIDBlock, mon);
-}
+/*
+ * Copyright 2009 Red Hat, 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
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * them Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) 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 MERCHANTIBILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS 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.
+ *
+ * Authors:
+ * Adam Jackson <ajax@redhat.com>
+ */
+
+#include "xorg-config.h"
+#include "xf86.h"
+#include "xf86str.h"
+#include "edid.h"
+#include "xf86DDC.h"
+
+typedef void (*did_proc)(int scrnIndex, unsigned char *data, void *closure);
+
+#define DID_PRODUCT_ID 0x00
+#define DID_DISPLAY_PARAMETERS 0x01
+#define DID_COLOR_INFO 0x02
+#define DID_TIMING_1_DETAILED 0x03
+#define DID_TIMING_2_DETAILED 0x04
+#define DID_TIMING_3_SHORT 0x05
+#define DID_TIMING_4_DMT 0x06
+#define DID_TIMING_VESA 0x07
+#define DID_TIMING_CEA 0x08
+#define DID_TIMING_RANGE_LIMITS 0x09
+#define DID_PRODUCT_SERIAL 0x0A
+#define DID_ASCII_STRING 0x0B
+#define DID_DISPLAY_DEVICE 0x0C
+#define DID_POWER_SEQUENCING 0x0D
+#define DID_TRANSFER_INFO 0x0E
+#define DID_DISPLAY_INTERFACE 0x0F
+#define DID_STEREO 0x10
+#define DID_VENDOR 0x7F
+
+#define extract_le16(x, i) ((x[i+1] << 8) + (x[i]))
+#define extract_le24(x, i) ((x[i+2] << 16) + (x[i+1] << 8) + (x[i]))
+
+static DisplayModePtr
+modeCalloc(void)
+{
+ return calloc(1, sizeof(DisplayModeRec));
+}
+
+/*
+ * How awesome is it to have two detailed timing formats, neither of which
+ * are compatible with the format in EDID? So awesome.
+ */
+
+static void
+didDetailedTiming1(int i, unsigned char *x, MonPtr mon)
+{
+ DisplayModePtr m = modeCalloc();
+
+ if (!m)
+ return;
+
+ m->Clock = extract_le24(x, 0);
+
+ m->HDisplay = extract_le16(x, 4);
+ m->HSyncStart = m->HDisplay + (extract_le16(x, 8) & 0x7f);
+ m->HSyncEnd = m->HSyncStart + extract_le16(x, 10);
+ m->HTotal = m->HDisplay + extract_le16(x, 6);
+ m->Flags |= (x[9] & 0x80) ? V_PHSYNC : V_NHSYNC;
+
+ m->VDisplay = extract_le16(x, 12);
+ m->VSyncStart = m->VDisplay + (extract_le16(x, 16) & 0x7f);
+ m->VSyncEnd = m->VSyncStart + extract_le16(x, 18);
+ m->VTotal = m->VDisplay + extract_le16(x, 14);
+ m->Flags |= (x[17] & 0x80) ? V_PVSYNC : V_NVSYNC;
+
+ m->type = M_T_DRIVER;
+ if (x[3] & 0x80)
+ m->type |= M_T_PREFERRED;
+
+ /* XXX double check handling of this */
+ if (x[3] & 0x10)
+ m->Flags |= V_INTERLACE;
+
+ mon->Modes = xf86ModesAdd(mon->Modes, m);
+}
+
+/* XXX no sync bits. what to do? */
+static void
+didDetailedTiming2(int i, unsigned char *x, MonPtr mon)
+{
+ DisplayModePtr mode = modeCalloc();
+
+ if (!mode)
+ return;
+
+ mode->Clock = extract_le24(x, 0);
+
+ /* horiz sizes are in character cells, not pixels, hence * 8 */
+ mode->HDisplay = ((extract_le16(x, 4) & 0x01ff) + 1) * 8;
+ mode->HSyncStart = mode->HDisplay + (((x[6] & 0xf0) >> 4) + 1) * 8;
+ mode->HSyncEnd = mode->HSyncStart + ((x[6] & 0x0f) + 1) * 8;
+ mode->HTotal = mode->HDisplay + ((x[5] >> 1) + 1) * 8;
+
+ mode->VDisplay = extract_le16(x, 7) & 0x07ff;
+ mode->VSyncStart = mode->VDisplay + (x[10] >> 4) + 1;
+ mode->VSyncEnd = mode->VSyncStart + (x[10] & 0x0f) + 1;
+ mode->VTotal = mode->VDisplay + x[9];
+
+ mode->status = M_T_DRIVER;
+ if (x[3] & 0x80)
+ mode->status |= M_T_PREFERRED;
+
+ /* XXX double check handling of this */
+ if (x[3] & 0x10)
+ mode->Flags |= V_INTERLACE;
+
+ mon->Modes = xf86ModesAdd(mon->Modes, mode);
+}
+
+static void
+didShortTiming(int i, unsigned char *x, MonPtr mon)
+{
+ DisplayModePtr m;
+ int w, h, r;
+
+ w = (x[1] + 1) * 8;
+ switch (x[0] & 0x0f) {
+ case 0:
+ h = w;
+ break;
+ case 1:
+ h = (w * 4) / 5;
+ break;
+ case 2:
+ h = (w * 3) / 4;
+ break;
+ case 3:
+ h = (w * 9) / 15;
+ break;
+ case 4:
+ h = (w * 9) / 16;
+ break;
+ case 5:
+ h = (w * 10) / 16;
+ break;
+ default:
+ return;
+ }
+ r = (x[2] & 0x7f) + 1;
+
+ m = xf86CVTMode(w, h, r, !!(x[0] & 0x10), !!(x[2] & 0x80));
+
+ m->type = M_T_DRIVER;
+ if (x[0] & 0x80)
+ m->type |= M_T_PREFERRED;
+
+ mon->Modes = xf86ModesAdd(mon->Modes, m);
+}
+
+static void
+didDMTTiming(int i, unsigned char *x, void *closure)
+{
+ MonPtr mon = closure;
+
+ mon->Modes = xf86ModesAdd(mon->Modes,
+ xf86DuplicateMode(DMTModes + *x));
+}
+
+#define RB 1
+#define INT 2
+static const struct did_dmt {
+ short w, h, r, f;
+} did_dmt[] = {
+ /* byte 3 */
+ { 640, 350, 85, 0 },
+ { 640, 400, 85, 0 },
+ { 720, 400, 85, 0 },
+ { 640, 480, 60, 0 },
+ { 640, 480, 72, 0 },
+ { 640, 480, 75, 0 },
+ { 640, 480, 85, 0 },
+ { 800, 600, 56, 0 },
+ /* byte 4 */
+ { 800, 600, 60, 0 },
+ { 800, 600, 72, 0 },
+ { 800, 600, 75, 0 },
+ { 800, 600, 85, 0 },
+ { 800, 600, 120, RB },
+ { 848, 480, 60, 0 },
+ { 1024, 768, 43, INT },
+ { 1024, 768, 60, 0 },
+ /* byte 5 */
+ { 1024, 768, 70, 0 },
+ { 1024, 768, 75, 0 },
+ { 1024, 768, 85, 0 },
+ { 1024, 768, 120, RB },
+ { 1152, 864, 75, 0 },
+ { 1280, 768, 60, RB },
+ { 1280, 768, 60, 0 },
+ { 1280, 768, 75, 0 },
+ /* byte 6 */
+ { 1280, 768, 85, 0 },
+ { 1280, 768, 120, RB },
+ { 1280, 800, 60, RB },
+ { 1280, 800, 60, 0 },
+ { 1280, 800, 75, 0 },
+ { 1280, 800, 85, 0 },
+ { 1280, 800, 120, RB },
+ { 1280, 960, 60, 0 },
+ /* byte 7 */
+ { 1280, 960, 85, 0 },
+ { 1280, 960, 120, RB },
+ { 1280, 1024, 60, 0 },
+ { 1280, 1024, 75, 0 },
+ { 1280, 1024, 85, 0 },
+ { 1280, 1024, 120, RB },
+ { 1360, 768, 60, 0 },
+ { 1360, 768, 120, RB },
+ /* byte 8 */
+ { 1400, 1050, 60, RB },
+ { 1400, 1050, 60, 0 },
+ { 1400, 1050, 75, 0 },
+ { 1400, 1050, 85, 0 },
+ { 1400, 1050, 120, RB },
+ { 1440, 900, 60, RB },
+ { 1440, 900, 60, 0 },
+ { 1440, 900, 75, 0 },
+ /* byte 9 */
+ { 1440, 900, 85, 0 },
+ { 1440, 900, 120, RB },
+ { 1600, 1200, 60, 0 },
+ { 1600, 1200, 65, 0 },
+ { 1600, 1200, 70, 0 },
+ { 1600, 1200, 75, 0 },
+ { 1600, 1200, 85, 0 },
+ { 1600, 1200, 120, RB },
+ /* byte a */
+ { 1680, 1050, 60, RB },
+ { 1680, 1050, 60, 0 },
+ { 1680, 1050, 75, 0 },
+ { 1680, 1050, 85, 0 },
+ { 1680, 1050, 120, RB },
+ { 1792, 1344, 60, 0 },
+ { 1792, 1344, 75, 0 },
+ { 1792, 1344, 120, RB },
+ /* byte b */
+ { 1856, 1392, 60, 0 },
+ { 1856, 1392, 75, 0 },
+ { 1856, 1392, 120, RB },
+ { 1920, 1200, 60, RB },
+ { 1920, 1200, 60, 0 },
+ { 1920, 1200, 75, 0 },
+ { 1920, 1200, 85, 0 },
+ { 1920, 1200, 120, RB },
+ /* byte c */
+ { 1920, 1440, 60, 0 },
+ { 1920, 1440, 75, 0 },
+ { 1920, 1440, 120, RB },
+ { 2560, 1600, 60, RB },
+ { 2560, 1600, 60, 0 },
+ { 2560, 1600, 75, 0 },
+ { 2560, 1600, 85, 0 },
+ { 2560, 1600, 120, RB },
+};
+
+static void
+didVesaTiming(int scrn, unsigned char *x, MonPtr mon)
+{
+ int i, j;
+
+ x += 3;
+
+ for (i = 0; i < 10; i++)
+ for (j = 0; j < 8; j++)
+ if (x[i] & (1 << j)) {
+ const struct did_dmt *d = &(did_dmt[i * 8 + j]);
+ if (d->f == INT)
+ continue;
+ mon->Modes = xf86ModesAdd(mon->Modes,
+ FindDMTMode(d->w, d->h, d->r,
+ d->f == RB));
+ }
+
+}
+
+static void
+handleDisplayIDBlock(int scrnIndex, unsigned char *x, void *closure)
+{
+ MonPtr mon = closure;
+
+ switch (x[0]) {
+ case DID_DISPLAY_PARAMETERS:
+ /* w/h are in decimillimeters */
+ mon->widthmm = (extract_le16(x, 3) + 5) / 10;
+ mon->heightmm = (extract_le16(x, 5) + 5) / 10;
+ /* XXX pixel count, feature flags, gamma, aspect, color depth */
+ break;
+
+ case DID_TIMING_RANGE_LIMITS:
+ {
+ int n;
+
+ mon->maxPixClock = max(mon->maxPixClock, extract_le24(x, 6) * 10);
+
+ n = mon->nHsync++;
+ if (n < MAX_HSYNC) {
+ mon->hsync[n].lo = x[9];
+ mon->hsync[n].hi = x[10];
+ } else {
+ n = MAX_HSYNC;
+ }
+ n = mon->nVrefresh++;
+ if (n < MAX_VREFRESH) {
+ mon->vrefresh[n].lo = x[13];
+ mon->vrefresh[n].hi = x[14];
+ } else {
+ n = MAX_VREFRESH;
+ }
+ break;
+ }
+
+ case DID_TIMING_1_DETAILED:
+ {
+ int i;
+ for (i = 0; i < x[2]; i += 20)
+ didDetailedTiming1(scrnIndex, x + i + 3, mon);
+ break;
+ }
+
+ case DID_TIMING_2_DETAILED:
+ {
+ int i;
+ for (i = 0; i < x[2]; i += 11)
+ didDetailedTiming2(scrnIndex, x + i + 3, mon);
+ break;
+ }
+
+ case DID_TIMING_3_SHORT:
+ {
+ int i;
+ for (i = 0; i < x[2]; i += 3)
+ didShortTiming(scrnIndex, x + i + 3, mon);
+ break;
+ }
+
+ case DID_TIMING_4_DMT:
+ {
+ int i;
+ for (i = 0; i < x[2]; i++)
+ didDMTTiming(scrnIndex, x + i + 3, mon);
+ break;
+ }
+
+ case DID_TIMING_VESA:
+ didVesaTiming(scrnIndex, x, mon);
+ break;
+
+ /* XXX pixel format, ar, orientation, subpixel, dot pitch, bit depth */
+ case DID_DISPLAY_DEVICE:
+
+ /* XXX interface, links, color encoding, ss, drm */
+ case DID_DISPLAY_INTERFACE:
+
+ /* XXX stereo */
+ case DID_STEREO:
+
+ /* nothing interesting in these */
+ case DID_COLOR_INFO:
+ case DID_PRODUCT_SERIAL:
+ case DID_ASCII_STRING:
+ case DID_POWER_SEQUENCING:
+ case DID_TRANSFER_INFO:
+ case DID_VENDOR:
+ break;
+
+ /* warn about anything else */
+ default:
+ xf86DrvMsg(scrnIndex, X_WARNING,
+ "Unknown DisplayID block type %hx\n", x[0]);
+ break;
+ }
+}
+
+static void
+forEachDisplayIDBlock(int scrnIndex, unsigned char *did, did_proc proc,
+ void *closure)
+{
+ int num_extensions = did[3];
+ int section_size = did[1];
+ unsigned char *block;
+
+ do {
+ if ((did[0] & 0xf0) != 0x10) /* not 1.x, abort */
+ return;
+ /* XXX also, checksum */
+
+ block = did + 4;
+
+ while (section_size > 0) {
+ int block_size = (block[2] + 2);
+
+ proc(scrnIndex, block, closure);
+
+ section_size -= block_size;
+ block += block_size;
+ }
+
+ did += (did[1] + 5);
+ } while (num_extensions--);
+}
+
+/*
+ * Fill out MonPtr with xf86MonPtr information.
+ */
+void
+xf86DisplayIDMonitorSet(int scrnIndex, MonPtr mon, xf86MonPtr DDC)
+{
+ if (!mon || !DDC)
+ return;
+
+ mon->DDC = DDC;
+
+ forEachDisplayIDBlock(scrnIndex, DDC->rawData, handleDisplayIDBlock, mon);
+}
diff --git a/xorg-server/hw/xfree86/modes/xf86EdidModes.c b/xorg-server/hw/xfree86/modes/xf86EdidModes.c
index ec6540841..fc469c6ba 100644
--- a/xorg-server/hw/xfree86/modes/xf86EdidModes.c
+++ b/xorg-server/hw/xfree86/modes/xf86EdidModes.c
@@ -1,1215 +1,1215 @@
-/*
- * Copyright 2006 Luc Verhaegen.
- * Copyright 2008 Red Hat, 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, sub license,
- * 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 (including the
- * next paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * @file This file covers code to convert a xf86MonPtr containing EDID-probed
- * information into a list of modes, including applying monitor-specific
- * quirks to fix broken EDID data.
- */
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#else
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#endif
-
-#define _PARSE_EDID_
-#include "xf86.h"
-#include "xf86DDC.h"
-#include <X11/Xatom.h>
-#include "property.h"
-#include "propertyst.h"
-#include "xf86Crtc.h"
-#include <string.h>
-#include <math.h>
-
-static void handle_detailed_rblank(struct detailed_monitor_section *det_mon,
- void *data)
-{
- if (det_mon->type == DS_RANGES)
- if (det_mon->section.ranges.supported_blanking & CVT_REDUCED)
- *(Bool*)data = TRUE;
-}
-
-static Bool
-xf86MonitorSupportsReducedBlanking(xf86MonPtr DDC)
-{
- /* EDID 1.4 explicitly defines RB support */
- if (DDC->ver.revision >= 4) {
- Bool ret = FALSE;
-
- xf86ForEachDetailedBlock(DDC, handle_detailed_rblank, &ret);
- return ret;
- }
-
- /* For anything older, assume digital means RB support. Boo. */
- if (DDC->features.input_type)
- return TRUE;
-
- return FALSE;
-}
-
-static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC)
-{
- /* Belinea 10 15 55 */
- if (memcmp (DDC->vendor.name, "MAX", 4) == 0 &&
- ((DDC->vendor.prod_id == 1516) ||
- (DDC->vendor.prod_id == 0x77e)))
- return TRUE;
-
- /* Acer AL1706 */
- if (memcmp (DDC->vendor.name, "ACR", 4) == 0 &&
- DDC->vendor.prod_id == 44358)
- return TRUE;
-
- /* Bug #10814: Samsung SyncMaster 225BW */
- if (memcmp (DDC->vendor.name, "SAM", 4) == 0 &&
- DDC->vendor.prod_id == 596)
- return TRUE;
-
- /* Bug #10545: Samsung SyncMaster 226BW */
- if (memcmp (DDC->vendor.name, "SAM", 4) == 0 &&
- DDC->vendor.prod_id == 638)
- return TRUE;
-
- /* Acer F51 */
- if (memcmp (DDC->vendor.name, "API", 4) == 0 &&
- DDC->vendor.prod_id == 0x7602)
- return TRUE;
-
-
- return FALSE;
-}
-
-static Bool quirk_prefer_large_75 (int scrnIndex, xf86MonPtr DDC)
-{
- /* Bug #11603: Funai Electronics PM36B */
- if (memcmp (DDC->vendor.name, "FCM", 4) == 0 &&
- DDC->vendor.prod_id == 13600)
- return TRUE;
-
- return FALSE;
-}
-
-static Bool quirk_detailed_h_in_cm (int scrnIndex, xf86MonPtr DDC)
-{
- /* Bug #11603: Funai Electronics PM36B */
- if (memcmp (DDC->vendor.name, "FCM", 4) == 0 &&
- DDC->vendor.prod_id == 13600)
- return TRUE;
-
- return FALSE;
-}
-
-static Bool quirk_detailed_v_in_cm (int scrnIndex, xf86MonPtr DDC)
-{
- /* Bug #11603: Funai Electronics PM36B */
- if (memcmp (DDC->vendor.name, "FCM", 4) == 0 &&
- DDC->vendor.prod_id == 13600)
- return TRUE;
-
- /* Bug #21000: LGPhilipsLCD LP154W01-TLAJ */
- if (memcmp (DDC->vendor.name, "LPL", 4) == 0 &&
- DDC->vendor.prod_id == 47360)
- return TRUE;
-
- /* Bug #10304: LGPhilipsLCD LP154W01-A5 */
- if (memcmp(DDC->vendor.name, "LPL", 4) == 0 &&
- DDC->vendor.prod_id == 0)
- return TRUE;
-
- /* Bug #24482: LGPhilipsLCD LP154W01-TLA1 */
- if (memcmp(DDC->vendor.name, "LPL", 4) == 0 &&
- DDC->vendor.prod_id == 0x2a00)
- return TRUE;
-
- /* Bug #21750: Samsung Syncmaster 2333HD */
- if (memcmp (DDC->vendor.name, "SAM", 4) == 0 &&
- DDC->vendor.prod_id == 1157)
- return TRUE;
-
- return FALSE;
-}
-
-static Bool quirk_detailed_use_maximum_size (int scrnIndex, xf86MonPtr DDC)
-{
- /* Bug #21324: Iiyama Vision Master 450 */
- if (memcmp (DDC->vendor.name, "IVM", 4) == 0 &&
- DDC->vendor.prod_id == 6400)
- return TRUE;
-
- return FALSE;
-}
-
-static Bool quirk_135_clock_too_high (int scrnIndex, xf86MonPtr DDC)
-{
- /* Envision Peripherals, Inc. EN-7100e. See bug #9550. */
- if (memcmp (DDC->vendor.name, "EPI", 4) == 0 &&
- DDC->vendor.prod_id == 59264)
- return TRUE;
-
- return FALSE;
-}
-
-static Bool quirk_first_detailed_preferred (int scrnIndex, xf86MonPtr DDC)
-{
- /* Philips 107p5 CRT. Reported on xorg@ with pastebin. */
- if (memcmp (DDC->vendor.name, "PHL", 4) == 0 &&
- DDC->vendor.prod_id == 57364)
- return TRUE;
-
- /* Proview AY765C 17" LCD. See bug #15160*/
- if (memcmp (DDC->vendor.name, "PTS", 4) == 0 &&
- DDC->vendor.prod_id == 765)
- return TRUE;
-
- /* ACR of some sort RH #284231 */
- if (memcmp (DDC->vendor.name, "ACR", 4) == 0 &&
- DDC->vendor.prod_id == 2423)
- return TRUE;
-
- /* Peacock Ergovision 19. See rh#492359 */
- if (memcmp (DDC->vendor.name, "PEA", 4) == 0 &&
- DDC->vendor.prod_id == 9003)
- return TRUE;
-
- return FALSE;
-}
-
-static Bool quirk_detailed_sync_pp(int scrnIndex, xf86MonPtr DDC)
-{
- /* Bug #12439: Samsung SyncMaster 205BW */
- if (memcmp (DDC->vendor.name, "SAM", 4) == 0 &&
- DDC->vendor.prod_id == 541)
- return TRUE;
- return FALSE;
-}
-
-/* This should probably be made more generic */
-static Bool quirk_dvi_single_link(int scrnIndex, xf86MonPtr DDC)
-{
- /* Red Hat bug #453106: Apple 23" Cinema Display */
- if (memcmp (DDC->vendor.name, "APL", 4) == 0 &&
- DDC->vendor.prod_id == 0x921c)
- return TRUE;
- return FALSE;
-}
-
-typedef struct {
- Bool (*detect) (int scrnIndex, xf86MonPtr DDC);
- ddc_quirk_t quirk;
- char *description;
-} ddc_quirk_map_t;
-
-static const ddc_quirk_map_t ddc_quirks[] = {
- {
- quirk_prefer_large_60, DDC_QUIRK_PREFER_LARGE_60,
- "Detailed timing is not preferred, use largest mode at 60Hz"
- },
- {
- quirk_135_clock_too_high, DDC_QUIRK_135_CLOCK_TOO_HIGH,
- "Recommended 135MHz pixel clock is too high"
- },
- {
- quirk_prefer_large_75, DDC_QUIRK_PREFER_LARGE_75,
- "Detailed timing is not preferred, use largest mode at 75Hz"
- },
- {
- quirk_detailed_h_in_cm, DDC_QUIRK_DETAILED_H_IN_CM,
- "Detailed timings give horizontal size in cm."
- },
- {
- quirk_detailed_v_in_cm, DDC_QUIRK_DETAILED_V_IN_CM,
- "Detailed timings give vertical size in cm."
- },
- {
- quirk_detailed_use_maximum_size, DDC_QUIRK_DETAILED_USE_MAXIMUM_SIZE,
- "Use maximum size instead of detailed timing sizes."
- },
- {
- quirk_first_detailed_preferred, DDC_QUIRK_FIRST_DETAILED_PREFERRED,
- "First detailed timing was not marked as preferred."
- },
- {
- quirk_detailed_sync_pp, DDC_QUIRK_DETAILED_SYNC_PP,
- "Use +hsync +vsync for detailed timing."
- },
- {
- quirk_dvi_single_link, DDC_QUIRK_DVI_SINGLE_LINK,
- "Forcing maximum pixel clock to single DVI link."
- },
- {
- NULL, DDC_QUIRK_NONE,
- "No known quirks"
- },
-};
-
-/*
- * These more or less come from the DMT spec. The 720x400 modes are
- * inferred from historical 80x25 practice. The 640x480@67 and 832x624@75
- * modes are old-school Mac modes. The EDID spec says the 1152x864@75 mode
- * should be 1152x870, again for the Mac, but instead we use the x864 DMT
- * mode.
- *
- * The DMT modes have been fact-checked; the rest are mild guesses.
- */
-#define MODEPREFIX NULL, NULL, NULL, 0, M_T_DRIVER
-#define MODESUFFIX 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FALSE,FALSE,0,NULL,0,0.0,0.0
-
-static const DisplayModeRec DDCEstablishedModes[17] = {
- { MODEPREFIX, 40000, 800, 840, 968, 1056, 0, 600, 601, 605, 628, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@60Hz */
- { MODEPREFIX, 36000, 800, 824, 896, 1024, 0, 600, 601, 603, 625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@56Hz */
- { MODEPREFIX, 31500, 640, 656, 720, 840, 0, 480, 481, 484, 500, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@75Hz */
- { MODEPREFIX, 31500, 640, 664, 704, 832, 0, 480, 489, 492, 520, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@72Hz */
- { MODEPREFIX, 30240, 640, 704, 768, 864, 0, 480, 483, 486, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@67Hz */
- { MODEPREFIX, 25175, 640, 656, 752, 800, 0, 480, 490, 492, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@60Hz */
- { MODEPREFIX, 35500, 720, 738, 846, 900, 0, 400, 421, 423, 449, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 720x400@88Hz */
- { MODEPREFIX, 28320, 720, 738, 846, 900, 0, 400, 412, 414, 449, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 720x400@70Hz */
- { MODEPREFIX, 135000, 1280, 1296, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x1024@75Hz */
- { MODEPREFIX, 78750, 1024, 1040, 1136, 1312, 0, 768, 769, 772, 800, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1024x768@75Hz */
- { MODEPREFIX, 75000, 1024, 1048, 1184, 1328, 0, 768, 771, 777, 806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768@70Hz */
- { MODEPREFIX, 65000, 1024, 1048, 1184, 1344, 0, 768, 771, 777, 806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768@60Hz */
- { MODEPREFIX, 44900, 1024, 1032, 1208, 1264, 0, 768, 768, 772, 817, 0, V_PHSYNC | V_PVSYNC | V_INTERLACE, MODESUFFIX }, /* 1024x768@43Hz */
- { MODEPREFIX, 57284, 832, 864, 928, 1152, 0, 624, 625, 628, 667, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 832x624@75Hz */
- { MODEPREFIX, 49500, 800, 816, 896, 1056, 0, 600, 601, 604, 625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@75Hz */
- { MODEPREFIX, 50000, 800, 856, 976, 1040, 0, 600, 637, 643, 666, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@72Hz */
- { MODEPREFIX, 108000, 1152, 1216, 1344, 1600, 0, 864, 865, 868, 900, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1152x864@75Hz */
-};
-
-static DisplayModePtr
-DDCModesFromEstablished(int scrnIndex, struct established_timings *timing,
- ddc_quirk_t quirks)
-{
- DisplayModePtr Modes = NULL, Mode = NULL;
- CARD32 bits = (timing->t1) | (timing->t2 << 8) |
- ((timing->t_manu & 0x80) << 9);
- int i;
-
- for (i = 0; i < 17; i++) {
- if (bits & (0x01 << i)) {
- Mode = xf86DuplicateMode(&DDCEstablishedModes[i]);
- Modes = xf86ModesAdd(Modes, Mode);
- }
- }
-
- return Modes;
-}
-
-/* Autogenerated from the DMT spec */
-const DisplayModeRec DMTModes[] = {
- { MODEPREFIX, 31500, 640, 672, 736, 832, 0, 350, 382, 385, 445, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x350@85Hz */
- { MODEPREFIX, 31500, 640, 672, 736, 832, 0, 400, 401, 404, 445, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 640x400@85Hz */
- { MODEPREFIX, 35500, 720, 756, 828, 936, 0, 400, 401, 404, 446, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 720x400@85Hz */
- { MODEPREFIX, 25175, 640, 656, 752, 800, 0, 480, 490, 492, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@60Hz */
- { MODEPREFIX, 31500, 640, 664, 704, 832, 0, 480, 489, 492, 520, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@72Hz */
- { MODEPREFIX, 31500, 640, 656, 720, 840, 0, 480, 481, 484, 500, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@75Hz */
- { MODEPREFIX, 36000, 640, 696, 752, 832, 0, 480, 481, 484, 509, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@85Hz */
- { MODEPREFIX, 36000, 800, 824, 896, 1024, 0, 600, 601, 603, 625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@56Hz */
- { MODEPREFIX, 40000, 800, 840, 968, 1056, 0, 600, 601, 605, 628, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@60Hz */
- { MODEPREFIX, 50000, 800, 856, 976, 1040, 0, 600, 637, 643, 666, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@72Hz */
- { MODEPREFIX, 49500, 800, 816, 896, 1056, 0, 600, 601, 604, 625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@75Hz */
- { MODEPREFIX, 56250, 800, 832, 896, 1048, 0, 600, 601, 604, 631, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@85Hz */
- { MODEPREFIX, 73250, 800, 848, 880, 960, 0, 600, 603, 607, 636, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 800x600@120Hz RB */
- { MODEPREFIX, 33750, 848, 864, 976, 1088, 0, 480, 486, 494, 517, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 848x480@60Hz */
- { MODEPREFIX, 44900, 1024, 1032, 1208, 1264, 0, 768, 768, 772, 817, 0, V_PHSYNC | V_PVSYNC | V_INTERLACE, MODESUFFIX }, /* 1024x768@43Hz (interlaced) */
- { MODEPREFIX, 65000, 1024, 1048, 1184, 1344, 0, 768, 771, 777, 806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768@60Hz */
- { MODEPREFIX, 75000, 1024, 1048, 1184, 1328, 0, 768, 771, 777, 806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768@70Hz */
- { MODEPREFIX, 78750, 1024, 1040, 1136, 1312, 0, 768, 769, 772, 800, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1024x768@75Hz */
- { MODEPREFIX, 94500, 1024, 1072, 1168, 1376, 0, 768, 769, 772, 808, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1024x768@85Hz */
- { MODEPREFIX, 115500, 1024, 1072, 1104, 1184, 0, 768, 771, 775, 813, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768@120Hz RB */
- { MODEPREFIX, 108000, 1152, 1216, 1344, 1600, 0, 864, 865, 868, 900, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1152x864@75Hz */
- { MODEPREFIX, 68250, 1280, 1328, 1360, 1440, 0, 768, 771, 778, 790, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1280x768@60Hz RB */
- { MODEPREFIX, 79500, 1280, 1344, 1472, 1664, 0, 768, 771, 778, 798, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x768@60Hz */
- { MODEPREFIX, 102250, 1280, 1360, 1488, 1696, 0, 768, 771, 778, 805, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x768@75Hz */
- { MODEPREFIX, 117500, 1280, 1360, 1496, 1712, 0, 768, 771, 778, 809, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x768@85Hz */
- { MODEPREFIX, 140250, 1280, 1328, 1360, 1440, 0, 768, 771, 778, 813, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1280x768@120Hz RB */
- { MODEPREFIX, 71000, 1280, 1328, 1360, 1440, 0, 800, 803, 809, 823, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1280x800@60Hz RB */
- { MODEPREFIX, 83500, 1280, 1352, 1480, 1680, 0, 800, 803, 809, 831, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x800@60Hz */
- { MODEPREFIX, 106500, 1280, 1360, 1488, 1696, 0, 800, 803, 809, 838, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x800@75Hz */
- { MODEPREFIX, 122500, 1280, 1360, 1496, 1712, 0, 800, 803, 809, 843, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x800@85Hz */
- { MODEPREFIX, 146250, 1280, 1328, 1360, 1440, 0, 800, 803, 809, 847, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1280x800@120Hz RB */
- { MODEPREFIX, 108000, 1280, 1376, 1488, 1800, 0, 960, 961, 964, 1000, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x960@60Hz */
- { MODEPREFIX, 148500, 1280, 1344, 1504, 1728, 0, 960, 961, 964, 1011, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x960@85Hz */
- { MODEPREFIX, 175500, 1280, 1328, 1360, 1440, 0, 960, 963, 967, 1017, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1280x960@120Hz RB */
- { MODEPREFIX, 108000, 1280, 1328, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x1024@60Hz */
- { MODEPREFIX, 135000, 1280, 1296, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x1024@75Hz */
- { MODEPREFIX, 157500, 1280, 1344, 1504, 1728, 0, 1024, 1025, 1028, 1072, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x1024@85Hz */
- { MODEPREFIX, 187250, 1280, 1328, 1360, 1440, 0, 1024, 1027, 1034, 1084, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1280x1024@120Hz RB */
- { MODEPREFIX, 85500, 1360, 1424, 1536, 1792, 0, 768, 771, 777, 795, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1360x768@60Hz */
- { MODEPREFIX, 148250, 1360, 1408, 1440, 1520, 0, 768, 771, 776, 813, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1360x768@120Hz RB */
- { MODEPREFIX, 101000, 1400, 1448, 1480, 1560, 0, 1050, 1053, 1057, 1080, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1400x1050@60Hz RB */
- { MODEPREFIX, 121750, 1400, 1488, 1632, 1864, 0, 1050, 1053, 1057, 1089, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1400x1050@60Hz */
- { MODEPREFIX, 156000, 1400, 1504, 1648, 1896, 0, 1050, 1053, 1057, 1099, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1400x1050@75Hz */
- { MODEPREFIX, 179500, 1400, 1504, 1656, 1912, 0, 1050, 1053, 1057, 1105, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1400x1050@85Hz */
- { MODEPREFIX, 208000, 1400, 1448, 1480, 1560, 0, 1050, 1053, 1057, 1112, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1400x1050@120Hz RB */
- { MODEPREFIX, 88750, 1440, 1488, 1520, 1600, 0, 900, 903, 909, 926, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1440x900@60Hz RB */
- { MODEPREFIX, 106500, 1440, 1520, 1672, 1904, 0, 900, 903, 909, 934, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1440x900@60Hz */
- { MODEPREFIX, 136750, 1440, 1536, 1688, 1936, 0, 900, 903, 909, 942, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1440x900@75Hz */
- { MODEPREFIX, 157000, 1440, 1544, 1696, 1952, 0, 900, 903, 909, 948, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1440x900@85Hz */
- { MODEPREFIX, 182750, 1440, 1488, 1520, 1600, 0, 900, 903, 909, 953, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1440x900@120Hz RB */
- { MODEPREFIX, 162000, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1600x1200@60Hz */
- { MODEPREFIX, 175500, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1600x1200@65Hz */
- { MODEPREFIX, 189000, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1600x1200@70Hz */
- { MODEPREFIX, 202500, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1600x1200@75Hz */
- { MODEPREFIX, 229500, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1600x1200@85Hz */
- { MODEPREFIX, 268250, 1600, 1648, 1680, 1760, 0, 1200, 1203, 1207, 1271, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1600x1200@120Hz RB */
- { MODEPREFIX, 119000, 1680, 1728, 1760, 1840, 0, 1050, 1053, 1059, 1080, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1680x1050@60Hz RB */
- { MODEPREFIX, 146250, 1680, 1784, 1960, 2240, 0, 1050, 1053, 1059, 1089, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1680x1050@60Hz */
- { MODEPREFIX, 187000, 1680, 1800, 1976, 2272, 0, 1050, 1053, 1059, 1099, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1680x1050@75Hz */
- { MODEPREFIX, 214750, 1680, 1808, 1984, 2288, 0, 1050, 1053, 1059, 1105, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1680x1050@85Hz */
- { MODEPREFIX, 245500, 1680, 1728, 1760, 1840, 0, 1050, 1053, 1059, 1112, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1680x1050@120Hz RB */
- { MODEPREFIX, 204750, 1792, 1920, 2120, 2448, 0, 1344, 1345, 1348, 1394, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1792x1344@60Hz */
- { MODEPREFIX, 261000, 1792, 1888, 2104, 2456, 0, 1344, 1345, 1348, 1417, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1792x1344@75Hz */
- { MODEPREFIX, 333250, 1792, 1840, 1872, 1952, 0, 1344, 1347, 1351, 1423, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1792x1344@120Hz RB */
- { MODEPREFIX, 218250, 1856, 1952, 2176, 2528, 0, 1392, 1393, 1396, 1439, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1856x1392@60Hz */
- { MODEPREFIX, 288000, 1856, 1984, 2208, 2560, 0, 1392, 1393, 1396, 1500, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1856x1392@75Hz */
- { MODEPREFIX, 356500, 1856, 1904, 1936, 2016, 0, 1392, 1395, 1399, 1474, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1856x1392@120Hz RB */
- { MODEPREFIX, 154000, 1920, 1968, 2000, 2080, 0, 1200, 1203, 1209, 1235, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1920x1200@60Hz RB */
- { MODEPREFIX, 193250, 1920, 2056, 2256, 2592, 0, 1200, 1203, 1209, 1245, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1920x1200@60Hz */
- { MODEPREFIX, 245250, 1920, 2056, 2264, 2608, 0, 1200, 1203, 1209, 1255, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1920x1200@75Hz */
- { MODEPREFIX, 281250, 1920, 2064, 2272, 2624, 0, 1200, 1203, 1209, 1262, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1920x1200@85Hz */
- { MODEPREFIX, 317000, 1920, 1968, 2000, 2080, 0, 1200, 1203, 1209, 1271, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1920x1200@120Hz RB */
- { MODEPREFIX, 234000, 1920, 2048, 2256, 2600, 0, 1440, 1441, 1444, 1500, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1920x1440@60Hz */
- { MODEPREFIX, 297000, 1920, 2064, 2288, 2640, 0, 1440, 1441, 1444, 1500, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1920x1440@75Hz */
- { MODEPREFIX, 380500, 1920, 1968, 2000, 2080, 0, 1440, 1443, 1447, 1525, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1920x1440@120Hz RB */
- { MODEPREFIX, 268500, 2560, 2608, 2640, 2720, 0, 1600, 1603, 1609, 1646, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 2560x1600@60Hz RB */
- { MODEPREFIX, 348500, 2560, 2752, 3032, 3504, 0, 1600, 1603, 1609, 1658, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 2560x1600@60Hz */
- { MODEPREFIX, 443250, 2560, 2768, 3048, 3536, 0, 1600, 1603, 1609, 1672, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 2560x1600@75Hz */
- { MODEPREFIX, 505250, 2560, 2768, 3048, 3536, 0, 1600, 1603, 1609, 1682, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 2560x1600@85Hz */
- { MODEPREFIX, 552750, 2560, 2608, 2640, 2720, 0, 1600, 1603, 1609, 1694, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 2560x1600@120Hz RB */
-};
-
-#define LEVEL_DMT 0
-#define LEVEL_GTF 1
-#define LEVEL_CVT 2
-
-static int
-MonitorStandardTimingLevel(xf86MonPtr DDC)
-{
- if (DDC->ver.revision >= 2) {
- if (DDC->ver.revision >= 4 && CVT_SUPPORTED(DDC->features.msc)) {
- return LEVEL_CVT;
- }
- return LEVEL_GTF;
- }
- return LEVEL_DMT;
-}
-
-static int
-ModeRefresh(const DisplayModeRec *mode)
-{
- return (int)(xf86ModeVRefresh(mode) + 0.5);
-}
-
-/*
- * If rb is not set, then we'll not consider reduced-blanking modes as
- * part of the DMT pool. For the 'standard' EDID mode descriptor there's
- * no way to specify whether the mode should be RB or not.
- */
-DisplayModePtr
-FindDMTMode(int hsize, int vsize, int refresh, Bool rb)
-{
- int i;
- const DisplayModeRec *ret;
-
- for (i = 0; i < sizeof(DMTModes) / sizeof(DisplayModeRec); i++) {
- ret = &DMTModes[i];
-
- if (!rb && xf86ModeIsReduced(ret))
- continue;
-
- if (ret->HDisplay == hsize &&
- ret->VDisplay == vsize &&
- refresh == ModeRefresh(ret))
- return xf86DuplicateMode(ret);
- }
-
- return NULL;
-}
-
-/*
- * Appendix B of the EDID 1.4 spec defines the right thing to do here.
- * If the timing given here matches a mode defined in the VESA DMT standard,
- * we _must_ use that. If the device supports CVT modes, then we should
- * generate a CVT timing. If both of the above fail, use GTF.
- *
- * There are some wrinkles here. EDID 1.1 and 1.0 sinks can't really
- * "support" GTF, since it wasn't a standard yet; so if they ask for a
- * timing in this section that isn't defined in DMT, returning a GTF mode
- * may not actually be valid. EDID 1.3 sinks often report support for
- * some CVT modes, but they are not required to support CVT timings for
- * modes in the standard timing descriptor, so we should _not_ treat them
- * as CVT-compliant (unless specified in an extension block I suppose).
- *
- * EDID 1.4 requires that all sink devices support both GTF and CVT timings
- * for modes in this section, but does say that CVT is preferred.
- */
-static DisplayModePtr
-DDCModesFromStandardTiming(struct std_timings *timing, ddc_quirk_t quirks,
- int timing_level, Bool rb)
-{
- DisplayModePtr Modes = NULL, Mode = NULL;
- int i, hsize, vsize, refresh;
-
- for (i = 0; i < STD_TIMINGS; i++) {
- hsize = timing[i].hsize;
- vsize = timing[i].vsize;
- refresh = timing[i].refresh;
-
- /* HDTV hack, because you can't say 1366 */
- if (refresh == 60 &&
- ((hsize == 1360 && vsize == 765) ||
- (hsize == 1368 && vsize == 769))) {
- Mode = xf86CVTMode(1366, 768, 60, FALSE, FALSE);
- Mode->HDisplay = 1366;
- Mode->VSyncStart--;
- Mode->VSyncEnd--;
- } else if (hsize && vsize && refresh) {
- Mode = FindDMTMode(hsize, vsize, refresh, rb);
-
- if (!Mode) {
- if (timing_level == LEVEL_CVT)
- /* pass rb here too? */
- Mode = xf86CVTMode(hsize, vsize, refresh, FALSE, FALSE);
- else if (timing_level == LEVEL_GTF)
- Mode = xf86GTFMode(hsize, vsize, refresh, FALSE, FALSE);
- }
-
- }
-
- if (Mode) {
- Mode->type = M_T_DRIVER;
- Modes = xf86ModesAdd(Modes, Mode);
- }
- Mode = NULL;
- }
-
- return Modes;
-}
-
-static void
-DDCModeDoInterlaceQuirks(DisplayModePtr mode)
-{
- /*
- * EDID is delightfully ambiguous about how interlaced modes are to be
- * encoded. X's internal representation is of frame height, but some
- * HDTV detailed timings are encoded as field height.
- *
- * The format list here is from CEA, in frame size. Technically we
- * should be checking refresh rate too. Whatever.
- */
- static const struct {
- int w, h;
- } cea_interlaced[] = {
- { 1920, 1080 },
- { 720, 480 },
- { 1440, 480 },
- { 2880, 480 },
- { 720, 576 },
- { 1440, 576 },
- { 2880, 576 },
- };
- static const int n_modes = sizeof(cea_interlaced)/sizeof(cea_interlaced[0]);
- int i;
-
- for (i = 0; i < n_modes; i++) {
- if ((mode->HDisplay == cea_interlaced[i].w) &&
- (mode->VDisplay == cea_interlaced[i].h / 2)) {
- mode->VDisplay *= 2;
- mode->VSyncStart *= 2;
- mode->VSyncEnd *= 2;
- mode->VTotal *= 2;
- mode->VTotal |= 1;
- }
- }
-
- mode->Flags |= V_INTERLACE;
-}
-
-/*
- *
- */
-static DisplayModePtr
-DDCModeFromDetailedTiming(int scrnIndex, struct detailed_timings *timing,
- Bool preferred, ddc_quirk_t quirks)
-{
- DisplayModePtr Mode;
-
- /*
- * Refuse to create modes that are insufficiently large. 64 is a random
- * number, maybe the spec says something about what the minimum is. In
- * particular I see this frequently with _old_ EDID, 1.0 or so, so maybe
- * our parser is just being too aggresive there.
- */
- if (timing->h_active < 64 || timing->v_active < 64) {
- xf86DrvMsg(scrnIndex, X_INFO,
- "%s: Ignoring tiny %dx%d mode\n", __func__,
- timing->h_active, timing->v_active);
- return NULL;
- }
-
- /* We don't do stereo */
- if (timing->stereo) {
- xf86DrvMsg(scrnIndex, X_INFO,
- "%s: Ignoring: We don't handle stereo.\n", __func__);
- return NULL;
- }
-
- /* We only do seperate sync currently */
- if (timing->sync != 0x03) {
- xf86DrvMsg(scrnIndex, X_INFO,
- "%s: %dx%d Warning: We only handle separate"
- " sync.\n", __func__, timing->h_active, timing->v_active);
- }
-
- Mode = xnfcalloc(1, sizeof(DisplayModeRec));
-
- Mode->type = M_T_DRIVER;
- if (preferred)
- Mode->type |= M_T_PREFERRED;
-
- if( ( quirks & DDC_QUIRK_135_CLOCK_TOO_HIGH ) &&
- timing->clock == 135000000 )
- Mode->Clock = 108880;
- else
- Mode->Clock = timing->clock / 1000.0;
-
- Mode->HDisplay = timing->h_active;
- Mode->HSyncStart = timing->h_active + timing->h_sync_off;
- Mode->HSyncEnd = Mode->HSyncStart + timing->h_sync_width;
- Mode->HTotal = timing->h_active + timing->h_blanking;
-
- Mode->VDisplay = timing->v_active;
- Mode->VSyncStart = timing->v_active + timing->v_sync_off;
- Mode->VSyncEnd = Mode->VSyncStart + timing->v_sync_width;
- Mode->VTotal = timing->v_active + timing->v_blanking;
-
- /* perform basic check on the detail timing */
- if (Mode->HSyncEnd > Mode->HTotal || Mode->VSyncEnd > Mode->VTotal) {
- xfree(Mode);
- return NULL;
- }
-
- /* We ignore h/v_size and h/v_border for now. */
-
- if (timing->interlaced)
- DDCModeDoInterlaceQuirks(Mode);
-
- if (quirks & DDC_QUIRK_DETAILED_SYNC_PP)
- Mode->Flags |= V_PVSYNC | V_PHSYNC;
- else {
- if (timing->misc & 0x02)
- Mode->Flags |= V_PVSYNC;
- else
- Mode->Flags |= V_NVSYNC;
-
- if (timing->misc & 0x01)
- Mode->Flags |= V_PHSYNC;
- else
- Mode->Flags |= V_NHSYNC;
- }
-
- xf86SetModeDefaultName(Mode);
-
- return Mode;
-}
-
-#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
-static DisplayModePtr
-DDCModesFromCVT(int scrnIndex, struct cvt_timings *t)
-{
- DisplayModePtr modes = NULL;
- int i;
-
- for (i = 0; i < 4; i++) {
- if (t[i].height) {
- if (t[i].rates & 0x10)
- modes = xf86ModesAdd(modes,
- xf86CVTMode(t[i].width, t[i].height, 50, 0, 0));
- if (t[i].rates & 0x08)
- modes = xf86ModesAdd(modes,
- xf86CVTMode(t[i].width, t[i].height, 60, 0, 0));
- if (t[i].rates & 0x04)
- modes = xf86ModesAdd(modes,
- xf86CVTMode(t[i].width, t[i].height, 75, 0, 0));
- if (t[i].rates & 0x02)
- modes = xf86ModesAdd(modes,
- xf86CVTMode(t[i].width, t[i].height, 85, 0, 0));
- if (t[i].rates & 0x01)
- modes = xf86ModesAdd(modes,
- xf86CVTMode(t[i].width, t[i].height, 60, 1, 0));
- } else break;
- }
-
- return modes;
-}
-#endif
-
-static const struct {
- short w;
- short h;
- short r;
- short rb;
-} EstIIIModes[] = {
- /* byte 6 */
- { 640, 350, 85, 0 },
- { 640, 400, 85, 0 },
- { 720, 400, 85, 0 },
- { 640, 480, 85, 0 },
- { 848, 480, 60, 0 },
- { 800, 600, 85, 0 },
- { 1024, 768, 85, 0 },
- { 1152, 864, 75, 0 },
- /* byte 7 */
- { 1280, 768, 60, 1 },
- { 1280, 768, 60, 0 },
- { 1280, 768, 75, 0 },
- { 1280, 768, 85, 0 },
- { 1280, 960, 60, 0 },
- { 1280, 960, 85, 0 },
- { 1280, 1024, 60, 0 },
- { 1280, 1024, 85, 0 },
- /* byte 8 */
- { 1360, 768, 60, 0 },
- { 1440, 900, 60, 1 },
- { 1440, 900, 60, 0 },
- { 1440, 900, 75, 0 },
- { 1440, 900, 85, 0 },
- { 1400, 1050, 60, 1 },
- { 1400, 1050, 60, 0 },
- { 1400, 1050, 75, 0 },
- /* byte 9 */
- { 1400, 1050, 85, 0 },
- { 1680, 1050, 60, 1 },
- { 1680, 1050, 60, 0 },
- { 1680, 1050, 75, 0 },
- { 1680, 1050, 85, 0 },
- { 1600, 1200, 60, 0 },
- { 1600, 1200, 65, 0 },
- { 1600, 1200, 70, 0 },
- /* byte 10 */
- { 1600, 1200, 75, 0 },
- { 1600, 1200, 85, 0 },
- { 1792, 1344, 60, 0 },
- { 1792, 1344, 85, 0 },
- { 1856, 1392, 60, 0 },
- { 1856, 1392, 75, 0 },
- { 1920, 1200, 60, 1 },
- { 1920, 1200, 60, 0 },
- /* byte 11 */
- { 1920, 1200, 75, 0 },
- { 1920, 1200, 85, 0 },
- { 1920, 1440, 60, 0 },
- { 1920, 1440, 75, 0 },
-};
-
-static DisplayModePtr
-DDCModesFromEstIII(unsigned char *est)
-{
- DisplayModePtr modes = NULL;
- int i, j, m;
-
- for (i = 0; i < 6; i++) {
- for (j = 7; j > 0; j--) {
- if (est[i] & (1 << j)) {
- m = (i * 8) + (7 - j);
- modes = xf86ModesAdd(modes,
- FindDMTMode(EstIIIModes[m].w,
- EstIIIModes[m].h,
- EstIIIModes[m].r,
- EstIIIModes[m].rb));
- }
- }
- }
-
- return modes;
-}
-
-/*
- * This is only valid when the sink claims to be continuous-frequency
- * but does not supply a detailed range descriptor. Such sinks are
- * arguably broken. Currently the mode validation code isn't aware of
- * this; the non-RANDR code even punts the decision of optional sync
- * range checking to the driver. Loss.
- */
-static void
-DDCGuessRangesFromModes(int scrnIndex, MonPtr Monitor, DisplayModePtr Modes)
-{
- DisplayModePtr Mode = Modes;
-
- if (!Monitor || !Modes)
- return;
-
- /* set up the ranges for scanning through the modes */
- Monitor->nHsync = 1;
- Monitor->hsync[0].lo = 1024.0;
- Monitor->hsync[0].hi = 0.0;
-
- Monitor->nVrefresh = 1;
- Monitor->vrefresh[0].lo = 1024.0;
- Monitor->vrefresh[0].hi = 0.0;
-
- while (Mode) {
- if (!Mode->HSync)
- Mode->HSync = ((float) Mode->Clock ) / ((float) Mode->HTotal);
-
- if (!Mode->VRefresh)
- Mode->VRefresh = (1000.0 * ((float) Mode->Clock)) /
- ((float) (Mode->HTotal * Mode->VTotal));
-
- if (Mode->HSync < Monitor->hsync[0].lo)
- Monitor->hsync[0].lo = Mode->HSync;
-
- if (Mode->HSync > Monitor->hsync[0].hi)
- Monitor->hsync[0].hi = Mode->HSync;
-
- if (Mode->VRefresh < Monitor->vrefresh[0].lo)
- Monitor->vrefresh[0].lo = Mode->VRefresh;
-
- if (Mode->VRefresh > Monitor->vrefresh[0].hi)
- Monitor->vrefresh[0].hi = Mode->VRefresh;
-
- Mode = Mode->next;
- }
-}
-
-ddc_quirk_t
-xf86DDCDetectQuirks(int scrnIndex, xf86MonPtr DDC, Bool verbose)
-{
- ddc_quirk_t quirks;
- int i;
-
- quirks = DDC_QUIRK_NONE;
- for (i = 0; ddc_quirks[i].detect; i++) {
- if (ddc_quirks[i].detect (scrnIndex, DDC)) {
- if (verbose) {
- xf86DrvMsg (scrnIndex, X_INFO, " EDID quirk: %s\n",
- ddc_quirks[i].description);
- }
- quirks |= ddc_quirks[i].quirk;
- }
- }
-
- return quirks;
-}
-
-void xf86DetTimingApplyQuirks(struct detailed_monitor_section *det_mon,
- ddc_quirk_t quirks,
- int hsize, int vsize)
-{
- if (det_mon->type != DT)
- return;
-
- if (quirks & DDC_QUIRK_DETAILED_H_IN_CM)
- det_mon->section.d_timings.h_size *= 10;
-
- if (quirks & DDC_QUIRK_DETAILED_V_IN_CM)
- det_mon->section.d_timings.v_size *= 10;
-
- if (quirks & DDC_QUIRK_DETAILED_USE_MAXIMUM_SIZE) {
- det_mon->section.d_timings.h_size = 10 * hsize;
- det_mon->section.d_timings.v_size = 10 * vsize;
- }
-}
-
-/**
- * Applies monitor-specific quirks to the decoded EDID information.
- *
- * Note that some quirks applying to the mode list are still implemented in
- * xf86DDCGetModes.
- */
-void
-xf86DDCApplyQuirks(int scrnIndex, xf86MonPtr DDC)
-{
- ddc_quirk_t quirks = xf86DDCDetectQuirks (scrnIndex, DDC, FALSE);
- int i;
-
- for (i = 0; i < DET_TIMINGS; i++) {
- xf86DetTimingApplyQuirks(DDC->det_mon + i, quirks,
- DDC->features.hsize,
- DDC->features.vsize);
- }
-}
-
-/**
- * Walks the modes list, finding the mode with the largest area which is
- * closest to the target refresh rate, and marks it as the only preferred mode.
-*/
-static void
-xf86DDCSetPreferredRefresh(int scrnIndex, DisplayModePtr modes,
- float target_refresh)
-{
- DisplayModePtr mode, best = modes;
-
- for (mode = modes; mode; mode = mode->next)
- {
- mode->type &= ~M_T_PREFERRED;
-
- if (mode == best) continue;
-
- if (mode->HDisplay * mode->VDisplay >
- best->HDisplay * best->VDisplay)
- {
- best = mode;
- continue;
- }
- if (mode->HDisplay * mode->VDisplay ==
- best->HDisplay * best->VDisplay)
- {
- double mode_refresh = xf86ModeVRefresh (mode);
- double best_refresh = xf86ModeVRefresh (best);
- double mode_dist = fabs(mode_refresh - target_refresh);
- double best_dist = fabs(best_refresh - target_refresh);
-
- if (mode_dist < best_dist)
- {
- best = mode;
- continue;
- }
- }
- }
- if (best)
- best->type |= M_T_PREFERRED;
-}
-
-#define CEA_VIDEO_MODES_NUM 64
-static const DisplayModeRec CEAVideoModes[CEA_VIDEO_MODES_NUM] = {
- { MODEPREFIX, 25175, 640, 656, 752, 800, 0, 480, 490, 492, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 1:640x480@60Hz */
- { MODEPREFIX, 27000, 720, 736, 798, 858, 0, 480, 489, 495, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 2:720x480@60Hz */
- { MODEPREFIX, 27000, 720, 736, 798, 858, 0, 480, 489, 495, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 3:720x480@60Hz */
- { MODEPREFIX, 74250, 1280, 1390, 1430, 1650, 0, 720, 725, 730, 750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 4: 1280x720@60Hz */
- { MODEPREFIX, 74250, 1920, 2008, 2052, 2200, 0, 1080, 1084, 1094, 1125, 0, V_PHSYNC | V_PVSYNC | V_INTERLACE, MODESUFFIX }, /* VIC 5:1920x1080i@60Hz */
- { MODEPREFIX, 27000, 1440, 1478, 1602, 1716, 0, 480, 488, 494, 525, 0, V_NHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX }, /* VIC 6:1440x480i@60Hz */
- { MODEPREFIX, 27000, 1440, 1478, 1602, 1716, 0, 480, 488, 494, 525, 0, V_NHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX }, /* VIC 7:1440x480i@60Hz */
- { MODEPREFIX, 27000, 1440, 1478, 1602, 1716, 0, 240, 244, 247, 262, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 8:1440x240@60Hz */
- { MODEPREFIX, 27000, 1440, 1478, 1602, 1716, 0, 240, 244, 247, 262, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 9:1440x240@60Hz */
- { MODEPREFIX, 54000, 2880, 2956, 3204, 3432, 0, 480, 488, 494, 525, 0, V_NHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX }, /* VIC 10:2880x480i@60Hz */
- { MODEPREFIX, 54000, 2880, 2956, 3204, 3432, 0, 480, 488, 494, 525, 0, V_NHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX }, /* VIC 11:2880x480i@60Hz */
- { MODEPREFIX, 54000, 2880, 2956, 3204, 3432, 0, 240, 244, 247, 262, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 12:2880x240@60Hz */
- { MODEPREFIX, 54000, 2880, 2956, 3204, 3432, 0, 240, 244, 247, 262, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 13:2880x240@60Hz */
- { MODEPREFIX, 54000, 1440, 1472, 1596, 1716, 0, 480, 489, 495, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 14:1440x480@60Hz */
- { MODEPREFIX, 54000, 1440, 1472, 1596, 1716, 0, 480, 489, 495, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 15:1440x480@60Hz */
- { MODEPREFIX, 148500, 1920, 2008, 2052, 2200, 0, 1080, 1084, 1089, 1125, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 16:1920x1080@60Hz */
- { MODEPREFIX, 27000, 720, 732, 796, 864, 0, 576, 581, 586, 625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 17:720x576@50Hz */
- { MODEPREFIX, 27000, 720, 732, 796, 864, 0, 576, 581, 586, 625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 18:720x576@50Hz */
- { MODEPREFIX, 74250, 1280, 1720, 1760, 1980, 0, 720, 725, 730, 750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 19: 1280x720@50Hz */
- { MODEPREFIX, 74250, 1920, 2448, 2492, 2640, 0, 1080, 1084, 1094, 1125, 0, V_PHSYNC | V_PVSYNC | V_INTERLACE, MODESUFFIX }, /* VIC 20:1920x1080i@50Hz */
- { MODEPREFIX, 27000, 1440, 1464, 1590, 1728, 0, 576, 580, 586, 625, 0, V_NHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX }, /* VIC 21:1440x576i@50Hz */
- { MODEPREFIX, 27000, 1440, 1464, 1590, 1728, 0, 576, 580, 586, 625, 0, V_NHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX }, /* VIC 22:1440x576i@50Hz */
- { MODEPREFIX, 27000, 1440, 1464, 1590, 1728, 0, 288, 290, 293, 312, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 23:1440x288@50Hz */
- { MODEPREFIX, 27000, 1440, 1464, 1590, 1728, 0, 288, 290, 293, 312, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 24:1440x288@50Hz */
- { MODEPREFIX, 54000, 2880, 2928, 3180, 3456, 0, 576, 580, 586, 625, 0, V_NHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX }, /* VIC 25:2880x576i@50Hz */
- { MODEPREFIX, 54000, 2880, 2928, 3180, 3456, 0, 576, 580, 586, 625, 0, V_NHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX }, /* VIC 26:2880x576i@50Hz */
- { MODEPREFIX, 54000, 2880, 2928, 3180, 3456, 0, 288, 290, 293, 312, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 27:2880x288@50Hz */
- { MODEPREFIX, 54000, 2880, 2928, 3180, 3456, 0, 288, 290, 293, 312, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 28:2880x288@50Hz */
- { MODEPREFIX, 54000, 1440, 1464, 1592, 1728, 0, 576, 581, 586, 625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 29:1440x576@50Hz */
- { MODEPREFIX, 54000, 1440, 1464, 1592, 1728, 0, 576, 581, 586, 625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 30:1440x576@50Hz */
- { MODEPREFIX, 148500, 1920, 2448, 2492, 2640, 0, 1080, 1084, 1089, 1125, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 31:1920x1080@50Hz */
- { MODEPREFIX, 74250, 1920, 2558, 2602, 2750, 0, 1080, 1084, 1089, 1125, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 32:1920x1080@24Hz */
- { MODEPREFIX, 74250, 1920, 2448, 2492, 2640, 0, 1080, 1084, 1089, 1125, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 33:1920x1080@25Hz */
- { MODEPREFIX, 74250, 1920, 2008, 2052, 2200, 0, 1080, 1084, 1089, 1125, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 34:1920x1080@30Hz */
- { MODEPREFIX, 108000, 2880, 2944, 3192, 3432, 0, 480, 489, 495, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 35:2880x480@60Hz */
- { MODEPREFIX, 108000, 2880, 2944, 3192, 3432, 0, 480, 489, 495, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 36:2880x480@60Hz */
- { MODEPREFIX, 108000, 2880, 2928, 3184, 3456, 0, 576, 581, 586, 625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 37:2880x576@50Hz */
- { MODEPREFIX, 108000, 2880, 2928, 3184, 3456, 0, 576, 581, 586, 625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 38:2880x576@50Hz */
- { MODEPREFIX, 72000, 1920, 1952, 2120, 2304, 0, 1080, 1126, 1136, 1250, 0, V_PHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX }, /* VIC 39:1920x1080i@50Hz */
- { MODEPREFIX, 148500, 1920, 2448, 2492, 2640, 0, 1080, 1084, 1094, 1125, 0, V_PHSYNC | V_PVSYNC | V_INTERLACE, MODESUFFIX }, /* VIC 40:1920x1080i@100Hz */
- { MODEPREFIX, 148500, 1280, 1720, 1760, 1980, 0, 720, 725, 730, 750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 41:1280x720@100Hz */
- { MODEPREFIX, 54000, 720, 732, 796, 864, 0, 576, 581, 586, 625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 42:720x576@100Hz */
- { MODEPREFIX, 54000, 720, 732, 796, 864, 0, 576, 581, 586, 625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 43:720x576@100Hz */
- { MODEPREFIX, 54000, 1440, 1464, 1590, 1728, 0, 576, 580, 586, 625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 44:1440x576i@100Hz */
- { MODEPREFIX, 54000, 1440, 1464, 1590, 1728, 0, 576, 580, 586, 625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 45:1440x576i@100Hz */
- { MODEPREFIX, 148500, 1920, 2008, 2052, 2200, 0, 1080, 1084, 1094, 1125, 0, V_PHSYNC | V_PVSYNC | V_INTERLACE, MODESUFFIX }, /* VIC 46:1920x1080i@120Hz */
- { MODEPREFIX, 148500, 1280, 1390, 1430, 1650, 0, 720, 725, 730, 750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 47:1280x720@120Hz */
- { MODEPREFIX, 54000, 720, 736, 798, 858, 0, 480, 489, 495, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 48:720x480@120Hz */
- { MODEPREFIX, 54000, 720, 736, 798, 858, 0, 480, 489, 495, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 49:720x480@120Hz */
- { MODEPREFIX, 54000, 1440, 1478, 1602, 1716, 0, 480, 488, 494, 525, 0, V_NHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX },/* VIC 50:1440x480i@120Hz */
- { MODEPREFIX, 54000, 1440, 1478, 1602, 1716, 0, 480, 488, 494, 525, 0, V_NHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX },/* VIC 51:1440x480i@120Hz */
- { MODEPREFIX, 108000, 720, 732, 796, 864, 0, 576, 581, 586, 625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 52:720x576@200Hz */
- { MODEPREFIX, 108000, 720, 732, 796, 864, 0, 576, 581, 586, 625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 53:720x576@200Hz */
- { MODEPREFIX, 108000, 1440, 1464, 1590, 1728, 0, 576, 580, 586, 625, 0, V_NHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX },/* VIC 54:1440x576i@200Hz */
- { MODEPREFIX, 108000, 1440, 1464, 1590, 1728, 0, 576, 580, 586, 625, 0, V_NHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX },/* VIC 55:1440x576i@200Hz */
- { MODEPREFIX, 108000, 720, 736, 798, 858, 0, 480, 489, 495, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 56:720x480@240Hz */
- { MODEPREFIX, 108000, 720, 736, 798, 858, 0, 480, 489, 495, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 57:720x480@240Hz */
- { MODEPREFIX, 108000, 1440, 1478, 1602, 1716, 0, 480, 488, 494, 525, 0, V_NHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX },/* VIC 58:1440x480i@240 */
- { MODEPREFIX, 108000, 1440, 1478, 1602, 1716, 0, 480, 488, 494, 525, 0, V_NHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX },/* VIC 59:1440x480i@240 */
- { MODEPREFIX, 59400, 1280, 3040, 3080, 3300, 0, 720, 725, 730, 750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 60: 1280x720@24Hz */
- { MODEPREFIX, 74250, 3700, 3740, 1430, 3960, 0, 720, 725, 730, 750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 61: 1280x720@25Hz */
- { MODEPREFIX, 74250, 1280, 3040, 3080, 3300, 0, 720, 725, 730, 750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 62: 1280x720@30Hz */
- { MODEPREFIX, 297000, 1920, 2008, 2052, 2200, 0, 1080, 1084, 1089, 1125, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 63: 1920x1080@120Hz */
- { MODEPREFIX, 297000, 1920, 2448, 2492, 2640, 0, 1080, 1084, 1094, 1125, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 64:1920x1080@100Hz */
-};
-
-/* chose mode line by cea short video descriptor*/
-static void handle_cea_svd(struct cea_video_block *video, void *data)
-{
- DisplayModePtr Mode;
- DisplayModePtr *Modes = (DisplayModePtr *) data;
- int vid;
-
- vid = video ->video_code & 0x7f;
- if (vid < CEA_VIDEO_MODES_NUM) {
- Mode = xf86DuplicateMode(CEAVideoModes + vid);
- *Modes = xf86ModesAdd(*Modes, Mode);
- }
-}
-
-static DisplayModePtr
-DDCModesFromCEAExtension(int scrnIndex, xf86MonPtr MonPtr)
-{
- DisplayModePtr Modes = NULL;
-
- xf86ForEachVideoBlock(MonPtr,
- handle_cea_svd,
- &Modes);
-
- return Modes;
-}
-
-struct det_modes_parameter {
- xf86MonPtr DDC;
- ddc_quirk_t quirks;
- DisplayModePtr Modes;
- Bool rb;
- Bool preferred;
- int timing_level;
-};
-
-static void handle_detailed_modes(struct detailed_monitor_section *det_mon,
- void *data)
-{
- DisplayModePtr Mode;
- struct det_modes_parameter *p = (struct det_modes_parameter *)data;
-
- xf86DetTimingApplyQuirks(det_mon,p->quirks,
- p->DDC->features.hsize,
- p->DDC->features.vsize);
-
- switch (det_mon->type) {
- case DT:
- Mode = DDCModeFromDetailedTiming(p->DDC->scrnIndex,
- &det_mon->section.d_timings,
- p->preferred,
- p->quirks);
- p->preferred = FALSE;
- p->Modes = xf86ModesAdd(p->Modes, Mode);
- break;
- case DS_STD_TIMINGS:
- Mode = DDCModesFromStandardTiming(det_mon->section.std_t,
- p->quirks, p->timing_level,p->rb);
- p->Modes = xf86ModesAdd(p->Modes, Mode);
- break;
-#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
- case DS_CVT:
- Mode = DDCModesFromCVT(p->DDC->scrnIndex, det_mon->section.cvt);
- p->Modes = xf86ModesAdd(p->Modes, Mode);
- break;
-#endif
- case DS_EST_III:
- Mode = DDCModesFromEstIII(det_mon->section.est_iii);
- p->Modes = xf86ModesAdd(p->Modes, Mode);
- break;
- default:
- break;
- }
-}
-
-DisplayModePtr
-xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
-{
- DisplayModePtr Modes = NULL, Mode;
- ddc_quirk_t quirks;
- Bool preferred, rb;
- int timing_level;
- struct det_modes_parameter p;
-
- xf86DrvMsg (scrnIndex, X_INFO, "EDID vendor \"%s\", prod id %d\n",
- DDC->vendor.name, DDC->vendor.prod_id);
-
- quirks = xf86DDCDetectQuirks(scrnIndex, DDC, TRUE);
-
- preferred = PREFERRED_TIMING_MODE(DDC->features.msc);
- if (DDC->ver.revision >= 4)
- preferred = TRUE;
- if (quirks & DDC_QUIRK_FIRST_DETAILED_PREFERRED)
- preferred = TRUE;
- if (quirks & (DDC_QUIRK_PREFER_LARGE_60 | DDC_QUIRK_PREFER_LARGE_75))
- preferred = FALSE;
-
- rb = xf86MonitorSupportsReducedBlanking(DDC);
-
- timing_level = MonitorStandardTimingLevel(DDC);
-
- p.quirks = quirks;
- p.DDC = DDC;
- p.Modes = Modes;
- p.rb = rb;
- p.preferred = preferred;
- p.timing_level = timing_level;
- xf86ForEachDetailedBlock(DDC, handle_detailed_modes, &p);
- Modes = p.Modes;
-
- /* Add established timings */
- Mode = DDCModesFromEstablished(scrnIndex, &DDC->timings1, quirks);
- Modes = xf86ModesAdd(Modes, Mode);
-
- /* Add standard timings */
- Mode = DDCModesFromStandardTiming(DDC->timings2, quirks, timing_level, rb);
- Modes = xf86ModesAdd(Modes, Mode);
-
- /* Add cea-extension mode timings */
- Mode = DDCModesFromCEAExtension(scrnIndex,DDC);
- Modes = xf86ModesAdd(Modes, Mode);
-
- if (quirks & DDC_QUIRK_PREFER_LARGE_60)
- xf86DDCSetPreferredRefresh(scrnIndex, Modes, 60);
-
- if (quirks & DDC_QUIRK_PREFER_LARGE_75)
- xf86DDCSetPreferredRefresh(scrnIndex, Modes, 75);
-
- Modes = xf86PruneDuplicateModes(Modes);
-
- return Modes;
-}
-
-struct det_mon_parameter {
- MonPtr Monitor;
- ddc_quirk_t quirks;
- Bool have_hsync;
- Bool have_vrefresh;
- Bool have_maxpixclock;
-};
-
-static void handle_detailed_monset(struct detailed_monitor_section *det_mon,
- void *data)
-{
- int clock;
- struct det_mon_parameter *p = (struct det_mon_parameter *)data;
- int scrnIndex = ((xf86MonPtr)(p->Monitor->DDC))->scrnIndex;
-
- switch (det_mon->type) {
- case DS_RANGES:
- if (!p->have_hsync) {
- if (!p->Monitor->nHsync)
- xf86DrvMsg(scrnIndex, X_INFO,
- "Using EDID range info for horizontal sync\n");
- p->Monitor->hsync[p->Monitor->nHsync].lo =
- det_mon->section.ranges.min_h;
- p->Monitor->hsync[p->Monitor->nHsync].hi =
- det_mon->section.ranges.max_h;
- p->Monitor->nHsync++;
- } else {
- xf86DrvMsg(scrnIndex, X_INFO,
- "Using hsync ranges from config file\n");
- }
-
- if (!p->have_vrefresh) {
- if (!p->Monitor->nVrefresh)
- xf86DrvMsg(scrnIndex, X_INFO,
- "Using EDID range info for vertical refresh\n");
- p->Monitor->vrefresh[p->Monitor->nVrefresh].lo =
- det_mon->section.ranges.min_v;
- p->Monitor->vrefresh[p->Monitor->nVrefresh].hi =
- det_mon->section.ranges.max_v;
- p->Monitor->nVrefresh++;
- } else {
- xf86DrvMsg(scrnIndex, X_INFO,
- "Using vrefresh ranges from config file\n");
- }
-
- clock = det_mon->section.ranges.max_clock * 1000;
- if (p->quirks & DDC_QUIRK_DVI_SINGLE_LINK)
- clock = min(clock, 165000);
- if (!p->have_maxpixclock && clock > p->Monitor->maxPixClock)
- p->Monitor->maxPixClock = clock;
-
- break;
- default:
- break;
- }
-}
-
-/*
- * Fill out MonPtr with xf86MonPtr information.
- */
-void
-xf86EdidMonitorSet(int scrnIndex, MonPtr Monitor, xf86MonPtr DDC)
-{
- DisplayModePtr Modes = NULL, Mode;
- struct det_mon_parameter p;
-
- if (!Monitor || !DDC)
- return;
-
- Monitor->DDC = DDC;
-
- if (Monitor->widthmm <= 0 || Monitor->heightmm <= 0) {
- Monitor->widthmm = 10 * DDC->features.hsize;
- Monitor->heightmm = 10 * DDC->features.vsize;
- }
-
- Monitor->reducedblanking = xf86MonitorSupportsReducedBlanking(DDC);
-
- Modes = xf86DDCGetModes(scrnIndex, DDC);
-
- /* Go through the detailed monitor sections */
- p.Monitor = Monitor;
- p.quirks = xf86DDCDetectQuirks(scrnIndex, Monitor->DDC, FALSE);
- p.have_hsync = (Monitor->nHsync != 0);
- p.have_vrefresh = (Monitor->nVrefresh != 0);
- p.have_maxpixclock = (Monitor->maxPixClock != 0);
- xf86ForEachDetailedBlock(DDC, handle_detailed_monset, &p);
-
- if (Modes) {
- /* Print Modes */
- xf86DrvMsg(scrnIndex, X_INFO, "Printing DDC gathered Modelines:\n");
-
- Mode = Modes;
- while (Mode) {
- xf86PrintModeline(scrnIndex, Mode);
- Mode = Mode->next;
- }
-
- /* Do we still need ranges to be filled in? */
- if (!Monitor->nHsync || !Monitor->nVrefresh)
- DDCGuessRangesFromModes(scrnIndex, Monitor, Modes);
-
- /* look for last Mode */
- Mode = Modes;
-
- while (Mode->next)
- Mode = Mode->next;
-
- /* add to MonPtr */
- if (Monitor->Modes) {
- Monitor->Last->next = Modes;
- Modes->prev = Monitor->Last;
- Monitor->Last = Mode;
- } else {
- Monitor->Modes = Modes;
- Monitor->Last = Mode;
- }
- }
-}
+/*
+ * Copyright 2006 Luc Verhaegen.
+ * Copyright 2008 Red Hat, 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, sub license,
+ * 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 (including the
+ * next paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * @file This file covers code to convert a xf86MonPtr containing EDID-probed
+ * information into a list of modes, including applying monitor-specific
+ * quirks to fix broken EDID data.
+ */
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#else
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#endif
+
+#define _PARSE_EDID_
+#include "xf86.h"
+#include "xf86DDC.h"
+#include <X11/Xatom.h>
+#include "property.h"
+#include "propertyst.h"
+#include "xf86Crtc.h"
+#include <string.h>
+#include <math.h>
+
+static void handle_detailed_rblank(struct detailed_monitor_section *det_mon,
+ void *data)
+{
+ if (det_mon->type == DS_RANGES)
+ if (det_mon->section.ranges.supported_blanking & CVT_REDUCED)
+ *(Bool*)data = TRUE;
+}
+
+static Bool
+xf86MonitorSupportsReducedBlanking(xf86MonPtr DDC)
+{
+ /* EDID 1.4 explicitly defines RB support */
+ if (DDC->ver.revision >= 4) {
+ Bool ret = FALSE;
+
+ xf86ForEachDetailedBlock(DDC, handle_detailed_rblank, &ret);
+ return ret;
+ }
+
+ /* For anything older, assume digital means RB support. Boo. */
+ if (DDC->features.input_type)
+ return TRUE;
+
+ return FALSE;
+}
+
+static Bool quirk_prefer_large_60 (int scrnIndex, xf86MonPtr DDC)
+{
+ /* Belinea 10 15 55 */
+ if (memcmp (DDC->vendor.name, "MAX", 4) == 0 &&
+ ((DDC->vendor.prod_id == 1516) ||
+ (DDC->vendor.prod_id == 0x77e)))
+ return TRUE;
+
+ /* Acer AL1706 */
+ if (memcmp (DDC->vendor.name, "ACR", 4) == 0 &&
+ DDC->vendor.prod_id == 44358)
+ return TRUE;
+
+ /* Bug #10814: Samsung SyncMaster 225BW */
+ if (memcmp (DDC->vendor.name, "SAM", 4) == 0 &&
+ DDC->vendor.prod_id == 596)
+ return TRUE;
+
+ /* Bug #10545: Samsung SyncMaster 226BW */
+ if (memcmp (DDC->vendor.name, "SAM", 4) == 0 &&
+ DDC->vendor.prod_id == 638)
+ return TRUE;
+
+ /* Acer F51 */
+ if (memcmp (DDC->vendor.name, "API", 4) == 0 &&
+ DDC->vendor.prod_id == 0x7602)
+ return TRUE;
+
+
+ return FALSE;
+}
+
+static Bool quirk_prefer_large_75 (int scrnIndex, xf86MonPtr DDC)
+{
+ /* Bug #11603: Funai Electronics PM36B */
+ if (memcmp (DDC->vendor.name, "FCM", 4) == 0 &&
+ DDC->vendor.prod_id == 13600)
+ return TRUE;
+
+ return FALSE;
+}
+
+static Bool quirk_detailed_h_in_cm (int scrnIndex, xf86MonPtr DDC)
+{
+ /* Bug #11603: Funai Electronics PM36B */
+ if (memcmp (DDC->vendor.name, "FCM", 4) == 0 &&
+ DDC->vendor.prod_id == 13600)
+ return TRUE;
+
+ return FALSE;
+}
+
+static Bool quirk_detailed_v_in_cm (int scrnIndex, xf86MonPtr DDC)
+{
+ /* Bug #11603: Funai Electronics PM36B */
+ if (memcmp (DDC->vendor.name, "FCM", 4) == 0 &&
+ DDC->vendor.prod_id == 13600)
+ return TRUE;
+
+ /* Bug #21000: LGPhilipsLCD LP154W01-TLAJ */
+ if (memcmp (DDC->vendor.name, "LPL", 4) == 0 &&
+ DDC->vendor.prod_id == 47360)
+ return TRUE;
+
+ /* Bug #10304: LGPhilipsLCD LP154W01-A5 */
+ if (memcmp(DDC->vendor.name, "LPL", 4) == 0 &&
+ DDC->vendor.prod_id == 0)
+ return TRUE;
+
+ /* Bug #24482: LGPhilipsLCD LP154W01-TLA1 */
+ if (memcmp(DDC->vendor.name, "LPL", 4) == 0 &&
+ DDC->vendor.prod_id == 0x2a00)
+ return TRUE;
+
+ /* Bug #21750: Samsung Syncmaster 2333HD */
+ if (memcmp (DDC->vendor.name, "SAM", 4) == 0 &&
+ DDC->vendor.prod_id == 1157)
+ return TRUE;
+
+ return FALSE;
+}
+
+static Bool quirk_detailed_use_maximum_size (int scrnIndex, xf86MonPtr DDC)
+{
+ /* Bug #21324: Iiyama Vision Master 450 */
+ if (memcmp (DDC->vendor.name, "IVM", 4) == 0 &&
+ DDC->vendor.prod_id == 6400)
+ return TRUE;
+
+ return FALSE;
+}
+
+static Bool quirk_135_clock_too_high (int scrnIndex, xf86MonPtr DDC)
+{
+ /* Envision Peripherals, Inc. EN-7100e. See bug #9550. */
+ if (memcmp (DDC->vendor.name, "EPI", 4) == 0 &&
+ DDC->vendor.prod_id == 59264)
+ return TRUE;
+
+ return FALSE;
+}
+
+static Bool quirk_first_detailed_preferred (int scrnIndex, xf86MonPtr DDC)
+{
+ /* Philips 107p5 CRT. Reported on xorg@ with pastebin. */
+ if (memcmp (DDC->vendor.name, "PHL", 4) == 0 &&
+ DDC->vendor.prod_id == 57364)
+ return TRUE;
+
+ /* Proview AY765C 17" LCD. See bug #15160*/
+ if (memcmp (DDC->vendor.name, "PTS", 4) == 0 &&
+ DDC->vendor.prod_id == 765)
+ return TRUE;
+
+ /* ACR of some sort RH #284231 */
+ if (memcmp (DDC->vendor.name, "ACR", 4) == 0 &&
+ DDC->vendor.prod_id == 2423)
+ return TRUE;
+
+ /* Peacock Ergovision 19. See rh#492359 */
+ if (memcmp (DDC->vendor.name, "PEA", 4) == 0 &&
+ DDC->vendor.prod_id == 9003)
+ return TRUE;
+
+ return FALSE;
+}
+
+static Bool quirk_detailed_sync_pp(int scrnIndex, xf86MonPtr DDC)
+{
+ /* Bug #12439: Samsung SyncMaster 205BW */
+ if (memcmp (DDC->vendor.name, "SAM", 4) == 0 &&
+ DDC->vendor.prod_id == 541)
+ return TRUE;
+ return FALSE;
+}
+
+/* This should probably be made more generic */
+static Bool quirk_dvi_single_link(int scrnIndex, xf86MonPtr DDC)
+{
+ /* Red Hat bug #453106: Apple 23" Cinema Display */
+ if (memcmp (DDC->vendor.name, "APL", 4) == 0 &&
+ DDC->vendor.prod_id == 0x921c)
+ return TRUE;
+ return FALSE;
+}
+
+typedef struct {
+ Bool (*detect) (int scrnIndex, xf86MonPtr DDC);
+ ddc_quirk_t quirk;
+ char *description;
+} ddc_quirk_map_t;
+
+static const ddc_quirk_map_t ddc_quirks[] = {
+ {
+ quirk_prefer_large_60, DDC_QUIRK_PREFER_LARGE_60,
+ "Detailed timing is not preferred, use largest mode at 60Hz"
+ },
+ {
+ quirk_135_clock_too_high, DDC_QUIRK_135_CLOCK_TOO_HIGH,
+ "Recommended 135MHz pixel clock is too high"
+ },
+ {
+ quirk_prefer_large_75, DDC_QUIRK_PREFER_LARGE_75,
+ "Detailed timing is not preferred, use largest mode at 75Hz"
+ },
+ {
+ quirk_detailed_h_in_cm, DDC_QUIRK_DETAILED_H_IN_CM,
+ "Detailed timings give horizontal size in cm."
+ },
+ {
+ quirk_detailed_v_in_cm, DDC_QUIRK_DETAILED_V_IN_CM,
+ "Detailed timings give vertical size in cm."
+ },
+ {
+ quirk_detailed_use_maximum_size, DDC_QUIRK_DETAILED_USE_MAXIMUM_SIZE,
+ "Use maximum size instead of detailed timing sizes."
+ },
+ {
+ quirk_first_detailed_preferred, DDC_QUIRK_FIRST_DETAILED_PREFERRED,
+ "First detailed timing was not marked as preferred."
+ },
+ {
+ quirk_detailed_sync_pp, DDC_QUIRK_DETAILED_SYNC_PP,
+ "Use +hsync +vsync for detailed timing."
+ },
+ {
+ quirk_dvi_single_link, DDC_QUIRK_DVI_SINGLE_LINK,
+ "Forcing maximum pixel clock to single DVI link."
+ },
+ {
+ NULL, DDC_QUIRK_NONE,
+ "No known quirks"
+ },
+};
+
+/*
+ * These more or less come from the DMT spec. The 720x400 modes are
+ * inferred from historical 80x25 practice. The 640x480@67 and 832x624@75
+ * modes are old-school Mac modes. The EDID spec says the 1152x864@75 mode
+ * should be 1152x870, again for the Mac, but instead we use the x864 DMT
+ * mode.
+ *
+ * The DMT modes have been fact-checked; the rest are mild guesses.
+ */
+#define MODEPREFIX NULL, NULL, NULL, 0, M_T_DRIVER
+#define MODESUFFIX 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,FALSE,FALSE,0,NULL,0,0.0,0.0
+
+static const DisplayModeRec DDCEstablishedModes[17] = {
+ { MODEPREFIX, 40000, 800, 840, 968, 1056, 0, 600, 601, 605, 628, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@60Hz */
+ { MODEPREFIX, 36000, 800, 824, 896, 1024, 0, 600, 601, 603, 625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@56Hz */
+ { MODEPREFIX, 31500, 640, 656, 720, 840, 0, 480, 481, 484, 500, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@75Hz */
+ { MODEPREFIX, 31500, 640, 664, 704, 832, 0, 480, 489, 492, 520, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@72Hz */
+ { MODEPREFIX, 30240, 640, 704, 768, 864, 0, 480, 483, 486, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@67Hz */
+ { MODEPREFIX, 25175, 640, 656, 752, 800, 0, 480, 490, 492, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@60Hz */
+ { MODEPREFIX, 35500, 720, 738, 846, 900, 0, 400, 421, 423, 449, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 720x400@88Hz */
+ { MODEPREFIX, 28320, 720, 738, 846, 900, 0, 400, 412, 414, 449, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 720x400@70Hz */
+ { MODEPREFIX, 135000, 1280, 1296, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x1024@75Hz */
+ { MODEPREFIX, 78750, 1024, 1040, 1136, 1312, 0, 768, 769, 772, 800, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1024x768@75Hz */
+ { MODEPREFIX, 75000, 1024, 1048, 1184, 1328, 0, 768, 771, 777, 806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768@70Hz */
+ { MODEPREFIX, 65000, 1024, 1048, 1184, 1344, 0, 768, 771, 777, 806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768@60Hz */
+ { MODEPREFIX, 44900, 1024, 1032, 1208, 1264, 0, 768, 768, 772, 817, 0, V_PHSYNC | V_PVSYNC | V_INTERLACE, MODESUFFIX }, /* 1024x768@43Hz */
+ { MODEPREFIX, 57284, 832, 864, 928, 1152, 0, 624, 625, 628, 667, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 832x624@75Hz */
+ { MODEPREFIX, 49500, 800, 816, 896, 1056, 0, 600, 601, 604, 625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@75Hz */
+ { MODEPREFIX, 50000, 800, 856, 976, 1040, 0, 600, 637, 643, 666, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@72Hz */
+ { MODEPREFIX, 108000, 1152, 1216, 1344, 1600, 0, 864, 865, 868, 900, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1152x864@75Hz */
+};
+
+static DisplayModePtr
+DDCModesFromEstablished(int scrnIndex, struct established_timings *timing,
+ ddc_quirk_t quirks)
+{
+ DisplayModePtr Modes = NULL, Mode = NULL;
+ CARD32 bits = (timing->t1) | (timing->t2 << 8) |
+ ((timing->t_manu & 0x80) << 9);
+ int i;
+
+ for (i = 0; i < 17; i++) {
+ if (bits & (0x01 << i)) {
+ Mode = xf86DuplicateMode(&DDCEstablishedModes[i]);
+ Modes = xf86ModesAdd(Modes, Mode);
+ }
+ }
+
+ return Modes;
+}
+
+/* Autogenerated from the DMT spec */
+const DisplayModeRec DMTModes[] = {
+ { MODEPREFIX, 31500, 640, 672, 736, 832, 0, 350, 382, 385, 445, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x350@85Hz */
+ { MODEPREFIX, 31500, 640, 672, 736, 832, 0, 400, 401, 404, 445, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 640x400@85Hz */
+ { MODEPREFIX, 35500, 720, 756, 828, 936, 0, 400, 401, 404, 446, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 720x400@85Hz */
+ { MODEPREFIX, 25175, 640, 656, 752, 800, 0, 480, 490, 492, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@60Hz */
+ { MODEPREFIX, 31500, 640, 664, 704, 832, 0, 480, 489, 492, 520, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@72Hz */
+ { MODEPREFIX, 31500, 640, 656, 720, 840, 0, 480, 481, 484, 500, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@75Hz */
+ { MODEPREFIX, 36000, 640, 696, 752, 832, 0, 480, 481, 484, 509, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 640x480@85Hz */
+ { MODEPREFIX, 36000, 800, 824, 896, 1024, 0, 600, 601, 603, 625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@56Hz */
+ { MODEPREFIX, 40000, 800, 840, 968, 1056, 0, 600, 601, 605, 628, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@60Hz */
+ { MODEPREFIX, 50000, 800, 856, 976, 1040, 0, 600, 637, 643, 666, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@72Hz */
+ { MODEPREFIX, 49500, 800, 816, 896, 1056, 0, 600, 601, 604, 625, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@75Hz */
+ { MODEPREFIX, 56250, 800, 832, 896, 1048, 0, 600, 601, 604, 631, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 800x600@85Hz */
+ { MODEPREFIX, 73250, 800, 848, 880, 960, 0, 600, 603, 607, 636, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 800x600@120Hz RB */
+ { MODEPREFIX, 33750, 848, 864, 976, 1088, 0, 480, 486, 494, 517, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 848x480@60Hz */
+ { MODEPREFIX, 44900, 1024, 1032, 1208, 1264, 0, 768, 768, 772, 817, 0, V_PHSYNC | V_PVSYNC | V_INTERLACE, MODESUFFIX }, /* 1024x768@43Hz (interlaced) */
+ { MODEPREFIX, 65000, 1024, 1048, 1184, 1344, 0, 768, 771, 777, 806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768@60Hz */
+ { MODEPREFIX, 75000, 1024, 1048, 1184, 1328, 0, 768, 771, 777, 806, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768@70Hz */
+ { MODEPREFIX, 78750, 1024, 1040, 1136, 1312, 0, 768, 769, 772, 800, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1024x768@75Hz */
+ { MODEPREFIX, 94500, 1024, 1072, 1168, 1376, 0, 768, 769, 772, 808, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1024x768@85Hz */
+ { MODEPREFIX, 115500, 1024, 1072, 1104, 1184, 0, 768, 771, 775, 813, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1024x768@120Hz RB */
+ { MODEPREFIX, 108000, 1152, 1216, 1344, 1600, 0, 864, 865, 868, 900, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1152x864@75Hz */
+ { MODEPREFIX, 68250, 1280, 1328, 1360, 1440, 0, 768, 771, 778, 790, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1280x768@60Hz RB */
+ { MODEPREFIX, 79500, 1280, 1344, 1472, 1664, 0, 768, 771, 778, 798, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x768@60Hz */
+ { MODEPREFIX, 102250, 1280, 1360, 1488, 1696, 0, 768, 771, 778, 805, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x768@75Hz */
+ { MODEPREFIX, 117500, 1280, 1360, 1496, 1712, 0, 768, 771, 778, 809, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x768@85Hz */
+ { MODEPREFIX, 140250, 1280, 1328, 1360, 1440, 0, 768, 771, 778, 813, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1280x768@120Hz RB */
+ { MODEPREFIX, 71000, 1280, 1328, 1360, 1440, 0, 800, 803, 809, 823, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1280x800@60Hz RB */
+ { MODEPREFIX, 83500, 1280, 1352, 1480, 1680, 0, 800, 803, 809, 831, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x800@60Hz */
+ { MODEPREFIX, 106500, 1280, 1360, 1488, 1696, 0, 800, 803, 809, 838, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x800@75Hz */
+ { MODEPREFIX, 122500, 1280, 1360, 1496, 1712, 0, 800, 803, 809, 843, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x800@85Hz */
+ { MODEPREFIX, 146250, 1280, 1328, 1360, 1440, 0, 800, 803, 809, 847, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1280x800@120Hz RB */
+ { MODEPREFIX, 108000, 1280, 1376, 1488, 1800, 0, 960, 961, 964, 1000, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x960@60Hz */
+ { MODEPREFIX, 148500, 1280, 1344, 1504, 1728, 0, 960, 961, 964, 1011, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x960@85Hz */
+ { MODEPREFIX, 175500, 1280, 1328, 1360, 1440, 0, 960, 963, 967, 1017, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1280x960@120Hz RB */
+ { MODEPREFIX, 108000, 1280, 1328, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x1024@60Hz */
+ { MODEPREFIX, 135000, 1280, 1296, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x1024@75Hz */
+ { MODEPREFIX, 157500, 1280, 1344, 1504, 1728, 0, 1024, 1025, 1028, 1072, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1280x1024@85Hz */
+ { MODEPREFIX, 187250, 1280, 1328, 1360, 1440, 0, 1024, 1027, 1034, 1084, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1280x1024@120Hz RB */
+ { MODEPREFIX, 85500, 1360, 1424, 1536, 1792, 0, 768, 771, 777, 795, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1360x768@60Hz */
+ { MODEPREFIX, 148250, 1360, 1408, 1440, 1520, 0, 768, 771, 776, 813, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1360x768@120Hz RB */
+ { MODEPREFIX, 101000, 1400, 1448, 1480, 1560, 0, 1050, 1053, 1057, 1080, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1400x1050@60Hz RB */
+ { MODEPREFIX, 121750, 1400, 1488, 1632, 1864, 0, 1050, 1053, 1057, 1089, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1400x1050@60Hz */
+ { MODEPREFIX, 156000, 1400, 1504, 1648, 1896, 0, 1050, 1053, 1057, 1099, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1400x1050@75Hz */
+ { MODEPREFIX, 179500, 1400, 1504, 1656, 1912, 0, 1050, 1053, 1057, 1105, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1400x1050@85Hz */
+ { MODEPREFIX, 208000, 1400, 1448, 1480, 1560, 0, 1050, 1053, 1057, 1112, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1400x1050@120Hz RB */
+ { MODEPREFIX, 88750, 1440, 1488, 1520, 1600, 0, 900, 903, 909, 926, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1440x900@60Hz RB */
+ { MODEPREFIX, 106500, 1440, 1520, 1672, 1904, 0, 900, 903, 909, 934, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1440x900@60Hz */
+ { MODEPREFIX, 136750, 1440, 1536, 1688, 1936, 0, 900, 903, 909, 942, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1440x900@75Hz */
+ { MODEPREFIX, 157000, 1440, 1544, 1696, 1952, 0, 900, 903, 909, 948, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1440x900@85Hz */
+ { MODEPREFIX, 182750, 1440, 1488, 1520, 1600, 0, 900, 903, 909, 953, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1440x900@120Hz RB */
+ { MODEPREFIX, 162000, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1600x1200@60Hz */
+ { MODEPREFIX, 175500, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1600x1200@65Hz */
+ { MODEPREFIX, 189000, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1600x1200@70Hz */
+ { MODEPREFIX, 202500, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1600x1200@75Hz */
+ { MODEPREFIX, 229500, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* 1600x1200@85Hz */
+ { MODEPREFIX, 268250, 1600, 1648, 1680, 1760, 0, 1200, 1203, 1207, 1271, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1600x1200@120Hz RB */
+ { MODEPREFIX, 119000, 1680, 1728, 1760, 1840, 0, 1050, 1053, 1059, 1080, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1680x1050@60Hz RB */
+ { MODEPREFIX, 146250, 1680, 1784, 1960, 2240, 0, 1050, 1053, 1059, 1089, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1680x1050@60Hz */
+ { MODEPREFIX, 187000, 1680, 1800, 1976, 2272, 0, 1050, 1053, 1059, 1099, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1680x1050@75Hz */
+ { MODEPREFIX, 214750, 1680, 1808, 1984, 2288, 0, 1050, 1053, 1059, 1105, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1680x1050@85Hz */
+ { MODEPREFIX, 245500, 1680, 1728, 1760, 1840, 0, 1050, 1053, 1059, 1112, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1680x1050@120Hz RB */
+ { MODEPREFIX, 204750, 1792, 1920, 2120, 2448, 0, 1344, 1345, 1348, 1394, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1792x1344@60Hz */
+ { MODEPREFIX, 261000, 1792, 1888, 2104, 2456, 0, 1344, 1345, 1348, 1417, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1792x1344@75Hz */
+ { MODEPREFIX, 333250, 1792, 1840, 1872, 1952, 0, 1344, 1347, 1351, 1423, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1792x1344@120Hz RB */
+ { MODEPREFIX, 218250, 1856, 1952, 2176, 2528, 0, 1392, 1393, 1396, 1439, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1856x1392@60Hz */
+ { MODEPREFIX, 288000, 1856, 1984, 2208, 2560, 0, 1392, 1393, 1396, 1500, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1856x1392@75Hz */
+ { MODEPREFIX, 356500, 1856, 1904, 1936, 2016, 0, 1392, 1395, 1399, 1474, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1856x1392@120Hz RB */
+ { MODEPREFIX, 154000, 1920, 1968, 2000, 2080, 0, 1200, 1203, 1209, 1235, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1920x1200@60Hz RB */
+ { MODEPREFIX, 193250, 1920, 2056, 2256, 2592, 0, 1200, 1203, 1209, 1245, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1920x1200@60Hz */
+ { MODEPREFIX, 245250, 1920, 2056, 2264, 2608, 0, 1200, 1203, 1209, 1255, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1920x1200@75Hz */
+ { MODEPREFIX, 281250, 1920, 2064, 2272, 2624, 0, 1200, 1203, 1209, 1262, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1920x1200@85Hz */
+ { MODEPREFIX, 317000, 1920, 1968, 2000, 2080, 0, 1200, 1203, 1209, 1271, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1920x1200@120Hz RB */
+ { MODEPREFIX, 234000, 1920, 2048, 2256, 2600, 0, 1440, 1441, 1444, 1500, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1920x1440@60Hz */
+ { MODEPREFIX, 297000, 1920, 2064, 2288, 2640, 0, 1440, 1441, 1444, 1500, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 1920x1440@75Hz */
+ { MODEPREFIX, 380500, 1920, 1968, 2000, 2080, 0, 1440, 1443, 1447, 1525, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 1920x1440@120Hz RB */
+ { MODEPREFIX, 268500, 2560, 2608, 2640, 2720, 0, 1600, 1603, 1609, 1646, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 2560x1600@60Hz RB */
+ { MODEPREFIX, 348500, 2560, 2752, 3032, 3504, 0, 1600, 1603, 1609, 1658, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 2560x1600@60Hz */
+ { MODEPREFIX, 443250, 2560, 2768, 3048, 3536, 0, 1600, 1603, 1609, 1672, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 2560x1600@75Hz */
+ { MODEPREFIX, 505250, 2560, 2768, 3048, 3536, 0, 1600, 1603, 1609, 1682, 0, V_NHSYNC | V_PVSYNC, MODESUFFIX }, /* 2560x1600@85Hz */
+ { MODEPREFIX, 552750, 2560, 2608, 2640, 2720, 0, 1600, 1603, 1609, 1694, 0, V_PHSYNC | V_NVSYNC, MODESUFFIX }, /* 2560x1600@120Hz RB */
+};
+
+#define LEVEL_DMT 0
+#define LEVEL_GTF 1
+#define LEVEL_CVT 2
+
+static int
+MonitorStandardTimingLevel(xf86MonPtr DDC)
+{
+ if (DDC->ver.revision >= 2) {
+ if (DDC->ver.revision >= 4 && CVT_SUPPORTED(DDC->features.msc)) {
+ return LEVEL_CVT;
+ }
+ return LEVEL_GTF;
+ }
+ return LEVEL_DMT;
+}
+
+static int
+ModeRefresh(const DisplayModeRec *mode)
+{
+ return (int)(xf86ModeVRefresh(mode) + 0.5);
+}
+
+/*
+ * If rb is not set, then we'll not consider reduced-blanking modes as
+ * part of the DMT pool. For the 'standard' EDID mode descriptor there's
+ * no way to specify whether the mode should be RB or not.
+ */
+DisplayModePtr
+FindDMTMode(int hsize, int vsize, int refresh, Bool rb)
+{
+ int i;
+ const DisplayModeRec *ret;
+
+ for (i = 0; i < sizeof(DMTModes) / sizeof(DisplayModeRec); i++) {
+ ret = &DMTModes[i];
+
+ if (!rb && xf86ModeIsReduced(ret))
+ continue;
+
+ if (ret->HDisplay == hsize &&
+ ret->VDisplay == vsize &&
+ refresh == ModeRefresh(ret))
+ return xf86DuplicateMode(ret);
+ }
+
+ return NULL;
+}
+
+/*
+ * Appendix B of the EDID 1.4 spec defines the right thing to do here.
+ * If the timing given here matches a mode defined in the VESA DMT standard,
+ * we _must_ use that. If the device supports CVT modes, then we should
+ * generate a CVT timing. If both of the above fail, use GTF.
+ *
+ * There are some wrinkles here. EDID 1.1 and 1.0 sinks can't really
+ * "support" GTF, since it wasn't a standard yet; so if they ask for a
+ * timing in this section that isn't defined in DMT, returning a GTF mode
+ * may not actually be valid. EDID 1.3 sinks often report support for
+ * some CVT modes, but they are not required to support CVT timings for
+ * modes in the standard timing descriptor, so we should _not_ treat them
+ * as CVT-compliant (unless specified in an extension block I suppose).
+ *
+ * EDID 1.4 requires that all sink devices support both GTF and CVT timings
+ * for modes in this section, but does say that CVT is preferred.
+ */
+static DisplayModePtr
+DDCModesFromStandardTiming(struct std_timings *timing, ddc_quirk_t quirks,
+ int timing_level, Bool rb)
+{
+ DisplayModePtr Modes = NULL, Mode = NULL;
+ int i, hsize, vsize, refresh;
+
+ for (i = 0; i < STD_TIMINGS; i++) {
+ hsize = timing[i].hsize;
+ vsize = timing[i].vsize;
+ refresh = timing[i].refresh;
+
+ /* HDTV hack, because you can't say 1366 */
+ if (refresh == 60 &&
+ ((hsize == 1360 && vsize == 765) ||
+ (hsize == 1368 && vsize == 769))) {
+ Mode = xf86CVTMode(1366, 768, 60, FALSE, FALSE);
+ Mode->HDisplay = 1366;
+ Mode->VSyncStart--;
+ Mode->VSyncEnd--;
+ } else if (hsize && vsize && refresh) {
+ Mode = FindDMTMode(hsize, vsize, refresh, rb);
+
+ if (!Mode) {
+ if (timing_level == LEVEL_CVT)
+ /* pass rb here too? */
+ Mode = xf86CVTMode(hsize, vsize, refresh, FALSE, FALSE);
+ else if (timing_level == LEVEL_GTF)
+ Mode = xf86GTFMode(hsize, vsize, refresh, FALSE, FALSE);
+ }
+
+ }
+
+ if (Mode) {
+ Mode->type = M_T_DRIVER;
+ Modes = xf86ModesAdd(Modes, Mode);
+ }
+ Mode = NULL;
+ }
+
+ return Modes;
+}
+
+static void
+DDCModeDoInterlaceQuirks(DisplayModePtr mode)
+{
+ /*
+ * EDID is delightfully ambiguous about how interlaced modes are to be
+ * encoded. X's internal representation is of frame height, but some
+ * HDTV detailed timings are encoded as field height.
+ *
+ * The format list here is from CEA, in frame size. Technically we
+ * should be checking refresh rate too. Whatever.
+ */
+ static const struct {
+ int w, h;
+ } cea_interlaced[] = {
+ { 1920, 1080 },
+ { 720, 480 },
+ { 1440, 480 },
+ { 2880, 480 },
+ { 720, 576 },
+ { 1440, 576 },
+ { 2880, 576 },
+ };
+ static const int n_modes = sizeof(cea_interlaced)/sizeof(cea_interlaced[0]);
+ int i;
+
+ for (i = 0; i < n_modes; i++) {
+ if ((mode->HDisplay == cea_interlaced[i].w) &&
+ (mode->VDisplay == cea_interlaced[i].h / 2)) {
+ mode->VDisplay *= 2;
+ mode->VSyncStart *= 2;
+ mode->VSyncEnd *= 2;
+ mode->VTotal *= 2;
+ mode->VTotal |= 1;
+ }
+ }
+
+ mode->Flags |= V_INTERLACE;
+}
+
+/*
+ *
+ */
+static DisplayModePtr
+DDCModeFromDetailedTiming(int scrnIndex, struct detailed_timings *timing,
+ Bool preferred, ddc_quirk_t quirks)
+{
+ DisplayModePtr Mode;
+
+ /*
+ * Refuse to create modes that are insufficiently large. 64 is a random
+ * number, maybe the spec says something about what the minimum is. In
+ * particular I see this frequently with _old_ EDID, 1.0 or so, so maybe
+ * our parser is just being too aggresive there.
+ */
+ if (timing->h_active < 64 || timing->v_active < 64) {
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "%s: Ignoring tiny %dx%d mode\n", __func__,
+ timing->h_active, timing->v_active);
+ return NULL;
+ }
+
+ /* We don't do stereo */
+ if (timing->stereo) {
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "%s: Ignoring: We don't handle stereo.\n", __func__);
+ return NULL;
+ }
+
+ /* We only do seperate sync currently */
+ if (timing->sync != 0x03) {
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "%s: %dx%d Warning: We only handle separate"
+ " sync.\n", __func__, timing->h_active, timing->v_active);
+ }
+
+ Mode = xnfcalloc(1, sizeof(DisplayModeRec));
+
+ Mode->type = M_T_DRIVER;
+ if (preferred)
+ Mode->type |= M_T_PREFERRED;
+
+ if( ( quirks & DDC_QUIRK_135_CLOCK_TOO_HIGH ) &&
+ timing->clock == 135000000 )
+ Mode->Clock = 108880;
+ else
+ Mode->Clock = timing->clock / 1000.0;
+
+ Mode->HDisplay = timing->h_active;
+ Mode->HSyncStart = timing->h_active + timing->h_sync_off;
+ Mode->HSyncEnd = Mode->HSyncStart + timing->h_sync_width;
+ Mode->HTotal = timing->h_active + timing->h_blanking;
+
+ Mode->VDisplay = timing->v_active;
+ Mode->VSyncStart = timing->v_active + timing->v_sync_off;
+ Mode->VSyncEnd = Mode->VSyncStart + timing->v_sync_width;
+ Mode->VTotal = timing->v_active + timing->v_blanking;
+
+ /* perform basic check on the detail timing */
+ if (Mode->HSyncEnd > Mode->HTotal || Mode->VSyncEnd > Mode->VTotal) {
+ free(Mode);
+ return NULL;
+ }
+
+ /* We ignore h/v_size and h/v_border for now. */
+
+ if (timing->interlaced)
+ DDCModeDoInterlaceQuirks(Mode);
+
+ if (quirks & DDC_QUIRK_DETAILED_SYNC_PP)
+ Mode->Flags |= V_PVSYNC | V_PHSYNC;
+ else {
+ if (timing->misc & 0x02)
+ Mode->Flags |= V_PVSYNC;
+ else
+ Mode->Flags |= V_NVSYNC;
+
+ if (timing->misc & 0x01)
+ Mode->Flags |= V_PHSYNC;
+ else
+ Mode->Flags |= V_NHSYNC;
+ }
+
+ xf86SetModeDefaultName(Mode);
+
+ return Mode;
+}
+
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
+static DisplayModePtr
+DDCModesFromCVT(int scrnIndex, struct cvt_timings *t)
+{
+ DisplayModePtr modes = NULL;
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ if (t[i].height) {
+ if (t[i].rates & 0x10)
+ modes = xf86ModesAdd(modes,
+ xf86CVTMode(t[i].width, t[i].height, 50, 0, 0));
+ if (t[i].rates & 0x08)
+ modes = xf86ModesAdd(modes,
+ xf86CVTMode(t[i].width, t[i].height, 60, 0, 0));
+ if (t[i].rates & 0x04)
+ modes = xf86ModesAdd(modes,
+ xf86CVTMode(t[i].width, t[i].height, 75, 0, 0));
+ if (t[i].rates & 0x02)
+ modes = xf86ModesAdd(modes,
+ xf86CVTMode(t[i].width, t[i].height, 85, 0, 0));
+ if (t[i].rates & 0x01)
+ modes = xf86ModesAdd(modes,
+ xf86CVTMode(t[i].width, t[i].height, 60, 1, 0));
+ } else break;
+ }
+
+ return modes;
+}
+#endif
+
+static const struct {
+ short w;
+ short h;
+ short r;
+ short rb;
+} EstIIIModes[] = {
+ /* byte 6 */
+ { 640, 350, 85, 0 },
+ { 640, 400, 85, 0 },
+ { 720, 400, 85, 0 },
+ { 640, 480, 85, 0 },
+ { 848, 480, 60, 0 },
+ { 800, 600, 85, 0 },
+ { 1024, 768, 85, 0 },
+ { 1152, 864, 75, 0 },
+ /* byte 7 */
+ { 1280, 768, 60, 1 },
+ { 1280, 768, 60, 0 },
+ { 1280, 768, 75, 0 },
+ { 1280, 768, 85, 0 },
+ { 1280, 960, 60, 0 },
+ { 1280, 960, 85, 0 },
+ { 1280, 1024, 60, 0 },
+ { 1280, 1024, 85, 0 },
+ /* byte 8 */
+ { 1360, 768, 60, 0 },
+ { 1440, 900, 60, 1 },
+ { 1440, 900, 60, 0 },
+ { 1440, 900, 75, 0 },
+ { 1440, 900, 85, 0 },
+ { 1400, 1050, 60, 1 },
+ { 1400, 1050, 60, 0 },
+ { 1400, 1050, 75, 0 },
+ /* byte 9 */
+ { 1400, 1050, 85, 0 },
+ { 1680, 1050, 60, 1 },
+ { 1680, 1050, 60, 0 },
+ { 1680, 1050, 75, 0 },
+ { 1680, 1050, 85, 0 },
+ { 1600, 1200, 60, 0 },
+ { 1600, 1200, 65, 0 },
+ { 1600, 1200, 70, 0 },
+ /* byte 10 */
+ { 1600, 1200, 75, 0 },
+ { 1600, 1200, 85, 0 },
+ { 1792, 1344, 60, 0 },
+ { 1792, 1344, 85, 0 },
+ { 1856, 1392, 60, 0 },
+ { 1856, 1392, 75, 0 },
+ { 1920, 1200, 60, 1 },
+ { 1920, 1200, 60, 0 },
+ /* byte 11 */
+ { 1920, 1200, 75, 0 },
+ { 1920, 1200, 85, 0 },
+ { 1920, 1440, 60, 0 },
+ { 1920, 1440, 75, 0 },
+};
+
+static DisplayModePtr
+DDCModesFromEstIII(unsigned char *est)
+{
+ DisplayModePtr modes = NULL;
+ int i, j, m;
+
+ for (i = 0; i < 6; i++) {
+ for (j = 7; j > 0; j--) {
+ if (est[i] & (1 << j)) {
+ m = (i * 8) + (7 - j);
+ modes = xf86ModesAdd(modes,
+ FindDMTMode(EstIIIModes[m].w,
+ EstIIIModes[m].h,
+ EstIIIModes[m].r,
+ EstIIIModes[m].rb));
+ }
+ }
+ }
+
+ return modes;
+}
+
+/*
+ * This is only valid when the sink claims to be continuous-frequency
+ * but does not supply a detailed range descriptor. Such sinks are
+ * arguably broken. Currently the mode validation code isn't aware of
+ * this; the non-RANDR code even punts the decision of optional sync
+ * range checking to the driver. Loss.
+ */
+static void
+DDCGuessRangesFromModes(int scrnIndex, MonPtr Monitor, DisplayModePtr Modes)
+{
+ DisplayModePtr Mode = Modes;
+
+ if (!Monitor || !Modes)
+ return;
+
+ /* set up the ranges for scanning through the modes */
+ Monitor->nHsync = 1;
+ Monitor->hsync[0].lo = 1024.0;
+ Monitor->hsync[0].hi = 0.0;
+
+ Monitor->nVrefresh = 1;
+ Monitor->vrefresh[0].lo = 1024.0;
+ Monitor->vrefresh[0].hi = 0.0;
+
+ while (Mode) {
+ if (!Mode->HSync)
+ Mode->HSync = ((float) Mode->Clock ) / ((float) Mode->HTotal);
+
+ if (!Mode->VRefresh)
+ Mode->VRefresh = (1000.0 * ((float) Mode->Clock)) /
+ ((float) (Mode->HTotal * Mode->VTotal));
+
+ if (Mode->HSync < Monitor->hsync[0].lo)
+ Monitor->hsync[0].lo = Mode->HSync;
+
+ if (Mode->HSync > Monitor->hsync[0].hi)
+ Monitor->hsync[0].hi = Mode->HSync;
+
+ if (Mode->VRefresh < Monitor->vrefresh[0].lo)
+ Monitor->vrefresh[0].lo = Mode->VRefresh;
+
+ if (Mode->VRefresh > Monitor->vrefresh[0].hi)
+ Monitor->vrefresh[0].hi = Mode->VRefresh;
+
+ Mode = Mode->next;
+ }
+}
+
+ddc_quirk_t
+xf86DDCDetectQuirks(int scrnIndex, xf86MonPtr DDC, Bool verbose)
+{
+ ddc_quirk_t quirks;
+ int i;
+
+ quirks = DDC_QUIRK_NONE;
+ for (i = 0; ddc_quirks[i].detect; i++) {
+ if (ddc_quirks[i].detect (scrnIndex, DDC)) {
+ if (verbose) {
+ xf86DrvMsg (scrnIndex, X_INFO, " EDID quirk: %s\n",
+ ddc_quirks[i].description);
+ }
+ quirks |= ddc_quirks[i].quirk;
+ }
+ }
+
+ return quirks;
+}
+
+void xf86DetTimingApplyQuirks(struct detailed_monitor_section *det_mon,
+ ddc_quirk_t quirks,
+ int hsize, int vsize)
+{
+ if (det_mon->type != DT)
+ return;
+
+ if (quirks & DDC_QUIRK_DETAILED_H_IN_CM)
+ det_mon->section.d_timings.h_size *= 10;
+
+ if (quirks & DDC_QUIRK_DETAILED_V_IN_CM)
+ det_mon->section.d_timings.v_size *= 10;
+
+ if (quirks & DDC_QUIRK_DETAILED_USE_MAXIMUM_SIZE) {
+ det_mon->section.d_timings.h_size = 10 * hsize;
+ det_mon->section.d_timings.v_size = 10 * vsize;
+ }
+}
+
+/**
+ * Applies monitor-specific quirks to the decoded EDID information.
+ *
+ * Note that some quirks applying to the mode list are still implemented in
+ * xf86DDCGetModes.
+ */
+void
+xf86DDCApplyQuirks(int scrnIndex, xf86MonPtr DDC)
+{
+ ddc_quirk_t quirks = xf86DDCDetectQuirks (scrnIndex, DDC, FALSE);
+ int i;
+
+ for (i = 0; i < DET_TIMINGS; i++) {
+ xf86DetTimingApplyQuirks(DDC->det_mon + i, quirks,
+ DDC->features.hsize,
+ DDC->features.vsize);
+ }
+}
+
+/**
+ * Walks the modes list, finding the mode with the largest area which is
+ * closest to the target refresh rate, and marks it as the only preferred mode.
+*/
+static void
+xf86DDCSetPreferredRefresh(int scrnIndex, DisplayModePtr modes,
+ float target_refresh)
+{
+ DisplayModePtr mode, best = modes;
+
+ for (mode = modes; mode; mode = mode->next)
+ {
+ mode->type &= ~M_T_PREFERRED;
+
+ if (mode == best) continue;
+
+ if (mode->HDisplay * mode->VDisplay >
+ best->HDisplay * best->VDisplay)
+ {
+ best = mode;
+ continue;
+ }
+ if (mode->HDisplay * mode->VDisplay ==
+ best->HDisplay * best->VDisplay)
+ {
+ double mode_refresh = xf86ModeVRefresh (mode);
+ double best_refresh = xf86ModeVRefresh (best);
+ double mode_dist = fabs(mode_refresh - target_refresh);
+ double best_dist = fabs(best_refresh - target_refresh);
+
+ if (mode_dist < best_dist)
+ {
+ best = mode;
+ continue;
+ }
+ }
+ }
+ if (best)
+ best->type |= M_T_PREFERRED;
+}
+
+#define CEA_VIDEO_MODES_NUM 64
+static const DisplayModeRec CEAVideoModes[CEA_VIDEO_MODES_NUM] = {
+ { MODEPREFIX, 25175, 640, 656, 752, 800, 0, 480, 490, 492, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 1:640x480@60Hz */
+ { MODEPREFIX, 27000, 720, 736, 798, 858, 0, 480, 489, 495, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 2:720x480@60Hz */
+ { MODEPREFIX, 27000, 720, 736, 798, 858, 0, 480, 489, 495, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 3:720x480@60Hz */
+ { MODEPREFIX, 74250, 1280, 1390, 1430, 1650, 0, 720, 725, 730, 750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 4: 1280x720@60Hz */
+ { MODEPREFIX, 74250, 1920, 2008, 2052, 2200, 0, 1080, 1084, 1094, 1125, 0, V_PHSYNC | V_PVSYNC | V_INTERLACE, MODESUFFIX }, /* VIC 5:1920x1080i@60Hz */
+ { MODEPREFIX, 27000, 1440, 1478, 1602, 1716, 0, 480, 488, 494, 525, 0, V_NHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX }, /* VIC 6:1440x480i@60Hz */
+ { MODEPREFIX, 27000, 1440, 1478, 1602, 1716, 0, 480, 488, 494, 525, 0, V_NHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX }, /* VIC 7:1440x480i@60Hz */
+ { MODEPREFIX, 27000, 1440, 1478, 1602, 1716, 0, 240, 244, 247, 262, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 8:1440x240@60Hz */
+ { MODEPREFIX, 27000, 1440, 1478, 1602, 1716, 0, 240, 244, 247, 262, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 9:1440x240@60Hz */
+ { MODEPREFIX, 54000, 2880, 2956, 3204, 3432, 0, 480, 488, 494, 525, 0, V_NHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX }, /* VIC 10:2880x480i@60Hz */
+ { MODEPREFIX, 54000, 2880, 2956, 3204, 3432, 0, 480, 488, 494, 525, 0, V_NHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX }, /* VIC 11:2880x480i@60Hz */
+ { MODEPREFIX, 54000, 2880, 2956, 3204, 3432, 0, 240, 244, 247, 262, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 12:2880x240@60Hz */
+ { MODEPREFIX, 54000, 2880, 2956, 3204, 3432, 0, 240, 244, 247, 262, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 13:2880x240@60Hz */
+ { MODEPREFIX, 54000, 1440, 1472, 1596, 1716, 0, 480, 489, 495, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 14:1440x480@60Hz */
+ { MODEPREFIX, 54000, 1440, 1472, 1596, 1716, 0, 480, 489, 495, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 15:1440x480@60Hz */
+ { MODEPREFIX, 148500, 1920, 2008, 2052, 2200, 0, 1080, 1084, 1089, 1125, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 16:1920x1080@60Hz */
+ { MODEPREFIX, 27000, 720, 732, 796, 864, 0, 576, 581, 586, 625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 17:720x576@50Hz */
+ { MODEPREFIX, 27000, 720, 732, 796, 864, 0, 576, 581, 586, 625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 18:720x576@50Hz */
+ { MODEPREFIX, 74250, 1280, 1720, 1760, 1980, 0, 720, 725, 730, 750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 19: 1280x720@50Hz */
+ { MODEPREFIX, 74250, 1920, 2448, 2492, 2640, 0, 1080, 1084, 1094, 1125, 0, V_PHSYNC | V_PVSYNC | V_INTERLACE, MODESUFFIX }, /* VIC 20:1920x1080i@50Hz */
+ { MODEPREFIX, 27000, 1440, 1464, 1590, 1728, 0, 576, 580, 586, 625, 0, V_NHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX }, /* VIC 21:1440x576i@50Hz */
+ { MODEPREFIX, 27000, 1440, 1464, 1590, 1728, 0, 576, 580, 586, 625, 0, V_NHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX }, /* VIC 22:1440x576i@50Hz */
+ { MODEPREFIX, 27000, 1440, 1464, 1590, 1728, 0, 288, 290, 293, 312, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 23:1440x288@50Hz */
+ { MODEPREFIX, 27000, 1440, 1464, 1590, 1728, 0, 288, 290, 293, 312, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 24:1440x288@50Hz */
+ { MODEPREFIX, 54000, 2880, 2928, 3180, 3456, 0, 576, 580, 586, 625, 0, V_NHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX }, /* VIC 25:2880x576i@50Hz */
+ { MODEPREFIX, 54000, 2880, 2928, 3180, 3456, 0, 576, 580, 586, 625, 0, V_NHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX }, /* VIC 26:2880x576i@50Hz */
+ { MODEPREFIX, 54000, 2880, 2928, 3180, 3456, 0, 288, 290, 293, 312, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 27:2880x288@50Hz */
+ { MODEPREFIX, 54000, 2880, 2928, 3180, 3456, 0, 288, 290, 293, 312, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 28:2880x288@50Hz */
+ { MODEPREFIX, 54000, 1440, 1464, 1592, 1728, 0, 576, 581, 586, 625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 29:1440x576@50Hz */
+ { MODEPREFIX, 54000, 1440, 1464, 1592, 1728, 0, 576, 581, 586, 625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 30:1440x576@50Hz */
+ { MODEPREFIX, 148500, 1920, 2448, 2492, 2640, 0, 1080, 1084, 1089, 1125, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 31:1920x1080@50Hz */
+ { MODEPREFIX, 74250, 1920, 2558, 2602, 2750, 0, 1080, 1084, 1089, 1125, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 32:1920x1080@24Hz */
+ { MODEPREFIX, 74250, 1920, 2448, 2492, 2640, 0, 1080, 1084, 1089, 1125, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 33:1920x1080@25Hz */
+ { MODEPREFIX, 74250, 1920, 2008, 2052, 2200, 0, 1080, 1084, 1089, 1125, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 34:1920x1080@30Hz */
+ { MODEPREFIX, 108000, 2880, 2944, 3192, 3432, 0, 480, 489, 495, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 35:2880x480@60Hz */
+ { MODEPREFIX, 108000, 2880, 2944, 3192, 3432, 0, 480, 489, 495, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 36:2880x480@60Hz */
+ { MODEPREFIX, 108000, 2880, 2928, 3184, 3456, 0, 576, 581, 586, 625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 37:2880x576@50Hz */
+ { MODEPREFIX, 108000, 2880, 2928, 3184, 3456, 0, 576, 581, 586, 625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 38:2880x576@50Hz */
+ { MODEPREFIX, 72000, 1920, 1952, 2120, 2304, 0, 1080, 1126, 1136, 1250, 0, V_PHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX }, /* VIC 39:1920x1080i@50Hz */
+ { MODEPREFIX, 148500, 1920, 2448, 2492, 2640, 0, 1080, 1084, 1094, 1125, 0, V_PHSYNC | V_PVSYNC | V_INTERLACE, MODESUFFIX }, /* VIC 40:1920x1080i@100Hz */
+ { MODEPREFIX, 148500, 1280, 1720, 1760, 1980, 0, 720, 725, 730, 750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 41:1280x720@100Hz */
+ { MODEPREFIX, 54000, 720, 732, 796, 864, 0, 576, 581, 586, 625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 42:720x576@100Hz */
+ { MODEPREFIX, 54000, 720, 732, 796, 864, 0, 576, 581, 586, 625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 43:720x576@100Hz */
+ { MODEPREFIX, 54000, 1440, 1464, 1590, 1728, 0, 576, 580, 586, 625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 44:1440x576i@100Hz */
+ { MODEPREFIX, 54000, 1440, 1464, 1590, 1728, 0, 576, 580, 586, 625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 45:1440x576i@100Hz */
+ { MODEPREFIX, 148500, 1920, 2008, 2052, 2200, 0, 1080, 1084, 1094, 1125, 0, V_PHSYNC | V_PVSYNC | V_INTERLACE, MODESUFFIX }, /* VIC 46:1920x1080i@120Hz */
+ { MODEPREFIX, 148500, 1280, 1390, 1430, 1650, 0, 720, 725, 730, 750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 47:1280x720@120Hz */
+ { MODEPREFIX, 54000, 720, 736, 798, 858, 0, 480, 489, 495, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 48:720x480@120Hz */
+ { MODEPREFIX, 54000, 720, 736, 798, 858, 0, 480, 489, 495, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 49:720x480@120Hz */
+ { MODEPREFIX, 54000, 1440, 1478, 1602, 1716, 0, 480, 488, 494, 525, 0, V_NHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX },/* VIC 50:1440x480i@120Hz */
+ { MODEPREFIX, 54000, 1440, 1478, 1602, 1716, 0, 480, 488, 494, 525, 0, V_NHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX },/* VIC 51:1440x480i@120Hz */
+ { MODEPREFIX, 108000, 720, 732, 796, 864, 0, 576, 581, 586, 625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 52:720x576@200Hz */
+ { MODEPREFIX, 108000, 720, 732, 796, 864, 0, 576, 581, 586, 625, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 53:720x576@200Hz */
+ { MODEPREFIX, 108000, 1440, 1464, 1590, 1728, 0, 576, 580, 586, 625, 0, V_NHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX },/* VIC 54:1440x576i@200Hz */
+ { MODEPREFIX, 108000, 1440, 1464, 1590, 1728, 0, 576, 580, 586, 625, 0, V_NHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX },/* VIC 55:1440x576i@200Hz */
+ { MODEPREFIX, 108000, 720, 736, 798, 858, 0, 480, 489, 495, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 56:720x480@240Hz */
+ { MODEPREFIX, 108000, 720, 736, 798, 858, 0, 480, 489, 495, 525, 0, V_NHSYNC | V_NVSYNC, MODESUFFIX }, /* VIC 57:720x480@240Hz */
+ { MODEPREFIX, 108000, 1440, 1478, 1602, 1716, 0, 480, 488, 494, 525, 0, V_NHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX },/* VIC 58:1440x480i@240 */
+ { MODEPREFIX, 108000, 1440, 1478, 1602, 1716, 0, 480, 488, 494, 525, 0, V_NHSYNC | V_NVSYNC | V_INTERLACE, MODESUFFIX },/* VIC 59:1440x480i@240 */
+ { MODEPREFIX, 59400, 1280, 3040, 3080, 3300, 0, 720, 725, 730, 750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 60: 1280x720@24Hz */
+ { MODEPREFIX, 74250, 3700, 3740, 1430, 3960, 0, 720, 725, 730, 750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 61: 1280x720@25Hz */
+ { MODEPREFIX, 74250, 1280, 3040, 3080, 3300, 0, 720, 725, 730, 750, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 62: 1280x720@30Hz */
+ { MODEPREFIX, 297000, 1920, 2008, 2052, 2200, 0, 1080, 1084, 1089, 1125, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 63: 1920x1080@120Hz */
+ { MODEPREFIX, 297000, 1920, 2448, 2492, 2640, 0, 1080, 1084, 1094, 1125, 0, V_PHSYNC | V_PVSYNC, MODESUFFIX }, /* VIC 64:1920x1080@100Hz */
+};
+
+/* chose mode line by cea short video descriptor*/
+static void handle_cea_svd(struct cea_video_block *video, void *data)
+{
+ DisplayModePtr Mode;
+ DisplayModePtr *Modes = (DisplayModePtr *) data;
+ int vid;
+
+ vid = video ->video_code & 0x7f;
+ if (vid < CEA_VIDEO_MODES_NUM) {
+ Mode = xf86DuplicateMode(CEAVideoModes + vid);
+ *Modes = xf86ModesAdd(*Modes, Mode);
+ }
+}
+
+static DisplayModePtr
+DDCModesFromCEAExtension(int scrnIndex, xf86MonPtr MonPtr)
+{
+ DisplayModePtr Modes = NULL;
+
+ xf86ForEachVideoBlock(MonPtr,
+ handle_cea_svd,
+ &Modes);
+
+ return Modes;
+}
+
+struct det_modes_parameter {
+ xf86MonPtr DDC;
+ ddc_quirk_t quirks;
+ DisplayModePtr Modes;
+ Bool rb;
+ Bool preferred;
+ int timing_level;
+};
+
+static void handle_detailed_modes(struct detailed_monitor_section *det_mon,
+ void *data)
+{
+ DisplayModePtr Mode;
+ struct det_modes_parameter *p = (struct det_modes_parameter *)data;
+
+ xf86DetTimingApplyQuirks(det_mon,p->quirks,
+ p->DDC->features.hsize,
+ p->DDC->features.vsize);
+
+ switch (det_mon->type) {
+ case DT:
+ Mode = DDCModeFromDetailedTiming(p->DDC->scrnIndex,
+ &det_mon->section.d_timings,
+ p->preferred,
+ p->quirks);
+ p->preferred = FALSE;
+ p->Modes = xf86ModesAdd(p->Modes, Mode);
+ break;
+ case DS_STD_TIMINGS:
+ Mode = DDCModesFromStandardTiming(det_mon->section.std_t,
+ p->quirks, p->timing_level,p->rb);
+ p->Modes = xf86ModesAdd(p->Modes, Mode);
+ break;
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
+ case DS_CVT:
+ Mode = DDCModesFromCVT(p->DDC->scrnIndex, det_mon->section.cvt);
+ p->Modes = xf86ModesAdd(p->Modes, Mode);
+ break;
+#endif
+ case DS_EST_III:
+ Mode = DDCModesFromEstIII(det_mon->section.est_iii);
+ p->Modes = xf86ModesAdd(p->Modes, Mode);
+ break;
+ default:
+ break;
+ }
+}
+
+DisplayModePtr
+xf86DDCGetModes(int scrnIndex, xf86MonPtr DDC)
+{
+ DisplayModePtr Modes = NULL, Mode;
+ ddc_quirk_t quirks;
+ Bool preferred, rb;
+ int timing_level;
+ struct det_modes_parameter p;
+
+ xf86DrvMsg (scrnIndex, X_INFO, "EDID vendor \"%s\", prod id %d\n",
+ DDC->vendor.name, DDC->vendor.prod_id);
+
+ quirks = xf86DDCDetectQuirks(scrnIndex, DDC, TRUE);
+
+ preferred = PREFERRED_TIMING_MODE(DDC->features.msc);
+ if (DDC->ver.revision >= 4)
+ preferred = TRUE;
+ if (quirks & DDC_QUIRK_FIRST_DETAILED_PREFERRED)
+ preferred = TRUE;
+ if (quirks & (DDC_QUIRK_PREFER_LARGE_60 | DDC_QUIRK_PREFER_LARGE_75))
+ preferred = FALSE;
+
+ rb = xf86MonitorSupportsReducedBlanking(DDC);
+
+ timing_level = MonitorStandardTimingLevel(DDC);
+
+ p.quirks = quirks;
+ p.DDC = DDC;
+ p.Modes = Modes;
+ p.rb = rb;
+ p.preferred = preferred;
+ p.timing_level = timing_level;
+ xf86ForEachDetailedBlock(DDC, handle_detailed_modes, &p);
+ Modes = p.Modes;
+
+ /* Add established timings */
+ Mode = DDCModesFromEstablished(scrnIndex, &DDC->timings1, quirks);
+ Modes = xf86ModesAdd(Modes, Mode);
+
+ /* Add standard timings */
+ Mode = DDCModesFromStandardTiming(DDC->timings2, quirks, timing_level, rb);
+ Modes = xf86ModesAdd(Modes, Mode);
+
+ /* Add cea-extension mode timings */
+ Mode = DDCModesFromCEAExtension(scrnIndex,DDC);
+ Modes = xf86ModesAdd(Modes, Mode);
+
+ if (quirks & DDC_QUIRK_PREFER_LARGE_60)
+ xf86DDCSetPreferredRefresh(scrnIndex, Modes, 60);
+
+ if (quirks & DDC_QUIRK_PREFER_LARGE_75)
+ xf86DDCSetPreferredRefresh(scrnIndex, Modes, 75);
+
+ Modes = xf86PruneDuplicateModes(Modes);
+
+ return Modes;
+}
+
+struct det_mon_parameter {
+ MonPtr Monitor;
+ ddc_quirk_t quirks;
+ Bool have_hsync;
+ Bool have_vrefresh;
+ Bool have_maxpixclock;
+};
+
+static void handle_detailed_monset(struct detailed_monitor_section *det_mon,
+ void *data)
+{
+ int clock;
+ struct det_mon_parameter *p = (struct det_mon_parameter *)data;
+ int scrnIndex = ((xf86MonPtr)(p->Monitor->DDC))->scrnIndex;
+
+ switch (det_mon->type) {
+ case DS_RANGES:
+ if (!p->have_hsync) {
+ if (!p->Monitor->nHsync)
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Using EDID range info for horizontal sync\n");
+ p->Monitor->hsync[p->Monitor->nHsync].lo =
+ det_mon->section.ranges.min_h;
+ p->Monitor->hsync[p->Monitor->nHsync].hi =
+ det_mon->section.ranges.max_h;
+ p->Monitor->nHsync++;
+ } else {
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Using hsync ranges from config file\n");
+ }
+
+ if (!p->have_vrefresh) {
+ if (!p->Monitor->nVrefresh)
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Using EDID range info for vertical refresh\n");
+ p->Monitor->vrefresh[p->Monitor->nVrefresh].lo =
+ det_mon->section.ranges.min_v;
+ p->Monitor->vrefresh[p->Monitor->nVrefresh].hi =
+ det_mon->section.ranges.max_v;
+ p->Monitor->nVrefresh++;
+ } else {
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Using vrefresh ranges from config file\n");
+ }
+
+ clock = det_mon->section.ranges.max_clock * 1000;
+ if (p->quirks & DDC_QUIRK_DVI_SINGLE_LINK)
+ clock = min(clock, 165000);
+ if (!p->have_maxpixclock && clock > p->Monitor->maxPixClock)
+ p->Monitor->maxPixClock = clock;
+
+ break;
+ default:
+ break;
+ }
+}
+
+/*
+ * Fill out MonPtr with xf86MonPtr information.
+ */
+void
+xf86EdidMonitorSet(int scrnIndex, MonPtr Monitor, xf86MonPtr DDC)
+{
+ DisplayModePtr Modes = NULL, Mode;
+ struct det_mon_parameter p;
+
+ if (!Monitor || !DDC)
+ return;
+
+ Monitor->DDC = DDC;
+
+ if (Monitor->widthmm <= 0 || Monitor->heightmm <= 0) {
+ Monitor->widthmm = 10 * DDC->features.hsize;
+ Monitor->heightmm = 10 * DDC->features.vsize;
+ }
+
+ Monitor->reducedblanking = xf86MonitorSupportsReducedBlanking(DDC);
+
+ Modes = xf86DDCGetModes(scrnIndex, DDC);
+
+ /* Go through the detailed monitor sections */
+ p.Monitor = Monitor;
+ p.quirks = xf86DDCDetectQuirks(scrnIndex, Monitor->DDC, FALSE);
+ p.have_hsync = (Monitor->nHsync != 0);
+ p.have_vrefresh = (Monitor->nVrefresh != 0);
+ p.have_maxpixclock = (Monitor->maxPixClock != 0);
+ xf86ForEachDetailedBlock(DDC, handle_detailed_monset, &p);
+
+ if (Modes) {
+ /* Print Modes */
+ xf86DrvMsg(scrnIndex, X_INFO, "Printing DDC gathered Modelines:\n");
+
+ Mode = Modes;
+ while (Mode) {
+ xf86PrintModeline(scrnIndex, Mode);
+ Mode = Mode->next;
+ }
+
+ /* Do we still need ranges to be filled in? */
+ if (!Monitor->nHsync || !Monitor->nVrefresh)
+ DDCGuessRangesFromModes(scrnIndex, Monitor, Modes);
+
+ /* look for last Mode */
+ Mode = Modes;
+
+ while (Mode->next)
+ Mode = Mode->next;
+
+ /* add to MonPtr */
+ if (Monitor->Modes) {
+ Monitor->Last->next = Modes;
+ Modes->prev = Monitor->Last;
+ Monitor->Last = Mode;
+ } else {
+ Monitor->Modes = Modes;
+ Monitor->Last = Mode;
+ }
+ }
+}
diff --git a/xorg-server/hw/xfree86/modes/xf86Modes.c b/xorg-server/hw/xfree86/modes/xf86Modes.c
index 75aedaa99..0507e9812 100644
--- a/xorg-server/hw/xfree86/modes/xf86Modes.c
+++ b/xorg-server/hw/xfree86/modes/xf86Modes.c
@@ -1,727 +1,727 @@
-/*
- * 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).
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#else
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#endif
-
-#include "xf86Modes.h"
-#include "xf86Priv.h"
-
-extern XF86ConfigPtr xf86configptr;
-
-/*
- * This is the version number where we epoched. These files get copied
- * into drivers that want to use this setup infrastructure on pre-1.3
- * servers, so when that happens they need to define these symbols
- * themselves. However, _in_ the server, we basically always define them now.
- */
-#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0)
-
-/**
- * Calculates the horizontal sync rate of a mode.
- */
-double
-xf86ModeHSync(const DisplayModeRec *mode)
-{
- double hsync = 0.0;
-
- if (mode->HSync > 0.0)
- hsync = mode->HSync;
- else if (mode->HTotal > 0)
- hsync = (float)mode->Clock / (float)mode->HTotal;
-
- return hsync;
-}
-
-/**
- * Calculates the vertical refresh rate of a mode.
- */
-double
-xf86ModeVRefresh(const DisplayModeRec *mode)
-{
- double refresh = 0.0;
-
- if (mode->VRefresh > 0.0)
- refresh = mode->VRefresh;
- else if (mode->HTotal > 0 && mode->VTotal > 0) {
- refresh = mode->Clock * 1000.0 / mode->HTotal / mode->VTotal;
- if (mode->Flags & V_INTERLACE)
- refresh *= 2.0;
- if (mode->Flags & V_DBLSCAN)
- refresh /= 2.0;
- if (mode->VScan > 1)
- refresh /= (float)(mode->VScan);
- }
- return refresh;
-}
-
-int
-xf86ModeWidth (const DisplayModeRec *mode, Rotation rotation)
-{
- switch (rotation & 0xf) {
- case RR_Rotate_0:
- case RR_Rotate_180:
- return mode->HDisplay;
- case RR_Rotate_90:
- case RR_Rotate_270:
- return mode->VDisplay;
- default:
- return 0;
- }
-}
-
-int
-xf86ModeHeight (const DisplayModeRec *mode, Rotation rotation)
-{
- switch (rotation & 0xf) {
- case RR_Rotate_0:
- case RR_Rotate_180:
- return mode->VDisplay;
- case RR_Rotate_90:
- case RR_Rotate_270:
- return mode->HDisplay;
- default:
- return 0;
- }
-}
-
-/** Calculates the memory bandwidth (in MiB/sec) of a mode. */
-unsigned int
-xf86ModeBandwidth(DisplayModePtr mode, int depth)
-{
- float a_active, a_total, active_percent, pixels_per_second;
- int bytes_per_pixel = bits_to_bytes(depth);
-
- if (!mode->HTotal || !mode->VTotal || !mode->Clock)
- return 0;
-
- a_active = mode->HDisplay * mode->VDisplay;
- a_total = mode->HTotal * mode->VTotal;
- active_percent = a_active / a_total;
- pixels_per_second = active_percent * mode->Clock * 1000.0;
-
- return (unsigned int)(pixels_per_second * bytes_per_pixel / (1024 * 1024));
-}
-
-/** Sets a default mode name of <width>x<height> on a mode. */
-void
-xf86SetModeDefaultName(DisplayModePtr mode)
-{
- Bool interlaced = !!(mode->Flags & V_INTERLACE);
-
- xfree(mode->name);
-
- mode->name = XNFprintf("%dx%d%s", mode->HDisplay, mode->VDisplay,
- interlaced ? "i" : "");
-}
-
-/*
- * xf86SetModeCrtc
- *
- * Initialises the Crtc parameters for a mode. The initialisation includes
- * adjustments for interlaced and double scan modes.
- */
-void
-xf86SetModeCrtc(DisplayModePtr p, int adjustFlags)
-{
- if ((p == NULL) || ((p->type & M_T_CRTC_C) == M_T_BUILTIN))
- return;
-
- p->CrtcHDisplay = p->HDisplay;
- p->CrtcHSyncStart = p->HSyncStart;
- p->CrtcHSyncEnd = p->HSyncEnd;
- p->CrtcHTotal = p->HTotal;
- p->CrtcHSkew = p->HSkew;
- p->CrtcVDisplay = p->VDisplay;
- p->CrtcVSyncStart = p->VSyncStart;
- p->CrtcVSyncEnd = p->VSyncEnd;
- p->CrtcVTotal = p->VTotal;
- if (p->Flags & V_INTERLACE) {
- if (adjustFlags & INTERLACE_HALVE_V) {
- p->CrtcVDisplay /= 2;
- p->CrtcVSyncStart /= 2;
- p->CrtcVSyncEnd /= 2;
- p->CrtcVTotal /= 2;
- }
- /* Force interlaced modes to have an odd VTotal */
- /* maybe we should only do this when INTERLACE_HALVE_V is set? */
- p->CrtcVTotal |= 1;
- }
-
- if (p->Flags & V_DBLSCAN) {
- p->CrtcVDisplay *= 2;
- p->CrtcVSyncStart *= 2;
- p->CrtcVSyncEnd *= 2;
- p->CrtcVTotal *= 2;
- }
- if (p->VScan > 1) {
- p->CrtcVDisplay *= p->VScan;
- p->CrtcVSyncStart *= p->VScan;
- p->CrtcVSyncEnd *= p->VScan;
- p->CrtcVTotal *= p->VScan;
- }
- p->CrtcVBlankStart = min(p->CrtcVSyncStart, p->CrtcVDisplay);
- p->CrtcVBlankEnd = max(p->CrtcVSyncEnd, p->CrtcVTotal);
- p->CrtcHBlankStart = min(p->CrtcHSyncStart, p->CrtcHDisplay);
- p->CrtcHBlankEnd = max(p->CrtcHSyncEnd, p->CrtcHTotal);
-
- p->CrtcHAdjusted = FALSE;
- p->CrtcVAdjusted = FALSE;
-}
-
-/**
- * Allocates and returns a copy of pMode, including pointers within pMode.
- */
-DisplayModePtr
-xf86DuplicateMode(const DisplayModeRec *pMode)
-{
- DisplayModePtr pNew;
-
- pNew = xnfalloc(sizeof(DisplayModeRec));
- *pNew = *pMode;
- pNew->next = NULL;
- pNew->prev = NULL;
-
- if (pMode->name == NULL)
- xf86SetModeDefaultName(pNew);
- else
- pNew->name = xnfstrdup(pMode->name);
-
- return pNew;
-}
-
-/**
- * Duplicates every mode in the given list and returns a pointer to the first
- * mode.
- *
- * \param modeList doubly-linked mode list
- */
-DisplayModePtr
-xf86DuplicateModes(ScrnInfoPtr pScrn, DisplayModePtr modeList)
-{
- DisplayModePtr first = NULL, last = NULL;
- DisplayModePtr mode;
-
- for (mode = modeList; mode != NULL; mode = mode->next) {
- DisplayModePtr new;
-
- new = xf86DuplicateMode(mode);
-
- /* Insert pNew into modeList */
- if (last) {
- last->next = new;
- new->prev = last;
- } else {
- first = new;
- new->prev = NULL;
- }
- new->next = NULL;
- last = new;
- }
-
- return first;
-}
-
-/**
- * Returns true if the given modes should program to the same timings.
- *
- * This doesn't use Crtc values, as it might be used on ModeRecs without the
- * Crtc values set. So, it's assumed that the other numbers are enough.
- */
-Bool
-xf86ModesEqual(const DisplayModeRec *pMode1, const DisplayModeRec *pMode2)
-{
- if (pMode1->Clock == pMode2->Clock &&
- pMode1->HDisplay == pMode2->HDisplay &&
- pMode1->HSyncStart == pMode2->HSyncStart &&
- pMode1->HSyncEnd == pMode2->HSyncEnd &&
- pMode1->HTotal == pMode2->HTotal &&
- pMode1->HSkew == pMode2->HSkew &&
- pMode1->VDisplay == pMode2->VDisplay &&
- pMode1->VSyncStart == pMode2->VSyncStart &&
- pMode1->VSyncEnd == pMode2->VSyncEnd &&
- pMode1->VTotal == pMode2->VTotal &&
- pMode1->VScan == pMode2->VScan &&
- pMode1->Flags == pMode2->Flags)
- {
- return TRUE;
- } else {
- return FALSE;
- }
-}
-
-static void
-add(char **p, char *new)
-{
- *p = xnfrealloc(*p, strlen(*p) + strlen(new) + 2);
- strcat(*p, " ");
- strcat(*p, new);
-}
-
-/**
- * Print out a modeline.
- */
-void
-xf86PrintModeline(int scrnIndex,DisplayModePtr mode)
-{
- char tmp[256];
- char *flags = xnfcalloc(1, 1);
-
- if (mode->HSkew) {
- snprintf(tmp, 256, "hskew %i", mode->HSkew);
- add(&flags, tmp);
- }
- if (mode->VScan) {
- snprintf(tmp, 256, "vscan %i", mode->VScan);
- add(&flags, tmp);
- }
- if (mode->Flags & V_INTERLACE) add(&flags, "interlace");
- if (mode->Flags & V_CSYNC) add(&flags, "composite");
- if (mode->Flags & V_DBLSCAN) add(&flags, "doublescan");
- if (mode->Flags & V_BCAST) add(&flags, "bcast");
- if (mode->Flags & V_PHSYNC) add(&flags, "+hsync");
- if (mode->Flags & V_NHSYNC) add(&flags, "-hsync");
- if (mode->Flags & V_PVSYNC) add(&flags, "+vsync");
- if (mode->Flags & V_NVSYNC) add(&flags, "-vsync");
- if (mode->Flags & V_PCSYNC) add(&flags, "+csync");
- if (mode->Flags & V_NCSYNC) add(&flags, "-csync");
-#if 0
- if (mode->Flags & V_CLKDIV2) add(&flags, "vclk/2");
-#endif
- xf86DrvMsg(scrnIndex, X_INFO,
- "Modeline \"%s\"x%.01f %6.2f %i %i %i %i %i %i %i %i%s "
- "(%.01f kHz)\n",
- mode->name, mode->VRefresh, mode->Clock/1000., mode->HDisplay,
- mode->HSyncStart, mode->HSyncEnd, mode->HTotal,
- mode->VDisplay, mode->VSyncStart, mode->VSyncEnd,
- mode->VTotal, flags, xf86ModeHSync(mode));
- xfree(flags);
-}
-#endif /* XORG_VERSION_CURRENT <= 7.2.99.2 */
-
-/**
- * Marks as bad any modes with unsupported flags.
- *
- * \param modeList doubly-linked list of modes.
- * \param flags flags supported by the driver.
- *
- * \bug only V_INTERLACE and V_DBLSCAN are supported. Is that enough?
- */
-void
-xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList,
- int flags)
-{
- DisplayModePtr mode;
-
- if (flags == (V_INTERLACE | V_DBLSCAN))
- return;
-
- for (mode = modeList; mode != NULL; mode = mode->next) {
- if (mode->Flags & V_INTERLACE && !(flags & V_INTERLACE))
- mode->status = MODE_NO_INTERLACE;
- if (mode->Flags & V_DBLSCAN && !(flags & V_DBLSCAN))
- mode->status = MODE_NO_DBLESCAN;
- }
-}
-
-/**
- * Marks as bad any modes extending beyond the given max X, Y, or pitch.
- *
- * \param modeList doubly-linked list of modes.
- */
-void
-xf86ValidateModesSize(ScrnInfoPtr pScrn, DisplayModePtr modeList,
- int maxX, int maxY, int maxPitch)
-{
- DisplayModePtr mode;
-
- for (mode = modeList; mode != NULL; mode = mode->next) {
- if (maxPitch > 0 && mode->HDisplay > maxPitch)
- mode->status = MODE_BAD_WIDTH;
-
- if (maxX > 0 && mode->HDisplay > maxX)
- mode->status = MODE_VIRTUAL_X;
-
- if (maxY > 0 && mode->VDisplay > maxY)
- mode->status = MODE_VIRTUAL_Y;
-
- if (mode->next == modeList)
- break;
- }
-}
-
-/**
- * Marks as bad any modes that aren't supported by the given monitor's
- * hsync and vrefresh ranges.
- *
- * \param modeList doubly-linked list of modes.
- */
-void
-xf86ValidateModesSync(ScrnInfoPtr pScrn, DisplayModePtr modeList,
- MonPtr mon)
-{
- DisplayModePtr mode;
-
- for (mode = modeList; mode != NULL; mode = mode->next) {
- Bool bad;
- int i;
-
- bad = TRUE;
- for (i = 0; i < mon->nHsync; i++) {
- if (xf86ModeHSync(mode) >= mon->hsync[i].lo * (1-SYNC_TOLERANCE) &&
- xf86ModeHSync(mode) <= mon->hsync[i].hi * (1+SYNC_TOLERANCE))
- {
- bad = FALSE;
- }
- }
- if (bad)
- mode->status = MODE_HSYNC;
-
- bad = TRUE;
- for (i = 0; i < mon->nVrefresh; i++) {
- if (xf86ModeVRefresh(mode) >= mon->vrefresh[i].lo * (1-SYNC_TOLERANCE) &&
- xf86ModeVRefresh(mode) <= mon->vrefresh[i].hi * (1+SYNC_TOLERANCE))
- {
- bad = FALSE;
- }
- }
- if (bad)
- mode->status = MODE_VSYNC;
-
- if (mode->next == modeList)
- break;
- }
-}
-
-/**
- * Marks as bad any modes extending beyond outside of the given clock ranges.
- *
- * \param modeList doubly-linked list of modes.
- * \param min pointer to minimums of clock ranges
- * \param max pointer to maximums of clock ranges
- * \param n_ranges number of ranges.
- */
-void
-xf86ValidateModesClocks(ScrnInfoPtr pScrn, DisplayModePtr modeList,
- int *min, int *max, int n_ranges)
-{
- DisplayModePtr mode;
- int i;
-
- for (mode = modeList; mode != NULL; mode = mode->next) {
- Bool good = FALSE;
- for (i = 0; i < n_ranges; i++) {
- if (mode->Clock >= min[i] * (1-SYNC_TOLERANCE) &&
- mode->Clock <= max[i] * (1+SYNC_TOLERANCE)) {
- good = TRUE;
- break;
- }
- }
- if (!good)
- mode->status = MODE_CLOCK_RANGE;
- }
-}
-
-/**
- * If the user has specified a set of mode names to use, mark as bad any modes
- * not listed.
- *
- * The user mode names specified are prefixes to names of modes, so "1024x768"
- * will match modes named "1024x768", "1024x768x75", "1024x768-good", but
- * "1024x768x75" would only match "1024x768x75" from that list.
- *
- * MODE_BAD is used as the rejection flag, for lack of a better flag.
- *
- * \param modeList doubly-linked list of modes.
- */
-void
-xf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList)
-{
- DisplayModePtr mode;
-
- if (pScrn->display->modes[0] == NULL)
- return;
-
- for (mode = modeList; mode != NULL; mode = mode->next) {
- int i;
- Bool good = FALSE;
-
- for (i = 0; pScrn->display->modes[i] != NULL; i++) {
- if (strncmp(pScrn->display->modes[i], mode->name,
- strlen(pScrn->display->modes[i])) == 0) {
- good = TRUE;
- break;
- }
- }
- if (!good)
- mode->status = MODE_BAD;
- }
-}
-
-
-/**
- * Marks as bad any modes exceeding the given bandwidth.
- *
- * \param modeList doubly-linked list of modes.
- * \param bandwidth bandwidth in MHz.
- * \param depth color depth.
- */
-void
-xf86ValidateModesBandwidth(ScrnInfoPtr pScrn, DisplayModePtr modeList,
- unsigned int bandwidth, int depth)
-{
- DisplayModePtr mode;
-
- for (mode = modeList; mode != NULL; mode = mode->next) {
- if (xf86ModeBandwidth(mode, depth) > bandwidth)
-#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
- mode->status = MODE_BANDWIDTH;
-#else
- /* MODE_BANDWIDTH didn't exist in xserver 1.2 */
- mode->status = MODE_BAD;
-#endif
- }
-}
-
-Bool
-xf86ModeIsReduced(const DisplayModeRec *mode)
-{
- if ((((mode->HDisplay * 5 / 4) & ~0x07) > mode->HTotal) &&
- ((mode->HTotal - mode->HDisplay) == 160) &&
- ((mode->HSyncEnd - mode->HDisplay) == 80) &&
- ((mode->HSyncEnd - mode->HSyncStart) == 32) &&
- ((mode->VSyncStart - mode->VDisplay) == 3))
- return TRUE;
- return FALSE;
-}
-
-/**
- * Marks as bad any reduced-blanking modes.
- *
- * \param modeList doubly-linked list of modes.
- */
-void
-xf86ValidateModesReducedBlanking(ScrnInfoPtr pScrn, DisplayModePtr modeList)
-{
- for (; modeList != NULL; modeList = modeList->next)
- if (xf86ModeIsReduced(modeList))
- modeList->status = MODE_NO_REDUCED;
-}
-
-/**
- * Frees any modes from the list with a status other than MODE_OK.
- *
- * \param modeList pointer to a doubly-linked or circular list of modes.
- * \param verbose determines whether the reason for mode invalidation is
- * printed.
- */
-void
-xf86PruneInvalidModes(ScrnInfoPtr pScrn, DisplayModePtr *modeList,
- Bool verbose)
-{
- DisplayModePtr mode;
-
- for (mode = *modeList; mode != NULL;) {
- DisplayModePtr next = mode->next, first = *modeList;
-
- if (mode->status != MODE_OK) {
- if (verbose) {
- char *type = "";
- if (mode->type & M_T_BUILTIN)
- type = "built-in ";
- else if (mode->type & M_T_DEFAULT)
- type = "default ";
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Not using %smode \"%s\" (%s)\n", type, mode->name,
- xf86ModeStatusToString(mode->status));
- }
- xf86DeleteMode(modeList, mode);
- }
-
- if (next == first)
- break;
- mode = next;
- }
-}
-
-/**
- * Adds the new mode into the mode list, and returns the new list
- *
- * \param modes doubly-linked mode list.
- */
-DisplayModePtr
-xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new)
-{
- if (modes == NULL)
- return new;
-
- if (new) {
- DisplayModePtr mode = modes;
-
- while (mode->next)
- mode = mode->next;
-
- mode->next = new;
- new->prev = mode;
- }
-
- return modes;
-}
-
-/**
- * Build a mode list from a list of config file modes
- */
-static DisplayModePtr
-xf86GetConfigModes (XF86ConfModeLinePtr conf_mode)
-{
- DisplayModePtr head = NULL, prev = NULL, mode;
-
- for (; conf_mode; conf_mode = (XF86ConfModeLinePtr) conf_mode->list.next)
- {
- mode = xcalloc(1, sizeof(DisplayModeRec));
- if (!mode)
- continue;
- mode->name = xstrdup(conf_mode->ml_identifier);
- if (!mode->name)
- {
- xfree (mode);
- continue;
- }
- mode->type = 0;
- mode->Clock = conf_mode->ml_clock;
- mode->HDisplay = conf_mode->ml_hdisplay;
- mode->HSyncStart = conf_mode->ml_hsyncstart;
- mode->HSyncEnd = conf_mode->ml_hsyncend;
- mode->HTotal = conf_mode->ml_htotal;
- mode->VDisplay = conf_mode->ml_vdisplay;
- mode->VSyncStart = conf_mode->ml_vsyncstart;
- mode->VSyncEnd = conf_mode->ml_vsyncend;
- mode->VTotal = conf_mode->ml_vtotal;
- mode->Flags = conf_mode->ml_flags;
- mode->HSkew = conf_mode->ml_hskew;
- mode->VScan = conf_mode->ml_vscan;
-
- mode->prev = prev;
- mode->next = NULL;
- if (prev)
- prev->next = mode;
- else
- head = mode;
- prev = mode;
- }
- return head;
-}
-
-/**
- * Build a mode list from a monitor configuration
- */
-DisplayModePtr
-xf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor)
-{
- DisplayModePtr modes = NULL;
- XF86ConfModesLinkPtr modes_link;
-
- if (!conf_monitor)
- return NULL;
-
- /*
- * first we collect the mode lines from the UseModes directive
- */
- for (modes_link = conf_monitor->mon_modes_sect_lst;
- modes_link;
- modes_link = modes_link->list.next)
- {
- /* If this modes link hasn't been resolved, go look it up now */
- if (!modes_link->ml_modes)
- modes_link->ml_modes = xf86findModes (modes_link->ml_modes_str,
- xf86configptr->conf_modes_lst);
- if (modes_link->ml_modes)
- modes = xf86ModesAdd (modes,
- xf86GetConfigModes (modes_link->ml_modes->mon_modeline_lst));
- }
-
- return xf86ModesAdd (modes,
- xf86GetConfigModes (conf_monitor->mon_modeline_lst));
-}
-
-/**
- * Build a mode list containing all of the default modes
- */
-DisplayModePtr
-xf86GetDefaultModes (void)
-{
- DisplayModePtr head = NULL, mode;
- int i;
-
- for (i = 0; i < xf86NumDefaultModes; i++)
- {
- const DisplayModeRec *defMode = &xf86DefaultModes[i];
-
- mode = xf86DuplicateMode(defMode);
- head = xf86ModesAdd(head, mode);
- }
- return head;
-}
-
-/*
- * Walk a mode list and prune out duplicates. Will preserve the preferred
- * mode of an otherwise-duplicate pair.
- *
- * Probably best to call this on lists that are all of a single class
- * (driver, default, user, etc.), otherwise, which mode gets deleted is
- * not especially well defined.
- *
- * Returns the new list.
- */
-
-DisplayModePtr
-xf86PruneDuplicateModes(DisplayModePtr modes)
-{
- DisplayModePtr m, n, o;
-
-top:
- for (m = modes; m; m = m->next) {
- for (n = m->next; n; n = o) {
- o = n->next;
- if (xf86ModesEqual(m, n)) {
- if (n->type & M_T_PREFERRED) {
- xf86DeleteMode(&modes, m);
- goto top;
- }
- else
- xf86DeleteMode(&modes, n);
- }
- }
- }
-
- return modes;
-}
+/*
+ * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#else
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#endif
+
+#include "xf86Modes.h"
+#include "xf86Priv.h"
+
+extern XF86ConfigPtr xf86configptr;
+
+/*
+ * This is the version number where we epoched. These files get copied
+ * into drivers that want to use this setup infrastructure on pre-1.3
+ * servers, so when that happens they need to define these symbols
+ * themselves. However, _in_ the server, we basically always define them now.
+ */
+#if XORG_VERSION_CURRENT <= XORG_VERSION_NUMERIC(7,2,99,2,0)
+
+/**
+ * Calculates the horizontal sync rate of a mode.
+ */
+double
+xf86ModeHSync(const DisplayModeRec *mode)
+{
+ double hsync = 0.0;
+
+ if (mode->HSync > 0.0)
+ hsync = mode->HSync;
+ else if (mode->HTotal > 0)
+ hsync = (float)mode->Clock / (float)mode->HTotal;
+
+ return hsync;
+}
+
+/**
+ * Calculates the vertical refresh rate of a mode.
+ */
+double
+xf86ModeVRefresh(const DisplayModeRec *mode)
+{
+ double refresh = 0.0;
+
+ if (mode->VRefresh > 0.0)
+ refresh = mode->VRefresh;
+ else if (mode->HTotal > 0 && mode->VTotal > 0) {
+ refresh = mode->Clock * 1000.0 / mode->HTotal / mode->VTotal;
+ if (mode->Flags & V_INTERLACE)
+ refresh *= 2.0;
+ if (mode->Flags & V_DBLSCAN)
+ refresh /= 2.0;
+ if (mode->VScan > 1)
+ refresh /= (float)(mode->VScan);
+ }
+ return refresh;
+}
+
+int
+xf86ModeWidth (const DisplayModeRec *mode, Rotation rotation)
+{
+ switch (rotation & 0xf) {
+ case RR_Rotate_0:
+ case RR_Rotate_180:
+ return mode->HDisplay;
+ case RR_Rotate_90:
+ case RR_Rotate_270:
+ return mode->VDisplay;
+ default:
+ return 0;
+ }
+}
+
+int
+xf86ModeHeight (const DisplayModeRec *mode, Rotation rotation)
+{
+ switch (rotation & 0xf) {
+ case RR_Rotate_0:
+ case RR_Rotate_180:
+ return mode->VDisplay;
+ case RR_Rotate_90:
+ case RR_Rotate_270:
+ return mode->HDisplay;
+ default:
+ return 0;
+ }
+}
+
+/** Calculates the memory bandwidth (in MiB/sec) of a mode. */
+unsigned int
+xf86ModeBandwidth(DisplayModePtr mode, int depth)
+{
+ float a_active, a_total, active_percent, pixels_per_second;
+ int bytes_per_pixel = bits_to_bytes(depth);
+
+ if (!mode->HTotal || !mode->VTotal || !mode->Clock)
+ return 0;
+
+ a_active = mode->HDisplay * mode->VDisplay;
+ a_total = mode->HTotal * mode->VTotal;
+ active_percent = a_active / a_total;
+ pixels_per_second = active_percent * mode->Clock * 1000.0;
+
+ return (unsigned int)(pixels_per_second * bytes_per_pixel / (1024 * 1024));
+}
+
+/** Sets a default mode name of <width>x<height> on a mode. */
+void
+xf86SetModeDefaultName(DisplayModePtr mode)
+{
+ Bool interlaced = !!(mode->Flags & V_INTERLACE);
+
+ free(mode->name);
+
+ mode->name = XNFprintf("%dx%d%s", mode->HDisplay, mode->VDisplay,
+ interlaced ? "i" : "");
+}
+
+/*
+ * xf86SetModeCrtc
+ *
+ * Initialises the Crtc parameters for a mode. The initialisation includes
+ * adjustments for interlaced and double scan modes.
+ */
+void
+xf86SetModeCrtc(DisplayModePtr p, int adjustFlags)
+{
+ if ((p == NULL) || ((p->type & M_T_CRTC_C) == M_T_BUILTIN))
+ return;
+
+ p->CrtcHDisplay = p->HDisplay;
+ p->CrtcHSyncStart = p->HSyncStart;
+ p->CrtcHSyncEnd = p->HSyncEnd;
+ p->CrtcHTotal = p->HTotal;
+ p->CrtcHSkew = p->HSkew;
+ p->CrtcVDisplay = p->VDisplay;
+ p->CrtcVSyncStart = p->VSyncStart;
+ p->CrtcVSyncEnd = p->VSyncEnd;
+ p->CrtcVTotal = p->VTotal;
+ if (p->Flags & V_INTERLACE) {
+ if (adjustFlags & INTERLACE_HALVE_V) {
+ p->CrtcVDisplay /= 2;
+ p->CrtcVSyncStart /= 2;
+ p->CrtcVSyncEnd /= 2;
+ p->CrtcVTotal /= 2;
+ }
+ /* Force interlaced modes to have an odd VTotal */
+ /* maybe we should only do this when INTERLACE_HALVE_V is set? */
+ p->CrtcVTotal |= 1;
+ }
+
+ if (p->Flags & V_DBLSCAN) {
+ p->CrtcVDisplay *= 2;
+ p->CrtcVSyncStart *= 2;
+ p->CrtcVSyncEnd *= 2;
+ p->CrtcVTotal *= 2;
+ }
+ if (p->VScan > 1) {
+ p->CrtcVDisplay *= p->VScan;
+ p->CrtcVSyncStart *= p->VScan;
+ p->CrtcVSyncEnd *= p->VScan;
+ p->CrtcVTotal *= p->VScan;
+ }
+ p->CrtcVBlankStart = min(p->CrtcVSyncStart, p->CrtcVDisplay);
+ p->CrtcVBlankEnd = max(p->CrtcVSyncEnd, p->CrtcVTotal);
+ p->CrtcHBlankStart = min(p->CrtcHSyncStart, p->CrtcHDisplay);
+ p->CrtcHBlankEnd = max(p->CrtcHSyncEnd, p->CrtcHTotal);
+
+ p->CrtcHAdjusted = FALSE;
+ p->CrtcVAdjusted = FALSE;
+}
+
+/**
+ * Allocates and returns a copy of pMode, including pointers within pMode.
+ */
+DisplayModePtr
+xf86DuplicateMode(const DisplayModeRec *pMode)
+{
+ DisplayModePtr pNew;
+
+ pNew = xnfalloc(sizeof(DisplayModeRec));
+ *pNew = *pMode;
+ pNew->next = NULL;
+ pNew->prev = NULL;
+
+ if (pMode->name == NULL)
+ xf86SetModeDefaultName(pNew);
+ else
+ pNew->name = xnfstrdup(pMode->name);
+
+ return pNew;
+}
+
+/**
+ * Duplicates every mode in the given list and returns a pointer to the first
+ * mode.
+ *
+ * \param modeList doubly-linked mode list
+ */
+DisplayModePtr
+xf86DuplicateModes(ScrnInfoPtr pScrn, DisplayModePtr modeList)
+{
+ DisplayModePtr first = NULL, last = NULL;
+ DisplayModePtr mode;
+
+ for (mode = modeList; mode != NULL; mode = mode->next) {
+ DisplayModePtr new;
+
+ new = xf86DuplicateMode(mode);
+
+ /* Insert pNew into modeList */
+ if (last) {
+ last->next = new;
+ new->prev = last;
+ } else {
+ first = new;
+ new->prev = NULL;
+ }
+ new->next = NULL;
+ last = new;
+ }
+
+ return first;
+}
+
+/**
+ * Returns true if the given modes should program to the same timings.
+ *
+ * This doesn't use Crtc values, as it might be used on ModeRecs without the
+ * Crtc values set. So, it's assumed that the other numbers are enough.
+ */
+Bool
+xf86ModesEqual(const DisplayModeRec *pMode1, const DisplayModeRec *pMode2)
+{
+ if (pMode1->Clock == pMode2->Clock &&
+ pMode1->HDisplay == pMode2->HDisplay &&
+ pMode1->HSyncStart == pMode2->HSyncStart &&
+ pMode1->HSyncEnd == pMode2->HSyncEnd &&
+ pMode1->HTotal == pMode2->HTotal &&
+ pMode1->HSkew == pMode2->HSkew &&
+ pMode1->VDisplay == pMode2->VDisplay &&
+ pMode1->VSyncStart == pMode2->VSyncStart &&
+ pMode1->VSyncEnd == pMode2->VSyncEnd &&
+ pMode1->VTotal == pMode2->VTotal &&
+ pMode1->VScan == pMode2->VScan &&
+ pMode1->Flags == pMode2->Flags)
+ {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+static void
+add(char **p, char *new)
+{
+ *p = xnfrealloc(*p, strlen(*p) + strlen(new) + 2);
+ strcat(*p, " ");
+ strcat(*p, new);
+}
+
+/**
+ * Print out a modeline.
+ */
+void
+xf86PrintModeline(int scrnIndex,DisplayModePtr mode)
+{
+ char tmp[256];
+ char *flags = xnfcalloc(1, 1);
+
+ if (mode->HSkew) {
+ snprintf(tmp, 256, "hskew %i", mode->HSkew);
+ add(&flags, tmp);
+ }
+ if (mode->VScan) {
+ snprintf(tmp, 256, "vscan %i", mode->VScan);
+ add(&flags, tmp);
+ }
+ if (mode->Flags & V_INTERLACE) add(&flags, "interlace");
+ if (mode->Flags & V_CSYNC) add(&flags, "composite");
+ if (mode->Flags & V_DBLSCAN) add(&flags, "doublescan");
+ if (mode->Flags & V_BCAST) add(&flags, "bcast");
+ if (mode->Flags & V_PHSYNC) add(&flags, "+hsync");
+ if (mode->Flags & V_NHSYNC) add(&flags, "-hsync");
+ if (mode->Flags & V_PVSYNC) add(&flags, "+vsync");
+ if (mode->Flags & V_NVSYNC) add(&flags, "-vsync");
+ if (mode->Flags & V_PCSYNC) add(&flags, "+csync");
+ if (mode->Flags & V_NCSYNC) add(&flags, "-csync");
+#if 0
+ if (mode->Flags & V_CLKDIV2) add(&flags, "vclk/2");
+#endif
+ xf86DrvMsg(scrnIndex, X_INFO,
+ "Modeline \"%s\"x%.01f %6.2f %i %i %i %i %i %i %i %i%s "
+ "(%.01f kHz)\n",
+ mode->name, mode->VRefresh, mode->Clock/1000., mode->HDisplay,
+ mode->HSyncStart, mode->HSyncEnd, mode->HTotal,
+ mode->VDisplay, mode->VSyncStart, mode->VSyncEnd,
+ mode->VTotal, flags, xf86ModeHSync(mode));
+ free(flags);
+}
+#endif /* XORG_VERSION_CURRENT <= 7.2.99.2 */
+
+/**
+ * Marks as bad any modes with unsupported flags.
+ *
+ * \param modeList doubly-linked list of modes.
+ * \param flags flags supported by the driver.
+ *
+ * \bug only V_INTERLACE and V_DBLSCAN are supported. Is that enough?
+ */
+void
+xf86ValidateModesFlags(ScrnInfoPtr pScrn, DisplayModePtr modeList,
+ int flags)
+{
+ DisplayModePtr mode;
+
+ if (flags == (V_INTERLACE | V_DBLSCAN))
+ return;
+
+ for (mode = modeList; mode != NULL; mode = mode->next) {
+ if (mode->Flags & V_INTERLACE && !(flags & V_INTERLACE))
+ mode->status = MODE_NO_INTERLACE;
+ if (mode->Flags & V_DBLSCAN && !(flags & V_DBLSCAN))
+ mode->status = MODE_NO_DBLESCAN;
+ }
+}
+
+/**
+ * Marks as bad any modes extending beyond the given max X, Y, or pitch.
+ *
+ * \param modeList doubly-linked list of modes.
+ */
+void
+xf86ValidateModesSize(ScrnInfoPtr pScrn, DisplayModePtr modeList,
+ int maxX, int maxY, int maxPitch)
+{
+ DisplayModePtr mode;
+
+ for (mode = modeList; mode != NULL; mode = mode->next) {
+ if (maxPitch > 0 && mode->HDisplay > maxPitch)
+ mode->status = MODE_BAD_WIDTH;
+
+ if (maxX > 0 && mode->HDisplay > maxX)
+ mode->status = MODE_VIRTUAL_X;
+
+ if (maxY > 0 && mode->VDisplay > maxY)
+ mode->status = MODE_VIRTUAL_Y;
+
+ if (mode->next == modeList)
+ break;
+ }
+}
+
+/**
+ * Marks as bad any modes that aren't supported by the given monitor's
+ * hsync and vrefresh ranges.
+ *
+ * \param modeList doubly-linked list of modes.
+ */
+void
+xf86ValidateModesSync(ScrnInfoPtr pScrn, DisplayModePtr modeList,
+ MonPtr mon)
+{
+ DisplayModePtr mode;
+
+ for (mode = modeList; mode != NULL; mode = mode->next) {
+ Bool bad;
+ int i;
+
+ bad = TRUE;
+ for (i = 0; i < mon->nHsync; i++) {
+ if (xf86ModeHSync(mode) >= mon->hsync[i].lo * (1-SYNC_TOLERANCE) &&
+ xf86ModeHSync(mode) <= mon->hsync[i].hi * (1+SYNC_TOLERANCE))
+ {
+ bad = FALSE;
+ }
+ }
+ if (bad)
+ mode->status = MODE_HSYNC;
+
+ bad = TRUE;
+ for (i = 0; i < mon->nVrefresh; i++) {
+ if (xf86ModeVRefresh(mode) >= mon->vrefresh[i].lo * (1-SYNC_TOLERANCE) &&
+ xf86ModeVRefresh(mode) <= mon->vrefresh[i].hi * (1+SYNC_TOLERANCE))
+ {
+ bad = FALSE;
+ }
+ }
+ if (bad)
+ mode->status = MODE_VSYNC;
+
+ if (mode->next == modeList)
+ break;
+ }
+}
+
+/**
+ * Marks as bad any modes extending beyond outside of the given clock ranges.
+ *
+ * \param modeList doubly-linked list of modes.
+ * \param min pointer to minimums of clock ranges
+ * \param max pointer to maximums of clock ranges
+ * \param n_ranges number of ranges.
+ */
+void
+xf86ValidateModesClocks(ScrnInfoPtr pScrn, DisplayModePtr modeList,
+ int *min, int *max, int n_ranges)
+{
+ DisplayModePtr mode;
+ int i;
+
+ for (mode = modeList; mode != NULL; mode = mode->next) {
+ Bool good = FALSE;
+ for (i = 0; i < n_ranges; i++) {
+ if (mode->Clock >= min[i] * (1-SYNC_TOLERANCE) &&
+ mode->Clock <= max[i] * (1+SYNC_TOLERANCE)) {
+ good = TRUE;
+ break;
+ }
+ }
+ if (!good)
+ mode->status = MODE_CLOCK_RANGE;
+ }
+}
+
+/**
+ * If the user has specified a set of mode names to use, mark as bad any modes
+ * not listed.
+ *
+ * The user mode names specified are prefixes to names of modes, so "1024x768"
+ * will match modes named "1024x768", "1024x768x75", "1024x768-good", but
+ * "1024x768x75" would only match "1024x768x75" from that list.
+ *
+ * MODE_BAD is used as the rejection flag, for lack of a better flag.
+ *
+ * \param modeList doubly-linked list of modes.
+ */
+void
+xf86ValidateModesUserConfig(ScrnInfoPtr pScrn, DisplayModePtr modeList)
+{
+ DisplayModePtr mode;
+
+ if (pScrn->display->modes[0] == NULL)
+ return;
+
+ for (mode = modeList; mode != NULL; mode = mode->next) {
+ int i;
+ Bool good = FALSE;
+
+ for (i = 0; pScrn->display->modes[i] != NULL; i++) {
+ if (strncmp(pScrn->display->modes[i], mode->name,
+ strlen(pScrn->display->modes[i])) == 0) {
+ good = TRUE;
+ break;
+ }
+ }
+ if (!good)
+ mode->status = MODE_BAD;
+ }
+}
+
+
+/**
+ * Marks as bad any modes exceeding the given bandwidth.
+ *
+ * \param modeList doubly-linked list of modes.
+ * \param bandwidth bandwidth in MHz.
+ * \param depth color depth.
+ */
+void
+xf86ValidateModesBandwidth(ScrnInfoPtr pScrn, DisplayModePtr modeList,
+ unsigned int bandwidth, int depth)
+{
+ DisplayModePtr mode;
+
+ for (mode = modeList; mode != NULL; mode = mode->next) {
+ if (xf86ModeBandwidth(mode, depth) > bandwidth)
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
+ mode->status = MODE_BANDWIDTH;
+#else
+ /* MODE_BANDWIDTH didn't exist in xserver 1.2 */
+ mode->status = MODE_BAD;
+#endif
+ }
+}
+
+Bool
+xf86ModeIsReduced(const DisplayModeRec *mode)
+{
+ if ((((mode->HDisplay * 5 / 4) & ~0x07) > mode->HTotal) &&
+ ((mode->HTotal - mode->HDisplay) == 160) &&
+ ((mode->HSyncEnd - mode->HDisplay) == 80) &&
+ ((mode->HSyncEnd - mode->HSyncStart) == 32) &&
+ ((mode->VSyncStart - mode->VDisplay) == 3))
+ return TRUE;
+ return FALSE;
+}
+
+/**
+ * Marks as bad any reduced-blanking modes.
+ *
+ * \param modeList doubly-linked list of modes.
+ */
+void
+xf86ValidateModesReducedBlanking(ScrnInfoPtr pScrn, DisplayModePtr modeList)
+{
+ for (; modeList != NULL; modeList = modeList->next)
+ if (xf86ModeIsReduced(modeList))
+ modeList->status = MODE_NO_REDUCED;
+}
+
+/**
+ * Frees any modes from the list with a status other than MODE_OK.
+ *
+ * \param modeList pointer to a doubly-linked or circular list of modes.
+ * \param verbose determines whether the reason for mode invalidation is
+ * printed.
+ */
+void
+xf86PruneInvalidModes(ScrnInfoPtr pScrn, DisplayModePtr *modeList,
+ Bool verbose)
+{
+ DisplayModePtr mode;
+
+ for (mode = *modeList; mode != NULL;) {
+ DisplayModePtr next = mode->next, first = *modeList;
+
+ if (mode->status != MODE_OK) {
+ if (verbose) {
+ char *type = "";
+ if (mode->type & M_T_BUILTIN)
+ type = "built-in ";
+ else if (mode->type & M_T_DEFAULT)
+ type = "default ";
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Not using %smode \"%s\" (%s)\n", type, mode->name,
+ xf86ModeStatusToString(mode->status));
+ }
+ xf86DeleteMode(modeList, mode);
+ }
+
+ if (next == first)
+ break;
+ mode = next;
+ }
+}
+
+/**
+ * Adds the new mode into the mode list, and returns the new list
+ *
+ * \param modes doubly-linked mode list.
+ */
+DisplayModePtr
+xf86ModesAdd(DisplayModePtr modes, DisplayModePtr new)
+{
+ if (modes == NULL)
+ return new;
+
+ if (new) {
+ DisplayModePtr mode = modes;
+
+ while (mode->next)
+ mode = mode->next;
+
+ mode->next = new;
+ new->prev = mode;
+ }
+
+ return modes;
+}
+
+/**
+ * Build a mode list from a list of config file modes
+ */
+static DisplayModePtr
+xf86GetConfigModes (XF86ConfModeLinePtr conf_mode)
+{
+ DisplayModePtr head = NULL, prev = NULL, mode;
+
+ for (; conf_mode; conf_mode = (XF86ConfModeLinePtr) conf_mode->list.next)
+ {
+ mode = calloc(1, sizeof(DisplayModeRec));
+ if (!mode)
+ continue;
+ mode->name = xstrdup(conf_mode->ml_identifier);
+ if (!mode->name)
+ {
+ free(mode);
+ continue;
+ }
+ mode->type = 0;
+ mode->Clock = conf_mode->ml_clock;
+ mode->HDisplay = conf_mode->ml_hdisplay;
+ mode->HSyncStart = conf_mode->ml_hsyncstart;
+ mode->HSyncEnd = conf_mode->ml_hsyncend;
+ mode->HTotal = conf_mode->ml_htotal;
+ mode->VDisplay = conf_mode->ml_vdisplay;
+ mode->VSyncStart = conf_mode->ml_vsyncstart;
+ mode->VSyncEnd = conf_mode->ml_vsyncend;
+ mode->VTotal = conf_mode->ml_vtotal;
+ mode->Flags = conf_mode->ml_flags;
+ mode->HSkew = conf_mode->ml_hskew;
+ mode->VScan = conf_mode->ml_vscan;
+
+ mode->prev = prev;
+ mode->next = NULL;
+ if (prev)
+ prev->next = mode;
+ else
+ head = mode;
+ prev = mode;
+ }
+ return head;
+}
+
+/**
+ * Build a mode list from a monitor configuration
+ */
+DisplayModePtr
+xf86GetMonitorModes (ScrnInfoPtr pScrn, XF86ConfMonitorPtr conf_monitor)
+{
+ DisplayModePtr modes = NULL;
+ XF86ConfModesLinkPtr modes_link;
+
+ if (!conf_monitor)
+ return NULL;
+
+ /*
+ * first we collect the mode lines from the UseModes directive
+ */
+ for (modes_link = conf_monitor->mon_modes_sect_lst;
+ modes_link;
+ modes_link = modes_link->list.next)
+ {
+ /* If this modes link hasn't been resolved, go look it up now */
+ if (!modes_link->ml_modes)
+ modes_link->ml_modes = xf86findModes (modes_link->ml_modes_str,
+ xf86configptr->conf_modes_lst);
+ if (modes_link->ml_modes)
+ modes = xf86ModesAdd (modes,
+ xf86GetConfigModes (modes_link->ml_modes->mon_modeline_lst));
+ }
+
+ return xf86ModesAdd (modes,
+ xf86GetConfigModes (conf_monitor->mon_modeline_lst));
+}
+
+/**
+ * Build a mode list containing all of the default modes
+ */
+DisplayModePtr
+xf86GetDefaultModes (void)
+{
+ DisplayModePtr head = NULL, mode;
+ int i;
+
+ for (i = 0; i < xf86NumDefaultModes; i++)
+ {
+ const DisplayModeRec *defMode = &xf86DefaultModes[i];
+
+ mode = xf86DuplicateMode(defMode);
+ head = xf86ModesAdd(head, mode);
+ }
+ return head;
+}
+
+/*
+ * Walk a mode list and prune out duplicates. Will preserve the preferred
+ * mode of an otherwise-duplicate pair.
+ *
+ * Probably best to call this on lists that are all of a single class
+ * (driver, default, user, etc.), otherwise, which mode gets deleted is
+ * not especially well defined.
+ *
+ * Returns the new list.
+ */
+
+DisplayModePtr
+xf86PruneDuplicateModes(DisplayModePtr modes)
+{
+ DisplayModePtr m, n, o;
+
+top:
+ for (m = modes; m; m = m->next) {
+ for (n = m->next; n; n = o) {
+ o = n->next;
+ if (xf86ModesEqual(m, n)) {
+ if (n->type & M_T_PREFERRED) {
+ xf86DeleteMode(&modes, m);
+ goto top;
+ }
+ else
+ xf86DeleteMode(&modes, n);
+ }
+ }
+ }
+
+ return modes;
+}
diff --git a/xorg-server/hw/xfree86/modes/xf86RandR12.c b/xorg-server/hw/xfree86/modes/xf86RandR12.c
index 8898f4dad..8a4d72bd6 100644
--- a/xorg-server/hw/xfree86/modes/xf86RandR12.c
+++ b/xorg-server/hw/xfree86/modes/xf86RandR12.c
@@ -1,1810 +1,1810 @@
-/*
- * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that copyright
- * notice and this permission notice appear in supporting documentation, and
- * that the name of the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. The copyright holders make no representations
- * about the suitability of this software for any purpose. It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS 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>
-#else
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#endif
-
-#include "xf86.h"
-#include "os.h"
-#include "globals.h"
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86DDC.h"
-#include "mipointer.h"
-#include "windowstr.h"
-#include "inputstr.h"
-#include <randrstr.h>
-#include <X11/extensions/render.h>
-
-#include "xf86Crtc.h"
-#include "xf86RandR12.h"
-
-typedef struct _xf86RandR12Info {
- int virtualX;
- int virtualY;
- int mmWidth;
- int mmHeight;
- int maxX;
- int maxY;
- int pointerX;
- int pointerY;
- Rotation rotation; /* current mode */
- Rotation supported_rotations; /* driver supported */
-
- /* Used to wrap EnterVT so we can re-probe the outputs when a laptop unsuspends
- * (actually, any time that we switch back into our VT).
- *
- * See https://bugs.freedesktop.org/show_bug.cgi?id=21554
- */
- xf86EnterVTProc *orig_EnterVT;
-} XF86RandRInfoRec, *XF86RandRInfoPtr;
-
-#ifdef RANDR_12_INTERFACE
-static Bool xf86RandR12Init12 (ScreenPtr pScreen);
-static Bool xf86RandR12CreateScreenResources12 (ScreenPtr pScreen);
-#endif
-
-static int xf86RandR12Generation;
-#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
-
-static int xf86RandR12KeyIndex;
-static DevPrivateKey xf86RandR12Key;
-#define XF86RANDRINFO(p) ((XF86RandRInfoPtr) \
- dixLookupPrivate(&(p)->devPrivates, xf86RandR12Key))
-
-#else /* XORG_VERSION_CURRENT < 7.0 */
-
-static int xf86RandR12Index;
-#define XF86RANDRINFO(p) \
- ((XF86RandRInfoPtr)(p)->devPrivates[xf86RandR12Index].ptr)
-
-#endif /* XORG_VERSION_CURRENT < 7.0 */
-
-
-static int
-xf86RandR12ModeRefresh (DisplayModePtr mode)
-{
- if (mode->VRefresh)
- return (int) (mode->VRefresh + 0.5);
- else
- return (int) (mode->Clock * 1000.0 / mode->HTotal / mode->VTotal + 0.5);
-}
-
-/* Adapt panning area; return TRUE if panning area was valid without adaption */
-static int
-xf86RandR13VerifyPanningArea (xf86CrtcPtr crtc, int screenWidth, int screenHeight)
-{
- int ret = TRUE;
-
- if (crtc->version < 2)
- return FALSE;
-
- if (crtc->panningTotalArea.x2 <= crtc->panningTotalArea.x1) {
- /* Panning in X is disabled */
- if (crtc->panningTotalArea.x1 || crtc->panningTotalArea.x2)
- /* Illegal configuration -> fail/disable */
- ret = FALSE;
- crtc->panningTotalArea.x1 = crtc->panningTotalArea.x2 = 0;
- crtc->panningTrackingArea.x1 = crtc->panningTrackingArea.x2 = 0;
- crtc->panningBorder[0] = crtc->panningBorder[2] = 0;
- } else {
- /* Panning in X is enabled */
- if (crtc->panningTotalArea.x1 < 0) {
- /* Panning region outside screen -> move inside */
- crtc->panningTotalArea.x2 -= crtc->panningTotalArea.x1;
- crtc->panningTotalArea.x1 = 0;
- ret = FALSE;
- }
- if (crtc->panningTotalArea.x2 < crtc->panningTotalArea.x1 + crtc->mode.HDisplay) {
- /* Panning region smaller than displayed area -> crop to displayed area */
- crtc->panningTotalArea.x2 = crtc->panningTotalArea.x1 + crtc->mode.HDisplay;
- ret = FALSE;
- }
- if (crtc->panningTotalArea.x2 > screenWidth) {
- /* Panning region larger than screen -> move inside, then crop to screen */
- crtc->panningTotalArea.x1 -= crtc->panningTotalArea.x2 - screenWidth;
- crtc->panningTotalArea.x2 = screenWidth;
- ret = FALSE;
- if (crtc->panningTotalArea.x1 < 0)
- crtc->panningTotalArea.x1 = 0;
- }
- if (crtc->panningBorder[0] + crtc->panningBorder[2] > crtc->mode.HDisplay) {
- /* Borders too large -> set to 0 */
- crtc->panningBorder[0] = crtc->panningBorder[2] = 0;
- ret = FALSE;
- }
- }
-
- if (crtc->panningTotalArea.y2 <= crtc->panningTotalArea.y1) {
- /* Panning in Y is disabled */
- if (crtc->panningTotalArea.y1 || crtc->panningTotalArea.y2)
- /* Illegal configuration -> fail/disable */
- ret = FALSE;
- crtc->panningTotalArea.y1 = crtc->panningTotalArea.y2 = 0;
- crtc->panningTrackingArea.y1 = crtc->panningTrackingArea.y2 = 0;
- crtc->panningBorder[1] = crtc->panningBorder[3] = 0;
- } else {
- /* Panning in Y is enabled */
- if (crtc->panningTotalArea.y1 < 0) {
- /* Panning region outside screen -> move inside */
- crtc->panningTotalArea.y2 -= crtc->panningTotalArea.y1;
- crtc->panningTotalArea.y1 = 0;
- ret = FALSE;
- }
- if (crtc->panningTotalArea.y2 < crtc->panningTotalArea.y1 + crtc->mode.VDisplay) {
- /* Panning region smaller than displayed area -> crop to displayed area */
- crtc->panningTotalArea.y2 = crtc->panningTotalArea.y1 + crtc->mode.VDisplay;
- ret = FALSE;
- }
- if (crtc->panningTotalArea.y2 > screenHeight) {
- /* Panning region larger than screen -> move inside, then crop to screen */
- crtc->panningTotalArea.y1 -= crtc->panningTotalArea.y2 - screenHeight;
- crtc->panningTotalArea.y2 = screenHeight;
- ret = FALSE;
- if (crtc->panningTotalArea.y1 < 0)
- crtc->panningTotalArea.y1 = 0;
- }
- if (crtc->panningBorder[1] + crtc->panningBorder[3] > crtc->mode.VDisplay) {
- /* Borders too large -> set to 0 */
- crtc->panningBorder[1] = crtc->panningBorder[3] = 0;
- ret = FALSE;
- }
- }
-
- return ret;
-}
-
-/*
- * The heart of the panning operation:
- *
- * Given a frame buffer position (fb_x, fb_y),
- * and a crtc position (crtc_x, crtc_y),
- * and a transform matrix which maps frame buffer to crtc,
- * compute a panning position (pan_x, pan_y) that
- * makes the resulting transform line those two up
- */
-
-static void
-xf86ComputeCrtcPan (Bool transform_in_use,
- struct pixman_f_transform *m,
- double screen_x, double screen_y,
- double crtc_x, double crtc_y,
- int old_pan_x, int old_pan_y,
- int *new_pan_x, int *new_pan_y)
-{
- if (transform_in_use) {
- /*
- * Given the current transform, M, the current position
- * on the Screen, S, and the desired position on the CRTC,
- * C, compute a translation, T, such that:
- *
- * M T S = C
- *
- * where T is of the form
- *
- * | 1 0 dx |
- * | 0 1 dy |
- * | 0 0 1 |
- *
- * M T S =
- * | M00 Sx + M01 Sy + M00 dx + M01 dy + M02 | | Cx F |
- * | M10 Sx + M11 Sy + M10 dx + M11 dy + M12 | = | Cy F |
- * | M20 Sx + M21 Sy + M20 dx + M21 dy + M22 | | F |
- *
- * R = M S
- *
- * Cx F = M00 dx + M01 dy + R0
- * Cy F = M10 dx + M11 dy + R1
- * F = M20 dx + M21 dy + R2
- *
- * Zero out dx, then dy
- *
- * F (Cx M10 - Cy M00) =
- * (M10 M01 - M00 M11) dy + M10 R0 - M00 R1
- * F (M10 - Cy M20) =
- * (M10 M21 - M20 M11) dy + M10 R2 - M20 R1
- *
- * F (Cx M11 - Cy M01) =
- * (M11 M00 - M01 M10) dx + M11 R0 - M01 R1
- * F (M11 - Cy M21) =
- * (M11 M20 - M21 M10) dx + M11 R2 - M21 R1
- *
- * Make some temporaries
- *
- * T = | Cx M10 - Cy M00 |
- * | Cx M11 - Cy M01 |
- *
- * U = | M10 M01 - M00 M11 |
- * | M11 M00 - M01 M10 |
- *
- * Q = | M10 R0 - M00 R1 |
- * | M11 R0 - M01 R1 |
- *
- * P = | M10 - Cy M20 |
- * | M11 - Cy M21 |
- *
- * W = | M10 M21 - M20 M11 |
- * | M11 M20 - M21 M10 |
- *
- * V = | M10 R2 - M20 R1 |
- * | M11 R2 - M21 R1 |
- *
- * Rewrite:
- *
- * F T0 = U0 dy + Q0
- * F P0 = W0 dy + V0
- * F T1 = U1 dx + Q1
- * F P1 = W1 dx + V1
- *
- * Solve for F (two ways)
- *
- * F (W0 T0 - U0 P0) = W0 Q0 - U0 V0
- *
- * W0 Q0 - U0 V0
- * F = -------------
- * W0 T0 - U0 P0
- *
- * F (W1 T1 - U1 P1) = W1 Q1 - U1 V1
- *
- * W1 Q1 - U1 V1
- * F = -------------
- * W1 T1 - U1 P1
- *
- * We'll use which ever solution works (denominator != 0)
- *
- * Finally, solve for dx and dy:
- *
- * dx = (F T1 - Q1) / U1
- * dx = (F P1 - V1) / W1
- *
- * dy = (F T0 - Q0) / U0
- * dy = (F P0 - V0) / W0
- */
- double r[3];
- double q[2], u[2], t[2], v[2], w[2], p[2];
- double f;
- struct pict_f_vector d;
- int i;
-
- /* Get the un-normalized crtc coordinates again */
- for (i = 0; i < 3; i++)
- r[i] = m->m[i][0] * screen_x + m->m[i][1] * screen_y + m->m[i][2];
-
- /* Combine values into temporaries */
- for (i = 0; i < 2; i++) {
- q[i] = m->m[1][i] * r[0] - m->m[0][i] * r[1];
- u[i] = m->m[1][i] * m->m[0][1-i] - m->m[0][i] * m->m[1][1-i];
- t[i] = m->m[1][i] * crtc_x - m->m[0][i] * crtc_y;
-
- v[i] = m->m[1][i] * r[2] - m->m[2][i] * r[1];
- w[i] = m->m[1][i] * m->m[2][1-i] - m->m[2][i] * m->m[1][1-i];
- p[i] = m->m[1][i] - m->m[2][i] * crtc_y;
- }
-
- /* Find a way to compute f */
- f = 0;
- for (i = 0; i < 2; i++) {
- double a = w[i] * q[i] - u[i] * v[i];
- double b = w[i] * t[i] - u[i] * p[i];
- if (b != 0) {
- f = a/b;
- break;
- }
- }
-
- /* Solve for the resulting transform vector */
- for (i = 0; i < 2; i++) {
- if (u[i])
- d.v[1-i] = (t[i] * f - q[i]) / u[i];
- else if (w[1])
- d.v[1-i] = (p[i] * f - v[i]) / w[i];
- else
- d.v[1-i] = 0;
- }
- *new_pan_x = old_pan_x - floor (d.v[0] + 0.5);
- *new_pan_y = old_pan_y - floor (d.v[1] + 0.5);
- } else {
- *new_pan_x = screen_x - crtc_x;
- *new_pan_y = screen_y - crtc_y;
- }
-}
-
-static void
-xf86RandR13Pan (xf86CrtcPtr crtc, int x, int y)
-{
- int newX, newY;
- int width, height;
- Bool panned = FALSE;
-
- if (crtc->version < 2)
- return;
-
- if (! crtc->enabled ||
- (crtc->panningTotalArea.x2 <= crtc->panningTotalArea.x1 &&
- crtc->panningTotalArea.y2 <= crtc->panningTotalArea.y1))
- return;
-
- newX = crtc->x;
- newY = crtc->y;
- width = crtc->mode.HDisplay;
- height = crtc->mode.VDisplay;
-
- if ((crtc->panningTrackingArea.x2 <= crtc->panningTrackingArea.x1 ||
- (x >= crtc->panningTrackingArea.x1 && x < crtc->panningTrackingArea.x2)) &&
- (crtc->panningTrackingArea.y2 <= crtc->panningTrackingArea.y1 ||
- (y >= crtc->panningTrackingArea.y1 && y < crtc->panningTrackingArea.y2)))
- {
- struct pict_f_vector c;
-
- /*
- * Pre-clip the mouse position to the panning area so that we don't
- * push the crtc outside. This doesn't deal with changes to the
- * panning values, only mouse position changes.
- */
- if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1)
- {
- if (x < crtc->panningTotalArea.x1)
- x = crtc->panningTotalArea.x1;
- if (x >= crtc->panningTotalArea.x2)
- x = crtc->panningTotalArea.x2 - 1;
- }
- if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1)
- {
- if (y < crtc->panningTotalArea.y1)
- y = crtc->panningTotalArea.y1;
- if (y >= crtc->panningTotalArea.y2)
- y = crtc->panningTotalArea.y2 - 1;
- }
-
- c.v[0] = x;
- c.v[1] = y;
- c.v[2] = 1.0;
- if (crtc->transform_in_use) {
- pixman_f_transform_point(&crtc->f_framebuffer_to_crtc, &c);
- } else {
- c.v[0] -= crtc->x;
- c.v[1] -= crtc->y;
- }
-
- if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1) {
- if (c.v[0] < crtc->panningBorder[0]) {
- c.v[0] = crtc->panningBorder[0];
- panned = TRUE;
- }
- if (c.v[0] >= width - crtc->panningBorder[2]) {
- c.v[0] = width - crtc->panningBorder[2] - 1;
- panned = TRUE;
- }
- }
- if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) {
- if (c.v[1] < crtc->panningBorder[1]) {
- c.v[1] = crtc->panningBorder[1];
- panned = TRUE;
- }
- if (c.v[1] >= height - crtc->panningBorder[3]) {
- c.v[1] = height - crtc->panningBorder[3] - 1;
- panned = TRUE;
- }
- }
- if (panned)
- xf86ComputeCrtcPan (crtc->transform_in_use,
- &crtc->f_framebuffer_to_crtc,
- x, y, c.v[0], c.v[1],
- newX, newY, &newX, &newY);
- }
-
- /*
- * Ensure that the crtc is within the panning region.
- *
- * XXX This computation only works when we do not have a transform
- * in use.
- */
- if (!crtc->transform_in_use)
- {
- /* Validate against [xy]1 after [xy]2, to be sure that results are > 0 for [xy]1 > 0 */
- if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1) {
- if (newX > crtc->panningTotalArea.x2 - width)
- newX = crtc->panningTotalArea.x2 - width;
- if (newX < crtc->panningTotalArea.x1)
- newX = crtc->panningTotalArea.x1;
- }
- if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) {
- if (newY > crtc->panningTotalArea.y2 - height)
- newY = crtc->panningTotalArea.y2 - height;
- if (newY < crtc->panningTotalArea.y1)
- newY = crtc->panningTotalArea.y1;
- }
- }
- if (newX != crtc->x || newY != crtc->y)
- xf86CrtcSetOrigin (crtc, newX, newY);
-}
-
-static Bool
-xf86RandR12GetInfo (ScreenPtr pScreen, Rotation *rotations)
-{
- RRScreenSizePtr pSize;
- ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- DisplayModePtr mode;
- int refresh0 = 60;
- int maxX = 0, maxY = 0;
-
- *rotations = randrp->supported_rotations;
-
- if (randrp->virtualX == -1 || randrp->virtualY == -1)
- {
- randrp->virtualX = scrp->virtualX;
- randrp->virtualY = scrp->virtualY;
- }
-
- /* Re-probe the outputs for new monitors or modes */
- if (scrp->vtSema)
- {
- xf86ProbeOutputModes (scrp, 0, 0);
- xf86SetScrnInfoModes (scrp);
- }
-
- for (mode = scrp->modes; ; mode = mode->next)
- {
- int refresh = xf86RandR12ModeRefresh (mode);
- if (randrp->maxX == 0 || randrp->maxY == 0)
- {
- if (maxX < mode->HDisplay)
- maxX = mode->HDisplay;
- if (maxY < mode->VDisplay)
- maxY = mode->VDisplay;
- }
- if (mode == scrp->modes)
- refresh0 = refresh;
- pSize = RRRegisterSize (pScreen,
- mode->HDisplay, mode->VDisplay,
- randrp->mmWidth, randrp->mmHeight);
- if (!pSize)
- return FALSE;
- RRRegisterRate (pScreen, pSize, refresh);
-
- if (xf86ModesEqual(mode, scrp->currentMode))
- {
- RRSetCurrentConfig (pScreen, randrp->rotation, refresh, pSize);
- }
- if (mode->next == scrp->modes)
- break;
- }
-
- if (randrp->maxX == 0 || randrp->maxY == 0)
- {
- randrp->maxX = maxX;
- randrp->maxY = maxY;
- }
-
- return TRUE;
-}
-
-static Bool
-xf86RandR12SetMode (ScreenPtr pScreen,
- DisplayModePtr mode,
- Bool useVirtual,
- int mmWidth,
- int mmHeight)
-{
- ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- int oldWidth = pScreen->width;
- int oldHeight = pScreen->height;
- int oldmmWidth = pScreen->mmWidth;
- int oldmmHeight = pScreen->mmHeight;
- WindowPtr pRoot = WindowTable[pScreen->myNum];
- DisplayModePtr currentMode = NULL;
- Bool ret = TRUE;
- PixmapPtr pspix = NULL;
-
- if (pRoot)
- (*scrp->EnableDisableFBAccess) (pScreen->myNum, FALSE);
- if (useVirtual)
- {
- scrp->virtualX = randrp->virtualX;
- scrp->virtualY = randrp->virtualY;
- }
- else
- {
- scrp->virtualX = mode->HDisplay;
- scrp->virtualY = mode->VDisplay;
- }
-
- if(randrp->rotation & (RR_Rotate_90 | RR_Rotate_270))
- {
- /* If the screen is rotated 90 or 270 degrees, swap the sizes. */
- pScreen->width = scrp->virtualY;
- pScreen->height = scrp->virtualX;
- pScreen->mmWidth = mmHeight;
- pScreen->mmHeight = mmWidth;
- }
- else
- {
- pScreen->width = scrp->virtualX;
- pScreen->height = scrp->virtualY;
- pScreen->mmWidth = mmWidth;
- pScreen->mmHeight = mmHeight;
- }
- if (scrp->currentMode == mode) {
- /* Save current mode */
- currentMode = scrp->currentMode;
- /* Reset, just so we ensure the drivers SwitchMode is called */
- scrp->currentMode = NULL;
- }
- /*
- * We know that if the driver failed to SwitchMode to the rotated
- * version, then it should revert back to it's prior mode.
- */
- if (!xf86SwitchMode (pScreen, mode))
- {
- ret = FALSE;
- scrp->virtualX = pScreen->width = oldWidth;
- scrp->virtualY = pScreen->height = oldHeight;
- pScreen->mmWidth = oldmmWidth;
- pScreen->mmHeight = oldmmHeight;
- scrp->currentMode = currentMode;
- }
- /*
- * Get the new Screen pixmap ptr as SwitchMode might have called
- * ModifyPixmapHeader and xf86EnableDisableFBAccess will put it back...
- * Unfortunately.
- */
- pspix = (*pScreen->GetScreenPixmap) (pScreen);
- if (pspix->devPrivate.ptr)
- scrp->pixmapPrivate = pspix->devPrivate;
-
- /*
- * Make sure the layout is correct
- */
- xf86ReconfigureLayout();
-
- /*
- * Make sure the whole screen is visible
- */
- xf86SetViewport (pScreen, pScreen->width, pScreen->height);
- xf86SetViewport (pScreen, 0, 0);
- if (pRoot)
- (*scrp->EnableDisableFBAccess) (pScreen->myNum, TRUE);
- return ret;
-}
-
-Bool
-xf86RandR12SetConfig (ScreenPtr pScreen,
- Rotation rotation,
- int rate,
- RRScreenSizePtr pSize)
-{
- ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- DisplayModePtr mode;
- int px, py;
- Bool useVirtual = FALSE;
- int maxX = 0, maxY = 0;
- Rotation oldRotation = randrp->rotation;
-
- randrp->rotation = rotation;
-
- if (randrp->virtualX == -1 || randrp->virtualY == -1)
- {
- randrp->virtualX = scrp->virtualX;
- randrp->virtualY = scrp->virtualY;
- }
-
- miPointerGetPosition (inputInfo.pointer, &px, &py);
- for (mode = scrp->modes; ; mode = mode->next)
- {
- if (randrp->maxX == 0 || randrp->maxY == 0)
- {
- if (maxX < mode->HDisplay)
- maxX = mode->HDisplay;
- if (maxY < mode->VDisplay)
- maxY = mode->VDisplay;
- }
- if (mode->HDisplay == pSize->width &&
- mode->VDisplay == pSize->height &&
- (rate == 0 || xf86RandR12ModeRefresh (mode) == rate))
- break;
- if (mode->next == scrp->modes)
- {
- if (pSize->width == randrp->virtualX &&
- pSize->height == randrp->virtualY)
- {
- mode = scrp->modes;
- useVirtual = TRUE;
- break;
- }
- if (randrp->maxX == 0 || randrp->maxY == 0)
- {
- randrp->maxX = maxX;
- randrp->maxY = maxY;
- }
- return FALSE;
- }
- }
-
- if (randrp->maxX == 0 || randrp->maxY == 0)
- {
- randrp->maxX = maxX;
- randrp->maxY = maxY;
- }
-
- if (!xf86RandR12SetMode (pScreen, mode, useVirtual, pSize->mmWidth,
- pSize->mmHeight)) {
- randrp->rotation = oldRotation;
- return FALSE;
- }
-
- /*
- * Move the cursor back where it belongs; SwitchMode repositions it
- */
- if (pScreen == miPointerGetScreen(inputInfo.pointer))
- {
- px = (px >= pScreen->width ? (pScreen->width - 1) : px);
- py = (py >= pScreen->height ? (pScreen->height - 1) : py);
-
- xf86SetViewport(pScreen, px, py);
-
- (*pScreen->SetCursorPosition) (inputInfo.pointer, pScreen, px, py, FALSE);
- }
-
- return TRUE;
-}
-
-static Bool
-xf86RandR12ScreenSetSize (ScreenPtr pScreen,
- CARD16 width,
- CARD16 height,
- CARD32 mmWidth,
- CARD32 mmHeight)
-{
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen);
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- WindowPtr pRoot = WindowTable[pScreen->myNum];
- PixmapPtr pScrnPix = (*pScreen->GetScreenPixmap)(pScreen);
- Bool ret = FALSE;
- int c;
-
-#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
- if (xf86RandR12Key) {
-#endif
- if (randrp->virtualX == -1 || randrp->virtualY == -1)
- {
- randrp->virtualX = pScrn->virtualX;
- randrp->virtualY = pScrn->virtualY;
- }
-#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
- }
-#endif
- if (pRoot && pScrn->vtSema)
- (*pScrn->EnableDisableFBAccess) (pScreen->myNum, FALSE);
-
- /* Let the driver update virtualX and virtualY */
- if (!(*config->funcs->resize)(pScrn, width, height))
- goto finish;
-
- ret = TRUE;
- /* Update panning information */
- for (c = 0; c < config->num_crtc; c++) {
- xf86CrtcPtr crtc = config->crtc[c];
- if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1 ||
- crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) {
- if (crtc->panningTotalArea.x2 > crtc->panningTrackingArea.x1)
- crtc->panningTotalArea.x2 += width - pScreen->width;
- if (crtc->panningTotalArea.y2 > crtc->panningTrackingArea.y1)
- crtc->panningTotalArea.y2 += height - pScreen->height;
- if (crtc->panningTrackingArea.x2 > crtc->panningTrackingArea.x1)
- crtc->panningTrackingArea.x2 += width - pScreen->width;
- if (crtc->panningTrackingArea.y2 > crtc->panningTrackingArea.y1)
- crtc->panningTrackingArea.y2 += height - pScreen->height;
- xf86RandR13VerifyPanningArea (crtc, width, height);
- xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
- }
- }
-
- pScreen->width = pScrnPix->drawable.width = width;
- pScreen->height = pScrnPix->drawable.height = height;
- randrp->mmWidth = pScreen->mmWidth = mmWidth;
- randrp->mmHeight = pScreen->mmHeight = mmHeight;
-
- xf86SetViewport (pScreen, pScreen->width-1, pScreen->height-1);
- xf86SetViewport (pScreen, 0, 0);
-
-finish:
- if (pRoot && pScrn->vtSema)
- (*pScrn->EnableDisableFBAccess) (pScreen->myNum, TRUE);
-#if RANDR_12_INTERFACE
- if (xf86RandR12Key && WindowTable[pScreen->myNum] && ret)
- RRScreenSizeNotify (pScreen);
-#endif
- return ret;
-}
-
-Rotation
-xf86RandR12GetRotation(ScreenPtr pScreen)
-{
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
-
- return randrp->rotation;
-}
-
-Bool
-xf86RandR12CreateScreenResources (ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr config;
- XF86RandRInfoPtr randrp;
- int c;
- int width, height;
- int mmWidth, mmHeight;
-#ifdef PANORAMIX
- /* XXX disable RandR when using Xinerama */
- if (!noPanoramiXExtension)
- return TRUE;
-#endif
-
- config = XF86_CRTC_CONFIG_PTR(pScrn);
- randrp = XF86RANDRINFO(pScreen);
- /*
- * Compute size of screen
- */
- width = 0; height = 0;
- for (c = 0; c < config->num_crtc; c++)
- {
- xf86CrtcPtr crtc = config->crtc[c];
- int crtc_width = crtc->x + xf86ModeWidth (&crtc->mode, crtc->rotation);
- int crtc_height = crtc->y + xf86ModeHeight (&crtc->mode, crtc->rotation);
-
- if (crtc->enabled) {
- if (crtc_width > width)
- width = crtc_width;
- if (crtc_height > height)
- height = crtc_height;
- if (crtc->panningTotalArea.x2 > width)
- width = crtc->panningTotalArea.x2;
- if (crtc->panningTotalArea.y2 > height)
- height = crtc->panningTotalArea.y2;
- }
- }
-
- if (width && height)
- {
- /*
- * Compute physical size of screen
- */
- if (monitorResolution)
- {
- mmWidth = width * 25.4 / monitorResolution;
- mmHeight = height * 25.4 / monitorResolution;
- }
- else
- {
- xf86OutputPtr output = xf86CompatOutput(pScrn);
-
- if (output &&
- output->conf_monitor &&
- (output->conf_monitor->mon_width > 0 &&
- output->conf_monitor->mon_height > 0))
- {
- /*
- * Prefer user configured DisplaySize
- */
- mmWidth = output->conf_monitor->mon_width;
- mmHeight = output->conf_monitor->mon_height;
- }
- else
- {
- /*
- * Otherwise, just set the screen to DEFAULT_DPI
- */
- mmWidth = width * 25.4 / DEFAULT_DPI;
- mmHeight = height * 25.4 / DEFAULT_DPI;
- }
- }
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Setting screen physical size to %d x %d\n",
- mmWidth, mmHeight);
- /*
- * This is the initial setting of the screen size.
- * We have to pre-set it here, otherwise panning would be adapted
- * to the new screen size.
- */
- pScreen->width = width;
- pScreen->height = height;
- xf86RandR12ScreenSetSize (pScreen,
- width,
- height,
- mmWidth,
- mmHeight);
- }
-
-#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
- if (xf86RandR12Key == NULL)
- return TRUE;
-#endif
-
- if (randrp->virtualX == -1 || randrp->virtualY == -1)
- {
- randrp->virtualX = pScrn->virtualX;
- randrp->virtualY = pScrn->virtualY;
- }
- xf86CrtcSetScreenSubpixelOrder (pScreen);
-#if RANDR_12_INTERFACE
- if (xf86RandR12CreateScreenResources12 (pScreen))
- return TRUE;
-#endif
- return TRUE;
-}
-
-
-Bool
-xf86RandR12Init (ScreenPtr pScreen)
-{
- rrScrPrivPtr rp;
- XF86RandRInfoPtr randrp;
-
-#ifdef PANORAMIX
- /* XXX disable RandR when using Xinerama */
- if (!noPanoramiXExtension)
- {
- if (xf86NumScreens == 1)
- noPanoramiXExtension = TRUE;
- else
- return TRUE;
- }
-#endif
-
- if (xf86RandR12Generation != serverGeneration)
- xf86RandR12Generation = serverGeneration;
-
-#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
- xf86RandR12Key = &xf86RandR12KeyIndex;
-#else
- xf86RandR12Index = AllocateScreenPrivateIndex();
-#endif
-
- randrp = xalloc (sizeof (XF86RandRInfoRec));
- if (!randrp)
- return FALSE;
-
- if (!RRScreenInit(pScreen))
- {
- xfree (randrp);
- return FALSE;
- }
- rp = rrGetScrPriv(pScreen);
- rp->rrGetInfo = xf86RandR12GetInfo;
- rp->rrSetConfig = xf86RandR12SetConfig;
-
- randrp->virtualX = -1;
- randrp->virtualY = -1;
- randrp->mmWidth = pScreen->mmWidth;
- randrp->mmHeight = pScreen->mmHeight;
-
- randrp->rotation = RR_Rotate_0; /* initial rotated mode */
-
- randrp->supported_rotations = RR_Rotate_0;
-
- randrp->maxX = randrp->maxY = 0;
-
-#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
- dixSetPrivate(&pScreen->devPrivates, xf86RandR12Key, randrp);
-#else
- pScreen->devPrivates[xf86RandR12Index].ptr = randrp;
-#endif
-
-#if RANDR_12_INTERFACE
- if (!xf86RandR12Init12 (pScreen))
- return FALSE;
-#endif
- return TRUE;
-}
-
-void
-xf86RandR12SetRotations (ScreenPtr pScreen, Rotation rotations)
-{
- XF86RandRInfoPtr randrp;
-#if RANDR_12_INTERFACE
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- int c;
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
-#endif
-
-#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
- if (xf86RandR12Key == NULL)
- return;
-#endif
-
- randrp = XF86RANDRINFO(pScreen);
-#if RANDR_12_INTERFACE
- for (c = 0; c < config->num_crtc; c++) {
- xf86CrtcPtr crtc = config->crtc[c];
-
- RRCrtcSetRotations (crtc->randr_crtc, rotations);
- }
-#endif
- randrp->supported_rotations = rotations;
-}
-
-void
-xf86RandR12SetTransformSupport (ScreenPtr pScreen, Bool transforms)
-{
- XF86RandRInfoPtr randrp;
-#if RANDR_13_INTERFACE
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- int c;
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
-#endif
-
-#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
- if (xf86RandR12Key == NULL)
- return;
-#endif
-
- randrp = XF86RANDRINFO(pScreen);
-#if RANDR_13_INTERFACE
- for (c = 0; c < config->num_crtc; c++) {
- xf86CrtcPtr crtc = config->crtc[c];
-
- RRCrtcSetTransformSupport (crtc->randr_crtc, transforms);
- }
-#endif
-}
-
-void
-xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y)
-{
- ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
-
- if (xf86RandR12Generation != serverGeneration ||
- XF86RANDRINFO(pScreen)->virtualX == -1)
- {
- *x = pScrn->virtualX;
- *y = pScrn->virtualY;
- } else {
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
-
- *x = randrp->virtualX;
- *y = randrp->virtualY;
- }
-}
-
-#if RANDR_12_INTERFACE
-
-#define FLAG_BITS (RR_HSyncPositive | \
- RR_HSyncNegative | \
- RR_VSyncPositive | \
- RR_VSyncNegative | \
- RR_Interlace | \
- RR_DoubleScan | \
- RR_CSync | \
- RR_CSyncPositive | \
- RR_CSyncNegative | \
- RR_HSkewPresent | \
- RR_BCast | \
- RR_PixelMultiplex | \
- RR_DoubleClock | \
- RR_ClockDivideBy2)
-
-static Bool
-xf86RandRModeMatches (RRModePtr randr_mode,
- DisplayModePtr mode)
-{
-#if 0
- if (match_name)
- {
- /* check for same name */
- int len = strlen (mode->name);
- if (randr_mode->mode.nameLength != len) return FALSE;
- if (memcmp (randr_mode->name, mode->name, len) != 0) return FALSE;
- }
-#endif
-
- /* check for same timings */
- if (randr_mode->mode.dotClock / 1000 != mode->Clock) return FALSE;
- if (randr_mode->mode.width != mode->HDisplay) return FALSE;
- if (randr_mode->mode.hSyncStart != mode->HSyncStart) return FALSE;
- if (randr_mode->mode.hSyncEnd != mode->HSyncEnd) return FALSE;
- if (randr_mode->mode.hTotal != mode->HTotal) return FALSE;
- if (randr_mode->mode.hSkew != mode->HSkew) return FALSE;
- if (randr_mode->mode.height != mode->VDisplay) return FALSE;
- if (randr_mode->mode.vSyncStart != mode->VSyncStart) return FALSE;
- if (randr_mode->mode.vSyncEnd != mode->VSyncEnd) return FALSE;
- if (randr_mode->mode.vTotal != mode->VTotal) return FALSE;
-
- /* check for same flags (using only the XF86 valid flag bits) */
- if ((randr_mode->mode.modeFlags & FLAG_BITS) != (mode->Flags & FLAG_BITS))
- return FALSE;
-
- /* everything matches */
- return TRUE;
-}
-
-static Bool
-xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc)
-{
- ScreenPtr pScreen = randr_crtc->pScreen;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- RRModePtr randr_mode = NULL;
- int x;
- int y;
- Rotation rotation;
- int numOutputs;
- RROutputPtr *randr_outputs;
- RROutputPtr randr_output;
- xf86CrtcPtr crtc = randr_crtc->devPrivate;
- xf86OutputPtr output;
- int i, j;
- DisplayModePtr mode = &crtc->mode;
- Bool ret;
-
- randr_outputs = xalloc(config->num_output * sizeof (RROutputPtr));
- if (!randr_outputs)
- return FALSE;
- x = crtc->x;
- y = crtc->y;
- rotation = crtc->rotation;
- numOutputs = 0;
- randr_mode = NULL;
- for (i = 0; i < config->num_output; i++)
- {
- output = config->output[i];
- if (output->crtc == crtc)
- {
- randr_output = output->randr_output;
- randr_outputs[numOutputs++] = randr_output;
- /*
- * We make copies of modes, so pointer equality
- * isn't sufficient
- */
- for (j = 0; j < randr_output->numModes + randr_output->numUserModes; j++)
- {
- RRModePtr m = (j < randr_output->numModes ?
- randr_output->modes[j] :
- randr_output->userModes[j-randr_output->numModes]);
-
- if (xf86RandRModeMatches (m, mode))
- {
- randr_mode = m;
- break;
- }
- }
- }
- }
- ret = RRCrtcNotify (randr_crtc, randr_mode, x, y,
- rotation,
- crtc->transformPresent ? &crtc->transform : NULL,
- numOutputs, randr_outputs);
- xfree(randr_outputs);
- return ret;
-}
-
-/*
- * Convert a RandR mode to a DisplayMode
- */
-static void
-xf86RandRModeConvert (ScrnInfoPtr scrn,
- RRModePtr randr_mode,
- DisplayModePtr mode)
-{
- memset(mode, 0, sizeof(DisplayModeRec));
- mode->status = MODE_OK;
-
- mode->Clock = randr_mode->mode.dotClock / 1000;
-
- mode->HDisplay = randr_mode->mode.width;
- mode->HSyncStart = randr_mode->mode.hSyncStart;
- mode->HSyncEnd = randr_mode->mode.hSyncEnd;
- mode->HTotal = randr_mode->mode.hTotal;
- mode->HSkew = randr_mode->mode.hSkew;
-
- mode->VDisplay = randr_mode->mode.height;
- mode->VSyncStart = randr_mode->mode.vSyncStart;
- mode->VSyncEnd = randr_mode->mode.vSyncEnd;
- mode->VTotal = randr_mode->mode.vTotal;
- mode->VScan = 0;
-
- mode->Flags = randr_mode->mode.modeFlags & FLAG_BITS;
-
- xf86SetModeCrtc (mode, scrn->adjustFlags);
-}
-
-static Bool
-xf86RandR12CrtcSet (ScreenPtr pScreen,
- RRCrtcPtr randr_crtc,
- RRModePtr randr_mode,
- int x,
- int y,
- Rotation rotation,
- int num_randr_outputs,
- RROutputPtr *randr_outputs)
-{
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- xf86CrtcPtr crtc = randr_crtc->devPrivate;
- RRTransformPtr transform;
- Bool changed = FALSE;
- int o, ro;
- xf86CrtcPtr *save_crtcs;
- Bool save_enabled = crtc->enabled;
-
- if (!crtc->scrn->vtSema)
- return FALSE;
-
- save_crtcs = xalloc(config->num_output * sizeof (xf86CrtcPtr));
- if ((randr_mode != NULL) != crtc->enabled)
- changed = TRUE;
- else if (randr_mode && !xf86RandRModeMatches (randr_mode, &crtc->mode))
- changed = TRUE;
-
- if (rotation != crtc->rotation)
- changed = TRUE;
-
- transform = RRCrtcGetTransform (randr_crtc);
- if ((transform != NULL) != crtc->transformPresent)
- changed = TRUE;
- else if (transform && memcmp (&transform->transform, &crtc->transform.transform,
- sizeof (transform->transform)) != 0)
- changed = TRUE;
-
- if (x != crtc->x || y != crtc->y)
- changed = TRUE;
- for (o = 0; o < config->num_output; o++)
- {
- xf86OutputPtr output = config->output[o];
- xf86CrtcPtr new_crtc;
-
- save_crtcs[o] = output->crtc;
-
- if (output->crtc == crtc)
- new_crtc = NULL;
- else
- new_crtc = output->crtc;
- for (ro = 0; ro < num_randr_outputs; ro++)
- if (output->randr_output == randr_outputs[ro])
- {
- new_crtc = crtc;
- break;
- }
- if (new_crtc != output->crtc)
- {
- changed = TRUE;
- output->crtc = new_crtc;
- }
- }
- for (ro = 0; ro < num_randr_outputs; ro++)
- if (randr_outputs[ro]->pendingProperties)
- changed = TRUE;
-
- /* XXX need device-independent mode setting code through an API */
- if (changed)
- {
- crtc->enabled = randr_mode != NULL;
-
- if (randr_mode)
- {
- DisplayModeRec mode;
- RRTransformPtr transform = RRCrtcGetTransform (randr_crtc);
-
- xf86RandRModeConvert (pScrn, randr_mode, &mode);
- if (!xf86CrtcSetModeTransform (crtc, &mode, rotation, transform, x, y))
- {
- crtc->enabled = save_enabled;
- for (o = 0; o < config->num_output; o++)
- {
- xf86OutputPtr output = config->output[o];
- output->crtc = save_crtcs[o];
- }
- xfree(save_crtcs);
- return FALSE;
- }
- xf86RandR13VerifyPanningArea (crtc, pScreen->width, pScreen->height);
- xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
- /*
- * Save the last successful setting for EnterVT
- */
- crtc->desiredMode = mode;
- crtc->desiredRotation = rotation;
- if (transform) {
- crtc->desiredTransform = *transform;
- crtc->desiredTransformPresent = TRUE;
- } else
- crtc->desiredTransformPresent = FALSE;
-
- crtc->desiredX = x;
- crtc->desiredY = y;
- }
- xf86DisableUnusedFunctions (pScrn);
- }
- xfree(save_crtcs);
- return xf86RandR12CrtcNotify (randr_crtc);
-}
-
-static Bool
-xf86RandR12CrtcSetGamma (ScreenPtr pScreen,
- RRCrtcPtr randr_crtc)
-{
- xf86CrtcPtr crtc = randr_crtc->devPrivate;
-
- if (crtc->funcs->gamma_set == NULL)
- return FALSE;
-
- if (!crtc->scrn->vtSema)
- return TRUE;
-
- /* Realloc local gamma if needed. */
- if (randr_crtc->gammaSize != crtc->gamma_size) {
- CARD16 *tmp_ptr;
- tmp_ptr = realloc(crtc->gamma_red, 3 * crtc->gamma_size * sizeof (CARD16));
- if (!tmp_ptr)
- return FALSE;
- crtc->gamma_red = tmp_ptr;
- crtc->gamma_green = crtc->gamma_red + crtc->gamma_size;
- crtc->gamma_blue = crtc->gamma_green + crtc->gamma_size;
- }
-
- crtc->gamma_size = randr_crtc->gammaSize;
- memcpy (crtc->gamma_red, randr_crtc->gammaRed, crtc->gamma_size * sizeof (CARD16));
- memcpy (crtc->gamma_green, randr_crtc->gammaGreen, crtc->gamma_size * sizeof (CARD16));
- memcpy (crtc->gamma_blue, randr_crtc->gammaBlue, crtc->gamma_size * sizeof (CARD16));
-
- /* Only set it when the crtc is actually running.
- * Otherwise it will be set when it's activated.
- */
- if (crtc->active)
- crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green,
- crtc->gamma_blue, crtc->gamma_size);
-
- return TRUE;
-}
-
-static Bool
-xf86RandR12CrtcGetGamma (ScreenPtr pScreen,
- RRCrtcPtr randr_crtc)
-{
- xf86CrtcPtr crtc = randr_crtc->devPrivate;
-
- if (!crtc->gamma_size)
- return FALSE;
-
- if (!crtc->gamma_red || !crtc->gamma_green || !crtc->gamma_blue)
- return FALSE;
-
- /* Realloc randr gamma if needed. */
- if (randr_crtc->gammaSize != crtc->gamma_size) {
- CARD16 *tmp_ptr;
- tmp_ptr = realloc(randr_crtc->gammaRed, 3 * crtc->gamma_size * sizeof (CARD16));
- if (!tmp_ptr)
- return FALSE;
- randr_crtc->gammaRed = tmp_ptr;
- randr_crtc->gammaGreen = randr_crtc->gammaRed + crtc->gamma_size;
- randr_crtc->gammaBlue = randr_crtc->gammaGreen + crtc->gamma_size;
- }
- randr_crtc->gammaSize = crtc->gamma_size;
- memcpy (randr_crtc->gammaRed, crtc->gamma_red, crtc->gamma_size * sizeof (CARD16));
- memcpy (randr_crtc->gammaGreen, crtc->gamma_green, crtc->gamma_size * sizeof (CARD16));
- memcpy (randr_crtc->gammaBlue, crtc->gamma_blue, crtc->gamma_size * sizeof (CARD16));
-
- return TRUE;
-}
-
-static Bool
-xf86RandR12OutputSetProperty (ScreenPtr pScreen,
- RROutputPtr randr_output,
- Atom property,
- RRPropertyValuePtr value)
-{
- xf86OutputPtr output = randr_output->devPrivate;
-
- /* If we don't have any property handler, then we don't care what the
- * user is setting properties to.
- */
- if (output->funcs->set_property == NULL)
- return TRUE;
-
- /*
- * This function gets called even when vtSema is FALSE, as
- * drivers will need to remember the correct value to apply
- * when the VT switch occurs
- */
- return output->funcs->set_property(output, property, value);
-}
-
-static Bool
-xf86RandR13OutputGetProperty (ScreenPtr pScreen,
- RROutputPtr randr_output,
- Atom property)
-{
- xf86OutputPtr output = randr_output->devPrivate;
-
- if (output->funcs->get_property == NULL)
- return TRUE;
-
- /* Should be safe even w/o vtSema */
- return output->funcs->get_property(output, property);
-}
-
-static Bool
-xf86RandR12OutputValidateMode (ScreenPtr pScreen,
- RROutputPtr randr_output,
- RRModePtr randr_mode)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86OutputPtr output = randr_output->devPrivate;
- DisplayModeRec mode;
-
- xf86RandRModeConvert (pScrn, randr_mode, &mode);
- /*
- * This function may be called when vtSema is FALSE, so
- * the underlying function must either avoid touching the hardware
- * or return FALSE when vtSema is FALSE
- */
- if (output->funcs->mode_valid (output, &mode) != MODE_OK)
- return FALSE;
- return TRUE;
-}
-
-static void
-xf86RandR12ModeDestroy (ScreenPtr pScreen, RRModePtr randr_mode)
-{
-}
-
-/**
- * Given a list of xf86 modes and a RandR Output object, construct
- * RandR modes and assign them to the output
- */
-static Bool
-xf86RROutputSetModes (RROutputPtr randr_output, DisplayModePtr modes)
-{
- DisplayModePtr mode;
- RRModePtr *rrmodes = NULL;
- int nmode = 0;
- int npreferred = 0;
- Bool ret = TRUE;
- int pref;
-
- for (mode = modes; mode; mode = mode->next)
- nmode++;
-
- if (nmode) {
- rrmodes = xalloc (nmode * sizeof (RRModePtr));
-
- if (!rrmodes)
- return FALSE;
- nmode = 0;
-
- for (pref = 1; pref >= 0; pref--) {
- for (mode = modes; mode; mode = mode->next) {
- if ((pref != 0) == ((mode->type & M_T_PREFERRED) != 0)) {
- xRRModeInfo modeInfo;
- RRModePtr rrmode;
-
- modeInfo.nameLength = strlen (mode->name);
- modeInfo.width = mode->HDisplay;
- modeInfo.dotClock = mode->Clock * 1000;
- modeInfo.hSyncStart = mode->HSyncStart;
- modeInfo.hSyncEnd = mode->HSyncEnd;
- modeInfo.hTotal = mode->HTotal;
- modeInfo.hSkew = mode->HSkew;
-
- modeInfo.height = mode->VDisplay;
- modeInfo.vSyncStart = mode->VSyncStart;
- modeInfo.vSyncEnd = mode->VSyncEnd;
- modeInfo.vTotal = mode->VTotal;
- modeInfo.modeFlags = mode->Flags;
-
- rrmode = RRModeGet (&modeInfo, mode->name);
- if (rrmode) {
- rrmodes[nmode++] = rrmode;
- npreferred += pref;
- }
- }
- }
- }
- }
-
- ret = RROutputSetModes (randr_output, rrmodes, nmode, npreferred);
- xfree (rrmodes);
- return ret;
-}
-
-/*
- * Mirror the current mode configuration to RandR
- */
-static Bool
-xf86RandR12SetInfo12 (ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- RROutputPtr *clones;
- RRCrtcPtr *crtcs;
- int ncrtc;
- int o, c, l;
- RRCrtcPtr randr_crtc;
- int nclone;
-
- clones = xalloc(config->num_output * sizeof (RROutputPtr));
- crtcs = xalloc (config->num_crtc * sizeof (RRCrtcPtr));
- for (o = 0; o < config->num_output; o++)
- {
- xf86OutputPtr output = config->output[o];
-
- ncrtc = 0;
- for (c = 0; c < config->num_crtc; c++)
- if (output->possible_crtcs & (1 << c))
- crtcs[ncrtc++] = config->crtc[c]->randr_crtc;
-
- if (output->crtc)
- randr_crtc = output->crtc->randr_crtc;
- else
- randr_crtc = NULL;
-
- if (!RROutputSetCrtcs (output->randr_output, crtcs, ncrtc))
- {
- xfree (crtcs);
- xfree (clones);
- return FALSE;
- }
-
- RROutputSetPhysicalSize(output->randr_output,
- output->mm_width,
- output->mm_height);
- xf86RROutputSetModes (output->randr_output, output->probed_modes);
-
- switch (output->status) {
- case XF86OutputStatusConnected:
- RROutputSetConnection (output->randr_output, RR_Connected);
- break;
- case XF86OutputStatusDisconnected:
- RROutputSetConnection (output->randr_output, RR_Disconnected);
- break;
- case XF86OutputStatusUnknown:
- RROutputSetConnection (output->randr_output, RR_UnknownConnection);
- break;
- }
-
- RROutputSetSubpixelOrder (output->randr_output, output->subpixel_order);
-
- /*
- * Valid clones
- */
- nclone = 0;
- for (l = 0; l < config->num_output; l++)
- {
- xf86OutputPtr clone = config->output[l];
-
- if (l != o && (output->possible_clones & (1 << l)))
- clones[nclone++] = clone->randr_output;
- }
- if (!RROutputSetClones (output->randr_output, clones, nclone))
- {
- xfree (crtcs);
- xfree (clones);
- return FALSE;
- }
- }
- xfree (crtcs);
- xfree (clones);
- return TRUE;
-}
-
-
-
-/*
- * Query the hardware for the current state, then mirror
- * that to RandR
- */
-static Bool
-xf86RandR12GetInfo12 (ScreenPtr pScreen, Rotation *rotations)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-
- if (!pScrn->vtSema)
- return TRUE;
- xf86ProbeOutputModes (pScrn, 0, 0);
- xf86SetScrnInfoModes (pScrn);
- return xf86RandR12SetInfo12 (pScreen);
-}
-
-static Bool
-xf86RandR12CreateObjects12 (ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- int c;
- int o;
-
- if (!RRInit ())
- return FALSE;
-
- /*
- * Configure crtcs
- */
- for (c = 0; c < config->num_crtc; c++)
- {
- xf86CrtcPtr crtc = config->crtc[c];
-
- crtc->randr_crtc = RRCrtcCreate (pScreen, crtc);
- RRCrtcGammaSetSize (crtc->randr_crtc, 256);
- }
- /*
- * Configure outputs
- */
- for (o = 0; o < config->num_output; o++)
- {
- xf86OutputPtr output = config->output[o];
-
- output->randr_output = RROutputCreate (pScreen, output->name,
- strlen (output->name),
- output);
-
- if (output->funcs->create_resources != NULL)
- output->funcs->create_resources(output);
- RRPostPendingProperties (output->randr_output);
- }
- return TRUE;
-}
-
-static Bool
-xf86RandR12CreateScreenResources12 (ScreenPtr pScreen)
-{
- int c;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
-
-#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
- if (xf86RandR12Key == NULL)
- return TRUE;
-#endif
-
- for (c = 0; c < config->num_crtc; c++)
- xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc);
-
- RRScreenSetSizeRange (pScreen, config->minWidth, config->minHeight,
- config->maxWidth, config->maxHeight);
- return TRUE;
-}
-
-/*
- * Something happened within the screen configuration due
- * to DGA, VidMode or hot key. Tell RandR
- */
-
-void
-xf86RandR12TellChanged (ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- int c;
-
-#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
- if (xf86RandR12Key == NULL)
- return;
-#else
- if (!XF86RANDRINFO(pScreen))
- return;
-#endif
-
- xf86RandR12SetInfo12 (pScreen);
- for (c = 0; c < config->num_crtc; c++)
- xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc);
-
- RRTellChanged (pScreen);
-}
-
-static void
-xf86RandR12PointerMoved (int scrnIndex, int x, int y)
-{
- ScreenPtr pScreen = screenInfo.screens[scrnIndex];
- ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen);
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- int c;
-
- randrp->pointerX = x;
- randrp->pointerY = y;
- for (c = 0; c < config->num_crtc; c++)
- xf86RandR13Pan (config->crtc[c], x, y);
-}
-
-static Bool
-xf86RandR13GetPanning (ScreenPtr pScreen,
- RRCrtcPtr randr_crtc,
- BoxPtr totalArea,
- BoxPtr trackingArea,
- INT16 *border)
-{
- xf86CrtcPtr crtc = randr_crtc->devPrivate;
-
- if (crtc->version < 2)
- return FALSE;
- if (totalArea)
- memcpy (totalArea, &crtc->panningTotalArea, sizeof(BoxRec));
- if (trackingArea)
- memcpy (trackingArea, &crtc->panningTrackingArea, sizeof(BoxRec));
- if (border)
- memcpy (border, crtc->panningBorder, 4*sizeof(INT16));
-
- return TRUE;
-}
-
-static Bool
-xf86RandR13SetPanning (ScreenPtr pScreen,
- RRCrtcPtr randr_crtc,
- BoxPtr totalArea,
- BoxPtr trackingArea,
- INT16 *border)
-{
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
- xf86CrtcPtr crtc = randr_crtc->devPrivate;
- BoxRec oldTotalArea;
- BoxRec oldTrackingArea;
- INT16 oldBorder[4];
-
-
- if (crtc->version < 2)
- return FALSE;
-
- memcpy (&oldTotalArea, &crtc->panningTotalArea, sizeof(BoxRec));
- memcpy (&oldTrackingArea, &crtc->panningTrackingArea, sizeof(BoxRec));
- memcpy (oldBorder, crtc->panningBorder, 4*sizeof(INT16));
-
- if (totalArea)
- memcpy (&crtc->panningTotalArea, totalArea, sizeof(BoxRec));
- if (trackingArea)
- memcpy (&crtc->panningTrackingArea, trackingArea, sizeof(BoxRec));
- if (border)
- memcpy (crtc->panningBorder, border, 4*sizeof(INT16));
-
- if (xf86RandR13VerifyPanningArea (crtc, pScreen->width, pScreen->height)) {
- xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
- return TRUE;
- } else {
- /* Restore old settings */
- memcpy (&crtc->panningTotalArea, &oldTotalArea, sizeof(BoxRec));
- memcpy (&crtc->panningTrackingArea, &oldTrackingArea, sizeof(BoxRec));
- memcpy (crtc->panningBorder, oldBorder, 4*sizeof(INT16));
- return FALSE;
- }
-}
-
-/*
- * Compatibility with XF86VidMode's gamma changer. This necessarily clobbers
- * any per-crtc setup. You asked for it...
- */
-
-static void
-gamma_to_ramp(float gamma, CARD16 *ramp, int size)
-{
- int i;
-
- for (i = 0; i < size; i++) {
- if (gamma == 1.0)
- ramp[i] = i << 8;
- else
- ramp[i] = (CARD16)(pow((double)i / (double)(size - 1), 1. / gamma)
- * (double)(size - 1) * 256);
- }
-}
-
-static int
-xf86RandR12ChangeGamma(int scrnIndex, Gamma gamma)
-{
- CARD16 *points, *red, *green, *blue;
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- RRCrtcPtr crtc = xf86CompatRRCrtc(pScrn);
- int size;
-
- if (!crtc)
- return Success;
-
- size = max(0, crtc->gammaSize);
- if (!size)
- return Success;
-
- points = xcalloc(size, 3 * sizeof(CARD16));
- if (!points)
- return BadAlloc;
-
- red = points;
- green = points + size;
- blue = points + 2 * size;
-
- gamma_to_ramp(gamma.red, red, size);
- gamma_to_ramp(gamma.green, green, size);
- gamma_to_ramp(gamma.blue, blue, size);
- RRCrtcGammaSet(crtc, red, green, blue);
-
- xfree(points);
-
- pScrn->gamma = gamma;
-
- return Success;
-}
-
-static Bool
-xf86RandR12EnterVT (int screen_index, int flags)
-{
- ScreenPtr pScreen = screenInfo.screens[screen_index];
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
-
- if (randrp->orig_EnterVT) {
- if (!randrp->orig_EnterVT (screen_index, flags))
- return FALSE;
- }
-
- return RRGetInfo (pScreen, TRUE); /* force a re-probe of outputs and notify clients about changes */
-}
-
-static Bool
-xf86RandR12Init12 (ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- rrScrPrivPtr rp = rrGetScrPriv(pScreen);
- XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
-
- rp->rrGetInfo = xf86RandR12GetInfo12;
- rp->rrScreenSetSize = xf86RandR12ScreenSetSize;
- rp->rrCrtcSet = xf86RandR12CrtcSet;
- rp->rrCrtcSetGamma = xf86RandR12CrtcSetGamma;
- rp->rrCrtcGetGamma = xf86RandR12CrtcGetGamma;
- rp->rrOutputSetProperty = xf86RandR12OutputSetProperty;
- rp->rrOutputValidateMode = xf86RandR12OutputValidateMode;
-#if RANDR_13_INTERFACE
- rp->rrOutputGetProperty = xf86RandR13OutputGetProperty;
- rp->rrGetPanning = xf86RandR13GetPanning;
- rp->rrSetPanning = xf86RandR13SetPanning;
-#endif
- rp->rrModeDestroy = xf86RandR12ModeDestroy;
- rp->rrSetConfig = NULL;
- pScrn->PointerMoved = xf86RandR12PointerMoved;
- pScrn->ChangeGamma = xf86RandR12ChangeGamma;
-
- randrp->orig_EnterVT = pScrn->EnterVT;
- pScrn->EnterVT = xf86RandR12EnterVT;
-
- if (!xf86RandR12CreateObjects12 (pScreen))
- return FALSE;
-
- /*
- * Configure output modes
- */
- if (!xf86RandR12SetInfo12 (pScreen))
- return FALSE;
- return TRUE;
-}
-
-#endif
-
-Bool
-xf86RandR12PreInit (ScrnInfoPtr pScrn)
-{
- return TRUE;
-}
+/*
+ * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS 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>
+#else
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#endif
+
+#include "xf86.h"
+#include "os.h"
+#include "globals.h"
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86DDC.h"
+#include "mipointer.h"
+#include "windowstr.h"
+#include "inputstr.h"
+#include <randrstr.h>
+#include <X11/extensions/render.h>
+
+#include "xf86Crtc.h"
+#include "xf86RandR12.h"
+
+typedef struct _xf86RandR12Info {
+ int virtualX;
+ int virtualY;
+ int mmWidth;
+ int mmHeight;
+ int maxX;
+ int maxY;
+ int pointerX;
+ int pointerY;
+ Rotation rotation; /* current mode */
+ Rotation supported_rotations; /* driver supported */
+
+ /* Used to wrap EnterVT so we can re-probe the outputs when a laptop unsuspends
+ * (actually, any time that we switch back into our VT).
+ *
+ * See https://bugs.freedesktop.org/show_bug.cgi?id=21554
+ */
+ xf86EnterVTProc *orig_EnterVT;
+} XF86RandRInfoRec, *XF86RandRInfoPtr;
+
+#ifdef RANDR_12_INTERFACE
+static Bool xf86RandR12Init12 (ScreenPtr pScreen);
+static Bool xf86RandR12CreateScreenResources12 (ScreenPtr pScreen);
+#endif
+
+static int xf86RandR12Generation;
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
+
+static int xf86RandR12KeyIndex;
+static DevPrivateKey xf86RandR12Key;
+#define XF86RANDRINFO(p) ((XF86RandRInfoPtr) \
+ dixLookupPrivate(&(p)->devPrivates, xf86RandR12Key))
+
+#else /* XORG_VERSION_CURRENT < 7.0 */
+
+static int xf86RandR12Index;
+#define XF86RANDRINFO(p) \
+ ((XF86RandRInfoPtr)(p)->devPrivates[xf86RandR12Index].ptr)
+
+#endif /* XORG_VERSION_CURRENT < 7.0 */
+
+
+static int
+xf86RandR12ModeRefresh (DisplayModePtr mode)
+{
+ if (mode->VRefresh)
+ return (int) (mode->VRefresh + 0.5);
+ else
+ return (int) (mode->Clock * 1000.0 / mode->HTotal / mode->VTotal + 0.5);
+}
+
+/* Adapt panning area; return TRUE if panning area was valid without adaption */
+static int
+xf86RandR13VerifyPanningArea (xf86CrtcPtr crtc, int screenWidth, int screenHeight)
+{
+ int ret = TRUE;
+
+ if (crtc->version < 2)
+ return FALSE;
+
+ if (crtc->panningTotalArea.x2 <= crtc->panningTotalArea.x1) {
+ /* Panning in X is disabled */
+ if (crtc->panningTotalArea.x1 || crtc->panningTotalArea.x2)
+ /* Illegal configuration -> fail/disable */
+ ret = FALSE;
+ crtc->panningTotalArea.x1 = crtc->panningTotalArea.x2 = 0;
+ crtc->panningTrackingArea.x1 = crtc->panningTrackingArea.x2 = 0;
+ crtc->panningBorder[0] = crtc->panningBorder[2] = 0;
+ } else {
+ /* Panning in X is enabled */
+ if (crtc->panningTotalArea.x1 < 0) {
+ /* Panning region outside screen -> move inside */
+ crtc->panningTotalArea.x2 -= crtc->panningTotalArea.x1;
+ crtc->panningTotalArea.x1 = 0;
+ ret = FALSE;
+ }
+ if (crtc->panningTotalArea.x2 < crtc->panningTotalArea.x1 + crtc->mode.HDisplay) {
+ /* Panning region smaller than displayed area -> crop to displayed area */
+ crtc->panningTotalArea.x2 = crtc->panningTotalArea.x1 + crtc->mode.HDisplay;
+ ret = FALSE;
+ }
+ if (crtc->panningTotalArea.x2 > screenWidth) {
+ /* Panning region larger than screen -> move inside, then crop to screen */
+ crtc->panningTotalArea.x1 -= crtc->panningTotalArea.x2 - screenWidth;
+ crtc->panningTotalArea.x2 = screenWidth;
+ ret = FALSE;
+ if (crtc->panningTotalArea.x1 < 0)
+ crtc->panningTotalArea.x1 = 0;
+ }
+ if (crtc->panningBorder[0] + crtc->panningBorder[2] > crtc->mode.HDisplay) {
+ /* Borders too large -> set to 0 */
+ crtc->panningBorder[0] = crtc->panningBorder[2] = 0;
+ ret = FALSE;
+ }
+ }
+
+ if (crtc->panningTotalArea.y2 <= crtc->panningTotalArea.y1) {
+ /* Panning in Y is disabled */
+ if (crtc->panningTotalArea.y1 || crtc->panningTotalArea.y2)
+ /* Illegal configuration -> fail/disable */
+ ret = FALSE;
+ crtc->panningTotalArea.y1 = crtc->panningTotalArea.y2 = 0;
+ crtc->panningTrackingArea.y1 = crtc->panningTrackingArea.y2 = 0;
+ crtc->panningBorder[1] = crtc->panningBorder[3] = 0;
+ } else {
+ /* Panning in Y is enabled */
+ if (crtc->panningTotalArea.y1 < 0) {
+ /* Panning region outside screen -> move inside */
+ crtc->panningTotalArea.y2 -= crtc->panningTotalArea.y1;
+ crtc->panningTotalArea.y1 = 0;
+ ret = FALSE;
+ }
+ if (crtc->panningTotalArea.y2 < crtc->panningTotalArea.y1 + crtc->mode.VDisplay) {
+ /* Panning region smaller than displayed area -> crop to displayed area */
+ crtc->panningTotalArea.y2 = crtc->panningTotalArea.y1 + crtc->mode.VDisplay;
+ ret = FALSE;
+ }
+ if (crtc->panningTotalArea.y2 > screenHeight) {
+ /* Panning region larger than screen -> move inside, then crop to screen */
+ crtc->panningTotalArea.y1 -= crtc->panningTotalArea.y2 - screenHeight;
+ crtc->panningTotalArea.y2 = screenHeight;
+ ret = FALSE;
+ if (crtc->panningTotalArea.y1 < 0)
+ crtc->panningTotalArea.y1 = 0;
+ }
+ if (crtc->panningBorder[1] + crtc->panningBorder[3] > crtc->mode.VDisplay) {
+ /* Borders too large -> set to 0 */
+ crtc->panningBorder[1] = crtc->panningBorder[3] = 0;
+ ret = FALSE;
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * The heart of the panning operation:
+ *
+ * Given a frame buffer position (fb_x, fb_y),
+ * and a crtc position (crtc_x, crtc_y),
+ * and a transform matrix which maps frame buffer to crtc,
+ * compute a panning position (pan_x, pan_y) that
+ * makes the resulting transform line those two up
+ */
+
+static void
+xf86ComputeCrtcPan (Bool transform_in_use,
+ struct pixman_f_transform *m,
+ double screen_x, double screen_y,
+ double crtc_x, double crtc_y,
+ int old_pan_x, int old_pan_y,
+ int *new_pan_x, int *new_pan_y)
+{
+ if (transform_in_use) {
+ /*
+ * Given the current transform, M, the current position
+ * on the Screen, S, and the desired position on the CRTC,
+ * C, compute a translation, T, such that:
+ *
+ * M T S = C
+ *
+ * where T is of the form
+ *
+ * | 1 0 dx |
+ * | 0 1 dy |
+ * | 0 0 1 |
+ *
+ * M T S =
+ * | M00 Sx + M01 Sy + M00 dx + M01 dy + M02 | | Cx F |
+ * | M10 Sx + M11 Sy + M10 dx + M11 dy + M12 | = | Cy F |
+ * | M20 Sx + M21 Sy + M20 dx + M21 dy + M22 | | F |
+ *
+ * R = M S
+ *
+ * Cx F = M00 dx + M01 dy + R0
+ * Cy F = M10 dx + M11 dy + R1
+ * F = M20 dx + M21 dy + R2
+ *
+ * Zero out dx, then dy
+ *
+ * F (Cx M10 - Cy M00) =
+ * (M10 M01 - M00 M11) dy + M10 R0 - M00 R1
+ * F (M10 - Cy M20) =
+ * (M10 M21 - M20 M11) dy + M10 R2 - M20 R1
+ *
+ * F (Cx M11 - Cy M01) =
+ * (M11 M00 - M01 M10) dx + M11 R0 - M01 R1
+ * F (M11 - Cy M21) =
+ * (M11 M20 - M21 M10) dx + M11 R2 - M21 R1
+ *
+ * Make some temporaries
+ *
+ * T = | Cx M10 - Cy M00 |
+ * | Cx M11 - Cy M01 |
+ *
+ * U = | M10 M01 - M00 M11 |
+ * | M11 M00 - M01 M10 |
+ *
+ * Q = | M10 R0 - M00 R1 |
+ * | M11 R0 - M01 R1 |
+ *
+ * P = | M10 - Cy M20 |
+ * | M11 - Cy M21 |
+ *
+ * W = | M10 M21 - M20 M11 |
+ * | M11 M20 - M21 M10 |
+ *
+ * V = | M10 R2 - M20 R1 |
+ * | M11 R2 - M21 R1 |
+ *
+ * Rewrite:
+ *
+ * F T0 = U0 dy + Q0
+ * F P0 = W0 dy + V0
+ * F T1 = U1 dx + Q1
+ * F P1 = W1 dx + V1
+ *
+ * Solve for F (two ways)
+ *
+ * F (W0 T0 - U0 P0) = W0 Q0 - U0 V0
+ *
+ * W0 Q0 - U0 V0
+ * F = -------------
+ * W0 T0 - U0 P0
+ *
+ * F (W1 T1 - U1 P1) = W1 Q1 - U1 V1
+ *
+ * W1 Q1 - U1 V1
+ * F = -------------
+ * W1 T1 - U1 P1
+ *
+ * We'll use which ever solution works (denominator != 0)
+ *
+ * Finally, solve for dx and dy:
+ *
+ * dx = (F T1 - Q1) / U1
+ * dx = (F P1 - V1) / W1
+ *
+ * dy = (F T0 - Q0) / U0
+ * dy = (F P0 - V0) / W0
+ */
+ double r[3];
+ double q[2], u[2], t[2], v[2], w[2], p[2];
+ double f;
+ struct pict_f_vector d;
+ int i;
+
+ /* Get the un-normalized crtc coordinates again */
+ for (i = 0; i < 3; i++)
+ r[i] = m->m[i][0] * screen_x + m->m[i][1] * screen_y + m->m[i][2];
+
+ /* Combine values into temporaries */
+ for (i = 0; i < 2; i++) {
+ q[i] = m->m[1][i] * r[0] - m->m[0][i] * r[1];
+ u[i] = m->m[1][i] * m->m[0][1-i] - m->m[0][i] * m->m[1][1-i];
+ t[i] = m->m[1][i] * crtc_x - m->m[0][i] * crtc_y;
+
+ v[i] = m->m[1][i] * r[2] - m->m[2][i] * r[1];
+ w[i] = m->m[1][i] * m->m[2][1-i] - m->m[2][i] * m->m[1][1-i];
+ p[i] = m->m[1][i] - m->m[2][i] * crtc_y;
+ }
+
+ /* Find a way to compute f */
+ f = 0;
+ for (i = 0; i < 2; i++) {
+ double a = w[i] * q[i] - u[i] * v[i];
+ double b = w[i] * t[i] - u[i] * p[i];
+ if (b != 0) {
+ f = a/b;
+ break;
+ }
+ }
+
+ /* Solve for the resulting transform vector */
+ for (i = 0; i < 2; i++) {
+ if (u[i])
+ d.v[1-i] = (t[i] * f - q[i]) / u[i];
+ else if (w[1])
+ d.v[1-i] = (p[i] * f - v[i]) / w[i];
+ else
+ d.v[1-i] = 0;
+ }
+ *new_pan_x = old_pan_x - floor (d.v[0] + 0.5);
+ *new_pan_y = old_pan_y - floor (d.v[1] + 0.5);
+ } else {
+ *new_pan_x = screen_x - crtc_x;
+ *new_pan_y = screen_y - crtc_y;
+ }
+}
+
+static void
+xf86RandR13Pan (xf86CrtcPtr crtc, int x, int y)
+{
+ int newX, newY;
+ int width, height;
+ Bool panned = FALSE;
+
+ if (crtc->version < 2)
+ return;
+
+ if (! crtc->enabled ||
+ (crtc->panningTotalArea.x2 <= crtc->panningTotalArea.x1 &&
+ crtc->panningTotalArea.y2 <= crtc->panningTotalArea.y1))
+ return;
+
+ newX = crtc->x;
+ newY = crtc->y;
+ width = crtc->mode.HDisplay;
+ height = crtc->mode.VDisplay;
+
+ if ((crtc->panningTrackingArea.x2 <= crtc->panningTrackingArea.x1 ||
+ (x >= crtc->panningTrackingArea.x1 && x < crtc->panningTrackingArea.x2)) &&
+ (crtc->panningTrackingArea.y2 <= crtc->panningTrackingArea.y1 ||
+ (y >= crtc->panningTrackingArea.y1 && y < crtc->panningTrackingArea.y2)))
+ {
+ struct pict_f_vector c;
+
+ /*
+ * Pre-clip the mouse position to the panning area so that we don't
+ * push the crtc outside. This doesn't deal with changes to the
+ * panning values, only mouse position changes.
+ */
+ if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1)
+ {
+ if (x < crtc->panningTotalArea.x1)
+ x = crtc->panningTotalArea.x1;
+ if (x >= crtc->panningTotalArea.x2)
+ x = crtc->panningTotalArea.x2 - 1;
+ }
+ if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1)
+ {
+ if (y < crtc->panningTotalArea.y1)
+ y = crtc->panningTotalArea.y1;
+ if (y >= crtc->panningTotalArea.y2)
+ y = crtc->panningTotalArea.y2 - 1;
+ }
+
+ c.v[0] = x;
+ c.v[1] = y;
+ c.v[2] = 1.0;
+ if (crtc->transform_in_use) {
+ pixman_f_transform_point(&crtc->f_framebuffer_to_crtc, &c);
+ } else {
+ c.v[0] -= crtc->x;
+ c.v[1] -= crtc->y;
+ }
+
+ if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1) {
+ if (c.v[0] < crtc->panningBorder[0]) {
+ c.v[0] = crtc->panningBorder[0];
+ panned = TRUE;
+ }
+ if (c.v[0] >= width - crtc->panningBorder[2]) {
+ c.v[0] = width - crtc->panningBorder[2] - 1;
+ panned = TRUE;
+ }
+ }
+ if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) {
+ if (c.v[1] < crtc->panningBorder[1]) {
+ c.v[1] = crtc->panningBorder[1];
+ panned = TRUE;
+ }
+ if (c.v[1] >= height - crtc->panningBorder[3]) {
+ c.v[1] = height - crtc->panningBorder[3] - 1;
+ panned = TRUE;
+ }
+ }
+ if (panned)
+ xf86ComputeCrtcPan (crtc->transform_in_use,
+ &crtc->f_framebuffer_to_crtc,
+ x, y, c.v[0], c.v[1],
+ newX, newY, &newX, &newY);
+ }
+
+ /*
+ * Ensure that the crtc is within the panning region.
+ *
+ * XXX This computation only works when we do not have a transform
+ * in use.
+ */
+ if (!crtc->transform_in_use)
+ {
+ /* Validate against [xy]1 after [xy]2, to be sure that results are > 0 for [xy]1 > 0 */
+ if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1) {
+ if (newX > crtc->panningTotalArea.x2 - width)
+ newX = crtc->panningTotalArea.x2 - width;
+ if (newX < crtc->panningTotalArea.x1)
+ newX = crtc->panningTotalArea.x1;
+ }
+ if (crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) {
+ if (newY > crtc->panningTotalArea.y2 - height)
+ newY = crtc->panningTotalArea.y2 - height;
+ if (newY < crtc->panningTotalArea.y1)
+ newY = crtc->panningTotalArea.y1;
+ }
+ }
+ if (newX != crtc->x || newY != crtc->y)
+ xf86CrtcSetOrigin (crtc, newX, newY);
+}
+
+static Bool
+xf86RandR12GetInfo (ScreenPtr pScreen, Rotation *rotations)
+{
+ RRScreenSizePtr pSize;
+ ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ DisplayModePtr mode;
+ int refresh0 = 60;
+ int maxX = 0, maxY = 0;
+
+ *rotations = randrp->supported_rotations;
+
+ if (randrp->virtualX == -1 || randrp->virtualY == -1)
+ {
+ randrp->virtualX = scrp->virtualX;
+ randrp->virtualY = scrp->virtualY;
+ }
+
+ /* Re-probe the outputs for new monitors or modes */
+ if (scrp->vtSema)
+ {
+ xf86ProbeOutputModes (scrp, 0, 0);
+ xf86SetScrnInfoModes (scrp);
+ }
+
+ for (mode = scrp->modes; ; mode = mode->next)
+ {
+ int refresh = xf86RandR12ModeRefresh (mode);
+ if (randrp->maxX == 0 || randrp->maxY == 0)
+ {
+ if (maxX < mode->HDisplay)
+ maxX = mode->HDisplay;
+ if (maxY < mode->VDisplay)
+ maxY = mode->VDisplay;
+ }
+ if (mode == scrp->modes)
+ refresh0 = refresh;
+ pSize = RRRegisterSize (pScreen,
+ mode->HDisplay, mode->VDisplay,
+ randrp->mmWidth, randrp->mmHeight);
+ if (!pSize)
+ return FALSE;
+ RRRegisterRate (pScreen, pSize, refresh);
+
+ if (xf86ModesEqual(mode, scrp->currentMode))
+ {
+ RRSetCurrentConfig (pScreen, randrp->rotation, refresh, pSize);
+ }
+ if (mode->next == scrp->modes)
+ break;
+ }
+
+ if (randrp->maxX == 0 || randrp->maxY == 0)
+ {
+ randrp->maxX = maxX;
+ randrp->maxY = maxY;
+ }
+
+ return TRUE;
+}
+
+static Bool
+xf86RandR12SetMode (ScreenPtr pScreen,
+ DisplayModePtr mode,
+ Bool useVirtual,
+ int mmWidth,
+ int mmHeight)
+{
+ ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ int oldWidth = pScreen->width;
+ int oldHeight = pScreen->height;
+ int oldmmWidth = pScreen->mmWidth;
+ int oldmmHeight = pScreen->mmHeight;
+ WindowPtr pRoot = WindowTable[pScreen->myNum];
+ DisplayModePtr currentMode = NULL;
+ Bool ret = TRUE;
+ PixmapPtr pspix = NULL;
+
+ if (pRoot)
+ (*scrp->EnableDisableFBAccess) (pScreen->myNum, FALSE);
+ if (useVirtual)
+ {
+ scrp->virtualX = randrp->virtualX;
+ scrp->virtualY = randrp->virtualY;
+ }
+ else
+ {
+ scrp->virtualX = mode->HDisplay;
+ scrp->virtualY = mode->VDisplay;
+ }
+
+ if(randrp->rotation & (RR_Rotate_90 | RR_Rotate_270))
+ {
+ /* If the screen is rotated 90 or 270 degrees, swap the sizes. */
+ pScreen->width = scrp->virtualY;
+ pScreen->height = scrp->virtualX;
+ pScreen->mmWidth = mmHeight;
+ pScreen->mmHeight = mmWidth;
+ }
+ else
+ {
+ pScreen->width = scrp->virtualX;
+ pScreen->height = scrp->virtualY;
+ pScreen->mmWidth = mmWidth;
+ pScreen->mmHeight = mmHeight;
+ }
+ if (scrp->currentMode == mode) {
+ /* Save current mode */
+ currentMode = scrp->currentMode;
+ /* Reset, just so we ensure the drivers SwitchMode is called */
+ scrp->currentMode = NULL;
+ }
+ /*
+ * We know that if the driver failed to SwitchMode to the rotated
+ * version, then it should revert back to it's prior mode.
+ */
+ if (!xf86SwitchMode (pScreen, mode))
+ {
+ ret = FALSE;
+ scrp->virtualX = pScreen->width = oldWidth;
+ scrp->virtualY = pScreen->height = oldHeight;
+ pScreen->mmWidth = oldmmWidth;
+ pScreen->mmHeight = oldmmHeight;
+ scrp->currentMode = currentMode;
+ }
+ /*
+ * Get the new Screen pixmap ptr as SwitchMode might have called
+ * ModifyPixmapHeader and xf86EnableDisableFBAccess will put it back...
+ * Unfortunately.
+ */
+ pspix = (*pScreen->GetScreenPixmap) (pScreen);
+ if (pspix->devPrivate.ptr)
+ scrp->pixmapPrivate = pspix->devPrivate;
+
+ /*
+ * Make sure the layout is correct
+ */
+ xf86ReconfigureLayout();
+
+ /*
+ * Make sure the whole screen is visible
+ */
+ xf86SetViewport (pScreen, pScreen->width, pScreen->height);
+ xf86SetViewport (pScreen, 0, 0);
+ if (pRoot)
+ (*scrp->EnableDisableFBAccess) (pScreen->myNum, TRUE);
+ return ret;
+}
+
+Bool
+xf86RandR12SetConfig (ScreenPtr pScreen,
+ Rotation rotation,
+ int rate,
+ RRScreenSizePtr pSize)
+{
+ ScrnInfoPtr scrp = XF86SCRNINFO(pScreen);
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ DisplayModePtr mode;
+ int px, py;
+ Bool useVirtual = FALSE;
+ int maxX = 0, maxY = 0;
+ Rotation oldRotation = randrp->rotation;
+
+ randrp->rotation = rotation;
+
+ if (randrp->virtualX == -1 || randrp->virtualY == -1)
+ {
+ randrp->virtualX = scrp->virtualX;
+ randrp->virtualY = scrp->virtualY;
+ }
+
+ miPointerGetPosition (inputInfo.pointer, &px, &py);
+ for (mode = scrp->modes; ; mode = mode->next)
+ {
+ if (randrp->maxX == 0 || randrp->maxY == 0)
+ {
+ if (maxX < mode->HDisplay)
+ maxX = mode->HDisplay;
+ if (maxY < mode->VDisplay)
+ maxY = mode->VDisplay;
+ }
+ if (mode->HDisplay == pSize->width &&
+ mode->VDisplay == pSize->height &&
+ (rate == 0 || xf86RandR12ModeRefresh (mode) == rate))
+ break;
+ if (mode->next == scrp->modes)
+ {
+ if (pSize->width == randrp->virtualX &&
+ pSize->height == randrp->virtualY)
+ {
+ mode = scrp->modes;
+ useVirtual = TRUE;
+ break;
+ }
+ if (randrp->maxX == 0 || randrp->maxY == 0)
+ {
+ randrp->maxX = maxX;
+ randrp->maxY = maxY;
+ }
+ return FALSE;
+ }
+ }
+
+ if (randrp->maxX == 0 || randrp->maxY == 0)
+ {
+ randrp->maxX = maxX;
+ randrp->maxY = maxY;
+ }
+
+ if (!xf86RandR12SetMode (pScreen, mode, useVirtual, pSize->mmWidth,
+ pSize->mmHeight)) {
+ randrp->rotation = oldRotation;
+ return FALSE;
+ }
+
+ /*
+ * Move the cursor back where it belongs; SwitchMode repositions it
+ */
+ if (pScreen == miPointerGetScreen(inputInfo.pointer))
+ {
+ px = (px >= pScreen->width ? (pScreen->width - 1) : px);
+ py = (py >= pScreen->height ? (pScreen->height - 1) : py);
+
+ xf86SetViewport(pScreen, px, py);
+
+ (*pScreen->SetCursorPosition) (inputInfo.pointer, pScreen, px, py, FALSE);
+ }
+
+ return TRUE;
+}
+
+static Bool
+xf86RandR12ScreenSetSize (ScreenPtr pScreen,
+ CARD16 width,
+ CARD16 height,
+ CARD32 mmWidth,
+ CARD32 mmHeight)
+{
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen);
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ WindowPtr pRoot = WindowTable[pScreen->myNum];
+ PixmapPtr pScrnPix = (*pScreen->GetScreenPixmap)(pScreen);
+ Bool ret = FALSE;
+ int c;
+
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
+ if (xf86RandR12Key) {
+#endif
+ if (randrp->virtualX == -1 || randrp->virtualY == -1)
+ {
+ randrp->virtualX = pScrn->virtualX;
+ randrp->virtualY = pScrn->virtualY;
+ }
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
+ }
+#endif
+ if (pRoot && pScrn->vtSema)
+ (*pScrn->EnableDisableFBAccess) (pScreen->myNum, FALSE);
+
+ /* Let the driver update virtualX and virtualY */
+ if (!(*config->funcs->resize)(pScrn, width, height))
+ goto finish;
+
+ ret = TRUE;
+ /* Update panning information */
+ for (c = 0; c < config->num_crtc; c++) {
+ xf86CrtcPtr crtc = config->crtc[c];
+ if (crtc->panningTotalArea.x2 > crtc->panningTotalArea.x1 ||
+ crtc->panningTotalArea.y2 > crtc->panningTotalArea.y1) {
+ if (crtc->panningTotalArea.x2 > crtc->panningTrackingArea.x1)
+ crtc->panningTotalArea.x2 += width - pScreen->width;
+ if (crtc->panningTotalArea.y2 > crtc->panningTrackingArea.y1)
+ crtc->panningTotalArea.y2 += height - pScreen->height;
+ if (crtc->panningTrackingArea.x2 > crtc->panningTrackingArea.x1)
+ crtc->panningTrackingArea.x2 += width - pScreen->width;
+ if (crtc->panningTrackingArea.y2 > crtc->panningTrackingArea.y1)
+ crtc->panningTrackingArea.y2 += height - pScreen->height;
+ xf86RandR13VerifyPanningArea (crtc, width, height);
+ xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
+ }
+ }
+
+ pScreen->width = pScrnPix->drawable.width = width;
+ pScreen->height = pScrnPix->drawable.height = height;
+ randrp->mmWidth = pScreen->mmWidth = mmWidth;
+ randrp->mmHeight = pScreen->mmHeight = mmHeight;
+
+ xf86SetViewport (pScreen, pScreen->width-1, pScreen->height-1);
+ xf86SetViewport (pScreen, 0, 0);
+
+finish:
+ if (pRoot && pScrn->vtSema)
+ (*pScrn->EnableDisableFBAccess) (pScreen->myNum, TRUE);
+#if RANDR_12_INTERFACE
+ if (xf86RandR12Key && WindowTable[pScreen->myNum] && ret)
+ RRScreenSizeNotify (pScreen);
+#endif
+ return ret;
+}
+
+Rotation
+xf86RandR12GetRotation(ScreenPtr pScreen)
+{
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+
+ return randrp->rotation;
+}
+
+Bool
+xf86RandR12CreateScreenResources (ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ xf86CrtcConfigPtr config;
+ XF86RandRInfoPtr randrp;
+ int c;
+ int width, height;
+ int mmWidth, mmHeight;
+#ifdef PANORAMIX
+ /* XXX disable RandR when using Xinerama */
+ if (!noPanoramiXExtension)
+ return TRUE;
+#endif
+
+ config = XF86_CRTC_CONFIG_PTR(pScrn);
+ randrp = XF86RANDRINFO(pScreen);
+ /*
+ * Compute size of screen
+ */
+ width = 0; height = 0;
+ for (c = 0; c < config->num_crtc; c++)
+ {
+ xf86CrtcPtr crtc = config->crtc[c];
+ int crtc_width = crtc->x + xf86ModeWidth (&crtc->mode, crtc->rotation);
+ int crtc_height = crtc->y + xf86ModeHeight (&crtc->mode, crtc->rotation);
+
+ if (crtc->enabled) {
+ if (crtc_width > width)
+ width = crtc_width;
+ if (crtc_height > height)
+ height = crtc_height;
+ if (crtc->panningTotalArea.x2 > width)
+ width = crtc->panningTotalArea.x2;
+ if (crtc->panningTotalArea.y2 > height)
+ height = crtc->panningTotalArea.y2;
+ }
+ }
+
+ if (width && height)
+ {
+ /*
+ * Compute physical size of screen
+ */
+ if (monitorResolution)
+ {
+ mmWidth = width * 25.4 / monitorResolution;
+ mmHeight = height * 25.4 / monitorResolution;
+ }
+ else
+ {
+ xf86OutputPtr output = xf86CompatOutput(pScrn);
+
+ if (output &&
+ output->conf_monitor &&
+ (output->conf_monitor->mon_width > 0 &&
+ output->conf_monitor->mon_height > 0))
+ {
+ /*
+ * Prefer user configured DisplaySize
+ */
+ mmWidth = output->conf_monitor->mon_width;
+ mmHeight = output->conf_monitor->mon_height;
+ }
+ else
+ {
+ /*
+ * Otherwise, just set the screen to DEFAULT_DPI
+ */
+ mmWidth = width * 25.4 / DEFAULT_DPI;
+ mmHeight = height * 25.4 / DEFAULT_DPI;
+ }
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Setting screen physical size to %d x %d\n",
+ mmWidth, mmHeight);
+ /*
+ * This is the initial setting of the screen size.
+ * We have to pre-set it here, otherwise panning would be adapted
+ * to the new screen size.
+ */
+ pScreen->width = width;
+ pScreen->height = height;
+ xf86RandR12ScreenSetSize (pScreen,
+ width,
+ height,
+ mmWidth,
+ mmHeight);
+ }
+
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
+ if (xf86RandR12Key == NULL)
+ return TRUE;
+#endif
+
+ if (randrp->virtualX == -1 || randrp->virtualY == -1)
+ {
+ randrp->virtualX = pScrn->virtualX;
+ randrp->virtualY = pScrn->virtualY;
+ }
+ xf86CrtcSetScreenSubpixelOrder (pScreen);
+#if RANDR_12_INTERFACE
+ if (xf86RandR12CreateScreenResources12 (pScreen))
+ return TRUE;
+#endif
+ return TRUE;
+}
+
+
+Bool
+xf86RandR12Init (ScreenPtr pScreen)
+{
+ rrScrPrivPtr rp;
+ XF86RandRInfoPtr randrp;
+
+#ifdef PANORAMIX
+ /* XXX disable RandR when using Xinerama */
+ if (!noPanoramiXExtension)
+ {
+ if (xf86NumScreens == 1)
+ noPanoramiXExtension = TRUE;
+ else
+ return TRUE;
+ }
+#endif
+
+ if (xf86RandR12Generation != serverGeneration)
+ xf86RandR12Generation = serverGeneration;
+
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
+ xf86RandR12Key = &xf86RandR12KeyIndex;
+#else
+ xf86RandR12Index = AllocateScreenPrivateIndex();
+#endif
+
+ randrp = malloc(sizeof (XF86RandRInfoRec));
+ if (!randrp)
+ return FALSE;
+
+ if (!RRScreenInit(pScreen))
+ {
+ free(randrp);
+ return FALSE;
+ }
+ rp = rrGetScrPriv(pScreen);
+ rp->rrGetInfo = xf86RandR12GetInfo;
+ rp->rrSetConfig = xf86RandR12SetConfig;
+
+ randrp->virtualX = -1;
+ randrp->virtualY = -1;
+ randrp->mmWidth = pScreen->mmWidth;
+ randrp->mmHeight = pScreen->mmHeight;
+
+ randrp->rotation = RR_Rotate_0; /* initial rotated mode */
+
+ randrp->supported_rotations = RR_Rotate_0;
+
+ randrp->maxX = randrp->maxY = 0;
+
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
+ dixSetPrivate(&pScreen->devPrivates, xf86RandR12Key, randrp);
+#else
+ pScreen->devPrivates[xf86RandR12Index].ptr = randrp;
+#endif
+
+#if RANDR_12_INTERFACE
+ if (!xf86RandR12Init12 (pScreen))
+ return FALSE;
+#endif
+ return TRUE;
+}
+
+void
+xf86RandR12SetRotations (ScreenPtr pScreen, Rotation rotations)
+{
+ XF86RandRInfoPtr randrp;
+#if RANDR_12_INTERFACE
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ int c;
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+#endif
+
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
+ if (xf86RandR12Key == NULL)
+ return;
+#endif
+
+ randrp = XF86RANDRINFO(pScreen);
+#if RANDR_12_INTERFACE
+ for (c = 0; c < config->num_crtc; c++) {
+ xf86CrtcPtr crtc = config->crtc[c];
+
+ RRCrtcSetRotations (crtc->randr_crtc, rotations);
+ }
+#endif
+ randrp->supported_rotations = rotations;
+}
+
+void
+xf86RandR12SetTransformSupport (ScreenPtr pScreen, Bool transforms)
+{
+ XF86RandRInfoPtr randrp;
+#if RANDR_13_INTERFACE
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ int c;
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+#endif
+
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
+ if (xf86RandR12Key == NULL)
+ return;
+#endif
+
+ randrp = XF86RANDRINFO(pScreen);
+#if RANDR_13_INTERFACE
+ for (c = 0; c < config->num_crtc; c++) {
+ xf86CrtcPtr crtc = config->crtc[c];
+
+ RRCrtcSetTransformSupport (crtc->randr_crtc, transforms);
+ }
+#endif
+}
+
+void
+xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr pScrn, int *x, int *y)
+{
+ ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
+
+ if (xf86RandR12Generation != serverGeneration ||
+ XF86RANDRINFO(pScreen)->virtualX == -1)
+ {
+ *x = pScrn->virtualX;
+ *y = pScrn->virtualY;
+ } else {
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+
+ *x = randrp->virtualX;
+ *y = randrp->virtualY;
+ }
+}
+
+#if RANDR_12_INTERFACE
+
+#define FLAG_BITS (RR_HSyncPositive | \
+ RR_HSyncNegative | \
+ RR_VSyncPositive | \
+ RR_VSyncNegative | \
+ RR_Interlace | \
+ RR_DoubleScan | \
+ RR_CSync | \
+ RR_CSyncPositive | \
+ RR_CSyncNegative | \
+ RR_HSkewPresent | \
+ RR_BCast | \
+ RR_PixelMultiplex | \
+ RR_DoubleClock | \
+ RR_ClockDivideBy2)
+
+static Bool
+xf86RandRModeMatches (RRModePtr randr_mode,
+ DisplayModePtr mode)
+{
+#if 0
+ if (match_name)
+ {
+ /* check for same name */
+ int len = strlen (mode->name);
+ if (randr_mode->mode.nameLength != len) return FALSE;
+ if (memcmp (randr_mode->name, mode->name, len) != 0) return FALSE;
+ }
+#endif
+
+ /* check for same timings */
+ if (randr_mode->mode.dotClock / 1000 != mode->Clock) return FALSE;
+ if (randr_mode->mode.width != mode->HDisplay) return FALSE;
+ if (randr_mode->mode.hSyncStart != mode->HSyncStart) return FALSE;
+ if (randr_mode->mode.hSyncEnd != mode->HSyncEnd) return FALSE;
+ if (randr_mode->mode.hTotal != mode->HTotal) return FALSE;
+ if (randr_mode->mode.hSkew != mode->HSkew) return FALSE;
+ if (randr_mode->mode.height != mode->VDisplay) return FALSE;
+ if (randr_mode->mode.vSyncStart != mode->VSyncStart) return FALSE;
+ if (randr_mode->mode.vSyncEnd != mode->VSyncEnd) return FALSE;
+ if (randr_mode->mode.vTotal != mode->VTotal) return FALSE;
+
+ /* check for same flags (using only the XF86 valid flag bits) */
+ if ((randr_mode->mode.modeFlags & FLAG_BITS) != (mode->Flags & FLAG_BITS))
+ return FALSE;
+
+ /* everything matches */
+ return TRUE;
+}
+
+static Bool
+xf86RandR12CrtcNotify (RRCrtcPtr randr_crtc)
+{
+ ScreenPtr pScreen = randr_crtc->pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ RRModePtr randr_mode = NULL;
+ int x;
+ int y;
+ Rotation rotation;
+ int numOutputs;
+ RROutputPtr *randr_outputs;
+ RROutputPtr randr_output;
+ xf86CrtcPtr crtc = randr_crtc->devPrivate;
+ xf86OutputPtr output;
+ int i, j;
+ DisplayModePtr mode = &crtc->mode;
+ Bool ret;
+
+ randr_outputs = malloc(config->num_output * sizeof (RROutputPtr));
+ if (!randr_outputs)
+ return FALSE;
+ x = crtc->x;
+ y = crtc->y;
+ rotation = crtc->rotation;
+ numOutputs = 0;
+ randr_mode = NULL;
+ for (i = 0; i < config->num_output; i++)
+ {
+ output = config->output[i];
+ if (output->crtc == crtc)
+ {
+ randr_output = output->randr_output;
+ randr_outputs[numOutputs++] = randr_output;
+ /*
+ * We make copies of modes, so pointer equality
+ * isn't sufficient
+ */
+ for (j = 0; j < randr_output->numModes + randr_output->numUserModes; j++)
+ {
+ RRModePtr m = (j < randr_output->numModes ?
+ randr_output->modes[j] :
+ randr_output->userModes[j-randr_output->numModes]);
+
+ if (xf86RandRModeMatches (m, mode))
+ {
+ randr_mode = m;
+ break;
+ }
+ }
+ }
+ }
+ ret = RRCrtcNotify (randr_crtc, randr_mode, x, y,
+ rotation,
+ crtc->transformPresent ? &crtc->transform : NULL,
+ numOutputs, randr_outputs);
+ free(randr_outputs);
+ return ret;
+}
+
+/*
+ * Convert a RandR mode to a DisplayMode
+ */
+static void
+xf86RandRModeConvert (ScrnInfoPtr scrn,
+ RRModePtr randr_mode,
+ DisplayModePtr mode)
+{
+ memset(mode, 0, sizeof(DisplayModeRec));
+ mode->status = MODE_OK;
+
+ mode->Clock = randr_mode->mode.dotClock / 1000;
+
+ mode->HDisplay = randr_mode->mode.width;
+ mode->HSyncStart = randr_mode->mode.hSyncStart;
+ mode->HSyncEnd = randr_mode->mode.hSyncEnd;
+ mode->HTotal = randr_mode->mode.hTotal;
+ mode->HSkew = randr_mode->mode.hSkew;
+
+ mode->VDisplay = randr_mode->mode.height;
+ mode->VSyncStart = randr_mode->mode.vSyncStart;
+ mode->VSyncEnd = randr_mode->mode.vSyncEnd;
+ mode->VTotal = randr_mode->mode.vTotal;
+ mode->VScan = 0;
+
+ mode->Flags = randr_mode->mode.modeFlags & FLAG_BITS;
+
+ xf86SetModeCrtc (mode, scrn->adjustFlags);
+}
+
+static Bool
+xf86RandR12CrtcSet (ScreenPtr pScreen,
+ RRCrtcPtr randr_crtc,
+ RRModePtr randr_mode,
+ int x,
+ int y,
+ Rotation rotation,
+ int num_randr_outputs,
+ RROutputPtr *randr_outputs)
+{
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ xf86CrtcPtr crtc = randr_crtc->devPrivate;
+ RRTransformPtr transform;
+ Bool changed = FALSE;
+ int o, ro;
+ xf86CrtcPtr *save_crtcs;
+ Bool save_enabled = crtc->enabled;
+
+ if (!crtc->scrn->vtSema)
+ return FALSE;
+
+ save_crtcs = malloc(config->num_output * sizeof (xf86CrtcPtr));
+ if ((randr_mode != NULL) != crtc->enabled)
+ changed = TRUE;
+ else if (randr_mode && !xf86RandRModeMatches (randr_mode, &crtc->mode))
+ changed = TRUE;
+
+ if (rotation != crtc->rotation)
+ changed = TRUE;
+
+ transform = RRCrtcGetTransform (randr_crtc);
+ if ((transform != NULL) != crtc->transformPresent)
+ changed = TRUE;
+ else if (transform && memcmp (&transform->transform, &crtc->transform.transform,
+ sizeof (transform->transform)) != 0)
+ changed = TRUE;
+
+ if (x != crtc->x || y != crtc->y)
+ changed = TRUE;
+ for (o = 0; o < config->num_output; o++)
+ {
+ xf86OutputPtr output = config->output[o];
+ xf86CrtcPtr new_crtc;
+
+ save_crtcs[o] = output->crtc;
+
+ if (output->crtc == crtc)
+ new_crtc = NULL;
+ else
+ new_crtc = output->crtc;
+ for (ro = 0; ro < num_randr_outputs; ro++)
+ if (output->randr_output == randr_outputs[ro])
+ {
+ new_crtc = crtc;
+ break;
+ }
+ if (new_crtc != output->crtc)
+ {
+ changed = TRUE;
+ output->crtc = new_crtc;
+ }
+ }
+ for (ro = 0; ro < num_randr_outputs; ro++)
+ if (randr_outputs[ro]->pendingProperties)
+ changed = TRUE;
+
+ /* XXX need device-independent mode setting code through an API */
+ if (changed)
+ {
+ crtc->enabled = randr_mode != NULL;
+
+ if (randr_mode)
+ {
+ DisplayModeRec mode;
+ RRTransformPtr transform = RRCrtcGetTransform (randr_crtc);
+
+ xf86RandRModeConvert (pScrn, randr_mode, &mode);
+ if (!xf86CrtcSetModeTransform (crtc, &mode, rotation, transform, x, y))
+ {
+ crtc->enabled = save_enabled;
+ for (o = 0; o < config->num_output; o++)
+ {
+ xf86OutputPtr output = config->output[o];
+ output->crtc = save_crtcs[o];
+ }
+ free(save_crtcs);
+ return FALSE;
+ }
+ xf86RandR13VerifyPanningArea (crtc, pScreen->width, pScreen->height);
+ xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
+ /*
+ * Save the last successful setting for EnterVT
+ */
+ crtc->desiredMode = mode;
+ crtc->desiredRotation = rotation;
+ if (transform) {
+ crtc->desiredTransform = *transform;
+ crtc->desiredTransformPresent = TRUE;
+ } else
+ crtc->desiredTransformPresent = FALSE;
+
+ crtc->desiredX = x;
+ crtc->desiredY = y;
+ }
+ xf86DisableUnusedFunctions (pScrn);
+ }
+ free(save_crtcs);
+ return xf86RandR12CrtcNotify (randr_crtc);
+}
+
+static Bool
+xf86RandR12CrtcSetGamma (ScreenPtr pScreen,
+ RRCrtcPtr randr_crtc)
+{
+ xf86CrtcPtr crtc = randr_crtc->devPrivate;
+
+ if (crtc->funcs->gamma_set == NULL)
+ return FALSE;
+
+ if (!crtc->scrn->vtSema)
+ return TRUE;
+
+ /* Realloc local gamma if needed. */
+ if (randr_crtc->gammaSize != crtc->gamma_size) {
+ CARD16 *tmp_ptr;
+ tmp_ptr = realloc(crtc->gamma_red, 3 * crtc->gamma_size * sizeof (CARD16));
+ if (!tmp_ptr)
+ return FALSE;
+ crtc->gamma_red = tmp_ptr;
+ crtc->gamma_green = crtc->gamma_red + crtc->gamma_size;
+ crtc->gamma_blue = crtc->gamma_green + crtc->gamma_size;
+ }
+
+ crtc->gamma_size = randr_crtc->gammaSize;
+ memcpy (crtc->gamma_red, randr_crtc->gammaRed, crtc->gamma_size * sizeof (CARD16));
+ memcpy (crtc->gamma_green, randr_crtc->gammaGreen, crtc->gamma_size * sizeof (CARD16));
+ memcpy (crtc->gamma_blue, randr_crtc->gammaBlue, crtc->gamma_size * sizeof (CARD16));
+
+ /* Only set it when the crtc is actually running.
+ * Otherwise it will be set when it's activated.
+ */
+ if (crtc->active)
+ crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green,
+ crtc->gamma_blue, crtc->gamma_size);
+
+ return TRUE;
+}
+
+static Bool
+xf86RandR12CrtcGetGamma (ScreenPtr pScreen,
+ RRCrtcPtr randr_crtc)
+{
+ xf86CrtcPtr crtc = randr_crtc->devPrivate;
+
+ if (!crtc->gamma_size)
+ return FALSE;
+
+ if (!crtc->gamma_red || !crtc->gamma_green || !crtc->gamma_blue)
+ return FALSE;
+
+ /* Realloc randr gamma if needed. */
+ if (randr_crtc->gammaSize != crtc->gamma_size) {
+ CARD16 *tmp_ptr;
+ tmp_ptr = realloc(randr_crtc->gammaRed, 3 * crtc->gamma_size * sizeof (CARD16));
+ if (!tmp_ptr)
+ return FALSE;
+ randr_crtc->gammaRed = tmp_ptr;
+ randr_crtc->gammaGreen = randr_crtc->gammaRed + crtc->gamma_size;
+ randr_crtc->gammaBlue = randr_crtc->gammaGreen + crtc->gamma_size;
+ }
+ randr_crtc->gammaSize = crtc->gamma_size;
+ memcpy (randr_crtc->gammaRed, crtc->gamma_red, crtc->gamma_size * sizeof (CARD16));
+ memcpy (randr_crtc->gammaGreen, crtc->gamma_green, crtc->gamma_size * sizeof (CARD16));
+ memcpy (randr_crtc->gammaBlue, crtc->gamma_blue, crtc->gamma_size * sizeof (CARD16));
+
+ return TRUE;
+}
+
+static Bool
+xf86RandR12OutputSetProperty (ScreenPtr pScreen,
+ RROutputPtr randr_output,
+ Atom property,
+ RRPropertyValuePtr value)
+{
+ xf86OutputPtr output = randr_output->devPrivate;
+
+ /* If we don't have any property handler, then we don't care what the
+ * user is setting properties to.
+ */
+ if (output->funcs->set_property == NULL)
+ return TRUE;
+
+ /*
+ * This function gets called even when vtSema is FALSE, as
+ * drivers will need to remember the correct value to apply
+ * when the VT switch occurs
+ */
+ return output->funcs->set_property(output, property, value);
+}
+
+static Bool
+xf86RandR13OutputGetProperty (ScreenPtr pScreen,
+ RROutputPtr randr_output,
+ Atom property)
+{
+ xf86OutputPtr output = randr_output->devPrivate;
+
+ if (output->funcs->get_property == NULL)
+ return TRUE;
+
+ /* Should be safe even w/o vtSema */
+ return output->funcs->get_property(output, property);
+}
+
+static Bool
+xf86RandR12OutputValidateMode (ScreenPtr pScreen,
+ RROutputPtr randr_output,
+ RRModePtr randr_mode)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ xf86OutputPtr output = randr_output->devPrivate;
+ DisplayModeRec mode;
+
+ xf86RandRModeConvert (pScrn, randr_mode, &mode);
+ /*
+ * This function may be called when vtSema is FALSE, so
+ * the underlying function must either avoid touching the hardware
+ * or return FALSE when vtSema is FALSE
+ */
+ if (output->funcs->mode_valid (output, &mode) != MODE_OK)
+ return FALSE;
+ return TRUE;
+}
+
+static void
+xf86RandR12ModeDestroy (ScreenPtr pScreen, RRModePtr randr_mode)
+{
+}
+
+/**
+ * Given a list of xf86 modes and a RandR Output object, construct
+ * RandR modes and assign them to the output
+ */
+static Bool
+xf86RROutputSetModes (RROutputPtr randr_output, DisplayModePtr modes)
+{
+ DisplayModePtr mode;
+ RRModePtr *rrmodes = NULL;
+ int nmode = 0;
+ int npreferred = 0;
+ Bool ret = TRUE;
+ int pref;
+
+ for (mode = modes; mode; mode = mode->next)
+ nmode++;
+
+ if (nmode) {
+ rrmodes = malloc(nmode * sizeof (RRModePtr));
+
+ if (!rrmodes)
+ return FALSE;
+ nmode = 0;
+
+ for (pref = 1; pref >= 0; pref--) {
+ for (mode = modes; mode; mode = mode->next) {
+ if ((pref != 0) == ((mode->type & M_T_PREFERRED) != 0)) {
+ xRRModeInfo modeInfo;
+ RRModePtr rrmode;
+
+ modeInfo.nameLength = strlen (mode->name);
+ modeInfo.width = mode->HDisplay;
+ modeInfo.dotClock = mode->Clock * 1000;
+ modeInfo.hSyncStart = mode->HSyncStart;
+ modeInfo.hSyncEnd = mode->HSyncEnd;
+ modeInfo.hTotal = mode->HTotal;
+ modeInfo.hSkew = mode->HSkew;
+
+ modeInfo.height = mode->VDisplay;
+ modeInfo.vSyncStart = mode->VSyncStart;
+ modeInfo.vSyncEnd = mode->VSyncEnd;
+ modeInfo.vTotal = mode->VTotal;
+ modeInfo.modeFlags = mode->Flags;
+
+ rrmode = RRModeGet (&modeInfo, mode->name);
+ if (rrmode) {
+ rrmodes[nmode++] = rrmode;
+ npreferred += pref;
+ }
+ }
+ }
+ }
+ }
+
+ ret = RROutputSetModes (randr_output, rrmodes, nmode, npreferred);
+ free(rrmodes);
+ return ret;
+}
+
+/*
+ * Mirror the current mode configuration to RandR
+ */
+static Bool
+xf86RandR12SetInfo12 (ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ RROutputPtr *clones;
+ RRCrtcPtr *crtcs;
+ int ncrtc;
+ int o, c, l;
+ RRCrtcPtr randr_crtc;
+ int nclone;
+
+ clones = malloc(config->num_output * sizeof (RROutputPtr));
+ crtcs = malloc(config->num_crtc * sizeof (RRCrtcPtr));
+ for (o = 0; o < config->num_output; o++)
+ {
+ xf86OutputPtr output = config->output[o];
+
+ ncrtc = 0;
+ for (c = 0; c < config->num_crtc; c++)
+ if (output->possible_crtcs & (1 << c))
+ crtcs[ncrtc++] = config->crtc[c]->randr_crtc;
+
+ if (output->crtc)
+ randr_crtc = output->crtc->randr_crtc;
+ else
+ randr_crtc = NULL;
+
+ if (!RROutputSetCrtcs (output->randr_output, crtcs, ncrtc))
+ {
+ free(crtcs);
+ free(clones);
+ return FALSE;
+ }
+
+ RROutputSetPhysicalSize(output->randr_output,
+ output->mm_width,
+ output->mm_height);
+ xf86RROutputSetModes (output->randr_output, output->probed_modes);
+
+ switch (output->status) {
+ case XF86OutputStatusConnected:
+ RROutputSetConnection (output->randr_output, RR_Connected);
+ break;
+ case XF86OutputStatusDisconnected:
+ RROutputSetConnection (output->randr_output, RR_Disconnected);
+ break;
+ case XF86OutputStatusUnknown:
+ RROutputSetConnection (output->randr_output, RR_UnknownConnection);
+ break;
+ }
+
+ RROutputSetSubpixelOrder (output->randr_output, output->subpixel_order);
+
+ /*
+ * Valid clones
+ */
+ nclone = 0;
+ for (l = 0; l < config->num_output; l++)
+ {
+ xf86OutputPtr clone = config->output[l];
+
+ if (l != o && (output->possible_clones & (1 << l)))
+ clones[nclone++] = clone->randr_output;
+ }
+ if (!RROutputSetClones (output->randr_output, clones, nclone))
+ {
+ free(crtcs);
+ free(clones);
+ return FALSE;
+ }
+ }
+ free(crtcs);
+ free(clones);
+ return TRUE;
+}
+
+
+
+/*
+ * Query the hardware for the current state, then mirror
+ * that to RandR
+ */
+static Bool
+xf86RandR12GetInfo12 (ScreenPtr pScreen, Rotation *rotations)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+
+ if (!pScrn->vtSema)
+ return TRUE;
+ xf86ProbeOutputModes (pScrn, 0, 0);
+ xf86SetScrnInfoModes (pScrn);
+ return xf86RandR12SetInfo12 (pScreen);
+}
+
+static Bool
+xf86RandR12CreateObjects12 (ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int c;
+ int o;
+
+ if (!RRInit ())
+ return FALSE;
+
+ /*
+ * Configure crtcs
+ */
+ for (c = 0; c < config->num_crtc; c++)
+ {
+ xf86CrtcPtr crtc = config->crtc[c];
+
+ crtc->randr_crtc = RRCrtcCreate (pScreen, crtc);
+ RRCrtcGammaSetSize (crtc->randr_crtc, 256);
+ }
+ /*
+ * Configure outputs
+ */
+ for (o = 0; o < config->num_output; o++)
+ {
+ xf86OutputPtr output = config->output[o];
+
+ output->randr_output = RROutputCreate (pScreen, output->name,
+ strlen (output->name),
+ output);
+
+ if (output->funcs->create_resources != NULL)
+ output->funcs->create_resources(output);
+ RRPostPendingProperties (output->randr_output);
+ }
+ return TRUE;
+}
+
+static Bool
+xf86RandR12CreateScreenResources12 (ScreenPtr pScreen)
+{
+ int c;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
+ if (xf86RandR12Key == NULL)
+ return TRUE;
+#endif
+
+ for (c = 0; c < config->num_crtc; c++)
+ xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc);
+
+ RRScreenSetSizeRange (pScreen, config->minWidth, config->minHeight,
+ config->maxWidth, config->maxHeight);
+ return TRUE;
+}
+
+/*
+ * Something happened within the screen configuration due
+ * to DGA, VidMode or hot key. Tell RandR
+ */
+
+void
+xf86RandR12TellChanged (ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int c;
+
+#if XORG_VERSION_CURRENT < XORG_VERSION_NUMERIC(7,0,0,0,0)
+ if (xf86RandR12Key == NULL)
+ return;
+#else
+ if (!XF86RANDRINFO(pScreen))
+ return;
+#endif
+
+ xf86RandR12SetInfo12 (pScreen);
+ for (c = 0; c < config->num_crtc; c++)
+ xf86RandR12CrtcNotify (config->crtc[c]->randr_crtc);
+
+ RRTellChanged (pScreen);
+}
+
+static void
+xf86RandR12PointerMoved (int scrnIndex, int x, int y)
+{
+ ScreenPtr pScreen = screenInfo.screens[scrnIndex];
+ ScrnInfoPtr pScrn = XF86SCRNINFO(pScreen);
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ int c;
+
+ randrp->pointerX = x;
+ randrp->pointerY = y;
+ for (c = 0; c < config->num_crtc; c++)
+ xf86RandR13Pan (config->crtc[c], x, y);
+}
+
+static Bool
+xf86RandR13GetPanning (ScreenPtr pScreen,
+ RRCrtcPtr randr_crtc,
+ BoxPtr totalArea,
+ BoxPtr trackingArea,
+ INT16 *border)
+{
+ xf86CrtcPtr crtc = randr_crtc->devPrivate;
+
+ if (crtc->version < 2)
+ return FALSE;
+ if (totalArea)
+ memcpy (totalArea, &crtc->panningTotalArea, sizeof(BoxRec));
+ if (trackingArea)
+ memcpy (trackingArea, &crtc->panningTrackingArea, sizeof(BoxRec));
+ if (border)
+ memcpy (border, crtc->panningBorder, 4*sizeof(INT16));
+
+ return TRUE;
+}
+
+static Bool
+xf86RandR13SetPanning (ScreenPtr pScreen,
+ RRCrtcPtr randr_crtc,
+ BoxPtr totalArea,
+ BoxPtr trackingArea,
+ INT16 *border)
+{
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+ xf86CrtcPtr crtc = randr_crtc->devPrivate;
+ BoxRec oldTotalArea;
+ BoxRec oldTrackingArea;
+ INT16 oldBorder[4];
+
+
+ if (crtc->version < 2)
+ return FALSE;
+
+ memcpy (&oldTotalArea, &crtc->panningTotalArea, sizeof(BoxRec));
+ memcpy (&oldTrackingArea, &crtc->panningTrackingArea, sizeof(BoxRec));
+ memcpy (oldBorder, crtc->panningBorder, 4*sizeof(INT16));
+
+ if (totalArea)
+ memcpy (&crtc->panningTotalArea, totalArea, sizeof(BoxRec));
+ if (trackingArea)
+ memcpy (&crtc->panningTrackingArea, trackingArea, sizeof(BoxRec));
+ if (border)
+ memcpy (crtc->panningBorder, border, 4*sizeof(INT16));
+
+ if (xf86RandR13VerifyPanningArea (crtc, pScreen->width, pScreen->height)) {
+ xf86RandR13Pan (crtc, randrp->pointerX, randrp->pointerY);
+ return TRUE;
+ } else {
+ /* Restore old settings */
+ memcpy (&crtc->panningTotalArea, &oldTotalArea, sizeof(BoxRec));
+ memcpy (&crtc->panningTrackingArea, &oldTrackingArea, sizeof(BoxRec));
+ memcpy (crtc->panningBorder, oldBorder, 4*sizeof(INT16));
+ return FALSE;
+ }
+}
+
+/*
+ * Compatibility with XF86VidMode's gamma changer. This necessarily clobbers
+ * any per-crtc setup. You asked for it...
+ */
+
+static void
+gamma_to_ramp(float gamma, CARD16 *ramp, int size)
+{
+ int i;
+
+ for (i = 0; i < size; i++) {
+ if (gamma == 1.0)
+ ramp[i] = i << 8;
+ else
+ ramp[i] = (CARD16)(pow((double)i / (double)(size - 1), 1. / gamma)
+ * (double)(size - 1) * 256);
+ }
+}
+
+static int
+xf86RandR12ChangeGamma(int scrnIndex, Gamma gamma)
+{
+ CARD16 *points, *red, *green, *blue;
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ RRCrtcPtr crtc = xf86CompatRRCrtc(pScrn);
+ int size;
+
+ if (!crtc)
+ return Success;
+
+ size = max(0, crtc->gammaSize);
+ if (!size)
+ return Success;
+
+ points = calloc(size, 3 * sizeof(CARD16));
+ if (!points)
+ return BadAlloc;
+
+ red = points;
+ green = points + size;
+ blue = points + 2 * size;
+
+ gamma_to_ramp(gamma.red, red, size);
+ gamma_to_ramp(gamma.green, green, size);
+ gamma_to_ramp(gamma.blue, blue, size);
+ RRCrtcGammaSet(crtc, red, green, blue);
+
+ free(points);
+
+ pScrn->gamma = gamma;
+
+ return Success;
+}
+
+static Bool
+xf86RandR12EnterVT (int screen_index, int flags)
+{
+ ScreenPtr pScreen = screenInfo.screens[screen_index];
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+
+ if (randrp->orig_EnterVT) {
+ if (!randrp->orig_EnterVT (screen_index, flags))
+ return FALSE;
+ }
+
+ return RRGetInfo (pScreen, TRUE); /* force a re-probe of outputs and notify clients about changes */
+}
+
+static Bool
+xf86RandR12Init12 (ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ rrScrPrivPtr rp = rrGetScrPriv(pScreen);
+ XF86RandRInfoPtr randrp = XF86RANDRINFO(pScreen);
+
+ rp->rrGetInfo = xf86RandR12GetInfo12;
+ rp->rrScreenSetSize = xf86RandR12ScreenSetSize;
+ rp->rrCrtcSet = xf86RandR12CrtcSet;
+ rp->rrCrtcSetGamma = xf86RandR12CrtcSetGamma;
+ rp->rrCrtcGetGamma = xf86RandR12CrtcGetGamma;
+ rp->rrOutputSetProperty = xf86RandR12OutputSetProperty;
+ rp->rrOutputValidateMode = xf86RandR12OutputValidateMode;
+#if RANDR_13_INTERFACE
+ rp->rrOutputGetProperty = xf86RandR13OutputGetProperty;
+ rp->rrGetPanning = xf86RandR13GetPanning;
+ rp->rrSetPanning = xf86RandR13SetPanning;
+#endif
+ rp->rrModeDestroy = xf86RandR12ModeDestroy;
+ rp->rrSetConfig = NULL;
+ pScrn->PointerMoved = xf86RandR12PointerMoved;
+ pScrn->ChangeGamma = xf86RandR12ChangeGamma;
+
+ randrp->orig_EnterVT = pScrn->EnterVT;
+ pScrn->EnterVT = xf86RandR12EnterVT;
+
+ if (!xf86RandR12CreateObjects12 (pScreen))
+ return FALSE;
+
+ /*
+ * Configure output modes
+ */
+ if (!xf86RandR12SetInfo12 (pScreen))
+ return FALSE;
+ return TRUE;
+}
+
+#endif
+
+Bool
+xf86RandR12PreInit (ScrnInfoPtr pScrn)
+{
+ return TRUE;
+}
diff --git a/xorg-server/hw/xfree86/modes/xf86Rotate.c b/xorg-server/hw/xfree86/modes/xf86Rotate.c
index 5de6b0c00..e15c61476 100644
--- a/xorg-server/hw/xfree86/modes/xf86Rotate.c
+++ b/xorg-server/hw/xfree86/modes/xf86Rotate.c
@@ -1,527 +1,527 @@
-/*
- * Copyright © 2006 Keith Packard
- *
- * 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 the copyright holders not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. The copyright holders make no representations
- * about the suitability of this software for any purpose. It is provided "as
- * is" without express or implied warranty.
- *
- * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THE COPYRIGHT HOLDERS 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>
-#else
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#endif
-
-#include <stddef.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "xf86.h"
-#include "xf86DDC.h"
-#include "fb.h"
-#include "windowstr.h"
-#include "xf86Crtc.h"
-#include "xf86Modes.h"
-#include "xf86RandR12.h"
-#include "X11/extensions/render.h"
-#include "X11/extensions/dpmsconst.h"
-#include "X11/Xatom.h"
-
-/* borrowed from composite extension, move to Render and publish? */
-
-static VisualPtr
-compGetWindowVisual (WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- VisualID vid = wVisual (pWin);
- int i;
-
- for (i = 0; i < pScreen->numVisuals; i++)
- if (pScreen->visuals[i].vid == vid)
- return &pScreen->visuals[i];
- return 0;
-}
-
-static PictFormatPtr
-compWindowFormat (WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
-
- return PictureMatchVisual (pScreen, pWin->drawable.depth,
- compGetWindowVisual (pWin));
-}
-
-#define F(x) IntToxFixed(x)
-
-#define toF(x) ((float) (x) / 65536.0f)
-
-static void
-xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region)
-{
- ScrnInfoPtr scrn = crtc->scrn;
- ScreenPtr screen = scrn->pScreen;
- WindowPtr root = WindowTable[screen->myNum];
- PixmapPtr dst_pixmap = crtc->rotatedPixmap;
- PictFormatPtr format = compWindowFormat (WindowTable[screen->myNum]);
- int error;
- PicturePtr src, dst;
- int n = REGION_NUM_RECTS(region);
- BoxPtr b = REGION_RECTS(region);
- XID include_inferiors = IncludeInferiors;
-
- src = CreatePicture (None,
- &root->drawable,
- format,
- CPSubwindowMode,
- &include_inferiors,
- serverClient,
- &error);
- if (!src)
- return;
-
- dst = CreatePicture (None,
- &dst_pixmap->drawable,
- format,
- 0L,
- NULL,
- serverClient,
- &error);
- if (!dst)
- return;
-
- error = SetPictureTransform (src, &crtc->crtc_to_framebuffer);
- if (error)
- return;
- if (crtc->transform_in_use && crtc->filter)
- SetPicturePictFilter (src, crtc->filter,
- crtc->params, crtc->nparams);
-
- if (crtc->shadowClear)
- {
- CompositePicture (PictOpSrc,
- src, NULL, dst,
- 0, 0, 0, 0, 0, 0,
- crtc->mode.HDisplay, crtc->mode.VDisplay);
- crtc->shadowClear = FALSE;
- }
- else
- {
- while (n--)
- {
- BoxRec dst_box;
-
- dst_box = *b;
- dst_box.x1 -= crtc->filter_width >> 1;
- dst_box.x2 += crtc->filter_width >> 1;
- dst_box.y1 -= crtc->filter_height >> 1;
- dst_box.y2 += crtc->filter_height >> 1;
- pixman_f_transform_bounds (&crtc->f_framebuffer_to_crtc, &dst_box);
- CompositePicture (PictOpSrc,
- src, NULL, dst,
- dst_box.x1, dst_box.y1, 0, 0, dst_box.x1, dst_box.y1,
- dst_box.x2 - dst_box.x1,
- dst_box.y2 - dst_box.y1);
- b++;
- }
- }
- FreePicture (src, None);
- FreePicture (dst, None);
-}
-
-static void
-xf86CrtcDamageShadow (xf86CrtcPtr crtc)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- BoxRec damage_box;
- RegionRec damage_region;
- ScreenPtr pScreen = pScrn->pScreen;
-
- damage_box.x1 = 0;
- damage_box.x2 = crtc->mode.HDisplay;
- damage_box.y1 = 0;
- damage_box.y2 = crtc->mode.VDisplay;
- if (!pixman_transform_bounds (&crtc->crtc_to_framebuffer, &damage_box))
- {
- damage_box.x1 = 0;
- damage_box.y1 = 0;
- damage_box.x2 = pScreen->width;
- damage_box.y2 = pScreen->height;
- }
- if (damage_box.x1 < 0) damage_box.x1 = 0;
- if (damage_box.y1 < 0) damage_box.y1 = 0;
- if (damage_box.x2 > pScreen->width) damage_box.x2 = pScreen->width;
- if (damage_box.y2 > pScreen->height) damage_box.y2 = pScreen->height;
- REGION_INIT (pScreen, &damage_region, &damage_box, 1);
- DamageRegionAppend (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
- &damage_region);
- REGION_UNINIT (pScreen, &damage_region);
- crtc->shadowClear = TRUE;
-}
-
-static void
-xf86RotatePrepare (ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- int c;
-
- for (c = 0; c < xf86_config->num_crtc; c++)
- {
- xf86CrtcPtr crtc = xf86_config->crtc[c];
-
- if (crtc->rotatedData && !crtc->rotatedPixmap)
- {
- crtc->rotatedPixmap = crtc->funcs->shadow_create (crtc,
- crtc->rotatedData,
- crtc->mode.HDisplay,
- crtc->mode.VDisplay);
- if (!xf86_config->rotation_damage_registered)
- {
- /* Hook damage to screen pixmap */
- DamageRegister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
- xf86_config->rotation_damage);
- xf86_config->rotation_damage_registered = TRUE;
- EnableLimitedSchedulingLatency();
- }
-
- xf86CrtcDamageShadow (crtc);
- }
- }
-}
-
-static Bool
-xf86RotateRedisplay(ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- DamagePtr damage = xf86_config->rotation_damage;
- RegionPtr region;
-
- if (!damage)
- return FALSE;
- xf86RotatePrepare (pScreen);
- region = DamageRegion(damage);
- if (REGION_NOTEMPTY(pScreen, region))
- {
- int c;
- SourceValidateProcPtr SourceValidate;
-
- /*
- * SourceValidate is used by the software cursor code
- * to pull the cursor off of the screen when reading
- * bits from the frame buffer. Bypassing this function
- * leaves the software cursor in place
- */
- SourceValidate = pScreen->SourceValidate;
- pScreen->SourceValidate = NULL;
-
- for (c = 0; c < xf86_config->num_crtc; c++)
- {
- xf86CrtcPtr crtc = xf86_config->crtc[c];
-
- if (crtc->transform_in_use && crtc->enabled)
- {
- RegionRec crtc_damage;
-
- /* compute portion of damage that overlaps crtc */
- REGION_INIT(pScreen, &crtc_damage, &crtc->bounds, 1);
- REGION_INTERSECT (pScreen, &crtc_damage, &crtc_damage, region);
-
- /* update damaged region */
- if (REGION_NOTEMPTY(pScreen, &crtc_damage))
- xf86RotateCrtcRedisplay (crtc, &crtc_damage);
-
- REGION_UNINIT (pScreen, &crtc_damage);
- }
- }
- pScreen->SourceValidate = SourceValidate;
- DamageEmpty(damage);
- }
- return TRUE;
-}
-
-static void
-xf86RotateBlockHandler(int screenNum, pointer blockData,
- pointer pTimeout, pointer pReadmask)
-{
- ScreenPtr pScreen = screenInfo.screens[screenNum];
- ScrnInfoPtr pScrn = xf86Screens[screenNum];
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- Bool rotation_active;
-
- rotation_active = xf86RotateRedisplay(pScreen);
- pScreen->BlockHandler = xf86_config->BlockHandler;
- (*pScreen->BlockHandler) (screenNum, blockData, pTimeout, pReadmask);
- /* cannot avoid re-wrapping until all wrapping is audited */
- xf86_config->BlockHandler = pScreen->BlockHandler;
- pScreen->BlockHandler = xf86RotateBlockHandler;
-}
-
-void
-xf86RotateDestroy (xf86CrtcPtr crtc)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- ScreenPtr pScreen = pScrn->pScreen;
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- int c;
-
- /* Free memory from rotation */
- if (crtc->rotatedPixmap || crtc->rotatedData)
- {
- crtc->funcs->shadow_destroy (crtc, crtc->rotatedPixmap, crtc->rotatedData);
- crtc->rotatedPixmap = NULL;
- crtc->rotatedData = NULL;
- }
-
- for (c = 0; c < xf86_config->num_crtc; c++)
- if (xf86_config->crtc[c]->transform_in_use)
- return;
-
- /*
- * Clean up damage structures when no crtcs are rotated
- */
- if (xf86_config->rotation_damage)
- {
- /* Free damage structure */
- if (xf86_config->rotation_damage_registered)
- {
- DamageUnregister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
- xf86_config->rotation_damage);
- xf86_config->rotation_damage_registered = FALSE;
- DisableLimitedSchedulingLatency();
- }
- DamageDestroy (xf86_config->rotation_damage);
- xf86_config->rotation_damage = NULL;
- }
-}
-
-void
-xf86RotateFreeShadow(ScrnInfoPtr pScrn)
-{
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- int c;
-
- for (c = 0; c < config->num_crtc; c++) {
- xf86CrtcPtr crtc = config->crtc[c];
-
- if (crtc->rotatedPixmap || crtc->rotatedData) {
- crtc->funcs->shadow_destroy(crtc, crtc->rotatedPixmap,
- crtc->rotatedData);
- crtc->rotatedPixmap = NULL;
- crtc->rotatedData = NULL;
- }
- }
-}
-
-void
-xf86RotateCloseScreen (ScreenPtr screen)
-{
- ScrnInfoPtr scrn = xf86Screens[screen->myNum];
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
- int c;
-
- for (c = 0; c < xf86_config->num_crtc; c++)
- xf86RotateDestroy (xf86_config->crtc[c]);
-}
-
-static Bool
-xf86CrtcFitsScreen (xf86CrtcPtr crtc, struct pict_f_transform *crtc_to_fb)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- BoxRec b;
-
- /* When called before PreInit, the driver is
- * presumably doing load detect
- */
- if (pScrn->virtualX == 0 || pScrn->virtualY == 0)
- return TRUE;
-
- b.x1 = 0;
- b.y1 = 0;
- b.x2 = crtc->mode.HDisplay;
- b.y2 = crtc->mode.VDisplay;
- if (crtc_to_fb)
- pixman_f_transform_bounds (crtc_to_fb, &b);
- else {
- b.x1 += crtc->x;
- b.y1 += crtc->y;
- b.x2 += crtc->x;
- b.y2 += crtc->y;
- }
-
- return (0 <= b.x1 && b.x2 <= pScrn->virtualX &&
- 0 <= b.y1 && b.y2 <= pScrn->virtualY);
-}
-
-Bool
-xf86CrtcRotate (xf86CrtcPtr crtc)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- /* if this is called during ScreenInit() we don't have pScrn->pScreen yet */
- ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
- PictTransform crtc_to_fb;
- struct pict_f_transform f_crtc_to_fb, f_fb_to_crtc;
- xFixed *new_params = NULL;
- int new_nparams = 0;
- PictFilterPtr new_filter = NULL;
- int new_width = 0;
- int new_height = 0;
- RRTransformPtr transform = NULL;
- Bool damage = FALSE;
-
- if (crtc->transformPresent)
- transform = &crtc->transform;
-
- if (!RRTransformCompute (crtc->x, crtc->y,
- crtc->mode.HDisplay, crtc->mode.VDisplay,
- crtc->rotation,
- transform,
-
- &crtc_to_fb,
- &f_crtc_to_fb,
- &f_fb_to_crtc) &&
- xf86CrtcFitsScreen (crtc, &f_crtc_to_fb))
- {
- /*
- * If the untranslated transformation is the identity,
- * disable the shadow buffer
- */
- xf86RotateDestroy (crtc);
- crtc->transform_in_use = FALSE;
- if (new_params)
- xfree (new_params);
- new_params = NULL;
- new_nparams = 0;
- new_filter = NULL;
- new_width = 0;
- new_height = 0;
- }
- else
- {
- /*
- * these are the size of the shadow pixmap, which
- * matches the mode, not the pre-rotated copy in the
- * frame buffer
- */
- int width = crtc->mode.HDisplay;
- int height = crtc->mode.VDisplay;
- void *shadowData = crtc->rotatedData;
- PixmapPtr shadow = crtc->rotatedPixmap;
- int old_width = shadow ? shadow->drawable.width : 0;
- int old_height = shadow ? shadow->drawable.height : 0;
-
- /* Allocate memory for rotation */
- if (old_width != width || old_height != height)
- {
- if (shadow || shadowData)
- {
- crtc->funcs->shadow_destroy (crtc, shadow, shadowData);
- crtc->rotatedPixmap = NULL;
- crtc->rotatedData = NULL;
- }
- shadowData = crtc->funcs->shadow_allocate (crtc, width, height);
- if (!shadowData)
- goto bail1;
- crtc->rotatedData = shadowData;
- /* shadow will be damaged in xf86RotatePrepare */
- }
- else
- {
- /* mark shadowed area as damaged so it will be repainted */
- damage = TRUE;
- }
-
- if (!xf86_config->rotation_damage)
- {
- /* Create damage structure */
- xf86_config->rotation_damage = DamageCreate (NULL, NULL,
- DamageReportNone,
- TRUE, pScreen, pScreen);
- if (!xf86_config->rotation_damage)
- goto bail2;
-
- /* Wrap block handler */
- if (!xf86_config->BlockHandler) {
- xf86_config->BlockHandler = pScreen->BlockHandler;
- pScreen->BlockHandler = xf86RotateBlockHandler;
- }
- }
-#ifdef RANDR_12_INTERFACE
- if (transform)
- {
- if (transform->nparams) {
- new_params = xalloc (transform->nparams * sizeof (xFixed));
- if (new_params) {
- memcpy (new_params, transform->params,
- transform->nparams * sizeof (xFixed));
- new_nparams = transform->nparams;
- new_filter = transform->filter;
- }
- } else
- new_filter = transform->filter;
- if (new_filter)
- {
- new_width = new_filter->width;
- new_height = new_filter->height;
- }
- }
-#endif
-
- if (0)
- {
- bail2:
- if (shadow || shadowData)
- {
- crtc->funcs->shadow_destroy (crtc, shadow, shadowData);
- crtc->rotatedPixmap = NULL;
- crtc->rotatedData = NULL;
- }
- bail1:
- if (old_width && old_height)
- crtc->rotatedPixmap = crtc->funcs->shadow_create (crtc,
- NULL,
- old_width,
- old_height);
- return FALSE;
- }
- crtc->transform_in_use = TRUE;
- }
- crtc->crtc_to_framebuffer = crtc_to_fb;
- crtc->f_crtc_to_framebuffer = f_crtc_to_fb;
- crtc->f_framebuffer_to_crtc = f_fb_to_crtc;
- if (crtc->params)
- xfree (crtc->params);
- crtc->params = new_params;
- crtc->nparams = new_nparams;
- crtc->filter = new_filter;
- crtc->filter_width = new_width;
- crtc->filter_height = new_height;
- crtc->bounds.x1 = 0;
- crtc->bounds.x2 = crtc->mode.HDisplay;
- crtc->bounds.y1 = 0;
- crtc->bounds.y2 = crtc->mode.VDisplay;
- pixman_f_transform_bounds (&f_crtc_to_fb, &crtc->bounds);
-
- if (damage)
- xf86CrtcDamageShadow (crtc);
-
- /* All done */
- return TRUE;
-}
+/*
+ * Copyright © 2006 Keith Packard
+ *
+ * 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 the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS 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>
+#else
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#endif
+
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "xf86.h"
+#include "xf86DDC.h"
+#include "fb.h"
+#include "windowstr.h"
+#include "xf86Crtc.h"
+#include "xf86Modes.h"
+#include "xf86RandR12.h"
+#include "X11/extensions/render.h"
+#include "X11/extensions/dpmsconst.h"
+#include "X11/Xatom.h"
+
+/* borrowed from composite extension, move to Render and publish? */
+
+static VisualPtr
+compGetWindowVisual (WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ VisualID vid = wVisual (pWin);
+ int i;
+
+ for (i = 0; i < pScreen->numVisuals; i++)
+ if (pScreen->visuals[i].vid == vid)
+ return &pScreen->visuals[i];
+ return 0;
+}
+
+static PictFormatPtr
+compWindowFormat (WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ return PictureMatchVisual (pScreen, pWin->drawable.depth,
+ compGetWindowVisual (pWin));
+}
+
+#define F(x) IntToxFixed(x)
+
+#define toF(x) ((float) (x) / 65536.0f)
+
+static void
+xf86RotateCrtcRedisplay (xf86CrtcPtr crtc, RegionPtr region)
+{
+ ScrnInfoPtr scrn = crtc->scrn;
+ ScreenPtr screen = scrn->pScreen;
+ WindowPtr root = WindowTable[screen->myNum];
+ PixmapPtr dst_pixmap = crtc->rotatedPixmap;
+ PictFormatPtr format = compWindowFormat (WindowTable[screen->myNum]);
+ int error;
+ PicturePtr src, dst;
+ int n = REGION_NUM_RECTS(region);
+ BoxPtr b = REGION_RECTS(region);
+ XID include_inferiors = IncludeInferiors;
+
+ src = CreatePicture (None,
+ &root->drawable,
+ format,
+ CPSubwindowMode,
+ &include_inferiors,
+ serverClient,
+ &error);
+ if (!src)
+ return;
+
+ dst = CreatePicture (None,
+ &dst_pixmap->drawable,
+ format,
+ 0L,
+ NULL,
+ serverClient,
+ &error);
+ if (!dst)
+ return;
+
+ error = SetPictureTransform (src, &crtc->crtc_to_framebuffer);
+ if (error)
+ return;
+ if (crtc->transform_in_use && crtc->filter)
+ SetPicturePictFilter (src, crtc->filter,
+ crtc->params, crtc->nparams);
+
+ if (crtc->shadowClear)
+ {
+ CompositePicture (PictOpSrc,
+ src, NULL, dst,
+ 0, 0, 0, 0, 0, 0,
+ crtc->mode.HDisplay, crtc->mode.VDisplay);
+ crtc->shadowClear = FALSE;
+ }
+ else
+ {
+ while (n--)
+ {
+ BoxRec dst_box;
+
+ dst_box = *b;
+ dst_box.x1 -= crtc->filter_width >> 1;
+ dst_box.x2 += crtc->filter_width >> 1;
+ dst_box.y1 -= crtc->filter_height >> 1;
+ dst_box.y2 += crtc->filter_height >> 1;
+ pixman_f_transform_bounds (&crtc->f_framebuffer_to_crtc, &dst_box);
+ CompositePicture (PictOpSrc,
+ src, NULL, dst,
+ dst_box.x1, dst_box.y1, 0, 0, dst_box.x1, dst_box.y1,
+ dst_box.x2 - dst_box.x1,
+ dst_box.y2 - dst_box.y1);
+ b++;
+ }
+ }
+ FreePicture (src, None);
+ FreePicture (dst, None);
+}
+
+static void
+xf86CrtcDamageShadow (xf86CrtcPtr crtc)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ BoxRec damage_box;
+ RegionRec damage_region;
+ ScreenPtr pScreen = pScrn->pScreen;
+
+ damage_box.x1 = 0;
+ damage_box.x2 = crtc->mode.HDisplay;
+ damage_box.y1 = 0;
+ damage_box.y2 = crtc->mode.VDisplay;
+ if (!pixman_transform_bounds (&crtc->crtc_to_framebuffer, &damage_box))
+ {
+ damage_box.x1 = 0;
+ damage_box.y1 = 0;
+ damage_box.x2 = pScreen->width;
+ damage_box.y2 = pScreen->height;
+ }
+ if (damage_box.x1 < 0) damage_box.x1 = 0;
+ if (damage_box.y1 < 0) damage_box.y1 = 0;
+ if (damage_box.x2 > pScreen->width) damage_box.x2 = pScreen->width;
+ if (damage_box.y2 > pScreen->height) damage_box.y2 = pScreen->height;
+ REGION_INIT (pScreen, &damage_region, &damage_box, 1);
+ DamageRegionAppend (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
+ &damage_region);
+ REGION_UNINIT (pScreen, &damage_region);
+ crtc->shadowClear = TRUE;
+}
+
+static void
+xf86RotatePrepare (ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int c;
+
+ for (c = 0; c < xf86_config->num_crtc; c++)
+ {
+ xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+ if (crtc->rotatedData && !crtc->rotatedPixmap)
+ {
+ crtc->rotatedPixmap = crtc->funcs->shadow_create (crtc,
+ crtc->rotatedData,
+ crtc->mode.HDisplay,
+ crtc->mode.VDisplay);
+ if (!xf86_config->rotation_damage_registered)
+ {
+ /* Hook damage to screen pixmap */
+ DamageRegister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
+ xf86_config->rotation_damage);
+ xf86_config->rotation_damage_registered = TRUE;
+ EnableLimitedSchedulingLatency();
+ }
+
+ xf86CrtcDamageShadow (crtc);
+ }
+ }
+}
+
+static Bool
+xf86RotateRedisplay(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ DamagePtr damage = xf86_config->rotation_damage;
+ RegionPtr region;
+
+ if (!damage)
+ return FALSE;
+ xf86RotatePrepare (pScreen);
+ region = DamageRegion(damage);
+ if (REGION_NOTEMPTY(pScreen, region))
+ {
+ int c;
+ SourceValidateProcPtr SourceValidate;
+
+ /*
+ * SourceValidate is used by the software cursor code
+ * to pull the cursor off of the screen when reading
+ * bits from the frame buffer. Bypassing this function
+ * leaves the software cursor in place
+ */
+ SourceValidate = pScreen->SourceValidate;
+ pScreen->SourceValidate = NULL;
+
+ for (c = 0; c < xf86_config->num_crtc; c++)
+ {
+ xf86CrtcPtr crtc = xf86_config->crtc[c];
+
+ if (crtc->transform_in_use && crtc->enabled)
+ {
+ RegionRec crtc_damage;
+
+ /* compute portion of damage that overlaps crtc */
+ REGION_INIT(pScreen, &crtc_damage, &crtc->bounds, 1);
+ REGION_INTERSECT (pScreen, &crtc_damage, &crtc_damage, region);
+
+ /* update damaged region */
+ if (REGION_NOTEMPTY(pScreen, &crtc_damage))
+ xf86RotateCrtcRedisplay (crtc, &crtc_damage);
+
+ REGION_UNINIT (pScreen, &crtc_damage);
+ }
+ }
+ pScreen->SourceValidate = SourceValidate;
+ DamageEmpty(damage);
+ }
+ return TRUE;
+}
+
+static void
+xf86RotateBlockHandler(int screenNum, pointer blockData,
+ pointer pTimeout, pointer pReadmask)
+{
+ ScreenPtr pScreen = screenInfo.screens[screenNum];
+ ScrnInfoPtr pScrn = xf86Screens[screenNum];
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ Bool rotation_active;
+
+ rotation_active = xf86RotateRedisplay(pScreen);
+ pScreen->BlockHandler = xf86_config->BlockHandler;
+ (*pScreen->BlockHandler) (screenNum, blockData, pTimeout, pReadmask);
+ /* cannot avoid re-wrapping until all wrapping is audited */
+ xf86_config->BlockHandler = pScreen->BlockHandler;
+ pScreen->BlockHandler = xf86RotateBlockHandler;
+}
+
+void
+xf86RotateDestroy (xf86CrtcPtr crtc)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ ScreenPtr pScreen = pScrn->pScreen;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int c;
+
+ /* Free memory from rotation */
+ if (crtc->rotatedPixmap || crtc->rotatedData)
+ {
+ crtc->funcs->shadow_destroy (crtc, crtc->rotatedPixmap, crtc->rotatedData);
+ crtc->rotatedPixmap = NULL;
+ crtc->rotatedData = NULL;
+ }
+
+ for (c = 0; c < xf86_config->num_crtc; c++)
+ if (xf86_config->crtc[c]->transform_in_use)
+ return;
+
+ /*
+ * Clean up damage structures when no crtcs are rotated
+ */
+ if (xf86_config->rotation_damage)
+ {
+ /* Free damage structure */
+ if (xf86_config->rotation_damage_registered)
+ {
+ DamageUnregister (&(*pScreen->GetScreenPixmap)(pScreen)->drawable,
+ xf86_config->rotation_damage);
+ xf86_config->rotation_damage_registered = FALSE;
+ DisableLimitedSchedulingLatency();
+ }
+ DamageDestroy (xf86_config->rotation_damage);
+ xf86_config->rotation_damage = NULL;
+ }
+}
+
+void
+xf86RotateFreeShadow(ScrnInfoPtr pScrn)
+{
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int c;
+
+ for (c = 0; c < config->num_crtc; c++) {
+ xf86CrtcPtr crtc = config->crtc[c];
+
+ if (crtc->rotatedPixmap || crtc->rotatedData) {
+ crtc->funcs->shadow_destroy(crtc, crtc->rotatedPixmap,
+ crtc->rotatedData);
+ crtc->rotatedPixmap = NULL;
+ crtc->rotatedData = NULL;
+ }
+ }
+}
+
+void
+xf86RotateCloseScreen (ScreenPtr screen)
+{
+ ScrnInfoPtr scrn = xf86Screens[screen->myNum];
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+ int c;
+
+ for (c = 0; c < xf86_config->num_crtc; c++)
+ xf86RotateDestroy (xf86_config->crtc[c]);
+}
+
+static Bool
+xf86CrtcFitsScreen (xf86CrtcPtr crtc, struct pict_f_transform *crtc_to_fb)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ BoxRec b;
+
+ /* When called before PreInit, the driver is
+ * presumably doing load detect
+ */
+ if (pScrn->virtualX == 0 || pScrn->virtualY == 0)
+ return TRUE;
+
+ b.x1 = 0;
+ b.y1 = 0;
+ b.x2 = crtc->mode.HDisplay;
+ b.y2 = crtc->mode.VDisplay;
+ if (crtc_to_fb)
+ pixman_f_transform_bounds (crtc_to_fb, &b);
+ else {
+ b.x1 += crtc->x;
+ b.y1 += crtc->y;
+ b.x2 += crtc->x;
+ b.y2 += crtc->y;
+ }
+
+ return (0 <= b.x1 && b.x2 <= pScrn->virtualX &&
+ 0 <= b.y1 && b.y2 <= pScrn->virtualY);
+}
+
+Bool
+xf86CrtcRotate (xf86CrtcPtr crtc)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ /* if this is called during ScreenInit() we don't have pScrn->pScreen yet */
+ ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
+ PictTransform crtc_to_fb;
+ struct pict_f_transform f_crtc_to_fb, f_fb_to_crtc;
+ xFixed *new_params = NULL;
+ int new_nparams = 0;
+ PictFilterPtr new_filter = NULL;
+ int new_width = 0;
+ int new_height = 0;
+ RRTransformPtr transform = NULL;
+ Bool damage = FALSE;
+
+ if (crtc->transformPresent)
+ transform = &crtc->transform;
+
+ if (!RRTransformCompute (crtc->x, crtc->y,
+ crtc->mode.HDisplay, crtc->mode.VDisplay,
+ crtc->rotation,
+ transform,
+
+ &crtc_to_fb,
+ &f_crtc_to_fb,
+ &f_fb_to_crtc) &&
+ xf86CrtcFitsScreen (crtc, &f_crtc_to_fb))
+ {
+ /*
+ * If the untranslated transformation is the identity,
+ * disable the shadow buffer
+ */
+ xf86RotateDestroy (crtc);
+ crtc->transform_in_use = FALSE;
+ if (new_params)
+ free(new_params);
+ new_params = NULL;
+ new_nparams = 0;
+ new_filter = NULL;
+ new_width = 0;
+ new_height = 0;
+ }
+ else
+ {
+ /*
+ * these are the size of the shadow pixmap, which
+ * matches the mode, not the pre-rotated copy in the
+ * frame buffer
+ */
+ int width = crtc->mode.HDisplay;
+ int height = crtc->mode.VDisplay;
+ void *shadowData = crtc->rotatedData;
+ PixmapPtr shadow = crtc->rotatedPixmap;
+ int old_width = shadow ? shadow->drawable.width : 0;
+ int old_height = shadow ? shadow->drawable.height : 0;
+
+ /* Allocate memory for rotation */
+ if (old_width != width || old_height != height)
+ {
+ if (shadow || shadowData)
+ {
+ crtc->funcs->shadow_destroy (crtc, shadow, shadowData);
+ crtc->rotatedPixmap = NULL;
+ crtc->rotatedData = NULL;
+ }
+ shadowData = crtc->funcs->shadow_allocate (crtc, width, height);
+ if (!shadowData)
+ goto bail1;
+ crtc->rotatedData = shadowData;
+ /* shadow will be damaged in xf86RotatePrepare */
+ }
+ else
+ {
+ /* mark shadowed area as damaged so it will be repainted */
+ damage = TRUE;
+ }
+
+ if (!xf86_config->rotation_damage)
+ {
+ /* Create damage structure */
+ xf86_config->rotation_damage = DamageCreate (NULL, NULL,
+ DamageReportNone,
+ TRUE, pScreen, pScreen);
+ if (!xf86_config->rotation_damage)
+ goto bail2;
+
+ /* Wrap block handler */
+ if (!xf86_config->BlockHandler) {
+ xf86_config->BlockHandler = pScreen->BlockHandler;
+ pScreen->BlockHandler = xf86RotateBlockHandler;
+ }
+ }
+#ifdef RANDR_12_INTERFACE
+ if (transform)
+ {
+ if (transform->nparams) {
+ new_params = malloc(transform->nparams * sizeof (xFixed));
+ if (new_params) {
+ memcpy (new_params, transform->params,
+ transform->nparams * sizeof (xFixed));
+ new_nparams = transform->nparams;
+ new_filter = transform->filter;
+ }
+ } else
+ new_filter = transform->filter;
+ if (new_filter)
+ {
+ new_width = new_filter->width;
+ new_height = new_filter->height;
+ }
+ }
+#endif
+
+ if (0)
+ {
+ bail2:
+ if (shadow || shadowData)
+ {
+ crtc->funcs->shadow_destroy (crtc, shadow, shadowData);
+ crtc->rotatedPixmap = NULL;
+ crtc->rotatedData = NULL;
+ }
+ bail1:
+ if (old_width && old_height)
+ crtc->rotatedPixmap = crtc->funcs->shadow_create (crtc,
+ NULL,
+ old_width,
+ old_height);
+ return FALSE;
+ }
+ crtc->transform_in_use = TRUE;
+ }
+ crtc->crtc_to_framebuffer = crtc_to_fb;
+ crtc->f_crtc_to_framebuffer = f_crtc_to_fb;
+ crtc->f_framebuffer_to_crtc = f_fb_to_crtc;
+ if (crtc->params)
+ free(crtc->params);
+ crtc->params = new_params;
+ crtc->nparams = new_nparams;
+ crtc->filter = new_filter;
+ crtc->filter_width = new_width;
+ crtc->filter_height = new_height;
+ crtc->bounds.x1 = 0;
+ crtc->bounds.x2 = crtc->mode.HDisplay;
+ crtc->bounds.y1 = 0;
+ crtc->bounds.y2 = crtc->mode.VDisplay;
+ pixman_f_transform_bounds (&f_crtc_to_fb, &crtc->bounds);
+
+ if (damage)
+ xf86CrtcDamageShadow (crtc);
+
+ /* All done */
+ return TRUE;
+}
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 10db9c7b8..0d457193a 100644
--- a/xorg-server/hw/xfree86/os-support/bsd/i386_video.c
+++ b/xorg-server/hw/xfree86/os-support/bsd/i386_video.c
@@ -1,908 +1,908 @@
-/*
- * Copyright 1992 by Rich Murphey <Rich@Rice.edu>
- * 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 Rich Murphey and David Wexelblat
- * not be used in advertising or publicity pertaining to distribution of
- * the software without specific, written prior permission. Rich Murphey 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.
- *
- * RICH MURPHEY AND DAVID WEXELBLAT DISCLAIM ALL WARRANTIES WITH REGARD TO
- * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL RICH MURPHEY 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 <X11/X.h>
-#include "xf86.h"
-#include "xf86Priv.h"
-
-#include <errno.h>
-#include <sys/mman.h>
-
-#ifdef HAS_MTRR_SUPPORT
-#ifndef __NetBSD__
-#include <sys/types.h>
-#include <sys/memrange.h>
-#else
-#include "memrange.h"
-#endif
-#define X_MTRR_ID "XFree86"
-#endif
-
-#if defined(HAS_MTRR_BUILTIN) && defined(__NetBSD__)
-#include <machine/mtrr.h>
-#include <machine/sysarch.h>
-#include <sys/queue.h>
-#ifdef __x86_64__
-#define i386_set_mtrr x86_64_set_mtrr
-#define i386_get_mtrr x86_64_get_mtrr
-#define i386_iopl x86_64_iopl
-#endif
-#endif
-
-#include "xf86_OSlib.h"
-#include "xf86OSpriv.h"
-
-#if defined(__NetBSD__) && !defined(MAP_FILE)
-#define MAP_FLAGS MAP_SHARED
-#else
-#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" \
- "\trefer to xf86(4) for details"
-#define SYSCTL_MSG2 \
- "Check that you have set 'machdep.allowaperture=2'\n" \
- "\tin /etc/sysctl.conf and reboot your machine\n" \
- "\trefer to xf86(4) for details"
-#endif
-
-/***************************************************************************/
-/* Video Memory Mapping section */
-/***************************************************************************/
-
-static Bool useDevMem = FALSE;
-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);
-
-#ifdef HAS_MTRR_SUPPORT
-static pointer setWC(int, unsigned long, unsigned long, Bool, MessageType);
-static void undoWC(int, pointer);
-static Bool cleanMTRR(void);
-#endif
-#if defined(HAS_MTRR_BUILTIN) && defined(__NetBSD__)
-static pointer NetBSDsetWC(int, unsigned long, unsigned long, Bool,
- MessageType);
-static void NetBSDundoWC(int, pointer);
-#endif
-
-/*
- * Check if /dev/mem can be mmap'd. If it can't print a warning when
- * "warn" is TRUE.
- */
-static void
-checkDevMem(Bool warn)
-{
- static Bool devMemChecked = FALSE;
- int fd;
- pointer base;
-
- if (devMemChecked)
- return;
- devMemChecked = TRUE;
-
- if ((fd = open(DEV_MEM, O_RDWR)) >= 0)
- {
- /* Try to map a page at the VGA address */
- base = mmap((caddr_t)0, 4096, PROT_READ | PROT_WRITE,
- MAP_FLAGS, fd, (off_t)0xA0000);
-
- if (base != MAP_FAILED)
- {
- munmap((caddr_t)base, 4096);
- devMemFd = fd;
- useDevMem = TRUE;
- return;
- } else {
- /* This should not happen */
- if (warn)
- {
- xf86Msg(X_WARNING, "checkDevMem: failed to mmap %s (%s)\n",
- DEV_MEM, strerror(errno));
- }
- useDevMem = FALSE;
- return;
- }
- }
-#ifndef HAS_APERTURE_DRV
- if (warn)
- {
- xf86Msg(X_WARNING, "checkDevMem: failed to open %s (%s)\n",
- DEV_MEM, strerror(errno));
- }
- useDevMem = FALSE;
- return;
-#else
- /* Failed to open /dev/mem, try the aperture driver */
- if ((fd = open(DEV_APERTURE, O_RDWR)) >= 0)
- {
- /* Try to map a page at the VGA address */
- base = mmap((caddr_t)0, 4096, PROT_READ | PROT_WRITE,
- MAP_FLAGS, fd, (off_t)0xA0000);
-
- if (base != MAP_FAILED)
- {
- munmap((caddr_t)base, 4096);
- devMemFd = fd;
- useDevMem = TRUE;
- xf86Msg(X_INFO, "checkDevMem: using aperture driver %s\n",
- DEV_APERTURE);
- return;
- } else {
-
- if (warn)
- {
- xf86Msg(X_WARNING, "checkDevMem: failed to mmap %s (%s)\n",
- DEV_APERTURE, strerror(errno));
- }
- }
- } else {
- if (warn)
- {
-#ifndef __OpenBSD__
- xf86Msg(X_WARNING, "checkDevMem: failed to open %s and %s\n"
- "\t(%s)\n", DEV_MEM, DEV_APERTURE, strerror(errno));
-#else /* __OpenBSD__ */
- xf86Msg(X_WARNING, "checkDevMem: failed to open %s and %s\n"
- "\t(%s)\n%s", DEV_MEM, DEV_APERTURE, strerror(errno),
- SYSCTL_MSG);
-#endif /* __OpenBSD__ */
- }
- }
-
- useDevMem = FALSE;
- return;
-
-#endif
-}
-
-void
-xf86OSInitVidMem(VidMemInfoPtr pVidMem)
-{
- checkDevMem(TRUE);
- pVidMem->linearSupported = useDevMem;
- pVidMem->mapMem = mapVidMem;
- pVidMem->unmapMem = unmapVidMem;
-
-#if HAVE_PCI_SYSTEM_INIT_DEV_MEM
- if (useDevMem)
- pci_system_init_dev_mem(devMemFd);
-#endif
-
-#ifdef HAS_MTRR_SUPPORT
- if (useDevMem) {
- if (cleanMTRR()) {
- pVidMem->setWC = setWC;
- pVidMem->undoWC = undoWC;
- }
- }
-#endif
-#if defined(HAS_MTRR_BUILTIN) && defined(__NetBSD__)
- pVidMem->setWC = NetBSDsetWC;
- pVidMem->undoWC = NetBSDundoWC;
-#endif
- pVidMem->initialised = TRUE;
-}
-
-static pointer
-mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
-{
- pointer base;
-
- checkDevMem(FALSE);
-
- if (useDevMem)
- {
- if (devMemFd < 0)
- {
- FatalError("xf86MapVidMem: failed to open %s (%s)",
- DEV_MEM, strerror(errno));
- }
- base = mmap((caddr_t)0, Size,
- (flags & VIDMEM_READONLY) ?
- PROT_READ : (PROT_READ | PROT_WRITE),
- MAP_FLAGS, devMemFd, (off_t)Base);
- if (base == MAP_FAILED)
- {
- FatalError("%s: could not mmap %s [s=%lx,a=%lx] (%s)",
- "xf86MapVidMem", DEV_MEM, Size, Base,
- strerror(errno));
- }
- return(base);
- }
-
- /* else, mmap /dev/vga */
- if ((unsigned long)Base < 0xA0000 || (unsigned long)Base >= 0xC0000)
- {
- FatalError("%s: Address 0x%lx outside allowable range",
- "xf86MapVidMem", Base);
- }
- base = mmap(0, Size,
- (flags & VIDMEM_READONLY) ?
- PROT_READ : (PROT_READ | PROT_WRITE),
- MAP_FLAGS, xf86Info.screenFd,
- (unsigned long)Base - 0xA0000
- );
- if (base == MAP_FAILED)
- {
- FatalError("xf86MapVidMem: Could not mmap /dev/vga (%s)",
- strerror(errno));
- }
- return(base);
-}
-
-static void
-unmapVidMem(int ScreenNum, pointer Base, unsigned long Size)
-{
- munmap((caddr_t)Base, Size);
-}
-
-/*
- * Read BIOS via mmap()ing DEV_MEM
- */
-
-int
-xf86ReadBIOS(unsigned long Base, unsigned long Offset, unsigned char *Buf,
- int Len)
-{
- unsigned char *ptr;
- int psize;
- int mlen;
-
- checkDevMem(TRUE);
- if (devMemFd == -1) {
- 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, devMemFd, (off_t)Base);
- if ((long)ptr == -1)
- {
- xf86Msg(X_WARNING,
- "xf86ReadBIOS: %s mmap[s=%x,a=%lx,o=%lx] failed (%s)\n",
- DEV_MEM, Len, Base, Offset, strerror(errno));
-#ifdef __OpenBSD__
- if (Base < 0xa0000) {
- xf86Msg(X_WARNING, SYSCTL_MSG2);
- }
-#endif
- return(-1);
- }
-#ifdef DEBUG
- ErrorF("xf86ReadBIOS: BIOS at 0x%08x has signature 0x%04x\n",
- Base, ptr[0] | (ptr[1] << 8));
-#endif
- (void)memcpy(Buf, (void *)(ptr + Offset), Len);
- (void)munmap((caddr_t)ptr, mlen);
-#ifdef DEBUG
- xf86MsgVerb(X_INFO, 3, "xf86ReadBIOS(%x, %x, Buf, %x)"
- "-> %02x %02x %02x %02x...\n",
- Base, Offset, Len, Buf[0], Buf[1], Buf[2], Buf[3]);
-#endif
- return(Len);
-}
-
-#ifdef USE_I386_IOPL
-/***************************************************************************/
-/* I/O Permissions section */
-/***************************************************************************/
-
-static Bool ExtendedEnabled = FALSE;
-
-Bool
-xf86EnableIO()
-{
- if (ExtendedEnabled)
- return TRUE;
-
- if (i386_iopl(TRUE) < 0)
- {
-#ifndef __OpenBSD__
- xf86Msg(X_WARNING,"%s: Failed to set IOPL for extended I/O",
- "xf86EnableIO");
-#else
- xf86Msg(X_WARNING,"%s: Failed to set IOPL for extended I/O\n%s",
- "xf86EnableIO", SYSCTL_MSG);
-#endif
- return FALSE;
- }
- ExtendedEnabled = TRUE;
-
- return TRUE;
-}
-
-void
-xf86DisableIO()
-{
- if (!ExtendedEnabled)
- return;
-
- i386_iopl(FALSE);
- ExtendedEnabled = FALSE;
-
- return;
-}
-
-#endif /* USE_I386_IOPL */
-
-#ifdef USE_AMD64_IOPL
-/***************************************************************************/
-/* I/O Permissions section */
-/***************************************************************************/
-
-static Bool ExtendedEnabled = FALSE;
-
-Bool
-xf86EnableIO()
-{
- if (ExtendedEnabled)
- return TRUE;
-
- if (amd64_iopl(TRUE) < 0)
- {
-#ifndef __OpenBSD__
- xf86Msg(X_WARNING,"%s: Failed to set IOPL for extended I/O",
- "xf86EnableIO");
-#else
- xf86Msg(X_WARNING,"%s: Failed to set IOPL for extended I/O\n%s",
- "xf86EnableIO", SYSCTL_MSG);
-#endif
- return FALSE;
- }
- ExtendedEnabled = TRUE;
-
- return TRUE;
-}
-
-void
-xf86DisableIO()
-{
- if (!ExtendedEnabled)
- return;
-
- if (amd64_iopl(FALSE) == 0) {
- ExtendedEnabled = FALSE;
- }
- /* Otherwise, the X server has revoqued its root uid,
- and thus cannot give up IO privileges any more */
-
- return;
-}
-
-#endif /* USE_AMD64_IOPL */
-
-#ifdef USE_DEV_IO
-static int IoFd = -1;
-
-Bool
-xf86EnableIO()
-{
- if (IoFd >= 0)
- return TRUE;
-
- if ((IoFd = open("/dev/io", O_RDWR)) == -1)
- {
- xf86Msg(X_WARNING,"xf86EnableIO: "
- "Failed to open /dev/io for extended I/O");
- return FALSE;
- }
- return TRUE;
-}
-
-void
-xf86DisableIO()
-{
- if (IoFd < 0)
- return;
-
- close(IoFd);
- IoFd = -1;
- return;
-}
-
-#endif
-
-#ifdef __NetBSD__
-/***************************************************************************/
-/* Set TV output mode */
-/***************************************************************************/
-void
-xf86SetTVOut(int mode)
-{
- switch (xf86Info.consType)
- {
-#ifdef PCCONS_SUPPORT
- case PCCONS:{
-
- if (ioctl (xf86Info.consoleFd, CONSOLE_X_TV_ON, &mode) < 0)
- {
- xf86Msg(X_WARNING,
- "xf86SetTVOut: Could not set console to TV output, %s\n",
- strerror(errno));
- }
- }
- break;
-#endif /* PCCONS_SUPPORT */
-
- default:
- FatalError("Xf86SetTVOut: Unsupported console");
- break;
- }
- return;
-}
-
-void
-xf86SetRGBOut()
-{
- switch (xf86Info.consType)
- {
-#ifdef PCCONS_SUPPORT
- case PCCONS:{
-
- if (ioctl (xf86Info.consoleFd, CONSOLE_X_TV_OFF, 0) < 0)
- {
- xf86Msg(X_WARNING,
- "xf86SetTVOut: Could not set console to RGB output, %s\n",
- strerror(errno));
- }
- }
- break;
-#endif /* PCCONS_SUPPORT */
-
- default:
- FatalError("Xf86SetTVOut: Unsupported console");
- break;
- }
- return;
-}
-#endif
-
-#ifdef HAS_MTRR_SUPPORT
-/* memory range (MTRR) support for FreeBSD */
-
-/*
- * This code is experimental. Some parts may be overkill, and other parts
- * may be incomplete.
- */
-
-/*
- * getAllRanges returns the full list of memory ranges with attributes set.
- */
-
-static struct mem_range_desc *
-getAllRanges(int *nmr)
-{
- struct mem_range_desc *mrd;
- struct mem_range_op mro;
-
- /*
- * Find how many ranges there are. If this fails, then the kernel
- * probably doesn't have MTRR support.
- */
- mro.mo_arg[0] = 0;
- if (ioctl(devMemFd, MEMRANGE_GET, &mro))
- return NULL;
- *nmr = mro.mo_arg[0];
- mrd = xnfalloc(*nmr * sizeof(struct mem_range_desc));
- mro.mo_arg[0] = *nmr;
- mro.mo_desc = mrd;
- if (ioctl(devMemFd, MEMRANGE_GET, &mro)) {
- xfree(mrd);
- return NULL;
- }
- return mrd;
-}
-
-/*
- * cleanMTRR removes any memory attribute that may be left by a previous
- * X server. Normally there won't be any, but this takes care of the
- * case where a server crashed without being able finish cleaning up.
- */
-
-static Bool
-cleanMTRR()
-{
- struct mem_range_desc *mrd;
- struct mem_range_op mro;
- int nmr, i;
-
- /* This shouldn't happen */
- if (devMemFd < 0)
- return FALSE;
-
- if (!(mrd = getAllRanges(&nmr)))
- return FALSE;
-
- for (i = 0; i < nmr; i++) {
- if (strcmp(mrd[i].mr_owner, X_MTRR_ID) == 0 &&
- (mrd[i].mr_flags & MDF_ACTIVE)) {
-#ifdef DEBUG
- ErrorF("Clean for (0x%lx,0x%lx)\n",
- (unsigned long)mrd[i].mr_base,
- (unsigned long)mrd[i].mr_len);
-#endif
- if (mrd[i].mr_flags & MDF_FIXACTIVE) {
- mro.mo_arg[0] = MEMRANGE_SET_UPDATE;
- mrd[i].mr_flags = MDF_UNCACHEABLE;
- } else {
- mro.mo_arg[0] = MEMRANGE_SET_REMOVE;
- }
- mro.mo_desc = mrd + i;
- ioctl(devMemFd, MEMRANGE_SET, &mro);
- }
- }
-#ifdef DEBUG
- sleep(10);
-#endif
- xfree(mrd);
- return TRUE;
-}
-
-typedef struct x_RangeRec {
- struct mem_range_desc mrd;
- Bool wasWC;
- struct x_RangeRec * next;
-} RangeRec, *RangePtr;
-
-static void
-freeRangeList(RangePtr range)
-{
- RangePtr rp;
-
- while (range) {
- rp = range;
- range = rp->next;
- xfree(rp);
- }
-}
-
-static RangePtr
-dupRangeList(RangePtr list)
-{
- RangePtr new = NULL, rp, p;
-
- rp = list;
- while (rp) {
- p = xnfalloc(sizeof(RangeRec));
- *p = *rp;
- p->next = new;
- new = p;
- rp = rp->next;
- }
- return new;
-}
-
-static RangePtr
-sortRangeList(RangePtr list)
-{
- RangePtr rp1, rp2, copy, sorted = NULL, minp, prev, minprev;
- unsigned long minBase;
-
- /* Sort by base address */
- rp1 = copy = dupRangeList(list);
- while (rp1) {
- minBase = rp1->mrd.mr_base;
- minp = rp1;
- minprev = NULL;
- prev = rp1;
- rp2 = rp1->next;
- while (rp2) {
- if (rp2->mrd.mr_base < minBase) {
- minBase = rp2->mrd.mr_base;
- minp = rp2;
- minprev = prev;
- }
- prev = rp2;
- rp2 = rp2->next;
- }
- if (minprev) {
- minprev->next = minp->next;
- rp1 = copy;
- } else {
- rp1 = minp->next;
- }
- minp->next = sorted;
- sorted = minp;
- }
- return sorted;
-}
-
-/*
- * findRanges returns a list of ranges that overlap the specified range.
- */
-
-static void
-findRanges(unsigned long base, unsigned long size, RangePtr *ucp, RangePtr *wcp)
-{
- struct mem_range_desc *mrd;
- int nmr, i;
- RangePtr rp, *p;
-
- if (!(mrd = getAllRanges(&nmr)))
- return;
-
- for (i = 0; i < nmr; i++) {
- if ((mrd[i].mr_flags & MDF_ACTIVE) &&
- mrd[i].mr_base < base + size &&
- mrd[i].mr_base + mrd[i].mr_len > base) {
- if (mrd[i].mr_flags & MDF_WRITECOMBINE)
- p = wcp;
- else if (mrd[i].mr_flags & MDF_UNCACHEABLE)
- p = ucp;
- else
- continue;
- rp = xnfalloc(sizeof(RangeRec));
- rp->mrd = mrd[i];
- rp->next = *p;
- *p = rp;
- }
- }
- xfree(mrd);
-}
-
-/*
- * This checks if the existing overlapping ranges fully cover the requested
- * range. Is this overkill?
- */
-
-static Bool
-fullCoverage(unsigned long base, unsigned long size, RangePtr overlap)
-{
- RangePtr rp1, sorted = NULL;
- unsigned long end;
-
- sorted = sortRangeList(overlap);
- /* Look for gaps */
- rp1 = sorted;
- end = base + size;
- while (rp1) {
- if (rp1->mrd.mr_base > base) {
- freeRangeList(sorted);
- return FALSE;
- } else {
- base = rp1->mrd.mr_base + rp1->mrd.mr_len;
- }
- if (base >= end) {
- freeRangeList(sorted);
- return TRUE;
- }
- rp1 = rp1->next;
- }
- freeRangeList(sorted);
- return FALSE;
-}
-
-static pointer
-addWC(int screenNum, unsigned long base, unsigned long size, MessageType from)
-{
- RangePtr uc = NULL, wc = NULL, retlist = NULL;
- struct mem_range_desc mrd;
- struct mem_range_op mro;
-
- findRanges(base, size, &uc, &wc);
-
- /* See of the full range is already WC */
- if (!uc && fullCoverage(base, size, wc)) {
- xf86DrvMsg(screenNum, from,
- "Write-combining range (0x%lx,0x%lx) was already set\n",
- base, size);
- return NULL;
- }
-
- /* Otherwise, try to add the new range */
- mrd.mr_base = base;
- mrd.mr_len = size;
- strcpy(mrd.mr_owner, X_MTRR_ID);
- mrd.mr_flags = MDF_WRITECOMBINE;
- mro.mo_desc = &mrd;
- mro.mo_arg[0] = MEMRANGE_SET_UPDATE;
- if (ioctl(devMemFd, MEMRANGE_SET, &mro)) {
- xf86DrvMsg(screenNum, X_WARNING,
- "Failed to set write-combining range "
- "(0x%lx,0x%lx)\n", base, size);
- return NULL;
- } else {
- xf86DrvMsg(screenNum, from,
- "Write-combining range (0x%lx,0x%lx)\n", base, size);
- retlist = xnfalloc(sizeof(RangeRec));
- retlist->mrd = mrd;
- retlist->wasWC = FALSE;
- retlist->next = NULL;
- return retlist;
- }
-}
-
-static pointer
-delWC(int screenNum, unsigned long base, unsigned long size, MessageType from)
-{
- RangePtr uc = NULL, wc = NULL, retlist = NULL;
- struct mem_range_desc mrd;
- struct mem_range_op mro;
-
- findRanges(base, size, &uc, &wc);
-
- /*
- * See of the full range is already not WC, or if there is full
- * coverage from UC ranges.
- */
- if (!wc || fullCoverage(base, size, uc)) {
- xf86DrvMsg(screenNum, from,
- "Write-combining range (0x%lx,0x%lx) was already clear\n",
- base, size);
- return NULL;
- }
-
- /* Otherwise, try to add the new range */
- mrd.mr_base = base;
- mrd.mr_len = size;
- strcpy(mrd.mr_owner, X_MTRR_ID);
- mrd.mr_flags = MDF_UNCACHEABLE;
- mro.mo_desc = &mrd;
- mro.mo_arg[0] = MEMRANGE_SET_UPDATE;
- if (ioctl(devMemFd, MEMRANGE_SET, &mro)) {
- xf86DrvMsg(screenNum, X_WARNING,
- "Failed to remove write-combining range "
- "(0x%lx,0x%lx)\n", base, size);
- /* XXX Should then remove all of the overlapping WC ranges */
- return NULL;
- } else {
- xf86DrvMsg(screenNum, from,
- "Removed Write-combining range (0x%lx,0x%lx)\n",
- base, size);
- retlist = xnfalloc(sizeof(RangeRec));
- retlist->mrd = mrd;
- retlist->wasWC = TRUE;
- retlist->next = NULL;
- return retlist;
- }
-}
-
-static pointer
-setWC(int screenNum, unsigned long base, unsigned long size, Bool enable,
- MessageType from)
-{
- if (enable)
- return addWC(screenNum, base, size, from);
- else
- return delWC(screenNum, base, size, from);
-}
-
-static void
-undoWC(int screenNum, pointer list)
-{
- RangePtr rp;
- struct mem_range_op mro;
- Bool failed;
-
- rp = list;
- while (rp) {
-#ifdef DEBUG
- ErrorF("Undo for (0x%lx,0x%lx), %d\n",
- (unsigned long)rp->mrd.mr_base,
- (unsigned long)rp->mrd.mr_len, rp->wasWC);
-#endif
- failed = FALSE;
- if (rp->wasWC) {
- mro.mo_arg[0] = MEMRANGE_SET_UPDATE;
- rp->mrd.mr_flags = MDF_WRITECOMBINE;
- strcpy(rp->mrd.mr_owner, "unknown");
- } else {
- mro.mo_arg[0] = MEMRANGE_SET_REMOVE;
- }
- mro.mo_desc = &rp->mrd;
-
- if (ioctl(devMemFd, MEMRANGE_SET, &mro)) {
- if (!rp->wasWC) {
- mro.mo_arg[0] = MEMRANGE_SET_UPDATE;
- rp->mrd.mr_flags = MDF_UNCACHEABLE;
- strcpy(rp->mrd.mr_owner, "unknown");
- if (ioctl(devMemFd, MEMRANGE_SET, &mro))
- failed = TRUE;
- } else
- failed = TRUE;
- }
- if (failed) {
- xf86DrvMsg(screenNum, X_WARNING,
- "Failed to restore MTRR range (0x%lx,0x%lx)\n",
- (unsigned long)rp->mrd.mr_base,
- (unsigned long)rp->mrd.mr_len);
- }
- rp = rp->next;
- }
-}
-
-#endif /* HAS_MTRR_SUPPORT */
-
-
-#if defined(HAS_MTRR_BUILTIN) && defined(__NetBSD__)
-static pointer
-NetBSDsetWC(int screenNum, unsigned long base, unsigned long size, Bool enable,
- MessageType from)
-{
- struct mtrr *mtrrp;
- int n;
-
- xf86DrvMsg(screenNum, X_WARNING,
- "%s MTRR %lx - %lx\n", enable ? "set" : "remove",
- base, (base + size));
-
- mtrrp = xnfalloc(sizeof (struct mtrr));
- mtrrp->base = base;
- mtrrp->len = size;
- mtrrp->type = MTRR_TYPE_WC;
-
- /*
- * MTRR_PRIVATE will make this MTRR get reset automatically
- * if this process exits, so we have no need for an explicit
- * cleanup operation when starting a new server.
- */
-
- if (enable)
- mtrrp->flags = MTRR_VALID | MTRR_PRIVATE;
- else
- mtrrp->flags = 0;
- n = 1;
-
- if (i386_set_mtrr(mtrrp, &n) < 0) {
- xfree(mtrrp);
- return NULL;
- }
- return mtrrp;
-}
-
-static void
-NetBSDundoWC(int screenNum, pointer list)
-{
- struct mtrr *mtrrp = (struct mtrr *)list;
- int n;
-
- if (mtrrp == NULL)
- return;
- n = 1;
- mtrrp->flags &= ~MTRR_VALID;
- i386_set_mtrr(mtrrp, &n);
- xfree(mtrrp);
-}
-#endif
+/*
+ * Copyright 1992 by Rich Murphey <Rich@Rice.edu>
+ * 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 Rich Murphey and David Wexelblat
+ * not be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. Rich Murphey 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.
+ *
+ * RICH MURPHEY AND DAVID WEXELBLAT DISCLAIM ALL WARRANTIES WITH REGARD TO
+ * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL RICH MURPHEY 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 <X11/X.h>
+#include "xf86.h"
+#include "xf86Priv.h"
+
+#include <errno.h>
+#include <sys/mman.h>
+
+#ifdef HAS_MTRR_SUPPORT
+#ifndef __NetBSD__
+#include <sys/types.h>
+#include <sys/memrange.h>
+#else
+#include "memrange.h"
+#endif
+#define X_MTRR_ID "XFree86"
+#endif
+
+#if defined(HAS_MTRR_BUILTIN) && defined(__NetBSD__)
+#include <machine/mtrr.h>
+#include <machine/sysarch.h>
+#include <sys/queue.h>
+#ifdef __x86_64__
+#define i386_set_mtrr x86_64_set_mtrr
+#define i386_get_mtrr x86_64_get_mtrr
+#define i386_iopl x86_64_iopl
+#endif
+#endif
+
+#include "xf86_OSlib.h"
+#include "xf86OSpriv.h"
+
+#if defined(__NetBSD__) && !defined(MAP_FILE)
+#define MAP_FLAGS MAP_SHARED
+#else
+#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" \
+ "\trefer to xf86(4) for details"
+#define SYSCTL_MSG2 \
+ "Check that you have set 'machdep.allowaperture=2'\n" \
+ "\tin /etc/sysctl.conf and reboot your machine\n" \
+ "\trefer to xf86(4) for details"
+#endif
+
+/***************************************************************************/
+/* Video Memory Mapping section */
+/***************************************************************************/
+
+static Bool useDevMem = FALSE;
+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);
+
+#ifdef HAS_MTRR_SUPPORT
+static pointer setWC(int, unsigned long, unsigned long, Bool, MessageType);
+static void undoWC(int, pointer);
+static Bool cleanMTRR(void);
+#endif
+#if defined(HAS_MTRR_BUILTIN) && defined(__NetBSD__)
+static pointer NetBSDsetWC(int, unsigned long, unsigned long, Bool,
+ MessageType);
+static void NetBSDundoWC(int, pointer);
+#endif
+
+/*
+ * Check if /dev/mem can be mmap'd. If it can't print a warning when
+ * "warn" is TRUE.
+ */
+static void
+checkDevMem(Bool warn)
+{
+ static Bool devMemChecked = FALSE;
+ int fd;
+ pointer base;
+
+ if (devMemChecked)
+ return;
+ devMemChecked = TRUE;
+
+ if ((fd = open(DEV_MEM, O_RDWR)) >= 0)
+ {
+ /* Try to map a page at the VGA address */
+ base = mmap((caddr_t)0, 4096, PROT_READ | PROT_WRITE,
+ MAP_FLAGS, fd, (off_t)0xA0000);
+
+ if (base != MAP_FAILED)
+ {
+ munmap((caddr_t)base, 4096);
+ devMemFd = fd;
+ useDevMem = TRUE;
+ return;
+ } else {
+ /* This should not happen */
+ if (warn)
+ {
+ xf86Msg(X_WARNING, "checkDevMem: failed to mmap %s (%s)\n",
+ DEV_MEM, strerror(errno));
+ }
+ useDevMem = FALSE;
+ return;
+ }
+ }
+#ifndef HAS_APERTURE_DRV
+ if (warn)
+ {
+ xf86Msg(X_WARNING, "checkDevMem: failed to open %s (%s)\n",
+ DEV_MEM, strerror(errno));
+ }
+ useDevMem = FALSE;
+ return;
+#else
+ /* Failed to open /dev/mem, try the aperture driver */
+ if ((fd = open(DEV_APERTURE, O_RDWR)) >= 0)
+ {
+ /* Try to map a page at the VGA address */
+ base = mmap((caddr_t)0, 4096, PROT_READ | PROT_WRITE,
+ MAP_FLAGS, fd, (off_t)0xA0000);
+
+ if (base != MAP_FAILED)
+ {
+ munmap((caddr_t)base, 4096);
+ devMemFd = fd;
+ useDevMem = TRUE;
+ xf86Msg(X_INFO, "checkDevMem: using aperture driver %s\n",
+ DEV_APERTURE);
+ return;
+ } else {
+
+ if (warn)
+ {
+ xf86Msg(X_WARNING, "checkDevMem: failed to mmap %s (%s)\n",
+ DEV_APERTURE, strerror(errno));
+ }
+ }
+ } else {
+ if (warn)
+ {
+#ifndef __OpenBSD__
+ xf86Msg(X_WARNING, "checkDevMem: failed to open %s and %s\n"
+ "\t(%s)\n", DEV_MEM, DEV_APERTURE, strerror(errno));
+#else /* __OpenBSD__ */
+ xf86Msg(X_WARNING, "checkDevMem: failed to open %s and %s\n"
+ "\t(%s)\n%s", DEV_MEM, DEV_APERTURE, strerror(errno),
+ SYSCTL_MSG);
+#endif /* __OpenBSD__ */
+ }
+ }
+
+ useDevMem = FALSE;
+ return;
+
+#endif
+}
+
+void
+xf86OSInitVidMem(VidMemInfoPtr pVidMem)
+{
+ checkDevMem(TRUE);
+ pVidMem->linearSupported = useDevMem;
+ pVidMem->mapMem = mapVidMem;
+ pVidMem->unmapMem = unmapVidMem;
+
+#if HAVE_PCI_SYSTEM_INIT_DEV_MEM
+ if (useDevMem)
+ pci_system_init_dev_mem(devMemFd);
+#endif
+
+#ifdef HAS_MTRR_SUPPORT
+ if (useDevMem) {
+ if (cleanMTRR()) {
+ pVidMem->setWC = setWC;
+ pVidMem->undoWC = undoWC;
+ }
+ }
+#endif
+#if defined(HAS_MTRR_BUILTIN) && defined(__NetBSD__)
+ pVidMem->setWC = NetBSDsetWC;
+ pVidMem->undoWC = NetBSDundoWC;
+#endif
+ pVidMem->initialised = TRUE;
+}
+
+static pointer
+mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
+{
+ pointer base;
+
+ checkDevMem(FALSE);
+
+ if (useDevMem)
+ {
+ if (devMemFd < 0)
+ {
+ FatalError("xf86MapVidMem: failed to open %s (%s)",
+ DEV_MEM, strerror(errno));
+ }
+ base = mmap((caddr_t)0, Size,
+ (flags & VIDMEM_READONLY) ?
+ PROT_READ : (PROT_READ | PROT_WRITE),
+ MAP_FLAGS, devMemFd, (off_t)Base);
+ if (base == MAP_FAILED)
+ {
+ FatalError("%s: could not mmap %s [s=%lx,a=%lx] (%s)",
+ "xf86MapVidMem", DEV_MEM, Size, Base,
+ strerror(errno));
+ }
+ return(base);
+ }
+
+ /* else, mmap /dev/vga */
+ if ((unsigned long)Base < 0xA0000 || (unsigned long)Base >= 0xC0000)
+ {
+ FatalError("%s: Address 0x%lx outside allowable range",
+ "xf86MapVidMem", Base);
+ }
+ base = mmap(0, Size,
+ (flags & VIDMEM_READONLY) ?
+ PROT_READ : (PROT_READ | PROT_WRITE),
+ MAP_FLAGS, xf86Info.screenFd,
+ (unsigned long)Base - 0xA0000
+ );
+ if (base == MAP_FAILED)
+ {
+ FatalError("xf86MapVidMem: Could not mmap /dev/vga (%s)",
+ strerror(errno));
+ }
+ return(base);
+}
+
+static void
+unmapVidMem(int ScreenNum, pointer Base, unsigned long Size)
+{
+ munmap((caddr_t)Base, Size);
+}
+
+/*
+ * Read BIOS via mmap()ing DEV_MEM
+ */
+
+int
+xf86ReadBIOS(unsigned long Base, unsigned long Offset, unsigned char *Buf,
+ int Len)
+{
+ unsigned char *ptr;
+ int psize;
+ int mlen;
+
+ checkDevMem(TRUE);
+ if (devMemFd == -1) {
+ 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, devMemFd, (off_t)Base);
+ if ((long)ptr == -1)
+ {
+ xf86Msg(X_WARNING,
+ "xf86ReadBIOS: %s mmap[s=%x,a=%lx,o=%lx] failed (%s)\n",
+ DEV_MEM, Len, Base, Offset, strerror(errno));
+#ifdef __OpenBSD__
+ if (Base < 0xa0000) {
+ xf86Msg(X_WARNING, SYSCTL_MSG2);
+ }
+#endif
+ return(-1);
+ }
+#ifdef DEBUG
+ ErrorF("xf86ReadBIOS: BIOS at 0x%08x has signature 0x%04x\n",
+ Base, ptr[0] | (ptr[1] << 8));
+#endif
+ (void)memcpy(Buf, (void *)(ptr + Offset), Len);
+ (void)munmap((caddr_t)ptr, mlen);
+#ifdef DEBUG
+ xf86MsgVerb(X_INFO, 3, "xf86ReadBIOS(%x, %x, Buf, %x)"
+ "-> %02x %02x %02x %02x...\n",
+ Base, Offset, Len, Buf[0], Buf[1], Buf[2], Buf[3]);
+#endif
+ return(Len);
+}
+
+#ifdef USE_I386_IOPL
+/***************************************************************************/
+/* I/O Permissions section */
+/***************************************************************************/
+
+static Bool ExtendedEnabled = FALSE;
+
+Bool
+xf86EnableIO()
+{
+ if (ExtendedEnabled)
+ return TRUE;
+
+ if (i386_iopl(TRUE) < 0)
+ {
+#ifndef __OpenBSD__
+ xf86Msg(X_WARNING,"%s: Failed to set IOPL for extended I/O",
+ "xf86EnableIO");
+#else
+ xf86Msg(X_WARNING,"%s: Failed to set IOPL for extended I/O\n%s",
+ "xf86EnableIO", SYSCTL_MSG);
+#endif
+ return FALSE;
+ }
+ ExtendedEnabled = TRUE;
+
+ return TRUE;
+}
+
+void
+xf86DisableIO()
+{
+ if (!ExtendedEnabled)
+ return;
+
+ i386_iopl(FALSE);
+ ExtendedEnabled = FALSE;
+
+ return;
+}
+
+#endif /* USE_I386_IOPL */
+
+#ifdef USE_AMD64_IOPL
+/***************************************************************************/
+/* I/O Permissions section */
+/***************************************************************************/
+
+static Bool ExtendedEnabled = FALSE;
+
+Bool
+xf86EnableIO()
+{
+ if (ExtendedEnabled)
+ return TRUE;
+
+ if (amd64_iopl(TRUE) < 0)
+ {
+#ifndef __OpenBSD__
+ xf86Msg(X_WARNING,"%s: Failed to set IOPL for extended I/O",
+ "xf86EnableIO");
+#else
+ xf86Msg(X_WARNING,"%s: Failed to set IOPL for extended I/O\n%s",
+ "xf86EnableIO", SYSCTL_MSG);
+#endif
+ return FALSE;
+ }
+ ExtendedEnabled = TRUE;
+
+ return TRUE;
+}
+
+void
+xf86DisableIO()
+{
+ if (!ExtendedEnabled)
+ return;
+
+ if (amd64_iopl(FALSE) == 0) {
+ ExtendedEnabled = FALSE;
+ }
+ /* Otherwise, the X server has revoqued its root uid,
+ and thus cannot give up IO privileges any more */
+
+ return;
+}
+
+#endif /* USE_AMD64_IOPL */
+
+#ifdef USE_DEV_IO
+static int IoFd = -1;
+
+Bool
+xf86EnableIO()
+{
+ if (IoFd >= 0)
+ return TRUE;
+
+ if ((IoFd = open("/dev/io", O_RDWR)) == -1)
+ {
+ xf86Msg(X_WARNING,"xf86EnableIO: "
+ "Failed to open /dev/io for extended I/O");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+void
+xf86DisableIO()
+{
+ if (IoFd < 0)
+ return;
+
+ close(IoFd);
+ IoFd = -1;
+ return;
+}
+
+#endif
+
+#ifdef __NetBSD__
+/***************************************************************************/
+/* Set TV output mode */
+/***************************************************************************/
+void
+xf86SetTVOut(int mode)
+{
+ switch (xf86Info.consType)
+ {
+#ifdef PCCONS_SUPPORT
+ case PCCONS:{
+
+ if (ioctl (xf86Info.consoleFd, CONSOLE_X_TV_ON, &mode) < 0)
+ {
+ xf86Msg(X_WARNING,
+ "xf86SetTVOut: Could not set console to TV output, %s\n",
+ strerror(errno));
+ }
+ }
+ break;
+#endif /* PCCONS_SUPPORT */
+
+ default:
+ FatalError("Xf86SetTVOut: Unsupported console");
+ break;
+ }
+ return;
+}
+
+void
+xf86SetRGBOut()
+{
+ switch (xf86Info.consType)
+ {
+#ifdef PCCONS_SUPPORT
+ case PCCONS:{
+
+ if (ioctl (xf86Info.consoleFd, CONSOLE_X_TV_OFF, 0) < 0)
+ {
+ xf86Msg(X_WARNING,
+ "xf86SetTVOut: Could not set console to RGB output, %s\n",
+ strerror(errno));
+ }
+ }
+ break;
+#endif /* PCCONS_SUPPORT */
+
+ default:
+ FatalError("Xf86SetTVOut: Unsupported console");
+ break;
+ }
+ return;
+}
+#endif
+
+#ifdef HAS_MTRR_SUPPORT
+/* memory range (MTRR) support for FreeBSD */
+
+/*
+ * This code is experimental. Some parts may be overkill, and other parts
+ * may be incomplete.
+ */
+
+/*
+ * getAllRanges returns the full list of memory ranges with attributes set.
+ */
+
+static struct mem_range_desc *
+getAllRanges(int *nmr)
+{
+ struct mem_range_desc *mrd;
+ struct mem_range_op mro;
+
+ /*
+ * Find how many ranges there are. If this fails, then the kernel
+ * probably doesn't have MTRR support.
+ */
+ mro.mo_arg[0] = 0;
+ if (ioctl(devMemFd, MEMRANGE_GET, &mro))
+ return NULL;
+ *nmr = mro.mo_arg[0];
+ mrd = xnfalloc(*nmr * sizeof(struct mem_range_desc));
+ mro.mo_arg[0] = *nmr;
+ mro.mo_desc = mrd;
+ if (ioctl(devMemFd, MEMRANGE_GET, &mro)) {
+ free(mrd);
+ return NULL;
+ }
+ return mrd;
+}
+
+/*
+ * cleanMTRR removes any memory attribute that may be left by a previous
+ * X server. Normally there won't be any, but this takes care of the
+ * case where a server crashed without being able finish cleaning up.
+ */
+
+static Bool
+cleanMTRR()
+{
+ struct mem_range_desc *mrd;
+ struct mem_range_op mro;
+ int nmr, i;
+
+ /* This shouldn't happen */
+ if (devMemFd < 0)
+ return FALSE;
+
+ if (!(mrd = getAllRanges(&nmr)))
+ return FALSE;
+
+ for (i = 0; i < nmr; i++) {
+ if (strcmp(mrd[i].mr_owner, X_MTRR_ID) == 0 &&
+ (mrd[i].mr_flags & MDF_ACTIVE)) {
+#ifdef DEBUG
+ ErrorF("Clean for (0x%lx,0x%lx)\n",
+ (unsigned long)mrd[i].mr_base,
+ (unsigned long)mrd[i].mr_len);
+#endif
+ if (mrd[i].mr_flags & MDF_FIXACTIVE) {
+ mro.mo_arg[0] = MEMRANGE_SET_UPDATE;
+ mrd[i].mr_flags = MDF_UNCACHEABLE;
+ } else {
+ mro.mo_arg[0] = MEMRANGE_SET_REMOVE;
+ }
+ mro.mo_desc = mrd + i;
+ ioctl(devMemFd, MEMRANGE_SET, &mro);
+ }
+ }
+#ifdef DEBUG
+ sleep(10);
+#endif
+ free(mrd);
+ return TRUE;
+}
+
+typedef struct x_RangeRec {
+ struct mem_range_desc mrd;
+ Bool wasWC;
+ struct x_RangeRec * next;
+} RangeRec, *RangePtr;
+
+static void
+freeRangeList(RangePtr range)
+{
+ RangePtr rp;
+
+ while (range) {
+ rp = range;
+ range = rp->next;
+ free(rp);
+ }
+}
+
+static RangePtr
+dupRangeList(RangePtr list)
+{
+ RangePtr new = NULL, rp, p;
+
+ rp = list;
+ while (rp) {
+ p = xnfalloc(sizeof(RangeRec));
+ *p = *rp;
+ p->next = new;
+ new = p;
+ rp = rp->next;
+ }
+ return new;
+}
+
+static RangePtr
+sortRangeList(RangePtr list)
+{
+ RangePtr rp1, rp2, copy, sorted = NULL, minp, prev, minprev;
+ unsigned long minBase;
+
+ /* Sort by base address */
+ rp1 = copy = dupRangeList(list);
+ while (rp1) {
+ minBase = rp1->mrd.mr_base;
+ minp = rp1;
+ minprev = NULL;
+ prev = rp1;
+ rp2 = rp1->next;
+ while (rp2) {
+ if (rp2->mrd.mr_base < minBase) {
+ minBase = rp2->mrd.mr_base;
+ minp = rp2;
+ minprev = prev;
+ }
+ prev = rp2;
+ rp2 = rp2->next;
+ }
+ if (minprev) {
+ minprev->next = minp->next;
+ rp1 = copy;
+ } else {
+ rp1 = minp->next;
+ }
+ minp->next = sorted;
+ sorted = minp;
+ }
+ return sorted;
+}
+
+/*
+ * findRanges returns a list of ranges that overlap the specified range.
+ */
+
+static void
+findRanges(unsigned long base, unsigned long size, RangePtr *ucp, RangePtr *wcp)
+{
+ struct mem_range_desc *mrd;
+ int nmr, i;
+ RangePtr rp, *p;
+
+ if (!(mrd = getAllRanges(&nmr)))
+ return;
+
+ for (i = 0; i < nmr; i++) {
+ if ((mrd[i].mr_flags & MDF_ACTIVE) &&
+ mrd[i].mr_base < base + size &&
+ mrd[i].mr_base + mrd[i].mr_len > base) {
+ if (mrd[i].mr_flags & MDF_WRITECOMBINE)
+ p = wcp;
+ else if (mrd[i].mr_flags & MDF_UNCACHEABLE)
+ p = ucp;
+ else
+ continue;
+ rp = xnfalloc(sizeof(RangeRec));
+ rp->mrd = mrd[i];
+ rp->next = *p;
+ *p = rp;
+ }
+ }
+ free(mrd);
+}
+
+/*
+ * This checks if the existing overlapping ranges fully cover the requested
+ * range. Is this overkill?
+ */
+
+static Bool
+fullCoverage(unsigned long base, unsigned long size, RangePtr overlap)
+{
+ RangePtr rp1, sorted = NULL;
+ unsigned long end;
+
+ sorted = sortRangeList(overlap);
+ /* Look for gaps */
+ rp1 = sorted;
+ end = base + size;
+ while (rp1) {
+ if (rp1->mrd.mr_base > base) {
+ freeRangeList(sorted);
+ return FALSE;
+ } else {
+ base = rp1->mrd.mr_base + rp1->mrd.mr_len;
+ }
+ if (base >= end) {
+ freeRangeList(sorted);
+ return TRUE;
+ }
+ rp1 = rp1->next;
+ }
+ freeRangeList(sorted);
+ return FALSE;
+}
+
+static pointer
+addWC(int screenNum, unsigned long base, unsigned long size, MessageType from)
+{
+ RangePtr uc = NULL, wc = NULL, retlist = NULL;
+ struct mem_range_desc mrd;
+ struct mem_range_op mro;
+
+ findRanges(base, size, &uc, &wc);
+
+ /* See of the full range is already WC */
+ if (!uc && fullCoverage(base, size, wc)) {
+ xf86DrvMsg(screenNum, from,
+ "Write-combining range (0x%lx,0x%lx) was already set\n",
+ base, size);
+ return NULL;
+ }
+
+ /* Otherwise, try to add the new range */
+ mrd.mr_base = base;
+ mrd.mr_len = size;
+ strcpy(mrd.mr_owner, X_MTRR_ID);
+ mrd.mr_flags = MDF_WRITECOMBINE;
+ mro.mo_desc = &mrd;
+ mro.mo_arg[0] = MEMRANGE_SET_UPDATE;
+ if (ioctl(devMemFd, MEMRANGE_SET, &mro)) {
+ xf86DrvMsg(screenNum, X_WARNING,
+ "Failed to set write-combining range "
+ "(0x%lx,0x%lx)\n", base, size);
+ return NULL;
+ } else {
+ xf86DrvMsg(screenNum, from,
+ "Write-combining range (0x%lx,0x%lx)\n", base, size);
+ retlist = xnfalloc(sizeof(RangeRec));
+ retlist->mrd = mrd;
+ retlist->wasWC = FALSE;
+ retlist->next = NULL;
+ return retlist;
+ }
+}
+
+static pointer
+delWC(int screenNum, unsigned long base, unsigned long size, MessageType from)
+{
+ RangePtr uc = NULL, wc = NULL, retlist = NULL;
+ struct mem_range_desc mrd;
+ struct mem_range_op mro;
+
+ findRanges(base, size, &uc, &wc);
+
+ /*
+ * See of the full range is already not WC, or if there is full
+ * coverage from UC ranges.
+ */
+ if (!wc || fullCoverage(base, size, uc)) {
+ xf86DrvMsg(screenNum, from,
+ "Write-combining range (0x%lx,0x%lx) was already clear\n",
+ base, size);
+ return NULL;
+ }
+
+ /* Otherwise, try to add the new range */
+ mrd.mr_base = base;
+ mrd.mr_len = size;
+ strcpy(mrd.mr_owner, X_MTRR_ID);
+ mrd.mr_flags = MDF_UNCACHEABLE;
+ mro.mo_desc = &mrd;
+ mro.mo_arg[0] = MEMRANGE_SET_UPDATE;
+ if (ioctl(devMemFd, MEMRANGE_SET, &mro)) {
+ xf86DrvMsg(screenNum, X_WARNING,
+ "Failed to remove write-combining range "
+ "(0x%lx,0x%lx)\n", base, size);
+ /* XXX Should then remove all of the overlapping WC ranges */
+ return NULL;
+ } else {
+ xf86DrvMsg(screenNum, from,
+ "Removed Write-combining range (0x%lx,0x%lx)\n",
+ base, size);
+ retlist = xnfalloc(sizeof(RangeRec));
+ retlist->mrd = mrd;
+ retlist->wasWC = TRUE;
+ retlist->next = NULL;
+ return retlist;
+ }
+}
+
+static pointer
+setWC(int screenNum, unsigned long base, unsigned long size, Bool enable,
+ MessageType from)
+{
+ if (enable)
+ return addWC(screenNum, base, size, from);
+ else
+ return delWC(screenNum, base, size, from);
+}
+
+static void
+undoWC(int screenNum, pointer list)
+{
+ RangePtr rp;
+ struct mem_range_op mro;
+ Bool failed;
+
+ rp = list;
+ while (rp) {
+#ifdef DEBUG
+ ErrorF("Undo for (0x%lx,0x%lx), %d\n",
+ (unsigned long)rp->mrd.mr_base,
+ (unsigned long)rp->mrd.mr_len, rp->wasWC);
+#endif
+ failed = FALSE;
+ if (rp->wasWC) {
+ mro.mo_arg[0] = MEMRANGE_SET_UPDATE;
+ rp->mrd.mr_flags = MDF_WRITECOMBINE;
+ strcpy(rp->mrd.mr_owner, "unknown");
+ } else {
+ mro.mo_arg[0] = MEMRANGE_SET_REMOVE;
+ }
+ mro.mo_desc = &rp->mrd;
+
+ if (ioctl(devMemFd, MEMRANGE_SET, &mro)) {
+ if (!rp->wasWC) {
+ mro.mo_arg[0] = MEMRANGE_SET_UPDATE;
+ rp->mrd.mr_flags = MDF_UNCACHEABLE;
+ strcpy(rp->mrd.mr_owner, "unknown");
+ if (ioctl(devMemFd, MEMRANGE_SET, &mro))
+ failed = TRUE;
+ } else
+ failed = TRUE;
+ }
+ if (failed) {
+ xf86DrvMsg(screenNum, X_WARNING,
+ "Failed to restore MTRR range (0x%lx,0x%lx)\n",
+ (unsigned long)rp->mrd.mr_base,
+ (unsigned long)rp->mrd.mr_len);
+ }
+ rp = rp->next;
+ }
+}
+
+#endif /* HAS_MTRR_SUPPORT */
+
+
+#if defined(HAS_MTRR_BUILTIN) && defined(__NetBSD__)
+static pointer
+NetBSDsetWC(int screenNum, unsigned long base, unsigned long size, Bool enable,
+ MessageType from)
+{
+ struct mtrr *mtrrp;
+ int n;
+
+ xf86DrvMsg(screenNum, X_WARNING,
+ "%s MTRR %lx - %lx\n", enable ? "set" : "remove",
+ base, (base + size));
+
+ mtrrp = xnfalloc(sizeof (struct mtrr));
+ mtrrp->base = base;
+ mtrrp->len = size;
+ mtrrp->type = MTRR_TYPE_WC;
+
+ /*
+ * MTRR_PRIVATE will make this MTRR get reset automatically
+ * if this process exits, so we have no need for an explicit
+ * cleanup operation when starting a new server.
+ */
+
+ if (enable)
+ mtrrp->flags = MTRR_VALID | MTRR_PRIVATE;
+ else
+ mtrrp->flags = 0;
+ n = 1;
+
+ if (i386_set_mtrr(mtrrp, &n) < 0) {
+ free(mtrrp);
+ return NULL;
+ }
+ return mtrrp;
+}
+
+static void
+NetBSDundoWC(int screenNum, pointer list)
+{
+ struct mtrr *mtrrp = (struct mtrr *)list;
+ int n;
+
+ if (mtrrp == NULL)
+ return;
+ n = 1;
+ mtrrp->flags &= ~MTRR_VALID;
+ i386_set_mtrr(mtrrp, &n);
+ free(mtrrp);
+}
+#endif
diff --git a/xorg-server/hw/xfree86/os-support/bus/Sbus.c b/xorg-server/hw/xfree86/os-support/bus/Sbus.c
index 0b6205f0b..4560ef016 100644
--- a/xorg-server/hw/xfree86/os-support/bus/Sbus.c
+++ b/xorg-server/hw/xfree86/os-support/bus/Sbus.c
@@ -1,690 +1,690 @@
-/*
- * SBUS and OpenPROM access functions.
- *
- * Copyright (C) 2000 Jakub Jelinek (jakub@redhat.com)
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * JAKUB JELINEK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#ifdef sun
-#include <sys/utsname.h>
-#endif
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86_OSlib.h"
-
-#include "xf86sbusBus.h"
-#include "xf86Sbus.h"
-
-int promRootNode;
-
-static int promFd = -1;
-static int promCurrentNode;
-static int promOpenCount = 0;
-static int promP1275 = -1;
-#define MAX_PROP 128
-#define MAX_VAL (4096-128-4)
-static struct openpromio *promOpio;
-
-sbusDevicePtr *xf86SbusInfo = NULL;
-
-struct sbus_devtable sbusDeviceTable[] = {
- { SBUS_DEVICE_BW2, FBTYPE_SUN2BW, "bwtwo", "sunbw2", "Sun Monochrome (bwtwo)" },
- { SBUS_DEVICE_CG2, FBTYPE_SUN2COLOR, "cgtwo", NULL, "Sun Color2 (cgtwo)" },
- { SBUS_DEVICE_CG3, FBTYPE_SUN3COLOR, "cgthree", "suncg3", "Sun Color3 (cgthree)" },
- { SBUS_DEVICE_CG4, FBTYPE_SUN4COLOR, "cgfour", NULL, "Sun Color4 (cgfour)" },
- { SBUS_DEVICE_CG6, FBTYPE_SUNFAST_COLOR, "cgsix", "suncg6", "Sun GX" },
- { SBUS_DEVICE_CG8, FBTYPE_MEMCOLOR, "cgeight", NULL, "Sun CG8/RasterOps" },
- { SBUS_DEVICE_CG12, FBTYPE_SUNGP3, "cgtwelve", NULL, "Sun GS (cgtwelve)" },
- { SBUS_DEVICE_CG14, FBTYPE_MDICOLOR, "cgfourteen", "suncg14", "Sun SX" },
- { SBUS_DEVICE_GT, FBTYPE_SUNGT, "gt", NULL, "Sun Graphics Tower" },
- { SBUS_DEVICE_MGX, -1, "mgx", NULL, "Quantum 3D MGXplus" },
- { SBUS_DEVICE_LEO, FBTYPE_SUNLEO, "leo", "sunleo", "Sun ZX or Turbo ZX" },
- { SBUS_DEVICE_TCX, FBTYPE_TCXCOLOR, "tcx", "suntcx", "Sun TCX" },
- { SBUS_DEVICE_FFB, FBTYPE_CREATOR, "ffb", "sunffb", "Sun FFB" },
- { SBUS_DEVICE_FFB, FBTYPE_CREATOR, "afb", "sunffb", "Sun Elite3D" },
- { 0, 0, NULL }
-};
-
-int
-promGetSibling(int node)
-{
- promOpio->oprom_size = sizeof(int);
-
- if (node == -1) return 0;
- *(int *)promOpio->oprom_array = node;
- if (ioctl(promFd, OPROMNEXT, promOpio) < 0)
- return 0;
- promCurrentNode = *(int *)promOpio->oprom_array;
- return *(int *)promOpio->oprom_array;
-}
-
-int
-promGetChild(int node)
-{
- promOpio->oprom_size = sizeof(int);
-
- if (!node || node == -1) return 0;
- *(int *)promOpio->oprom_array = node;
- if (ioctl(promFd, OPROMCHILD, promOpio) < 0)
- return 0;
- promCurrentNode = *(int *)promOpio->oprom_array;
- return *(int *)promOpio->oprom_array;
-}
-
-char *
-promGetProperty(const char *prop, int *lenp)
-{
- promOpio->oprom_size = MAX_VAL;
-
- strcpy(promOpio->oprom_array, prop);
- if (ioctl(promFd, OPROMGETPROP, promOpio) < 0)
- return 0;
- if (lenp) *lenp = promOpio->oprom_size;
- return promOpio->oprom_array;
-}
-
-int
-promGetBool(const char *prop)
-{
- promOpio->oprom_size = 0;
-
- *(int *)promOpio->oprom_array = 0;
- for (;;) {
- promOpio->oprom_size = MAX_PROP;
- if (ioctl(promFd, OPROMNXTPROP, promOpio) < 0)
- return 0;
- if (!promOpio->oprom_size)
- return 0;
- if (!strcmp(promOpio->oprom_array, prop))
- return 1;
- }
-}
-
-#define PROM_NODE_SIBLING 0x01
-#define PROM_NODE_PREF 0x02
-#define PROM_NODE_SBUS 0x04
-#define PROM_NODE_EBUS 0x08
-#define PROM_NODE_PCI 0x10
-
-static int
-promSetNode(sbusPromNodePtr pnode)
-{
- int node;
-
- if (!pnode->node || pnode->node == -1)
- return -1;
- if (pnode->cookie[0] & PROM_NODE_SIBLING)
- node = promGetSibling(pnode->cookie[1]);
- else
- node = promGetChild(pnode->cookie[1]);
- if (pnode->node != node)
- return -1;
- return 0;
-}
-
-static void
-promIsP1275(void)
-{
-#ifdef linux
- FILE *f;
- char buffer[1024];
-
- if (promP1275 != -1)
- return;
- promP1275 = 0;
- f = fopen("/proc/cpuinfo","r");
- if (!f) return;
- while (fgets(buffer, 1024, f) != NULL)
- if (!strncmp (buffer, "type", 4) && strstr (buffer, "sun4u")) {
- promP1275 = 1;
- break;
- }
- fclose(f);
-#elif defined(sun)
- struct utsname buffer;
-
- if ((uname(&buffer) >= 0) && !strcmp(buffer.machine, "sun4u"))
- promP1275 = TRUE;
- else
- promP1275 = FALSE;
-#elif defined(__FreeBSD__)
- promP1275 = TRUE;
-#else
-#error Missing promIsP1275() function for this OS
-#endif
-}
-
-void
-sparcPromClose(void)
-{
- if (promOpenCount > 1) {
- promOpenCount--;
- return;
- }
- if (promFd != -1) {
- close(promFd);
- promFd = -1;
- }
- if (promOpio) {
- xfree(promOpio);
- promOpio = NULL;
- }
- promOpenCount = 0;
-}
-
-int
-sparcPromInit(void)
-{
- if (promOpenCount) {
- promOpenCount++;
- return 0;
- }
- promFd = open("/dev/openprom", O_RDONLY, 0);
- if (promFd == -1)
- return -1;
- promOpio = (struct openpromio *)xalloc(4096);
- if (!promOpio) {
- sparcPromClose();
- return -1;
- }
- promRootNode = promGetSibling(0);
- if (!promRootNode) {
- sparcPromClose();
- return -1;
- }
- promIsP1275();
- promOpenCount++;
-
- return 0;
-}
-
-char *
-sparcPromGetProperty(sbusPromNodePtr pnode, const char *prop, int *lenp)
-{
- if (promSetNode(pnode))
- return NULL;
- return promGetProperty(prop, lenp);
-}
-
-int
-sparcPromGetBool(sbusPromNodePtr pnode, const char *prop)
-{
- if (promSetNode(pnode))
- return 0;
- return promGetBool(prop);
-}
-
-static char *
-promWalkGetDriverName(int node, int oldnode)
-{
- int nextnode;
- int len;
- char *prop;
- int devId, i;
-
- prop = promGetProperty("device_type", &len);
- if (prop && (len > 0)) do {
- if (!strcmp(prop, "display")) {
- prop = promGetProperty("name", &len);
- if (!prop || len <= 0)
- break;
- while ((*prop >= 'A' && *prop <= 'Z') || *prop == ',')
- prop++;
- for (i = 0; sbusDeviceTable[i].devId; i++)
- if (!strcmp(prop, sbusDeviceTable[i].promName))
- break;
- devId = sbusDeviceTable[i].devId;
- if (!devId)
- break;
- if (sbusDeviceTable[i].driverName)
- return sbusDeviceTable[i].driverName;
- }
- } while (0);
-
- nextnode = promGetChild(node);
- if (nextnode) {
- char *name;
- name = promWalkGetDriverName(nextnode, node);
- if (name)
- return name;
- }
-
- nextnode = promGetSibling(node);
- if (nextnode)
- return promWalkGetDriverName(nextnode, node);
- return NULL;
-}
-
-char *
-sparcDriverName(void)
-{
- char *name;
-
- if (sparcPromInit() < 0)
- return NULL;
- promGetSibling(0);
- name = promWalkGetDriverName(promRootNode, 0);
- sparcPromClose();
- return name;
-}
-
-static void
-promWalkAssignNodes(int node, int oldnode, int flags, sbusDevicePtr *devicePtrs)
-{
- int nextnode;
- int len, sbus = flags & PROM_NODE_SBUS;
- char *prop;
- int devId, i, j;
- sbusPromNode pNode, pNode2;
-
- prop = promGetProperty("device_type", &len);
- if (prop && (len > 0)) do {
- if (!strcmp(prop, "display")) {
- prop = promGetProperty("name", &len);
- if (!prop || len <= 0)
- break;
- while ((*prop >= 'A' && *prop <= 'Z') || *prop == ',')
- prop++;
- for (i = 0; sbusDeviceTable[i].devId; i++)
- if (!strcmp(prop, sbusDeviceTable[i].promName))
- break;
- devId = sbusDeviceTable[i].devId;
- if (!devId)
- break;
- if (!sbus) {
- if (devId == SBUS_DEVICE_FFB) {
- /*
- * All /SUNW,ffb outside of SBUS tree come before all
- * /SUNW,afb outside of SBUS tree in Linux.
- */
- if (!strcmp(prop, "afb"))
- flags |= PROM_NODE_PREF;
- } else if (devId != SBUS_DEVICE_CG14)
- break;
- }
- for (i = 0; i < 32; i++) {
- if (!devicePtrs[i] || devicePtrs[i]->devId != devId)
- continue;
- if (devicePtrs[i]->node.node) {
- if ((devicePtrs[i]->node.cookie[0] & ~PROM_NODE_SIBLING) <=
- (flags & ~PROM_NODE_SIBLING))
- continue;
- for (j = i + 1, pNode = devicePtrs[i]->node; j < 32; j++) {
- if (!devicePtrs[j] || devicePtrs[j]->devId != devId)
- continue;
- pNode2 = devicePtrs[j]->node;
- devicePtrs[j]->node = pNode;
- pNode = pNode2;
- }
- }
- devicePtrs[i]->node.node = node;
- devicePtrs[i]->node.cookie[0] = flags;
- devicePtrs[i]->node.cookie[1] = oldnode;
- break;
- }
- break;
- }
- } while (0);
-
- prop = promGetProperty("name", &len);
- if (prop && len > 0) {
- if (!strcmp(prop, "sbus") || !strcmp(prop, "sbi"))
- sbus = PROM_NODE_SBUS;
- }
-
- nextnode = promGetChild(node);
- if (nextnode)
- promWalkAssignNodes(nextnode, node, sbus, devicePtrs);
-
- nextnode = promGetSibling(node);
- if (nextnode)
- promWalkAssignNodes(nextnode, node, PROM_NODE_SIBLING | sbus, devicePtrs);
-}
-
-void
-sparcPromAssignNodes(void)
-{
- sbusDevicePtr psdp, *psdpp;
- int n, holes = 0, i, j;
- FILE *f;
- sbusDevicePtr devicePtrs[32];
-
- memset(devicePtrs, 0, sizeof(devicePtrs));
- for (psdpp = xf86SbusInfo, n = 0; (psdp = *psdpp); psdpp++, n++) {
- if (psdp->fbNum != n)
- holes = 1;
- devicePtrs[psdp->fbNum] = psdp;
- }
- if (holes && (f = fopen("/proc/fb", "r")) != NULL) {
- /* We could not open one of fb devices, check /proc/fb to see what
- * were the types of the cards missed. */
- char buffer[64];
- int fbNum, devId;
- static struct {
- int devId;
- char *prefix;
- } procFbPrefixes[] = {
- { SBUS_DEVICE_BW2, "BWtwo" },
- { SBUS_DEVICE_CG14, "CGfourteen" },
- { SBUS_DEVICE_CG6, "CGsix" },
- { SBUS_DEVICE_CG3, "CGthree" },
- { SBUS_DEVICE_FFB, "Creator" },
- { SBUS_DEVICE_FFB, "Elite 3D" },
- { SBUS_DEVICE_LEO, "Leo" },
- { SBUS_DEVICE_TCX, "TCX" },
- { 0, NULL },
- };
-
- while (fscanf(f, "%d %63s\n", &fbNum, buffer) == 2) {
- for (i = 0; procFbPrefixes[i].devId; i++)
- if (! strncmp(procFbPrefixes[i].prefix, buffer,
- strlen(procFbPrefixes[i].prefix)))
- break;
- devId = procFbPrefixes[i].devId;
- if (! devId) continue;
- if (devicePtrs[fbNum]) {
- if (devicePtrs[fbNum]->devId != devId)
- xf86ErrorF("Inconsistent /proc/fb with FBIOGATTR\n");
- } else if (!devicePtrs[fbNum]) {
- devicePtrs[fbNum] = psdp = xnfcalloc(sizeof (sbusDevice), 1);
- psdp->devId = devId;
- psdp->fbNum = fbNum;
- psdp->fd = -2;
- }
- }
- fclose(f);
- }
- promGetSibling(0);
- promWalkAssignNodes(promRootNode, 0, PROM_NODE_PREF, devicePtrs);
- for (i = 0, j = 0; i < 32; i++)
- if (devicePtrs[i] && devicePtrs[i]->fbNum == -1)
- j++;
- xf86SbusInfo = xnfrealloc(xf86SbusInfo, sizeof(psdp) * (n + j + 1));
- for (i = 0, psdpp = xf86SbusInfo; i < 32; i++)
- if (devicePtrs[i]) {
- if (devicePtrs[i]->fbNum == -1) {
- memmove(psdpp + 1, psdpp, sizeof(psdpp) * (n + 1));
- *psdpp = devicePtrs[i];
- } else
- n--;
- }
-}
-
-static char *
-promGetReg(int type)
-{
- char *prop;
- int len;
- static char regstr[40];
-
- regstr[0] = 0;
- prop = promGetProperty("reg", &len);
- if (prop && len >= 4) {
- unsigned int *reg = (unsigned int *)prop;
- if (!promP1275 || (type == PROM_NODE_SBUS) || (type == PROM_NODE_EBUS))
- sprintf (regstr, "@%x,%x", reg[0], reg[1]);
- else if (type == PROM_NODE_PCI) {
- if ((reg[0] >> 8) & 7)
- sprintf (regstr, "@%x,%x", (reg[0] >> 11) & 0x1f, (reg[0] >> 8) & 7);
- else
- sprintf (regstr, "@%x", (reg[0] >> 11) & 0x1f);
- } else if (len == 4)
- sprintf (regstr, "@%x", reg[0]);
- else {
- unsigned int regs[2];
-
- /* Things get more complicated on UPA. If upa-portid exists,
- then address is @upa-portid,second-int-in-reg, otherwise
- it is @first-int-in-reg/16,second-int-in-reg (well, probably
- upa-portid always exists, but just to be safe). */
- memcpy (regs, reg, sizeof(regs));
- prop = promGetProperty("upa-portid", &len);
- if (prop && len == 4) {
- reg = (unsigned int *)prop;
- sprintf (regstr, "@%x,%x", reg[0], regs[1]);
- } else
- sprintf (regstr, "@%x,%x", regs[0] >> 4, regs[1]);
- }
- }
- return regstr;
-}
-
-static int
-promWalkNode2Pathname(char *path, int parent, int node, int searchNode, int type)
-{
- int nextnode;
- int len, ntype = type;
- char *prop, *p;
-
- prop = promGetProperty("name", &len);
- *path = '/';
- if (!prop || len <= 0)
- return 0;
- if ((!strcmp(prop, "sbus") || !strcmp(prop, "sbi")) && !type)
- ntype = PROM_NODE_SBUS;
- else if (!strcmp(prop, "ebus") && type == PROM_NODE_PCI)
- ntype = PROM_NODE_EBUS;
- else if (!strcmp(prop, "pci") && !type)
- ntype = PROM_NODE_PCI;
- strcpy (path + 1, prop);
- p = promGetReg(type);
- if (*p)
- strcat (path, p);
- if (node == searchNode)
- return 1;
- nextnode = promGetChild(node);
- if (nextnode &&
- promWalkNode2Pathname(strchr(path, 0), node, nextnode, searchNode, ntype))
- return 1;
- nextnode = promGetSibling(node);
- if (nextnode &&
- promWalkNode2Pathname(path, parent, nextnode, searchNode, type))
- return 1;
- return 0;
-}
-
-char *
-sparcPromNode2Pathname(sbusPromNodePtr pnode)
-{
- char *ret;
-
- if (!pnode->node) return NULL;
- ret = xalloc(4096);
- if (!ret) return NULL;
- if (promWalkNode2Pathname(ret, promRootNode, promGetChild(promRootNode), pnode->node, 0))
- return ret;
- xfree(ret);
- return NULL;
-}
-
-static int
-promWalkPathname2Node(char *name, char *regstr, int parent, int type)
-{
- int len, node, ret;
- char *prop, *p;
-
- for (;;) {
- prop = promGetProperty("name", &len);
- if (!prop || len <= 0)
- return 0;
- if ((!strcmp(prop, "sbus") || !strcmp(prop, "sbi")) && !type)
- type = PROM_NODE_SBUS;
- else if (!strcmp(prop, "ebus") && type == PROM_NODE_PCI)
- type = PROM_NODE_EBUS;
- else if (!strcmp(prop, "pci") && !type)
- type = PROM_NODE_PCI;
- for (node = promGetChild(parent); node; node = promGetSibling(node)) {
- prop = promGetProperty("name", &len);
- if (!prop || len <= 0)
- continue;
- if (*name && strcmp(name, prop))
- continue;
- if (*regstr) {
- p = promGetReg(type);
- if (! *p || strcmp(p + 1, regstr))
- continue;
- }
- break;
- }
- if (!node) {
- for (node = promGetChild(parent); node; node = promGetSibling(node)) {
- ret = promWalkPathname2Node(name, regstr, node, type);
- if (ret) return ret;
- }
- return 0;
- }
- name = strchr(regstr, 0) + 1;
- if (! *name)
- return node;
- p = strchr(name, '/');
- if (p)
- *p = 0;
- else
- p = strchr(name, 0);
- regstr = strchr(name, '@');
- if (regstr)
- *regstr++ = 0;
- else
- regstr = p;
- if (name == regstr)
- return 0;
- parent = node;
- }
-}
-
-int
-sparcPromPathname2Node(const char *pathName)
-{
- int i;
- char *name, *regstr, *p;
-
- i = strlen(pathName);
- name = xalloc(i + 2);
- if (! name) return 0;
- strcpy (name, pathName);
- name [i + 1] = 0;
- if (name[0] != '/')
- return 0;
- p = strchr(name + 1, '/');
- if (p)
- *p = 0;
- else
- p = strchr(name, 0);
- regstr = strchr(name, '@');
- if (regstr)
- *regstr++ = 0;
- else
- regstr = p;
- if (name + 1 == regstr)
- return 0;
- promGetSibling(0);
- i = promWalkPathname2Node(name + 1, regstr, promRootNode, 0);
- xfree(name);
- return i;
-}
-
-pointer
-xf86MapSbusMem(sbusDevicePtr psdp, unsigned long offset, unsigned long size)
-{
- pointer ret;
- unsigned long pagemask = getpagesize() - 1;
- unsigned long off = offset & ~pagemask;
- unsigned long len = ((offset + size + pagemask) & ~pagemask) - off;
-
- if (psdp->fd == -1) {
- psdp->fd = open(psdp->device, O_RDWR);
- if (psdp->fd == -1)
- return NULL;
- } else if (psdp->fd < 0)
- return NULL;
-
- ret = (pointer) mmap (NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE,
- psdp->fd, off);
- if (ret == (pointer) -1) {
- ret = (pointer) mmap (NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED,
- psdp->fd, off);
- }
- if (ret == (pointer) -1)
- return NULL;
-
- return (char *)ret + (offset - off);
-}
-
-void
-xf86UnmapSbusMem(sbusDevicePtr psdp, pointer addr, unsigned long size)
-{
- unsigned long mask = getpagesize() - 1;
- unsigned long base = (unsigned long)addr & ~mask;
- unsigned long len = (((unsigned long)addr + size + mask) & ~mask) - base;
-
- munmap ((pointer)base, len);
-}
-
-/* Tell OS that we are driving the HW cursor ourselves. */
-void
-xf86SbusHideOsHwCursor(sbusDevicePtr psdp)
-{
- struct fbcursor fbcursor;
- unsigned char zeros[8];
-
- memset(&fbcursor, 0, sizeof(fbcursor));
- memset(&zeros, 0, sizeof(zeros));
- fbcursor.cmap.count = 2;
- fbcursor.cmap.red = zeros;
- fbcursor.cmap.green = zeros;
- fbcursor.cmap.blue = zeros;
- fbcursor.image = (char *)zeros;
- fbcursor.mask = (char *)zeros;
- fbcursor.size.x = 32;
- fbcursor.size.y = 1;
- fbcursor.set = FB_CUR_SETALL;
- ioctl(psdp->fd, FBIOSCURSOR, &fbcursor);
-}
-
-/* Set HW cursor colormap. */
-void
-xf86SbusSetOsHwCursorCmap(sbusDevicePtr psdp, int bg, int fg)
-{
- struct fbcursor fbcursor;
- unsigned char red[2], green[2], blue[2];
-
- memset(&fbcursor, 0, sizeof(fbcursor));
- red[0] = bg >> 16;
- green[0] = bg >> 8;
- blue[0] = bg;
- red[1] = fg >> 16;
- green[1] = fg >> 8;
- blue[1] = fg;
- fbcursor.cmap.count = 2;
- fbcursor.cmap.red = red;
- fbcursor.cmap.green = green;
- fbcursor.cmap.blue = blue;
- fbcursor.set = FB_CUR_SETCMAP;
- ioctl(psdp->fd, FBIOSCURSOR, &fbcursor);
-}
+/*
+ * SBUS and OpenPROM access functions.
+ *
+ * Copyright (C) 2000 Jakub Jelinek (jakub@redhat.com)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * JAKUB JELINEK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#ifdef sun
+#include <sys/utsname.h>
+#endif
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+#include "xf86sbusBus.h"
+#include "xf86Sbus.h"
+
+int promRootNode;
+
+static int promFd = -1;
+static int promCurrentNode;
+static int promOpenCount = 0;
+static int promP1275 = -1;
+#define MAX_PROP 128
+#define MAX_VAL (4096-128-4)
+static struct openpromio *promOpio;
+
+sbusDevicePtr *xf86SbusInfo = NULL;
+
+struct sbus_devtable sbusDeviceTable[] = {
+ { SBUS_DEVICE_BW2, FBTYPE_SUN2BW, "bwtwo", "sunbw2", "Sun Monochrome (bwtwo)" },
+ { SBUS_DEVICE_CG2, FBTYPE_SUN2COLOR, "cgtwo", NULL, "Sun Color2 (cgtwo)" },
+ { SBUS_DEVICE_CG3, FBTYPE_SUN3COLOR, "cgthree", "suncg3", "Sun Color3 (cgthree)" },
+ { SBUS_DEVICE_CG4, FBTYPE_SUN4COLOR, "cgfour", NULL, "Sun Color4 (cgfour)" },
+ { SBUS_DEVICE_CG6, FBTYPE_SUNFAST_COLOR, "cgsix", "suncg6", "Sun GX" },
+ { SBUS_DEVICE_CG8, FBTYPE_MEMCOLOR, "cgeight", NULL, "Sun CG8/RasterOps" },
+ { SBUS_DEVICE_CG12, FBTYPE_SUNGP3, "cgtwelve", NULL, "Sun GS (cgtwelve)" },
+ { SBUS_DEVICE_CG14, FBTYPE_MDICOLOR, "cgfourteen", "suncg14", "Sun SX" },
+ { SBUS_DEVICE_GT, FBTYPE_SUNGT, "gt", NULL, "Sun Graphics Tower" },
+ { SBUS_DEVICE_MGX, -1, "mgx", NULL, "Quantum 3D MGXplus" },
+ { SBUS_DEVICE_LEO, FBTYPE_SUNLEO, "leo", "sunleo", "Sun ZX or Turbo ZX" },
+ { SBUS_DEVICE_TCX, FBTYPE_TCXCOLOR, "tcx", "suntcx", "Sun TCX" },
+ { SBUS_DEVICE_FFB, FBTYPE_CREATOR, "ffb", "sunffb", "Sun FFB" },
+ { SBUS_DEVICE_FFB, FBTYPE_CREATOR, "afb", "sunffb", "Sun Elite3D" },
+ { 0, 0, NULL }
+};
+
+int
+promGetSibling(int node)
+{
+ promOpio->oprom_size = sizeof(int);
+
+ if (node == -1) return 0;
+ *(int *)promOpio->oprom_array = node;
+ if (ioctl(promFd, OPROMNEXT, promOpio) < 0)
+ return 0;
+ promCurrentNode = *(int *)promOpio->oprom_array;
+ return *(int *)promOpio->oprom_array;
+}
+
+int
+promGetChild(int node)
+{
+ promOpio->oprom_size = sizeof(int);
+
+ if (!node || node == -1) return 0;
+ *(int *)promOpio->oprom_array = node;
+ if (ioctl(promFd, OPROMCHILD, promOpio) < 0)
+ return 0;
+ promCurrentNode = *(int *)promOpio->oprom_array;
+ return *(int *)promOpio->oprom_array;
+}
+
+char *
+promGetProperty(const char *prop, int *lenp)
+{
+ promOpio->oprom_size = MAX_VAL;
+
+ strcpy(promOpio->oprom_array, prop);
+ if (ioctl(promFd, OPROMGETPROP, promOpio) < 0)
+ return 0;
+ if (lenp) *lenp = promOpio->oprom_size;
+ return promOpio->oprom_array;
+}
+
+int
+promGetBool(const char *prop)
+{
+ promOpio->oprom_size = 0;
+
+ *(int *)promOpio->oprom_array = 0;
+ for (;;) {
+ promOpio->oprom_size = MAX_PROP;
+ if (ioctl(promFd, OPROMNXTPROP, promOpio) < 0)
+ return 0;
+ if (!promOpio->oprom_size)
+ return 0;
+ if (!strcmp(promOpio->oprom_array, prop))
+ return 1;
+ }
+}
+
+#define PROM_NODE_SIBLING 0x01
+#define PROM_NODE_PREF 0x02
+#define PROM_NODE_SBUS 0x04
+#define PROM_NODE_EBUS 0x08
+#define PROM_NODE_PCI 0x10
+
+static int
+promSetNode(sbusPromNodePtr pnode)
+{
+ int node;
+
+ if (!pnode->node || pnode->node == -1)
+ return -1;
+ if (pnode->cookie[0] & PROM_NODE_SIBLING)
+ node = promGetSibling(pnode->cookie[1]);
+ else
+ node = promGetChild(pnode->cookie[1]);
+ if (pnode->node != node)
+ return -1;
+ return 0;
+}
+
+static void
+promIsP1275(void)
+{
+#ifdef linux
+ FILE *f;
+ char buffer[1024];
+
+ if (promP1275 != -1)
+ return;
+ promP1275 = 0;
+ f = fopen("/proc/cpuinfo","r");
+ if (!f) return;
+ while (fgets(buffer, 1024, f) != NULL)
+ if (!strncmp (buffer, "type", 4) && strstr (buffer, "sun4u")) {
+ promP1275 = 1;
+ break;
+ }
+ fclose(f);
+#elif defined(sun)
+ struct utsname buffer;
+
+ if ((uname(&buffer) >= 0) && !strcmp(buffer.machine, "sun4u"))
+ promP1275 = TRUE;
+ else
+ promP1275 = FALSE;
+#elif defined(__FreeBSD__)
+ promP1275 = TRUE;
+#else
+#error Missing promIsP1275() function for this OS
+#endif
+}
+
+void
+sparcPromClose(void)
+{
+ if (promOpenCount > 1) {
+ promOpenCount--;
+ return;
+ }
+ if (promFd != -1) {
+ close(promFd);
+ promFd = -1;
+ }
+ if (promOpio) {
+ free(promOpio);
+ promOpio = NULL;
+ }
+ promOpenCount = 0;
+}
+
+int
+sparcPromInit(void)
+{
+ if (promOpenCount) {
+ promOpenCount++;
+ return 0;
+ }
+ promFd = open("/dev/openprom", O_RDONLY, 0);
+ if (promFd == -1)
+ return -1;
+ promOpio = (struct openpromio *)malloc(4096);
+ if (!promOpio) {
+ sparcPromClose();
+ return -1;
+ }
+ promRootNode = promGetSibling(0);
+ if (!promRootNode) {
+ sparcPromClose();
+ return -1;
+ }
+ promIsP1275();
+ promOpenCount++;
+
+ return 0;
+}
+
+char *
+sparcPromGetProperty(sbusPromNodePtr pnode, const char *prop, int *lenp)
+{
+ if (promSetNode(pnode))
+ return NULL;
+ return promGetProperty(prop, lenp);
+}
+
+int
+sparcPromGetBool(sbusPromNodePtr pnode, const char *prop)
+{
+ if (promSetNode(pnode))
+ return 0;
+ return promGetBool(prop);
+}
+
+static char *
+promWalkGetDriverName(int node, int oldnode)
+{
+ int nextnode;
+ int len;
+ char *prop;
+ int devId, i;
+
+ prop = promGetProperty("device_type", &len);
+ if (prop && (len > 0)) do {
+ if (!strcmp(prop, "display")) {
+ prop = promGetProperty("name", &len);
+ if (!prop || len <= 0)
+ break;
+ while ((*prop >= 'A' && *prop <= 'Z') || *prop == ',')
+ prop++;
+ for (i = 0; sbusDeviceTable[i].devId; i++)
+ if (!strcmp(prop, sbusDeviceTable[i].promName))
+ break;
+ devId = sbusDeviceTable[i].devId;
+ if (!devId)
+ break;
+ if (sbusDeviceTable[i].driverName)
+ return sbusDeviceTable[i].driverName;
+ }
+ } while (0);
+
+ nextnode = promGetChild(node);
+ if (nextnode) {
+ char *name;
+ name = promWalkGetDriverName(nextnode, node);
+ if (name)
+ return name;
+ }
+
+ nextnode = promGetSibling(node);
+ if (nextnode)
+ return promWalkGetDriverName(nextnode, node);
+ return NULL;
+}
+
+char *
+sparcDriverName(void)
+{
+ char *name;
+
+ if (sparcPromInit() < 0)
+ return NULL;
+ promGetSibling(0);
+ name = promWalkGetDriverName(promRootNode, 0);
+ sparcPromClose();
+ return name;
+}
+
+static void
+promWalkAssignNodes(int node, int oldnode, int flags, sbusDevicePtr *devicePtrs)
+{
+ int nextnode;
+ int len, sbus = flags & PROM_NODE_SBUS;
+ char *prop;
+ int devId, i, j;
+ sbusPromNode pNode, pNode2;
+
+ prop = promGetProperty("device_type", &len);
+ if (prop && (len > 0)) do {
+ if (!strcmp(prop, "display")) {
+ prop = promGetProperty("name", &len);
+ if (!prop || len <= 0)
+ break;
+ while ((*prop >= 'A' && *prop <= 'Z') || *prop == ',')
+ prop++;
+ for (i = 0; sbusDeviceTable[i].devId; i++)
+ if (!strcmp(prop, sbusDeviceTable[i].promName))
+ break;
+ devId = sbusDeviceTable[i].devId;
+ if (!devId)
+ break;
+ if (!sbus) {
+ if (devId == SBUS_DEVICE_FFB) {
+ /*
+ * All /SUNW,ffb outside of SBUS tree come before all
+ * /SUNW,afb outside of SBUS tree in Linux.
+ */
+ if (!strcmp(prop, "afb"))
+ flags |= PROM_NODE_PREF;
+ } else if (devId != SBUS_DEVICE_CG14)
+ break;
+ }
+ for (i = 0; i < 32; i++) {
+ if (!devicePtrs[i] || devicePtrs[i]->devId != devId)
+ continue;
+ if (devicePtrs[i]->node.node) {
+ if ((devicePtrs[i]->node.cookie[0] & ~PROM_NODE_SIBLING) <=
+ (flags & ~PROM_NODE_SIBLING))
+ continue;
+ for (j = i + 1, pNode = devicePtrs[i]->node; j < 32; j++) {
+ if (!devicePtrs[j] || devicePtrs[j]->devId != devId)
+ continue;
+ pNode2 = devicePtrs[j]->node;
+ devicePtrs[j]->node = pNode;
+ pNode = pNode2;
+ }
+ }
+ devicePtrs[i]->node.node = node;
+ devicePtrs[i]->node.cookie[0] = flags;
+ devicePtrs[i]->node.cookie[1] = oldnode;
+ break;
+ }
+ break;
+ }
+ } while (0);
+
+ prop = promGetProperty("name", &len);
+ if (prop && len > 0) {
+ if (!strcmp(prop, "sbus") || !strcmp(prop, "sbi"))
+ sbus = PROM_NODE_SBUS;
+ }
+
+ nextnode = promGetChild(node);
+ if (nextnode)
+ promWalkAssignNodes(nextnode, node, sbus, devicePtrs);
+
+ nextnode = promGetSibling(node);
+ if (nextnode)
+ promWalkAssignNodes(nextnode, node, PROM_NODE_SIBLING | sbus, devicePtrs);
+}
+
+void
+sparcPromAssignNodes(void)
+{
+ sbusDevicePtr psdp, *psdpp;
+ int n, holes = 0, i, j;
+ FILE *f;
+ sbusDevicePtr devicePtrs[32];
+
+ memset(devicePtrs, 0, sizeof(devicePtrs));
+ for (psdpp = xf86SbusInfo, n = 0; (psdp = *psdpp); psdpp++, n++) {
+ if (psdp->fbNum != n)
+ holes = 1;
+ devicePtrs[psdp->fbNum] = psdp;
+ }
+ if (holes && (f = fopen("/proc/fb", "r")) != NULL) {
+ /* We could not open one of fb devices, check /proc/fb to see what
+ * were the types of the cards missed. */
+ char buffer[64];
+ int fbNum, devId;
+ static struct {
+ int devId;
+ char *prefix;
+ } procFbPrefixes[] = {
+ { SBUS_DEVICE_BW2, "BWtwo" },
+ { SBUS_DEVICE_CG14, "CGfourteen" },
+ { SBUS_DEVICE_CG6, "CGsix" },
+ { SBUS_DEVICE_CG3, "CGthree" },
+ { SBUS_DEVICE_FFB, "Creator" },
+ { SBUS_DEVICE_FFB, "Elite 3D" },
+ { SBUS_DEVICE_LEO, "Leo" },
+ { SBUS_DEVICE_TCX, "TCX" },
+ { 0, NULL },
+ };
+
+ while (fscanf(f, "%d %63s\n", &fbNum, buffer) == 2) {
+ for (i = 0; procFbPrefixes[i].devId; i++)
+ if (! strncmp(procFbPrefixes[i].prefix, buffer,
+ strlen(procFbPrefixes[i].prefix)))
+ break;
+ devId = procFbPrefixes[i].devId;
+ if (! devId) continue;
+ if (devicePtrs[fbNum]) {
+ if (devicePtrs[fbNum]->devId != devId)
+ xf86ErrorF("Inconsistent /proc/fb with FBIOGATTR\n");
+ } else if (!devicePtrs[fbNum]) {
+ devicePtrs[fbNum] = psdp = xnfcalloc(sizeof (sbusDevice), 1);
+ psdp->devId = devId;
+ psdp->fbNum = fbNum;
+ psdp->fd = -2;
+ }
+ }
+ fclose(f);
+ }
+ promGetSibling(0);
+ promWalkAssignNodes(promRootNode, 0, PROM_NODE_PREF, devicePtrs);
+ for (i = 0, j = 0; i < 32; i++)
+ if (devicePtrs[i] && devicePtrs[i]->fbNum == -1)
+ j++;
+ xf86SbusInfo = xnfrealloc(xf86SbusInfo, sizeof(psdp) * (n + j + 1));
+ for (i = 0, psdpp = xf86SbusInfo; i < 32; i++)
+ if (devicePtrs[i]) {
+ if (devicePtrs[i]->fbNum == -1) {
+ memmove(psdpp + 1, psdpp, sizeof(psdpp) * (n + 1));
+ *psdpp = devicePtrs[i];
+ } else
+ n--;
+ }
+}
+
+static char *
+promGetReg(int type)
+{
+ char *prop;
+ int len;
+ static char regstr[40];
+
+ regstr[0] = 0;
+ prop = promGetProperty("reg", &len);
+ if (prop && len >= 4) {
+ unsigned int *reg = (unsigned int *)prop;
+ if (!promP1275 || (type == PROM_NODE_SBUS) || (type == PROM_NODE_EBUS))
+ sprintf (regstr, "@%x,%x", reg[0], reg[1]);
+ else if (type == PROM_NODE_PCI) {
+ if ((reg[0] >> 8) & 7)
+ sprintf (regstr, "@%x,%x", (reg[0] >> 11) & 0x1f, (reg[0] >> 8) & 7);
+ else
+ sprintf (regstr, "@%x", (reg[0] >> 11) & 0x1f);
+ } else if (len == 4)
+ sprintf (regstr, "@%x", reg[0]);
+ else {
+ unsigned int regs[2];
+
+ /* Things get more complicated on UPA. If upa-portid exists,
+ then address is @upa-portid,second-int-in-reg, otherwise
+ it is @first-int-in-reg/16,second-int-in-reg (well, probably
+ upa-portid always exists, but just to be safe). */
+ memcpy (regs, reg, sizeof(regs));
+ prop = promGetProperty("upa-portid", &len);
+ if (prop && len == 4) {
+ reg = (unsigned int *)prop;
+ sprintf (regstr, "@%x,%x", reg[0], regs[1]);
+ } else
+ sprintf (regstr, "@%x,%x", regs[0] >> 4, regs[1]);
+ }
+ }
+ return regstr;
+}
+
+static int
+promWalkNode2Pathname(char *path, int parent, int node, int searchNode, int type)
+{
+ int nextnode;
+ int len, ntype = type;
+ char *prop, *p;
+
+ prop = promGetProperty("name", &len);
+ *path = '/';
+ if (!prop || len <= 0)
+ return 0;
+ if ((!strcmp(prop, "sbus") || !strcmp(prop, "sbi")) && !type)
+ ntype = PROM_NODE_SBUS;
+ else if (!strcmp(prop, "ebus") && type == PROM_NODE_PCI)
+ ntype = PROM_NODE_EBUS;
+ else if (!strcmp(prop, "pci") && !type)
+ ntype = PROM_NODE_PCI;
+ strcpy (path + 1, prop);
+ p = promGetReg(type);
+ if (*p)
+ strcat (path, p);
+ if (node == searchNode)
+ return 1;
+ nextnode = promGetChild(node);
+ if (nextnode &&
+ promWalkNode2Pathname(strchr(path, 0), node, nextnode, searchNode, ntype))
+ return 1;
+ nextnode = promGetSibling(node);
+ if (nextnode &&
+ promWalkNode2Pathname(path, parent, nextnode, searchNode, type))
+ return 1;
+ return 0;
+}
+
+char *
+sparcPromNode2Pathname(sbusPromNodePtr pnode)
+{
+ char *ret;
+
+ if (!pnode->node) return NULL;
+ ret = malloc(4096);
+ if (!ret) return NULL;
+ if (promWalkNode2Pathname(ret, promRootNode, promGetChild(promRootNode), pnode->node, 0))
+ return ret;
+ free(ret);
+ return NULL;
+}
+
+static int
+promWalkPathname2Node(char *name, char *regstr, int parent, int type)
+{
+ int len, node, ret;
+ char *prop, *p;
+
+ for (;;) {
+ prop = promGetProperty("name", &len);
+ if (!prop || len <= 0)
+ return 0;
+ if ((!strcmp(prop, "sbus") || !strcmp(prop, "sbi")) && !type)
+ type = PROM_NODE_SBUS;
+ else if (!strcmp(prop, "ebus") && type == PROM_NODE_PCI)
+ type = PROM_NODE_EBUS;
+ else if (!strcmp(prop, "pci") && !type)
+ type = PROM_NODE_PCI;
+ for (node = promGetChild(parent); node; node = promGetSibling(node)) {
+ prop = promGetProperty("name", &len);
+ if (!prop || len <= 0)
+ continue;
+ if (*name && strcmp(name, prop))
+ continue;
+ if (*regstr) {
+ p = promGetReg(type);
+ if (! *p || strcmp(p + 1, regstr))
+ continue;
+ }
+ break;
+ }
+ if (!node) {
+ for (node = promGetChild(parent); node; node = promGetSibling(node)) {
+ ret = promWalkPathname2Node(name, regstr, node, type);
+ if (ret) return ret;
+ }
+ return 0;
+ }
+ name = strchr(regstr, 0) + 1;
+ if (! *name)
+ return node;
+ p = strchr(name, '/');
+ if (p)
+ *p = 0;
+ else
+ p = strchr(name, 0);
+ regstr = strchr(name, '@');
+ if (regstr)
+ *regstr++ = 0;
+ else
+ regstr = p;
+ if (name == regstr)
+ return 0;
+ parent = node;
+ }
+}
+
+int
+sparcPromPathname2Node(const char *pathName)
+{
+ int i;
+ char *name, *regstr, *p;
+
+ i = strlen(pathName);
+ name = malloc(i + 2);
+ if (! name) return 0;
+ strcpy (name, pathName);
+ name [i + 1] = 0;
+ if (name[0] != '/')
+ return 0;
+ p = strchr(name + 1, '/');
+ if (p)
+ *p = 0;
+ else
+ p = strchr(name, 0);
+ regstr = strchr(name, '@');
+ if (regstr)
+ *regstr++ = 0;
+ else
+ regstr = p;
+ if (name + 1 == regstr)
+ return 0;
+ promGetSibling(0);
+ i = promWalkPathname2Node(name + 1, regstr, promRootNode, 0);
+ free(name);
+ return i;
+}
+
+pointer
+xf86MapSbusMem(sbusDevicePtr psdp, unsigned long offset, unsigned long size)
+{
+ pointer ret;
+ unsigned long pagemask = getpagesize() - 1;
+ unsigned long off = offset & ~pagemask;
+ unsigned long len = ((offset + size + pagemask) & ~pagemask) - off;
+
+ if (psdp->fd == -1) {
+ psdp->fd = open(psdp->device, O_RDWR);
+ if (psdp->fd == -1)
+ return NULL;
+ } else if (psdp->fd < 0)
+ return NULL;
+
+ ret = (pointer) mmap (NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE,
+ psdp->fd, off);
+ if (ret == (pointer) -1) {
+ ret = (pointer) mmap (NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED,
+ psdp->fd, off);
+ }
+ if (ret == (pointer) -1)
+ return NULL;
+
+ return (char *)ret + (offset - off);
+}
+
+void
+xf86UnmapSbusMem(sbusDevicePtr psdp, pointer addr, unsigned long size)
+{
+ unsigned long mask = getpagesize() - 1;
+ unsigned long base = (unsigned long)addr & ~mask;
+ unsigned long len = (((unsigned long)addr + size + mask) & ~mask) - base;
+
+ munmap ((pointer)base, len);
+}
+
+/* Tell OS that we are driving the HW cursor ourselves. */
+void
+xf86SbusHideOsHwCursor(sbusDevicePtr psdp)
+{
+ struct fbcursor fbcursor;
+ unsigned char zeros[8];
+
+ memset(&fbcursor, 0, sizeof(fbcursor));
+ memset(&zeros, 0, sizeof(zeros));
+ fbcursor.cmap.count = 2;
+ fbcursor.cmap.red = zeros;
+ fbcursor.cmap.green = zeros;
+ fbcursor.cmap.blue = zeros;
+ fbcursor.image = (char *)zeros;
+ fbcursor.mask = (char *)zeros;
+ fbcursor.size.x = 32;
+ fbcursor.size.y = 1;
+ fbcursor.set = FB_CUR_SETALL;
+ ioctl(psdp->fd, FBIOSCURSOR, &fbcursor);
+}
+
+/* Set HW cursor colormap. */
+void
+xf86SbusSetOsHwCursorCmap(sbusDevicePtr psdp, int bg, int fg)
+{
+ struct fbcursor fbcursor;
+ unsigned char red[2], green[2], blue[2];
+
+ memset(&fbcursor, 0, sizeof(fbcursor));
+ red[0] = bg >> 16;
+ green[0] = bg >> 8;
+ blue[0] = bg;
+ red[1] = fg >> 16;
+ green[1] = fg >> 8;
+ blue[1] = fg;
+ fbcursor.cmap.count = 2;
+ fbcursor.cmap.red = red;
+ fbcursor.cmap.green = green;
+ fbcursor.cmap.blue = blue;
+ fbcursor.set = FB_CUR_SETCMAP;
+ ioctl(psdp->fd, FBIOSCURSOR, &fbcursor);
+}
diff --git a/xorg-server/hw/xfree86/os-support/linux/int10/linux.c b/xorg-server/hw/xfree86/os-support/linux/int10/linux.c
index 0cf3507c3..e3c8a984d 100644
--- a/xorg-server/hw/xfree86/os-support/linux/int10/linux.c
+++ b/xorg-server/hw/xfree86/os-support/linux/int10/linux.c
@@ -1,544 +1,544 @@
-/*
- * linux specific part of the int10 module
- * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2008 Egbert Eich
- */
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "xf86.h"
-#include "xf86_OSproc.h"
-#include "xf86Pci.h"
-#include "compiler.h"
-#define _INT10_PRIVATE
-#include "xf86int10.h"
-#ifdef __sparc__
-#define DEV_MEM "/dev/fb"
-#else
-#define DEV_MEM "/dev/mem"
-#endif
-#define ALLOC_ENTRIES(x) ((V_RAM / x) - 1)
-#define SHMERRORPTR (pointer)(-1)
-
-#include <fcntl.h>
-#include <errno.h>
-#include <sys/mman.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#include <unistd.h>
-#include <string.h>
-
-static int counter = 0;
-static unsigned long int10Generation = 0;
-
-static CARD8 read_b(xf86Int10InfoPtr pInt, int addr);
-static CARD16 read_w(xf86Int10InfoPtr pInt, int addr);
-static CARD32 read_l(xf86Int10InfoPtr pInt, int addr);
-static void write_b(xf86Int10InfoPtr pInt, int addr, CARD8 val);
-static void write_w(xf86Int10InfoPtr pInt, int addr, CARD16 val);
-static void write_l(xf86Int10InfoPtr pInt, int addr, CARD32 val);
-
-int10MemRec linuxMem = {
- read_b,
- read_w,
- read_l,
- write_b,
- write_w,
- write_l
-};
-
-typedef struct {
- int lowMem;
- int highMem;
- char* base;
- char* base_high;
- int screen;
- char* alloc;
-} linuxInt10Priv;
-
-#if defined DoSubModules
-
-typedef enum {
- INT10_NOT_LOADED,
- INT10_LOADED_VM86,
- INT10_LOADED_X86EMU,
- INT10_LOAD_FAILED
-} Int10LinuxSubModuleState;
-
-static Int10LinuxSubModuleState loadedSubModule = INT10_NOT_LOADED;
-
-static Int10LinuxSubModuleState int10LinuxLoadSubModule(ScrnInfoPtr pScrn);
-
-#endif /* DoSubModules */
-
-xf86Int10InfoPtr
-xf86ExtendedInitInt10(int entityIndex, int Flags)
-{
- xf86Int10InfoPtr pInt = NULL;
- int screen;
- int fd;
- static void* vidMem = NULL;
- static void* sysMem = NULL;
- void* vMem = NULL;
- void *options = NULL;
- int low_mem;
- int high_mem = -1;
- char *base = SHMERRORPTR;
- char *base_high = SHMERRORPTR;
- int pagesize;
- memType cs;
- legacyVGARec vga;
- Bool videoBiosMapped = FALSE;
-
- if (int10Generation != serverGeneration) {
- counter = 0;
- int10Generation = serverGeneration;
- }
-
- screen = (xf86FindScreenForEntity(entityIndex))->scrnIndex;
-
- options = xf86HandleInt10Options(xf86Screens[screen],entityIndex);
-
- if (int10skip(options)) {
- xfree(options);
- return NULL;
- }
-
-#if defined DoSubModules
- if (loadedSubModule == INT10_NOT_LOADED)
- loadedSubModule = int10LinuxLoadSubModule(xf86Screens[screen]);
-
- if (loadedSubModule == INT10_LOAD_FAILED)
- return NULL;
-#endif
-
- if ((!vidMem) || (!sysMem)) {
- if ((fd = open(DEV_MEM, O_RDWR, 0)) >= 0) {
- if (!sysMem) {
- DebugF("Mapping sys bios area\n");
- if ((sysMem = mmap((void *)(SYS_BIOS), BIOS_SIZE,
- PROT_READ | PROT_EXEC,
- MAP_SHARED | MAP_FIXED, fd, SYS_BIOS))
- == MAP_FAILED) {
- xf86DrvMsg(screen, X_ERROR, "Cannot map SYS BIOS\n");
- close(fd);
- goto error0;
- }
- }
- if (!vidMem) {
- DebugF("Mapping VRAM area\n");
- if ((vidMem = mmap((void *)(V_RAM), VRAM_SIZE,
- PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_SHARED | MAP_FIXED, fd, V_RAM))
- == MAP_FAILED) {
- xf86DrvMsg(screen, X_ERROR, "Cannot map V_RAM\n");
- close(fd);
- goto error0;
- }
- }
- close(fd);
- } else {
- xf86DrvMsg(screen, X_ERROR, "Cannot open %s\n", DEV_MEM);
- goto error0;
- }
- }
-
- pInt = (xf86Int10InfoPtr)xnfcalloc(1, sizeof(xf86Int10InfoRec));
- pInt->scrnIndex = screen;
- pInt->entityIndex = entityIndex;
- pInt->dev = xf86GetPciInfoForEntity(entityIndex);
-
- if (!xf86Int10ExecSetup(pInt))
- goto error0;
- pInt->mem = &linuxMem;
- pagesize = getpagesize();
- pInt->private = (pointer)xnfcalloc(1, sizeof(linuxInt10Priv));
- ((linuxInt10Priv*)pInt->private)->screen = screen;
- ((linuxInt10Priv*)pInt->private)->alloc =
- (pointer)xnfcalloc(1, ALLOC_ENTRIES(pagesize));
-
- if (!xf86IsEntityPrimary(entityIndex)) {
- DebugF("Mapping high memory area\n");
- if ((high_mem = shmget(counter++, HIGH_MEM_SIZE,
- IPC_CREAT | SHM_R | SHM_W)) == -1) {
- if (errno == ENOSYS)
- xf86DrvMsg(screen, X_ERROR, "shmget error\n Please reconfigure"
- " your kernel to include System V IPC support\n");
- else
- xf86DrvMsg(screen, X_ERROR,
- "shmget(highmem) error: %s\n",strerror(errno));
- goto error1;
- }
- } else {
- DebugF("Mapping Video BIOS\n");
- videoBiosMapped = TRUE;
- if ((fd = open(DEV_MEM, O_RDWR, 0)) >= 0) {
- if ((vMem = mmap((void *)(V_BIOS), SYS_BIOS - V_BIOS,
- PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_SHARED | MAP_FIXED, fd, V_BIOS))
- == MAP_FAILED) {
- xf86DrvMsg(screen, X_ERROR, "Cannot map V_BIOS\n");
- close(fd);
- goto error1;
- }
- close (fd);
- } else
- goto error1;
- }
- ((linuxInt10Priv*)pInt->private)->highMem = high_mem;
-
- DebugF("Mapping 640kB area\n");
- if ((low_mem = shmget(counter++, V_RAM,
- IPC_CREAT | SHM_R | SHM_W)) == -1) {
- xf86DrvMsg(screen, X_ERROR,
- "shmget(lowmem) error: %s\n",strerror(errno));
- goto error2;
- }
-
- ((linuxInt10Priv*)pInt->private)->lowMem = low_mem;
- base = shmat(low_mem, 0, 0);
- if (base == SHMERRORPTR) {
- xf86DrvMsg(screen, X_ERROR,
- "shmat(low_mem) error: %s\n",strerror(errno));
- goto error3;
- }
- ((linuxInt10Priv *)pInt->private)->base = base;
- if (high_mem > -1) {
- base_high = shmat(high_mem, 0, 0);
- if (base_high == SHMERRORPTR) {
- xf86DrvMsg(screen, X_ERROR,
- "shmat(high_mem) error: %s\n",strerror(errno));
- goto error3;
- }
- ((linuxInt10Priv*)pInt->private)->base_high = base_high;
- } else
- ((linuxInt10Priv*)pInt->private)->base_high = NULL;
-
- if (!MapCurrentInt10(pInt))
- goto error3;
-
- Int10Current = pInt;
-
- DebugF("Mapping int area\n");
- if (xf86ReadBIOS(0, 0, (unsigned char *)0, LOW_PAGE_SIZE) < 0) {
- xf86DrvMsg(screen, X_ERROR, "Cannot read int vect\n");
- goto error3;
- }
- DebugF("done\n");
- /*
- * Read in everything between V_BIOS and SYS_BIOS as some system BIOSes
- * have executable code there. Note that xf86ReadBIOS() can only bring in
- * 64K bytes at a time.
- */
- if (!videoBiosMapped) {
- memset((pointer)V_BIOS, 0, SYS_BIOS - V_BIOS);
- DebugF("Reading BIOS\n");
- for (cs = V_BIOS; cs < SYS_BIOS; cs += V_BIOS_SIZE)
- if (xf86ReadBIOS(cs, 0, (pointer)cs, V_BIOS_SIZE) < V_BIOS_SIZE)
- xf86DrvMsg(screen, X_WARNING,
- "Unable to retrieve all of segment 0x%06lX.\n",
- (long)cs);
- DebugF("done\n");
- }
-
- if (xf86IsEntityPrimary(entityIndex) && !(initPrimary(options))) {
- if (!xf86int10GetBiosSegment(pInt, NULL))
- goto error3;
-
- set_return_trap(pInt);
-#ifdef _PC
- pInt->Flags = Flags & (SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH);
- if (! (pInt->Flags & SET_BIOS_SCRATCH))
- pInt->Flags &= ~RESTORE_BIOS_SCRATCH;
- xf86Int10SaveRestoreBIOSVars(pInt, TRUE);
-#endif
- } else {
- const BusType location_type = xf86int10GetBiosLocationType(pInt);
-
- switch (location_type) {
- case BUS_PCI: {
- int err;
- struct pci_device *rom_device =
- xf86GetPciInfoForEntity(pInt->entityIndex);
-
-#if HAVE_PCI_DEVICE_ENABLE
- pci_device_enable(rom_device);
-#endif
-
- err = pci_device_read_rom(rom_device, (unsigned char *)(V_BIOS));
- if (err) {
- xf86DrvMsg(screen,X_ERROR,"Cannot read V_BIOS (%s)\n",
- strerror(err));
- goto error3;
- }
-
- pInt->BIOSseg = V_BIOS >> 4;
- break;
- }
- default:
- goto error3;
- }
-
- pInt->num = 0xe6;
- reset_int_vect(pInt);
- set_return_trap(pInt);
- LockLegacyVGA(pInt, &vga);
- xf86ExecX86int10(pInt);
- UnlockLegacyVGA(pInt, &vga);
- }
-#ifdef DEBUG
- dprint(0xc0000, 0x20);
-#endif
-
- xfree(options);
- return pInt;
-
-error3:
- if (base_high)
- shmdt(base_high);
- shmdt(base);
- shmdt(0);
- if (base_high)
- shmdt((char*)HIGH_MEM);
- shmctl(low_mem, IPC_RMID, NULL);
- Int10Current = NULL;
-error2:
- if (high_mem > -1)
- shmctl(high_mem, IPC_RMID,NULL);
-error1:
- if (vMem)
- munmap(vMem, SYS_BIOS - V_BIOS);
- xfree(((linuxInt10Priv*)pInt->private)->alloc);
- xfree(pInt->private);
-error0:
- xfree(options);
- xfree(pInt);
- return NULL;
-}
-
-Bool
-MapCurrentInt10(xf86Int10InfoPtr pInt)
-{
- pointer addr;
- int fd = -1;
-
- if (Int10Current) {
- shmdt(0);
- if (((linuxInt10Priv*)Int10Current->private)->highMem >= 0)
- shmdt((char*)HIGH_MEM);
- else
- munmap((pointer)V_BIOS, (SYS_BIOS - V_BIOS));
- }
- addr = shmat(((linuxInt10Priv*)pInt->private)->lowMem, (char*)1, SHM_RND);
- if (addr == SHMERRORPTR) {
- xf86DrvMsg(pInt->scrnIndex, X_ERROR, "Cannot shmat() low memory\n");
- xf86DrvMsg(pInt->scrnIndex, X_ERROR,
- "shmat(low_mem) error: %s\n",strerror(errno));
- return FALSE;
- }
- if (mprotect((void*)0, V_RAM, PROT_READ|PROT_WRITE|PROT_EXEC) != 0)
- xf86DrvMsg(pInt->scrnIndex, X_ERROR,
- "Cannot set EXEC bit on low memory: %s\n", strerror(errno));
-
- if (((linuxInt10Priv*)pInt->private)->highMem >= 0) {
- addr = shmat(((linuxInt10Priv*)pInt->private)->highMem,
- (char*)HIGH_MEM, 0);
- if (addr == SHMERRORPTR) {
- xf86DrvMsg(pInt->scrnIndex, X_ERROR,
- "Cannot shmat() high memory\n");
- xf86DrvMsg(pInt->scrnIndex, X_ERROR,
- "shmget error: %s\n",strerror(errno));
- return FALSE;
- }
- if (mprotect((void*)HIGH_MEM, HIGH_MEM_SIZE,
- PROT_READ|PROT_WRITE|PROT_EXEC) != 0)
- xf86DrvMsg(pInt->scrnIndex, X_ERROR,
- "Cannot set EXEC bit on high memory: %s\n",
- strerror(errno));
- } else {
- if ((fd = open(DEV_MEM, O_RDWR, 0)) >= 0) {
- if (mmap((void *)(V_BIOS), SYS_BIOS - V_BIOS,
- PROT_READ | PROT_WRITE | PROT_EXEC,
- MAP_SHARED | MAP_FIXED, fd, V_BIOS)
- == MAP_FAILED) {
- xf86DrvMsg(pInt->scrnIndex, X_ERROR, "Cannot map V_BIOS\n");
- close (fd);
- return FALSE;
- }
- } else {
- xf86DrvMsg(pInt->scrnIndex, X_ERROR, "Cannot open %s\n",DEV_MEM);
- return FALSE;
- }
- close (fd);
- }
-
- return TRUE;
-}
-
-void
-xf86FreeInt10(xf86Int10InfoPtr pInt)
-{
- if (!pInt)
- return;
-
-#ifdef _PC
- xf86Int10SaveRestoreBIOSVars(pInt, FALSE);
-#endif
- if (Int10Current == pInt) {
- shmdt(0);
- if (((linuxInt10Priv*)pInt->private)->highMem >= 0)
- shmdt((char*)HIGH_MEM);
- else
- munmap((pointer)V_BIOS, (SYS_BIOS - V_BIOS));
- Int10Current = NULL;
- }
-
- if (((linuxInt10Priv*)pInt->private)->base_high)
- shmdt(((linuxInt10Priv*)pInt->private)->base_high);
- shmdt(((linuxInt10Priv*)pInt->private)->base);
- shmctl(((linuxInt10Priv*)pInt->private)->lowMem, IPC_RMID, NULL);
- if (((linuxInt10Priv*)pInt->private)->highMem >= 0)
- shmctl(((linuxInt10Priv*)pInt->private)->highMem, IPC_RMID, NULL);
- xfree(((linuxInt10Priv*)pInt->private)->alloc);
- xfree(pInt->private);
- xfree(pInt);
-}
-
-void *
-xf86Int10AllocPages(xf86Int10InfoPtr pInt, int num, int *off)
-{
- int pagesize = getpagesize();
- int num_pages = ALLOC_ENTRIES(pagesize);
- int i, j;
-
- for (i = 0; i < (num_pages - num); i++) {
- if (((linuxInt10Priv*)pInt->private)->alloc[i] == 0) {
- for (j = i; j < (num + i); j++)
- if ((((linuxInt10Priv*)pInt->private)->alloc[j] != 0))
- break;
- if (j == (num + i))
- break;
- else
- i = i + num;
- }
- }
- if (i == (num_pages - num))
- return NULL;
-
- for (j = i; j < (i + num); j++)
- ((linuxInt10Priv*)pInt->private)->alloc[j] = 1;
-
- *off = (i + 1) * pagesize;
-
- return ((linuxInt10Priv*)pInt->private)->base + ((i + 1) * pagesize);
-}
-
-void
-xf86Int10FreePages(xf86Int10InfoPtr pInt, void *pbase, int num)
-{
- int pagesize = getpagesize();
- int first = (((unsigned long)pbase
- - (unsigned long)((linuxInt10Priv*)pInt->private)->base)
- / pagesize) - 1;
- int i;
-
- for (i = first; i < (first + num); i++)
- ((linuxInt10Priv*)pInt->private)->alloc[i] = 0;
-}
-
-static CARD8
-read_b(xf86Int10InfoPtr pInt, int addr)
-{
- return *((CARD8 *)(memType)addr);
-}
-
-static CARD16
-read_w(xf86Int10InfoPtr pInt, int addr)
-{
- return *((CARD16 *)(memType)addr);
-}
-
-static CARD32
-read_l(xf86Int10InfoPtr pInt, int addr)
-{
- return *((CARD32 *)(memType)addr);
-}
-
-static void
-write_b(xf86Int10InfoPtr pInt, int addr, CARD8 val)
-{
- *((CARD8 *)(memType)addr) = val;
-}
-
-static void
-write_w(xf86Int10InfoPtr pInt, int addr, CARD16 val)
-{
- *((CARD16 *)(memType)addr) = val;
-}
-
-static
-void write_l(xf86Int10InfoPtr pInt, int addr, CARD32 val)
-{
- *((CARD32 *)(memType) addr) = val;
-}
-
-pointer
-xf86int10Addr(xf86Int10InfoPtr pInt, CARD32 addr)
-{
- if (addr < V_RAM)
- return ((linuxInt10Priv*)pInt->private)->base + addr;
- else if (addr < V_BIOS)
- return (pointer)(memType)addr;
- else if (addr < SYS_BIOS) {
- if (((linuxInt10Priv*)pInt->private)->base_high)
- return (pointer)(((linuxInt10Priv*)pInt->private)->base_high
- - V_BIOS + addr);
- else
- return (pointer) (memType)addr;
- } else
- return (pointer) (memType)addr;
-}
-
-#if defined DoSubModules
-
-static Bool
-vm86_tst(void)
-{
- int __res;
-
-#ifdef __PIC__
- /* When compiling with -fPIC, we can't use asm constraint "b" because
- %ebx is already taken by gcc. */
- __asm__ __volatile__("pushl %%ebx\n\t"
- "movl %2,%%ebx\n\t"
- "movl %1,%%eax\n\t"
- "int $0x80\n\t"
- "popl %%ebx"
- :"=a" (__res)
- :"n" ((int)113), "r" (NULL));
-#else
- __asm__ __volatile__("int $0x80\n\t"
- :"=a" (__res):"a" ((int)113),
- "b" ((struct vm86_struct *)NULL));
-#endif
-
- if (__res < 0 && __res == -ENOSYS)
- return FALSE;
-
- return TRUE;
-}
-
-static Int10LinuxSubModuleState
-int10LinuxLoadSubModule(ScrnInfoPtr pScrn)
-{
- if (vm86_tst()) {
- if (xf86LoadSubModule(pScrn,"vm86"))
- return INT10_LOADED_VM86;
- }
- if (xf86LoadSubModule(pScrn,"x86emu"))
- return INT10_LOADED_X86EMU;
-
- return INT10_LOAD_FAILED;
-}
-
-#endif /* DoSubModules */
+/*
+ * linux specific part of the int10 module
+ * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2008 Egbert Eich
+ */
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "xf86Pci.h"
+#include "compiler.h"
+#define _INT10_PRIVATE
+#include "xf86int10.h"
+#ifdef __sparc__
+#define DEV_MEM "/dev/fb"
+#else
+#define DEV_MEM "/dev/mem"
+#endif
+#define ALLOC_ENTRIES(x) ((V_RAM / x) - 1)
+#define SHMERRORPTR (pointer)(-1)
+
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <unistd.h>
+#include <string.h>
+
+static int counter = 0;
+static unsigned long int10Generation = 0;
+
+static CARD8 read_b(xf86Int10InfoPtr pInt, int addr);
+static CARD16 read_w(xf86Int10InfoPtr pInt, int addr);
+static CARD32 read_l(xf86Int10InfoPtr pInt, int addr);
+static void write_b(xf86Int10InfoPtr pInt, int addr, CARD8 val);
+static void write_w(xf86Int10InfoPtr pInt, int addr, CARD16 val);
+static void write_l(xf86Int10InfoPtr pInt, int addr, CARD32 val);
+
+int10MemRec linuxMem = {
+ read_b,
+ read_w,
+ read_l,
+ write_b,
+ write_w,
+ write_l
+};
+
+typedef struct {
+ int lowMem;
+ int highMem;
+ char* base;
+ char* base_high;
+ int screen;
+ char* alloc;
+} linuxInt10Priv;
+
+#if defined DoSubModules
+
+typedef enum {
+ INT10_NOT_LOADED,
+ INT10_LOADED_VM86,
+ INT10_LOADED_X86EMU,
+ INT10_LOAD_FAILED
+} Int10LinuxSubModuleState;
+
+static Int10LinuxSubModuleState loadedSubModule = INT10_NOT_LOADED;
+
+static Int10LinuxSubModuleState int10LinuxLoadSubModule(ScrnInfoPtr pScrn);
+
+#endif /* DoSubModules */
+
+xf86Int10InfoPtr
+xf86ExtendedInitInt10(int entityIndex, int Flags)
+{
+ xf86Int10InfoPtr pInt = NULL;
+ int screen;
+ int fd;
+ static void* vidMem = NULL;
+ static void* sysMem = NULL;
+ void* vMem = NULL;
+ void *options = NULL;
+ int low_mem;
+ int high_mem = -1;
+ char *base = SHMERRORPTR;
+ char *base_high = SHMERRORPTR;
+ int pagesize;
+ memType cs;
+ legacyVGARec vga;
+ Bool videoBiosMapped = FALSE;
+
+ if (int10Generation != serverGeneration) {
+ counter = 0;
+ int10Generation = serverGeneration;
+ }
+
+ screen = (xf86FindScreenForEntity(entityIndex))->scrnIndex;
+
+ options = xf86HandleInt10Options(xf86Screens[screen],entityIndex);
+
+ if (int10skip(options)) {
+ free(options);
+ return NULL;
+ }
+
+#if defined DoSubModules
+ if (loadedSubModule == INT10_NOT_LOADED)
+ loadedSubModule = int10LinuxLoadSubModule(xf86Screens[screen]);
+
+ if (loadedSubModule == INT10_LOAD_FAILED)
+ return NULL;
+#endif
+
+ if ((!vidMem) || (!sysMem)) {
+ if ((fd = open(DEV_MEM, O_RDWR, 0)) >= 0) {
+ if (!sysMem) {
+ DebugF("Mapping sys bios area\n");
+ if ((sysMem = mmap((void *)(SYS_BIOS), BIOS_SIZE,
+ PROT_READ | PROT_EXEC,
+ MAP_SHARED | MAP_FIXED, fd, SYS_BIOS))
+ == MAP_FAILED) {
+ xf86DrvMsg(screen, X_ERROR, "Cannot map SYS BIOS\n");
+ close(fd);
+ goto error0;
+ }
+ }
+ if (!vidMem) {
+ DebugF("Mapping VRAM area\n");
+ if ((vidMem = mmap((void *)(V_RAM), VRAM_SIZE,
+ PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_SHARED | MAP_FIXED, fd, V_RAM))
+ == MAP_FAILED) {
+ xf86DrvMsg(screen, X_ERROR, "Cannot map V_RAM\n");
+ close(fd);
+ goto error0;
+ }
+ }
+ close(fd);
+ } else {
+ xf86DrvMsg(screen, X_ERROR, "Cannot open %s\n", DEV_MEM);
+ goto error0;
+ }
+ }
+
+ pInt = (xf86Int10InfoPtr)xnfcalloc(1, sizeof(xf86Int10InfoRec));
+ pInt->scrnIndex = screen;
+ pInt->entityIndex = entityIndex;
+ pInt->dev = xf86GetPciInfoForEntity(entityIndex);
+
+ if (!xf86Int10ExecSetup(pInt))
+ goto error0;
+ pInt->mem = &linuxMem;
+ pagesize = getpagesize();
+ pInt->private = (pointer)xnfcalloc(1, sizeof(linuxInt10Priv));
+ ((linuxInt10Priv*)pInt->private)->screen = screen;
+ ((linuxInt10Priv*)pInt->private)->alloc =
+ (pointer)xnfcalloc(1, ALLOC_ENTRIES(pagesize));
+
+ if (!xf86IsEntityPrimary(entityIndex)) {
+ DebugF("Mapping high memory area\n");
+ if ((high_mem = shmget(counter++, HIGH_MEM_SIZE,
+ IPC_CREAT | SHM_R | SHM_W)) == -1) {
+ if (errno == ENOSYS)
+ xf86DrvMsg(screen, X_ERROR, "shmget error\n Please reconfigure"
+ " your kernel to include System V IPC support\n");
+ else
+ xf86DrvMsg(screen, X_ERROR,
+ "shmget(highmem) error: %s\n",strerror(errno));
+ goto error1;
+ }
+ } else {
+ DebugF("Mapping Video BIOS\n");
+ videoBiosMapped = TRUE;
+ if ((fd = open(DEV_MEM, O_RDWR, 0)) >= 0) {
+ if ((vMem = mmap((void *)(V_BIOS), SYS_BIOS - V_BIOS,
+ PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_SHARED | MAP_FIXED, fd, V_BIOS))
+ == MAP_FAILED) {
+ xf86DrvMsg(screen, X_ERROR, "Cannot map V_BIOS\n");
+ close(fd);
+ goto error1;
+ }
+ close (fd);
+ } else
+ goto error1;
+ }
+ ((linuxInt10Priv*)pInt->private)->highMem = high_mem;
+
+ DebugF("Mapping 640kB area\n");
+ if ((low_mem = shmget(counter++, V_RAM,
+ IPC_CREAT | SHM_R | SHM_W)) == -1) {
+ xf86DrvMsg(screen, X_ERROR,
+ "shmget(lowmem) error: %s\n",strerror(errno));
+ goto error2;
+ }
+
+ ((linuxInt10Priv*)pInt->private)->lowMem = low_mem;
+ base = shmat(low_mem, 0, 0);
+ if (base == SHMERRORPTR) {
+ xf86DrvMsg(screen, X_ERROR,
+ "shmat(low_mem) error: %s\n",strerror(errno));
+ goto error3;
+ }
+ ((linuxInt10Priv *)pInt->private)->base = base;
+ if (high_mem > -1) {
+ base_high = shmat(high_mem, 0, 0);
+ if (base_high == SHMERRORPTR) {
+ xf86DrvMsg(screen, X_ERROR,
+ "shmat(high_mem) error: %s\n",strerror(errno));
+ goto error3;
+ }
+ ((linuxInt10Priv*)pInt->private)->base_high = base_high;
+ } else
+ ((linuxInt10Priv*)pInt->private)->base_high = NULL;
+
+ if (!MapCurrentInt10(pInt))
+ goto error3;
+
+ Int10Current = pInt;
+
+ DebugF("Mapping int area\n");
+ if (xf86ReadBIOS(0, 0, (unsigned char *)0, LOW_PAGE_SIZE) < 0) {
+ xf86DrvMsg(screen, X_ERROR, "Cannot read int vect\n");
+ goto error3;
+ }
+ DebugF("done\n");
+ /*
+ * Read in everything between V_BIOS and SYS_BIOS as some system BIOSes
+ * have executable code there. Note that xf86ReadBIOS() can only bring in
+ * 64K bytes at a time.
+ */
+ if (!videoBiosMapped) {
+ memset((pointer)V_BIOS, 0, SYS_BIOS - V_BIOS);
+ DebugF("Reading BIOS\n");
+ for (cs = V_BIOS; cs < SYS_BIOS; cs += V_BIOS_SIZE)
+ if (xf86ReadBIOS(cs, 0, (pointer)cs, V_BIOS_SIZE) < V_BIOS_SIZE)
+ xf86DrvMsg(screen, X_WARNING,
+ "Unable to retrieve all of segment 0x%06lX.\n",
+ (long)cs);
+ DebugF("done\n");
+ }
+
+ if (xf86IsEntityPrimary(entityIndex) && !(initPrimary(options))) {
+ if (!xf86int10GetBiosSegment(pInt, NULL))
+ goto error3;
+
+ set_return_trap(pInt);
+#ifdef _PC
+ pInt->Flags = Flags & (SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH);
+ if (! (pInt->Flags & SET_BIOS_SCRATCH))
+ pInt->Flags &= ~RESTORE_BIOS_SCRATCH;
+ xf86Int10SaveRestoreBIOSVars(pInt, TRUE);
+#endif
+ } else {
+ const BusType location_type = xf86int10GetBiosLocationType(pInt);
+
+ switch (location_type) {
+ case BUS_PCI: {
+ int err;
+ struct pci_device *rom_device =
+ xf86GetPciInfoForEntity(pInt->entityIndex);
+
+#if HAVE_PCI_DEVICE_ENABLE
+ pci_device_enable(rom_device);
+#endif
+
+ err = pci_device_read_rom(rom_device, (unsigned char *)(V_BIOS));
+ if (err) {
+ xf86DrvMsg(screen,X_ERROR,"Cannot read V_BIOS (%s)\n",
+ strerror(err));
+ goto error3;
+ }
+
+ pInt->BIOSseg = V_BIOS >> 4;
+ break;
+ }
+ default:
+ goto error3;
+ }
+
+ pInt->num = 0xe6;
+ reset_int_vect(pInt);
+ set_return_trap(pInt);
+ LockLegacyVGA(pInt, &vga);
+ xf86ExecX86int10(pInt);
+ UnlockLegacyVGA(pInt, &vga);
+ }
+#ifdef DEBUG
+ dprint(0xc0000, 0x20);
+#endif
+
+ free(options);
+ return pInt;
+
+error3:
+ if (base_high)
+ shmdt(base_high);
+ shmdt(base);
+ shmdt(0);
+ if (base_high)
+ shmdt((char*)HIGH_MEM);
+ shmctl(low_mem, IPC_RMID, NULL);
+ Int10Current = NULL;
+error2:
+ if (high_mem > -1)
+ shmctl(high_mem, IPC_RMID,NULL);
+error1:
+ if (vMem)
+ munmap(vMem, SYS_BIOS - V_BIOS);
+ free(((linuxInt10Priv*)pInt->private)->alloc);
+ free(pInt->private);
+error0:
+ free(options);
+ free(pInt);
+ return NULL;
+}
+
+Bool
+MapCurrentInt10(xf86Int10InfoPtr pInt)
+{
+ pointer addr;
+ int fd = -1;
+
+ if (Int10Current) {
+ shmdt(0);
+ if (((linuxInt10Priv*)Int10Current->private)->highMem >= 0)
+ shmdt((char*)HIGH_MEM);
+ else
+ munmap((pointer)V_BIOS, (SYS_BIOS - V_BIOS));
+ }
+ addr = shmat(((linuxInt10Priv*)pInt->private)->lowMem, (char*)1, SHM_RND);
+ if (addr == SHMERRORPTR) {
+ xf86DrvMsg(pInt->scrnIndex, X_ERROR, "Cannot shmat() low memory\n");
+ xf86DrvMsg(pInt->scrnIndex, X_ERROR,
+ "shmat(low_mem) error: %s\n",strerror(errno));
+ return FALSE;
+ }
+ if (mprotect((void*)0, V_RAM, PROT_READ|PROT_WRITE|PROT_EXEC) != 0)
+ xf86DrvMsg(pInt->scrnIndex, X_ERROR,
+ "Cannot set EXEC bit on low memory: %s\n", strerror(errno));
+
+ if (((linuxInt10Priv*)pInt->private)->highMem >= 0) {
+ addr = shmat(((linuxInt10Priv*)pInt->private)->highMem,
+ (char*)HIGH_MEM, 0);
+ if (addr == SHMERRORPTR) {
+ xf86DrvMsg(pInt->scrnIndex, X_ERROR,
+ "Cannot shmat() high memory\n");
+ xf86DrvMsg(pInt->scrnIndex, X_ERROR,
+ "shmget error: %s\n",strerror(errno));
+ return FALSE;
+ }
+ if (mprotect((void*)HIGH_MEM, HIGH_MEM_SIZE,
+ PROT_READ|PROT_WRITE|PROT_EXEC) != 0)
+ xf86DrvMsg(pInt->scrnIndex, X_ERROR,
+ "Cannot set EXEC bit on high memory: %s\n",
+ strerror(errno));
+ } else {
+ if ((fd = open(DEV_MEM, O_RDWR, 0)) >= 0) {
+ if (mmap((void *)(V_BIOS), SYS_BIOS - V_BIOS,
+ PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_SHARED | MAP_FIXED, fd, V_BIOS)
+ == MAP_FAILED) {
+ xf86DrvMsg(pInt->scrnIndex, X_ERROR, "Cannot map V_BIOS\n");
+ close (fd);
+ return FALSE;
+ }
+ } else {
+ xf86DrvMsg(pInt->scrnIndex, X_ERROR, "Cannot open %s\n",DEV_MEM);
+ return FALSE;
+ }
+ close (fd);
+ }
+
+ return TRUE;
+}
+
+void
+xf86FreeInt10(xf86Int10InfoPtr pInt)
+{
+ if (!pInt)
+ return;
+
+#ifdef _PC
+ xf86Int10SaveRestoreBIOSVars(pInt, FALSE);
+#endif
+ if (Int10Current == pInt) {
+ shmdt(0);
+ if (((linuxInt10Priv*)pInt->private)->highMem >= 0)
+ shmdt((char*)HIGH_MEM);
+ else
+ munmap((pointer)V_BIOS, (SYS_BIOS - V_BIOS));
+ Int10Current = NULL;
+ }
+
+ if (((linuxInt10Priv*)pInt->private)->base_high)
+ shmdt(((linuxInt10Priv*)pInt->private)->base_high);
+ shmdt(((linuxInt10Priv*)pInt->private)->base);
+ shmctl(((linuxInt10Priv*)pInt->private)->lowMem, IPC_RMID, NULL);
+ if (((linuxInt10Priv*)pInt->private)->highMem >= 0)
+ shmctl(((linuxInt10Priv*)pInt->private)->highMem, IPC_RMID, NULL);
+ free(((linuxInt10Priv*)pInt->private)->alloc);
+ free(pInt->private);
+ free(pInt);
+}
+
+void *
+xf86Int10AllocPages(xf86Int10InfoPtr pInt, int num, int *off)
+{
+ int pagesize = getpagesize();
+ int num_pages = ALLOC_ENTRIES(pagesize);
+ int i, j;
+
+ for (i = 0; i < (num_pages - num); i++) {
+ if (((linuxInt10Priv*)pInt->private)->alloc[i] == 0) {
+ for (j = i; j < (num + i); j++)
+ if ((((linuxInt10Priv*)pInt->private)->alloc[j] != 0))
+ break;
+ if (j == (num + i))
+ break;
+ else
+ i = i + num;
+ }
+ }
+ if (i == (num_pages - num))
+ return NULL;
+
+ for (j = i; j < (i + num); j++)
+ ((linuxInt10Priv*)pInt->private)->alloc[j] = 1;
+
+ *off = (i + 1) * pagesize;
+
+ return ((linuxInt10Priv*)pInt->private)->base + ((i + 1) * pagesize);
+}
+
+void
+xf86Int10FreePages(xf86Int10InfoPtr pInt, void *pbase, int num)
+{
+ int pagesize = getpagesize();
+ int first = (((unsigned long)pbase
+ - (unsigned long)((linuxInt10Priv*)pInt->private)->base)
+ / pagesize) - 1;
+ int i;
+
+ for (i = first; i < (first + num); i++)
+ ((linuxInt10Priv*)pInt->private)->alloc[i] = 0;
+}
+
+static CARD8
+read_b(xf86Int10InfoPtr pInt, int addr)
+{
+ return *((CARD8 *)(memType)addr);
+}
+
+static CARD16
+read_w(xf86Int10InfoPtr pInt, int addr)
+{
+ return *((CARD16 *)(memType)addr);
+}
+
+static CARD32
+read_l(xf86Int10InfoPtr pInt, int addr)
+{
+ return *((CARD32 *)(memType)addr);
+}
+
+static void
+write_b(xf86Int10InfoPtr pInt, int addr, CARD8 val)
+{
+ *((CARD8 *)(memType)addr) = val;
+}
+
+static void
+write_w(xf86Int10InfoPtr pInt, int addr, CARD16 val)
+{
+ *((CARD16 *)(memType)addr) = val;
+}
+
+static
+void write_l(xf86Int10InfoPtr pInt, int addr, CARD32 val)
+{
+ *((CARD32 *)(memType) addr) = val;
+}
+
+pointer
+xf86int10Addr(xf86Int10InfoPtr pInt, CARD32 addr)
+{
+ if (addr < V_RAM)
+ return ((linuxInt10Priv*)pInt->private)->base + addr;
+ else if (addr < V_BIOS)
+ return (pointer)(memType)addr;
+ else if (addr < SYS_BIOS) {
+ if (((linuxInt10Priv*)pInt->private)->base_high)
+ return (pointer)(((linuxInt10Priv*)pInt->private)->base_high
+ - V_BIOS + addr);
+ else
+ return (pointer) (memType)addr;
+ } else
+ return (pointer) (memType)addr;
+}
+
+#if defined DoSubModules
+
+static Bool
+vm86_tst(void)
+{
+ int __res;
+
+#ifdef __PIC__
+ /* When compiling with -fPIC, we can't use asm constraint "b" because
+ %ebx is already taken by gcc. */
+ __asm__ __volatile__("pushl %%ebx\n\t"
+ "movl %2,%%ebx\n\t"
+ "movl %1,%%eax\n\t"
+ "int $0x80\n\t"
+ "popl %%ebx"
+ :"=a" (__res)
+ :"n" ((int)113), "r" (NULL));
+#else
+ __asm__ __volatile__("int $0x80\n\t"
+ :"=a" (__res):"a" ((int)113),
+ "b" ((struct vm86_struct *)NULL));
+#endif
+
+ if (__res < 0 && __res == -ENOSYS)
+ return FALSE;
+
+ return TRUE;
+}
+
+static Int10LinuxSubModuleState
+int10LinuxLoadSubModule(ScrnInfoPtr pScrn)
+{
+ if (vm86_tst()) {
+ if (xf86LoadSubModule(pScrn,"vm86"))
+ return INT10_LOADED_VM86;
+ }
+ if (xf86LoadSubModule(pScrn,"x86emu"))
+ return INT10_LOADED_X86EMU;
+
+ return INT10_LOAD_FAILED;
+}
+
+#endif /* DoSubModules */
diff --git a/xorg-server/hw/xfree86/os-support/linux/lnx_agp.c b/xorg-server/hw/xfree86/os-support/linux/lnx_agp.c
index 61437406d..3fa897366 100644
--- a/xorg-server/hw/xfree86/os-support/linux/lnx_agp.c
+++ b/xorg-server/hw/xfree86/os-support/linux/lnx_agp.c
@@ -1,374 +1,374 @@
-/*
- * Abstraction of the AGP GART interface.
- *
- * This version is for Linux and Free/Open/NetBSD.
- *
- * Copyright © 2000 VA Linux Systems, Inc.
- * Copyright © 2001 The XFree86 Project, Inc.
- */
-
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <X11/X.h>
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86_OSlib.h"
-#include "xf86OSpriv.h"
-
-#if defined(linux)
-#include <asm/ioctl.h>
-#include <linux/agpgart.h>
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
-#include <sys/ioctl.h>
-#include <sys/agpio.h>
-#endif
-
-#ifndef AGP_DEVICE
-#define AGP_DEVICE "/dev/agpgart"
-#endif
-/* AGP page size is independent of the host page size. */
-#ifndef AGP_PAGE_SIZE
-#define AGP_PAGE_SIZE 4096
-#endif
-#define AGPGART_MAJOR_VERSION 0
-#define AGPGART_MINOR_VERSION 99
-
-static int gartFd = -1;
-static int acquiredScreen = -1;
-static Bool initDone = FALSE;
-/*
- * Close /dev/agpgart. This frees all associated memory allocated during
- * this server generation.
- */
-Bool
-xf86GARTCloseScreen(int screenNum)
-{
- if(gartFd != -1) {
- close(gartFd);
- acquiredScreen = -1;
- gartFd = -1;
- initDone = FALSE;
- }
- return TRUE;
-}
-
-/*
- * Open /dev/agpgart. Keep it open until xf86GARTCloseScreen is called.
- */
-static Bool
-GARTInit(int screenNum)
-{
- struct _agp_info agpinf;
-
- if (initDone)
- return (gartFd != -1);
-
- initDone = TRUE;
-
- if (gartFd == -1)
- gartFd = open(AGP_DEVICE, O_RDWR, 0);
- else
- return FALSE;
-
- if (gartFd == -1) {
- xf86DrvMsg(screenNum, X_ERROR,
- "GARTInit: Unable to open " AGP_DEVICE " (%s)\n",
- strerror(errno));
- return FALSE;
- }
-
- xf86AcquireGART(-1);
- /* Check the kernel driver version. */
- if (ioctl(gartFd, AGPIOC_INFO, &agpinf) != 0) {
- xf86DrvMsg(screenNum, X_ERROR,
- "GARTInit: AGPIOC_INFO failed (%s)\n", strerror(errno));
- close(gartFd);
- gartFd = -1;
- return FALSE;
- }
- xf86ReleaseGART(-1);
-
-#if defined(linux)
- /* Per Dave Jones, every effort will be made to keep the
- * agpgart interface backwards compatible, so allow all
- * future versions.
- */
- if (
-#if (AGPGART_MAJOR_VERSION > 0) /* quiet compiler */
- agpinf.version.major < AGPGART_MAJOR_VERSION ||
-#endif
- (agpinf.version.major == AGPGART_MAJOR_VERSION &&
- agpinf.version.minor < AGPGART_MINOR_VERSION)) {
- xf86DrvMsg(screenNum, X_ERROR,
- "GARTInit: Kernel agpgart driver version is not current"
- " (%d.%d vs %d.%d)\n",
- agpinf.version.major, agpinf.version.minor,
- AGPGART_MAJOR_VERSION, AGPGART_MINOR_VERSION);
- close(gartFd);
- gartFd = -1;
- return FALSE;
- }
-#endif
-
- return TRUE;
-}
-
-Bool
-xf86AgpGARTSupported(void)
-{
- return GARTInit(-1);
-}
-
-AgpInfoPtr
-xf86GetAGPInfo(int screenNum)
-{
- struct _agp_info agpinf;
- AgpInfoPtr info;
-
- if (!GARTInit(screenNum))
- return NULL;
-
-
- if ((info = xcalloc(sizeof(AgpInfo), 1)) == NULL) {
- xf86DrvMsg(screenNum, X_ERROR,
- "xf86GetAGPInfo: Failed to allocate AgpInfo\n");
- return NULL;
- }
-
- memset((char*)&agpinf, 0, sizeof(agpinf));
-
- if (ioctl(gartFd, AGPIOC_INFO, &agpinf) != 0) {
- xf86DrvMsg(screenNum, X_ERROR,
- "xf86GetAGPInfo: AGPIOC_INFO failed (%s)\n",
- strerror(errno));
- return NULL;
- }
-
- info->bridgeId = agpinf.bridge_id;
- info->agpMode = agpinf.agp_mode;
- info->base = agpinf.aper_base;
- info->size = agpinf.aper_size;
- info->totalPages = agpinf.pg_total;
- info->systemPages = agpinf.pg_system;
- info->usedPages = agpinf.pg_used;
-
- xf86DrvMsg(screenNum, X_INFO, "Kernel reported %zu total, %zu used\n", agpinf.pg_total, agpinf.pg_used);
-
- return info;
-}
-
-/*
- * XXX If multiple screens can acquire the GART, should we have a reference
- * count instead of using acquiredScreen?
- */
-
-Bool
-xf86AcquireGART(int screenNum)
-{
- if (screenNum != -1 && !GARTInit(screenNum))
- return FALSE;
-
- if (screenNum == -1 || acquiredScreen != screenNum) {
- if (ioctl(gartFd, AGPIOC_ACQUIRE, 0) != 0) {
- xf86DrvMsg(screenNum, X_WARNING,
- "xf86AcquireGART: AGPIOC_ACQUIRE failed (%s)\n",
- strerror(errno));
- return FALSE;
- }
- acquiredScreen = screenNum;
- }
- return TRUE;
-}
-
-Bool
-xf86ReleaseGART(int screenNum)
-{
- if (screenNum != -1 && !GARTInit(screenNum))
- return FALSE;
-
- if (acquiredScreen == screenNum) {
- /*
- * The FreeBSD agp driver removes allocations on release.
- * The Linux driver doesn't. xf86ReleaseGART() is expected
- * to give up access to the GART, but not to remove any
- * allocations.
- */
-#if !defined(linux)
- if (screenNum == -1)
-#endif
- {
- if (ioctl(gartFd, AGPIOC_RELEASE, 0) != 0) {
- xf86DrvMsg(screenNum, X_WARNING,
- "xf86ReleaseGART: AGPIOC_RELEASE failed (%s)\n",
- strerror(errno));
- return FALSE;
- }
- acquiredScreen = -1;
- }
- return TRUE;
- }
- return FALSE;
-}
-
-int
-xf86AllocateGARTMemory(int screenNum, unsigned long size, int type,
- unsigned long *physical)
-{
- struct _agp_allocate alloc;
- int pages;
-
- /*
- * Allocates "size" bytes of GART memory (rounds up to the next
- * page multiple) or type "type". A handle (key) for the allocated
- * memory is returned. On error, the return value is -1.
- */
-
- if (!GARTInit(screenNum) || acquiredScreen != screenNum)
- return -1;
-
- pages = (size / AGP_PAGE_SIZE);
- if (size % AGP_PAGE_SIZE != 0)
- pages++;
-
- /* XXX check for pages == 0? */
-
- alloc.pg_count = pages;
- alloc.type = type;
-
- if (ioctl(gartFd, AGPIOC_ALLOCATE, &alloc) != 0) {
- xf86DrvMsg(screenNum, X_WARNING, "xf86AllocateGARTMemory: "
- "allocation of %d pages failed\n\t(%s)\n", pages,
- strerror(errno));
- return -1;
- }
-
- if (physical)
- *physical = alloc.physical;
-
- return alloc.key;
-}
-
-Bool
-xf86DeallocateGARTMemory(int screenNum, int key)
-{
- if (!GARTInit(screenNum) || acquiredScreen != screenNum)
- return FALSE;
-
- if (acquiredScreen != screenNum) {
- xf86DrvMsg(screenNum, X_ERROR,
- "xf86UnbindGARTMemory: AGP not acquired by this screen\n");
- return FALSE;
- }
-
-#ifdef __linux__
- if (ioctl(gartFd, AGPIOC_DEALLOCATE, (int *)key) != 0) {
-#else
- if (ioctl(gartFd, AGPIOC_DEALLOCATE, &key) != 0) {
-#endif
- xf86DrvMsg(screenNum, X_WARNING,"xf86DeAllocateGARTMemory: "
- "deallocation gart memory with key %d failed\n\t(%s)\n",
- key, strerror(errno));
- return FALSE;
- }
-
- return TRUE;
-}
-
-/* Bind GART memory with "key" at "offset" */
-Bool
-xf86BindGARTMemory(int screenNum, int key, unsigned long offset)
-{
- struct _agp_bind bind;
- int pageOffset;
-
- if (!GARTInit(screenNum) || acquiredScreen != screenNum)
- return FALSE;
-
- if (acquiredScreen != screenNum) {
- xf86DrvMsg(screenNum, X_ERROR,
- "xf86BindGARTMemory: AGP not acquired by this screen\n");
- return FALSE;
- }
-
- if (offset % AGP_PAGE_SIZE != 0) {
- xf86DrvMsg(screenNum, X_WARNING, "xf86BindGARTMemory: "
- "offset (0x%lx) is not page-aligned (%d)\n",
- offset, AGP_PAGE_SIZE);
- return FALSE;
- }
- pageOffset = offset / AGP_PAGE_SIZE;
-
- xf86DrvMsgVerb(screenNum, X_INFO, 3,
- "xf86BindGARTMemory: bind key %d at 0x%08lx "
- "(pgoffset %d)\n", key, offset, pageOffset);
-
- bind.pg_start = pageOffset;
- bind.key = key;
-
- if (ioctl(gartFd, AGPIOC_BIND, &bind) != 0) {
- xf86DrvMsg(screenNum, X_WARNING, "xf86BindGARTMemory: "
- "binding of gart memory with key %d\n"
- "\tat offset 0x%lx failed (%s)\n",
- key, offset, strerror(errno));
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-/* Unbind GART memory with "key" */
-Bool
-xf86UnbindGARTMemory(int screenNum, int key)
-{
- struct _agp_unbind unbind;
-
- if (!GARTInit(screenNum) || acquiredScreen != screenNum)
- return FALSE;
-
- if (acquiredScreen != screenNum) {
- xf86DrvMsg(screenNum, X_ERROR,
- "xf86UnbindGARTMemory: AGP not acquired by this screen\n");
- return FALSE;
- }
-
- unbind.priority = 0;
- unbind.key = key;
-
- if (ioctl(gartFd, AGPIOC_UNBIND, &unbind) != 0) {
- xf86DrvMsg(screenNum, X_WARNING, "xf86UnbindGARTMemory: "
- "unbinding of gart memory with key %d "
- "failed (%s)\n", key, strerror(errno));
- return FALSE;
- }
-
- xf86DrvMsgVerb(screenNum, X_INFO, 3,
- "xf86UnbindGARTMemory: unbind key %d\n", key);
-
- return TRUE;
-}
-
-
-/* XXX Interface may change. */
-Bool
-xf86EnableAGP(int screenNum, CARD32 mode)
-{
- agp_setup setup;
-
- if (!GARTInit(screenNum) || acquiredScreen != screenNum)
- return FALSE;
-
- setup.agp_mode = mode;
- if (ioctl(gartFd, AGPIOC_SETUP, &setup) != 0) {
- xf86DrvMsg(screenNum, X_WARNING, "xf86EnableAGP: "
- "AGPIOC_SETUP with mode %ld failed (%s)\n",
- (unsigned long)mode, strerror(errno));
- return FALSE;
- }
-
- return TRUE;
-}
-
+/*
+ * Abstraction of the AGP GART interface.
+ *
+ * This version is for Linux and Free/Open/NetBSD.
+ *
+ * Copyright © 2000 VA Linux Systems, Inc.
+ * Copyright © 2001 The XFree86 Project, Inc.
+ */
+
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <X11/X.h>
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "xf86OSpriv.h"
+
+#if defined(linux)
+#include <asm/ioctl.h>
+#include <linux/agpgart.h>
+#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
+#include <sys/ioctl.h>
+#include <sys/agpio.h>
+#endif
+
+#ifndef AGP_DEVICE
+#define AGP_DEVICE "/dev/agpgart"
+#endif
+/* AGP page size is independent of the host page size. */
+#ifndef AGP_PAGE_SIZE
+#define AGP_PAGE_SIZE 4096
+#endif
+#define AGPGART_MAJOR_VERSION 0
+#define AGPGART_MINOR_VERSION 99
+
+static int gartFd = -1;
+static int acquiredScreen = -1;
+static Bool initDone = FALSE;
+/*
+ * Close /dev/agpgart. This frees all associated memory allocated during
+ * this server generation.
+ */
+Bool
+xf86GARTCloseScreen(int screenNum)
+{
+ if(gartFd != -1) {
+ close(gartFd);
+ acquiredScreen = -1;
+ gartFd = -1;
+ initDone = FALSE;
+ }
+ return TRUE;
+}
+
+/*
+ * Open /dev/agpgart. Keep it open until xf86GARTCloseScreen is called.
+ */
+static Bool
+GARTInit(int screenNum)
+{
+ struct _agp_info agpinf;
+
+ if (initDone)
+ return (gartFd != -1);
+
+ initDone = TRUE;
+
+ if (gartFd == -1)
+ gartFd = open(AGP_DEVICE, O_RDWR, 0);
+ else
+ return FALSE;
+
+ if (gartFd == -1) {
+ xf86DrvMsg(screenNum, X_ERROR,
+ "GARTInit: Unable to open " AGP_DEVICE " (%s)\n",
+ strerror(errno));
+ return FALSE;
+ }
+
+ xf86AcquireGART(-1);
+ /* Check the kernel driver version. */
+ if (ioctl(gartFd, AGPIOC_INFO, &agpinf) != 0) {
+ xf86DrvMsg(screenNum, X_ERROR,
+ "GARTInit: AGPIOC_INFO failed (%s)\n", strerror(errno));
+ close(gartFd);
+ gartFd = -1;
+ return FALSE;
+ }
+ xf86ReleaseGART(-1);
+
+#if defined(linux)
+ /* Per Dave Jones, every effort will be made to keep the
+ * agpgart interface backwards compatible, so allow all
+ * future versions.
+ */
+ if (
+#if (AGPGART_MAJOR_VERSION > 0) /* quiet compiler */
+ agpinf.version.major < AGPGART_MAJOR_VERSION ||
+#endif
+ (agpinf.version.major == AGPGART_MAJOR_VERSION &&
+ agpinf.version.minor < AGPGART_MINOR_VERSION)) {
+ xf86DrvMsg(screenNum, X_ERROR,
+ "GARTInit: Kernel agpgart driver version is not current"
+ " (%d.%d vs %d.%d)\n",
+ agpinf.version.major, agpinf.version.minor,
+ AGPGART_MAJOR_VERSION, AGPGART_MINOR_VERSION);
+ close(gartFd);
+ gartFd = -1;
+ return FALSE;
+ }
+#endif
+
+ return TRUE;
+}
+
+Bool
+xf86AgpGARTSupported(void)
+{
+ return GARTInit(-1);
+}
+
+AgpInfoPtr
+xf86GetAGPInfo(int screenNum)
+{
+ struct _agp_info agpinf;
+ AgpInfoPtr info;
+
+ if (!GARTInit(screenNum))
+ return NULL;
+
+
+ if ((info = calloc(sizeof(AgpInfo), 1)) == NULL) {
+ xf86DrvMsg(screenNum, X_ERROR,
+ "xf86GetAGPInfo: Failed to allocate AgpInfo\n");
+ return NULL;
+ }
+
+ memset((char*)&agpinf, 0, sizeof(agpinf));
+
+ if (ioctl(gartFd, AGPIOC_INFO, &agpinf) != 0) {
+ xf86DrvMsg(screenNum, X_ERROR,
+ "xf86GetAGPInfo: AGPIOC_INFO failed (%s)\n",
+ strerror(errno));
+ return NULL;
+ }
+
+ info->bridgeId = agpinf.bridge_id;
+ info->agpMode = agpinf.agp_mode;
+ info->base = agpinf.aper_base;
+ info->size = agpinf.aper_size;
+ info->totalPages = agpinf.pg_total;
+ info->systemPages = agpinf.pg_system;
+ info->usedPages = agpinf.pg_used;
+
+ xf86DrvMsg(screenNum, X_INFO, "Kernel reported %zu total, %zu used\n", agpinf.pg_total, agpinf.pg_used);
+
+ return info;
+}
+
+/*
+ * XXX If multiple screens can acquire the GART, should we have a reference
+ * count instead of using acquiredScreen?
+ */
+
+Bool
+xf86AcquireGART(int screenNum)
+{
+ if (screenNum != -1 && !GARTInit(screenNum))
+ return FALSE;
+
+ if (screenNum == -1 || acquiredScreen != screenNum) {
+ if (ioctl(gartFd, AGPIOC_ACQUIRE, 0) != 0) {
+ xf86DrvMsg(screenNum, X_WARNING,
+ "xf86AcquireGART: AGPIOC_ACQUIRE failed (%s)\n",
+ strerror(errno));
+ return FALSE;
+ }
+ acquiredScreen = screenNum;
+ }
+ return TRUE;
+}
+
+Bool
+xf86ReleaseGART(int screenNum)
+{
+ if (screenNum != -1 && !GARTInit(screenNum))
+ return FALSE;
+
+ if (acquiredScreen == screenNum) {
+ /*
+ * The FreeBSD agp driver removes allocations on release.
+ * The Linux driver doesn't. xf86ReleaseGART() is expected
+ * to give up access to the GART, but not to remove any
+ * allocations.
+ */
+#if !defined(linux)
+ if (screenNum == -1)
+#endif
+ {
+ if (ioctl(gartFd, AGPIOC_RELEASE, 0) != 0) {
+ xf86DrvMsg(screenNum, X_WARNING,
+ "xf86ReleaseGART: AGPIOC_RELEASE failed (%s)\n",
+ strerror(errno));
+ return FALSE;
+ }
+ acquiredScreen = -1;
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+int
+xf86AllocateGARTMemory(int screenNum, unsigned long size, int type,
+ unsigned long *physical)
+{
+ struct _agp_allocate alloc;
+ int pages;
+
+ /*
+ * Allocates "size" bytes of GART memory (rounds up to the next
+ * page multiple) or type "type". A handle (key) for the allocated
+ * memory is returned. On error, the return value is -1.
+ */
+
+ if (!GARTInit(screenNum) || acquiredScreen != screenNum)
+ return -1;
+
+ pages = (size / AGP_PAGE_SIZE);
+ if (size % AGP_PAGE_SIZE != 0)
+ pages++;
+
+ /* XXX check for pages == 0? */
+
+ alloc.pg_count = pages;
+ alloc.type = type;
+
+ if (ioctl(gartFd, AGPIOC_ALLOCATE, &alloc) != 0) {
+ xf86DrvMsg(screenNum, X_WARNING, "xf86AllocateGARTMemory: "
+ "allocation of %d pages failed\n\t(%s)\n", pages,
+ strerror(errno));
+ return -1;
+ }
+
+ if (physical)
+ *physical = alloc.physical;
+
+ return alloc.key;
+}
+
+Bool
+xf86DeallocateGARTMemory(int screenNum, int key)
+{
+ if (!GARTInit(screenNum) || acquiredScreen != screenNum)
+ return FALSE;
+
+ if (acquiredScreen != screenNum) {
+ xf86DrvMsg(screenNum, X_ERROR,
+ "xf86UnbindGARTMemory: AGP not acquired by this screen\n");
+ return FALSE;
+ }
+
+#ifdef __linux__
+ if (ioctl(gartFd, AGPIOC_DEALLOCATE, (int *)key) != 0) {
+#else
+ if (ioctl(gartFd, AGPIOC_DEALLOCATE, &key) != 0) {
+#endif
+ xf86DrvMsg(screenNum, X_WARNING,"xf86DeAllocateGARTMemory: "
+ "deallocation gart memory with key %d failed\n\t(%s)\n",
+ key, strerror(errno));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Bind GART memory with "key" at "offset" */
+Bool
+xf86BindGARTMemory(int screenNum, int key, unsigned long offset)
+{
+ struct _agp_bind bind;
+ int pageOffset;
+
+ if (!GARTInit(screenNum) || acquiredScreen != screenNum)
+ return FALSE;
+
+ if (acquiredScreen != screenNum) {
+ xf86DrvMsg(screenNum, X_ERROR,
+ "xf86BindGARTMemory: AGP not acquired by this screen\n");
+ return FALSE;
+ }
+
+ if (offset % AGP_PAGE_SIZE != 0) {
+ xf86DrvMsg(screenNum, X_WARNING, "xf86BindGARTMemory: "
+ "offset (0x%lx) is not page-aligned (%d)\n",
+ offset, AGP_PAGE_SIZE);
+ return FALSE;
+ }
+ pageOffset = offset / AGP_PAGE_SIZE;
+
+ xf86DrvMsgVerb(screenNum, X_INFO, 3,
+ "xf86BindGARTMemory: bind key %d at 0x%08lx "
+ "(pgoffset %d)\n", key, offset, pageOffset);
+
+ bind.pg_start = pageOffset;
+ bind.key = key;
+
+ if (ioctl(gartFd, AGPIOC_BIND, &bind) != 0) {
+ xf86DrvMsg(screenNum, X_WARNING, "xf86BindGARTMemory: "
+ "binding of gart memory with key %d\n"
+ "\tat offset 0x%lx failed (%s)\n",
+ key, offset, strerror(errno));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/* Unbind GART memory with "key" */
+Bool
+xf86UnbindGARTMemory(int screenNum, int key)
+{
+ struct _agp_unbind unbind;
+
+ if (!GARTInit(screenNum) || acquiredScreen != screenNum)
+ return FALSE;
+
+ if (acquiredScreen != screenNum) {
+ xf86DrvMsg(screenNum, X_ERROR,
+ "xf86UnbindGARTMemory: AGP not acquired by this screen\n");
+ return FALSE;
+ }
+
+ unbind.priority = 0;
+ unbind.key = key;
+
+ if (ioctl(gartFd, AGPIOC_UNBIND, &unbind) != 0) {
+ xf86DrvMsg(screenNum, X_WARNING, "xf86UnbindGARTMemory: "
+ "unbinding of gart memory with key %d "
+ "failed (%s)\n", key, strerror(errno));
+ return FALSE;
+ }
+
+ xf86DrvMsgVerb(screenNum, X_INFO, 3,
+ "xf86UnbindGARTMemory: unbind key %d\n", key);
+
+ return TRUE;
+}
+
+
+/* XXX Interface may change. */
+Bool
+xf86EnableAGP(int screenNum, CARD32 mode)
+{
+ agp_setup setup;
+
+ if (!GARTInit(screenNum) || acquiredScreen != screenNum)
+ return FALSE;
+
+ setup.agp_mode = mode;
+ if (ioctl(gartFd, AGPIOC_SETUP, &setup) != 0) {
+ xf86DrvMsg(screenNum, X_WARNING, "xf86EnableAGP: "
+ "AGPIOC_SETUP with mode %ld failed (%s)\n",
+ (unsigned long)mode, strerror(errno));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
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 26a17425a..a515b4080 100644
--- a/xorg-server/hw/xfree86/os-support/linux/lnx_video.c
+++ b/xorg-server/hw/xfree86/os-support/linux/lnx_video.c
@@ -1,878 +1,878 @@
-/*
- * 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(__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 = xalloc(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 {
- xfree(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 = xalloc(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;
- xfree(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;
- xfree(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, 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__)
- 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__)
- 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__)
- 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
+
+#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(__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, 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__)
+ 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__)
+ 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__)
+ 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/posix_tty.c b/xorg-server/hw/xfree86/os-support/shared/posix_tty.c
index da57939cf..7e2c4a181 100644
--- a/xorg-server/hw/xfree86/os-support/shared/posix_tty.c
+++ b/xorg-server/hw/xfree86/os-support/shared/posix_tty.c
@@ -1,655 +1,655 @@
-/*
- * Copyright 1993-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 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.
- */
-/*
- *
- * 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.
- *
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <X11/X.h>
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86_OSlib.h"
-
-static int
-GetBaud (int baudrate)
-{
-#ifdef B300
- if (baudrate == 300)
- return B300;
-#endif
-#ifdef B1200
- if (baudrate == 1200)
- return B1200;
-#endif
-#ifdef B2400
- if (baudrate == 2400)
- return B2400;
-#endif
-#ifdef B4800
- if (baudrate == 4800)
- return B4800;
-#endif
-#ifdef B9600
- if (baudrate == 9600)
- return B9600;
-#endif
-#ifdef B19200
- if (baudrate == 19200)
- return B19200;
-#endif
-#ifdef B38400
- if (baudrate == 38400)
- return B38400;
-#endif
-#ifdef B57600
- if (baudrate == 57600)
- return B57600;
-#endif
-#ifdef B115200
- if (baudrate == 115200)
- return B115200;
-#endif
-#ifdef B230400
- if (baudrate == 230400)
- return B230400;
-#endif
-#ifdef B460800
- if (baudrate == 460800)
- return B460800;
-#endif
- return (0);
-}
-
-int
-xf86OpenSerial (pointer options)
-{
- struct termios t;
- int fd, i;
- char *dev;
-
- dev = xf86SetStrOption (options, "Device", NULL);
- if (!dev)
- {
- xf86Msg (X_ERROR, "xf86OpenSerial: No Device specified.\n");
- return (-1);
- }
-
- SYSCALL (fd = open (dev, O_RDWR | O_NONBLOCK));
- if (fd == -1)
- {
- xf86Msg (X_ERROR,
- "xf86OpenSerial: Cannot open device %s\n\t%s.\n",
- dev, strerror (errno));
- xfree(dev);
- return (-1);
- }
-
- if (!isatty (fd))
- {
- /* Allow non-tty devices to be opened. */
- xfree(dev);
- return (fd);
- }
-
- /* set up default port parameters */
- SYSCALL (tcgetattr (fd, &t));
- t.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR\
- |IGNCR|ICRNL|IXON);
- t.c_oflag &= ~OPOST;
- t.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
- t.c_cflag &= ~(CSIZE|PARENB);
- t.c_cflag |= CS8|CLOCAL;
-
- cfsetispeed (&t, B9600);
- cfsetospeed (&t, B9600);
- t.c_cc[VMIN] = 1;
- t.c_cc[VTIME] = 0;
-
- SYSCALL (tcsetattr (fd, TCSANOW, &t));
-
- if (xf86SetSerial (fd, options) == -1)
- {
- SYSCALL (close (fd));
- xfree(dev);
- return (-1);
- }
-
- SYSCALL (i = fcntl (fd, F_GETFL, 0));
- if (i == -1)
- {
- SYSCALL (close (fd));
- xfree(dev);
- return (-1);
- }
- i &= ~O_NONBLOCK;
- SYSCALL (i = fcntl (fd, F_SETFL, i));
- if (i == -1)
- {
- SYSCALL (close (fd));
- xfree(dev);
- return (-1);
- }
- xfree(dev);
- return (fd);
-}
-
-int
-xf86SetSerial (int fd, pointer options)
-{
- struct termios t;
- int val;
- const char *s;
- int baud, r;
-
- if (fd < 0)
- return -1;
-
- /* Don't try to set parameters for non-tty devices. */
- if (!isatty(fd))
- return 0;
-
- SYSCALL (tcgetattr (fd, &t));
-
- if ((val = xf86SetIntOption (options, "BaudRate", 0)))
- {
- if ((baud = GetBaud (val)))
- {
- cfsetispeed (&t, baud);
- cfsetospeed (&t, baud);
- }
- else
- {
- xf86Msg (X_ERROR,
- "Invalid Option BaudRate value: %d\n", val);
- return (-1);
- }
- }
-
- if ((val = xf86SetIntOption (options, "StopBits", 0)))
- {
- switch (val)
- {
- case 1:
- t.c_cflag &= ~(CSTOPB);
- break;
- case 2:
- t.c_cflag |= CSTOPB;
- break;
- default:
- xf86Msg (X_ERROR,
- "Invalid Option StopBits value: %d\n", val);
- return (-1);
- break;
- }
- }
-
- if ((val = xf86SetIntOption (options, "DataBits", 0)))
- {
- switch (val)
- {
- case 5:
- t.c_cflag &= ~(CSIZE);
- t.c_cflag |= CS5;
- break;
- case 6:
- t.c_cflag &= ~(CSIZE);
- t.c_cflag |= CS6;
- break;
- case 7:
- t.c_cflag &= ~(CSIZE);
- t.c_cflag |= CS7;
- break;
- case 8:
- t.c_cflag &= ~(CSIZE);
- t.c_cflag |= CS8;
- break;
- default:
- xf86Msg (X_ERROR,
- "Invalid Option DataBits value: %d\n", val);
- return (-1);
- break;
- }
- }
-
- if ((s = xf86SetStrOption (options, "Parity", NULL)))
- {
- if (xf86NameCmp (s, "Odd") == 0)
- {
- t.c_cflag |= PARENB | PARODD;
- }
- else if (xf86NameCmp (s, "Even") == 0)
- {
- t.c_cflag |= PARENB;
- t.c_cflag &= ~(PARODD);
- }
- else if (xf86NameCmp (s, "None") == 0)
- {
- t.c_cflag &= ~(PARENB);
- }
- else
- {
- xf86Msg (X_ERROR, "Invalid Option Parity value: %s\n",
- s);
- return (-1);
- }
- }
-
- if ((val = xf86SetIntOption (options, "Vmin", -1)) != -1)
- {
- t.c_cc[VMIN] = val;
- }
- if ((val = xf86SetIntOption (options, "Vtime", -1)) != -1)
- {
- t.c_cc[VTIME] = val;
- }
-
- if ((s = xf86SetStrOption (options, "FlowControl", NULL)))
- {
- xf86MarkOptionUsedByName (options, "FlowControl");
- if (xf86NameCmp (s, "Xoff") == 0)
- {
- t.c_iflag |= IXOFF;
- }
- else if (xf86NameCmp (s, "Xon") == 0)
- {
- t.c_iflag |= IXON;
- }
- else if (xf86NameCmp (s, "XonXoff") == 0)
- {
- t.c_iflag |= IXON|IXOFF;
- }
- else if (xf86NameCmp (s, "None") == 0)
- {
- t.c_iflag &= ~(IXON | IXOFF);
- }
- else
- {
- xf86Msg (X_ERROR,
- "Invalid Option FlowControl value: %s\n", s);
- return (-1);
- }
- }
-
- if ((xf86SetBoolOption (options, "ClearDTR", FALSE)))
- {
-#ifdef CLEARDTR_SUPPORT
-# if defined(TIOCMBIC)
- val = TIOCM_DTR;
- SYSCALL (ioctl(fd, TIOCMBIC, &val));
-# else
- SYSCALL (ioctl(fd, TIOCCDTR, NULL));
-# endif
-#else
- xf86Msg (X_WARNING,
- "Option ClearDTR not supported on this OS\n");
- return (-1);
-#endif
- xf86MarkOptionUsedByName (options, "ClearDTR");
- }
-
- if ((xf86SetBoolOption (options, "ClearRTS", FALSE)))
- {
- xf86Msg (X_WARNING,
- "Option ClearRTS not supported on this OS\n");
- return (-1);
- xf86MarkOptionUsedByName (options, "ClearRTS");
- }
-
- SYSCALL (r = tcsetattr (fd, TCSANOW, &t));
- return (r);
-}
-
-int
-xf86SetSerialSpeed (int fd, int speed)
-{
- struct termios t;
- int baud, r;
-
- if (fd < 0)
- return -1;
-
- /* Don't try to set parameters for non-tty devices. */
- if (!isatty(fd))
- return 0;
-
- SYSCALL (tcgetattr (fd, &t));
-
- if ((baud = GetBaud (speed)))
- {
- cfsetispeed (&t, baud);
- cfsetospeed (&t, baud);
- }
- else
- {
- xf86Msg (X_ERROR,
- "Invalid Option BaudRate value: %d\n", speed);
- return (-1);
- }
-
- SYSCALL (r = tcsetattr (fd, TCSANOW, &t));
- return (r);
-}
-
-int
-xf86ReadSerial (int fd, void *buf, int count)
-{
- int r;
- int i;
-
- SYSCALL (r = read (fd, buf, count));
- DebugF("ReadingSerial: 0x%x",
- (unsigned char)*(((unsigned char *)buf)));
- for (i = 1; i < r; i++)
- DebugF(", 0x%x",(unsigned char)*(((unsigned char *)buf) + i));
- DebugF("\n");
- return (r);
-}
-
-int
-xf86WriteSerial (int fd, const void *buf, int count)
-{
- int r;
- int i;
-
- DebugF("WritingSerial: 0x%x",(unsigned char)*(((unsigned char *)buf)));
- for (i = 1; i < count; i++)
- ErrorF(", 0x%x",(unsigned char)*(((unsigned char *)buf) + i));
- DebugF("\n");
- SYSCALL (r = write (fd, buf, count));
- return (r);
-}
-
-int
-xf86CloseSerial (int fd)
-{
- int r;
-
- SYSCALL (r = close (fd));
- return (r);
-}
-
-int
-xf86WaitForInput (int fd, int timeout)
-{
- fd_set readfds;
- struct timeval to;
- int r;
-
- FD_ZERO(&readfds);
-
- if (fd >= 0) {
- FD_SET(fd, &readfds);
- }
-
- to.tv_sec = timeout / 1000000;
- to.tv_usec = timeout % 1000000;
-
- if (fd >= 0) {
- SYSCALL (r = select (FD_SETSIZE, &readfds, NULL, NULL, &to));
- }
- else {
- SYSCALL (r = select (FD_SETSIZE, NULL, NULL, NULL, &to));
- }
- xf86ErrorFVerb (9,"select returned %d\n", r);
- return (r);
-}
-
-int
-xf86SerialSendBreak (int fd, int duration)
-{
- int r;
-
- SYSCALL (r = tcsendbreak (fd, duration));
- return (r);
-
-}
-
-int
-xf86FlushInput(int fd)
-{
- fd_set fds;
- struct timeval timeout;
- char c[4];
-
- DebugF("FlushingSerial\n");
- if (tcflush(fd, TCIFLUSH) == 0)
- return 0;
-
- timeout.tv_sec = 0;
- timeout.tv_usec = 0;
- FD_ZERO(&fds);
- FD_SET(fd, &fds);
- while (select(FD_SETSIZE, &fds, NULL, NULL, &timeout) > 0) {
- if (read(fd, &c, sizeof(c)) < 1)
- return 0;
- FD_ZERO(&fds);
- FD_SET(fd, &fds);
- }
- return 0;
-}
-
-static struct states {
- int xf;
- int os;
-} modemStates[] = {
-#ifdef TIOCM_LE
- { XF86_M_LE, TIOCM_LE },
-#endif
-#ifdef TIOCM_DTR
- { XF86_M_DTR, TIOCM_DTR },
-#endif
-#ifdef TIOCM_RTS
- { XF86_M_RTS, TIOCM_RTS },
-#endif
-#ifdef TIOCM_ST
- { XF86_M_ST, TIOCM_ST },
-#endif
-#ifdef TIOCM_SR
- { XF86_M_SR, TIOCM_SR },
-#endif
-#ifdef TIOCM_CTS
- { XF86_M_CTS, TIOCM_CTS },
-#endif
-#ifdef TIOCM_CAR
- { XF86_M_CAR, TIOCM_CAR },
-#elif defined(TIOCM_CD)
- { XF86_M_CAR, TIOCM_CD },
-#endif
-#ifdef TIOCM_RNG
- { XF86_M_RNG, TIOCM_RNG },
-#elif defined(TIOCM_RI)
- { XF86_M_CAR, TIOCM_RI },
-#endif
-#ifdef TIOCM_DSR
- { XF86_M_DSR, TIOCM_DSR },
-#endif
-};
-
-static int numStates = sizeof(modemStates) / sizeof(modemStates[0]);
-
-static int
-xf2osState(int state)
-{
- int i;
- int ret = 0;
-
- for (i = 0; i < numStates; i++)
- if (state & modemStates[i].xf)
- ret |= modemStates[i].os;
- return ret;
-}
-
-static int
-os2xfState(int state)
-{
- int i;
- int ret = 0;
-
- for (i = 0; i < numStates; i++)
- if (state & modemStates[i].os)
- ret |= modemStates[i].xf;
- return ret;
-}
-
-static int
-getOsStateMask(void)
-{
- int i;
- int ret = 0;
- for (i = 0; i < numStates; i++)
- ret |= modemStates[i].os;
- return ret;
-}
-
-static int osStateMask = 0;
-
-int
-xf86SetSerialModemState(int fd, int state)
-{
- int ret;
- int s;
-
- if (fd < 0)
- return -1;
-
- /* Don't try to set parameters for non-tty devices. */
- if (!isatty(fd))
- return 0;
-
-#ifndef TIOCMGET
- return -1;
-#else
- if (!osStateMask)
- osStateMask = getOsStateMask();
-
- state = xf2osState(state);
- SYSCALL((ret = ioctl(fd, TIOCMGET, &s)));
- if (ret < 0)
- return -1;
- s &= ~osStateMask;
- s |= state;
- SYSCALL((ret = ioctl(fd, TIOCMSET, &s)));
- if (ret < 0)
- return -1;
- else
- return 0;
-#endif
-}
-
-int
-xf86GetSerialModemState(int fd)
-{
- int ret;
- int s;
-
- if (fd < 0)
- return -1;
-
- /* Don't try to set parameters for non-tty devices. */
- if (!isatty(fd))
- return 0;
-
-#ifndef TIOCMGET
- return -1;
-#else
- SYSCALL((ret = ioctl(fd, TIOCMGET, &s)));
- if (ret < 0)
- return -1;
- return os2xfState(s);
-#endif
-}
-
-int
-xf86SerialModemSetBits(int fd, int bits)
-{
- int ret;
- int s;
-
- if (fd < 0)
- return -1;
-
- /* Don't try to set parameters for non-tty devices. */
- if (!isatty(fd))
- return 0;
-
-#ifndef TIOCMGET
- return -1;
-#else
- s = xf2osState(bits);
- SYSCALL((ret = ioctl(fd, TIOCMBIS, &s)));
- return ret;
-#endif
-}
-
-int
-xf86SerialModemClearBits(int fd, int bits)
-{
- int ret;
- int s;
-
- if (fd < 0)
- return -1;
-
- /* Don't try to set parameters for non-tty devices. */
- if (!isatty(fd))
- return 0;
-
-#ifndef TIOCMGET
- return -1;
-#else
- s = xf2osState(bits);
- SYSCALL((ret = ioctl(fd, TIOCMBIC, &s)));
- return ret;
-#endif
-}
+/*
+ * Copyright 1993-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 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.
+ */
+/*
+ *
+ * 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.
+ *
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <X11/X.h>
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+
+static int
+GetBaud (int baudrate)
+{
+#ifdef B300
+ if (baudrate == 300)
+ return B300;
+#endif
+#ifdef B1200
+ if (baudrate == 1200)
+ return B1200;
+#endif
+#ifdef B2400
+ if (baudrate == 2400)
+ return B2400;
+#endif
+#ifdef B4800
+ if (baudrate == 4800)
+ return B4800;
+#endif
+#ifdef B9600
+ if (baudrate == 9600)
+ return B9600;
+#endif
+#ifdef B19200
+ if (baudrate == 19200)
+ return B19200;
+#endif
+#ifdef B38400
+ if (baudrate == 38400)
+ return B38400;
+#endif
+#ifdef B57600
+ if (baudrate == 57600)
+ return B57600;
+#endif
+#ifdef B115200
+ if (baudrate == 115200)
+ return B115200;
+#endif
+#ifdef B230400
+ if (baudrate == 230400)
+ return B230400;
+#endif
+#ifdef B460800
+ if (baudrate == 460800)
+ return B460800;
+#endif
+ return (0);
+}
+
+int
+xf86OpenSerial (pointer options)
+{
+ struct termios t;
+ int fd, i;
+ char *dev;
+
+ dev = xf86SetStrOption (options, "Device", NULL);
+ if (!dev)
+ {
+ xf86Msg (X_ERROR, "xf86OpenSerial: No Device specified.\n");
+ return (-1);
+ }
+
+ SYSCALL (fd = open (dev, O_RDWR | O_NONBLOCK));
+ if (fd == -1)
+ {
+ xf86Msg (X_ERROR,
+ "xf86OpenSerial: Cannot open device %s\n\t%s.\n",
+ dev, strerror (errno));
+ free(dev);
+ return (-1);
+ }
+
+ if (!isatty (fd))
+ {
+ /* Allow non-tty devices to be opened. */
+ free(dev);
+ return (fd);
+ }
+
+ /* set up default port parameters */
+ SYSCALL (tcgetattr (fd, &t));
+ t.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR\
+ |IGNCR|ICRNL|IXON);
+ t.c_oflag &= ~OPOST;
+ t.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
+ t.c_cflag &= ~(CSIZE|PARENB);
+ t.c_cflag |= CS8|CLOCAL;
+
+ cfsetispeed (&t, B9600);
+ cfsetospeed (&t, B9600);
+ t.c_cc[VMIN] = 1;
+ t.c_cc[VTIME] = 0;
+
+ SYSCALL (tcsetattr (fd, TCSANOW, &t));
+
+ if (xf86SetSerial (fd, options) == -1)
+ {
+ SYSCALL (close (fd));
+ free(dev);
+ return (-1);
+ }
+
+ SYSCALL (i = fcntl (fd, F_GETFL, 0));
+ if (i == -1)
+ {
+ SYSCALL (close (fd));
+ free(dev);
+ return (-1);
+ }
+ i &= ~O_NONBLOCK;
+ SYSCALL (i = fcntl (fd, F_SETFL, i));
+ if (i == -1)
+ {
+ SYSCALL (close (fd));
+ free(dev);
+ return (-1);
+ }
+ free(dev);
+ return (fd);
+}
+
+int
+xf86SetSerial (int fd, pointer options)
+{
+ struct termios t;
+ int val;
+ const char *s;
+ int baud, r;
+
+ if (fd < 0)
+ return -1;
+
+ /* Don't try to set parameters for non-tty devices. */
+ if (!isatty(fd))
+ return 0;
+
+ SYSCALL (tcgetattr (fd, &t));
+
+ if ((val = xf86SetIntOption (options, "BaudRate", 0)))
+ {
+ if ((baud = GetBaud (val)))
+ {
+ cfsetispeed (&t, baud);
+ cfsetospeed (&t, baud);
+ }
+ else
+ {
+ xf86Msg (X_ERROR,
+ "Invalid Option BaudRate value: %d\n", val);
+ return (-1);
+ }
+ }
+
+ if ((val = xf86SetIntOption (options, "StopBits", 0)))
+ {
+ switch (val)
+ {
+ case 1:
+ t.c_cflag &= ~(CSTOPB);
+ break;
+ case 2:
+ t.c_cflag |= CSTOPB;
+ break;
+ default:
+ xf86Msg (X_ERROR,
+ "Invalid Option StopBits value: %d\n", val);
+ return (-1);
+ break;
+ }
+ }
+
+ if ((val = xf86SetIntOption (options, "DataBits", 0)))
+ {
+ switch (val)
+ {
+ case 5:
+ t.c_cflag &= ~(CSIZE);
+ t.c_cflag |= CS5;
+ break;
+ case 6:
+ t.c_cflag &= ~(CSIZE);
+ t.c_cflag |= CS6;
+ break;
+ case 7:
+ t.c_cflag &= ~(CSIZE);
+ t.c_cflag |= CS7;
+ break;
+ case 8:
+ t.c_cflag &= ~(CSIZE);
+ t.c_cflag |= CS8;
+ break;
+ default:
+ xf86Msg (X_ERROR,
+ "Invalid Option DataBits value: %d\n", val);
+ return (-1);
+ break;
+ }
+ }
+
+ if ((s = xf86SetStrOption (options, "Parity", NULL)))
+ {
+ if (xf86NameCmp (s, "Odd") == 0)
+ {
+ t.c_cflag |= PARENB | PARODD;
+ }
+ else if (xf86NameCmp (s, "Even") == 0)
+ {
+ t.c_cflag |= PARENB;
+ t.c_cflag &= ~(PARODD);
+ }
+ else if (xf86NameCmp (s, "None") == 0)
+ {
+ t.c_cflag &= ~(PARENB);
+ }
+ else
+ {
+ xf86Msg (X_ERROR, "Invalid Option Parity value: %s\n",
+ s);
+ return (-1);
+ }
+ }
+
+ if ((val = xf86SetIntOption (options, "Vmin", -1)) != -1)
+ {
+ t.c_cc[VMIN] = val;
+ }
+ if ((val = xf86SetIntOption (options, "Vtime", -1)) != -1)
+ {
+ t.c_cc[VTIME] = val;
+ }
+
+ if ((s = xf86SetStrOption (options, "FlowControl", NULL)))
+ {
+ xf86MarkOptionUsedByName (options, "FlowControl");
+ if (xf86NameCmp (s, "Xoff") == 0)
+ {
+ t.c_iflag |= IXOFF;
+ }
+ else if (xf86NameCmp (s, "Xon") == 0)
+ {
+ t.c_iflag |= IXON;
+ }
+ else if (xf86NameCmp (s, "XonXoff") == 0)
+ {
+ t.c_iflag |= IXON|IXOFF;
+ }
+ else if (xf86NameCmp (s, "None") == 0)
+ {
+ t.c_iflag &= ~(IXON | IXOFF);
+ }
+ else
+ {
+ xf86Msg (X_ERROR,
+ "Invalid Option FlowControl value: %s\n", s);
+ return (-1);
+ }
+ }
+
+ if ((xf86SetBoolOption (options, "ClearDTR", FALSE)))
+ {
+#ifdef CLEARDTR_SUPPORT
+# if defined(TIOCMBIC)
+ val = TIOCM_DTR;
+ SYSCALL (ioctl(fd, TIOCMBIC, &val));
+# else
+ SYSCALL (ioctl(fd, TIOCCDTR, NULL));
+# endif
+#else
+ xf86Msg (X_WARNING,
+ "Option ClearDTR not supported on this OS\n");
+ return (-1);
+#endif
+ xf86MarkOptionUsedByName (options, "ClearDTR");
+ }
+
+ if ((xf86SetBoolOption (options, "ClearRTS", FALSE)))
+ {
+ xf86Msg (X_WARNING,
+ "Option ClearRTS not supported on this OS\n");
+ return (-1);
+ xf86MarkOptionUsedByName (options, "ClearRTS");
+ }
+
+ SYSCALL (r = tcsetattr (fd, TCSANOW, &t));
+ return (r);
+}
+
+int
+xf86SetSerialSpeed (int fd, int speed)
+{
+ struct termios t;
+ int baud, r;
+
+ if (fd < 0)
+ return -1;
+
+ /* Don't try to set parameters for non-tty devices. */
+ if (!isatty(fd))
+ return 0;
+
+ SYSCALL (tcgetattr (fd, &t));
+
+ if ((baud = GetBaud (speed)))
+ {
+ cfsetispeed (&t, baud);
+ cfsetospeed (&t, baud);
+ }
+ else
+ {
+ xf86Msg (X_ERROR,
+ "Invalid Option BaudRate value: %d\n", speed);
+ return (-1);
+ }
+
+ SYSCALL (r = tcsetattr (fd, TCSANOW, &t));
+ return (r);
+}
+
+int
+xf86ReadSerial (int fd, void *buf, int count)
+{
+ int r;
+ int i;
+
+ SYSCALL (r = read (fd, buf, count));
+ DebugF("ReadingSerial: 0x%x",
+ (unsigned char)*(((unsigned char *)buf)));
+ for (i = 1; i < r; i++)
+ DebugF(", 0x%x",(unsigned char)*(((unsigned char *)buf) + i));
+ DebugF("\n");
+ return (r);
+}
+
+int
+xf86WriteSerial (int fd, const void *buf, int count)
+{
+ int r;
+ int i;
+
+ DebugF("WritingSerial: 0x%x",(unsigned char)*(((unsigned char *)buf)));
+ for (i = 1; i < count; i++)
+ ErrorF(", 0x%x",(unsigned char)*(((unsigned char *)buf) + i));
+ DebugF("\n");
+ SYSCALL (r = write (fd, buf, count));
+ return (r);
+}
+
+int
+xf86CloseSerial (int fd)
+{
+ int r;
+
+ SYSCALL (r = close (fd));
+ return (r);
+}
+
+int
+xf86WaitForInput (int fd, int timeout)
+{
+ fd_set readfds;
+ struct timeval to;
+ int r;
+
+ FD_ZERO(&readfds);
+
+ if (fd >= 0) {
+ FD_SET(fd, &readfds);
+ }
+
+ to.tv_sec = timeout / 1000000;
+ to.tv_usec = timeout % 1000000;
+
+ if (fd >= 0) {
+ SYSCALL (r = select (FD_SETSIZE, &readfds, NULL, NULL, &to));
+ }
+ else {
+ SYSCALL (r = select (FD_SETSIZE, NULL, NULL, NULL, &to));
+ }
+ xf86ErrorFVerb (9,"select returned %d\n", r);
+ return (r);
+}
+
+int
+xf86SerialSendBreak (int fd, int duration)
+{
+ int r;
+
+ SYSCALL (r = tcsendbreak (fd, duration));
+ return (r);
+
+}
+
+int
+xf86FlushInput(int fd)
+{
+ fd_set fds;
+ struct timeval timeout;
+ char c[4];
+
+ DebugF("FlushingSerial\n");
+ if (tcflush(fd, TCIFLUSH) == 0)
+ return 0;
+
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+ FD_ZERO(&fds);
+ FD_SET(fd, &fds);
+ while (select(FD_SETSIZE, &fds, NULL, NULL, &timeout) > 0) {
+ if (read(fd, &c, sizeof(c)) < 1)
+ return 0;
+ FD_ZERO(&fds);
+ FD_SET(fd, &fds);
+ }
+ return 0;
+}
+
+static struct states {
+ int xf;
+ int os;
+} modemStates[] = {
+#ifdef TIOCM_LE
+ { XF86_M_LE, TIOCM_LE },
+#endif
+#ifdef TIOCM_DTR
+ { XF86_M_DTR, TIOCM_DTR },
+#endif
+#ifdef TIOCM_RTS
+ { XF86_M_RTS, TIOCM_RTS },
+#endif
+#ifdef TIOCM_ST
+ { XF86_M_ST, TIOCM_ST },
+#endif
+#ifdef TIOCM_SR
+ { XF86_M_SR, TIOCM_SR },
+#endif
+#ifdef TIOCM_CTS
+ { XF86_M_CTS, TIOCM_CTS },
+#endif
+#ifdef TIOCM_CAR
+ { XF86_M_CAR, TIOCM_CAR },
+#elif defined(TIOCM_CD)
+ { XF86_M_CAR, TIOCM_CD },
+#endif
+#ifdef TIOCM_RNG
+ { XF86_M_RNG, TIOCM_RNG },
+#elif defined(TIOCM_RI)
+ { XF86_M_CAR, TIOCM_RI },
+#endif
+#ifdef TIOCM_DSR
+ { XF86_M_DSR, TIOCM_DSR },
+#endif
+};
+
+static int numStates = sizeof(modemStates) / sizeof(modemStates[0]);
+
+static int
+xf2osState(int state)
+{
+ int i;
+ int ret = 0;
+
+ for (i = 0; i < numStates; i++)
+ if (state & modemStates[i].xf)
+ ret |= modemStates[i].os;
+ return ret;
+}
+
+static int
+os2xfState(int state)
+{
+ int i;
+ int ret = 0;
+
+ for (i = 0; i < numStates; i++)
+ if (state & modemStates[i].os)
+ ret |= modemStates[i].xf;
+ return ret;
+}
+
+static int
+getOsStateMask(void)
+{
+ int i;
+ int ret = 0;
+ for (i = 0; i < numStates; i++)
+ ret |= modemStates[i].os;
+ return ret;
+}
+
+static int osStateMask = 0;
+
+int
+xf86SetSerialModemState(int fd, int state)
+{
+ int ret;
+ int s;
+
+ if (fd < 0)
+ return -1;
+
+ /* Don't try to set parameters for non-tty devices. */
+ if (!isatty(fd))
+ return 0;
+
+#ifndef TIOCMGET
+ return -1;
+#else
+ if (!osStateMask)
+ osStateMask = getOsStateMask();
+
+ state = xf2osState(state);
+ SYSCALL((ret = ioctl(fd, TIOCMGET, &s)));
+ if (ret < 0)
+ return -1;
+ s &= ~osStateMask;
+ s |= state;
+ SYSCALL((ret = ioctl(fd, TIOCMSET, &s)));
+ if (ret < 0)
+ return -1;
+ else
+ return 0;
+#endif
+}
+
+int
+xf86GetSerialModemState(int fd)
+{
+ int ret;
+ int s;
+
+ if (fd < 0)
+ return -1;
+
+ /* Don't try to set parameters for non-tty devices. */
+ if (!isatty(fd))
+ return 0;
+
+#ifndef TIOCMGET
+ return -1;
+#else
+ SYSCALL((ret = ioctl(fd, TIOCMGET, &s)));
+ if (ret < 0)
+ return -1;
+ return os2xfState(s);
+#endif
+}
+
+int
+xf86SerialModemSetBits(int fd, int bits)
+{
+ int ret;
+ int s;
+
+ if (fd < 0)
+ return -1;
+
+ /* Don't try to set parameters for non-tty devices. */
+ if (!isatty(fd))
+ return 0;
+
+#ifndef TIOCMGET
+ return -1;
+#else
+ s = xf2osState(bits);
+ SYSCALL((ret = ioctl(fd, TIOCMBIS, &s)));
+ return ret;
+#endif
+}
+
+int
+xf86SerialModemClearBits(int fd, int bits)
+{
+ int ret;
+ int s;
+
+ if (fd < 0)
+ return -1;
+
+ /* Don't try to set parameters for non-tty devices. */
+ if (!isatty(fd))
+ return 0;
+
+#ifndef TIOCMGET
+ return -1;
+#else
+ s = xf2osState(bits);
+ SYSCALL((ret = ioctl(fd, TIOCMBIC, &s)));
+ return ret;
+#endif
+}
diff --git a/xorg-server/hw/xfree86/os-support/shared/vidmem.c b/xorg-server/hw/xfree86/os-support/shared/vidmem.c
index 803ce09bd..6358138d8 100644
--- a/xorg-server/hw/xfree86/os-support/shared/vidmem.c
+++ b/xorg-server/hw/xfree86/os-support/shared/vidmem.c
@@ -1,296 +1,296 @@
-/*
- * Copyright (c) 1993-2003 by The XFree86 Project, Inc.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
- * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
- * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- * OTHER DEALINGS IN THE SOFTWARE.
- *
- * Except as contained in this notice, the name of the copyright holder(s)
- * and author(s) shall not be used in advertising or otherwise to promote
- * the sale, use or other dealings in this Software without prior written
- * authorization from the copyright holder(s) and author(s).
- */
-
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <X11/X.h>
-#include "input.h"
-#include "scrnintstr.h"
-
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86_OSlib.h"
-#include "xf86OSpriv.h"
-
-/*
- * This file contains the common part of the video memory mapping functions
- */
-
-/*
- * Get a piece of the ScrnInfoRec. At the moment, this is only used to hold
- * the MTRR option information, but it is likely to be expanded if we do
- * auto unmapping of memory at VT switch.
- *
- */
-
-typedef struct {
- unsigned long physBase;
- unsigned long size;
- pointer virtBase;
- pointer mtrrInfo;
- int flags;
-} MappingRec, *MappingPtr;
-
-typedef struct {
- int numMappings;
- MappingPtr * mappings;
- Bool mtrrEnabled;
- MessageType mtrrFrom;
- Bool mtrrOptChecked;
- ScrnInfoPtr pScrn;
-} VidMapRec, *VidMapPtr;
-
-static int vidMapIndex = -1;
-
-#define VIDMAPPTR(p) ((VidMapPtr)((p)->privates[vidMapIndex].ptr))
-
-static VidMemInfo vidMemInfo = {FALSE, };
-static VidMapRec vidMapRec = {0, NULL, TRUE, X_DEFAULT, FALSE, NULL};
-
-static VidMapPtr
-getVidMapRec(int scrnIndex)
-{
- VidMapPtr vp;
- ScrnInfoPtr pScrn;
-
- if ((scrnIndex < 0) ||
- !(pScrn = xf86Screens[scrnIndex]))
- return &vidMapRec;
-
- if (vidMapIndex < 0)
- vidMapIndex = xf86AllocateScrnInfoPrivateIndex();
-
- if (VIDMAPPTR(pScrn) != NULL)
- return VIDMAPPTR(pScrn);
-
- vp = pScrn->privates[vidMapIndex].ptr = xnfcalloc(sizeof(VidMapRec), 1);
- vp->mtrrEnabled = TRUE; /* default to enabled */
- vp->mtrrFrom = X_DEFAULT;
- vp->mtrrOptChecked = FALSE;
- vp->pScrn = pScrn;
- return vp;
-}
-
-static MappingPtr
-newMapping(VidMapPtr vp)
-{
- vp->mappings = xnfrealloc(vp->mappings, sizeof(MappingPtr) *
- (vp->numMappings + 1));
- vp->mappings[vp->numMappings] = xnfcalloc(sizeof(MappingRec), 1);
- return vp->mappings[vp->numMappings++];
-}
-
-static MappingPtr
-findMapping(VidMapPtr vp, pointer vbase, unsigned long size)
-{
- int i;
-
- for (i = 0; i < vp->numMappings; i++) {
- if (vp->mappings[i]->virtBase == vbase &&
- vp->mappings[i]->size == size)
- return vp->mappings[i];
- }
- return NULL;
-}
-
-static void
-removeMapping(VidMapPtr vp, MappingPtr mp)
-{
- int i, found = 0;
-
- for (i = 0; i < vp->numMappings; i++) {
- if (vp->mappings[i] == mp) {
- found = 1;
- xfree(vp->mappings[i]);
- } else if (found) {
- vp->mappings[i - 1] = vp->mappings[i];
- }
- }
- vp->numMappings--;
- vp->mappings[vp->numMappings] = NULL;
-}
-
-enum { OPTION_MTRR };
-static const OptionInfoRec opts[] =
-{
- { OPTION_MTRR, "mtrr", OPTV_BOOLEAN, {0}, FALSE },
- { -1, NULL, OPTV_NONE, {0}, FALSE }
-};
-
-static void
-checkMtrrOption(VidMapPtr vp)
-{
- if (!vp->mtrrOptChecked && vp->pScrn && vp->pScrn->options != NULL) {
- OptionInfoPtr options;
-
- options = xnfalloc(sizeof(opts));
- (void)memcpy(options, opts, sizeof(opts));
- xf86ProcessOptions(vp->pScrn->scrnIndex, vp->pScrn->options,
- options);
- if (xf86GetOptValBool(options, OPTION_MTRR, &vp->mtrrEnabled))
- vp->mtrrFrom = X_CONFIG;
- xfree(options);
- vp->mtrrOptChecked = TRUE;
- }
-}
-
-void
-xf86MakeNewMapping(int ScreenNum, int Flags, unsigned long Base, unsigned long Size, pointer Vbase)
-{
- VidMapPtr vp;
- MappingPtr mp;
-
- vp = getVidMapRec(ScreenNum);
- mp = newMapping(vp);
- mp->physBase = Base;
- mp->size = Size;
- mp->virtBase = Vbase;
- mp->flags = Flags;
-}
-
-void
-xf86InitVidMem(void)
-{
- if (!vidMemInfo.initialised) {
- memset(&vidMemInfo, 0, sizeof(VidMemInfo));
- xf86OSInitVidMem(&vidMemInfo);
- }
-}
-
-pointer
-xf86MapVidMem(int ScreenNum, int Flags, unsigned long Base, unsigned long Size)
-{
- pointer vbase = NULL;
- VidMapPtr vp;
- MappingPtr mp;
-
- if (((Flags & VIDMEM_FRAMEBUFFER) &&
- (Flags & (VIDMEM_MMIO | VIDMEM_MMIO_32BIT))))
- FatalError("Mapping memory with more than one type\n");
-
- xf86InitVidMem();
- if (!vidMemInfo.initialised || !vidMemInfo.mapMem)
- return NULL;
-
- vbase = vidMemInfo.mapMem(ScreenNum, Base, Size, Flags);
-
- if (!vbase || vbase == (pointer)-1)
- return NULL;
-
- vp = getVidMapRec(ScreenNum);
- mp = newMapping(vp);
- mp->physBase = Base;
- mp->size = Size;
- mp->virtBase = vbase;
- mp->flags = Flags;
-
- /*
- * Check the "mtrr" option even when MTRR isn't supported to avoid
- * warnings about unrecognised options.
- */
- checkMtrrOption(vp);
-
- if (vp->mtrrEnabled && vidMemInfo.setWC) {
- if (Flags & (VIDMEM_MMIO | VIDMEM_MMIO_32BIT))
- mp->mtrrInfo =
- vidMemInfo.setWC(ScreenNum, Base, Size, FALSE,
- vp->mtrrFrom);
- else if (Flags & VIDMEM_FRAMEBUFFER)
- mp->mtrrInfo =
- vidMemInfo.setWC(ScreenNum, Base, Size, TRUE,
- vp->mtrrFrom);
- }
- return vbase;
-}
-
-void
-xf86UnMapVidMem(int ScreenNum, pointer Base, unsigned long Size)
-{
- VidMapPtr vp;
- MappingPtr mp;
-
- if (!vidMemInfo.initialised || !vidMemInfo.unmapMem) {
- xf86DrvMsg(ScreenNum, X_WARNING,
- "xf86UnMapVidMem() called before xf86MapVidMem()\n");
- return;
- }
-
- vp = getVidMapRec(ScreenNum);
- mp = findMapping(vp, Base, Size);
- if (!mp) {
- xf86DrvMsg(ScreenNum, X_WARNING,
- "xf86UnMapVidMem: cannot find region for [%p,0x%lx]\n",
- Base, Size);
- return;
- }
- if (vp->mtrrEnabled && vidMemInfo.undoWC && mp)
- vidMemInfo.undoWC(ScreenNum, mp->mtrrInfo);
-
- vidMemInfo.unmapMem(ScreenNum, Base, Size);
- removeMapping(vp, mp);
-}
-
-Bool
-xf86CheckMTRR(int ScreenNum)
-{
- VidMapPtr vp = getVidMapRec(ScreenNum);
-
- /*
- * Check the "mtrr" option even when MTRR isn't supported to avoid
- * warnings about unrecognised options.
- */
- checkMtrrOption(vp);
-
- if (vp->mtrrEnabled && vidMemInfo.setWC)
- return TRUE;
-
- return FALSE;
-}
-
-Bool
-xf86LinearVidMem(void)
-{
- xf86InitVidMem();
- return vidMemInfo.linearSupported;
-}
-
-void
-xf86MapReadSideEffects(int ScreenNum, int Flags, pointer base,
- unsigned long Size)
-{
- if (!(Flags & VIDMEM_READSIDEEFFECT))
- return;
-
- if (!vidMemInfo.initialised || !vidMemInfo.readSideEffects)
- return;
-
- vidMemInfo.readSideEffects(ScreenNum, base, Size);
-}
-
+/*
+ * Copyright (c) 1993-2003 by The XFree86 Project, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of the copyright holder(s)
+ * and author(s) shall not be used in advertising or otherwise to promote
+ * the sale, use or other dealings in this Software without prior written
+ * authorization from the copyright holder(s) and author(s).
+ */
+
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <X11/X.h>
+#include "input.h"
+#include "scrnintstr.h"
+
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "xf86OSpriv.h"
+
+/*
+ * This file contains the common part of the video memory mapping functions
+ */
+
+/*
+ * Get a piece of the ScrnInfoRec. At the moment, this is only used to hold
+ * the MTRR option information, but it is likely to be expanded if we do
+ * auto unmapping of memory at VT switch.
+ *
+ */
+
+typedef struct {
+ unsigned long physBase;
+ unsigned long size;
+ pointer virtBase;
+ pointer mtrrInfo;
+ int flags;
+} MappingRec, *MappingPtr;
+
+typedef struct {
+ int numMappings;
+ MappingPtr * mappings;
+ Bool mtrrEnabled;
+ MessageType mtrrFrom;
+ Bool mtrrOptChecked;
+ ScrnInfoPtr pScrn;
+} VidMapRec, *VidMapPtr;
+
+static int vidMapIndex = -1;
+
+#define VIDMAPPTR(p) ((VidMapPtr)((p)->privates[vidMapIndex].ptr))
+
+static VidMemInfo vidMemInfo = {FALSE, };
+static VidMapRec vidMapRec = {0, NULL, TRUE, X_DEFAULT, FALSE, NULL};
+
+static VidMapPtr
+getVidMapRec(int scrnIndex)
+{
+ VidMapPtr vp;
+ ScrnInfoPtr pScrn;
+
+ if ((scrnIndex < 0) ||
+ !(pScrn = xf86Screens[scrnIndex]))
+ return &vidMapRec;
+
+ if (vidMapIndex < 0)
+ vidMapIndex = xf86AllocateScrnInfoPrivateIndex();
+
+ if (VIDMAPPTR(pScrn) != NULL)
+ return VIDMAPPTR(pScrn);
+
+ vp = pScrn->privates[vidMapIndex].ptr = xnfcalloc(sizeof(VidMapRec), 1);
+ vp->mtrrEnabled = TRUE; /* default to enabled */
+ vp->mtrrFrom = X_DEFAULT;
+ vp->mtrrOptChecked = FALSE;
+ vp->pScrn = pScrn;
+ return vp;
+}
+
+static MappingPtr
+newMapping(VidMapPtr vp)
+{
+ vp->mappings = xnfrealloc(vp->mappings, sizeof(MappingPtr) *
+ (vp->numMappings + 1));
+ vp->mappings[vp->numMappings] = xnfcalloc(sizeof(MappingRec), 1);
+ return vp->mappings[vp->numMappings++];
+}
+
+static MappingPtr
+findMapping(VidMapPtr vp, pointer vbase, unsigned long size)
+{
+ int i;
+
+ for (i = 0; i < vp->numMappings; i++) {
+ if (vp->mappings[i]->virtBase == vbase &&
+ vp->mappings[i]->size == size)
+ return vp->mappings[i];
+ }
+ return NULL;
+}
+
+static void
+removeMapping(VidMapPtr vp, MappingPtr mp)
+{
+ int i, found = 0;
+
+ for (i = 0; i < vp->numMappings; i++) {
+ if (vp->mappings[i] == mp) {
+ found = 1;
+ free(vp->mappings[i]);
+ } else if (found) {
+ vp->mappings[i - 1] = vp->mappings[i];
+ }
+ }
+ vp->numMappings--;
+ vp->mappings[vp->numMappings] = NULL;
+}
+
+enum { OPTION_MTRR };
+static const OptionInfoRec opts[] =
+{
+ { OPTION_MTRR, "mtrr", OPTV_BOOLEAN, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
+static void
+checkMtrrOption(VidMapPtr vp)
+{
+ if (!vp->mtrrOptChecked && vp->pScrn && vp->pScrn->options != NULL) {
+ OptionInfoPtr options;
+
+ options = xnfalloc(sizeof(opts));
+ (void)memcpy(options, opts, sizeof(opts));
+ xf86ProcessOptions(vp->pScrn->scrnIndex, vp->pScrn->options,
+ options);
+ if (xf86GetOptValBool(options, OPTION_MTRR, &vp->mtrrEnabled))
+ vp->mtrrFrom = X_CONFIG;
+ free(options);
+ vp->mtrrOptChecked = TRUE;
+ }
+}
+
+void
+xf86MakeNewMapping(int ScreenNum, int Flags, unsigned long Base, unsigned long Size, pointer Vbase)
+{
+ VidMapPtr vp;
+ MappingPtr mp;
+
+ vp = getVidMapRec(ScreenNum);
+ mp = newMapping(vp);
+ mp->physBase = Base;
+ mp->size = Size;
+ mp->virtBase = Vbase;
+ mp->flags = Flags;
+}
+
+void
+xf86InitVidMem(void)
+{
+ if (!vidMemInfo.initialised) {
+ memset(&vidMemInfo, 0, sizeof(VidMemInfo));
+ xf86OSInitVidMem(&vidMemInfo);
+ }
+}
+
+pointer
+xf86MapVidMem(int ScreenNum, int Flags, unsigned long Base, unsigned long Size)
+{
+ pointer vbase = NULL;
+ VidMapPtr vp;
+ MappingPtr mp;
+
+ if (((Flags & VIDMEM_FRAMEBUFFER) &&
+ (Flags & (VIDMEM_MMIO | VIDMEM_MMIO_32BIT))))
+ FatalError("Mapping memory with more than one type\n");
+
+ xf86InitVidMem();
+ if (!vidMemInfo.initialised || !vidMemInfo.mapMem)
+ return NULL;
+
+ vbase = vidMemInfo.mapMem(ScreenNum, Base, Size, Flags);
+
+ if (!vbase || vbase == (pointer)-1)
+ return NULL;
+
+ vp = getVidMapRec(ScreenNum);
+ mp = newMapping(vp);
+ mp->physBase = Base;
+ mp->size = Size;
+ mp->virtBase = vbase;
+ mp->flags = Flags;
+
+ /*
+ * Check the "mtrr" option even when MTRR isn't supported to avoid
+ * warnings about unrecognised options.
+ */
+ checkMtrrOption(vp);
+
+ if (vp->mtrrEnabled && vidMemInfo.setWC) {
+ if (Flags & (VIDMEM_MMIO | VIDMEM_MMIO_32BIT))
+ mp->mtrrInfo =
+ vidMemInfo.setWC(ScreenNum, Base, Size, FALSE,
+ vp->mtrrFrom);
+ else if (Flags & VIDMEM_FRAMEBUFFER)
+ mp->mtrrInfo =
+ vidMemInfo.setWC(ScreenNum, Base, Size, TRUE,
+ vp->mtrrFrom);
+ }
+ return vbase;
+}
+
+void
+xf86UnMapVidMem(int ScreenNum, pointer Base, unsigned long Size)
+{
+ VidMapPtr vp;
+ MappingPtr mp;
+
+ if (!vidMemInfo.initialised || !vidMemInfo.unmapMem) {
+ xf86DrvMsg(ScreenNum, X_WARNING,
+ "xf86UnMapVidMem() called before xf86MapVidMem()\n");
+ return;
+ }
+
+ vp = getVidMapRec(ScreenNum);
+ mp = findMapping(vp, Base, Size);
+ if (!mp) {
+ xf86DrvMsg(ScreenNum, X_WARNING,
+ "xf86UnMapVidMem: cannot find region for [%p,0x%lx]\n",
+ Base, Size);
+ return;
+ }
+ if (vp->mtrrEnabled && vidMemInfo.undoWC && mp)
+ vidMemInfo.undoWC(ScreenNum, mp->mtrrInfo);
+
+ vidMemInfo.unmapMem(ScreenNum, Base, Size);
+ removeMapping(vp, mp);
+}
+
+Bool
+xf86CheckMTRR(int ScreenNum)
+{
+ VidMapPtr vp = getVidMapRec(ScreenNum);
+
+ /*
+ * Check the "mtrr" option even when MTRR isn't supported to avoid
+ * warnings about unrecognised options.
+ */
+ checkMtrrOption(vp);
+
+ if (vp->mtrrEnabled && vidMemInfo.setWC)
+ return TRUE;
+
+ return FALSE;
+}
+
+Bool
+xf86LinearVidMem(void)
+{
+ xf86InitVidMem();
+ return vidMemInfo.linearSupported;
+}
+
+void
+xf86MapReadSideEffects(int ScreenNum, int Flags, pointer base,
+ unsigned long Size)
+{
+ if (!(Flags & VIDMEM_READSIDEEFFECT))
+ return;
+
+ if (!vidMemInfo.initialised || !vidMemInfo.readSideEffects)
+ return;
+
+ vidMemInfo.readSideEffects(ScreenNum, base, Size);
+}
+
diff --git a/xorg-server/hw/xfree86/os-support/solaris/sun_agp.c b/xorg-server/hw/xfree86/os-support/solaris/sun_agp.c
index e6a55a48b..a5fb5c6e6 100644
--- a/xorg-server/hw/xfree86/os-support/solaris/sun_agp.c
+++ b/xorg-server/hw/xfree86/os-support/solaris/sun_agp.c
@@ -1,327 +1,327 @@
-/*
- * Abstraction of the AGP GART interface.
- *
- * This version is for Solaris.
- *
- * Copyright © 2000 VA Linux Systems, Inc.
- * Copyright © 2001 The XFree86 Project, Inc.
- */
-/* Copyright 2005 Sun Microsystems, 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 (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <X11/X.h>
-#include "xf86.h"
-#include "xf86Priv.h"
-#include "xf86_OSlib.h"
-#include "xf86_OSproc.h"
-#include <unistd.h>
-#include <sys/ioccom.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <sys/agpgart.h>
-
-/* AGP page size is independent of the host page size. */
-#ifndef AGP_PAGE_SIZE
-#define AGP_PAGE_SIZE 4096
-#endif
-
-static int gartFd = -1;
-static int acquiredScreen = -1;
-static Bool initDone = FALSE;
-/*
- * Close /dev/agpgart. This frees all associated memory allocated during
- * this server generation.
- */
-Bool
-xf86GARTCloseScreen(int screenNum)
-{
- if (gartFd != -1) {
- close(gartFd);
- acquiredScreen = -1;
- gartFd = -1;
- initDone = FALSE;
-
- xf86DrvMsg(screenNum, X_INFO,
- "xf86GARTCloseScreen: device closed successfully\n");
-
- }
- return TRUE;
-}
-
-/*
- * Open /dev/agpgart. Keep it open until xf86GARTCloseScreen is called.
- */
-static Bool
-GARTInit(int screenNum)
-{
- if (initDone)
- return (gartFd != -1);
-
- if (gartFd == -1)
- gartFd = open(AGP_DEVICE, O_RDWR);
- else
- return FALSE;
-
- if (gartFd == -1) {
- xf86DrvMsg(screenNum, X_ERROR,
- "GARTInit: Unable to open " AGP_DEVICE " (%s)\n",
- strerror(errno));
- return FALSE;
- }
-
- initDone = TRUE;
- xf86DrvMsg(screenNum, X_INFO,
- "GARTInit: " AGP_DEVICE " opened successfully\n");
-
- return TRUE;
-}
-
-Bool
-xf86AgpGARTSupported(void)
-{
- return (GARTInit(-1));
-
-}
-
-AgpInfoPtr
-xf86GetAGPInfo(int screenNum)
-{
- agp_info_t agpinf;
- AgpInfoPtr info;
-
- if (!GARTInit(screenNum))
- return NULL;
-
- if ((info = xcalloc(sizeof(AgpInfo), 1)) == NULL) {
- xf86DrvMsg(screenNum, X_ERROR,
- "xf86GetAGPInfo: Failed to allocate AgpInfo\n");
- return NULL;
- }
-
- if (ioctl(gartFd, AGPIOC_INFO, &agpinf) != 0) {
- xf86DrvMsg(screenNum, X_ERROR,
- "xf86GetAGPInfo: AGPIOC_INFO failed (%s)\n",
- strerror(errno));
- return NULL;
- }
-
- info->bridgeId = agpinf.agpi_devid;
- info->agpMode = agpinf.agpi_mode;
- info->base = agpinf.agpi_aperbase;
- info->size = agpinf.agpi_apersize;
- info->totalPages = (unsigned long)agpinf.agpi_pgtotal;
- info->systemPages = (unsigned long)agpinf.agpi_pgsystem;
- info->usedPages = (unsigned long)agpinf.agpi_pgused;
-
- return info;
-}
-
-Bool
-xf86AcquireGART(int screenNum)
-{
-
- if (!GARTInit(screenNum))
- return FALSE;
-
- if (acquiredScreen != screenNum) {
- if (ioctl(gartFd, AGPIOC_ACQUIRE, 0) != 0) {
- xf86DrvMsg(screenNum, X_WARNING,
- "xf86AcquireGART: AGPIOC_ACQUIRE failed (%s)\n",
- strerror(errno));
- return FALSE;
- }
- acquiredScreen = screenNum;
- xf86DrvMsg(screenNum, X_INFO,
- "xf86AcquireGART: AGPIOC_ACQUIRE succeeded\n");
- }
- return TRUE;
-}
-
-Bool
-xf86ReleaseGART(int screenNum)
-{
-
- if (!GARTInit(screenNum))
- return FALSE;
-
- if (acquiredScreen == screenNum) {
- /*
- * The FreeBSD agp driver removes allocations on release.
- * The Solaris driver doesn't. xf86ReleaseGART() is expected
- * to give up access to the GART, but not to remove any
- * allocations.
- */
-
- if (ioctl(gartFd, AGPIOC_RELEASE, 0) != 0) {
- xf86DrvMsg(screenNum, X_WARNING,
- "xf86ReleaseGART: AGPIOC_RELEASE failed (%s)\n",
- strerror(errno));
- return FALSE;
- }
- acquiredScreen = -1;
- xf86DrvMsg(screenNum, X_INFO,
- "xf86ReleaseGART: AGPIOC_RELEASE succeeded\n");
- return TRUE;
- }
- return FALSE;
-}
-
-int
-xf86AllocateGARTMemory(int screenNum, unsigned long size, int type,
- unsigned long *physical)
-{
- agp_allocate_t alloc;
- int pages;
-
- /*
- * Allocates "size" bytes of GART memory (rounds up to the next
- * page multiple) or type "type". A handle (key) for the allocated
- * memory is returned. On error, the return value is -1.
- * "size" should be larger than 0, or AGPIOC_ALLOCATE ioctl will
- * return error.
- */
-
- if (!GARTInit(screenNum) || (acquiredScreen != screenNum))
- return -1;
-
- pages = (size / AGP_PAGE_SIZE);
- if (size % AGP_PAGE_SIZE != 0)
- pages++;
-
- alloc.agpa_pgcount = pages;
- alloc.agpa_type = type;
-
- if (ioctl(gartFd, AGPIOC_ALLOCATE, &alloc) != 0) {
- xf86DrvMsg(screenNum, X_WARNING, "xf86AllocateGARTMemory: "
- "allocation of %d pages failed\n\t(%s)\n", pages,
- strerror(errno));
- return -1;
- }
-
- if (physical)
- *physical = (unsigned long)alloc.agpa_physical;
-
- return alloc.agpa_key;
-}
-
-Bool
-xf86DeallocateGARTMemory(int screenNum, int key)
-{
- if (!GARTInit(screenNum) || (acquiredScreen != screenNum))
- return FALSE;
-
- if (ioctl(gartFd, AGPIOC_DEALLOCATE, (int *)key) != 0) {
- xf86DrvMsg(screenNum, X_WARNING, "xf86DeAllocateGARTMemory: "
- "deallocation of gart memory with key %d failed\n"
- "\t(%s)\n", key, strerror(errno));
- return FALSE;
- }
-
- return TRUE;
-}
-
-/* Bind GART memory with "key" at "offset" */
-Bool
-xf86BindGARTMemory(int screenNum, int key, unsigned long offset)
-{
- agp_bind_t bind;
- int pageOffset;
-
- if (!GARTInit(screenNum) || (acquiredScreen != screenNum))
- return FALSE;
-
- if (offset % AGP_PAGE_SIZE != 0) {
- xf86DrvMsg(screenNum, X_WARNING, "xf86BindGARTMemory: "
- "offset (0x%lx) is not page-aligned (%d)\n",
- offset, AGP_PAGE_SIZE);
- return FALSE;
- }
- pageOffset = offset / AGP_PAGE_SIZE;
-
- xf86DrvMsgVerb(screenNum, X_INFO, 3,
- "xf86BindGARTMemory: bind key %d at 0x%08lx "
- "(pgoffset %d)\n", key, offset, pageOffset);
-
- bind.agpb_pgstart = pageOffset;
- bind.agpb_key = key;
-
- if (ioctl(gartFd, AGPIOC_BIND, &bind) != 0) {
- xf86DrvMsg(screenNum, X_WARNING, "xf86BindGARTMemory: "
- "binding of gart memory with key %d\n"
- "\tat offset 0x%lx failed (%s)\n",
- key, offset, strerror(errno));
- return FALSE;
- }
-
- return TRUE;
-}
-
-/* Unbind GART memory with "key" */
-Bool
-xf86UnbindGARTMemory(int screenNum, int key)
-{
- agp_unbind_t unbind;
-
- if (!GARTInit(screenNum) || (acquiredScreen != screenNum))
- return FALSE;
-
- unbind.agpu_pri = 0;
- unbind.agpu_key = key;
-
- if (ioctl(gartFd, AGPIOC_UNBIND, &unbind) != 0) {
- xf86DrvMsg(screenNum, X_WARNING, "xf86UnbindGARTMemory: "
- "unbinding of gart memory with key %d "
- "failed (%s)\n", key, strerror(errno));
- return FALSE;
- }
-
- xf86DrvMsgVerb(screenNum, X_INFO, 3,
- "xf86UnbindGARTMemory: unbind key %d\n", key);
-
- return TRUE;
-}
-
-
-/* XXX Interface may change. */
-Bool
-xf86EnableAGP(int screenNum, CARD32 mode)
-{
- agp_setup_t setup;
-
- if (!GARTInit(screenNum) || (acquiredScreen != screenNum))
- return FALSE;
-
- setup.agps_mode = mode;
- if (ioctl(gartFd, AGPIOC_SETUP, &setup) != 0) {
- xf86DrvMsg(screenNum, X_WARNING, "xf86EnableAGP: "
- "AGPIOC_SETUP with mode %x failed (%s)\n",
- mode, strerror(errno));
- return FALSE;
- }
-
- return TRUE;
-}
-
+/*
+ * Abstraction of the AGP GART interface.
+ *
+ * This version is for Solaris.
+ *
+ * Copyright © 2000 VA Linux Systems, Inc.
+ * Copyright © 2001 The XFree86 Project, Inc.
+ */
+/* Copyright 2005 Sun Microsystems, 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 (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <X11/X.h>
+#include "xf86.h"
+#include "xf86Priv.h"
+#include "xf86_OSlib.h"
+#include "xf86_OSproc.h"
+#include <unistd.h>
+#include <sys/ioccom.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/agpgart.h>
+
+/* AGP page size is independent of the host page size. */
+#ifndef AGP_PAGE_SIZE
+#define AGP_PAGE_SIZE 4096
+#endif
+
+static int gartFd = -1;
+static int acquiredScreen = -1;
+static Bool initDone = FALSE;
+/*
+ * Close /dev/agpgart. This frees all associated memory allocated during
+ * this server generation.
+ */
+Bool
+xf86GARTCloseScreen(int screenNum)
+{
+ if (gartFd != -1) {
+ close(gartFd);
+ acquiredScreen = -1;
+ gartFd = -1;
+ initDone = FALSE;
+
+ xf86DrvMsg(screenNum, X_INFO,
+ "xf86GARTCloseScreen: device closed successfully\n");
+
+ }
+ return TRUE;
+}
+
+/*
+ * Open /dev/agpgart. Keep it open until xf86GARTCloseScreen is called.
+ */
+static Bool
+GARTInit(int screenNum)
+{
+ if (initDone)
+ return (gartFd != -1);
+
+ if (gartFd == -1)
+ gartFd = open(AGP_DEVICE, O_RDWR);
+ else
+ return FALSE;
+
+ if (gartFd == -1) {
+ xf86DrvMsg(screenNum, X_ERROR,
+ "GARTInit: Unable to open " AGP_DEVICE " (%s)\n",
+ strerror(errno));
+ return FALSE;
+ }
+
+ initDone = TRUE;
+ xf86DrvMsg(screenNum, X_INFO,
+ "GARTInit: " AGP_DEVICE " opened successfully\n");
+
+ return TRUE;
+}
+
+Bool
+xf86AgpGARTSupported(void)
+{
+ return (GARTInit(-1));
+
+}
+
+AgpInfoPtr
+xf86GetAGPInfo(int screenNum)
+{
+ agp_info_t agpinf;
+ AgpInfoPtr info;
+
+ if (!GARTInit(screenNum))
+ return NULL;
+
+ if ((info = calloc(sizeof(AgpInfo), 1)) == NULL) {
+ xf86DrvMsg(screenNum, X_ERROR,
+ "xf86GetAGPInfo: Failed to allocate AgpInfo\n");
+ return NULL;
+ }
+
+ if (ioctl(gartFd, AGPIOC_INFO, &agpinf) != 0) {
+ xf86DrvMsg(screenNum, X_ERROR,
+ "xf86GetAGPInfo: AGPIOC_INFO failed (%s)\n",
+ strerror(errno));
+ return NULL;
+ }
+
+ info->bridgeId = agpinf.agpi_devid;
+ info->agpMode = agpinf.agpi_mode;
+ info->base = agpinf.agpi_aperbase;
+ info->size = agpinf.agpi_apersize;
+ info->totalPages = (unsigned long)agpinf.agpi_pgtotal;
+ info->systemPages = (unsigned long)agpinf.agpi_pgsystem;
+ info->usedPages = (unsigned long)agpinf.agpi_pgused;
+
+ return info;
+}
+
+Bool
+xf86AcquireGART(int screenNum)
+{
+
+ if (!GARTInit(screenNum))
+ return FALSE;
+
+ if (acquiredScreen != screenNum) {
+ if (ioctl(gartFd, AGPIOC_ACQUIRE, 0) != 0) {
+ xf86DrvMsg(screenNum, X_WARNING,
+ "xf86AcquireGART: AGPIOC_ACQUIRE failed (%s)\n",
+ strerror(errno));
+ return FALSE;
+ }
+ acquiredScreen = screenNum;
+ xf86DrvMsg(screenNum, X_INFO,
+ "xf86AcquireGART: AGPIOC_ACQUIRE succeeded\n");
+ }
+ return TRUE;
+}
+
+Bool
+xf86ReleaseGART(int screenNum)
+{
+
+ if (!GARTInit(screenNum))
+ return FALSE;
+
+ if (acquiredScreen == screenNum) {
+ /*
+ * The FreeBSD agp driver removes allocations on release.
+ * The Solaris driver doesn't. xf86ReleaseGART() is expected
+ * to give up access to the GART, but not to remove any
+ * allocations.
+ */
+
+ if (ioctl(gartFd, AGPIOC_RELEASE, 0) != 0) {
+ xf86DrvMsg(screenNum, X_WARNING,
+ "xf86ReleaseGART: AGPIOC_RELEASE failed (%s)\n",
+ strerror(errno));
+ return FALSE;
+ }
+ acquiredScreen = -1;
+ xf86DrvMsg(screenNum, X_INFO,
+ "xf86ReleaseGART: AGPIOC_RELEASE succeeded\n");
+ return TRUE;
+ }
+ return FALSE;
+}
+
+int
+xf86AllocateGARTMemory(int screenNum, unsigned long size, int type,
+ unsigned long *physical)
+{
+ agp_allocate_t alloc;
+ int pages;
+
+ /*
+ * Allocates "size" bytes of GART memory (rounds up to the next
+ * page multiple) or type "type". A handle (key) for the allocated
+ * memory is returned. On error, the return value is -1.
+ * "size" should be larger than 0, or AGPIOC_ALLOCATE ioctl will
+ * return error.
+ */
+
+ if (!GARTInit(screenNum) || (acquiredScreen != screenNum))
+ return -1;
+
+ pages = (size / AGP_PAGE_SIZE);
+ if (size % AGP_PAGE_SIZE != 0)
+ pages++;
+
+ alloc.agpa_pgcount = pages;
+ alloc.agpa_type = type;
+
+ if (ioctl(gartFd, AGPIOC_ALLOCATE, &alloc) != 0) {
+ xf86DrvMsg(screenNum, X_WARNING, "xf86AllocateGARTMemory: "
+ "allocation of %d pages failed\n\t(%s)\n", pages,
+ strerror(errno));
+ return -1;
+ }
+
+ if (physical)
+ *physical = (unsigned long)alloc.agpa_physical;
+
+ return alloc.agpa_key;
+}
+
+Bool
+xf86DeallocateGARTMemory(int screenNum, int key)
+{
+ if (!GARTInit(screenNum) || (acquiredScreen != screenNum))
+ return FALSE;
+
+ if (ioctl(gartFd, AGPIOC_DEALLOCATE, (int *)key) != 0) {
+ xf86DrvMsg(screenNum, X_WARNING, "xf86DeAllocateGARTMemory: "
+ "deallocation of gart memory with key %d failed\n"
+ "\t(%s)\n", key, strerror(errno));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Bind GART memory with "key" at "offset" */
+Bool
+xf86BindGARTMemory(int screenNum, int key, unsigned long offset)
+{
+ agp_bind_t bind;
+ int pageOffset;
+
+ if (!GARTInit(screenNum) || (acquiredScreen != screenNum))
+ return FALSE;
+
+ if (offset % AGP_PAGE_SIZE != 0) {
+ xf86DrvMsg(screenNum, X_WARNING, "xf86BindGARTMemory: "
+ "offset (0x%lx) is not page-aligned (%d)\n",
+ offset, AGP_PAGE_SIZE);
+ return FALSE;
+ }
+ pageOffset = offset / AGP_PAGE_SIZE;
+
+ xf86DrvMsgVerb(screenNum, X_INFO, 3,
+ "xf86BindGARTMemory: bind key %d at 0x%08lx "
+ "(pgoffset %d)\n", key, offset, pageOffset);
+
+ bind.agpb_pgstart = pageOffset;
+ bind.agpb_key = key;
+
+ if (ioctl(gartFd, AGPIOC_BIND, &bind) != 0) {
+ xf86DrvMsg(screenNum, X_WARNING, "xf86BindGARTMemory: "
+ "binding of gart memory with key %d\n"
+ "\tat offset 0x%lx failed (%s)\n",
+ key, offset, strerror(errno));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* Unbind GART memory with "key" */
+Bool
+xf86UnbindGARTMemory(int screenNum, int key)
+{
+ agp_unbind_t unbind;
+
+ if (!GARTInit(screenNum) || (acquiredScreen != screenNum))
+ return FALSE;
+
+ unbind.agpu_pri = 0;
+ unbind.agpu_key = key;
+
+ if (ioctl(gartFd, AGPIOC_UNBIND, &unbind) != 0) {
+ xf86DrvMsg(screenNum, X_WARNING, "xf86UnbindGARTMemory: "
+ "unbinding of gart memory with key %d "
+ "failed (%s)\n", key, strerror(errno));
+ return FALSE;
+ }
+
+ xf86DrvMsgVerb(screenNum, X_INFO, 3,
+ "xf86UnbindGARTMemory: unbind key %d\n", key);
+
+ return TRUE;
+}
+
+
+/* XXX Interface may change. */
+Bool
+xf86EnableAGP(int screenNum, CARD32 mode)
+{
+ agp_setup_t setup;
+
+ if (!GARTInit(screenNum) || (acquiredScreen != screenNum))
+ return FALSE;
+
+ setup.agps_mode = mode;
+ if (ioctl(gartFd, AGPIOC_SETUP, &setup) != 0) {
+ xf86DrvMsg(screenNum, X_WARNING, "xf86EnableAGP: "
+ "AGPIOC_SETUP with mode %x failed (%s)\n",
+ mode, strerror(errno));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
diff --git a/xorg-server/hw/xfree86/ramdac/xf86Cursor.c b/xorg-server/hw/xfree86/ramdac/xf86Cursor.c
index 346e99490..91b5795c3 100644
--- a/xorg-server/hw/xfree86/ramdac/xf86Cursor.c
+++ b/xorg-server/hw/xfree86/ramdac/xf86Cursor.c
@@ -1,479 +1,479 @@
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "xf86.h"
-#include "xf86CursorPriv.h"
-#include "colormapst.h"
-#include "cursorstr.h"
-
-/* FIXME: This was added with the ABI change of the miPointerSpriteFuncs for
- * MPX.
- * inputInfo is needed to pass the core pointer as the default argument into
- * the cursor functions.
- *
- * Externing inputInfo is not the nice way to do it but it works.
- */
-#include "inputstr.h"
-extern InputInfo inputInfo;
-
-static int xf86CursorScreenKeyIndex;
-DevPrivateKey xf86CursorScreenKey = &xf86CursorScreenKeyIndex;
-
-/* sprite functions */
-
-static Bool xf86CursorRealizeCursor(DeviceIntPtr, ScreenPtr, CursorPtr);
-static Bool xf86CursorUnrealizeCursor(DeviceIntPtr, ScreenPtr, CursorPtr);
-static void xf86CursorSetCursor(DeviceIntPtr, ScreenPtr, CursorPtr, int, int);
-static void xf86CursorMoveCursor(DeviceIntPtr, ScreenPtr, int, int);
-static Bool xf86DeviceCursorInitialize(DeviceIntPtr, ScreenPtr);
-static void xf86DeviceCursorCleanup(DeviceIntPtr, ScreenPtr);
-
-static miPointerSpriteFuncRec xf86CursorSpriteFuncs = {
- xf86CursorRealizeCursor,
- xf86CursorUnrealizeCursor,
- xf86CursorSetCursor,
- xf86CursorMoveCursor,
- xf86DeviceCursorInitialize,
- xf86DeviceCursorCleanup
-};
-
-/* Screen functions */
-
-static void xf86CursorInstallColormap(ColormapPtr);
-static void xf86CursorRecolorCursor(DeviceIntPtr pDev, ScreenPtr, CursorPtr, Bool);
-static Bool xf86CursorCloseScreen(int, ScreenPtr);
-static void xf86CursorQueryBestSize(int, unsigned short*, unsigned short*,
- ScreenPtr);
-
-/* ScrnInfoRec functions */
-
-static void xf86CursorEnableDisableFBAccess(int, Bool);
-static Bool xf86CursorSwitchMode(int, DisplayModePtr,int);
-
-Bool
-xf86InitCursor(
- ScreenPtr pScreen,
- xf86CursorInfoPtr infoPtr
-)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- xf86CursorScreenPtr ScreenPriv;
- miPointerScreenPtr PointPriv;
-
- if (!xf86InitHardwareCursor(pScreen, infoPtr))
- return FALSE;
-
- ScreenPriv = xcalloc(1, sizeof(xf86CursorScreenRec));
- if (!ScreenPriv)
- return FALSE;
-
- dixSetPrivate(&pScreen->devPrivates, xf86CursorScreenKey, ScreenPriv);
-
- ScreenPriv->SWCursor = TRUE;
- ScreenPriv->isUp = FALSE;
- ScreenPriv->CurrentCursor = NULL;
- ScreenPriv->CursorInfoPtr = infoPtr;
- ScreenPriv->PalettedCursor = FALSE;
- ScreenPriv->pInstalledMap = NULL;
-
- ScreenPriv->CloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = xf86CursorCloseScreen;
- ScreenPriv->QueryBestSize = pScreen->QueryBestSize;
- pScreen->QueryBestSize = xf86CursorQueryBestSize;
- ScreenPriv->RecolorCursor = pScreen->RecolorCursor;
- pScreen->RecolorCursor = xf86CursorRecolorCursor;
-
- if ((infoPtr->pScrn->bitsPerPixel == 8) &&
- !(infoPtr->Flags & HARDWARE_CURSOR_TRUECOLOR_AT_8BPP)) {
- ScreenPriv->InstallColormap = pScreen->InstallColormap;
- pScreen->InstallColormap = xf86CursorInstallColormap;
- ScreenPriv->PalettedCursor = TRUE;
- }
-
- PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
-
- ScreenPriv->showTransparent = PointPriv->showTransparent;
- if (infoPtr->Flags & HARDWARE_CURSOR_SHOW_TRANSPARENT)
- PointPriv->showTransparent = TRUE;
- else
- PointPriv->showTransparent = FALSE;
- ScreenPriv->spriteFuncs = PointPriv->spriteFuncs;
- PointPriv->spriteFuncs = &xf86CursorSpriteFuncs;
-
- ScreenPriv->EnableDisableFBAccess = pScrn->EnableDisableFBAccess;
- ScreenPriv->SwitchMode = pScrn->SwitchMode;
-
- ScreenPriv->ForceHWCursorCount = 0;
- ScreenPriv->HWCursorForced = FALSE;
-
- pScrn->EnableDisableFBAccess = xf86CursorEnableDisableFBAccess;
- if (pScrn->SwitchMode)
- pScrn->SwitchMode = xf86CursorSwitchMode;
-
- return TRUE;
-}
-
-/***** Screen functions *****/
-
-static Bool
-xf86CursorCloseScreen(int i, ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- miPointerScreenPtr PointPriv = (miPointerScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, miPointerScreenKey);
- xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, xf86CursorScreenKey);
-
- if (ScreenPriv->isUp && pScrn->vtSema)
- xf86SetCursor(pScreen, NullCursor, ScreenPriv->x, ScreenPriv->y);
-
- if (ScreenPriv->CurrentCursor)
- FreeCursor(ScreenPriv->CurrentCursor, None);
-
- pScreen->CloseScreen = ScreenPriv->CloseScreen;
- pScreen->QueryBestSize = ScreenPriv->QueryBestSize;
- pScreen->RecolorCursor = ScreenPriv->RecolorCursor;
- if (ScreenPriv->InstallColormap)
- pScreen->InstallColormap = ScreenPriv->InstallColormap;
-
- PointPriv->spriteFuncs = ScreenPriv->spriteFuncs;
- PointPriv->showTransparent = ScreenPriv->showTransparent;
-
- pScrn->EnableDisableFBAccess = ScreenPriv->EnableDisableFBAccess;
- pScrn->SwitchMode = ScreenPriv->SwitchMode;
-
- xfree(ScreenPriv->transparentData);
- xfree(ScreenPriv);
-
- return (*pScreen->CloseScreen)(i, pScreen);
-}
-
-static void
-xf86CursorQueryBestSize(
- int class,
- unsigned short *width,
- unsigned short *height,
- ScreenPtr pScreen)
-{
- xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, xf86CursorScreenKey);
-
- if (class == CursorShape) {
- if(*width > ScreenPriv->CursorInfoPtr->MaxWidth)
- *width = ScreenPriv->CursorInfoPtr->MaxWidth;
- if(*height > ScreenPriv->CursorInfoPtr->MaxHeight)
- *height = ScreenPriv->CursorInfoPtr->MaxHeight;
- } else
- (*ScreenPriv->QueryBestSize)(class, width, height, pScreen);
-}
-
-static void
-xf86CursorInstallColormap(ColormapPtr pMap)
-{
- xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
- &pMap->pScreen->devPrivates, xf86CursorScreenKey);
-
- ScreenPriv->pInstalledMap = pMap;
-
- (*ScreenPriv->InstallColormap)(pMap);
-}
-
-static void
-xf86CursorRecolorCursor(
- DeviceIntPtr pDev,
- ScreenPtr pScreen,
- CursorPtr pCurs,
- Bool displayed)
-{
- xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, xf86CursorScreenKey);
-
- if (!displayed)
- return;
-
- if (ScreenPriv->SWCursor)
- (*ScreenPriv->RecolorCursor)(pDev, pScreen, pCurs, displayed);
- else
- xf86RecolorCursor(pScreen, pCurs, displayed);
-}
-
-/***** ScrnInfoRec functions *********/
-
-static void
-xf86CursorEnableDisableFBAccess(
- int index,
- Bool enable)
-{
- DeviceIntPtr pDev = inputInfo.pointer;
-
- ScreenPtr pScreen = screenInfo.screens[index];
- xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, xf86CursorScreenKey);
-
- if (!enable && ScreenPriv->CurrentCursor != NullCursor) {
- CursorPtr currentCursor = ScreenPriv->CurrentCursor;
- xf86CursorSetCursor(pDev, pScreen, NullCursor, ScreenPriv->x,
- ScreenPriv->y);
- ScreenPriv->isUp = FALSE;
- ScreenPriv->SWCursor = TRUE;
- ScreenPriv->SavedCursor = currentCursor;
- }
-
- if (ScreenPriv->EnableDisableFBAccess)
- (*ScreenPriv->EnableDisableFBAccess)(index, enable);
-
- if (enable && ScreenPriv->SavedCursor)
- {
- /*
- * Re-set current cursor so drivers can react to FB access having been
- * temporarily disabled.
- */
- xf86CursorSetCursor(pDev, pScreen, ScreenPriv->SavedCursor,
- ScreenPriv->x, ScreenPriv->y);
- ScreenPriv->SavedCursor = NULL;
- }
-}
-
-static Bool
-xf86CursorSwitchMode(int index, DisplayModePtr mode, int flags)
-{
- Bool ret;
- ScreenPtr pScreen = screenInfo.screens[index];
- xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, xf86CursorScreenKey);
- miPointerScreenPtr PointPriv = (miPointerScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, miPointerScreenKey);
-
- if (ScreenPriv->isUp) {
- xf86SetCursor(pScreen, NullCursor, ScreenPriv->x, ScreenPriv->y);
- ScreenPriv->isUp = FALSE;
- }
-
- ret = (*ScreenPriv->SwitchMode)(index, mode, flags);
-
- /*
- * Cannot restore cursor here because the new frame[XY][01] haven't been
- * calculated yet. However, because the hardware cursor was removed above,
- * ensure the cursor is repainted by miPointerWarpCursor().
- */
- ScreenPriv->CursorToRestore = ScreenPriv->CurrentCursor;
- PointPriv->waitForUpdate = FALSE; /* Force cursor repaint */
-
- return ret;
-}
-
-/****** miPointerSpriteFunctions *******/
-
-static Bool
-xf86CursorRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs)
-{
- xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, xf86CursorScreenKey);
-
- if (pCurs->refcnt <= 1)
- dixSetPrivate(&pCurs->devPrivates, CursorScreenKey(pScreen), NULL);
-
- return (*ScreenPriv->spriteFuncs->RealizeCursor)(pDev, pScreen, pCurs);
-}
-
-static Bool
-xf86CursorUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
- CursorPtr pCurs)
-{
- xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, xf86CursorScreenKey);
-
- if (pCurs->refcnt <= 1) {
- xfree(dixLookupPrivate(&pCurs->devPrivates, CursorScreenKey(pScreen)));
- dixSetPrivate(&pCurs->devPrivates, CursorScreenKey(pScreen), NULL);
- }
-
- return (*ScreenPriv->spriteFuncs->UnrealizeCursor)(pDev, pScreen, pCurs);
-}
-
-static void
-xf86CursorSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs,
- int x, int y)
-{
- xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, xf86CursorScreenKey);
- xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
- miPointerScreenPtr PointPriv = (miPointerScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, miPointerScreenKey);
-
-
- if (pCurs == NullCursor) { /* means we're supposed to remove the cursor */
- if (ScreenPriv->SWCursor ||
- !(GetMaster(pDev, MASTER_POINTER) == inputInfo.pointer))
- (*ScreenPriv->spriteFuncs->SetCursor)(pDev, pScreen, NullCursor, x, y);
- else if (ScreenPriv->isUp) {
- xf86SetCursor(pScreen, NullCursor, x, y);
- ScreenPriv->isUp = FALSE;
- }
- if (ScreenPriv->CurrentCursor)
- FreeCursor(ScreenPriv->CurrentCursor, None);
- ScreenPriv->CurrentCursor = NullCursor;
- return;
- }
-
- /* only update for VCP, otherwise we get cursor jumps when removing a
- sprite. The second cursor is never HW rendered anyway. */
- if (pDev == inputInfo.pointer ||
- (!IsMaster(pDev) && pDev->u.master == inputInfo.pointer))
- {
- pCurs->refcnt++;
- if (ScreenPriv->CurrentCursor)
- FreeCursor(ScreenPriv->CurrentCursor, None);
- ScreenPriv->CurrentCursor = pCurs;
- ScreenPriv->x = x;
- ScreenPriv->y = y;
- ScreenPriv->CursorToRestore = NULL;
- ScreenPriv->HotX = pCurs->bits->xhot;
- ScreenPriv->HotY = pCurs->bits->yhot;
-
- if (!infoPtr->pScrn->vtSema)
- ScreenPriv->SavedCursor = pCurs;
-
- if (infoPtr->pScrn->vtSema && (ScreenPriv->ForceHWCursorCount || ((
-#ifdef ARGB_CURSOR
- pCurs->bits->argb && infoPtr->UseHWCursorARGB &&
- (*infoPtr->UseHWCursorARGB) (pScreen, pCurs) ) || (
- pCurs->bits->argb == 0 &&
-#endif
- (pCurs->bits->height <= infoPtr->MaxHeight) &&
- (pCurs->bits->width <= infoPtr->MaxWidth) &&
- (!infoPtr->UseHWCursor || (*infoPtr->UseHWCursor)(pScreen, pCurs))))))
- {
-
- if (ScreenPriv->SWCursor) /* remove the SW cursor */
- (*ScreenPriv->spriteFuncs->SetCursor)(pDev, pScreen, NullCursor, x, y);
-
- xf86SetCursor(pScreen, pCurs, x, y);
- ScreenPriv->SWCursor = FALSE;
- ScreenPriv->isUp = TRUE;
- PointPriv->waitForUpdate = !infoPtr->pScrn->silkenMouse;
- return;
- }
-
- PointPriv->waitForUpdate = TRUE;
-
- if (ScreenPriv->isUp) {
- /* Remove the HW cursor, or make it transparent */
- if (infoPtr->Flags & HARDWARE_CURSOR_SHOW_TRANSPARENT) {
- xf86SetTransparentCursor(pScreen);
- } else {
- xf86SetCursor(pScreen, NullCursor, x, y);
- ScreenPriv->isUp = FALSE;
- }
- }
-
- if (!ScreenPriv->SWCursor)
- ScreenPriv->SWCursor = TRUE;
-
- }
-
- if (pCurs->bits->emptyMask && !ScreenPriv->showTransparent)
- pCurs = NullCursor;
-
- (*ScreenPriv->spriteFuncs->SetCursor)(pDev, pScreen, pCurs, x, y);
-}
-
-static void
-xf86CursorMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
-{
- xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, xf86CursorScreenKey);
-
- /* only update coordinate state for first sprite, otherwise we get jumps
- when removing a sprite. The second sprite is never HW rendered anyway */
- if (pDev == inputInfo.pointer ||
- (!IsMaster(pDev) && pDev->u.master == inputInfo.pointer))
- {
- ScreenPriv->x = x;
- ScreenPriv->y = y;
-
- if (ScreenPriv->CursorToRestore)
- xf86CursorSetCursor(pDev, pScreen, ScreenPriv->CursorToRestore, x, y);
- else if (ScreenPriv->SWCursor)
- (*ScreenPriv->spriteFuncs->MoveCursor)(pDev, pScreen, x, y);
- else if (ScreenPriv->isUp)
- xf86MoveCursor(pScreen, x, y);
- } else
- (*ScreenPriv->spriteFuncs->MoveCursor)(pDev, pScreen, x, y);
-}
-
-void
-xf86ForceHWCursor (ScreenPtr pScreen, Bool on)
-{
- DeviceIntPtr pDev = inputInfo.pointer;
- xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, xf86CursorScreenKey);
-
- if (on)
- {
- if (ScreenPriv->ForceHWCursorCount++ == 0)
- {
- if (ScreenPriv->SWCursor && ScreenPriv->CurrentCursor)
- {
- ScreenPriv->HWCursorForced = TRUE;
- xf86CursorSetCursor (pDev, pScreen, ScreenPriv->CurrentCursor,
- ScreenPriv->x, ScreenPriv->y);
- }
- else
- ScreenPriv->HWCursorForced = FALSE;
- }
- }
- else
- {
- if (--ScreenPriv->ForceHWCursorCount == 0)
- {
- if (ScreenPriv->HWCursorForced && ScreenPriv->CurrentCursor)
- xf86CursorSetCursor (pDev, pScreen, ScreenPriv->CurrentCursor,
- ScreenPriv->x, ScreenPriv->y);
- }
- }
-}
-
-xf86CursorInfoPtr
-xf86CreateCursorInfoRec(void)
-{
- return xcalloc(1, sizeof(xf86CursorInfoRec));
-}
-
-void
-xf86DestroyCursorInfoRec(xf86CursorInfoPtr infoPtr)
-{
- xfree(infoPtr);
-}
-
-/**
- * New cursor has been created. Do your initalizations here.
- */
-static Bool
-xf86DeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
-{
- int ret;
- xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, xf86CursorScreenKey);
-
- /* Init SW cursor */
- ret = (*ScreenPriv->spriteFuncs->DeviceCursorInitialize)(pDev, pScreen);
-
- return ret;
-}
-
-/**
- * Cursor has been removed. Clean up after yourself.
- */
-static void
-xf86DeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
-{
- xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, xf86CursorScreenKey);
-
- /* Clean up SW cursor */
- (*ScreenPriv->spriteFuncs->DeviceCursorCleanup)(pDev, pScreen);
-}
-
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "xf86.h"
+#include "xf86CursorPriv.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+
+/* FIXME: This was added with the ABI change of the miPointerSpriteFuncs for
+ * MPX.
+ * inputInfo is needed to pass the core pointer as the default argument into
+ * the cursor functions.
+ *
+ * Externing inputInfo is not the nice way to do it but it works.
+ */
+#include "inputstr.h"
+extern InputInfo inputInfo;
+
+static int xf86CursorScreenKeyIndex;
+DevPrivateKey xf86CursorScreenKey = &xf86CursorScreenKeyIndex;
+
+/* sprite functions */
+
+static Bool xf86CursorRealizeCursor(DeviceIntPtr, ScreenPtr, CursorPtr);
+static Bool xf86CursorUnrealizeCursor(DeviceIntPtr, ScreenPtr, CursorPtr);
+static void xf86CursorSetCursor(DeviceIntPtr, ScreenPtr, CursorPtr, int, int);
+static void xf86CursorMoveCursor(DeviceIntPtr, ScreenPtr, int, int);
+static Bool xf86DeviceCursorInitialize(DeviceIntPtr, ScreenPtr);
+static void xf86DeviceCursorCleanup(DeviceIntPtr, ScreenPtr);
+
+static miPointerSpriteFuncRec xf86CursorSpriteFuncs = {
+ xf86CursorRealizeCursor,
+ xf86CursorUnrealizeCursor,
+ xf86CursorSetCursor,
+ xf86CursorMoveCursor,
+ xf86DeviceCursorInitialize,
+ xf86DeviceCursorCleanup
+};
+
+/* Screen functions */
+
+static void xf86CursorInstallColormap(ColormapPtr);
+static void xf86CursorRecolorCursor(DeviceIntPtr pDev, ScreenPtr, CursorPtr, Bool);
+static Bool xf86CursorCloseScreen(int, ScreenPtr);
+static void xf86CursorQueryBestSize(int, unsigned short*, unsigned short*,
+ ScreenPtr);
+
+/* ScrnInfoRec functions */
+
+static void xf86CursorEnableDisableFBAccess(int, Bool);
+static Bool xf86CursorSwitchMode(int, DisplayModePtr,int);
+
+Bool
+xf86InitCursor(
+ ScreenPtr pScreen,
+ xf86CursorInfoPtr infoPtr
+)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ xf86CursorScreenPtr ScreenPriv;
+ miPointerScreenPtr PointPriv;
+
+ if (!xf86InitHardwareCursor(pScreen, infoPtr))
+ return FALSE;
+
+ ScreenPriv = calloc(1, sizeof(xf86CursorScreenRec));
+ if (!ScreenPriv)
+ return FALSE;
+
+ dixSetPrivate(&pScreen->devPrivates, xf86CursorScreenKey, ScreenPriv);
+
+ ScreenPriv->SWCursor = TRUE;
+ ScreenPriv->isUp = FALSE;
+ ScreenPriv->CurrentCursor = NULL;
+ ScreenPriv->CursorInfoPtr = infoPtr;
+ ScreenPriv->PalettedCursor = FALSE;
+ ScreenPriv->pInstalledMap = NULL;
+
+ ScreenPriv->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = xf86CursorCloseScreen;
+ ScreenPriv->QueryBestSize = pScreen->QueryBestSize;
+ pScreen->QueryBestSize = xf86CursorQueryBestSize;
+ ScreenPriv->RecolorCursor = pScreen->RecolorCursor;
+ pScreen->RecolorCursor = xf86CursorRecolorCursor;
+
+ if ((infoPtr->pScrn->bitsPerPixel == 8) &&
+ !(infoPtr->Flags & HARDWARE_CURSOR_TRUECOLOR_AT_8BPP)) {
+ ScreenPriv->InstallColormap = pScreen->InstallColormap;
+ pScreen->InstallColormap = xf86CursorInstallColormap;
+ ScreenPriv->PalettedCursor = TRUE;
+ }
+
+ PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
+
+ ScreenPriv->showTransparent = PointPriv->showTransparent;
+ if (infoPtr->Flags & HARDWARE_CURSOR_SHOW_TRANSPARENT)
+ PointPriv->showTransparent = TRUE;
+ else
+ PointPriv->showTransparent = FALSE;
+ ScreenPriv->spriteFuncs = PointPriv->spriteFuncs;
+ PointPriv->spriteFuncs = &xf86CursorSpriteFuncs;
+
+ ScreenPriv->EnableDisableFBAccess = pScrn->EnableDisableFBAccess;
+ ScreenPriv->SwitchMode = pScrn->SwitchMode;
+
+ ScreenPriv->ForceHWCursorCount = 0;
+ ScreenPriv->HWCursorForced = FALSE;
+
+ pScrn->EnableDisableFBAccess = xf86CursorEnableDisableFBAccess;
+ if (pScrn->SwitchMode)
+ pScrn->SwitchMode = xf86CursorSwitchMode;
+
+ return TRUE;
+}
+
+/***** Screen functions *****/
+
+static Bool
+xf86CursorCloseScreen(int i, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ miPointerScreenPtr PointPriv = (miPointerScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, miPointerScreenKey);
+ xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, xf86CursorScreenKey);
+
+ if (ScreenPriv->isUp && pScrn->vtSema)
+ xf86SetCursor(pScreen, NullCursor, ScreenPriv->x, ScreenPriv->y);
+
+ if (ScreenPriv->CurrentCursor)
+ FreeCursor(ScreenPriv->CurrentCursor, None);
+
+ pScreen->CloseScreen = ScreenPriv->CloseScreen;
+ pScreen->QueryBestSize = ScreenPriv->QueryBestSize;
+ pScreen->RecolorCursor = ScreenPriv->RecolorCursor;
+ if (ScreenPriv->InstallColormap)
+ pScreen->InstallColormap = ScreenPriv->InstallColormap;
+
+ PointPriv->spriteFuncs = ScreenPriv->spriteFuncs;
+ PointPriv->showTransparent = ScreenPriv->showTransparent;
+
+ pScrn->EnableDisableFBAccess = ScreenPriv->EnableDisableFBAccess;
+ pScrn->SwitchMode = ScreenPriv->SwitchMode;
+
+ free(ScreenPriv->transparentData);
+ free(ScreenPriv);
+
+ return (*pScreen->CloseScreen)(i, pScreen);
+}
+
+static void
+xf86CursorQueryBestSize(
+ int class,
+ unsigned short *width,
+ unsigned short *height,
+ ScreenPtr pScreen)
+{
+ xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, xf86CursorScreenKey);
+
+ if (class == CursorShape) {
+ if(*width > ScreenPriv->CursorInfoPtr->MaxWidth)
+ *width = ScreenPriv->CursorInfoPtr->MaxWidth;
+ if(*height > ScreenPriv->CursorInfoPtr->MaxHeight)
+ *height = ScreenPriv->CursorInfoPtr->MaxHeight;
+ } else
+ (*ScreenPriv->QueryBestSize)(class, width, height, pScreen);
+}
+
+static void
+xf86CursorInstallColormap(ColormapPtr pMap)
+{
+ xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+ &pMap->pScreen->devPrivates, xf86CursorScreenKey);
+
+ ScreenPriv->pInstalledMap = pMap;
+
+ (*ScreenPriv->InstallColormap)(pMap);
+}
+
+static void
+xf86CursorRecolorCursor(
+ DeviceIntPtr pDev,
+ ScreenPtr pScreen,
+ CursorPtr pCurs,
+ Bool displayed)
+{
+ xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, xf86CursorScreenKey);
+
+ if (!displayed)
+ return;
+
+ if (ScreenPriv->SWCursor)
+ (*ScreenPriv->RecolorCursor)(pDev, pScreen, pCurs, displayed);
+ else
+ xf86RecolorCursor(pScreen, pCurs, displayed);
+}
+
+/***** ScrnInfoRec functions *********/
+
+static void
+xf86CursorEnableDisableFBAccess(
+ int index,
+ Bool enable)
+{
+ DeviceIntPtr pDev = inputInfo.pointer;
+
+ ScreenPtr pScreen = screenInfo.screens[index];
+ xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, xf86CursorScreenKey);
+
+ if (!enable && ScreenPriv->CurrentCursor != NullCursor) {
+ CursorPtr currentCursor = ScreenPriv->CurrentCursor;
+ xf86CursorSetCursor(pDev, pScreen, NullCursor, ScreenPriv->x,
+ ScreenPriv->y);
+ ScreenPriv->isUp = FALSE;
+ ScreenPriv->SWCursor = TRUE;
+ ScreenPriv->SavedCursor = currentCursor;
+ }
+
+ if (ScreenPriv->EnableDisableFBAccess)
+ (*ScreenPriv->EnableDisableFBAccess)(index, enable);
+
+ if (enable && ScreenPriv->SavedCursor)
+ {
+ /*
+ * Re-set current cursor so drivers can react to FB access having been
+ * temporarily disabled.
+ */
+ xf86CursorSetCursor(pDev, pScreen, ScreenPriv->SavedCursor,
+ ScreenPriv->x, ScreenPriv->y);
+ ScreenPriv->SavedCursor = NULL;
+ }
+}
+
+static Bool
+xf86CursorSwitchMode(int index, DisplayModePtr mode, int flags)
+{
+ Bool ret;
+ ScreenPtr pScreen = screenInfo.screens[index];
+ xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, xf86CursorScreenKey);
+ miPointerScreenPtr PointPriv = (miPointerScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, miPointerScreenKey);
+
+ if (ScreenPriv->isUp) {
+ xf86SetCursor(pScreen, NullCursor, ScreenPriv->x, ScreenPriv->y);
+ ScreenPriv->isUp = FALSE;
+ }
+
+ ret = (*ScreenPriv->SwitchMode)(index, mode, flags);
+
+ /*
+ * Cannot restore cursor here because the new frame[XY][01] haven't been
+ * calculated yet. However, because the hardware cursor was removed above,
+ * ensure the cursor is repainted by miPointerWarpCursor().
+ */
+ ScreenPriv->CursorToRestore = ScreenPriv->CurrentCursor;
+ PointPriv->waitForUpdate = FALSE; /* Force cursor repaint */
+
+ return ret;
+}
+
+/****** miPointerSpriteFunctions *******/
+
+static Bool
+xf86CursorRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs)
+{
+ xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, xf86CursorScreenKey);
+
+ if (pCurs->refcnt <= 1)
+ dixSetPrivate(&pCurs->devPrivates, CursorScreenKey(pScreen), NULL);
+
+ return (*ScreenPriv->spriteFuncs->RealizeCursor)(pDev, pScreen, pCurs);
+}
+
+static Bool
+xf86CursorUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen,
+ CursorPtr pCurs)
+{
+ xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, xf86CursorScreenKey);
+
+ if (pCurs->refcnt <= 1) {
+ free(dixLookupPrivate(&pCurs->devPrivates, CursorScreenKey(pScreen)));
+ dixSetPrivate(&pCurs->devPrivates, CursorScreenKey(pScreen), NULL);
+ }
+
+ return (*ScreenPriv->spriteFuncs->UnrealizeCursor)(pDev, pScreen, pCurs);
+}
+
+static void
+xf86CursorSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCurs,
+ int x, int y)
+{
+ xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, xf86CursorScreenKey);
+ xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
+ miPointerScreenPtr PointPriv = (miPointerScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, miPointerScreenKey);
+
+
+ if (pCurs == NullCursor) { /* means we're supposed to remove the cursor */
+ if (ScreenPriv->SWCursor ||
+ !(GetMaster(pDev, MASTER_POINTER) == inputInfo.pointer))
+ (*ScreenPriv->spriteFuncs->SetCursor)(pDev, pScreen, NullCursor, x, y);
+ else if (ScreenPriv->isUp) {
+ xf86SetCursor(pScreen, NullCursor, x, y);
+ ScreenPriv->isUp = FALSE;
+ }
+ if (ScreenPriv->CurrentCursor)
+ FreeCursor(ScreenPriv->CurrentCursor, None);
+ ScreenPriv->CurrentCursor = NullCursor;
+ return;
+ }
+
+ /* only update for VCP, otherwise we get cursor jumps when removing a
+ sprite. The second cursor is never HW rendered anyway. */
+ if (pDev == inputInfo.pointer ||
+ (!IsMaster(pDev) && pDev->u.master == inputInfo.pointer))
+ {
+ pCurs->refcnt++;
+ if (ScreenPriv->CurrentCursor)
+ FreeCursor(ScreenPriv->CurrentCursor, None);
+ ScreenPriv->CurrentCursor = pCurs;
+ ScreenPriv->x = x;
+ ScreenPriv->y = y;
+ ScreenPriv->CursorToRestore = NULL;
+ ScreenPriv->HotX = pCurs->bits->xhot;
+ ScreenPriv->HotY = pCurs->bits->yhot;
+
+ if (!infoPtr->pScrn->vtSema)
+ ScreenPriv->SavedCursor = pCurs;
+
+ if (infoPtr->pScrn->vtSema && (ScreenPriv->ForceHWCursorCount || ((
+#ifdef ARGB_CURSOR
+ pCurs->bits->argb && infoPtr->UseHWCursorARGB &&
+ (*infoPtr->UseHWCursorARGB) (pScreen, pCurs) ) || (
+ pCurs->bits->argb == 0 &&
+#endif
+ (pCurs->bits->height <= infoPtr->MaxHeight) &&
+ (pCurs->bits->width <= infoPtr->MaxWidth) &&
+ (!infoPtr->UseHWCursor || (*infoPtr->UseHWCursor)(pScreen, pCurs))))))
+ {
+
+ if (ScreenPriv->SWCursor) /* remove the SW cursor */
+ (*ScreenPriv->spriteFuncs->SetCursor)(pDev, pScreen, NullCursor, x, y);
+
+ xf86SetCursor(pScreen, pCurs, x, y);
+ ScreenPriv->SWCursor = FALSE;
+ ScreenPriv->isUp = TRUE;
+ PointPriv->waitForUpdate = !infoPtr->pScrn->silkenMouse;
+ return;
+ }
+
+ PointPriv->waitForUpdate = TRUE;
+
+ if (ScreenPriv->isUp) {
+ /* Remove the HW cursor, or make it transparent */
+ if (infoPtr->Flags & HARDWARE_CURSOR_SHOW_TRANSPARENT) {
+ xf86SetTransparentCursor(pScreen);
+ } else {
+ xf86SetCursor(pScreen, NullCursor, x, y);
+ ScreenPriv->isUp = FALSE;
+ }
+ }
+
+ if (!ScreenPriv->SWCursor)
+ ScreenPriv->SWCursor = TRUE;
+
+ }
+
+ if (pCurs->bits->emptyMask && !ScreenPriv->showTransparent)
+ pCurs = NullCursor;
+
+ (*ScreenPriv->spriteFuncs->SetCursor)(pDev, pScreen, pCurs, x, y);
+}
+
+static void
+xf86CursorMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
+{
+ xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, xf86CursorScreenKey);
+
+ /* only update coordinate state for first sprite, otherwise we get jumps
+ when removing a sprite. The second sprite is never HW rendered anyway */
+ if (pDev == inputInfo.pointer ||
+ (!IsMaster(pDev) && pDev->u.master == inputInfo.pointer))
+ {
+ ScreenPriv->x = x;
+ ScreenPriv->y = y;
+
+ if (ScreenPriv->CursorToRestore)
+ xf86CursorSetCursor(pDev, pScreen, ScreenPriv->CursorToRestore, x, y);
+ else if (ScreenPriv->SWCursor)
+ (*ScreenPriv->spriteFuncs->MoveCursor)(pDev, pScreen, x, y);
+ else if (ScreenPriv->isUp)
+ xf86MoveCursor(pScreen, x, y);
+ } else
+ (*ScreenPriv->spriteFuncs->MoveCursor)(pDev, pScreen, x, y);
+}
+
+void
+xf86ForceHWCursor (ScreenPtr pScreen, Bool on)
+{
+ DeviceIntPtr pDev = inputInfo.pointer;
+ xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, xf86CursorScreenKey);
+
+ if (on)
+ {
+ if (ScreenPriv->ForceHWCursorCount++ == 0)
+ {
+ if (ScreenPriv->SWCursor && ScreenPriv->CurrentCursor)
+ {
+ ScreenPriv->HWCursorForced = TRUE;
+ xf86CursorSetCursor (pDev, pScreen, ScreenPriv->CurrentCursor,
+ ScreenPriv->x, ScreenPriv->y);
+ }
+ else
+ ScreenPriv->HWCursorForced = FALSE;
+ }
+ }
+ else
+ {
+ if (--ScreenPriv->ForceHWCursorCount == 0)
+ {
+ if (ScreenPriv->HWCursorForced && ScreenPriv->CurrentCursor)
+ xf86CursorSetCursor (pDev, pScreen, ScreenPriv->CurrentCursor,
+ ScreenPriv->x, ScreenPriv->y);
+ }
+ }
+}
+
+xf86CursorInfoPtr
+xf86CreateCursorInfoRec(void)
+{
+ return calloc(1, sizeof(xf86CursorInfoRec));
+}
+
+void
+xf86DestroyCursorInfoRec(xf86CursorInfoPtr infoPtr)
+{
+ free(infoPtr);
+}
+
+/**
+ * New cursor has been created. Do your initalizations here.
+ */
+static Bool
+xf86DeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
+{
+ int ret;
+ xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, xf86CursorScreenKey);
+
+ /* Init SW cursor */
+ ret = (*ScreenPriv->spriteFuncs->DeviceCursorInitialize)(pDev, pScreen);
+
+ return ret;
+}
+
+/**
+ * Cursor has been removed. Clean up after yourself.
+ */
+static void
+xf86DeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
+{
+ xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, xf86CursorScreenKey);
+
+ /* Clean up SW cursor */
+ (*ScreenPriv->spriteFuncs->DeviceCursorCleanup)(pDev, pScreen);
+}
+
diff --git a/xorg-server/hw/xfree86/ramdac/xf86HWCurs.c b/xorg-server/hw/xfree86/ramdac/xf86HWCurs.c
index 4374e51d4..43f28ef8e 100644
--- a/xorg-server/hw/xfree86/ramdac/xf86HWCurs.c
+++ b/xorg-server/hw/xfree86/ramdac/xf86HWCurs.c
@@ -1,527 +1,527 @@
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <string.h>
-
-#include "misc.h"
-#include "xf86.h"
-#include "xf86_OSproc.h"
-
-#include <X11/X.h>
-#include "scrnintstr.h"
-#include "pixmapstr.h"
-#include "windowstr.h"
-#include "xf86str.h"
-#include "cursorstr.h"
-#include "mi.h"
-#include "mipointer.h"
-#include "xf86CursorPriv.h"
-
-#include "servermd.h"
-
-#if BITMAP_SCANLINE_PAD == 64
-
-#if 1
-/* Cursors might be only 32 wide. Give'em a chance */
-#define SCANLINE CARD32
-#define CUR_BITMAP_SCANLINE_PAD 32
-#define CUR_LOG2_BITMAP_PAD 5
-#define REVERSE_BIT_ORDER(w) xf86ReverseBitOrder(w)
-#else
-#define SCANLINE CARD64
-#define CUR_BITMAP_SCANLINE_PAD BITMAP_SCANLINE_PAD
-#define CUR_LOG2_BITMAP_PAD LOG2_BITMAP_PAD
-#define REVERSE_BIT_ORDER(w) xf86CARD64ReverseBits(w)
-static CARD64 xf86CARD64ReverseBits(CARD64 w);
-
-static CARD64
-xf86CARD64ReverseBits(CARD64 w)
-{
- unsigned char *p = (unsigned char *)&w;
-
- p[0] = byte_reversed[p[0]];
- p[1] = byte_reversed[p[1]];
- p[2] = byte_reversed[p[2]];
- p[3] = byte_reversed[p[3]];
- p[4] = byte_reversed[p[4]];
- p[5] = byte_reversed[p[5]];
- p[6] = byte_reversed[p[6]];
- p[7] = byte_reversed[p[7]];
-
- return w;
-}
-#endif
-
-#else
-
-#define SCANLINE CARD32
-#define CUR_BITMAP_SCANLINE_PAD BITMAP_SCANLINE_PAD
-#define CUR_LOG2_BITMAP_PAD LOG2_BITMAP_PAD
-#define REVERSE_BIT_ORDER(w) xf86ReverseBitOrder(w)
-
-#endif /* BITMAP_SCANLINE_PAD == 64 */
-
-static unsigned char* RealizeCursorInterleave0(xf86CursorInfoPtr, CursorPtr);
-static unsigned char* RealizeCursorInterleave1(xf86CursorInfoPtr, CursorPtr);
-static unsigned char* RealizeCursorInterleave8(xf86CursorInfoPtr, CursorPtr);
-static unsigned char* RealizeCursorInterleave16(xf86CursorInfoPtr, CursorPtr);
-static unsigned char* RealizeCursorInterleave32(xf86CursorInfoPtr, CursorPtr);
-static unsigned char* RealizeCursorInterleave64(xf86CursorInfoPtr, CursorPtr);
-
-Bool
-xf86InitHardwareCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr)
-{
- if ((infoPtr->MaxWidth <= 0) || (infoPtr->MaxHeight <= 0))
- return FALSE;
-
- /* These are required for now */
- if (!infoPtr->SetCursorPosition ||
- !infoPtr->LoadCursorImage ||
- !infoPtr->HideCursor ||
- !infoPtr->ShowCursor ||
- !infoPtr->SetCursorColors)
- return FALSE;
-
- if (infoPtr->RealizeCursor) {
- /* Don't overwrite a driver provided Realize Cursor function */
- } else
- if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 & infoPtr->Flags) {
- infoPtr->RealizeCursor = RealizeCursorInterleave1;
- } else
- if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8 & infoPtr->Flags) {
- infoPtr->RealizeCursor = RealizeCursorInterleave8;
- } else
- if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16 & infoPtr->Flags) {
- infoPtr->RealizeCursor = RealizeCursorInterleave16;
- } else
- if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 & infoPtr->Flags) {
- infoPtr->RealizeCursor = RealizeCursorInterleave32;
- } else
- if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 & infoPtr->Flags) {
- infoPtr->RealizeCursor = RealizeCursorInterleave64;
- } else { /* not interleaved */
- infoPtr->RealizeCursor = RealizeCursorInterleave0;
- }
-
- infoPtr->pScrn = xf86Screens[pScreen->myNum];
-
- return TRUE;
-}
-
-void
-xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
-{
- xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, xf86CursorScreenKey);
- xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
- unsigned char *bits;
-
- if (pCurs == NullCursor) {
- (*infoPtr->HideCursor)(infoPtr->pScrn);
- return;
- }
-
- bits = dixLookupPrivate(&pCurs->devPrivates, CursorScreenKey(pScreen));
-
- x -= infoPtr->pScrn->frameX0 + ScreenPriv->HotX;
- y -= infoPtr->pScrn->frameY0 + ScreenPriv->HotY;
-
-#ifdef ARGB_CURSOR
- if (!pCurs->bits->argb || !infoPtr->LoadCursorARGB)
-#endif
- if (!bits) {
- bits = (*infoPtr->RealizeCursor)(infoPtr, pCurs);
- dixSetPrivate(&pCurs->devPrivates, CursorScreenKey(pScreen), bits);
- }
-
- if (!(infoPtr->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
- (*infoPtr->HideCursor)(infoPtr->pScrn);
-
-#ifdef ARGB_CURSOR
- if (pCurs->bits->argb && infoPtr->LoadCursorARGB)
- (*infoPtr->LoadCursorARGB) (infoPtr->pScrn, pCurs);
- else
-#endif
- if (bits)
- (*infoPtr->LoadCursorImage)(infoPtr->pScrn, bits);
-
- xf86RecolorCursor(pScreen, pCurs, 1);
-
- (*infoPtr->SetCursorPosition)(infoPtr->pScrn, x, y);
-
- (*infoPtr->ShowCursor)(infoPtr->pScrn);
-}
-
-void
-xf86SetTransparentCursor(ScreenPtr pScreen)
-{
- xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, xf86CursorScreenKey);
- xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
-
- if (!ScreenPriv->transparentData)
- ScreenPriv->transparentData =
- (*infoPtr->RealizeCursor)(infoPtr, NullCursor);
-
- if (!(infoPtr->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
- (*infoPtr->HideCursor)(infoPtr->pScrn);
-
- if (ScreenPriv->transparentData)
- (*infoPtr->LoadCursorImage)(infoPtr->pScrn,
- ScreenPriv->transparentData);
-
- (*infoPtr->ShowCursor)(infoPtr->pScrn);
-}
-
-void
-xf86MoveCursor(ScreenPtr pScreen, int x, int y)
-{
- xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, xf86CursorScreenKey);
- xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
-
- x -= infoPtr->pScrn->frameX0 + ScreenPriv->HotX;
- y -= infoPtr->pScrn->frameY0 + ScreenPriv->HotY;
-
- (*infoPtr->SetCursorPosition)(infoPtr->pScrn, x, y);
-}
-
-void
-xf86RecolorCursor(ScreenPtr pScreen, CursorPtr pCurs, Bool displayed)
-{
- xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
- &pScreen->devPrivates, xf86CursorScreenKey);
- xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
-
-#ifdef ARGB_CURSOR
- /* recoloring isn't applicable to ARGB cursors and drivers
- shouldn't have to ignore SetCursorColors requests */
- if (pCurs->bits->argb)
- return;
-#endif
-
- if (ScreenPriv->PalettedCursor) {
- xColorItem sourceColor, maskColor;
- ColormapPtr pmap = ScreenPriv->pInstalledMap;
-
- if (!pmap)
- return;
-
- sourceColor.red = pCurs->foreRed;
- sourceColor.green = pCurs->foreGreen;
- sourceColor.blue = pCurs->foreBlue;
- FakeAllocColor(pmap, &sourceColor);
- maskColor.red = pCurs->backRed;
- maskColor.green = pCurs->backGreen;
- maskColor.blue = pCurs->backBlue;
- FakeAllocColor(pmap, &maskColor);
- FakeFreeColor(pmap, sourceColor.pixel);
- FakeFreeColor(pmap, maskColor.pixel);
- (*infoPtr->SetCursorColors)(infoPtr->pScrn,
- maskColor.pixel, sourceColor.pixel);
- } else { /* Pass colors in 8-8-8 RGB format */
- (*infoPtr->SetCursorColors)(infoPtr->pScrn,
- (pCurs->backBlue >> 8) |
- ((pCurs->backGreen >> 8) << 8) |
- ((pCurs->backRed >> 8) << 16),
- (pCurs->foreBlue >> 8) |
- ((pCurs->foreGreen >> 8) << 8) |
- ((pCurs->foreRed >> 8) << 16)
- );
- }
-}
-
-/* These functions assume that MaxWidth is a multiple of 32 */
-static unsigned char*
-RealizeCursorInterleave0(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
-{
-
- SCANLINE *SrcS, *SrcM, *DstS, *DstM;
- SCANLINE *pSrc, *pMsk;
- unsigned char *mem;
- int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
- int SrcPitch, DstPitch, Pitch, y, x;
- /* how many words are in the source or mask */
- int words = size / (CUR_BITMAP_SCANLINE_PAD / 4);
-
-
- if (!(mem = xcalloc(1, size)))
- return NULL;
-
- if (pCurs == NullCursor) {
- if (infoPtr->Flags & HARDWARE_CURSOR_INVERT_MASK) {
- DstM = (SCANLINE*)mem;
- if (!(infoPtr->Flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK))
- DstM += words;
- memset(DstM, -1, words * sizeof(SCANLINE));
- }
- return mem;
- }
-
- /* SrcPitch == the number of scanlines wide the cursor image is */
- SrcPitch = (pCurs->bits->width + (BITMAP_SCANLINE_PAD - 1)) >>
- CUR_LOG2_BITMAP_PAD;
-
- /* DstPitch is the width of the hw cursor in scanlines */
- DstPitch = infoPtr->MaxWidth >> CUR_LOG2_BITMAP_PAD;
- Pitch = SrcPitch < DstPitch ? SrcPitch : DstPitch;
-
- SrcS = (SCANLINE*)pCurs->bits->source;
- SrcM = (SCANLINE*)pCurs->bits->mask;
- DstS = (SCANLINE*)mem;
- DstM = DstS + words;
-
- if (infoPtr->Flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK) {
- SCANLINE *tmp;
- tmp = DstS; DstS = DstM; DstM = tmp;
- }
-
- if (infoPtr->Flags & HARDWARE_CURSOR_AND_SOURCE_WITH_MASK) {
- for(y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
- y--;
- pSrc+=DstPitch, pMsk+=DstPitch, SrcS+=SrcPitch, SrcM+=SrcPitch) {
- for(x = 0; x < Pitch; x++) {
- pSrc[x] = SrcS[x] & SrcM[x];
- pMsk[x] = SrcM[x];
- }
- }
- } else {
- for(y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
- y--;
- pSrc+=DstPitch, pMsk+=DstPitch, SrcS+=SrcPitch, SrcM+=SrcPitch) {
- for(x = 0; x < Pitch; x++) {
- pSrc[x] = SrcS[x];
- pMsk[x] = SrcM[x];
- }
- }
- }
-
- if (infoPtr->Flags & HARDWARE_CURSOR_NIBBLE_SWAPPED) {
- int count = size;
- unsigned char* pntr1 = (unsigned char *)DstS;
- unsigned char* pntr2 = (unsigned char *)DstM;
- unsigned char a, b;
- while (count) {
-
- a = *pntr1;
- b = *pntr2;
- *pntr1 = ((a & 0xF0) >> 4) | ((a & 0x0F) << 4);
- *pntr2 = ((b & 0xF0) >> 4) | ((b & 0x0F) << 4);
- pntr1++; pntr2++;
- count-=2;
- }
- }
-
- /*
- * Must be _after_ HARDWARE_CURSOR_AND_SOURCE_WITH_MASK to avoid wiping
- * out entire source mask.
- */
- if (infoPtr->Flags & HARDWARE_CURSOR_INVERT_MASK) {
- int count = words;
- SCANLINE* pntr = DstM;
- while (count--) {
- *pntr = ~(*pntr);
- pntr++;
- }
- }
-
- if (infoPtr->Flags & HARDWARE_CURSOR_BIT_ORDER_MSBFIRST) {
- for(y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
- y--;
- pSrc+=DstPitch, pMsk+=DstPitch) {
- for(x = 0; x < Pitch; x++) {
- pSrc[x] = REVERSE_BIT_ORDER(pSrc[x]);
- pMsk[x] = REVERSE_BIT_ORDER(pMsk[x]);
- }
- }
- }
-
- return mem;
-}
-
-static unsigned char*
-RealizeCursorInterleave1(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
-{
- unsigned char *DstS, *DstM;
- unsigned char *pntr;
- unsigned char *mem, *mem2;
- int count;
- int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
-
- /* Realize the cursor without interleaving */
- if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
- return NULL;
-
- if (!(mem = xcalloc(1, size))) {
- xfree(mem2);
- return NULL;
- }
-
- /* 1 bit interleave */
- DstS = mem2;
- DstM = DstS + (size >> 1);
- pntr = mem;
- count = size;
- while (count) {
- *pntr++ = ((*DstS&0x01) ) | ((*DstM&0x01) << 1) |
- ((*DstS&0x02) << 1) | ((*DstM&0x02) << 2) |
- ((*DstS&0x04) << 2) | ((*DstM&0x04) << 3) |
- ((*DstS&0x08) << 3) | ((*DstM&0x08) << 4);
- *pntr++ = ((*DstS&0x10) >> 4) | ((*DstM&0x10) >> 3) |
- ((*DstS&0x20) >> 3) | ((*DstM&0x20) >> 2) |
- ((*DstS&0x40) >> 2) | ((*DstM&0x40) >> 1) |
- ((*DstS&0x80) >> 1) | ((*DstM&0x80) );
- DstS++;
- DstM++;
- count-=2;
- }
-
- /* Free the uninterleaved cursor */
- xfree(mem2);
-
- return mem;
-}
-
-static unsigned char*
-RealizeCursorInterleave8(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
-{
- unsigned char *DstS, *DstM;
- unsigned char *pntr;
- unsigned char *mem, *mem2;
- int count;
- int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
-
- /* Realize the cursor without interleaving */
- if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
- return NULL;
-
- if (!(mem = xcalloc(1, size))) {
- xfree(mem2);
- return NULL;
- }
-
- /* 8 bit interleave */
- DstS = mem2;
- DstM = DstS + (size >> 1);
- pntr = mem;
- count = size;
- while (count) {
- *pntr++ = *DstS++;
- *pntr++ = *DstM++;
- count-=2;
- }
-
- /* Free the uninterleaved cursor */
- xfree(mem2);
-
- return mem;
-}
-
-static unsigned char*
-RealizeCursorInterleave16(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
-{
- unsigned short *DstS, *DstM;
- unsigned short *pntr;
- unsigned char *mem, *mem2;
- int count;
- int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
-
- /* Realize the cursor without interleaving */
- if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
- return NULL;
-
- if (!(mem = xcalloc(1, size))) {
- xfree(mem2);
- return NULL;
- }
-
- /* 16 bit interleave */
- DstS = (pointer)mem2;
- DstM = DstS + (size >> 2);
- pntr = (pointer)mem;
- count = (size >> 1);
- while (count) {
- *pntr++ = *DstS++;
- *pntr++ = *DstM++;
- count-=2;
- }
-
- /* Free the uninterleaved cursor */
- xfree(mem2);
-
- return mem;
-}
-
-static unsigned char*
-RealizeCursorInterleave32(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
-{
- CARD32 *DstS, *DstM;
- CARD32 *pntr;
- unsigned char *mem, *mem2;
- int count;
- int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
-
- /* Realize the cursor without interleaving */
- if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
- return NULL;
-
- if (!(mem = xcalloc(1, size))) {
- xfree(mem2);
- return NULL;
- }
-
- /* 32 bit interleave */
- DstS = (pointer)mem2;
- DstM = DstS + (size >> 3);
- pntr = (pointer)mem;
- count = (size >> 2);
- while (count) {
- *pntr++ = *DstS++;
- *pntr++ = *DstM++;
- count-=2;
- }
-
- /* Free the uninterleaved cursor */
- xfree(mem2);
-
- return mem;
-}
-
-static unsigned char*
-RealizeCursorInterleave64(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
-{
- CARD32 *DstS, *DstM;
- CARD32 *pntr;
- unsigned char *mem, *mem2;
- int count;
- int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
-
- /* Realize the cursor without interleaving */
- if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
- return NULL;
-
- if (!(mem = xcalloc(1, size))) {
- xfree(mem2);
- return NULL;
- }
-
- /* 64 bit interleave */
- DstS = (pointer)mem2;
- DstM = DstS + (size >> 3);
- pntr = (pointer)mem;
- count = (size >> 2);
- while (count) {
- *pntr++ = *DstS++;
- *pntr++ = *DstS++;
- *pntr++ = *DstM++;
- *pntr++ = *DstM++;
- count-=4;
- }
-
- /* Free the uninterleaved cursor */
- xfree(mem2);
-
- return mem;
-}
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <string.h>
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include <X11/X.h>
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "xf86str.h"
+#include "cursorstr.h"
+#include "mi.h"
+#include "mipointer.h"
+#include "xf86CursorPriv.h"
+
+#include "servermd.h"
+
+#if BITMAP_SCANLINE_PAD == 64
+
+#if 1
+/* Cursors might be only 32 wide. Give'em a chance */
+#define SCANLINE CARD32
+#define CUR_BITMAP_SCANLINE_PAD 32
+#define CUR_LOG2_BITMAP_PAD 5
+#define REVERSE_BIT_ORDER(w) xf86ReverseBitOrder(w)
+#else
+#define SCANLINE CARD64
+#define CUR_BITMAP_SCANLINE_PAD BITMAP_SCANLINE_PAD
+#define CUR_LOG2_BITMAP_PAD LOG2_BITMAP_PAD
+#define REVERSE_BIT_ORDER(w) xf86CARD64ReverseBits(w)
+static CARD64 xf86CARD64ReverseBits(CARD64 w);
+
+static CARD64
+xf86CARD64ReverseBits(CARD64 w)
+{
+ unsigned char *p = (unsigned char *)&w;
+
+ p[0] = byte_reversed[p[0]];
+ p[1] = byte_reversed[p[1]];
+ p[2] = byte_reversed[p[2]];
+ p[3] = byte_reversed[p[3]];
+ p[4] = byte_reversed[p[4]];
+ p[5] = byte_reversed[p[5]];
+ p[6] = byte_reversed[p[6]];
+ p[7] = byte_reversed[p[7]];
+
+ return w;
+}
+#endif
+
+#else
+
+#define SCANLINE CARD32
+#define CUR_BITMAP_SCANLINE_PAD BITMAP_SCANLINE_PAD
+#define CUR_LOG2_BITMAP_PAD LOG2_BITMAP_PAD
+#define REVERSE_BIT_ORDER(w) xf86ReverseBitOrder(w)
+
+#endif /* BITMAP_SCANLINE_PAD == 64 */
+
+static unsigned char* RealizeCursorInterleave0(xf86CursorInfoPtr, CursorPtr);
+static unsigned char* RealizeCursorInterleave1(xf86CursorInfoPtr, CursorPtr);
+static unsigned char* RealizeCursorInterleave8(xf86CursorInfoPtr, CursorPtr);
+static unsigned char* RealizeCursorInterleave16(xf86CursorInfoPtr, CursorPtr);
+static unsigned char* RealizeCursorInterleave32(xf86CursorInfoPtr, CursorPtr);
+static unsigned char* RealizeCursorInterleave64(xf86CursorInfoPtr, CursorPtr);
+
+Bool
+xf86InitHardwareCursor(ScreenPtr pScreen, xf86CursorInfoPtr infoPtr)
+{
+ if ((infoPtr->MaxWidth <= 0) || (infoPtr->MaxHeight <= 0))
+ return FALSE;
+
+ /* These are required for now */
+ if (!infoPtr->SetCursorPosition ||
+ !infoPtr->LoadCursorImage ||
+ !infoPtr->HideCursor ||
+ !infoPtr->ShowCursor ||
+ !infoPtr->SetCursorColors)
+ return FALSE;
+
+ if (infoPtr->RealizeCursor) {
+ /* Don't overwrite a driver provided Realize Cursor function */
+ } else
+ if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1 & infoPtr->Flags) {
+ infoPtr->RealizeCursor = RealizeCursorInterleave1;
+ } else
+ if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_8 & infoPtr->Flags) {
+ infoPtr->RealizeCursor = RealizeCursorInterleave8;
+ } else
+ if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_16 & infoPtr->Flags) {
+ infoPtr->RealizeCursor = RealizeCursorInterleave16;
+ } else
+ if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 & infoPtr->Flags) {
+ infoPtr->RealizeCursor = RealizeCursorInterleave32;
+ } else
+ if (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 & infoPtr->Flags) {
+ infoPtr->RealizeCursor = RealizeCursorInterleave64;
+ } else { /* not interleaved */
+ infoPtr->RealizeCursor = RealizeCursorInterleave0;
+ }
+
+ infoPtr->pScrn = xf86Screens[pScreen->myNum];
+
+ return TRUE;
+}
+
+void
+xf86SetCursor(ScreenPtr pScreen, CursorPtr pCurs, int x, int y)
+{
+ xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, xf86CursorScreenKey);
+ xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
+ unsigned char *bits;
+
+ if (pCurs == NullCursor) {
+ (*infoPtr->HideCursor)(infoPtr->pScrn);
+ return;
+ }
+
+ bits = dixLookupPrivate(&pCurs->devPrivates, CursorScreenKey(pScreen));
+
+ x -= infoPtr->pScrn->frameX0 + ScreenPriv->HotX;
+ y -= infoPtr->pScrn->frameY0 + ScreenPriv->HotY;
+
+#ifdef ARGB_CURSOR
+ if (!pCurs->bits->argb || !infoPtr->LoadCursorARGB)
+#endif
+ if (!bits) {
+ bits = (*infoPtr->RealizeCursor)(infoPtr, pCurs);
+ dixSetPrivate(&pCurs->devPrivates, CursorScreenKey(pScreen), bits);
+ }
+
+ if (!(infoPtr->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
+ (*infoPtr->HideCursor)(infoPtr->pScrn);
+
+#ifdef ARGB_CURSOR
+ if (pCurs->bits->argb && infoPtr->LoadCursorARGB)
+ (*infoPtr->LoadCursorARGB) (infoPtr->pScrn, pCurs);
+ else
+#endif
+ if (bits)
+ (*infoPtr->LoadCursorImage)(infoPtr->pScrn, bits);
+
+ xf86RecolorCursor(pScreen, pCurs, 1);
+
+ (*infoPtr->SetCursorPosition)(infoPtr->pScrn, x, y);
+
+ (*infoPtr->ShowCursor)(infoPtr->pScrn);
+}
+
+void
+xf86SetTransparentCursor(ScreenPtr pScreen)
+{
+ xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, xf86CursorScreenKey);
+ xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
+
+ if (!ScreenPriv->transparentData)
+ ScreenPriv->transparentData =
+ (*infoPtr->RealizeCursor)(infoPtr, NullCursor);
+
+ if (!(infoPtr->Flags & HARDWARE_CURSOR_UPDATE_UNHIDDEN))
+ (*infoPtr->HideCursor)(infoPtr->pScrn);
+
+ if (ScreenPriv->transparentData)
+ (*infoPtr->LoadCursorImage)(infoPtr->pScrn,
+ ScreenPriv->transparentData);
+
+ (*infoPtr->ShowCursor)(infoPtr->pScrn);
+}
+
+void
+xf86MoveCursor(ScreenPtr pScreen, int x, int y)
+{
+ xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, xf86CursorScreenKey);
+ xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
+
+ x -= infoPtr->pScrn->frameX0 + ScreenPriv->HotX;
+ y -= infoPtr->pScrn->frameY0 + ScreenPriv->HotY;
+
+ (*infoPtr->SetCursorPosition)(infoPtr->pScrn, x, y);
+}
+
+void
+xf86RecolorCursor(ScreenPtr pScreen, CursorPtr pCurs, Bool displayed)
+{
+ xf86CursorScreenPtr ScreenPriv = (xf86CursorScreenPtr)dixLookupPrivate(
+ &pScreen->devPrivates, xf86CursorScreenKey);
+ xf86CursorInfoPtr infoPtr = ScreenPriv->CursorInfoPtr;
+
+#ifdef ARGB_CURSOR
+ /* recoloring isn't applicable to ARGB cursors and drivers
+ shouldn't have to ignore SetCursorColors requests */
+ if (pCurs->bits->argb)
+ return;
+#endif
+
+ if (ScreenPriv->PalettedCursor) {
+ xColorItem sourceColor, maskColor;
+ ColormapPtr pmap = ScreenPriv->pInstalledMap;
+
+ if (!pmap)
+ return;
+
+ sourceColor.red = pCurs->foreRed;
+ sourceColor.green = pCurs->foreGreen;
+ sourceColor.blue = pCurs->foreBlue;
+ FakeAllocColor(pmap, &sourceColor);
+ maskColor.red = pCurs->backRed;
+ maskColor.green = pCurs->backGreen;
+ maskColor.blue = pCurs->backBlue;
+ FakeAllocColor(pmap, &maskColor);
+ FakeFreeColor(pmap, sourceColor.pixel);
+ FakeFreeColor(pmap, maskColor.pixel);
+ (*infoPtr->SetCursorColors)(infoPtr->pScrn,
+ maskColor.pixel, sourceColor.pixel);
+ } else { /* Pass colors in 8-8-8 RGB format */
+ (*infoPtr->SetCursorColors)(infoPtr->pScrn,
+ (pCurs->backBlue >> 8) |
+ ((pCurs->backGreen >> 8) << 8) |
+ ((pCurs->backRed >> 8) << 16),
+ (pCurs->foreBlue >> 8) |
+ ((pCurs->foreGreen >> 8) << 8) |
+ ((pCurs->foreRed >> 8) << 16)
+ );
+ }
+}
+
+/* These functions assume that MaxWidth is a multiple of 32 */
+static unsigned char*
+RealizeCursorInterleave0(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
+{
+
+ SCANLINE *SrcS, *SrcM, *DstS, *DstM;
+ SCANLINE *pSrc, *pMsk;
+ unsigned char *mem;
+ int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
+ int SrcPitch, DstPitch, Pitch, y, x;
+ /* how many words are in the source or mask */
+ int words = size / (CUR_BITMAP_SCANLINE_PAD / 4);
+
+
+ if (!(mem = calloc(1, size)))
+ return NULL;
+
+ if (pCurs == NullCursor) {
+ if (infoPtr->Flags & HARDWARE_CURSOR_INVERT_MASK) {
+ DstM = (SCANLINE*)mem;
+ if (!(infoPtr->Flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK))
+ DstM += words;
+ memset(DstM, -1, words * sizeof(SCANLINE));
+ }
+ return mem;
+ }
+
+ /* SrcPitch == the number of scanlines wide the cursor image is */
+ SrcPitch = (pCurs->bits->width + (BITMAP_SCANLINE_PAD - 1)) >>
+ CUR_LOG2_BITMAP_PAD;
+
+ /* DstPitch is the width of the hw cursor in scanlines */
+ DstPitch = infoPtr->MaxWidth >> CUR_LOG2_BITMAP_PAD;
+ Pitch = SrcPitch < DstPitch ? SrcPitch : DstPitch;
+
+ SrcS = (SCANLINE*)pCurs->bits->source;
+ SrcM = (SCANLINE*)pCurs->bits->mask;
+ DstS = (SCANLINE*)mem;
+ DstM = DstS + words;
+
+ if (infoPtr->Flags & HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK) {
+ SCANLINE *tmp;
+ tmp = DstS; DstS = DstM; DstM = tmp;
+ }
+
+ if (infoPtr->Flags & HARDWARE_CURSOR_AND_SOURCE_WITH_MASK) {
+ for(y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
+ y--;
+ pSrc+=DstPitch, pMsk+=DstPitch, SrcS+=SrcPitch, SrcM+=SrcPitch) {
+ for(x = 0; x < Pitch; x++) {
+ pSrc[x] = SrcS[x] & SrcM[x];
+ pMsk[x] = SrcM[x];
+ }
+ }
+ } else {
+ for(y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
+ y--;
+ pSrc+=DstPitch, pMsk+=DstPitch, SrcS+=SrcPitch, SrcM+=SrcPitch) {
+ for(x = 0; x < Pitch; x++) {
+ pSrc[x] = SrcS[x];
+ pMsk[x] = SrcM[x];
+ }
+ }
+ }
+
+ if (infoPtr->Flags & HARDWARE_CURSOR_NIBBLE_SWAPPED) {
+ int count = size;
+ unsigned char* pntr1 = (unsigned char *)DstS;
+ unsigned char* pntr2 = (unsigned char *)DstM;
+ unsigned char a, b;
+ while (count) {
+
+ a = *pntr1;
+ b = *pntr2;
+ *pntr1 = ((a & 0xF0) >> 4) | ((a & 0x0F) << 4);
+ *pntr2 = ((b & 0xF0) >> 4) | ((b & 0x0F) << 4);
+ pntr1++; pntr2++;
+ count-=2;
+ }
+ }
+
+ /*
+ * Must be _after_ HARDWARE_CURSOR_AND_SOURCE_WITH_MASK to avoid wiping
+ * out entire source mask.
+ */
+ if (infoPtr->Flags & HARDWARE_CURSOR_INVERT_MASK) {
+ int count = words;
+ SCANLINE* pntr = DstM;
+ while (count--) {
+ *pntr = ~(*pntr);
+ pntr++;
+ }
+ }
+
+ if (infoPtr->Flags & HARDWARE_CURSOR_BIT_ORDER_MSBFIRST) {
+ for(y = pCurs->bits->height, pSrc = DstS, pMsk = DstM;
+ y--;
+ pSrc+=DstPitch, pMsk+=DstPitch) {
+ for(x = 0; x < Pitch; x++) {
+ pSrc[x] = REVERSE_BIT_ORDER(pSrc[x]);
+ pMsk[x] = REVERSE_BIT_ORDER(pMsk[x]);
+ }
+ }
+ }
+
+ return mem;
+}
+
+static unsigned char*
+RealizeCursorInterleave1(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
+{
+ unsigned char *DstS, *DstM;
+ unsigned char *pntr;
+ unsigned char *mem, *mem2;
+ int count;
+ int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
+
+ /* Realize the cursor without interleaving */
+ if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
+ return NULL;
+
+ if (!(mem = calloc(1, size))) {
+ free(mem2);
+ return NULL;
+ }
+
+ /* 1 bit interleave */
+ DstS = mem2;
+ DstM = DstS + (size >> 1);
+ pntr = mem;
+ count = size;
+ while (count) {
+ *pntr++ = ((*DstS&0x01) ) | ((*DstM&0x01) << 1) |
+ ((*DstS&0x02) << 1) | ((*DstM&0x02) << 2) |
+ ((*DstS&0x04) << 2) | ((*DstM&0x04) << 3) |
+ ((*DstS&0x08) << 3) | ((*DstM&0x08) << 4);
+ *pntr++ = ((*DstS&0x10) >> 4) | ((*DstM&0x10) >> 3) |
+ ((*DstS&0x20) >> 3) | ((*DstM&0x20) >> 2) |
+ ((*DstS&0x40) >> 2) | ((*DstM&0x40) >> 1) |
+ ((*DstS&0x80) >> 1) | ((*DstM&0x80) );
+ DstS++;
+ DstM++;
+ count-=2;
+ }
+
+ /* Free the uninterleaved cursor */
+ free(mem2);
+
+ return mem;
+}
+
+static unsigned char*
+RealizeCursorInterleave8(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
+{
+ unsigned char *DstS, *DstM;
+ unsigned char *pntr;
+ unsigned char *mem, *mem2;
+ int count;
+ int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
+
+ /* Realize the cursor without interleaving */
+ if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
+ return NULL;
+
+ if (!(mem = calloc(1, size))) {
+ free(mem2);
+ return NULL;
+ }
+
+ /* 8 bit interleave */
+ DstS = mem2;
+ DstM = DstS + (size >> 1);
+ pntr = mem;
+ count = size;
+ while (count) {
+ *pntr++ = *DstS++;
+ *pntr++ = *DstM++;
+ count-=2;
+ }
+
+ /* Free the uninterleaved cursor */
+ free(mem2);
+
+ return mem;
+}
+
+static unsigned char*
+RealizeCursorInterleave16(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
+{
+ unsigned short *DstS, *DstM;
+ unsigned short *pntr;
+ unsigned char *mem, *mem2;
+ int count;
+ int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
+
+ /* Realize the cursor without interleaving */
+ if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
+ return NULL;
+
+ if (!(mem = calloc(1, size))) {
+ free(mem2);
+ return NULL;
+ }
+
+ /* 16 bit interleave */
+ DstS = (pointer)mem2;
+ DstM = DstS + (size >> 2);
+ pntr = (pointer)mem;
+ count = (size >> 1);
+ while (count) {
+ *pntr++ = *DstS++;
+ *pntr++ = *DstM++;
+ count-=2;
+ }
+
+ /* Free the uninterleaved cursor */
+ free(mem2);
+
+ return mem;
+}
+
+static unsigned char*
+RealizeCursorInterleave32(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
+{
+ CARD32 *DstS, *DstM;
+ CARD32 *pntr;
+ unsigned char *mem, *mem2;
+ int count;
+ int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
+
+ /* Realize the cursor without interleaving */
+ if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
+ return NULL;
+
+ if (!(mem = calloc(1, size))) {
+ free(mem2);
+ return NULL;
+ }
+
+ /* 32 bit interleave */
+ DstS = (pointer)mem2;
+ DstM = DstS + (size >> 3);
+ pntr = (pointer)mem;
+ count = (size >> 2);
+ while (count) {
+ *pntr++ = *DstS++;
+ *pntr++ = *DstM++;
+ count-=2;
+ }
+
+ /* Free the uninterleaved cursor */
+ free(mem2);
+
+ return mem;
+}
+
+static unsigned char*
+RealizeCursorInterleave64(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
+{
+ CARD32 *DstS, *DstM;
+ CARD32 *pntr;
+ unsigned char *mem, *mem2;
+ int count;
+ int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
+
+ /* Realize the cursor without interleaving */
+ if (!(mem2 = RealizeCursorInterleave0(infoPtr, pCurs)))
+ return NULL;
+
+ if (!(mem = calloc(1, size))) {
+ free(mem2);
+ return NULL;
+ }
+
+ /* 64 bit interleave */
+ DstS = (pointer)mem2;
+ DstM = DstS + (size >> 3);
+ pntr = (pointer)mem;
+ count = (size >> 2);
+ while (count) {
+ *pntr++ = *DstS++;
+ *pntr++ = *DstS++;
+ *pntr++ = *DstM++;
+ *pntr++ = *DstM++;
+ count-=4;
+ }
+
+ /* Free the uninterleaved cursor */
+ free(mem2);
+
+ return mem;
+}
diff --git a/xorg-server/hw/xfree86/ramdac/xf86RamDac.c b/xorg-server/hw/xfree86/ramdac/xf86RamDac.c
index bd4f3466a..25d450c07 100644
--- a/xorg-server/hw/xfree86/ramdac/xf86RamDac.c
+++ b/xorg-server/hw/xfree86/ramdac/xf86RamDac.c
@@ -1,154 +1,154 @@
-/*
- * Copyright 1998 by Alan Hourihane, Wigan, England.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Alan Hourihane not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Alan Hourihane makes no representations
- * about the suitability of this software for any purpose. It is provided
- * "as is" without express or implied warranty.
- *
- * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
- *
- * Generic RAMDAC access routines.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "xf86.h"
-#include "xf86_OSproc.h"
-
-#include "xf86RamDacPriv.h"
-
-int RamDacHWPrivateIndex = -1;
-int RamDacScreenPrivateIndex = -1;
-
-RamDacRecPtr
-RamDacCreateInfoRec(void)
-{
- RamDacRecPtr infoRec;
-
- infoRec = xcalloc(1, sizeof(RamDacRec));
-
- return infoRec;
-}
-
-RamDacHelperRecPtr
-RamDacHelperCreateInfoRec(void)
-{
- RamDacHelperRecPtr infoRec;
-
- infoRec = xcalloc(1, sizeof(RamDacHelperRec));
-
- return infoRec;
-}
-
-void
-RamDacDestroyInfoRec(RamDacRecPtr infoRec)
-{
- xfree(infoRec);
-}
-
-void
-RamDacHelperDestroyInfoRec(RamDacHelperRecPtr infoRec)
-{
- xfree(infoRec);
-}
-
-Bool
-RamDacInit(ScrnInfoPtr pScrn, RamDacRecPtr ramdacPriv)
-{
- RamDacScreenRecPtr ramdacScrPtr;
-
- /*
- * make sure the RamDacRec is allocated
- */
- if (!RamDacGetRec(pScrn))
- return FALSE;
- ramdacScrPtr =
- ((RamDacScreenRecPtr) (pScrn)->privates[RamDacGetScreenIndex()].ptr);
- ramdacScrPtr->RamDacRec = ramdacPriv;
-
- return(TRUE);
-}
-
-void
-RamDacGetRecPrivate(void)
-{
- if (RamDacHWPrivateIndex < 0)
- RamDacHWPrivateIndex = xf86AllocateScrnInfoPrivateIndex();
- if (RamDacScreenPrivateIndex < 0)
- RamDacScreenPrivateIndex = xf86AllocateScrnInfoPrivateIndex();
- return;
-}
-
-Bool
-RamDacGetRec(ScrnInfoPtr scrp)
-{
- RamDacGetRecPrivate();
- /*
- * New privates are always set to NULL, so we can check if the allocation
- * has already been done.
- */
- if (scrp->privates[RamDacHWPrivateIndex].ptr != NULL)
- return TRUE;
- if (scrp->privates[RamDacScreenPrivateIndex].ptr != NULL)
- return TRUE;
-
- scrp->privates[RamDacHWPrivateIndex].ptr =
- xnfcalloc(sizeof(RamDacHWRec), 1);
- scrp->privates[RamDacScreenPrivateIndex].ptr =
- xnfcalloc(sizeof(RamDacScreenRec), 1);
-
- return TRUE;
-}
-
-void
-RamDacFreeRec(ScrnInfoPtr pScrn)
-{
- RamDacHWRecPtr ramdacHWPtr;
- RamDacScreenRecPtr ramdacScrPtr;
-
- if (RamDacHWPrivateIndex < 0)
- return;
-
- if (RamDacScreenPrivateIndex < 0)
- return;
-
- ramdacHWPtr = RAMDACHWPTR(pScrn);
- ramdacScrPtr = ((RamDacScreenRecPtr)
- (pScrn)->privates[RamDacGetScreenIndex()].ptr);
-
- if (ramdacHWPtr)
- xfree(ramdacHWPtr);
- ramdacHWPtr = NULL;
-
- if (ramdacScrPtr)
- xfree(ramdacScrPtr);
- ramdacScrPtr = NULL;
-}
-
-int
-RamDacGetHWIndex(void)
-{
- return RamDacHWPrivateIndex;
-}
-
-int
-RamDacGetScreenIndex(void)
-{
- return RamDacScreenPrivateIndex;
-}
+/*
+ * Copyright 1998 by Alan Hourihane, Wigan, England.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Alan Hourihane not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Alan Hourihane makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * ALAN HOURIHANE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL ALAN HOURIHANE BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Authors: Alan Hourihane, <alanh@fairlite.demon.co.uk>
+ *
+ * Generic RAMDAC access routines.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include "xf86RamDacPriv.h"
+
+int RamDacHWPrivateIndex = -1;
+int RamDacScreenPrivateIndex = -1;
+
+RamDacRecPtr
+RamDacCreateInfoRec(void)
+{
+ RamDacRecPtr infoRec;
+
+ infoRec = calloc(1, sizeof(RamDacRec));
+
+ return infoRec;
+}
+
+RamDacHelperRecPtr
+RamDacHelperCreateInfoRec(void)
+{
+ RamDacHelperRecPtr infoRec;
+
+ infoRec = calloc(1, sizeof(RamDacHelperRec));
+
+ return infoRec;
+}
+
+void
+RamDacDestroyInfoRec(RamDacRecPtr infoRec)
+{
+ free(infoRec);
+}
+
+void
+RamDacHelperDestroyInfoRec(RamDacHelperRecPtr infoRec)
+{
+ free(infoRec);
+}
+
+Bool
+RamDacInit(ScrnInfoPtr pScrn, RamDacRecPtr ramdacPriv)
+{
+ RamDacScreenRecPtr ramdacScrPtr;
+
+ /*
+ * make sure the RamDacRec is allocated
+ */
+ if (!RamDacGetRec(pScrn))
+ return FALSE;
+ ramdacScrPtr =
+ ((RamDacScreenRecPtr) (pScrn)->privates[RamDacGetScreenIndex()].ptr);
+ ramdacScrPtr->RamDacRec = ramdacPriv;
+
+ return(TRUE);
+}
+
+void
+RamDacGetRecPrivate(void)
+{
+ if (RamDacHWPrivateIndex < 0)
+ RamDacHWPrivateIndex = xf86AllocateScrnInfoPrivateIndex();
+ if (RamDacScreenPrivateIndex < 0)
+ RamDacScreenPrivateIndex = xf86AllocateScrnInfoPrivateIndex();
+ return;
+}
+
+Bool
+RamDacGetRec(ScrnInfoPtr scrp)
+{
+ RamDacGetRecPrivate();
+ /*
+ * New privates are always set to NULL, so we can check if the allocation
+ * has already been done.
+ */
+ if (scrp->privates[RamDacHWPrivateIndex].ptr != NULL)
+ return TRUE;
+ if (scrp->privates[RamDacScreenPrivateIndex].ptr != NULL)
+ return TRUE;
+
+ scrp->privates[RamDacHWPrivateIndex].ptr =
+ xnfcalloc(sizeof(RamDacHWRec), 1);
+ scrp->privates[RamDacScreenPrivateIndex].ptr =
+ xnfcalloc(sizeof(RamDacScreenRec), 1);
+
+ return TRUE;
+}
+
+void
+RamDacFreeRec(ScrnInfoPtr pScrn)
+{
+ RamDacHWRecPtr ramdacHWPtr;
+ RamDacScreenRecPtr ramdacScrPtr;
+
+ if (RamDacHWPrivateIndex < 0)
+ return;
+
+ if (RamDacScreenPrivateIndex < 0)
+ return;
+
+ ramdacHWPtr = RAMDACHWPTR(pScrn);
+ ramdacScrPtr = ((RamDacScreenRecPtr)
+ (pScrn)->privates[RamDacGetScreenIndex()].ptr);
+
+ if (ramdacHWPtr)
+ free(ramdacHWPtr);
+ ramdacHWPtr = NULL;
+
+ if (ramdacScrPtr)
+ free(ramdacScrPtr);
+ ramdacScrPtr = NULL;
+}
+
+int
+RamDacGetHWIndex(void)
+{
+ return RamDacHWPrivateIndex;
+}
+
+int
+RamDacGetScreenIndex(void)
+{
+ return RamDacScreenPrivateIndex;
+}
diff --git a/xorg-server/hw/xfree86/shadowfb/shadow.c b/xorg-server/hw/xfree86/shadowfb/shadow.c
index 1c8170104..9e847f4d2 100644
--- a/xorg-server/hw/xfree86/shadowfb/shadow.c
+++ b/xorg-server/hw/xfree86/shadowfb/shadow.c
@@ -1,1729 +1,1729 @@
-/*
- Copyright (C) 1999. The XFree86 Project Inc.
-
- Written by Mark Vojkovich (mvojkovi@ucsd.edu)
-
- Pre-fb-write callbacks and RENDER support - Nolan Leake (nolan@vmware.com)
-*/
-
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "pixmapstr.h"
-#include "input.h"
-#include <X11/fonts/font.h>
-#include "mi.h"
-#include "scrnintstr.h"
-#include "windowstr.h"
-#include "gcstruct.h"
-#include "dixfontstr.h"
-#include <X11/fonts/fontstruct.h>
-#include "xf86.h"
-#include "xf86str.h"
-#include "shadowfb.h"
-
-# include "picturestr.h"
-
-static Bool ShadowCloseScreen (int i, ScreenPtr pScreen);
-static void ShadowCopyWindow(
- WindowPtr pWin,
- DDXPointRec ptOldOrg,
- RegionPtr prgn
-);
-static Bool ShadowCreateGC(GCPtr pGC);
-static Bool ShadowModifyPixmapHeader(
- PixmapPtr pPixmap,
- int width,
- int height,
- int depth,
- int bitsPerPixel,
- int devKind,
- pointer pPixData
-);
-
-static Bool ShadowEnterVT(int index, int flags);
-static void ShadowLeaveVT(int index, int flags);
-
-static void ShadowComposite(
- CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst,
- INT16 yDst,
- CARD16 width,
- CARD16 height
-);
-
-
-typedef struct {
- ScrnInfoPtr pScrn;
- RefreshAreaFuncPtr preRefresh;
- RefreshAreaFuncPtr postRefresh;
- CloseScreenProcPtr CloseScreen;
- CopyWindowProcPtr CopyWindow;
- CreateGCProcPtr CreateGC;
- ModifyPixmapHeaderProcPtr ModifyPixmapHeader;
- CompositeProcPtr Composite;
- Bool (*EnterVT)(int, int);
- void (*LeaveVT)(int, int);
- Bool vtSema;
-} ShadowScreenRec, *ShadowScreenPtr;
-
-typedef struct {
- GCOps *ops;
- GCFuncs *funcs;
-} ShadowGCRec, *ShadowGCPtr;
-
-
-static int ShadowScreenKeyIndex;
-static DevPrivateKey ShadowScreenKey = &ShadowScreenKeyIndex;
-static int ShadowGCKeyIndex;
-static DevPrivateKey ShadowGCKey = &ShadowGCKeyIndex;
-
-#define GET_SCREEN_PRIVATE(pScreen) \
- (ShadowScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates, ShadowScreenKey)
-#define GET_GC_PRIVATE(pGC) \
- (ShadowGCPtr)dixLookupPrivate(&(pGC)->devPrivates, ShadowGCKey)
-
-#define SHADOW_GC_FUNC_PROLOGUE(pGC)\
- ShadowGCPtr pGCPriv = GET_GC_PRIVATE(pGC);\
- (pGC)->funcs = pGCPriv->funcs;\
- if(pGCPriv->ops)\
- (pGC)->ops = pGCPriv->ops
-
-#define SHADOW_GC_FUNC_EPILOGUE(pGC)\
- pGCPriv->funcs = (pGC)->funcs;\
- (pGC)->funcs = &ShadowGCFuncs;\
- if(pGCPriv->ops) {\
- pGCPriv->ops = (pGC)->ops;\
- (pGC)->ops = &ShadowGCOps;\
- }
-
-#define SHADOW_GC_OP_PROLOGUE(pGC)\
- ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pGC->pScreen); \
- ShadowGCPtr pGCPriv = GET_GC_PRIVATE(pGC);\
- GCFuncs *oldFuncs = pGC->funcs;\
- pGC->funcs = pGCPriv->funcs;\
- pGC->ops = pGCPriv->ops
-
-
-#define SHADOW_GC_OP_EPILOGUE(pGC)\
- pGCPriv->ops = pGC->ops;\
- pGC->funcs = oldFuncs;\
- pGC->ops = &ShadowGCOps
-
-#define IS_VISIBLE(pWin) (pPriv->vtSema && \
- (((WindowPtr)pWin)->visibility != VisibilityFullyObscured))
-
-#define TRIM_BOX(box, pGC) { \
- BoxPtr extents = &pGC->pCompositeClip->extents;\
- if(box.x1 < extents->x1) box.x1 = extents->x1; \
- if(box.x2 > extents->x2) box.x2 = extents->x2; \
- if(box.y1 < extents->y1) box.y1 = extents->y1; \
- if(box.y2 > extents->y2) box.y2 = extents->y2; \
- }
-
-#define TRANSLATE_BOX(box, pDraw) { \
- box.x1 += pDraw->x; \
- box.x2 += pDraw->x; \
- box.y1 += pDraw->y; \
- box.y2 += pDraw->y; \
- }
-
-#define TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC) { \
- TRANSLATE_BOX(box, pDraw); \
- TRIM_BOX(box, pGC); \
- }
-
-#define BOX_NOT_EMPTY(box) \
- (((box.x2 - box.x1) > 0) && ((box.y2 - box.y1) > 0))
-
-
-
-Bool
-ShadowFBInit2 (
- ScreenPtr pScreen,
- RefreshAreaFuncPtr preRefreshArea,
- RefreshAreaFuncPtr postRefreshArea
-){
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- ShadowScreenPtr pPriv;
- PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
-
- if(!preRefreshArea && !postRefreshArea) return FALSE;
-
- if(!dixRequestPrivate(ShadowGCKey, sizeof(ShadowGCRec)))
- return FALSE;
-
- if(!(pPriv = (ShadowScreenPtr)xalloc(sizeof(ShadowScreenRec))))
- return FALSE;
-
- dixSetPrivate(&pScreen->devPrivates, ShadowScreenKey, pPriv);
-
- pPriv->pScrn = pScrn;
- pPriv->preRefresh = preRefreshArea;
- pPriv->postRefresh = postRefreshArea;
- pPriv->vtSema = TRUE;
-
- pPriv->CloseScreen = pScreen->CloseScreen;
- pPriv->CopyWindow = pScreen->CopyWindow;
- pPriv->CreateGC = pScreen->CreateGC;
- pPriv->ModifyPixmapHeader = pScreen->ModifyPixmapHeader;
-
- pPriv->EnterVT = pScrn->EnterVT;
- pPriv->LeaveVT = pScrn->LeaveVT;
-
- pScreen->CloseScreen = ShadowCloseScreen;
- pScreen->CopyWindow = ShadowCopyWindow;
- pScreen->CreateGC = ShadowCreateGC;
- pScreen->ModifyPixmapHeader = ShadowModifyPixmapHeader;
-
- pScrn->EnterVT = ShadowEnterVT;
- pScrn->LeaveVT = ShadowLeaveVT;
-
- if(ps) {
- pPriv->Composite = ps->Composite;
- ps->Composite = ShadowComposite;
- }
-
- return TRUE;
-}
-
-Bool
-ShadowFBInit (
- ScreenPtr pScreen,
- RefreshAreaFuncPtr refreshArea
-){
- return ShadowFBInit2(pScreen, NULL, refreshArea);
-}
-
-/**********************************************************/
-
-static Bool
-ShadowEnterVT(int index, int flags)
-{
- ScrnInfoPtr pScrn = xf86Screens[index];
- ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pScrn->pScreen);
-
- if((*pPriv->EnterVT)(index, flags)) {
- pPriv->vtSema = TRUE;
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void
-ShadowLeaveVT(int index, int flags)
-{
- ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(xf86Screens[index]->pScreen);
-
- pPriv->vtSema = FALSE;
-
- (*pPriv->LeaveVT)(index, flags);
-}
-
-/**********************************************************/
-
-
-static Bool
-ShadowCloseScreen (int i, ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pScreen);
- PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
-
- pScreen->CloseScreen = pPriv->CloseScreen;
- pScreen->CopyWindow = pPriv->CopyWindow;
- pScreen->CreateGC = pPriv->CreateGC;
- pScreen->ModifyPixmapHeader = pPriv->ModifyPixmapHeader;
-
- pScrn->EnterVT = pPriv->EnterVT;
- pScrn->LeaveVT = pPriv->LeaveVT;
-
- if(ps) {
- ps->Composite = pPriv->Composite;
- }
-
- xfree((pointer)pPriv);
-
- return (*pScreen->CloseScreen) (i, pScreen);
-}
-
-static void
-ShadowCopyWindow(
- WindowPtr pWin,
- DDXPointRec ptOldOrg,
- RegionPtr prgn
-){
- ScreenPtr pScreen = pWin->drawable.pScreen;
- ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pScreen);
- int num = 0;
- RegionRec rgnDst;
-
- if (pPriv->vtSema) {
- REGION_NULL(pWin->drawable.pScreen, &rgnDst);
- REGION_COPY(pWin->drawable.pScreen, &rgnDst, prgn);
-
- REGION_TRANSLATE(pWin->drawable.pScreen, &rgnDst,
- pWin->drawable.x - ptOldOrg.x,
- pWin->drawable.y - ptOldOrg.y);
- REGION_INTERSECT(pScreen, &rgnDst, &pWin->borderClip, &rgnDst);
- if ((num = REGION_NUM_RECTS(&rgnDst))) {
- if(pPriv->preRefresh)
- (*pPriv->preRefresh)(pPriv->pScrn, num, REGION_RECTS(&rgnDst));
- } else {
- REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
- }
- }
-
- pScreen->CopyWindow = pPriv->CopyWindow;
- (*pScreen->CopyWindow) (pWin, ptOldOrg, prgn);
- pScreen->CopyWindow = ShadowCopyWindow;
-
- if (num) {
- if (pPriv->postRefresh)
- (*pPriv->postRefresh)(pPriv->pScrn, num, REGION_RECTS(&rgnDst));
- REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
- }
-}
-
-static Bool
-ShadowModifyPixmapHeader(
- PixmapPtr pPixmap,
- int width,
- int height,
- int depth,
- int bitsPerPixel,
- int devKind,
- pointer pPixData
-)
-{
- ScreenPtr pScreen;
- ScrnInfoPtr pScrn;
- ShadowScreenPtr pPriv;
- Bool retval;
- PixmapPtr pScreenPix;
-
- if (!pPixmap)
- return FALSE;
-
- pScreen = pPixmap->drawable.pScreen;
- pScrn = xf86Screens[pScreen->myNum];
-
- pScreenPix = (*pScreen->GetScreenPixmap)(pScreen);
-
- if (pPixmap == pScreenPix && !pScrn->vtSema)
- pScreenPix->devPrivate = pScrn->pixmapPrivate;
-
- pPriv = GET_SCREEN_PRIVATE(pScreen);
-
- pScreen->ModifyPixmapHeader = pPriv->ModifyPixmapHeader;
- retval = (*pScreen->ModifyPixmapHeader)(pPixmap,
- width, height, depth, bitsPerPixel, devKind, pPixData);
- pScreen->ModifyPixmapHeader = ShadowModifyPixmapHeader;
-
- if (pPixmap == pScreenPix && !pScrn->vtSema)
- {
- pScrn->pixmapPrivate = pScreenPix->devPrivate;
- pScreenPix->devPrivate.ptr = 0;
- }
- return retval;
-}
-
-static void
-ShadowComposite(
- CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst,
- INT16 yDst,
- CARD16 width,
- CARD16 height
-){
- ScreenPtr pScreen = pDst->pDrawable->pScreen;
- ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pScreen);
- PictureScreenPtr ps = GetPictureScreen(pScreen);
- BoxRec box;
- BoxPtr extents;
- Bool boxNotEmpty = FALSE;
-
- if (pPriv->vtSema
- && pDst->pDrawable->type == DRAWABLE_WINDOW) {
-
- box.x1 = pDst->pDrawable->x + xDst;
- box.y1 = pDst->pDrawable->y + yDst;
- box.x2 = box.x1 + width;
- box.y2 = box.y1 + height;
-
- extents = &pDst->pCompositeClip->extents;
- if(box.x1 < extents->x1) box.x1 = extents->x1;
- if(box.x2 > extents->x2) box.x2 = extents->x2;
- if(box.y1 < extents->y1) box.y1 = extents->y1;
- if(box.y2 > extents->y2) box.y2 = extents->y2;
-
- if (BOX_NOT_EMPTY(box)) {
- if (pPriv->preRefresh)
- (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
- }
-
- ps->Composite = pPriv->Composite;
- (*ps->Composite)(op, pSrc, pMask, pDst, xSrc, ySrc,
- xMask, yMask, xDst, yDst, width, height);
- ps->Composite = ShadowComposite;
-
- if (pPriv->postRefresh && boxNotEmpty) {
- (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
- }
-}
-
-/**********************************************************/
-
-static void ShadowValidateGC(GCPtr, unsigned long, DrawablePtr);
-static void ShadowChangeGC(GCPtr, unsigned long);
-static void ShadowCopyGC(GCPtr, unsigned long, GCPtr);
-static void ShadowDestroyGC(GCPtr);
-static void ShadowChangeClip(GCPtr, int, pointer, int);
-static void ShadowDestroyClip(GCPtr);
-static void ShadowCopyClip(GCPtr, GCPtr);
-
-GCFuncs ShadowGCFuncs = {
- ShadowValidateGC, ShadowChangeGC, ShadowCopyGC, ShadowDestroyGC,
- ShadowChangeClip, ShadowDestroyClip, ShadowCopyClip
-};
-
-
-extern GCOps ShadowGCOps;
-
-static Bool
-ShadowCreateGC(GCPtr pGC)
-{
- ScreenPtr pScreen = pGC->pScreen;
- ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pScreen);
- ShadowGCPtr pGCPriv = GET_GC_PRIVATE(pGC);
- Bool ret;
-
- pScreen->CreateGC = pPriv->CreateGC;
- if((ret = (*pScreen->CreateGC) (pGC))) {
- pGCPriv->ops = NULL;
- pGCPriv->funcs = pGC->funcs;
- pGC->funcs = &ShadowGCFuncs;
- }
- pScreen->CreateGC = ShadowCreateGC;
-
- return ret;
-}
-
-
-static void
-ShadowValidateGC(
- GCPtr pGC,
- unsigned long changes,
- DrawablePtr pDraw
-){
- SHADOW_GC_FUNC_PROLOGUE (pGC);
- (*pGC->funcs->ValidateGC)(pGC, changes, pDraw);
- if(pDraw->type == DRAWABLE_WINDOW)
- pGCPriv->ops = pGC->ops; /* just so it's not NULL */
- else
- pGCPriv->ops = NULL;
- SHADOW_GC_FUNC_EPILOGUE (pGC);
-}
-
-
-static void
-ShadowDestroyGC(GCPtr pGC)
-{
- SHADOW_GC_FUNC_PROLOGUE (pGC);
- (*pGC->funcs->DestroyGC)(pGC);
- SHADOW_GC_FUNC_EPILOGUE (pGC);
-}
-
-static void
-ShadowChangeGC (
- GCPtr pGC,
- unsigned long mask
-){
- SHADOW_GC_FUNC_PROLOGUE (pGC);
- (*pGC->funcs->ChangeGC) (pGC, mask);
- SHADOW_GC_FUNC_EPILOGUE (pGC);
-}
-
-static void
-ShadowCopyGC (
- GCPtr pGCSrc,
- unsigned long mask,
- GCPtr pGCDst
-){
- SHADOW_GC_FUNC_PROLOGUE (pGCDst);
- (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
- SHADOW_GC_FUNC_EPILOGUE (pGCDst);
-}
-
-static void
-ShadowChangeClip (
- GCPtr pGC,
- int type,
- pointer pvalue,
- int nrects
-){
- SHADOW_GC_FUNC_PROLOGUE (pGC);
- (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
- SHADOW_GC_FUNC_EPILOGUE (pGC);
-}
-
-static void
-ShadowCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
-{
- SHADOW_GC_FUNC_PROLOGUE (pgcDst);
- (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
- SHADOW_GC_FUNC_EPILOGUE (pgcDst);
-}
-
-static void
-ShadowDestroyClip(GCPtr pGC)
-{
- SHADOW_GC_FUNC_PROLOGUE (pGC);
- (* pGC->funcs->DestroyClip)(pGC);
- SHADOW_GC_FUNC_EPILOGUE (pGC);
-}
-
-
-
-
-/**********************************************************/
-
-
-static void
-ShadowFillSpans(
- DrawablePtr pDraw,
- GC *pGC,
- int nInit,
- DDXPointPtr pptInit,
- int *pwidthInit,
- int fSorted
-){
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if(IS_VISIBLE(pDraw) && nInit) {
- DDXPointPtr ppt = pptInit;
- int *pwidth = pwidthInit;
- int i = nInit;
- BoxRec box;
- Bool boxNotEmpty = FALSE;
-
- box.x1 = ppt->x;
- box.x2 = box.x1 + *pwidth;
- box.y2 = box.y1 = ppt->y;
-
- while(--i) {
- ppt++;
- pwidth++;
- if(box.x1 > ppt->x) box.x1 = ppt->x;
- if(box.x2 < (ppt->x + *pwidth))
- box.x2 = ppt->x + *pwidth;
- if(box.y1 > ppt->y) box.y1 = ppt->y;
- else if(box.y2 < ppt->y) box.y2 = ppt->y;
- }
-
- box.y2++;
-
- if(!pGC->miTranslate) {
- TRANSLATE_BOX(box, pDraw);
- }
- TRIM_BOX(box, pGC);
-
- if(BOX_NOT_EMPTY(box)) {
- if(pPriv->preRefresh)
- (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
-
- (*pGC->ops->FillSpans)(pDraw, pGC, nInit, pptInit, pwidthInit, fSorted);
-
- if(boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
- } else
- (*pGC->ops->FillSpans)(pDraw, pGC, nInit, pptInit, pwidthInit, fSorted);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-}
-
-static void
-ShadowSetSpans(
- DrawablePtr pDraw,
- GCPtr pGC,
- char *pcharsrc,
- DDXPointPtr pptInit,
- int *pwidthInit,
- int nspans,
- int fSorted
-){
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if(IS_VISIBLE(pDraw) && nspans) {
- DDXPointPtr ppt = pptInit;
- int *pwidth = pwidthInit;
- int i = nspans;
- BoxRec box;
- Bool boxNotEmpty = FALSE;
-
- box.x1 = ppt->x;
- box.x2 = box.x1 + *pwidth;
- box.y2 = box.y1 = ppt->y;
-
- while(--i) {
- ppt++;
- pwidth++;
- if(box.x1 > ppt->x) box.x1 = ppt->x;
- if(box.x2 < (ppt->x + *pwidth))
- box.x2 = ppt->x + *pwidth;
- if(box.y1 > ppt->y) box.y1 = ppt->y;
- else if(box.y2 < ppt->y) box.y2 = ppt->y;
- }
-
- box.y2++;
-
- if(!pGC->miTranslate) {
- TRANSLATE_BOX(box, pDraw);
- }
- TRIM_BOX(box, pGC);
-
- if(BOX_NOT_EMPTY(box)) {
- if(pPriv->preRefresh)
- (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
-
- (*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, pptInit,
- pwidthInit, nspans, fSorted);
-
- if(boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
- } else
- (*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, pptInit,
- pwidthInit, nspans, fSorted);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-}
-
-static void
-ShadowPutImage(
- DrawablePtr pDraw,
- GCPtr pGC,
- int depth,
- int x, int y, int w, int h,
- int leftPad,
- int format,
- char *pImage
-){
- BoxRec box;
- Bool boxNotEmpty = FALSE;
-
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if(IS_VISIBLE(pDraw)) {
- box.x1 = x + pDraw->x;
- box.x2 = box.x1 + w;
- box.y1 = y + pDraw->y;
- box.y2 = box.y1 + h;
-
- TRIM_BOX(box, pGC);
- if(BOX_NOT_EMPTY(box)) {
- if(pPriv->preRefresh)
- (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
- }
-
- (*pGC->ops->PutImage)(pDraw, pGC, depth, x, y, w, h,
- leftPad, format, pImage);
-
- if(boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-
-}
-
-static RegionPtr
-ShadowCopyArea(
- DrawablePtr pSrc,
- DrawablePtr pDst,
- GC *pGC,
- int srcx, int srcy,
- int width, int height,
- int dstx, int dsty
-){
- RegionPtr ret;
- BoxRec box;
- Bool boxNotEmpty = FALSE;
-
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if(IS_VISIBLE(pDst)) {
- box.x1 = dstx + pDst->x;
- box.x2 = box.x1 + width;
- box.y1 = dsty + pDst->y;
- box.y2 = box.y1 + height;
-
- TRIM_BOX(box, pGC);
- if(BOX_NOT_EMPTY(box)) {
- if(pPriv->preRefresh)
- (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
- }
-
- ret = (*pGC->ops->CopyArea)(pSrc, pDst,
- pGC, srcx, srcy, width, height, dstx, dsty);
-
- if(boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-
- return ret;
-}
-
-static RegionPtr
-ShadowCopyPlane(
- DrawablePtr pSrc,
- DrawablePtr pDst,
- GCPtr pGC,
- int srcx, int srcy,
- int width, int height,
- int dstx, int dsty,
- unsigned long bitPlane
-){
- RegionPtr ret;
- BoxRec box;
- Bool boxNotEmpty = FALSE;
-
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if(IS_VISIBLE(pDst)) {
- box.x1 = dstx + pDst->x;
- box.x2 = box.x1 + width;
- box.y1 = dsty + pDst->y;
- box.y2 = box.y1 + height;
-
- TRIM_BOX(box, pGC);
- if(BOX_NOT_EMPTY(box)) {
- if(pPriv->preRefresh)
- (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
- }
-
- ret = (*pGC->ops->CopyPlane)(pSrc, pDst,
- pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
-
- if(boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-
- return ret;
-}
-
-static void
-ShadowPolyPoint(
- DrawablePtr pDraw,
- GCPtr pGC,
- int mode,
- int nptInit,
- xPoint *pptInit
-){
- BoxRec box;
- Bool boxNotEmpty = FALSE;
-
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if(IS_VISIBLE(pDraw) && nptInit) {
- xPoint *ppt = pptInit;
- int npt = nptInit;
-
- box.x2 = box.x1 = pptInit->x;
- box.y2 = box.y1 = pptInit->y;
-
- /* this could be slow if the points were spread out */
-
- while(--npt) {
- ppt++;
- if(box.x1 > ppt->x) box.x1 = ppt->x;
- else if(box.x2 < ppt->x) box.x2 = ppt->x;
- if(box.y1 > ppt->y) box.y1 = ppt->y;
- else if(box.y2 < ppt->y) box.y2 = ppt->y;
- }
-
- box.x2++;
- box.y2++;
-
- TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
- if(BOX_NOT_EMPTY(box)) {
- if(pPriv->preRefresh)
- (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
- }
-
- (*pGC->ops->PolyPoint)(pDraw, pGC, mode, nptInit, pptInit);
-
- if(boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-}
-
-static void
-ShadowPolylines(
- DrawablePtr pDraw,
- GCPtr pGC,
- int mode,
- int nptInit,
- DDXPointPtr pptInit
-){
- BoxRec box;
- Bool boxNotEmpty = FALSE;
-
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if(IS_VISIBLE(pDraw) && nptInit) {
- DDXPointPtr ppt = pptInit;
- int npt = nptInit;
- int extra = pGC->lineWidth >> 1;
-
- box.x2 = box.x1 = pptInit->x;
- box.y2 = box.y1 = pptInit->y;
-
- if(npt > 1) {
- if(pGC->joinStyle == JoinMiter)
- extra = 6 * pGC->lineWidth;
- else if(pGC->capStyle == CapProjecting)
- extra = pGC->lineWidth;
- }
-
- if(mode == CoordModePrevious) {
- int x = box.x1;
- int y = box.y1;
- while(--npt) {
- ppt++;
- x += ppt->x;
- y += ppt->y;
- if(box.x1 > x) box.x1 = x;
- else if(box.x2 < x) box.x2 = x;
- if(box.y1 > y) box.y1 = y;
- else if(box.y2 < y) box.y2 = y;
- }
- } else {
- while(--npt) {
- ppt++;
- if(box.x1 > ppt->x) box.x1 = ppt->x;
- else if(box.x2 < ppt->x) box.x2 = ppt->x;
- if(box.y1 > ppt->y) box.y1 = ppt->y;
- else if(box.y2 < ppt->y) box.y2 = ppt->y;
- }
- }
-
- box.x2++;
- box.y2++;
-
- if(extra) {
- box.x1 -= extra;
- box.x2 += extra;
- box.y1 -= extra;
- box.y2 += extra;
- }
-
- TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
- if(BOX_NOT_EMPTY(box)) {
- if(pPriv->preRefresh)
- (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
- }
-
- (*pGC->ops->Polylines)(pDraw, pGC, mode, nptInit, pptInit);
-
- if(boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-}
-
-static void
-ShadowPolySegment(
- DrawablePtr pDraw,
- GCPtr pGC,
- int nsegInit,
- xSegment *pSegInit
-){
- BoxRec box;
- Bool boxNotEmpty = FALSE;
-
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if(IS_VISIBLE(pDraw) && nsegInit) {
- int extra = pGC->lineWidth;
- xSegment *pSeg = pSegInit;
- int nseg = nsegInit;
-
- if(pGC->capStyle != CapProjecting)
- extra >>= 1;
-
- if(pSeg->x2 > pSeg->x1) {
- box.x1 = pSeg->x1;
- box.x2 = pSeg->x2;
- } else {
- box.x2 = pSeg->x1;
- box.x1 = pSeg->x2;
- }
-
- if(pSeg->y2 > pSeg->y1) {
- box.y1 = pSeg->y1;
- box.y2 = pSeg->y2;
- } else {
- box.y2 = pSeg->y1;
- box.y1 = pSeg->y2;
- }
-
- while(--nseg) {
- pSeg++;
- if(pSeg->x2 > pSeg->x1) {
- if(pSeg->x1 < box.x1) box.x1 = pSeg->x1;
- if(pSeg->x2 > box.x2) box.x2 = pSeg->x2;
- } else {
- if(pSeg->x2 < box.x1) box.x1 = pSeg->x2;
- if(pSeg->x1 > box.x2) box.x2 = pSeg->x1;
- }
- if(pSeg->y2 > pSeg->y1) {
- if(pSeg->y1 < box.y1) box.y1 = pSeg->y1;
- if(pSeg->y2 > box.y2) box.y2 = pSeg->y2;
- } else {
- if(pSeg->y2 < box.y1) box.y1 = pSeg->y2;
- if(pSeg->y1 > box.y2) box.y2 = pSeg->y1;
- }
- }
-
- box.x2++;
- box.y2++;
-
- if(extra) {
- box.x1 -= extra;
- box.x2 += extra;
- box.y1 -= extra;
- box.y2 += extra;
- }
-
- TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
- if(BOX_NOT_EMPTY(box)) {
- if(pPriv->preRefresh)
- (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
- }
-
- (*pGC->ops->PolySegment)(pDraw, pGC, nsegInit, pSegInit);
-
- if(boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-}
-
-static void
-ShadowPolyRectangle(
- DrawablePtr pDraw,
- GCPtr pGC,
- int nRectsInit,
- xRectangle *pRectsInit
-){
- BoxRec box;
- BoxPtr pBoxInit = NULL;
- Bool boxNotEmpty = FALSE;
- int num = 0;
-
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if(IS_VISIBLE(pDraw) && nRectsInit) {
- xRectangle *pRects = pRectsInit;
- int nRects = nRectsInit;
-
- if(nRects >= 32) {
- int extra = pGC->lineWidth >> 1;
-
- box.x1 = pRects->x;
- box.x2 = box.x1 + pRects->width;
- box.y1 = pRects->y;
- box.y2 = box.y1 + pRects->height;
-
- while(--nRects) {
- pRects++;
- if(box.x1 > pRects->x) box.x1 = pRects->x;
- if(box.x2 < (pRects->x + pRects->width))
- box.x2 = pRects->x + pRects->width;
- if(box.y1 > pRects->y) box.y1 = pRects->y;
- if(box.y2 < (pRects->y + pRects->height))
- box.y2 = pRects->y + pRects->height;
- }
-
- if(extra) {
- box.x1 -= extra;
- box.x2 += extra;
- box.y1 -= extra;
- box.y2 += extra;
- }
-
- box.x2++;
- box.y2++;
-
- TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
- if(BOX_NOT_EMPTY(box)) {
- if(pPriv->preRefresh)
- (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
- } else {
- BoxPtr pbox;
- int offset1, offset2, offset3;
-
- offset2 = pGC->lineWidth;
- if(!offset2) offset2 = 1;
- offset1 = offset2 >> 1;
- offset3 = offset2 - offset1;
-
- pBoxInit = (BoxPtr)xalloc(nRects * 4 * sizeof(BoxRec));
- pbox = pBoxInit;
-
- while(nRects--) {
- pbox->x1 = pRects->x - offset1;
- pbox->y1 = pRects->y - offset1;
- pbox->x2 = pbox->x1 + pRects->width + offset2;
- pbox->y2 = pbox->y1 + offset2;
- TRIM_AND_TRANSLATE_BOX((*pbox), pDraw, pGC);
- if(BOX_NOT_EMPTY((*pbox))) {
- num++;
- pbox++;
- }
-
- pbox->x1 = pRects->x - offset1;
- pbox->y1 = pRects->y + offset3;
- pbox->x2 = pbox->x1 + offset2;
- pbox->y2 = pbox->y1 + pRects->height - offset2;
- TRIM_AND_TRANSLATE_BOX((*pbox), pDraw, pGC);
- if(BOX_NOT_EMPTY((*pbox))) {
- num++;
- pbox++;
- }
-
- pbox->x1 = pRects->x + pRects->width - offset1;
- pbox->y1 = pRects->y + offset3;
- pbox->x2 = pbox->x1 + offset2;
- pbox->y2 = pbox->y1 + pRects->height - offset2;
- TRIM_AND_TRANSLATE_BOX((*pbox), pDraw, pGC);
- if(BOX_NOT_EMPTY((*pbox))) {
- num++;
- pbox++;
- }
-
- pbox->x1 = pRects->x - offset1;
- pbox->y1 = pRects->y + pRects->height - offset1;
- pbox->x2 = pbox->x1 + pRects->width + offset2;
- pbox->y2 = pbox->y1 + offset2;
- TRIM_AND_TRANSLATE_BOX((*pbox), pDraw, pGC);
- if(BOX_NOT_EMPTY((*pbox))) {
- num++;
- pbox++;
- }
-
- pRects++;
- }
-
- if(num) {
- if(pPriv->preRefresh)
- (*pPriv->preRefresh)(pPriv->pScrn, num, pBoxInit);
- } else {
- xfree(pBoxInit);
- }
- }
- }
-
- (*pGC->ops->PolyRectangle)(pDraw, pGC, nRectsInit, pRectsInit);
-
- if(boxNotEmpty && pPriv->postRefresh) {
- (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
- } else if(num) {
- if(pPriv->postRefresh)
- (*pPriv->postRefresh)(pPriv->pScrn, num, pBoxInit);
- xfree(pBoxInit);
- }
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-
-}
-
-static void
-ShadowPolyArc(
- DrawablePtr pDraw,
- GCPtr pGC,
- int narcsInit,
- xArc *parcsInit
-){
- BoxRec box;
- Bool boxNotEmpty = FALSE;
-
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if(IS_VISIBLE(pDraw) && narcsInit) {
- int narcs = narcsInit;
- xArc *parcs = parcsInit;
- int extra = pGC->lineWidth >> 1;
-
- box.x1 = parcs->x;
- box.x2 = box.x1 + parcs->width;
- box.y1 = parcs->y;
- box.y2 = box.y1 + parcs->height;
-
- /* should I break these up instead ? */
-
- while(--narcs) {
- parcs++;
- if(box.x1 > parcs->x) box.x1 = parcs->x;
- if(box.x2 < (parcs->x + parcs->width))
- box.x2 = parcs->x + parcs->width;
- if(box.y1 > parcs->y) box.y1 = parcs->y;
- if(box.y2 < (parcs->y + parcs->height))
- box.y2 = parcs->y + parcs->height;
- }
-
- if(extra) {
- box.x1 -= extra;
- box.x2 += extra;
- box.y1 -= extra;
- box.y2 += extra;
- }
-
- box.x2++;
- box.y2++;
-
- TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
- if(BOX_NOT_EMPTY(box)) {
- if(pPriv->preRefresh)
- (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
- }
-
- (*pGC->ops->PolyArc)(pDraw, pGC, narcsInit, parcsInit);
-
- if(boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-
-}
-
-static void
-ShadowFillPolygon(
- DrawablePtr pDraw,
- GCPtr pGC,
- int shape,
- int mode,
- int count,
- DDXPointPtr pptInit
-){
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if(IS_VISIBLE(pDraw) && (count > 2)) {
- DDXPointPtr ppt = pptInit;
- int i = count;
- BoxRec box;
- Bool boxNotEmpty = FALSE;
-
- box.x2 = box.x1 = ppt->x;
- box.y2 = box.y1 = ppt->y;
-
- if(mode != CoordModeOrigin) {
- int x = box.x1;
- int y = box.y1;
- while(--i) {
- ppt++;
- x += ppt->x;
- y += ppt->y;
- if(box.x1 > x) box.x1 = x;
- else if(box.x2 < x) box.x2 = x;
- if(box.y1 > y) box.y1 = y;
- else if(box.y2 < y) box.y2 = y;
- }
- } else {
- while(--i) {
- ppt++;
- if(box.x1 > ppt->x) box.x1 = ppt->x;
- else if(box.x2 < ppt->x) box.x2 = ppt->x;
- if(box.y1 > ppt->y) box.y1 = ppt->y;
- else if(box.y2 < ppt->y) box.y2 = ppt->y;
- }
- }
-
- box.x2++;
- box.y2++;
-
- TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
- if(BOX_NOT_EMPTY(box)) {
- if(pPriv->preRefresh)
- (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
-
- (*pGC->ops->FillPolygon)(pDraw, pGC, shape, mode, count, pptInit);
-
- if(boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
- } else
- (*pGC->ops->FillPolygon)(pDraw, pGC, shape, mode, count, pptInit);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-}
-
-
-static void
-ShadowPolyFillRect(
- DrawablePtr pDraw,
- GCPtr pGC,
- int nRectsInit,
- xRectangle *pRectsInit
-){
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if(IS_VISIBLE(pDraw) && nRectsInit) {
- BoxRec box;
- Bool boxNotEmpty = FALSE;
- xRectangle *pRects = pRectsInit;
- int nRects = nRectsInit;
-
- box.x1 = pRects->x;
- box.x2 = box.x1 + pRects->width;
- box.y1 = pRects->y;
- box.y2 = box.y1 + pRects->height;
-
- while(--nRects) {
- pRects++;
- if(box.x1 > pRects->x) box.x1 = pRects->x;
- if(box.x2 < (pRects->x + pRects->width))
- box.x2 = pRects->x + pRects->width;
- if(box.y1 > pRects->y) box.y1 = pRects->y;
- if(box.y2 < (pRects->y + pRects->height))
- box.y2 = pRects->y + pRects->height;
- }
-
- /* cfb messes with the pRectsInit so we have to do our
- calculations first */
-
- TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
- if(BOX_NOT_EMPTY(box)) {
- if(pPriv->preRefresh)
- (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
-
- (*pGC->ops->PolyFillRect)(pDraw, pGC, nRectsInit, pRectsInit);
-
- if(boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
- } else
- (*pGC->ops->PolyFillRect)(pDraw, pGC, nRectsInit, pRectsInit);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-}
-
-
-static void
-ShadowPolyFillArc(
- DrawablePtr pDraw,
- GCPtr pGC,
- int narcsInit,
- xArc *parcsInit
-){
- BoxRec box;
- Bool boxNotEmpty = FALSE;
-
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if(IS_VISIBLE(pDraw) && narcsInit) {
- xArc *parcs = parcsInit;
- int narcs = narcsInit;
-
- box.x1 = parcs->x;
- box.x2 = box.x1 + parcs->width;
- box.y1 = parcs->y;
- box.y2 = box.y1 + parcs->height;
-
- /* should I break these up instead ? */
-
- while(--narcs) {
- parcs++;
- if(box.x1 > parcs->x) box.x1 = parcs->x;
- if(box.x2 < (parcs->x + parcs->width))
- box.x2 = parcs->x + parcs->width;
- if(box.y1 > parcs->y) box.y1 = parcs->y;
- if(box.y2 < (parcs->y + parcs->height))
- box.y2 = parcs->y + parcs->height;
- }
-
- TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
- if(BOX_NOT_EMPTY(box)) {
- if(pPriv->preRefresh)
- (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
- }
-
- (*pGC->ops->PolyFillArc)(pDraw, pGC, narcsInit, parcsInit);
-
- if(boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-}
-
-static void
-ShadowTextExtent(FontPtr pFont, int count, char* chars,
- FontEncoding fontEncoding, BoxPtr box)
-{
- unsigned long n, i;
- int w;
- CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */
-
- GetGlyphs(pFont, (unsigned long)count, (unsigned char *)chars,
- fontEncoding, &n, charinfo);
- w = 0;
- for (i=0; i < n; i++) {
- w += charinfo[i]->metrics.characterWidth;
- }
- if (i) {
- w += charinfo[i - 1]->metrics.rightSideBearing;
- }
-
- box->x1 = 0;
- if (n) {
- if (charinfo[0]->metrics.leftSideBearing < 0) {
- box->x1 = charinfo[0]->metrics.leftSideBearing;
- }
- }
- box->x2 = w;
- box->y1 = -FONTMAXBOUNDS(pFont,ascent);
- box->y2 = FONTMAXBOUNDS(pFont,descent);
-}
-
-
-
-static void
-ShadowFontToBox(BoxPtr BB, DrawablePtr pDrawable, GCPtr pGC, int x, int y,
- int count, char *chars, int wide)
-{
- FontPtr pFont;
-
- pFont = pGC->font;
- if (pFont->info.constantWidth) {
- int ascent, descent, left, right = 0;
-
- ascent = max(pFont->info.fontAscent, pFont->info.maxbounds.ascent);
- descent = max(pFont->info.fontDescent, pFont->info.maxbounds.descent);
- left = pFont->info.maxbounds.leftSideBearing;
- if (count > 0) {
- right = (count - 1) * pFont->info.maxbounds.characterWidth;
- }
- right += pFont->info.maxbounds.rightSideBearing;
- BB->x1 =
- max(pDrawable->x + x - left, (REGION_EXTENTS(pGC->pScreen,
- &((WindowPtr) pDrawable)->winSize))->x1);
- BB->y1 =
- max(pDrawable->y + y - ascent,
- (REGION_EXTENTS(pGC->pScreen,
- &((WindowPtr) pDrawable)->winSize))->y1);
- BB->x2 =
- min(pDrawable->x + x + right,
- (REGION_EXTENTS(pGC->pScreen,
- &((WindowPtr) pDrawable)->winSize))->x2);
- BB->y2 =
- min(pDrawable->y + y + descent,
- (REGION_EXTENTS(pGC->pScreen,
- &((WindowPtr) pDrawable)->winSize))->y2);
- } else {
- ShadowTextExtent(pFont, count, chars, wide ? (FONTLASTROW(pFont) == 0)
- ? Linear16Bit : TwoD16Bit : Linear8Bit, BB);
- BB->x1 =
- max(pDrawable->x + x + BB->x1, (REGION_EXTENTS(pGC->pScreen,
- &((WindowPtr) pDrawable)->winSize))->x1);
- BB->y1 =
- max(pDrawable->y + y + BB->y1,
- (REGION_EXTENTS(pGC->pScreen,
- &((WindowPtr) pDrawable)->winSize))->y1);
- BB->x2 =
- min(pDrawable->x + x + BB->x2,
- (REGION_EXTENTS(pGC->pScreen,
- &((WindowPtr) pDrawable)->winSize))->x2);
- BB->y2 =
- min(pDrawable->y + y + BB->y2,
- (REGION_EXTENTS(pGC->pScreen,
- &((WindowPtr) pDrawable)->winSize))->y2);
- }
-}
-
-static int
-ShadowPolyText8(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x,
- int y,
- int count,
- char *chars
-){
- int width;
- BoxRec box;
- Bool boxNotEmpty = FALSE;
-
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if(IS_VISIBLE(pDraw)) {
- ShadowFontToBox(&box, pDraw, pGC, x, y, count, chars, 0);
-
- TRIM_BOX(box, pGC);
- if(BOX_NOT_EMPTY(box)) {
- if(pPriv->preRefresh)
- (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
- }
-
- width = (*pGC->ops->PolyText8)(pDraw, pGC, x, y, count, chars);
-
- if(boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-
- return width;
-}
-
-static int
-ShadowPolyText16(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x,
- int y,
- int count,
- unsigned short *chars
-){
- int width;
- BoxRec box;
- Bool boxNotEmpty = FALSE;
-
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if(IS_VISIBLE(pDraw)) {
- ShadowFontToBox(&box, pDraw, pGC, x, y, count, (char*)chars, 1);
-
- TRIM_BOX(box, pGC);
- if(BOX_NOT_EMPTY(box)) {
- if(pPriv->preRefresh)
- (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
- }
-
- width = (*pGC->ops->PolyText16)(pDraw, pGC, x, y, count, chars);
-
- if(boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-
- return width;
-}
-
-static void
-ShadowImageText8(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x,
- int y,
- int count,
- char *chars
-){
- BoxRec box;
- Bool boxNotEmpty = FALSE;
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if(IS_VISIBLE(pDraw) && count) {
- int top, bot, Min, Max;
-
- top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font));
- bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font));
-
- Min = count * FONTMINBOUNDS(pGC->font, characterWidth);
- if(Min > 0) Min = 0;
- Max = count * FONTMAXBOUNDS(pGC->font, characterWidth);
- if(Max < 0) Max = 0;
-
- /* ugh */
- box.x1 = pDraw->x + x + Min +
- FONTMINBOUNDS(pGC->font, leftSideBearing);
- box.x2 = pDraw->x + x + Max +
- FONTMAXBOUNDS(pGC->font, rightSideBearing);
-
- box.y1 = pDraw->y + y - top;
- box.y2 = pDraw->y + y + bot;
-
- TRIM_BOX(box, pGC);
- if(BOX_NOT_EMPTY(box)) {
- if(pPriv->preRefresh)
- (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
- }
-
- (*pGC->ops->ImageText8)(pDraw, pGC, x, y, count, chars);
-
- if(boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-}
-static void
-ShadowImageText16(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x,
- int y,
- int count,
- unsigned short *chars
-){
- BoxRec box;
- Bool boxNotEmpty = FALSE;
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if(IS_VISIBLE(pDraw) && count) {
- int top, bot, Min, Max;
-
- top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font));
- bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font));
-
- Min = count * FONTMINBOUNDS(pGC->font, characterWidth);
- if(Min > 0) Min = 0;
- Max = count * FONTMAXBOUNDS(pGC->font, characterWidth);
- if(Max < 0) Max = 0;
-
- /* ugh */
- box.x1 = pDraw->x + x + Min +
- FONTMINBOUNDS(pGC->font, leftSideBearing);
- box.x2 = pDraw->x + x + Max +
- FONTMAXBOUNDS(pGC->font, rightSideBearing);
-
- box.y1 = pDraw->y + y - top;
- box.y2 = pDraw->y + y + bot;
-
- TRIM_BOX(box, pGC);
- if(BOX_NOT_EMPTY(box)) {
- if(pPriv->preRefresh)
- (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
- }
-
- (*pGC->ops->ImageText16)(pDraw, pGC, x, y, count, chars);
-
- if(boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-}
-
-
-static void
-ShadowImageGlyphBlt(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x, int y,
- unsigned int nglyphInit,
- CharInfoPtr *ppciInit,
- pointer pglyphBase
-){
- BoxRec box;
- Bool boxNotEmpty = FALSE;
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if(IS_VISIBLE(pDraw) && nglyphInit) {
- CharInfoPtr *ppci = ppciInit;
- unsigned int nglyph = nglyphInit;
- int top, bot, width = 0;
-
- top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font));
- bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font));
-
- box.x1 = ppci[0]->metrics.leftSideBearing;
- if(box.x1 > 0) box.x1 = 0;
- box.x2 = ppci[nglyph - 1]->metrics.rightSideBearing -
- ppci[nglyph - 1]->metrics.characterWidth;
- if(box.x2 < 0) box.x2 = 0;
-
- box.x2 += pDraw->x + x;
- box.x1 += pDraw->x + x;
-
- while(nglyph--) {
- width += (*ppci)->metrics.characterWidth;
- ppci++;
- }
-
- if(width > 0)
- box.x2 += width;
- else
- box.x1 += width;
-
- box.y1 = pDraw->y + y - top;
- box.y2 = pDraw->y + y + bot;
-
- TRIM_BOX(box, pGC);
- if(BOX_NOT_EMPTY(box)) {
- if(pPriv->preRefresh)
- (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
- }
-
- (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, x, y, nglyphInit,
- ppciInit, pglyphBase);
-
- if(boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-}
-
-static void
-ShadowPolyGlyphBlt(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x, int y,
- unsigned int nglyphInit,
- CharInfoPtr *ppciInit,
- pointer pglyphBase
-){
- BoxRec box;
- Bool boxNotEmpty = FALSE;
-
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if(IS_VISIBLE(pDraw) && nglyphInit) {
- CharInfoPtr *ppci = ppciInit;
- unsigned int nglyph = nglyphInit;
-
- /* ugh */
- box.x1 = pDraw->x + x + ppci[0]->metrics.leftSideBearing;
- box.x2 = pDraw->x + x + ppci[nglyph - 1]->metrics.rightSideBearing;
-
- if(nglyph > 1) {
- int width = 0;
-
- while(--nglyph) {
- width += (*ppci)->metrics.characterWidth;
- ppci++;
- }
-
- if(width > 0) box.x2 += width;
- else box.x1 += width;
- }
-
- box.y1 = pDraw->y + y - FONTMAXBOUNDS(pGC->font, ascent);
- box.y2 = pDraw->y + y + FONTMAXBOUNDS(pGC->font, descent);
-
- TRIM_BOX(box, pGC);
- if(BOX_NOT_EMPTY(box)) {
- if(pPriv->preRefresh)
- (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
- }
-
- (*pGC->ops->PolyGlyphBlt)(pDraw, pGC, x, y, nglyphInit,
- ppciInit, pglyphBase);
-
- if(boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-}
-
-static void
-ShadowPushPixels(
- GCPtr pGC,
- PixmapPtr pBitMap,
- DrawablePtr pDraw,
- int dx, int dy, int xOrg, int yOrg
-){
- BoxRec box;
- Bool boxNotEmpty = FALSE;
-
- SHADOW_GC_OP_PROLOGUE(pGC);
-
- if(IS_VISIBLE(pDraw)) {
- box.x1 = xOrg;
- box.y1 = yOrg;
-
- if(!pGC->miTranslate) {
- box.x1 += pDraw->x;
- box.y1 += pDraw->y;
- }
-
- box.x2 = box.x1 + dx;
- box.y2 = box.y1 + dy;
-
- TRIM_BOX(box, pGC);
- if(BOX_NOT_EMPTY(box)) {
- if(pPriv->preRefresh)
- (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
- boxNotEmpty = TRUE;
- }
- }
-
- (*pGC->ops->PushPixels)(pGC, pBitMap, pDraw, dx, dy, xOrg, yOrg);
-
- if(boxNotEmpty && pPriv->postRefresh)
- (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
-
- SHADOW_GC_OP_EPILOGUE(pGC);
-}
-
-
-GCOps ShadowGCOps = {
- ShadowFillSpans, ShadowSetSpans,
- ShadowPutImage, ShadowCopyArea,
- ShadowCopyPlane, ShadowPolyPoint,
- ShadowPolylines, ShadowPolySegment,
- ShadowPolyRectangle, ShadowPolyArc,
- ShadowFillPolygon, ShadowPolyFillRect,
- ShadowPolyFillArc, ShadowPolyText8,
- ShadowPolyText16, ShadowImageText8,
- ShadowImageText16, ShadowImageGlyphBlt,
- ShadowPolyGlyphBlt, ShadowPushPixels,
- {NULL} /* devPrivate */
-};
-
+/*
+ Copyright (C) 1999. The XFree86 Project Inc.
+
+ Written by Mark Vojkovich (mvojkovi@ucsd.edu)
+
+ Pre-fb-write callbacks and RENDER support - Nolan Leake (nolan@vmware.com)
+*/
+
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "pixmapstr.h"
+#include "input.h"
+#include <X11/fonts/font.h>
+#include "mi.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "gcstruct.h"
+#include "dixfontstr.h"
+#include <X11/fonts/fontstruct.h>
+#include "xf86.h"
+#include "xf86str.h"
+#include "shadowfb.h"
+
+# include "picturestr.h"
+
+static Bool ShadowCloseScreen (int i, ScreenPtr pScreen);
+static void ShadowCopyWindow(
+ WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgn
+);
+static Bool ShadowCreateGC(GCPtr pGC);
+static Bool ShadowModifyPixmapHeader(
+ PixmapPtr pPixmap,
+ int width,
+ int height,
+ int depth,
+ int bitsPerPixel,
+ int devKind,
+ pointer pPixData
+);
+
+static Bool ShadowEnterVT(int index, int flags);
+static void ShadowLeaveVT(int index, int flags);
+
+static void ShadowComposite(
+ CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height
+);
+
+
+typedef struct {
+ ScrnInfoPtr pScrn;
+ RefreshAreaFuncPtr preRefresh;
+ RefreshAreaFuncPtr postRefresh;
+ CloseScreenProcPtr CloseScreen;
+ CopyWindowProcPtr CopyWindow;
+ CreateGCProcPtr CreateGC;
+ ModifyPixmapHeaderProcPtr ModifyPixmapHeader;
+ CompositeProcPtr Composite;
+ Bool (*EnterVT)(int, int);
+ void (*LeaveVT)(int, int);
+ Bool vtSema;
+} ShadowScreenRec, *ShadowScreenPtr;
+
+typedef struct {
+ GCOps *ops;
+ GCFuncs *funcs;
+} ShadowGCRec, *ShadowGCPtr;
+
+
+static int ShadowScreenKeyIndex;
+static DevPrivateKey ShadowScreenKey = &ShadowScreenKeyIndex;
+static int ShadowGCKeyIndex;
+static DevPrivateKey ShadowGCKey = &ShadowGCKeyIndex;
+
+#define GET_SCREEN_PRIVATE(pScreen) \
+ (ShadowScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates, ShadowScreenKey)
+#define GET_GC_PRIVATE(pGC) \
+ (ShadowGCPtr)dixLookupPrivate(&(pGC)->devPrivates, ShadowGCKey)
+
+#define SHADOW_GC_FUNC_PROLOGUE(pGC)\
+ ShadowGCPtr pGCPriv = GET_GC_PRIVATE(pGC);\
+ (pGC)->funcs = pGCPriv->funcs;\
+ if(pGCPriv->ops)\
+ (pGC)->ops = pGCPriv->ops
+
+#define SHADOW_GC_FUNC_EPILOGUE(pGC)\
+ pGCPriv->funcs = (pGC)->funcs;\
+ (pGC)->funcs = &ShadowGCFuncs;\
+ if(pGCPriv->ops) {\
+ pGCPriv->ops = (pGC)->ops;\
+ (pGC)->ops = &ShadowGCOps;\
+ }
+
+#define SHADOW_GC_OP_PROLOGUE(pGC)\
+ ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pGC->pScreen); \
+ ShadowGCPtr pGCPriv = GET_GC_PRIVATE(pGC);\
+ GCFuncs *oldFuncs = pGC->funcs;\
+ pGC->funcs = pGCPriv->funcs;\
+ pGC->ops = pGCPriv->ops
+
+
+#define SHADOW_GC_OP_EPILOGUE(pGC)\
+ pGCPriv->ops = pGC->ops;\
+ pGC->funcs = oldFuncs;\
+ pGC->ops = &ShadowGCOps
+
+#define IS_VISIBLE(pWin) (pPriv->vtSema && \
+ (((WindowPtr)pWin)->visibility != VisibilityFullyObscured))
+
+#define TRIM_BOX(box, pGC) { \
+ BoxPtr extents = &pGC->pCompositeClip->extents;\
+ if(box.x1 < extents->x1) box.x1 = extents->x1; \
+ if(box.x2 > extents->x2) box.x2 = extents->x2; \
+ if(box.y1 < extents->y1) box.y1 = extents->y1; \
+ if(box.y2 > extents->y2) box.y2 = extents->y2; \
+ }
+
+#define TRANSLATE_BOX(box, pDraw) { \
+ box.x1 += pDraw->x; \
+ box.x2 += pDraw->x; \
+ box.y1 += pDraw->y; \
+ box.y2 += pDraw->y; \
+ }
+
+#define TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC) { \
+ TRANSLATE_BOX(box, pDraw); \
+ TRIM_BOX(box, pGC); \
+ }
+
+#define BOX_NOT_EMPTY(box) \
+ (((box.x2 - box.x1) > 0) && ((box.y2 - box.y1) > 0))
+
+
+
+Bool
+ShadowFBInit2 (
+ ScreenPtr pScreen,
+ RefreshAreaFuncPtr preRefreshArea,
+ RefreshAreaFuncPtr postRefreshArea
+){
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ ShadowScreenPtr pPriv;
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+
+ if(!preRefreshArea && !postRefreshArea) return FALSE;
+
+ if(!dixRequestPrivate(ShadowGCKey, sizeof(ShadowGCRec)))
+ return FALSE;
+
+ if(!(pPriv = (ShadowScreenPtr)malloc(sizeof(ShadowScreenRec))))
+ return FALSE;
+
+ dixSetPrivate(&pScreen->devPrivates, ShadowScreenKey, pPriv);
+
+ pPriv->pScrn = pScrn;
+ pPriv->preRefresh = preRefreshArea;
+ pPriv->postRefresh = postRefreshArea;
+ pPriv->vtSema = TRUE;
+
+ pPriv->CloseScreen = pScreen->CloseScreen;
+ pPriv->CopyWindow = pScreen->CopyWindow;
+ pPriv->CreateGC = pScreen->CreateGC;
+ pPriv->ModifyPixmapHeader = pScreen->ModifyPixmapHeader;
+
+ pPriv->EnterVT = pScrn->EnterVT;
+ pPriv->LeaveVT = pScrn->LeaveVT;
+
+ pScreen->CloseScreen = ShadowCloseScreen;
+ pScreen->CopyWindow = ShadowCopyWindow;
+ pScreen->CreateGC = ShadowCreateGC;
+ pScreen->ModifyPixmapHeader = ShadowModifyPixmapHeader;
+
+ pScrn->EnterVT = ShadowEnterVT;
+ pScrn->LeaveVT = ShadowLeaveVT;
+
+ if(ps) {
+ pPriv->Composite = ps->Composite;
+ ps->Composite = ShadowComposite;
+ }
+
+ return TRUE;
+}
+
+Bool
+ShadowFBInit (
+ ScreenPtr pScreen,
+ RefreshAreaFuncPtr refreshArea
+){
+ return ShadowFBInit2(pScreen, NULL, refreshArea);
+}
+
+/**********************************************************/
+
+static Bool
+ShadowEnterVT(int index, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[index];
+ ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pScrn->pScreen);
+
+ if((*pPriv->EnterVT)(index, flags)) {
+ pPriv->vtSema = TRUE;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static void
+ShadowLeaveVT(int index, int flags)
+{
+ ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(xf86Screens[index]->pScreen);
+
+ pPriv->vtSema = FALSE;
+
+ (*pPriv->LeaveVT)(index, flags);
+}
+
+/**********************************************************/
+
+
+static Bool
+ShadowCloseScreen (int i, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pScreen);
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+
+ pScreen->CloseScreen = pPriv->CloseScreen;
+ pScreen->CopyWindow = pPriv->CopyWindow;
+ pScreen->CreateGC = pPriv->CreateGC;
+ pScreen->ModifyPixmapHeader = pPriv->ModifyPixmapHeader;
+
+ pScrn->EnterVT = pPriv->EnterVT;
+ pScrn->LeaveVT = pPriv->LeaveVT;
+
+ if(ps) {
+ ps->Composite = pPriv->Composite;
+ }
+
+ free((pointer)pPriv);
+
+ return (*pScreen->CloseScreen) (i, pScreen);
+}
+
+static void
+ShadowCopyWindow(
+ WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgn
+){
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pScreen);
+ int num = 0;
+ RegionRec rgnDst;
+
+ if (pPriv->vtSema) {
+ REGION_NULL(pWin->drawable.pScreen, &rgnDst);
+ REGION_COPY(pWin->drawable.pScreen, &rgnDst, prgn);
+
+ REGION_TRANSLATE(pWin->drawable.pScreen, &rgnDst,
+ pWin->drawable.x - ptOldOrg.x,
+ pWin->drawable.y - ptOldOrg.y);
+ REGION_INTERSECT(pScreen, &rgnDst, &pWin->borderClip, &rgnDst);
+ if ((num = REGION_NUM_RECTS(&rgnDst))) {
+ if(pPriv->preRefresh)
+ (*pPriv->preRefresh)(pPriv->pScrn, num, REGION_RECTS(&rgnDst));
+ } else {
+ REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
+ }
+ }
+
+ pScreen->CopyWindow = pPriv->CopyWindow;
+ (*pScreen->CopyWindow) (pWin, ptOldOrg, prgn);
+ pScreen->CopyWindow = ShadowCopyWindow;
+
+ if (num) {
+ if (pPriv->postRefresh)
+ (*pPriv->postRefresh)(pPriv->pScrn, num, REGION_RECTS(&rgnDst));
+ REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
+ }
+}
+
+static Bool
+ShadowModifyPixmapHeader(
+ PixmapPtr pPixmap,
+ int width,
+ int height,
+ int depth,
+ int bitsPerPixel,
+ int devKind,
+ pointer pPixData
+)
+{
+ ScreenPtr pScreen;
+ ScrnInfoPtr pScrn;
+ ShadowScreenPtr pPriv;
+ Bool retval;
+ PixmapPtr pScreenPix;
+
+ if (!pPixmap)
+ return FALSE;
+
+ pScreen = pPixmap->drawable.pScreen;
+ pScrn = xf86Screens[pScreen->myNum];
+
+ pScreenPix = (*pScreen->GetScreenPixmap)(pScreen);
+
+ if (pPixmap == pScreenPix && !pScrn->vtSema)
+ pScreenPix->devPrivate = pScrn->pixmapPrivate;
+
+ pPriv = GET_SCREEN_PRIVATE(pScreen);
+
+ pScreen->ModifyPixmapHeader = pPriv->ModifyPixmapHeader;
+ retval = (*pScreen->ModifyPixmapHeader)(pPixmap,
+ width, height, depth, bitsPerPixel, devKind, pPixData);
+ pScreen->ModifyPixmapHeader = ShadowModifyPixmapHeader;
+
+ if (pPixmap == pScreenPix && !pScrn->vtSema)
+ {
+ pScrn->pixmapPrivate = pScreenPix->devPrivate;
+ pScreenPix->devPrivate.ptr = 0;
+ }
+ return retval;
+}
+
+static void
+ShadowComposite(
+ CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height
+){
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pScreen);
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ BoxRec box;
+ BoxPtr extents;
+ Bool boxNotEmpty = FALSE;
+
+ if (pPriv->vtSema
+ && pDst->pDrawable->type == DRAWABLE_WINDOW) {
+
+ box.x1 = pDst->pDrawable->x + xDst;
+ box.y1 = pDst->pDrawable->y + yDst;
+ box.x2 = box.x1 + width;
+ box.y2 = box.y1 + height;
+
+ extents = &pDst->pCompositeClip->extents;
+ if(box.x1 < extents->x1) box.x1 = extents->x1;
+ if(box.x2 > extents->x2) box.x2 = extents->x2;
+ if(box.y1 < extents->y1) box.y1 = extents->y1;
+ if(box.y2 > extents->y2) box.y2 = extents->y2;
+
+ if (BOX_NOT_EMPTY(box)) {
+ if (pPriv->preRefresh)
+ (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
+ boxNotEmpty = TRUE;
+ }
+ }
+
+ ps->Composite = pPriv->Composite;
+ (*ps->Composite)(op, pSrc, pMask, pDst, xSrc, ySrc,
+ xMask, yMask, xDst, yDst, width, height);
+ ps->Composite = ShadowComposite;
+
+ if (pPriv->postRefresh && boxNotEmpty) {
+ (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
+ }
+}
+
+/**********************************************************/
+
+static void ShadowValidateGC(GCPtr, unsigned long, DrawablePtr);
+static void ShadowChangeGC(GCPtr, unsigned long);
+static void ShadowCopyGC(GCPtr, unsigned long, GCPtr);
+static void ShadowDestroyGC(GCPtr);
+static void ShadowChangeClip(GCPtr, int, pointer, int);
+static void ShadowDestroyClip(GCPtr);
+static void ShadowCopyClip(GCPtr, GCPtr);
+
+GCFuncs ShadowGCFuncs = {
+ ShadowValidateGC, ShadowChangeGC, ShadowCopyGC, ShadowDestroyGC,
+ ShadowChangeClip, ShadowDestroyClip, ShadowCopyClip
+};
+
+
+extern GCOps ShadowGCOps;
+
+static Bool
+ShadowCreateGC(GCPtr pGC)
+{
+ ScreenPtr pScreen = pGC->pScreen;
+ ShadowScreenPtr pPriv = GET_SCREEN_PRIVATE(pScreen);
+ ShadowGCPtr pGCPriv = GET_GC_PRIVATE(pGC);
+ Bool ret;
+
+ pScreen->CreateGC = pPriv->CreateGC;
+ if((ret = (*pScreen->CreateGC) (pGC))) {
+ pGCPriv->ops = NULL;
+ pGCPriv->funcs = pGC->funcs;
+ pGC->funcs = &ShadowGCFuncs;
+ }
+ pScreen->CreateGC = ShadowCreateGC;
+
+ return ret;
+}
+
+
+static void
+ShadowValidateGC(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+){
+ SHADOW_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->ValidateGC)(pGC, changes, pDraw);
+ if(pDraw->type == DRAWABLE_WINDOW)
+ pGCPriv->ops = pGC->ops; /* just so it's not NULL */
+ else
+ pGCPriv->ops = NULL;
+ SHADOW_GC_FUNC_EPILOGUE (pGC);
+}
+
+
+static void
+ShadowDestroyGC(GCPtr pGC)
+{
+ SHADOW_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->DestroyGC)(pGC);
+ SHADOW_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+ShadowChangeGC (
+ GCPtr pGC,
+ unsigned long mask
+){
+ SHADOW_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->ChangeGC) (pGC, mask);
+ SHADOW_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+ShadowCopyGC (
+ GCPtr pGCSrc,
+ unsigned long mask,
+ GCPtr pGCDst
+){
+ SHADOW_GC_FUNC_PROLOGUE (pGCDst);
+ (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
+ SHADOW_GC_FUNC_EPILOGUE (pGCDst);
+}
+
+static void
+ShadowChangeClip (
+ GCPtr pGC,
+ int type,
+ pointer pvalue,
+ int nrects
+){
+ SHADOW_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
+ SHADOW_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+ShadowCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
+{
+ SHADOW_GC_FUNC_PROLOGUE (pgcDst);
+ (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
+ SHADOW_GC_FUNC_EPILOGUE (pgcDst);
+}
+
+static void
+ShadowDestroyClip(GCPtr pGC)
+{
+ SHADOW_GC_FUNC_PROLOGUE (pGC);
+ (* pGC->funcs->DestroyClip)(pGC);
+ SHADOW_GC_FUNC_EPILOGUE (pGC);
+}
+
+
+
+
+/**********************************************************/
+
+
+static void
+ShadowFillSpans(
+ DrawablePtr pDraw,
+ GC *pGC,
+ int nInit,
+ DDXPointPtr pptInit,
+ int *pwidthInit,
+ int fSorted
+){
+ SHADOW_GC_OP_PROLOGUE(pGC);
+
+ if(IS_VISIBLE(pDraw) && nInit) {
+ DDXPointPtr ppt = pptInit;
+ int *pwidth = pwidthInit;
+ int i = nInit;
+ BoxRec box;
+ Bool boxNotEmpty = FALSE;
+
+ box.x1 = ppt->x;
+ box.x2 = box.x1 + *pwidth;
+ box.y2 = box.y1 = ppt->y;
+
+ while(--i) {
+ ppt++;
+ pwidth++;
+ if(box.x1 > ppt->x) box.x1 = ppt->x;
+ if(box.x2 < (ppt->x + *pwidth))
+ box.x2 = ppt->x + *pwidth;
+ if(box.y1 > ppt->y) box.y1 = ppt->y;
+ else if(box.y2 < ppt->y) box.y2 = ppt->y;
+ }
+
+ box.y2++;
+
+ if(!pGC->miTranslate) {
+ TRANSLATE_BOX(box, pDraw);
+ }
+ TRIM_BOX(box, pGC);
+
+ if(BOX_NOT_EMPTY(box)) {
+ if(pPriv->preRefresh)
+ (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
+ boxNotEmpty = TRUE;
+ }
+
+ (*pGC->ops->FillSpans)(pDraw, pGC, nInit, pptInit, pwidthInit, fSorted);
+
+ if(boxNotEmpty && pPriv->postRefresh)
+ (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
+ } else
+ (*pGC->ops->FillSpans)(pDraw, pGC, nInit, pptInit, pwidthInit, fSorted);
+
+ SHADOW_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+ShadowSetSpans(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ char *pcharsrc,
+ DDXPointPtr pptInit,
+ int *pwidthInit,
+ int nspans,
+ int fSorted
+){
+ SHADOW_GC_OP_PROLOGUE(pGC);
+
+ if(IS_VISIBLE(pDraw) && nspans) {
+ DDXPointPtr ppt = pptInit;
+ int *pwidth = pwidthInit;
+ int i = nspans;
+ BoxRec box;
+ Bool boxNotEmpty = FALSE;
+
+ box.x1 = ppt->x;
+ box.x2 = box.x1 + *pwidth;
+ box.y2 = box.y1 = ppt->y;
+
+ while(--i) {
+ ppt++;
+ pwidth++;
+ if(box.x1 > ppt->x) box.x1 = ppt->x;
+ if(box.x2 < (ppt->x + *pwidth))
+ box.x2 = ppt->x + *pwidth;
+ if(box.y1 > ppt->y) box.y1 = ppt->y;
+ else if(box.y2 < ppt->y) box.y2 = ppt->y;
+ }
+
+ box.y2++;
+
+ if(!pGC->miTranslate) {
+ TRANSLATE_BOX(box, pDraw);
+ }
+ TRIM_BOX(box, pGC);
+
+ if(BOX_NOT_EMPTY(box)) {
+ if(pPriv->preRefresh)
+ (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
+ boxNotEmpty = TRUE;
+ }
+
+ (*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, pptInit,
+ pwidthInit, nspans, fSorted);
+
+ if(boxNotEmpty && pPriv->postRefresh)
+ (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
+ } else
+ (*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, pptInit,
+ pwidthInit, nspans, fSorted);
+
+ SHADOW_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+ShadowPutImage(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int depth,
+ int x, int y, int w, int h,
+ int leftPad,
+ int format,
+ char *pImage
+){
+ BoxRec box;
+ Bool boxNotEmpty = FALSE;
+
+ SHADOW_GC_OP_PROLOGUE(pGC);
+
+ if(IS_VISIBLE(pDraw)) {
+ box.x1 = x + pDraw->x;
+ box.x2 = box.x1 + w;
+ box.y1 = y + pDraw->y;
+ box.y2 = box.y1 + h;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box)) {
+ if(pPriv->preRefresh)
+ (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
+ boxNotEmpty = TRUE;
+ }
+ }
+
+ (*pGC->ops->PutImage)(pDraw, pGC, depth, x, y, w, h,
+ leftPad, format, pImage);
+
+ if(boxNotEmpty && pPriv->postRefresh)
+ (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
+
+ SHADOW_GC_OP_EPILOGUE(pGC);
+
+}
+
+static RegionPtr
+ShadowCopyArea(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty
+){
+ RegionPtr ret;
+ BoxRec box;
+ Bool boxNotEmpty = FALSE;
+
+ SHADOW_GC_OP_PROLOGUE(pGC);
+
+ if(IS_VISIBLE(pDst)) {
+ box.x1 = dstx + pDst->x;
+ box.x2 = box.x1 + width;
+ box.y1 = dsty + pDst->y;
+ box.y2 = box.y1 + height;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box)) {
+ if(pPriv->preRefresh)
+ (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
+ boxNotEmpty = TRUE;
+ }
+ }
+
+ ret = (*pGC->ops->CopyArea)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty);
+
+ if(boxNotEmpty && pPriv->postRefresh)
+ (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
+
+ SHADOW_GC_OP_EPILOGUE(pGC);
+
+ return ret;
+}
+
+static RegionPtr
+ShadowCopyPlane(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty,
+ unsigned long bitPlane
+){
+ RegionPtr ret;
+ BoxRec box;
+ Bool boxNotEmpty = FALSE;
+
+ SHADOW_GC_OP_PROLOGUE(pGC);
+
+ if(IS_VISIBLE(pDst)) {
+ box.x1 = dstx + pDst->x;
+ box.x2 = box.x1 + width;
+ box.y1 = dsty + pDst->y;
+ box.y2 = box.y1 + height;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box)) {
+ if(pPriv->preRefresh)
+ (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
+ boxNotEmpty = TRUE;
+ }
+ }
+
+ ret = (*pGC->ops->CopyPlane)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
+
+ if(boxNotEmpty && pPriv->postRefresh)
+ (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
+
+ SHADOW_GC_OP_EPILOGUE(pGC);
+
+ return ret;
+}
+
+static void
+ShadowPolyPoint(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int nptInit,
+ xPoint *pptInit
+){
+ BoxRec box;
+ Bool boxNotEmpty = FALSE;
+
+ SHADOW_GC_OP_PROLOGUE(pGC);
+
+ if(IS_VISIBLE(pDraw) && nptInit) {
+ xPoint *ppt = pptInit;
+ int npt = nptInit;
+
+ box.x2 = box.x1 = pptInit->x;
+ box.y2 = box.y1 = pptInit->y;
+
+ /* this could be slow if the points were spread out */
+
+ while(--npt) {
+ ppt++;
+ if(box.x1 > ppt->x) box.x1 = ppt->x;
+ else if(box.x2 < ppt->x) box.x2 = ppt->x;
+ if(box.y1 > ppt->y) box.y1 = ppt->y;
+ else if(box.y2 < ppt->y) box.y2 = ppt->y;
+ }
+
+ box.x2++;
+ box.y2++;
+
+ TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
+ if(BOX_NOT_EMPTY(box)) {
+ if(pPriv->preRefresh)
+ (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
+ boxNotEmpty = TRUE;
+ }
+ }
+
+ (*pGC->ops->PolyPoint)(pDraw, pGC, mode, nptInit, pptInit);
+
+ if(boxNotEmpty && pPriv->postRefresh)
+ (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
+
+ SHADOW_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+ShadowPolylines(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int nptInit,
+ DDXPointPtr pptInit
+){
+ BoxRec box;
+ Bool boxNotEmpty = FALSE;
+
+ SHADOW_GC_OP_PROLOGUE(pGC);
+
+ if(IS_VISIBLE(pDraw) && nptInit) {
+ DDXPointPtr ppt = pptInit;
+ int npt = nptInit;
+ int extra = pGC->lineWidth >> 1;
+
+ box.x2 = box.x1 = pptInit->x;
+ box.y2 = box.y1 = pptInit->y;
+
+ if(npt > 1) {
+ if(pGC->joinStyle == JoinMiter)
+ extra = 6 * pGC->lineWidth;
+ else if(pGC->capStyle == CapProjecting)
+ extra = pGC->lineWidth;
+ }
+
+ if(mode == CoordModePrevious) {
+ int x = box.x1;
+ int y = box.y1;
+ while(--npt) {
+ ppt++;
+ x += ppt->x;
+ y += ppt->y;
+ if(box.x1 > x) box.x1 = x;
+ else if(box.x2 < x) box.x2 = x;
+ if(box.y1 > y) box.y1 = y;
+ else if(box.y2 < y) box.y2 = y;
+ }
+ } else {
+ while(--npt) {
+ ppt++;
+ if(box.x1 > ppt->x) box.x1 = ppt->x;
+ else if(box.x2 < ppt->x) box.x2 = ppt->x;
+ if(box.y1 > ppt->y) box.y1 = ppt->y;
+ else if(box.y2 < ppt->y) box.y2 = ppt->y;
+ }
+ }
+
+ box.x2++;
+ box.y2++;
+
+ if(extra) {
+ box.x1 -= extra;
+ box.x2 += extra;
+ box.y1 -= extra;
+ box.y2 += extra;
+ }
+
+ TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
+ if(BOX_NOT_EMPTY(box)) {
+ if(pPriv->preRefresh)
+ (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
+ boxNotEmpty = TRUE;
+ }
+ }
+
+ (*pGC->ops->Polylines)(pDraw, pGC, mode, nptInit, pptInit);
+
+ if(boxNotEmpty && pPriv->postRefresh)
+ (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
+
+ SHADOW_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+ShadowPolySegment(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nsegInit,
+ xSegment *pSegInit
+){
+ BoxRec box;
+ Bool boxNotEmpty = FALSE;
+
+ SHADOW_GC_OP_PROLOGUE(pGC);
+
+ if(IS_VISIBLE(pDraw) && nsegInit) {
+ int extra = pGC->lineWidth;
+ xSegment *pSeg = pSegInit;
+ int nseg = nsegInit;
+
+ if(pGC->capStyle != CapProjecting)
+ extra >>= 1;
+
+ if(pSeg->x2 > pSeg->x1) {
+ box.x1 = pSeg->x1;
+ box.x2 = pSeg->x2;
+ } else {
+ box.x2 = pSeg->x1;
+ box.x1 = pSeg->x2;
+ }
+
+ if(pSeg->y2 > pSeg->y1) {
+ box.y1 = pSeg->y1;
+ box.y2 = pSeg->y2;
+ } else {
+ box.y2 = pSeg->y1;
+ box.y1 = pSeg->y2;
+ }
+
+ while(--nseg) {
+ pSeg++;
+ if(pSeg->x2 > pSeg->x1) {
+ if(pSeg->x1 < box.x1) box.x1 = pSeg->x1;
+ if(pSeg->x2 > box.x2) box.x2 = pSeg->x2;
+ } else {
+ if(pSeg->x2 < box.x1) box.x1 = pSeg->x2;
+ if(pSeg->x1 > box.x2) box.x2 = pSeg->x1;
+ }
+ if(pSeg->y2 > pSeg->y1) {
+ if(pSeg->y1 < box.y1) box.y1 = pSeg->y1;
+ if(pSeg->y2 > box.y2) box.y2 = pSeg->y2;
+ } else {
+ if(pSeg->y2 < box.y1) box.y1 = pSeg->y2;
+ if(pSeg->y1 > box.y2) box.y2 = pSeg->y1;
+ }
+ }
+
+ box.x2++;
+ box.y2++;
+
+ if(extra) {
+ box.x1 -= extra;
+ box.x2 += extra;
+ box.y1 -= extra;
+ box.y2 += extra;
+ }
+
+ TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
+ if(BOX_NOT_EMPTY(box)) {
+ if(pPriv->preRefresh)
+ (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
+ boxNotEmpty = TRUE;
+ }
+ }
+
+ (*pGC->ops->PolySegment)(pDraw, pGC, nsegInit, pSegInit);
+
+ if(boxNotEmpty && pPriv->postRefresh)
+ (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
+
+ SHADOW_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+ShadowPolyRectangle(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nRectsInit,
+ xRectangle *pRectsInit
+){
+ BoxRec box;
+ BoxPtr pBoxInit = NULL;
+ Bool boxNotEmpty = FALSE;
+ int num = 0;
+
+ SHADOW_GC_OP_PROLOGUE(pGC);
+
+ if(IS_VISIBLE(pDraw) && nRectsInit) {
+ xRectangle *pRects = pRectsInit;
+ int nRects = nRectsInit;
+
+ if(nRects >= 32) {
+ int extra = pGC->lineWidth >> 1;
+
+ box.x1 = pRects->x;
+ box.x2 = box.x1 + pRects->width;
+ box.y1 = pRects->y;
+ box.y2 = box.y1 + pRects->height;
+
+ while(--nRects) {
+ pRects++;
+ if(box.x1 > pRects->x) box.x1 = pRects->x;
+ if(box.x2 < (pRects->x + pRects->width))
+ box.x2 = pRects->x + pRects->width;
+ if(box.y1 > pRects->y) box.y1 = pRects->y;
+ if(box.y2 < (pRects->y + pRects->height))
+ box.y2 = pRects->y + pRects->height;
+ }
+
+ if(extra) {
+ box.x1 -= extra;
+ box.x2 += extra;
+ box.y1 -= extra;
+ box.y2 += extra;
+ }
+
+ box.x2++;
+ box.y2++;
+
+ TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
+ if(BOX_NOT_EMPTY(box)) {
+ if(pPriv->preRefresh)
+ (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
+ boxNotEmpty = TRUE;
+ }
+ } else {
+ BoxPtr pbox;
+ int offset1, offset2, offset3;
+
+ offset2 = pGC->lineWidth;
+ if(!offset2) offset2 = 1;
+ offset1 = offset2 >> 1;
+ offset3 = offset2 - offset1;
+
+ pBoxInit = (BoxPtr)malloc(nRects * 4 * sizeof(BoxRec));
+ pbox = pBoxInit;
+
+ while(nRects--) {
+ pbox->x1 = pRects->x - offset1;
+ pbox->y1 = pRects->y - offset1;
+ pbox->x2 = pbox->x1 + pRects->width + offset2;
+ pbox->y2 = pbox->y1 + offset2;
+ TRIM_AND_TRANSLATE_BOX((*pbox), pDraw, pGC);
+ if(BOX_NOT_EMPTY((*pbox))) {
+ num++;
+ pbox++;
+ }
+
+ pbox->x1 = pRects->x - offset1;
+ pbox->y1 = pRects->y + offset3;
+ pbox->x2 = pbox->x1 + offset2;
+ pbox->y2 = pbox->y1 + pRects->height - offset2;
+ TRIM_AND_TRANSLATE_BOX((*pbox), pDraw, pGC);
+ if(BOX_NOT_EMPTY((*pbox))) {
+ num++;
+ pbox++;
+ }
+
+ pbox->x1 = pRects->x + pRects->width - offset1;
+ pbox->y1 = pRects->y + offset3;
+ pbox->x2 = pbox->x1 + offset2;
+ pbox->y2 = pbox->y1 + pRects->height - offset2;
+ TRIM_AND_TRANSLATE_BOX((*pbox), pDraw, pGC);
+ if(BOX_NOT_EMPTY((*pbox))) {
+ num++;
+ pbox++;
+ }
+
+ pbox->x1 = pRects->x - offset1;
+ pbox->y1 = pRects->y + pRects->height - offset1;
+ pbox->x2 = pbox->x1 + pRects->width + offset2;
+ pbox->y2 = pbox->y1 + offset2;
+ TRIM_AND_TRANSLATE_BOX((*pbox), pDraw, pGC);
+ if(BOX_NOT_EMPTY((*pbox))) {
+ num++;
+ pbox++;
+ }
+
+ pRects++;
+ }
+
+ if(num) {
+ if(pPriv->preRefresh)
+ (*pPriv->preRefresh)(pPriv->pScrn, num, pBoxInit);
+ } else {
+ free(pBoxInit);
+ }
+ }
+ }
+
+ (*pGC->ops->PolyRectangle)(pDraw, pGC, nRectsInit, pRectsInit);
+
+ if(boxNotEmpty && pPriv->postRefresh) {
+ (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
+ } else if(num) {
+ if(pPriv->postRefresh)
+ (*pPriv->postRefresh)(pPriv->pScrn, num, pBoxInit);
+ free(pBoxInit);
+ }
+
+ SHADOW_GC_OP_EPILOGUE(pGC);
+
+}
+
+static void
+ShadowPolyArc(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcsInit,
+ xArc *parcsInit
+){
+ BoxRec box;
+ Bool boxNotEmpty = FALSE;
+
+ SHADOW_GC_OP_PROLOGUE(pGC);
+
+ if(IS_VISIBLE(pDraw) && narcsInit) {
+ int narcs = narcsInit;
+ xArc *parcs = parcsInit;
+ int extra = pGC->lineWidth >> 1;
+
+ box.x1 = parcs->x;
+ box.x2 = box.x1 + parcs->width;
+ box.y1 = parcs->y;
+ box.y2 = box.y1 + parcs->height;
+
+ /* should I break these up instead ? */
+
+ while(--narcs) {
+ parcs++;
+ if(box.x1 > parcs->x) box.x1 = parcs->x;
+ if(box.x2 < (parcs->x + parcs->width))
+ box.x2 = parcs->x + parcs->width;
+ if(box.y1 > parcs->y) box.y1 = parcs->y;
+ if(box.y2 < (parcs->y + parcs->height))
+ box.y2 = parcs->y + parcs->height;
+ }
+
+ if(extra) {
+ box.x1 -= extra;
+ box.x2 += extra;
+ box.y1 -= extra;
+ box.y2 += extra;
+ }
+
+ box.x2++;
+ box.y2++;
+
+ TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
+ if(BOX_NOT_EMPTY(box)) {
+ if(pPriv->preRefresh)
+ (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
+ boxNotEmpty = TRUE;
+ }
+ }
+
+ (*pGC->ops->PolyArc)(pDraw, pGC, narcsInit, parcsInit);
+
+ if(boxNotEmpty && pPriv->postRefresh)
+ (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
+
+ SHADOW_GC_OP_EPILOGUE(pGC);
+
+}
+
+static void
+ShadowFillPolygon(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr pptInit
+){
+ SHADOW_GC_OP_PROLOGUE(pGC);
+
+ if(IS_VISIBLE(pDraw) && (count > 2)) {
+ DDXPointPtr ppt = pptInit;
+ int i = count;
+ BoxRec box;
+ Bool boxNotEmpty = FALSE;
+
+ box.x2 = box.x1 = ppt->x;
+ box.y2 = box.y1 = ppt->y;
+
+ if(mode != CoordModeOrigin) {
+ int x = box.x1;
+ int y = box.y1;
+ while(--i) {
+ ppt++;
+ x += ppt->x;
+ y += ppt->y;
+ if(box.x1 > x) box.x1 = x;
+ else if(box.x2 < x) box.x2 = x;
+ if(box.y1 > y) box.y1 = y;
+ else if(box.y2 < y) box.y2 = y;
+ }
+ } else {
+ while(--i) {
+ ppt++;
+ if(box.x1 > ppt->x) box.x1 = ppt->x;
+ else if(box.x2 < ppt->x) box.x2 = ppt->x;
+ if(box.y1 > ppt->y) box.y1 = ppt->y;
+ else if(box.y2 < ppt->y) box.y2 = ppt->y;
+ }
+ }
+
+ box.x2++;
+ box.y2++;
+
+ TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
+ if(BOX_NOT_EMPTY(box)) {
+ if(pPriv->preRefresh)
+ (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
+ boxNotEmpty = TRUE;
+ }
+
+ (*pGC->ops->FillPolygon)(pDraw, pGC, shape, mode, count, pptInit);
+
+ if(boxNotEmpty && pPriv->postRefresh)
+ (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
+ } else
+ (*pGC->ops->FillPolygon)(pDraw, pGC, shape, mode, count, pptInit);
+
+ SHADOW_GC_OP_EPILOGUE(pGC);
+}
+
+
+static void
+ShadowPolyFillRect(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nRectsInit,
+ xRectangle *pRectsInit
+){
+ SHADOW_GC_OP_PROLOGUE(pGC);
+
+ if(IS_VISIBLE(pDraw) && nRectsInit) {
+ BoxRec box;
+ Bool boxNotEmpty = FALSE;
+ xRectangle *pRects = pRectsInit;
+ int nRects = nRectsInit;
+
+ box.x1 = pRects->x;
+ box.x2 = box.x1 + pRects->width;
+ box.y1 = pRects->y;
+ box.y2 = box.y1 + pRects->height;
+
+ while(--nRects) {
+ pRects++;
+ if(box.x1 > pRects->x) box.x1 = pRects->x;
+ if(box.x2 < (pRects->x + pRects->width))
+ box.x2 = pRects->x + pRects->width;
+ if(box.y1 > pRects->y) box.y1 = pRects->y;
+ if(box.y2 < (pRects->y + pRects->height))
+ box.y2 = pRects->y + pRects->height;
+ }
+
+ /* cfb messes with the pRectsInit so we have to do our
+ calculations first */
+
+ TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
+ if(BOX_NOT_EMPTY(box)) {
+ if(pPriv->preRefresh)
+ (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
+ boxNotEmpty = TRUE;
+ }
+
+ (*pGC->ops->PolyFillRect)(pDraw, pGC, nRectsInit, pRectsInit);
+
+ if(boxNotEmpty && pPriv->postRefresh)
+ (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
+ } else
+ (*pGC->ops->PolyFillRect)(pDraw, pGC, nRectsInit, pRectsInit);
+
+ SHADOW_GC_OP_EPILOGUE(pGC);
+}
+
+
+static void
+ShadowPolyFillArc(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcsInit,
+ xArc *parcsInit
+){
+ BoxRec box;
+ Bool boxNotEmpty = FALSE;
+
+ SHADOW_GC_OP_PROLOGUE(pGC);
+
+ if(IS_VISIBLE(pDraw) && narcsInit) {
+ xArc *parcs = parcsInit;
+ int narcs = narcsInit;
+
+ box.x1 = parcs->x;
+ box.x2 = box.x1 + parcs->width;
+ box.y1 = parcs->y;
+ box.y2 = box.y1 + parcs->height;
+
+ /* should I break these up instead ? */
+
+ while(--narcs) {
+ parcs++;
+ if(box.x1 > parcs->x) box.x1 = parcs->x;
+ if(box.x2 < (parcs->x + parcs->width))
+ box.x2 = parcs->x + parcs->width;
+ if(box.y1 > parcs->y) box.y1 = parcs->y;
+ if(box.y2 < (parcs->y + parcs->height))
+ box.y2 = parcs->y + parcs->height;
+ }
+
+ TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC);
+ if(BOX_NOT_EMPTY(box)) {
+ if(pPriv->preRefresh)
+ (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
+ boxNotEmpty = TRUE;
+ }
+ }
+
+ (*pGC->ops->PolyFillArc)(pDraw, pGC, narcsInit, parcsInit);
+
+ if(boxNotEmpty && pPriv->postRefresh)
+ (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
+
+ SHADOW_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+ShadowTextExtent(FontPtr pFont, int count, char* chars,
+ FontEncoding fontEncoding, BoxPtr box)
+{
+ unsigned long n, i;
+ int w;
+ CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */
+
+ GetGlyphs(pFont, (unsigned long)count, (unsigned char *)chars,
+ fontEncoding, &n, charinfo);
+ w = 0;
+ for (i=0; i < n; i++) {
+ w += charinfo[i]->metrics.characterWidth;
+ }
+ if (i) {
+ w += charinfo[i - 1]->metrics.rightSideBearing;
+ }
+
+ box->x1 = 0;
+ if (n) {
+ if (charinfo[0]->metrics.leftSideBearing < 0) {
+ box->x1 = charinfo[0]->metrics.leftSideBearing;
+ }
+ }
+ box->x2 = w;
+ box->y1 = -FONTMAXBOUNDS(pFont,ascent);
+ box->y2 = FONTMAXBOUNDS(pFont,descent);
+}
+
+
+
+static void
+ShadowFontToBox(BoxPtr BB, DrawablePtr pDrawable, GCPtr pGC, int x, int y,
+ int count, char *chars, int wide)
+{
+ FontPtr pFont;
+
+ pFont = pGC->font;
+ if (pFont->info.constantWidth) {
+ int ascent, descent, left, right = 0;
+
+ ascent = max(pFont->info.fontAscent, pFont->info.maxbounds.ascent);
+ descent = max(pFont->info.fontDescent, pFont->info.maxbounds.descent);
+ left = pFont->info.maxbounds.leftSideBearing;
+ if (count > 0) {
+ right = (count - 1) * pFont->info.maxbounds.characterWidth;
+ }
+ right += pFont->info.maxbounds.rightSideBearing;
+ BB->x1 =
+ max(pDrawable->x + x - left, (REGION_EXTENTS(pGC->pScreen,
+ &((WindowPtr) pDrawable)->winSize))->x1);
+ BB->y1 =
+ max(pDrawable->y + y - ascent,
+ (REGION_EXTENTS(pGC->pScreen,
+ &((WindowPtr) pDrawable)->winSize))->y1);
+ BB->x2 =
+ min(pDrawable->x + x + right,
+ (REGION_EXTENTS(pGC->pScreen,
+ &((WindowPtr) pDrawable)->winSize))->x2);
+ BB->y2 =
+ min(pDrawable->y + y + descent,
+ (REGION_EXTENTS(pGC->pScreen,
+ &((WindowPtr) pDrawable)->winSize))->y2);
+ } else {
+ ShadowTextExtent(pFont, count, chars, wide ? (FONTLASTROW(pFont) == 0)
+ ? Linear16Bit : TwoD16Bit : Linear8Bit, BB);
+ BB->x1 =
+ max(pDrawable->x + x + BB->x1, (REGION_EXTENTS(pGC->pScreen,
+ &((WindowPtr) pDrawable)->winSize))->x1);
+ BB->y1 =
+ max(pDrawable->y + y + BB->y1,
+ (REGION_EXTENTS(pGC->pScreen,
+ &((WindowPtr) pDrawable)->winSize))->y1);
+ BB->x2 =
+ min(pDrawable->x + x + BB->x2,
+ (REGION_EXTENTS(pGC->pScreen,
+ &((WindowPtr) pDrawable)->winSize))->x2);
+ BB->y2 =
+ min(pDrawable->y + y + BB->y2,
+ (REGION_EXTENTS(pGC->pScreen,
+ &((WindowPtr) pDrawable)->winSize))->y2);
+ }
+}
+
+static int
+ShadowPolyText8(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars
+){
+ int width;
+ BoxRec box;
+ Bool boxNotEmpty = FALSE;
+
+ SHADOW_GC_OP_PROLOGUE(pGC);
+
+ if(IS_VISIBLE(pDraw)) {
+ ShadowFontToBox(&box, pDraw, pGC, x, y, count, chars, 0);
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box)) {
+ if(pPriv->preRefresh)
+ (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
+ boxNotEmpty = TRUE;
+ }
+ }
+
+ width = (*pGC->ops->PolyText8)(pDraw, pGC, x, y, count, chars);
+
+ if(boxNotEmpty && pPriv->postRefresh)
+ (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
+
+ SHADOW_GC_OP_EPILOGUE(pGC);
+
+ return width;
+}
+
+static int
+ShadowPolyText16(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars
+){
+ int width;
+ BoxRec box;
+ Bool boxNotEmpty = FALSE;
+
+ SHADOW_GC_OP_PROLOGUE(pGC);
+
+ if(IS_VISIBLE(pDraw)) {
+ ShadowFontToBox(&box, pDraw, pGC, x, y, count, (char*)chars, 1);
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box)) {
+ if(pPriv->preRefresh)
+ (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
+ boxNotEmpty = TRUE;
+ }
+ }
+
+ width = (*pGC->ops->PolyText16)(pDraw, pGC, x, y, count, chars);
+
+ if(boxNotEmpty && pPriv->postRefresh)
+ (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
+
+ SHADOW_GC_OP_EPILOGUE(pGC);
+
+ return width;
+}
+
+static void
+ShadowImageText8(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars
+){
+ BoxRec box;
+ Bool boxNotEmpty = FALSE;
+ SHADOW_GC_OP_PROLOGUE(pGC);
+
+ if(IS_VISIBLE(pDraw) && count) {
+ int top, bot, Min, Max;
+
+ top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font));
+ bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font));
+
+ Min = count * FONTMINBOUNDS(pGC->font, characterWidth);
+ if(Min > 0) Min = 0;
+ Max = count * FONTMAXBOUNDS(pGC->font, characterWidth);
+ if(Max < 0) Max = 0;
+
+ /* ugh */
+ box.x1 = pDraw->x + x + Min +
+ FONTMINBOUNDS(pGC->font, leftSideBearing);
+ box.x2 = pDraw->x + x + Max +
+ FONTMAXBOUNDS(pGC->font, rightSideBearing);
+
+ box.y1 = pDraw->y + y - top;
+ box.y2 = pDraw->y + y + bot;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box)) {
+ if(pPriv->preRefresh)
+ (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
+ boxNotEmpty = TRUE;
+ }
+ }
+
+ (*pGC->ops->ImageText8)(pDraw, pGC, x, y, count, chars);
+
+ if(boxNotEmpty && pPriv->postRefresh)
+ (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
+
+ SHADOW_GC_OP_EPILOGUE(pGC);
+}
+static void
+ShadowImageText16(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars
+){
+ BoxRec box;
+ Bool boxNotEmpty = FALSE;
+ SHADOW_GC_OP_PROLOGUE(pGC);
+
+ if(IS_VISIBLE(pDraw) && count) {
+ int top, bot, Min, Max;
+
+ top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font));
+ bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font));
+
+ Min = count * FONTMINBOUNDS(pGC->font, characterWidth);
+ if(Min > 0) Min = 0;
+ Max = count * FONTMAXBOUNDS(pGC->font, characterWidth);
+ if(Max < 0) Max = 0;
+
+ /* ugh */
+ box.x1 = pDraw->x + x + Min +
+ FONTMINBOUNDS(pGC->font, leftSideBearing);
+ box.x2 = pDraw->x + x + Max +
+ FONTMAXBOUNDS(pGC->font, rightSideBearing);
+
+ box.y1 = pDraw->y + y - top;
+ box.y2 = pDraw->y + y + bot;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box)) {
+ if(pPriv->preRefresh)
+ (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
+ boxNotEmpty = TRUE;
+ }
+ }
+
+ (*pGC->ops->ImageText16)(pDraw, pGC, x, y, count, chars);
+
+ if(boxNotEmpty && pPriv->postRefresh)
+ (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
+
+ SHADOW_GC_OP_EPILOGUE(pGC);
+}
+
+
+static void
+ShadowImageGlyphBlt(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ unsigned int nglyphInit,
+ CharInfoPtr *ppciInit,
+ pointer pglyphBase
+){
+ BoxRec box;
+ Bool boxNotEmpty = FALSE;
+ SHADOW_GC_OP_PROLOGUE(pGC);
+
+ if(IS_VISIBLE(pDraw) && nglyphInit) {
+ CharInfoPtr *ppci = ppciInit;
+ unsigned int nglyph = nglyphInit;
+ int top, bot, width = 0;
+
+ top = max(FONTMAXBOUNDS(pGC->font, ascent), FONTASCENT(pGC->font));
+ bot = max(FONTMAXBOUNDS(pGC->font, descent), FONTDESCENT(pGC->font));
+
+ box.x1 = ppci[0]->metrics.leftSideBearing;
+ if(box.x1 > 0) box.x1 = 0;
+ box.x2 = ppci[nglyph - 1]->metrics.rightSideBearing -
+ ppci[nglyph - 1]->metrics.characterWidth;
+ if(box.x2 < 0) box.x2 = 0;
+
+ box.x2 += pDraw->x + x;
+ box.x1 += pDraw->x + x;
+
+ while(nglyph--) {
+ width += (*ppci)->metrics.characterWidth;
+ ppci++;
+ }
+
+ if(width > 0)
+ box.x2 += width;
+ else
+ box.x1 += width;
+
+ box.y1 = pDraw->y + y - top;
+ box.y2 = pDraw->y + y + bot;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box)) {
+ if(pPriv->preRefresh)
+ (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
+ boxNotEmpty = TRUE;
+ }
+ }
+
+ (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, x, y, nglyphInit,
+ ppciInit, pglyphBase);
+
+ if(boxNotEmpty && pPriv->postRefresh)
+ (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
+
+ SHADOW_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+ShadowPolyGlyphBlt(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ unsigned int nglyphInit,
+ CharInfoPtr *ppciInit,
+ pointer pglyphBase
+){
+ BoxRec box;
+ Bool boxNotEmpty = FALSE;
+
+ SHADOW_GC_OP_PROLOGUE(pGC);
+
+ if(IS_VISIBLE(pDraw) && nglyphInit) {
+ CharInfoPtr *ppci = ppciInit;
+ unsigned int nglyph = nglyphInit;
+
+ /* ugh */
+ box.x1 = pDraw->x + x + ppci[0]->metrics.leftSideBearing;
+ box.x2 = pDraw->x + x + ppci[nglyph - 1]->metrics.rightSideBearing;
+
+ if(nglyph > 1) {
+ int width = 0;
+
+ while(--nglyph) {
+ width += (*ppci)->metrics.characterWidth;
+ ppci++;
+ }
+
+ if(width > 0) box.x2 += width;
+ else box.x1 += width;
+ }
+
+ box.y1 = pDraw->y + y - FONTMAXBOUNDS(pGC->font, ascent);
+ box.y2 = pDraw->y + y + FONTMAXBOUNDS(pGC->font, descent);
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box)) {
+ if(pPriv->preRefresh)
+ (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
+ boxNotEmpty = TRUE;
+ }
+ }
+
+ (*pGC->ops->PolyGlyphBlt)(pDraw, pGC, x, y, nglyphInit,
+ ppciInit, pglyphBase);
+
+ if(boxNotEmpty && pPriv->postRefresh)
+ (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
+
+ SHADOW_GC_OP_EPILOGUE(pGC);
+}
+
+static void
+ShadowPushPixels(
+ GCPtr pGC,
+ PixmapPtr pBitMap,
+ DrawablePtr pDraw,
+ int dx, int dy, int xOrg, int yOrg
+){
+ BoxRec box;
+ Bool boxNotEmpty = FALSE;
+
+ SHADOW_GC_OP_PROLOGUE(pGC);
+
+ if(IS_VISIBLE(pDraw)) {
+ box.x1 = xOrg;
+ box.y1 = yOrg;
+
+ if(!pGC->miTranslate) {
+ box.x1 += pDraw->x;
+ box.y1 += pDraw->y;
+ }
+
+ box.x2 = box.x1 + dx;
+ box.y2 = box.y1 + dy;
+
+ TRIM_BOX(box, pGC);
+ if(BOX_NOT_EMPTY(box)) {
+ if(pPriv->preRefresh)
+ (*pPriv->preRefresh)(pPriv->pScrn, 1, &box);
+ boxNotEmpty = TRUE;
+ }
+ }
+
+ (*pGC->ops->PushPixels)(pGC, pBitMap, pDraw, dx, dy, xOrg, yOrg);
+
+ if(boxNotEmpty && pPriv->postRefresh)
+ (*pPriv->postRefresh)(pPriv->pScrn, 1, &box);
+
+ SHADOW_GC_OP_EPILOGUE(pGC);
+}
+
+
+GCOps ShadowGCOps = {
+ ShadowFillSpans, ShadowSetSpans,
+ ShadowPutImage, ShadowCopyArea,
+ ShadowCopyPlane, ShadowPolyPoint,
+ ShadowPolylines, ShadowPolySegment,
+ ShadowPolyRectangle, ShadowPolyArc,
+ ShadowFillPolygon, ShadowPolyFillRect,
+ ShadowPolyFillArc, ShadowPolyText8,
+ ShadowPolyText16, ShadowImageText8,
+ ShadowImageText16, ShadowImageGlyphBlt,
+ ShadowPolyGlyphBlt, ShadowPushPixels,
+ {NULL} /* devPrivate */
+};
+
diff --git a/xorg-server/hw/xfree86/vbe/vbe.c b/xorg-server/hw/xfree86/vbe/vbe.c
index 26f5911d5..bb88b86cf 100644
--- a/xorg-server/hw/xfree86/vbe/vbe.c
+++ b/xorg-server/hw/xfree86/vbe/vbe.c
@@ -1,1145 +1,1145 @@
-
-/*
- * XFree86 vbe module
- * Copyright 2000 Egbert Eich
- *
- * The mode query/save/set/restore functions from the vesa driver
- * have been moved here.
- * Copyright (c) 2000 by Conectiva S.A. (http://www.conectiva.com)
- * Authors: Paulo César Pereira de Andrade <pcpa@conectiva.com.br>
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <string.h>
-
-#include "xf86.h"
-#include "vbe.h"
-#include <X11/Xarch.h>
-#include <X11/extensions/dpmsconst.h>
-
-#define VERSION(x) VBE_VERSION_MAJOR(x),VBE_VERSION_MINOR(x)
-
-#if X_BYTE_ORDER == X_LITTLE_ENDIAN
-#define B_O16(x) (x)
-#define B_O32(x) (x)
-#else
-#define B_O16(x) ((((x) & 0xff) << 8) | (((x) & 0xff) >> 8))
-#define B_O32(x) ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) \
- | (((x) & 0xff0000) >> 8) | (((x) & 0xff000000) >> 24))
-#endif
-#define L_ADD(x) (B_O32(x) & 0xffff) + ((B_O32(x) >> 12) & 0xffff00)
-
-#define FARP(p) (((unsigned)(p & 0xffff0000) >> 12) | (p & 0xffff))
-#define R16(v) ((v) & 0xffff)
-
-static unsigned char * vbeReadEDID(vbeInfoPtr pVbe);
-static Bool vbeProbeDDC(vbeInfoPtr pVbe);
-
-static const char vbeVersionString[] = "VBE2";
-
-vbeInfoPtr
-VBEInit(xf86Int10InfoPtr pInt, int entityIndex)
-{
- return VBEExtendedInit(pInt, entityIndex, 0);
-}
-
-vbeInfoPtr
-VBEExtendedInit(xf86Int10InfoPtr pInt, int entityIndex, int Flags)
-{
- int RealOff;
- pointer page = NULL;
- ScrnInfoPtr pScrn = xf86FindScreenForEntity(entityIndex);
- vbeControllerInfoPtr vbe = NULL;
- Bool init_int10 = FALSE;
- vbeInfoPtr vip = NULL;
- int screen;
-
- if (!pScrn) return NULL;
- screen = pScrn->scrnIndex;
-
- if (!pInt) {
- if (!xf86LoadSubModule(pScrn, "int10"))
- goto error;
-
- xf86DrvMsg(screen,X_INFO,"initializing int10\n");
- pInt = xf86ExtendedInitInt10(entityIndex,Flags);
- if (!pInt)
- goto error;
- init_int10 = TRUE;
- }
-
- page = xf86Int10AllocPages(pInt,1,&RealOff);
- if (!page) goto error;
- vbe = (vbeControllerInfoPtr) page;
- memcpy(vbe->VbeSignature,vbeVersionString,4);
-
- pInt->ax = 0x4F00;
- pInt->es = SEG_ADDR(RealOff);
- pInt->di = SEG_OFF(RealOff);
- pInt->num = 0x10;
-
- xf86ExecX86int10(pInt);
-
- if ((pInt->ax & 0xff) != 0x4f) {
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA BIOS not detected\n");
- goto error;
- }
-
- switch (pInt->ax & 0xff00) {
- case 0:
- xf86DrvMsg(screen,X_INFO,"VESA BIOS detected\n");
- break;
- case 0x100:
- xf86DrvMsg(screen,X_INFO,"VESA BIOS function failed\n");
- goto error;
- case 0x200:
- xf86DrvMsg(screen,X_INFO,"VESA BIOS not supported\n");
- goto error;
- case 0x300:
- xf86DrvMsg(screen,X_INFO,"VESA BIOS not supported in current mode\n");
- goto error;
- default:
- xf86DrvMsg(screen,X_INFO,"Invalid\n");
- goto error;
- }
-
- xf86DrvMsgVerb(screen, X_INFO, 4,
- "VbeVersion is %d, OemStringPtr is 0x%08lx,\n"
- "\tOemVendorNamePtr is 0x%08lx, OemProductNamePtr is 0x%08lx,\n"
- "\tOemProductRevPtr is 0x%08lx\n",
- vbe->VbeVersion, (unsigned long)vbe->OemStringPtr,
- (unsigned long)vbe->OemVendorNamePtr,
- (unsigned long)vbe->OemProductNamePtr,
- (unsigned long)vbe->OemProductRevPtr);
-
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE Version %i.%i\n",
- VERSION(vbe->VbeVersion));
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE Total Mem: %i kB\n",
- vbe->TotalMem * 64);
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM: %s\n",
- (CARD8*)xf86int10Addr(pInt,L_ADD(vbe->OemStringPtr)));
-
- if (B_O16(vbe->VbeVersion) >= 0x200) {
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM Software Rev: %i.%i\n",
- VERSION(vbe->OemSoftwareRev));
- if (vbe->OemVendorNamePtr)
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM Vendor: %s\n",
- (CARD8*)xf86int10Addr(pInt,L_ADD(vbe->OemVendorNamePtr)));
- if (vbe->OemProductNamePtr)
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM Product: %s\n",
- (CARD8*)xf86int10Addr(pInt,L_ADD(vbe->OemProductNamePtr)));
- if (vbe->OemProductRevPtr)
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM Product Rev: %s\n",
- (CARD8*)xf86int10Addr(pInt,L_ADD(vbe->OemProductRevPtr)));
- }
- vip = (vbeInfoPtr)xnfalloc(sizeof(vbeInfoRec));
- vip->version = B_O16(vbe->VbeVersion);
- vip->pInt10 = pInt;
- vip->ddc = DDC_UNCHECKED;
- vip->memory = page;
- vip->real_mode_base = RealOff;
- vip->num_pages = 1;
- vip->init_int10 = init_int10;
-
- return vip;
-
- error:
- if (page)
- xf86Int10FreePages(pInt, page, 1);
- if (init_int10)
- xf86FreeInt10(pInt);
- return NULL;
-}
-
-void
-vbeFree(vbeInfoPtr pVbe)
-{
- if (!pVbe)
- return;
-
- xf86Int10FreePages(pVbe->pInt10,pVbe->memory,pVbe->num_pages);
- /* If we have initalized int10 we ought to free it, too */
- if (pVbe->init_int10)
- xf86FreeInt10(pVbe->pInt10);
- xfree(pVbe);
- return;
-}
-
-static Bool
-vbeProbeDDC(vbeInfoPtr pVbe)
-{
- char *ddc_level;
- int screen = pVbe->pInt10->scrnIndex;
-
- if (pVbe->ddc == DDC_NONE)
- return FALSE;
- if (pVbe->ddc != DDC_UNCHECKED)
- return TRUE;
-
- pVbe->pInt10->ax = 0x4F15;
- pVbe->pInt10->bx = 0;
- pVbe->pInt10->cx = 0;
- pVbe->pInt10->es = 0;
- pVbe->pInt10->di = 0;
- pVbe->pInt10->num = 0x10;
-
- xf86ExecX86int10(pVbe->pInt10);
-
- if ((pVbe->pInt10->ax & 0xff) != 0x4f) {
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC not supported\n");
- pVbe->ddc = DDC_NONE;
- return FALSE;
- }
-
- switch ((pVbe->pInt10->ax >> 8) & 0xff) {
- case 0:
- xf86DrvMsg(screen,X_INFO,"VESA VBE DDC supported\n");
- switch (pVbe->pInt10->bx & 0x3) {
- case 0:
- ddc_level = " none";
- pVbe->ddc = DDC_NONE;
- break;
- case 1:
- ddc_level = " 1";
- pVbe->ddc = DDC_1;
- break;
- case 2:
- ddc_level = " 2";
- pVbe->ddc = DDC_2;
- break;
- case 3:
- ddc_level = " 1 + 2";
- pVbe->ddc = DDC_1_2;
- break;
- default:
- ddc_level = "";
- pVbe->ddc = DDC_NONE;
- break;
- }
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC Level%s\n",ddc_level);
- if (pVbe->pInt10->bx & 0x4) {
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC Screen blanked"
- "for data transfer\n");
- pVbe->ddc_blank = TRUE;
- } else
- pVbe->ddc_blank = FALSE;
-
- xf86DrvMsgVerb(screen,X_INFO,3,
- "VESA VBE DDC transfer in appr. %x sec.\n",
- (pVbe->pInt10->bx >> 8) & 0xff);
- }
-
- return TRUE;
-}
-
-typedef enum {
- VBEOPT_NOVBE,
- VBEOPT_NODDC
-} VBEOpts;
-
-static const OptionInfoRec VBEOptions[] = {
- { VBEOPT_NOVBE, "NoVBE", OPTV_BOOLEAN, {0}, FALSE },
- { VBEOPT_NODDC, "NoDDC", OPTV_BOOLEAN, {0}, FALSE },
- { -1, NULL, OPTV_NONE, {0}, FALSE },
-};
-
-static unsigned char *
-vbeReadEDID(vbeInfoPtr pVbe)
-{
- int RealOff = pVbe->real_mode_base;
- pointer page = pVbe->memory;
- unsigned char *tmp = NULL;
- Bool novbe = FALSE;
- Bool noddc = FALSE;
- int screen = pVbe->pInt10->scrnIndex;
- OptionInfoPtr options;
-
- if (!page) return NULL;
-
- options = xnfalloc(sizeof(VBEOptions));
- (void)memcpy(options, VBEOptions, sizeof(VBEOptions));
- xf86ProcessOptions(screen, xf86Screens[screen]->options, options);
- xf86GetOptValBool(options, VBEOPT_NOVBE, &novbe);
- xf86GetOptValBool(options, VBEOPT_NODDC, &noddc);
- xfree(options);
- if (novbe || noddc) return NULL;
-
- if (!vbeProbeDDC(pVbe)) goto error;
-
- memset(page,0,sizeof(vbeInfoPtr));
- strcpy(page,vbeVersionString);
-
- pVbe->pInt10->ax = 0x4F15;
- pVbe->pInt10->bx = 0x01;
- pVbe->pInt10->cx = 0;
- pVbe->pInt10->dx = 0;
- pVbe->pInt10->es = SEG_ADDR(RealOff);
- pVbe->pInt10->di = SEG_OFF(RealOff);
- pVbe->pInt10->num = 0x10;
-
- xf86ExecX86int10(pVbe->pInt10);
-
- if ((pVbe->pInt10->ax & 0xff) != 0x4f) {
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC invalid\n");
- goto error;
- }
- switch (pVbe->pInt10->ax & 0xff00) {
- case 0x0:
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC read successfully\n");
- tmp = (unsigned char *)xnfalloc(128);
- memcpy(tmp,page,128);
- break;
- case 0x100:
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC read failed\n");
- break;
- default:
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC unkown failure %i\n",
- pVbe->pInt10->ax & 0xff00);
- break;
- }
-
- error:
- return tmp;
-}
-
-xf86MonPtr
-vbeDoEDID(vbeInfoPtr pVbe, pointer pDDCModule)
-{
- xf86MonPtr pMonitor;
- pointer pModule;
- unsigned char *DDC_data = NULL;
-
- if (!pVbe) return NULL;
- if (pVbe->version < 0x200)
- return NULL;
-
- if (!(pModule = pDDCModule)) {
- pModule =
- xf86LoadSubModule(xf86Screens[pVbe->pInt10->scrnIndex], "ddc");
- if (!pModule)
- return NULL;
- }
-
- DDC_data = vbeReadEDID(pVbe);
-
- if (!DDC_data)
- return NULL;
-
- pMonitor = xf86InterpretEDID(pVbe->pInt10->scrnIndex, DDC_data);
-
- if (!pDDCModule)
- xf86UnloadSubModule(pModule);
- return pMonitor;
-}
-
-#define GET_UNALIGNED2(x) \
- ((*(CARD16*)(x)) | (*(((CARD16*)(x) + 1))) << 16)
-
-VbeInfoBlock *
-VBEGetVBEInfo(vbeInfoPtr pVbe)
-{
- VbeInfoBlock *block = NULL;
- int i, pStr, pModes;
- char *str;
- CARD16 major, *modes;
-
- bzero(pVbe->memory, sizeof(VbeInfoBlock));
-
- /*
- Input:
- AH := 4Fh Super VGA support
- AL := 00h Return Super VGA information
- ES:DI := Pointer to buffer
-
- Output:
- AX := status
- (All other registers are preserved)
- */
-
- ((char*)pVbe->memory)[0] = 'V';
- ((char*)pVbe->memory)[1] = 'B';
- ((char*)pVbe->memory)[2] = 'E';
- ((char*)pVbe->memory)[3] = '2';
-
- pVbe->pInt10->num = 0x10;
- pVbe->pInt10->ax = 0x4f00;
- pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
- pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
- xf86ExecX86int10(pVbe->pInt10);
-
- if (R16(pVbe->pInt10->ax) != 0x4f)
- return (NULL);
-
- block = xcalloc(sizeof(VbeInfoBlock), 1);
- block->VESASignature[0] = ((char*)pVbe->memory)[0];
- block->VESASignature[1] = ((char*)pVbe->memory)[1];
- block->VESASignature[2] = ((char*)pVbe->memory)[2];
- block->VESASignature[3] = ((char*)pVbe->memory)[3];
-
- block->VESAVersion = *(CARD16*)(((char*)pVbe->memory) + 4);
- major = (unsigned)block->VESAVersion >> 8;
-
- pStr = GET_UNALIGNED2((((char*)pVbe->memory) + 6));
- str = xf86int10Addr(pVbe->pInt10, FARP(pStr));
- block->OEMStringPtr = strdup(str);
-
- block->Capabilities[0] = ((char*)pVbe->memory)[10];
- block->Capabilities[1] = ((char*)pVbe->memory)[11];
- block->Capabilities[2] = ((char*)pVbe->memory)[12];
- block->Capabilities[3] = ((char*)pVbe->memory)[13];
-
- pModes = GET_UNALIGNED2((((char*)pVbe->memory) + 14));
- modes = xf86int10Addr(pVbe->pInt10, FARP(pModes));
- i = 0;
- while (modes[i] != 0xffff)
- i++;
- block->VideoModePtr = xalloc(sizeof(CARD16) * i + 1);
- memcpy(block->VideoModePtr, modes, sizeof(CARD16) * i);
- block->VideoModePtr[i] = 0xffff;
-
- block->TotalMemory = *(CARD16*)(((char*)pVbe->memory) + 18);
-
- if (major < 2)
- memcpy(&block->OemSoftwareRev, ((char*)pVbe->memory) + 20, 236);
- else {
- block->OemSoftwareRev = *(CARD16*)(((char*)pVbe->memory) + 20);
- pStr = GET_UNALIGNED2((((char*)pVbe->memory) + 22));
- str = xf86int10Addr(pVbe->pInt10, FARP(pStr));
- block->OemVendorNamePtr = strdup(str);
- pStr = GET_UNALIGNED2((((char*)pVbe->memory) + 26));
- str = xf86int10Addr(pVbe->pInt10, FARP(pStr));
- block->OemProductNamePtr = strdup(str);
- pStr = GET_UNALIGNED2((((char*)pVbe->memory) + 30));
- str = xf86int10Addr(pVbe->pInt10, FARP(pStr));
- block->OemProductRevPtr = strdup(str);
- memcpy(&block->Reserved, ((char*)pVbe->memory) + 34, 222);
- memcpy(&block->OemData, ((char*)pVbe->memory) + 256, 256);
- }
-
- return (block);
-}
-
-void
-VBEFreeVBEInfo(VbeInfoBlock *block)
-{
- xfree(block->OEMStringPtr);
- xfree(block->VideoModePtr);
- if (((unsigned)block->VESAVersion >> 8) >= 2) {
- xfree(block->OemVendorNamePtr);
- xfree(block->OemProductNamePtr);
- xfree(block->OemProductRevPtr);
- }
- xfree(block);
-}
-
-Bool
-VBESetVBEMode(vbeInfoPtr pVbe, int mode, VbeCRTCInfoBlock *block)
-{
- /*
- Input:
- AH := 4Fh Super VGA support
- AL := 02h Set Super VGA video mode
- BX := Video mode
- D0-D8 := Mode number
- D9-D10 := Reserved (must be 0)
- D11 := 0 Use current default refresh rate
- := 1 Use user specified CRTC values for refresh rate
- D12-13 Reserved for VBE/AF (must be 0)
- D14 := 0 Use windowed frame buffer model
- := 1 Use linear/flat frame buffer model
- D15 := 0 Clear video memory
- := 1 Don't clear video memory
- ES:DI := Pointer to VbeCRTCInfoBlock structure
-
- Output: AX = Status
- (All other registers are preserved)
- */
- pVbe->pInt10->num = 0x10;
- pVbe->pInt10->ax = 0x4f02;
- pVbe->pInt10->bx = mode;
- if (block) {
- pVbe->pInt10->bx |= 1 << 11;
- memcpy(pVbe->memory, block, sizeof(VbeCRTCInfoBlock));
- pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
- pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
- } else
- pVbe->pInt10->bx &= ~(1 << 11);
-
- xf86ExecX86int10(pVbe->pInt10);
-
- return (R16(pVbe->pInt10->ax) == 0x4f);
-}
-
-Bool
-VBEGetVBEMode(vbeInfoPtr pVbe, int *mode)
-{
- /*
- Input:
- AH := 4Fh Super VGA support
- AL := 03h Return current video mode
-
- Output:
- AX := Status
- BX := Current video mode
- (All other registers are preserved)
- */
- pVbe->pInt10->num = 0x10;
- pVbe->pInt10->ax = 0x4f03;
-
- xf86ExecX86int10(pVbe->pInt10);
-
- if (R16(pVbe->pInt10->ax) == 0x4f) {
- *mode = R16(pVbe->pInt10->bx);
-
- return (TRUE);
- }
-
- return (FALSE);
-}
-
-VbeModeInfoBlock *
-VBEGetModeInfo(vbeInfoPtr pVbe, int mode)
-{
- VbeModeInfoBlock *block = NULL;
-
- bzero(pVbe->memory, sizeof(VbeModeInfoBlock));
-
- /*
- Input:
- AH := 4Fh Super VGA support
- AL := 01h Return Super VGA mode information
- CX := Super VGA video mode
- (mode number must be one of those returned by Function 0)
- ES:DI := Pointer to buffer
-
- Output:
- AX := status
- (All other registers are preserved)
- */
- pVbe->pInt10->num = 0x10;
- pVbe->pInt10->ax = 0x4f01;
- pVbe->pInt10->cx = mode;
- pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
- pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
- xf86ExecX86int10(pVbe->pInt10);
- if (R16(pVbe->pInt10->ax) != 0x4f)
- return (NULL);
-
- block = xcalloc(sizeof(VbeModeInfoBlock), 1);
-
- block->ModeAttributes = *(CARD16*)pVbe->memory;
- block->WinAAttributes = ((char*)pVbe->memory)[2];
- block->WinBAttributes = ((char*)pVbe->memory)[3];
- block->WinGranularity = *(CARD16*)(((char*)pVbe->memory) + 4);
- block->WinSize = *(CARD16*)(((char*)pVbe->memory) + 6);
- block->WinASegment = *(CARD16*)(((char*)pVbe->memory) + 8);
- block->WinBSegment = *(CARD16*)(((char*)pVbe->memory) + 10);
- block->WinFuncPtr = *(CARD32*)(((char*)pVbe->memory) + 12);
- block->BytesPerScanline = *(CARD16*)(((char*)pVbe->memory) + 16);
-
- /* mandatory information for VBE 1.2 and above */
- block->XResolution = *(CARD16*)(((char*)pVbe->memory) + 18);
- block->YResolution = *(CARD16*)(((char*)pVbe->memory) + 20);
- block->XCharSize = ((char*)pVbe->memory)[22];
- block->YCharSize = ((char*)pVbe->memory)[23];
- block->NumberOfPlanes = ((char*)pVbe->memory)[24];
- block->BitsPerPixel = ((char*)pVbe->memory)[25];
- block->NumberOfBanks = ((char*)pVbe->memory)[26];
- block->MemoryModel = ((char*)pVbe->memory)[27];
- block->BankSize = ((char*)pVbe->memory)[28];
- block->NumberOfImages = ((char*)pVbe->memory)[29];
- block->Reserved = ((char*)pVbe->memory)[30];
-
- /* Direct color fields (required for direct/6 and YUV/7 memory models) */
- block->RedMaskSize = ((char*)pVbe->memory)[31];
- block->RedFieldPosition = ((char*)pVbe->memory)[32];
- block->GreenMaskSize = ((char*)pVbe->memory)[33];
- block->GreenFieldPosition = ((char*)pVbe->memory)[34];
- block->BlueMaskSize = ((char*)pVbe->memory)[35];
- block->BlueFieldPosition = ((char*)pVbe->memory)[36];
- block->RsvdMaskSize = ((char*)pVbe->memory)[37];
- block->RsvdFieldPosition = ((char*)pVbe->memory)[38];
- block->DirectColorModeInfo = ((char*)pVbe->memory)[39];
-
- /* Mandatory information for VBE 2.0 and above */
- if (pVbe->version >= 0x200) {
- block->PhysBasePtr = *(CARD32*)(((char*)pVbe->memory) + 40);
- block->Reserved32 = *(CARD32*)(((char*)pVbe->memory) + 44);
- block->Reserved16 = *(CARD16*)(((char*)pVbe->memory) + 48);
-
- /* Mandatory information for VBE 3.0 and above */
- if (pVbe->version >= 0x300) {
- block->LinBytesPerScanLine = *(CARD16*)(((char*)pVbe->memory) + 50);
- block->BnkNumberOfImagePages = ((char*)pVbe->memory)[52];
- block->LinNumberOfImagePages = ((char*)pVbe->memory)[53];
- block->LinRedMaskSize = ((char*)pVbe->memory)[54];
- block->LinRedFieldPosition = ((char*)pVbe->memory)[55];
- block->LinGreenMaskSize = ((char*)pVbe->memory)[56];
- block->LinGreenFieldPosition = ((char*)pVbe->memory)[57];
- block->LinBlueMaskSize = ((char*)pVbe->memory)[58];
- block->LinBlueFieldPosition = ((char*)pVbe->memory)[59];
- block->LinRsvdMaskSize = ((char*)pVbe->memory)[60];
- block->LinRsvdFieldPosition = ((char*)pVbe->memory)[61];
- block->MaxPixelClock = *(CARD32*)(((char*)pVbe->memory) + 62);
- memcpy(&block->Reserved2, ((char*)pVbe->memory) + 66, 188);
- }
- else
- memcpy(&block->LinBytesPerScanLine, ((char*)pVbe->memory) + 50, 206);
- }
- else
- memcpy(&block->PhysBasePtr, ((char*)pVbe->memory) + 40, 216);
-
- return (block);
-}
-
-void
-VBEFreeModeInfo(VbeModeInfoBlock *block)
-{
- xfree(block);
-}
-
-Bool
-VBESaveRestore(vbeInfoPtr pVbe, vbeSaveRestoreFunction function,
- pointer *memory, int *size, int *real_mode_pages)
-{
- /*
- Input:
- AH := 4Fh Super VGA support
- AL := 04h Save/restore Super VGA video state
- DL := 00h Return save/restore state buffer size
- CX := Requested states
- D0 = Save/restore video hardware state
- D1 = Save/restore video BIOS data state
- D2 = Save/restore video DAC state
- D3 = Save/restore Super VGA state
-
- Output:
- AX = Status
- BX = Number of 64-byte blocks to hold the state buffer
- (All other registers are preserved)
-
-
- Input:
- AH := 4Fh Super VGA support
- AL := 04h Save/restore Super VGA video state
- DL := 01h Save Super VGA video state
- CX := Requested states (see above)
- ES:BX := Pointer to buffer
-
- Output:
- AX := Status
- (All other registers are preserved)
-
-
- Input:
- AH := 4Fh Super VGA support
- AL := 04h Save/restore Super VGA video state
- DL := 02h Restore Super VGA video state
- CX := Requested states (see above)
- ES:BX := Pointer to buffer
-
- Output:
- AX := Status
- (All other registers are preserved)
- */
-
- if ((pVbe->version & 0xff00) > 0x100) {
- int screen = pVbe->pInt10->scrnIndex;
- if (function == MODE_QUERY ||
- (function == MODE_SAVE && !*memory)) {
- /* Query amount of memory to save state */
-
- pVbe->pInt10->num = 0x10;
- pVbe->pInt10->ax = 0x4f04;
- pVbe->pInt10->dx = 0;
- pVbe->pInt10->cx = 0x000f;
- xf86ExecX86int10(pVbe->pInt10);
- if (R16(pVbe->pInt10->ax) != 0x4f)
- return (FALSE);
-
- if (function == MODE_SAVE) {
- int npages = (R16(pVbe->pInt10->bx) * 64) / 4096 + 1;
- if ((*memory = xf86Int10AllocPages(pVbe->pInt10, npages,
- real_mode_pages)) == NULL) {
- xf86DrvMsg(screen, X_ERROR,
- "Cannot allocate memory to save SVGA state.\n");
- return (FALSE);
- }
- }
- *size = pVbe->pInt10->bx * 64;
- }
-
- /* Save/Restore Super VGA state */
- if (function != MODE_QUERY) {
-
- if (!*memory) return FALSE;
- pVbe->pInt10->num = 0x10;
- pVbe->pInt10->ax = 0x4f04;
- switch (function) {
- case MODE_SAVE:
- pVbe->pInt10->dx = 1;
- break;
- case MODE_RESTORE:
- pVbe->pInt10->dx = 2;
- break;
- case MODE_QUERY:
- return FALSE;
- }
- pVbe->pInt10->cx = 0x000f;
-
- pVbe->pInt10->es = SEG_ADDR(*real_mode_pages);
- pVbe->pInt10->bx = SEG_OFF(*real_mode_pages);
- xf86ExecX86int10(pVbe->pInt10);
- return (R16(pVbe->pInt10->ax) == 0x4f);
-
- }
- }
- return TRUE;
-}
-
-Bool
-VBEBankSwitch(vbeInfoPtr pVbe, unsigned int iBank, int window)
-{
- /*
- Input:
- AH := 4Fh Super VGA support
- AL := 05h
-
- Output:
- */
- pVbe->pInt10->num = 0x10;
- pVbe->pInt10->ax = 0x4f05;
- pVbe->pInt10->bx = window;
- pVbe->pInt10->dx = iBank;
- xf86ExecX86int10(pVbe->pInt10);
-
- if (R16(pVbe->pInt10->ax) != 0x4f)
- return (FALSE);
-
- return (TRUE);
-}
-
-Bool
-VBESetGetLogicalScanlineLength(vbeInfoPtr pVbe, vbeScanwidthCommand command,
- int width, int *pixels, int *bytes, int *max)
-{
- if (command < SCANWID_SET || command > SCANWID_GET_MAX)
- return (FALSE);
-
- /*
- Input:
- AX := 4F06h VBE Set/Get Logical Scan Line Length
- BL := 00h Set Scan Line Length in Pixels
- := 01h Get Scan Line Length
- := 02h Set Scan Line Length in Bytes
- := 03h Get Maximum Scan Line Length
- CX := If BL=00h Desired Width in Pixels
- If BL=02h Desired Width in Bytes
- (Ignored for Get Functions)
-
- Output:
- AX := VBE Return Status
- BX := Bytes Per Scan Line
- CX := Actual Pixels Per Scan Line
- (truncated to nearest complete pixel)
- DX := Maximum Number of Scan Lines
- */
-
- pVbe->pInt10->num = 0x10;
- pVbe->pInt10->ax = 0x4f06;
- pVbe->pInt10->bx = command;
- if (command == SCANWID_SET || command == SCANWID_SET_BYTES)
- pVbe->pInt10->cx = width;
- xf86ExecX86int10(pVbe->pInt10);
-
- if (R16(pVbe->pInt10->ax) != 0x4f)
- return (FALSE);
-
- if (command == SCANWID_GET || command == SCANWID_GET_MAX) {
- if (pixels)
- *pixels = R16(pVbe->pInt10->cx);
- if (bytes)
- *bytes = R16(pVbe->pInt10->bx);
- if (max)
- *max = R16(pVbe->pInt10->dx);
- }
-
- return (TRUE);
-}
-
-Bool
-VBESetDisplayStart(vbeInfoPtr pVbe, int x, int y, Bool wait_retrace)
-{
- pVbe->pInt10->num = 0x10;
- pVbe->pInt10->ax = 0x4f07;
- pVbe->pInt10->bx = wait_retrace ? 0x80 : 0x00;
- pVbe->pInt10->cx = x;
- pVbe->pInt10->dx = y;
- xf86ExecX86int10(pVbe->pInt10);
-
- if (R16(pVbe->pInt10->ax) != 0x4f)
- return (FALSE);
-
- return (TRUE);
-}
-
-Bool
-VBEGetDisplayStart(vbeInfoPtr pVbe, int *x, int *y)
-{
- pVbe->pInt10->num = 0x10;
- pVbe->pInt10->ax = 0x4f07;
- pVbe->pInt10->bx = 0x01;
- xf86ExecX86int10(pVbe->pInt10);
-
- if (R16(pVbe->pInt10->ax) != 0x4f)
- return (FALSE);
-
- *x = pVbe->pInt10->cx;
- *y = pVbe->pInt10->dx;
-
- return (TRUE);
-}
-
-int
-VBESetGetDACPaletteFormat(vbeInfoPtr pVbe, int bits)
-{
- /*
- Input:
- AX := 4F08h VBE Set/Get Palette Format
- BL := 00h Set DAC Palette Format
- := 01h Get DAC Palette Format
- BH := Desired bits of color per primary
- (Set DAC Palette Format only)
-
- Output:
- AX := VBE Return Status
- BH := Current number of bits of color per primary
- */
-
- pVbe->pInt10->num = 0x10;
- pVbe->pInt10->ax = 0x4f08;
- if (!bits)
- pVbe->pInt10->bx = 0x01;
- else
- pVbe->pInt10->bx = (bits & 0x00ff) << 8;
- xf86ExecX86int10(pVbe->pInt10);
-
- if (R16(pVbe->pInt10->ax) != 0x4f)
- return (0);
-
- return (bits != 0 ? bits : (pVbe->pInt10->bx >> 8) & 0x00ff);
-}
-
-CARD32 *
-VBESetGetPaletteData(vbeInfoPtr pVbe, Bool set, int first, int num,
- CARD32 *data, Bool secondary, Bool wait_retrace)
-{
- /*
- Input:
- (16-bit)
- AX := 4F09h VBE Load/Unload Palette Data
- BL := 00h Set Palette Data
- := 01h Get Palette Data
- := 02h Set Secondary Palette Data
- := 03h Get Secondary Palette Data
- := 80h Set Palette Data during Vertical Retrace
- CX := Number of palette registers to update (to a maximum of 256)
- DX := First of the palette registers to update (start)
- ES:DI := Table of palette values (see below for format)
-
- Output:
- AX := VBE Return Status
-
-
- Input:
- (32-bit)
- BL := 00h Set Palette Data
- := 80h Set Palette Data during Vertical Retrace
- CX := Number of palette registers to update (to a maximum of 256)
- DX := First of the palette registers to update (start)
- ES:EDI := Table of palette values (see below for format)
- DS := Selector for memory mapped registers
- */
-
- pVbe->pInt10->num = 0x10;
- pVbe->pInt10->ax = 0x4f09;
- if (!secondary)
- pVbe->pInt10->bx = set && wait_retrace ? 0x80 : set ? 0 : 1;
- else
- pVbe->pInt10->bx = set ? 2 : 3;
- pVbe->pInt10->cx = num;
- pVbe->pInt10->dx = first;
- pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
- pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
- if (set)
- memcpy(pVbe->memory, data, num * sizeof(CARD32));
- xf86ExecX86int10(pVbe->pInt10);
-
- if (R16(pVbe->pInt10->ax) != 0x4f)
- return (NULL);
-
- if (set)
- return (data);
-
- data = xalloc(num * sizeof(CARD32));
- memcpy(data, pVbe->memory, num * sizeof(CARD32));
-
- return (data);
-}
-
-VBEpmi *
-VBEGetVBEpmi(vbeInfoPtr pVbe)
-{
- VBEpmi *pmi;
-
- /*
- Input:
- AH := 4Fh Super VGA support
- AL := 0Ah Protected Mode Interface
- BL := 00h Return Protected Mode Table
-
- Output:
- AX := Status
- ES := Real Mode Segment of Table
- DI := Offset of Table
- CX := Lenght of Table including protected mode code in bytes (for copying purposes)
- (All other registers are preserved)
- */
-
- pVbe->pInt10->num = 0x10;
- pVbe->pInt10->ax = 0x4f0a;
- pVbe->pInt10->bx = 0;
- pVbe->pInt10->di = 0;
- xf86ExecX86int10(pVbe->pInt10);
-
- if (R16(pVbe->pInt10->ax) != 0x4f)
- return (NULL);
-
- pmi = xalloc(sizeof(VBEpmi));
- pmi->seg_tbl = R16(pVbe->pInt10->es);
- pmi->tbl_off = R16(pVbe->pInt10->di);
- pmi->tbl_len = R16(pVbe->pInt10->cx);
-
- return (pmi);
-}
-
-#if 0
-vbeModeInfoPtr
-VBEBuildVbeModeList(vbeInfoPtr pVbe, VbeInfoBlock *vbe)
-{
- vbeModeInfoPtr ModeList = NULL;
-
- int i = 0;
- while (vbe->VideoModePtr[i] != 0xffff) {
- vbeModeInfoPtr m;
- VbeModeInfoBlock *mode;
- int id = vbe->VideoModePtr[i++];
- int bpp;
-
- if ((mode = VBEGetModeInfo(pVbe, id)) == NULL)
- continue;
-
- bpp = mode->BitsPerPixel;
-
- m = xnfcalloc(sizeof(vbeModeInfoRec),1);
- m->width = mode->XResolution;
- m->height = mode->YResolution;
- m->bpp = bpp;
- m->n = id;
- m->next = ModeList;
-
- xf86DrvMsgVerb(pVbe->pInt10->scrnIndex, X_PROBED, 3,
- "BIOS reported VESA mode 0x%x: x:%i y:%i bpp:%i\n",
- m->n, m->width, m->height, m->bpp);
-
- ModeList = m;
-
- VBEFreeModeInfo(mode);
- }
- return ModeList;
-}
-
-unsigned short
-VBECalcVbeModeIndex(vbeModeInfoPtr m, DisplayModePtr mode, int bpp)
-{
- while (m) {
- if (bpp == m->bpp
- && mode->HDisplay == m->width
- && mode->VDisplay == m->height)
- return m->n;
- m = m->next;
- }
- return 0;
-}
-#endif
-
-void
-VBEVesaSaveRestore(vbeInfoPtr pVbe, vbeSaveRestorePtr vbe_sr,
- vbeSaveRestoreFunction function)
-{
- Bool SaveSucc = FALSE;
-
- if (VBE_VERSION_MAJOR(pVbe->version) > 1
- && (function == MODE_SAVE || vbe_sr->pstate)) {
- if (function == MODE_RESTORE)
- memcpy(vbe_sr->state, vbe_sr->pstate, vbe_sr->stateSize);
- ErrorF("VBESaveRestore\n");
- if ((VBESaveRestore(pVbe,function,
- (pointer)&vbe_sr->state,
- &vbe_sr->stateSize,&vbe_sr->statePage))) {
- if (function == MODE_SAVE) {
- SaveSucc = TRUE;
- vbe_sr->stateMode = -1; /* invalidate */
- /* don't rely on the memory not being touched */
- if (vbe_sr->pstate == NULL)
- vbe_sr->pstate = xalloc(vbe_sr->stateSize);
- memcpy(vbe_sr->pstate, vbe_sr->state, vbe_sr->stateSize);
- }
- ErrorF("VBESaveRestore done with success\n");
- return;
- }
- ErrorF("VBESaveRestore done\n");
- }
-
- if (function == MODE_SAVE && !SaveSucc)
- (void)VBEGetVBEMode(pVbe, &vbe_sr->stateMode);
-
- if (function == MODE_RESTORE && vbe_sr->stateMode != -1)
- VBESetVBEMode(pVbe, vbe_sr->stateMode, NULL);
-
-}
-
-int
-VBEGetPixelClock(vbeInfoPtr pVbe, int mode, int clock)
-{
- /*
- Input:
- AX := 4F0Bh VBE Get Pixel Clock
- BL := 00h Get Pixel Clock
- ECX := pixel clock in units of Hz
- DX := mode number
-
- Output:
- AX := VBE Return Status
- ECX := Closest pixel clock
- */
-
- pVbe->pInt10->num = 0x10;
- pVbe->pInt10->ax = 0x4f0b;
- pVbe->pInt10->bx = 0x00;
- pVbe->pInt10->cx = clock;
- pVbe->pInt10->dx = mode;
- xf86ExecX86int10(pVbe->pInt10);
-
- if (R16(pVbe->pInt10->ax) != 0x4f)
- return (0);
-
- return (pVbe->pInt10->cx);
-}
-
-Bool
-VBEDPMSSet(vbeInfoPtr pVbe, int mode)
-{
- /*
- Input:
- AX := 4F10h DPMS
- BL := 01h Set Display Power State
- BH := requested power state
-
- Output:
- AX := VBE Return Status
- */
-
- pVbe->pInt10->num = 0x10;
- pVbe->pInt10->ax = 0x4f10;
- pVbe->pInt10->bx = 0x01;
- switch (mode) {
- case DPMSModeOn:
- break;
- case DPMSModeStandby:
- pVbe->pInt10->bx |= 0x100;
- break;
- case DPMSModeSuspend:
- pVbe->pInt10->bx |= 0x200;
- break;
- case DPMSModeOff:
- pVbe->pInt10->bx |= 0x400;
- break;
- }
- xf86ExecX86int10(pVbe->pInt10);
- return (R16(pVbe->pInt10->ax) == 0x4f);
-}
-
-void
-VBEInterpretPanelID(int scrnIndex, struct vbePanelID *data)
-{
- ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
- DisplayModePtr mode;
- const float PANEL_HZ = 60.0;
-
- if (!data)
- return;
-
- xf86DrvMsg(scrnIndex, X_INFO, "PanelID returned panel resolution %dx%d\n",
- data->hsize, data->vsize);
-
- if (pScrn->monitor->nHsync || pScrn->monitor->nVrefresh)
- return;
-
- mode = xf86CVTMode(data->hsize, data->vsize, PANEL_HZ, 1, 0);
-
- pScrn->monitor->nHsync = 1;
- pScrn->monitor->hsync[0].lo = 31.5;
- pScrn->monitor->hsync[0].hi = (float)mode->Clock / (float)mode->HTotal;
- pScrn->monitor->nVrefresh = 1;
- pScrn->monitor->vrefresh[0].lo = 56.0;
- pScrn->monitor->vrefresh[0].hi =
- (float)mode->Clock*1000.0 / (float)mode->HTotal / (float)mode->VTotal;
-
- xfree(mode);
-}
-
-struct vbePanelID *
-VBEReadPanelID(vbeInfoPtr pVbe)
-{
- int RealOff = pVbe->real_mode_base;
- pointer page = pVbe->memory;
- void *tmp = NULL;
- int screen = pVbe->pInt10->scrnIndex;
-
- pVbe->pInt10->ax = 0x4F11;
- pVbe->pInt10->bx = 0x01;
- pVbe->pInt10->cx = 0;
- pVbe->pInt10->dx = 0;
- pVbe->pInt10->es = SEG_ADDR(RealOff);
- pVbe->pInt10->di = SEG_OFF(RealOff);
- pVbe->pInt10->num = 0x10;
-
- xf86ExecX86int10(pVbe->pInt10);
-
- if ((pVbe->pInt10->ax & 0xff) != 0x4f) {
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID invalid\n");
- goto error;
- }
-
- switch (pVbe->pInt10->ax & 0xff00) {
- case 0x0:
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID read successfully\n");
- tmp = xnfalloc(32);
- memcpy(tmp, page, 32);
- break;
- case 0x100:
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID read failed\n");
- break;
- default:
- xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID unknown failure %i\n",
- pVbe->pInt10->ax & 0xff00);
- break;
- }
-
-error:
- return tmp;
-}
+
+/*
+ * XFree86 vbe module
+ * Copyright 2000 Egbert Eich
+ *
+ * The mode query/save/set/restore functions from the vesa driver
+ * have been moved here.
+ * Copyright (c) 2000 by Conectiva S.A. (http://www.conectiva.com)
+ * Authors: Paulo César Pereira de Andrade <pcpa@conectiva.com.br>
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <string.h>
+
+#include "xf86.h"
+#include "vbe.h"
+#include <X11/Xarch.h>
+#include <X11/extensions/dpmsconst.h>
+
+#define VERSION(x) VBE_VERSION_MAJOR(x),VBE_VERSION_MINOR(x)
+
+#if X_BYTE_ORDER == X_LITTLE_ENDIAN
+#define B_O16(x) (x)
+#define B_O32(x) (x)
+#else
+#define B_O16(x) ((((x) & 0xff) << 8) | (((x) & 0xff) >> 8))
+#define B_O32(x) ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) \
+ | (((x) & 0xff0000) >> 8) | (((x) & 0xff000000) >> 24))
+#endif
+#define L_ADD(x) (B_O32(x) & 0xffff) + ((B_O32(x) >> 12) & 0xffff00)
+
+#define FARP(p) (((unsigned)(p & 0xffff0000) >> 12) | (p & 0xffff))
+#define R16(v) ((v) & 0xffff)
+
+static unsigned char * vbeReadEDID(vbeInfoPtr pVbe);
+static Bool vbeProbeDDC(vbeInfoPtr pVbe);
+
+static const char vbeVersionString[] = "VBE2";
+
+vbeInfoPtr
+VBEInit(xf86Int10InfoPtr pInt, int entityIndex)
+{
+ return VBEExtendedInit(pInt, entityIndex, 0);
+}
+
+vbeInfoPtr
+VBEExtendedInit(xf86Int10InfoPtr pInt, int entityIndex, int Flags)
+{
+ int RealOff;
+ pointer page = NULL;
+ ScrnInfoPtr pScrn = xf86FindScreenForEntity(entityIndex);
+ vbeControllerInfoPtr vbe = NULL;
+ Bool init_int10 = FALSE;
+ vbeInfoPtr vip = NULL;
+ int screen;
+
+ if (!pScrn) return NULL;
+ screen = pScrn->scrnIndex;
+
+ if (!pInt) {
+ if (!xf86LoadSubModule(pScrn, "int10"))
+ goto error;
+
+ xf86DrvMsg(screen,X_INFO,"initializing int10\n");
+ pInt = xf86ExtendedInitInt10(entityIndex,Flags);
+ if (!pInt)
+ goto error;
+ init_int10 = TRUE;
+ }
+
+ page = xf86Int10AllocPages(pInt,1,&RealOff);
+ if (!page) goto error;
+ vbe = (vbeControllerInfoPtr) page;
+ memcpy(vbe->VbeSignature,vbeVersionString,4);
+
+ pInt->ax = 0x4F00;
+ pInt->es = SEG_ADDR(RealOff);
+ pInt->di = SEG_OFF(RealOff);
+ pInt->num = 0x10;
+
+ xf86ExecX86int10(pInt);
+
+ if ((pInt->ax & 0xff) != 0x4f) {
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA BIOS not detected\n");
+ goto error;
+ }
+
+ switch (pInt->ax & 0xff00) {
+ case 0:
+ xf86DrvMsg(screen,X_INFO,"VESA BIOS detected\n");
+ break;
+ case 0x100:
+ xf86DrvMsg(screen,X_INFO,"VESA BIOS function failed\n");
+ goto error;
+ case 0x200:
+ xf86DrvMsg(screen,X_INFO,"VESA BIOS not supported\n");
+ goto error;
+ case 0x300:
+ xf86DrvMsg(screen,X_INFO,"VESA BIOS not supported in current mode\n");
+ goto error;
+ default:
+ xf86DrvMsg(screen,X_INFO,"Invalid\n");
+ goto error;
+ }
+
+ xf86DrvMsgVerb(screen, X_INFO, 4,
+ "VbeVersion is %d, OemStringPtr is 0x%08lx,\n"
+ "\tOemVendorNamePtr is 0x%08lx, OemProductNamePtr is 0x%08lx,\n"
+ "\tOemProductRevPtr is 0x%08lx\n",
+ vbe->VbeVersion, (unsigned long)vbe->OemStringPtr,
+ (unsigned long)vbe->OemVendorNamePtr,
+ (unsigned long)vbe->OemProductNamePtr,
+ (unsigned long)vbe->OemProductRevPtr);
+
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE Version %i.%i\n",
+ VERSION(vbe->VbeVersion));
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE Total Mem: %i kB\n",
+ vbe->TotalMem * 64);
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM: %s\n",
+ (CARD8*)xf86int10Addr(pInt,L_ADD(vbe->OemStringPtr)));
+
+ if (B_O16(vbe->VbeVersion) >= 0x200) {
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM Software Rev: %i.%i\n",
+ VERSION(vbe->OemSoftwareRev));
+ if (vbe->OemVendorNamePtr)
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM Vendor: %s\n",
+ (CARD8*)xf86int10Addr(pInt,L_ADD(vbe->OemVendorNamePtr)));
+ if (vbe->OemProductNamePtr)
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM Product: %s\n",
+ (CARD8*)xf86int10Addr(pInt,L_ADD(vbe->OemProductNamePtr)));
+ if (vbe->OemProductRevPtr)
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM Product Rev: %s\n",
+ (CARD8*)xf86int10Addr(pInt,L_ADD(vbe->OemProductRevPtr)));
+ }
+ vip = (vbeInfoPtr)xnfalloc(sizeof(vbeInfoRec));
+ vip->version = B_O16(vbe->VbeVersion);
+ vip->pInt10 = pInt;
+ vip->ddc = DDC_UNCHECKED;
+ vip->memory = page;
+ vip->real_mode_base = RealOff;
+ vip->num_pages = 1;
+ vip->init_int10 = init_int10;
+
+ return vip;
+
+ error:
+ if (page)
+ xf86Int10FreePages(pInt, page, 1);
+ if (init_int10)
+ xf86FreeInt10(pInt);
+ return NULL;
+}
+
+void
+vbeFree(vbeInfoPtr pVbe)
+{
+ if (!pVbe)
+ return;
+
+ xf86Int10FreePages(pVbe->pInt10,pVbe->memory,pVbe->num_pages);
+ /* If we have initalized int10 we ought to free it, too */
+ if (pVbe->init_int10)
+ xf86FreeInt10(pVbe->pInt10);
+ free(pVbe);
+ return;
+}
+
+static Bool
+vbeProbeDDC(vbeInfoPtr pVbe)
+{
+ char *ddc_level;
+ int screen = pVbe->pInt10->scrnIndex;
+
+ if (pVbe->ddc == DDC_NONE)
+ return FALSE;
+ if (pVbe->ddc != DDC_UNCHECKED)
+ return TRUE;
+
+ pVbe->pInt10->ax = 0x4F15;
+ pVbe->pInt10->bx = 0;
+ pVbe->pInt10->cx = 0;
+ pVbe->pInt10->es = 0;
+ pVbe->pInt10->di = 0;
+ pVbe->pInt10->num = 0x10;
+
+ xf86ExecX86int10(pVbe->pInt10);
+
+ if ((pVbe->pInt10->ax & 0xff) != 0x4f) {
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC not supported\n");
+ pVbe->ddc = DDC_NONE;
+ return FALSE;
+ }
+
+ switch ((pVbe->pInt10->ax >> 8) & 0xff) {
+ case 0:
+ xf86DrvMsg(screen,X_INFO,"VESA VBE DDC supported\n");
+ switch (pVbe->pInt10->bx & 0x3) {
+ case 0:
+ ddc_level = " none";
+ pVbe->ddc = DDC_NONE;
+ break;
+ case 1:
+ ddc_level = " 1";
+ pVbe->ddc = DDC_1;
+ break;
+ case 2:
+ ddc_level = " 2";
+ pVbe->ddc = DDC_2;
+ break;
+ case 3:
+ ddc_level = " 1 + 2";
+ pVbe->ddc = DDC_1_2;
+ break;
+ default:
+ ddc_level = "";
+ pVbe->ddc = DDC_NONE;
+ break;
+ }
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC Level%s\n",ddc_level);
+ if (pVbe->pInt10->bx & 0x4) {
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC Screen blanked"
+ "for data transfer\n");
+ pVbe->ddc_blank = TRUE;
+ } else
+ pVbe->ddc_blank = FALSE;
+
+ xf86DrvMsgVerb(screen,X_INFO,3,
+ "VESA VBE DDC transfer in appr. %x sec.\n",
+ (pVbe->pInt10->bx >> 8) & 0xff);
+ }
+
+ return TRUE;
+}
+
+typedef enum {
+ VBEOPT_NOVBE,
+ VBEOPT_NODDC
+} VBEOpts;
+
+static const OptionInfoRec VBEOptions[] = {
+ { VBEOPT_NOVBE, "NoVBE", OPTV_BOOLEAN, {0}, FALSE },
+ { VBEOPT_NODDC, "NoDDC", OPTV_BOOLEAN, {0}, FALSE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE },
+};
+
+static unsigned char *
+vbeReadEDID(vbeInfoPtr pVbe)
+{
+ int RealOff = pVbe->real_mode_base;
+ pointer page = pVbe->memory;
+ unsigned char *tmp = NULL;
+ Bool novbe = FALSE;
+ Bool noddc = FALSE;
+ int screen = pVbe->pInt10->scrnIndex;
+ OptionInfoPtr options;
+
+ if (!page) return NULL;
+
+ options = xnfalloc(sizeof(VBEOptions));
+ (void)memcpy(options, VBEOptions, sizeof(VBEOptions));
+ xf86ProcessOptions(screen, xf86Screens[screen]->options, options);
+ xf86GetOptValBool(options, VBEOPT_NOVBE, &novbe);
+ xf86GetOptValBool(options, VBEOPT_NODDC, &noddc);
+ free(options);
+ if (novbe || noddc) return NULL;
+
+ if (!vbeProbeDDC(pVbe)) goto error;
+
+ memset(page,0,sizeof(vbeInfoPtr));
+ strcpy(page,vbeVersionString);
+
+ pVbe->pInt10->ax = 0x4F15;
+ pVbe->pInt10->bx = 0x01;
+ pVbe->pInt10->cx = 0;
+ pVbe->pInt10->dx = 0;
+ pVbe->pInt10->es = SEG_ADDR(RealOff);
+ pVbe->pInt10->di = SEG_OFF(RealOff);
+ pVbe->pInt10->num = 0x10;
+
+ xf86ExecX86int10(pVbe->pInt10);
+
+ if ((pVbe->pInt10->ax & 0xff) != 0x4f) {
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC invalid\n");
+ goto error;
+ }
+ switch (pVbe->pInt10->ax & 0xff00) {
+ case 0x0:
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC read successfully\n");
+ tmp = (unsigned char *)xnfalloc(128);
+ memcpy(tmp,page,128);
+ break;
+ case 0x100:
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC read failed\n");
+ break;
+ default:
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC unkown failure %i\n",
+ pVbe->pInt10->ax & 0xff00);
+ break;
+ }
+
+ error:
+ return tmp;
+}
+
+xf86MonPtr
+vbeDoEDID(vbeInfoPtr pVbe, pointer pDDCModule)
+{
+ xf86MonPtr pMonitor;
+ pointer pModule;
+ unsigned char *DDC_data = NULL;
+
+ if (!pVbe) return NULL;
+ if (pVbe->version < 0x200)
+ return NULL;
+
+ if (!(pModule = pDDCModule)) {
+ pModule =
+ xf86LoadSubModule(xf86Screens[pVbe->pInt10->scrnIndex], "ddc");
+ if (!pModule)
+ return NULL;
+ }
+
+ DDC_data = vbeReadEDID(pVbe);
+
+ if (!DDC_data)
+ return NULL;
+
+ pMonitor = xf86InterpretEDID(pVbe->pInt10->scrnIndex, DDC_data);
+
+ if (!pDDCModule)
+ xf86UnloadSubModule(pModule);
+ return pMonitor;
+}
+
+#define GET_UNALIGNED2(x) \
+ ((*(CARD16*)(x)) | (*(((CARD16*)(x) + 1))) << 16)
+
+VbeInfoBlock *
+VBEGetVBEInfo(vbeInfoPtr pVbe)
+{
+ VbeInfoBlock *block = NULL;
+ int i, pStr, pModes;
+ char *str;
+ CARD16 major, *modes;
+
+ bzero(pVbe->memory, sizeof(VbeInfoBlock));
+
+ /*
+ Input:
+ AH := 4Fh Super VGA support
+ AL := 00h Return Super VGA information
+ ES:DI := Pointer to buffer
+
+ Output:
+ AX := status
+ (All other registers are preserved)
+ */
+
+ ((char*)pVbe->memory)[0] = 'V';
+ ((char*)pVbe->memory)[1] = 'B';
+ ((char*)pVbe->memory)[2] = 'E';
+ ((char*)pVbe->memory)[3] = '2';
+
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x4f00;
+ pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
+ pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
+ xf86ExecX86int10(pVbe->pInt10);
+
+ if (R16(pVbe->pInt10->ax) != 0x4f)
+ return (NULL);
+
+ block = calloc(sizeof(VbeInfoBlock), 1);
+ block->VESASignature[0] = ((char*)pVbe->memory)[0];
+ block->VESASignature[1] = ((char*)pVbe->memory)[1];
+ block->VESASignature[2] = ((char*)pVbe->memory)[2];
+ block->VESASignature[3] = ((char*)pVbe->memory)[3];
+
+ block->VESAVersion = *(CARD16*)(((char*)pVbe->memory) + 4);
+ major = (unsigned)block->VESAVersion >> 8;
+
+ pStr = GET_UNALIGNED2((((char*)pVbe->memory) + 6));
+ str = xf86int10Addr(pVbe->pInt10, FARP(pStr));
+ block->OEMStringPtr = strdup(str);
+
+ block->Capabilities[0] = ((char*)pVbe->memory)[10];
+ block->Capabilities[1] = ((char*)pVbe->memory)[11];
+ block->Capabilities[2] = ((char*)pVbe->memory)[12];
+ block->Capabilities[3] = ((char*)pVbe->memory)[13];
+
+ pModes = GET_UNALIGNED2((((char*)pVbe->memory) + 14));
+ modes = xf86int10Addr(pVbe->pInt10, FARP(pModes));
+ i = 0;
+ while (modes[i] != 0xffff)
+ i++;
+ block->VideoModePtr = malloc(sizeof(CARD16) * i + 1);
+ memcpy(block->VideoModePtr, modes, sizeof(CARD16) * i);
+ block->VideoModePtr[i] = 0xffff;
+
+ block->TotalMemory = *(CARD16*)(((char*)pVbe->memory) + 18);
+
+ if (major < 2)
+ memcpy(&block->OemSoftwareRev, ((char*)pVbe->memory) + 20, 236);
+ else {
+ block->OemSoftwareRev = *(CARD16*)(((char*)pVbe->memory) + 20);
+ pStr = GET_UNALIGNED2((((char*)pVbe->memory) + 22));
+ str = xf86int10Addr(pVbe->pInt10, FARP(pStr));
+ block->OemVendorNamePtr = strdup(str);
+ pStr = GET_UNALIGNED2((((char*)pVbe->memory) + 26));
+ str = xf86int10Addr(pVbe->pInt10, FARP(pStr));
+ block->OemProductNamePtr = strdup(str);
+ pStr = GET_UNALIGNED2((((char*)pVbe->memory) + 30));
+ str = xf86int10Addr(pVbe->pInt10, FARP(pStr));
+ block->OemProductRevPtr = strdup(str);
+ memcpy(&block->Reserved, ((char*)pVbe->memory) + 34, 222);
+ memcpy(&block->OemData, ((char*)pVbe->memory) + 256, 256);
+ }
+
+ return (block);
+}
+
+void
+VBEFreeVBEInfo(VbeInfoBlock *block)
+{
+ free(block->OEMStringPtr);
+ free(block->VideoModePtr);
+ if (((unsigned)block->VESAVersion >> 8) >= 2) {
+ free(block->OemVendorNamePtr);
+ free(block->OemProductNamePtr);
+ free(block->OemProductRevPtr);
+ }
+ free(block);
+}
+
+Bool
+VBESetVBEMode(vbeInfoPtr pVbe, int mode, VbeCRTCInfoBlock *block)
+{
+ /*
+ Input:
+ AH := 4Fh Super VGA support
+ AL := 02h Set Super VGA video mode
+ BX := Video mode
+ D0-D8 := Mode number
+ D9-D10 := Reserved (must be 0)
+ D11 := 0 Use current default refresh rate
+ := 1 Use user specified CRTC values for refresh rate
+ D12-13 Reserved for VBE/AF (must be 0)
+ D14 := 0 Use windowed frame buffer model
+ := 1 Use linear/flat frame buffer model
+ D15 := 0 Clear video memory
+ := 1 Don't clear video memory
+ ES:DI := Pointer to VbeCRTCInfoBlock structure
+
+ Output: AX = Status
+ (All other registers are preserved)
+ */
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x4f02;
+ pVbe->pInt10->bx = mode;
+ if (block) {
+ pVbe->pInt10->bx |= 1 << 11;
+ memcpy(pVbe->memory, block, sizeof(VbeCRTCInfoBlock));
+ pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
+ pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
+ } else
+ pVbe->pInt10->bx &= ~(1 << 11);
+
+ xf86ExecX86int10(pVbe->pInt10);
+
+ return (R16(pVbe->pInt10->ax) == 0x4f);
+}
+
+Bool
+VBEGetVBEMode(vbeInfoPtr pVbe, int *mode)
+{
+ /*
+ Input:
+ AH := 4Fh Super VGA support
+ AL := 03h Return current video mode
+
+ Output:
+ AX := Status
+ BX := Current video mode
+ (All other registers are preserved)
+ */
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x4f03;
+
+ xf86ExecX86int10(pVbe->pInt10);
+
+ if (R16(pVbe->pInt10->ax) == 0x4f) {
+ *mode = R16(pVbe->pInt10->bx);
+
+ return (TRUE);
+ }
+
+ return (FALSE);
+}
+
+VbeModeInfoBlock *
+VBEGetModeInfo(vbeInfoPtr pVbe, int mode)
+{
+ VbeModeInfoBlock *block = NULL;
+
+ bzero(pVbe->memory, sizeof(VbeModeInfoBlock));
+
+ /*
+ Input:
+ AH := 4Fh Super VGA support
+ AL := 01h Return Super VGA mode information
+ CX := Super VGA video mode
+ (mode number must be one of those returned by Function 0)
+ ES:DI := Pointer to buffer
+
+ Output:
+ AX := status
+ (All other registers are preserved)
+ */
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x4f01;
+ pVbe->pInt10->cx = mode;
+ pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
+ pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
+ xf86ExecX86int10(pVbe->pInt10);
+ if (R16(pVbe->pInt10->ax) != 0x4f)
+ return (NULL);
+
+ block = calloc(sizeof(VbeModeInfoBlock), 1);
+
+ block->ModeAttributes = *(CARD16*)pVbe->memory;
+ block->WinAAttributes = ((char*)pVbe->memory)[2];
+ block->WinBAttributes = ((char*)pVbe->memory)[3];
+ block->WinGranularity = *(CARD16*)(((char*)pVbe->memory) + 4);
+ block->WinSize = *(CARD16*)(((char*)pVbe->memory) + 6);
+ block->WinASegment = *(CARD16*)(((char*)pVbe->memory) + 8);
+ block->WinBSegment = *(CARD16*)(((char*)pVbe->memory) + 10);
+ block->WinFuncPtr = *(CARD32*)(((char*)pVbe->memory) + 12);
+ block->BytesPerScanline = *(CARD16*)(((char*)pVbe->memory) + 16);
+
+ /* mandatory information for VBE 1.2 and above */
+ block->XResolution = *(CARD16*)(((char*)pVbe->memory) + 18);
+ block->YResolution = *(CARD16*)(((char*)pVbe->memory) + 20);
+ block->XCharSize = ((char*)pVbe->memory)[22];
+ block->YCharSize = ((char*)pVbe->memory)[23];
+ block->NumberOfPlanes = ((char*)pVbe->memory)[24];
+ block->BitsPerPixel = ((char*)pVbe->memory)[25];
+ block->NumberOfBanks = ((char*)pVbe->memory)[26];
+ block->MemoryModel = ((char*)pVbe->memory)[27];
+ block->BankSize = ((char*)pVbe->memory)[28];
+ block->NumberOfImages = ((char*)pVbe->memory)[29];
+ block->Reserved = ((char*)pVbe->memory)[30];
+
+ /* Direct color fields (required for direct/6 and YUV/7 memory models) */
+ block->RedMaskSize = ((char*)pVbe->memory)[31];
+ block->RedFieldPosition = ((char*)pVbe->memory)[32];
+ block->GreenMaskSize = ((char*)pVbe->memory)[33];
+ block->GreenFieldPosition = ((char*)pVbe->memory)[34];
+ block->BlueMaskSize = ((char*)pVbe->memory)[35];
+ block->BlueFieldPosition = ((char*)pVbe->memory)[36];
+ block->RsvdMaskSize = ((char*)pVbe->memory)[37];
+ block->RsvdFieldPosition = ((char*)pVbe->memory)[38];
+ block->DirectColorModeInfo = ((char*)pVbe->memory)[39];
+
+ /* Mandatory information for VBE 2.0 and above */
+ if (pVbe->version >= 0x200) {
+ block->PhysBasePtr = *(CARD32*)(((char*)pVbe->memory) + 40);
+ block->Reserved32 = *(CARD32*)(((char*)pVbe->memory) + 44);
+ block->Reserved16 = *(CARD16*)(((char*)pVbe->memory) + 48);
+
+ /* Mandatory information for VBE 3.0 and above */
+ if (pVbe->version >= 0x300) {
+ block->LinBytesPerScanLine = *(CARD16*)(((char*)pVbe->memory) + 50);
+ block->BnkNumberOfImagePages = ((char*)pVbe->memory)[52];
+ block->LinNumberOfImagePages = ((char*)pVbe->memory)[53];
+ block->LinRedMaskSize = ((char*)pVbe->memory)[54];
+ block->LinRedFieldPosition = ((char*)pVbe->memory)[55];
+ block->LinGreenMaskSize = ((char*)pVbe->memory)[56];
+ block->LinGreenFieldPosition = ((char*)pVbe->memory)[57];
+ block->LinBlueMaskSize = ((char*)pVbe->memory)[58];
+ block->LinBlueFieldPosition = ((char*)pVbe->memory)[59];
+ block->LinRsvdMaskSize = ((char*)pVbe->memory)[60];
+ block->LinRsvdFieldPosition = ((char*)pVbe->memory)[61];
+ block->MaxPixelClock = *(CARD32*)(((char*)pVbe->memory) + 62);
+ memcpy(&block->Reserved2, ((char*)pVbe->memory) + 66, 188);
+ }
+ else
+ memcpy(&block->LinBytesPerScanLine, ((char*)pVbe->memory) + 50, 206);
+ }
+ else
+ memcpy(&block->PhysBasePtr, ((char*)pVbe->memory) + 40, 216);
+
+ return (block);
+}
+
+void
+VBEFreeModeInfo(VbeModeInfoBlock *block)
+{
+ free(block);
+}
+
+Bool
+VBESaveRestore(vbeInfoPtr pVbe, vbeSaveRestoreFunction function,
+ pointer *memory, int *size, int *real_mode_pages)
+{
+ /*
+ Input:
+ AH := 4Fh Super VGA support
+ AL := 04h Save/restore Super VGA video state
+ DL := 00h Return save/restore state buffer size
+ CX := Requested states
+ D0 = Save/restore video hardware state
+ D1 = Save/restore video BIOS data state
+ D2 = Save/restore video DAC state
+ D3 = Save/restore Super VGA state
+
+ Output:
+ AX = Status
+ BX = Number of 64-byte blocks to hold the state buffer
+ (All other registers are preserved)
+
+
+ Input:
+ AH := 4Fh Super VGA support
+ AL := 04h Save/restore Super VGA video state
+ DL := 01h Save Super VGA video state
+ CX := Requested states (see above)
+ ES:BX := Pointer to buffer
+
+ Output:
+ AX := Status
+ (All other registers are preserved)
+
+
+ Input:
+ AH := 4Fh Super VGA support
+ AL := 04h Save/restore Super VGA video state
+ DL := 02h Restore Super VGA video state
+ CX := Requested states (see above)
+ ES:BX := Pointer to buffer
+
+ Output:
+ AX := Status
+ (All other registers are preserved)
+ */
+
+ if ((pVbe->version & 0xff00) > 0x100) {
+ int screen = pVbe->pInt10->scrnIndex;
+ if (function == MODE_QUERY ||
+ (function == MODE_SAVE && !*memory)) {
+ /* Query amount of memory to save state */
+
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x4f04;
+ pVbe->pInt10->dx = 0;
+ pVbe->pInt10->cx = 0x000f;
+ xf86ExecX86int10(pVbe->pInt10);
+ if (R16(pVbe->pInt10->ax) != 0x4f)
+ return (FALSE);
+
+ if (function == MODE_SAVE) {
+ int npages = (R16(pVbe->pInt10->bx) * 64) / 4096 + 1;
+ if ((*memory = xf86Int10AllocPages(pVbe->pInt10, npages,
+ real_mode_pages)) == NULL) {
+ xf86DrvMsg(screen, X_ERROR,
+ "Cannot allocate memory to save SVGA state.\n");
+ return (FALSE);
+ }
+ }
+ *size = pVbe->pInt10->bx * 64;
+ }
+
+ /* Save/Restore Super VGA state */
+ if (function != MODE_QUERY) {
+
+ if (!*memory) return FALSE;
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x4f04;
+ switch (function) {
+ case MODE_SAVE:
+ pVbe->pInt10->dx = 1;
+ break;
+ case MODE_RESTORE:
+ pVbe->pInt10->dx = 2;
+ break;
+ case MODE_QUERY:
+ return FALSE;
+ }
+ pVbe->pInt10->cx = 0x000f;
+
+ pVbe->pInt10->es = SEG_ADDR(*real_mode_pages);
+ pVbe->pInt10->bx = SEG_OFF(*real_mode_pages);
+ xf86ExecX86int10(pVbe->pInt10);
+ return (R16(pVbe->pInt10->ax) == 0x4f);
+
+ }
+ }
+ return TRUE;
+}
+
+Bool
+VBEBankSwitch(vbeInfoPtr pVbe, unsigned int iBank, int window)
+{
+ /*
+ Input:
+ AH := 4Fh Super VGA support
+ AL := 05h
+
+ Output:
+ */
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x4f05;
+ pVbe->pInt10->bx = window;
+ pVbe->pInt10->dx = iBank;
+ xf86ExecX86int10(pVbe->pInt10);
+
+ if (R16(pVbe->pInt10->ax) != 0x4f)
+ return (FALSE);
+
+ return (TRUE);
+}
+
+Bool
+VBESetGetLogicalScanlineLength(vbeInfoPtr pVbe, vbeScanwidthCommand command,
+ int width, int *pixels, int *bytes, int *max)
+{
+ if (command < SCANWID_SET || command > SCANWID_GET_MAX)
+ return (FALSE);
+
+ /*
+ Input:
+ AX := 4F06h VBE Set/Get Logical Scan Line Length
+ BL := 00h Set Scan Line Length in Pixels
+ := 01h Get Scan Line Length
+ := 02h Set Scan Line Length in Bytes
+ := 03h Get Maximum Scan Line Length
+ CX := If BL=00h Desired Width in Pixels
+ If BL=02h Desired Width in Bytes
+ (Ignored for Get Functions)
+
+ Output:
+ AX := VBE Return Status
+ BX := Bytes Per Scan Line
+ CX := Actual Pixels Per Scan Line
+ (truncated to nearest complete pixel)
+ DX := Maximum Number of Scan Lines
+ */
+
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x4f06;
+ pVbe->pInt10->bx = command;
+ if (command == SCANWID_SET || command == SCANWID_SET_BYTES)
+ pVbe->pInt10->cx = width;
+ xf86ExecX86int10(pVbe->pInt10);
+
+ if (R16(pVbe->pInt10->ax) != 0x4f)
+ return (FALSE);
+
+ if (command == SCANWID_GET || command == SCANWID_GET_MAX) {
+ if (pixels)
+ *pixels = R16(pVbe->pInt10->cx);
+ if (bytes)
+ *bytes = R16(pVbe->pInt10->bx);
+ if (max)
+ *max = R16(pVbe->pInt10->dx);
+ }
+
+ return (TRUE);
+}
+
+Bool
+VBESetDisplayStart(vbeInfoPtr pVbe, int x, int y, Bool wait_retrace)
+{
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x4f07;
+ pVbe->pInt10->bx = wait_retrace ? 0x80 : 0x00;
+ pVbe->pInt10->cx = x;
+ pVbe->pInt10->dx = y;
+ xf86ExecX86int10(pVbe->pInt10);
+
+ if (R16(pVbe->pInt10->ax) != 0x4f)
+ return (FALSE);
+
+ return (TRUE);
+}
+
+Bool
+VBEGetDisplayStart(vbeInfoPtr pVbe, int *x, int *y)
+{
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x4f07;
+ pVbe->pInt10->bx = 0x01;
+ xf86ExecX86int10(pVbe->pInt10);
+
+ if (R16(pVbe->pInt10->ax) != 0x4f)
+ return (FALSE);
+
+ *x = pVbe->pInt10->cx;
+ *y = pVbe->pInt10->dx;
+
+ return (TRUE);
+}
+
+int
+VBESetGetDACPaletteFormat(vbeInfoPtr pVbe, int bits)
+{
+ /*
+ Input:
+ AX := 4F08h VBE Set/Get Palette Format
+ BL := 00h Set DAC Palette Format
+ := 01h Get DAC Palette Format
+ BH := Desired bits of color per primary
+ (Set DAC Palette Format only)
+
+ Output:
+ AX := VBE Return Status
+ BH := Current number of bits of color per primary
+ */
+
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x4f08;
+ if (!bits)
+ pVbe->pInt10->bx = 0x01;
+ else
+ pVbe->pInt10->bx = (bits & 0x00ff) << 8;
+ xf86ExecX86int10(pVbe->pInt10);
+
+ if (R16(pVbe->pInt10->ax) != 0x4f)
+ return (0);
+
+ return (bits != 0 ? bits : (pVbe->pInt10->bx >> 8) & 0x00ff);
+}
+
+CARD32 *
+VBESetGetPaletteData(vbeInfoPtr pVbe, Bool set, int first, int num,
+ CARD32 *data, Bool secondary, Bool wait_retrace)
+{
+ /*
+ Input:
+ (16-bit)
+ AX := 4F09h VBE Load/Unload Palette Data
+ BL := 00h Set Palette Data
+ := 01h Get Palette Data
+ := 02h Set Secondary Palette Data
+ := 03h Get Secondary Palette Data
+ := 80h Set Palette Data during Vertical Retrace
+ CX := Number of palette registers to update (to a maximum of 256)
+ DX := First of the palette registers to update (start)
+ ES:DI := Table of palette values (see below for format)
+
+ Output:
+ AX := VBE Return Status
+
+
+ Input:
+ (32-bit)
+ BL := 00h Set Palette Data
+ := 80h Set Palette Data during Vertical Retrace
+ CX := Number of palette registers to update (to a maximum of 256)
+ DX := First of the palette registers to update (start)
+ ES:EDI := Table of palette values (see below for format)
+ DS := Selector for memory mapped registers
+ */
+
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x4f09;
+ if (!secondary)
+ pVbe->pInt10->bx = set && wait_retrace ? 0x80 : set ? 0 : 1;
+ else
+ pVbe->pInt10->bx = set ? 2 : 3;
+ pVbe->pInt10->cx = num;
+ pVbe->pInt10->dx = first;
+ pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base);
+ pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base);
+ if (set)
+ memcpy(pVbe->memory, data, num * sizeof(CARD32));
+ xf86ExecX86int10(pVbe->pInt10);
+
+ if (R16(pVbe->pInt10->ax) != 0x4f)
+ return (NULL);
+
+ if (set)
+ return (data);
+
+ data = malloc(num * sizeof(CARD32));
+ memcpy(data, pVbe->memory, num * sizeof(CARD32));
+
+ return (data);
+}
+
+VBEpmi *
+VBEGetVBEpmi(vbeInfoPtr pVbe)
+{
+ VBEpmi *pmi;
+
+ /*
+ Input:
+ AH := 4Fh Super VGA support
+ AL := 0Ah Protected Mode Interface
+ BL := 00h Return Protected Mode Table
+
+ Output:
+ AX := Status
+ ES := Real Mode Segment of Table
+ DI := Offset of Table
+ CX := Lenght of Table including protected mode code in bytes (for copying purposes)
+ (All other registers are preserved)
+ */
+
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x4f0a;
+ pVbe->pInt10->bx = 0;
+ pVbe->pInt10->di = 0;
+ xf86ExecX86int10(pVbe->pInt10);
+
+ if (R16(pVbe->pInt10->ax) != 0x4f)
+ return (NULL);
+
+ pmi = malloc(sizeof(VBEpmi));
+ pmi->seg_tbl = R16(pVbe->pInt10->es);
+ pmi->tbl_off = R16(pVbe->pInt10->di);
+ pmi->tbl_len = R16(pVbe->pInt10->cx);
+
+ return (pmi);
+}
+
+#if 0
+vbeModeInfoPtr
+VBEBuildVbeModeList(vbeInfoPtr pVbe, VbeInfoBlock *vbe)
+{
+ vbeModeInfoPtr ModeList = NULL;
+
+ int i = 0;
+ while (vbe->VideoModePtr[i] != 0xffff) {
+ vbeModeInfoPtr m;
+ VbeModeInfoBlock *mode;
+ int id = vbe->VideoModePtr[i++];
+ int bpp;
+
+ if ((mode = VBEGetModeInfo(pVbe, id)) == NULL)
+ continue;
+
+ bpp = mode->BitsPerPixel;
+
+ m = xnfcalloc(sizeof(vbeModeInfoRec),1);
+ m->width = mode->XResolution;
+ m->height = mode->YResolution;
+ m->bpp = bpp;
+ m->n = id;
+ m->next = ModeList;
+
+ xf86DrvMsgVerb(pVbe->pInt10->scrnIndex, X_PROBED, 3,
+ "BIOS reported VESA mode 0x%x: x:%i y:%i bpp:%i\n",
+ m->n, m->width, m->height, m->bpp);
+
+ ModeList = m;
+
+ VBEFreeModeInfo(mode);
+ }
+ return ModeList;
+}
+
+unsigned short
+VBECalcVbeModeIndex(vbeModeInfoPtr m, DisplayModePtr mode, int bpp)
+{
+ while (m) {
+ if (bpp == m->bpp
+ && mode->HDisplay == m->width
+ && mode->VDisplay == m->height)
+ return m->n;
+ m = m->next;
+ }
+ return 0;
+}
+#endif
+
+void
+VBEVesaSaveRestore(vbeInfoPtr pVbe, vbeSaveRestorePtr vbe_sr,
+ vbeSaveRestoreFunction function)
+{
+ Bool SaveSucc = FALSE;
+
+ if (VBE_VERSION_MAJOR(pVbe->version) > 1
+ && (function == MODE_SAVE || vbe_sr->pstate)) {
+ if (function == MODE_RESTORE)
+ memcpy(vbe_sr->state, vbe_sr->pstate, vbe_sr->stateSize);
+ ErrorF("VBESaveRestore\n");
+ if ((VBESaveRestore(pVbe,function,
+ (pointer)&vbe_sr->state,
+ &vbe_sr->stateSize,&vbe_sr->statePage))) {
+ if (function == MODE_SAVE) {
+ SaveSucc = TRUE;
+ vbe_sr->stateMode = -1; /* invalidate */
+ /* don't rely on the memory not being touched */
+ if (vbe_sr->pstate == NULL)
+ vbe_sr->pstate = malloc(vbe_sr->stateSize);
+ memcpy(vbe_sr->pstate, vbe_sr->state, vbe_sr->stateSize);
+ }
+ ErrorF("VBESaveRestore done with success\n");
+ return;
+ }
+ ErrorF("VBESaveRestore done\n");
+ }
+
+ if (function == MODE_SAVE && !SaveSucc)
+ (void)VBEGetVBEMode(pVbe, &vbe_sr->stateMode);
+
+ if (function == MODE_RESTORE && vbe_sr->stateMode != -1)
+ VBESetVBEMode(pVbe, vbe_sr->stateMode, NULL);
+
+}
+
+int
+VBEGetPixelClock(vbeInfoPtr pVbe, int mode, int clock)
+{
+ /*
+ Input:
+ AX := 4F0Bh VBE Get Pixel Clock
+ BL := 00h Get Pixel Clock
+ ECX := pixel clock in units of Hz
+ DX := mode number
+
+ Output:
+ AX := VBE Return Status
+ ECX := Closest pixel clock
+ */
+
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x4f0b;
+ pVbe->pInt10->bx = 0x00;
+ pVbe->pInt10->cx = clock;
+ pVbe->pInt10->dx = mode;
+ xf86ExecX86int10(pVbe->pInt10);
+
+ if (R16(pVbe->pInt10->ax) != 0x4f)
+ return (0);
+
+ return (pVbe->pInt10->cx);
+}
+
+Bool
+VBEDPMSSet(vbeInfoPtr pVbe, int mode)
+{
+ /*
+ Input:
+ AX := 4F10h DPMS
+ BL := 01h Set Display Power State
+ BH := requested power state
+
+ Output:
+ AX := VBE Return Status
+ */
+
+ pVbe->pInt10->num = 0x10;
+ pVbe->pInt10->ax = 0x4f10;
+ pVbe->pInt10->bx = 0x01;
+ switch (mode) {
+ case DPMSModeOn:
+ break;
+ case DPMSModeStandby:
+ pVbe->pInt10->bx |= 0x100;
+ break;
+ case DPMSModeSuspend:
+ pVbe->pInt10->bx |= 0x200;
+ break;
+ case DPMSModeOff:
+ pVbe->pInt10->bx |= 0x400;
+ break;
+ }
+ xf86ExecX86int10(pVbe->pInt10);
+ return (R16(pVbe->pInt10->ax) == 0x4f);
+}
+
+void
+VBEInterpretPanelID(int scrnIndex, struct vbePanelID *data)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ DisplayModePtr mode;
+ const float PANEL_HZ = 60.0;
+
+ if (!data)
+ return;
+
+ xf86DrvMsg(scrnIndex, X_INFO, "PanelID returned panel resolution %dx%d\n",
+ data->hsize, data->vsize);
+
+ if (pScrn->monitor->nHsync || pScrn->monitor->nVrefresh)
+ return;
+
+ mode = xf86CVTMode(data->hsize, data->vsize, PANEL_HZ, 1, 0);
+
+ pScrn->monitor->nHsync = 1;
+ pScrn->monitor->hsync[0].lo = 31.5;
+ pScrn->monitor->hsync[0].hi = (float)mode->Clock / (float)mode->HTotal;
+ pScrn->monitor->nVrefresh = 1;
+ pScrn->monitor->vrefresh[0].lo = 56.0;
+ pScrn->monitor->vrefresh[0].hi =
+ (float)mode->Clock*1000.0 / (float)mode->HTotal / (float)mode->VTotal;
+
+ free(mode);
+}
+
+struct vbePanelID *
+VBEReadPanelID(vbeInfoPtr pVbe)
+{
+ int RealOff = pVbe->real_mode_base;
+ pointer page = pVbe->memory;
+ void *tmp = NULL;
+ int screen = pVbe->pInt10->scrnIndex;
+
+ pVbe->pInt10->ax = 0x4F11;
+ pVbe->pInt10->bx = 0x01;
+ pVbe->pInt10->cx = 0;
+ pVbe->pInt10->dx = 0;
+ pVbe->pInt10->es = SEG_ADDR(RealOff);
+ pVbe->pInt10->di = SEG_OFF(RealOff);
+ pVbe->pInt10->num = 0x10;
+
+ xf86ExecX86int10(pVbe->pInt10);
+
+ if ((pVbe->pInt10->ax & 0xff) != 0x4f) {
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID invalid\n");
+ goto error;
+ }
+
+ switch (pVbe->pInt10->ax & 0xff00) {
+ case 0x0:
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID read successfully\n");
+ tmp = xnfalloc(32);
+ memcpy(tmp, page, 32);
+ break;
+ case 0x100:
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID read failed\n");
+ break;
+ default:
+ xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID unknown failure %i\n",
+ pVbe->pInt10->ax & 0xff00);
+ break;
+ }
+
+error:
+ return tmp;
+}
diff --git a/xorg-server/hw/xfree86/vbe/vbe.h b/xorg-server/hw/xfree86/vbe/vbe.h
index b1ec5a9fb..4786709ea 100644
--- a/xorg-server/hw/xfree86/vbe/vbe.h
+++ b/xorg-server/hw/xfree86/vbe/vbe.h
@@ -1,341 +1,341 @@
-
-/*
- * XFree86 vbe module
- * Copyright 2000 Egbert Eich
- *
- * The mode query/save/set/restore functions from the vesa driver
- * have been moved here.
- * Copyright (c) 2000 by Conectiva S.A. (http://www.conectiva.com)
- * Authors: Paulo César Pereira de Andrade <pcpa@conectiva.com.br>
- */
-
-#ifndef _VBE_H
-#define _VBE_H
-#include "xf86int10.h"
-#include "xf86DDC.h"
-
-typedef enum {
- DDC_UNCHECKED,
- DDC_NONE,
- DDC_1,
- DDC_2,
- DDC_1_2
-}
-ddc_lvl;
-
-typedef struct {
- xf86Int10InfoPtr pInt10;
- int version;
- pointer memory;
- int real_mode_base;
- int num_pages;
- Bool init_int10;
- ddc_lvl ddc;
- Bool ddc_blank;
-} vbeInfoRec, *vbeInfoPtr;
-
-#define VBE_VERSION_MAJOR(x) *((CARD8*)(&x) + 1)
-#define VBE_VERSION_MINOR(x) (CARD8)(x)
-
-extern _X_EXPORT vbeInfoPtr VBEInit(xf86Int10InfoPtr pInt, int entityIndex);
-extern _X_EXPORT vbeInfoPtr VBEExtendedInit(xf86Int10InfoPtr pInt, int entityIndex, int Flags);
-extern _X_EXPORT void vbeFree(vbeInfoPtr pVbe);
-extern _X_EXPORT xf86MonPtr vbeDoEDID(vbeInfoPtr pVbe, pointer pDDCModule);
-
-#pragma pack(1)
-
-typedef struct vbeControllerInfoBlock {
- CARD8 VbeSignature[4];
- CARD16 VbeVersion;
- CARD32 OemStringPtr;
- CARD8 Capabilities[4];
- CARD32 VideoModePtr;
- CARD16 TotalMem;
- CARD16 OemSoftwareRev;
- CARD32 OemVendorNamePtr;
- CARD32 OemProductNamePtr;
- CARD32 OemProductRevPtr;
- CARD8 Scratch[222];
- CARD8 OemData[256];
-} vbeControllerInfoRec, *vbeControllerInfoPtr;
-
-#if defined(__GNUC__) || defined(__USLC__) || defined(__SUNPRO_C)
-#pragma pack() /* All GCC versions recognise this syntax */
-#else
-#pragma pack(0)
-#endif
-
-#ifndef __GNUC__
-#define __attribute__(a)
-#endif
-
-typedef struct _VbeInfoBlock VbeInfoBlock;
-typedef struct _VbeModeInfoBlock VbeModeInfoBlock;
-typedef struct _VbeCRTCInfoBlock VbeCRTCInfoBlock;
-
-/*
- * INT 0
- */
-
-struct _VbeInfoBlock {
- /* VESA 1.2 fields */
- CARD8 VESASignature[4]; /* VESA */
- CARD16 VESAVersion; /* Higher byte major, lower byte minor */
- /*CARD32*/char *OEMStringPtr; /* Pointer to OEM string */
- CARD8 Capabilities[4]; /* Capabilities of the video environment */
-
- /*CARD32*/CARD16 *VideoModePtr; /* pointer to supported Super VGA modes */
-
- CARD16 TotalMemory; /* Number of 64kb memory blocks on board */
- /* if not VESA 2, 236 scratch bytes follow (256 bytes total size) */
-
- /* VESA 2 fields */
- CARD16 OemSoftwareRev; /* VBE implementation Software revision */
- /*CARD32*/char *OemVendorNamePtr; /* Pointer to Vendor Name String */
- /*CARD32*/char *OemProductNamePtr; /* Pointer to Product Name String */
- /*CARD32*/char *OemProductRevPtr; /* Pointer to Product Revision String */
- CARD8 Reserved[222]; /* Reserved for VBE implementation */
- CARD8 OemData[256]; /* Data Area for OEM Strings */
-} __attribute__((packed));
-
-/* Return Super VGA Information */
-extern _X_EXPORT VbeInfoBlock *VBEGetVBEInfo(vbeInfoPtr pVbe);
-extern _X_EXPORT void VBEFreeVBEInfo(VbeInfoBlock *block);
-
-/*
- * INT 1
- */
-
-struct _VbeModeInfoBlock {
- CARD16 ModeAttributes; /* mode attributes */
- CARD8 WinAAttributes; /* window A attributes */
- CARD8 WinBAttributes; /* window B attributes */
- CARD16 WinGranularity; /* window granularity */
- CARD16 WinSize; /* window size */
- CARD16 WinASegment; /* window A start segment */
- CARD16 WinBSegment; /* window B start segment */
- CARD32 WinFuncPtr; /* real mode pointer to window function */
- CARD16 BytesPerScanline; /* bytes per scanline */
-
- /* Mandatory information for VBE 1.2 and above */
- CARD16 XResolution; /* horizontal resolution in pixels or characters */
- CARD16 YResolution; /* vertical resolution in pixels or characters */
- CARD8 XCharSize; /* character cell width in pixels */
- CARD8 YCharSize; /* character cell height in pixels */
- CARD8 NumberOfPlanes; /* number of memory planes */
- CARD8 BitsPerPixel; /* bits per pixel */
- CARD8 NumberOfBanks; /* number of banks */
- CARD8 MemoryModel; /* memory model type */
- CARD8 BankSize; /* bank size in KB */
- CARD8 NumberOfImages; /* number of images */
- CARD8 Reserved; /* 1 */ /* reserved for page function */
-
- /* Direct color fields (required for direct/6 and YUV/7 memory models) */
- CARD8 RedMaskSize; /* size of direct color red mask in bits */
- CARD8 RedFieldPosition; /* bit position of lsb of red mask */
- CARD8 GreenMaskSize; /* size of direct color green mask in bits */
- CARD8 GreenFieldPosition; /* bit position of lsb of green mask */
- CARD8 BlueMaskSize; /* size of direct color blue mask in bits */
- CARD8 BlueFieldPosition; /* bit position of lsb of blue mask */
- CARD8 RsvdMaskSize; /* size of direct color reserved mask in bits */
- CARD8 RsvdFieldPosition; /* bit position of lsb of reserved mask */
- CARD8 DirectColorModeInfo; /* direct color mode attributes */
-
- /* Mandatory information for VBE 2.0 and above */
- CARD32 PhysBasePtr; /* physical address for flat memory frame buffer */
- CARD32 Reserved32; /* 0 */ /* Reserved - always set to 0 */
- CARD16 Reserved16; /* 0 */ /* Reserved - always set to 0 */
-
- /* Mandatory information for VBE 3.0 and above */
- CARD16 LinBytesPerScanLine; /* bytes per scan line for linear modes */
- CARD8 BnkNumberOfImagePages; /* number of images for banked modes */
- CARD8 LinNumberOfImagePages; /* number of images for linear modes */
- CARD8 LinRedMaskSize; /* size of direct color red mask (linear modes) */
- CARD8 LinRedFieldPosition; /* bit position of lsb of red mask (linear modes) */
- CARD8 LinGreenMaskSize; /* size of direct color green mask (linear modes) */
- CARD8 LinGreenFieldPosition; /* bit position of lsb of green mask (linear modes) */
- CARD8 LinBlueMaskSize; /* size of direct color blue mask (linear modes) */
- CARD8 LinBlueFieldPosition; /* bit position of lsb of blue mask (linear modes) */
- CARD8 LinRsvdMaskSize; /* size of direct color reserved mask (linear modes) */
- CARD8 LinRsvdFieldPosition; /* bit position of lsb of reserved mask (linear modes) */
- CARD32 MaxPixelClock; /* maximum pixel clock (in Hz) for graphics mode */
- CARD8 Reserved2[189]; /* remainder of VbeModeInfoBlock */
-} __attribute__((packed));
-
-/* Return VBE Mode Information */
-extern _X_EXPORT VbeModeInfoBlock *VBEGetModeInfo(vbeInfoPtr pVbe, int mode);
-extern _X_EXPORT void VBEFreeModeInfo(VbeModeInfoBlock *block);
-
-/*
- * INT2
- */
-
-#define CRTC_DBLSCAN (1<<0)
-#define CRTC_INTERLACE (1<<1)
-#define CRTC_NHSYNC (1<<2)
-#define CRTC_NVSYNC (1<<3)
-
-struct _VbeCRTCInfoBlock {
- CARD16 HorizontalTotal; /* Horizontal total in pixels */
- CARD16 HorizontalSyncStart; /* Horizontal sync start in pixels */
- CARD16 HorizontalSyncEnd; /* Horizontal sync end in pixels */
- CARD16 VerticalTotal; /* Vertical total in lines */
- CARD16 VerticalSyncStart; /* Vertical sync start in lines */
- CARD16 VerticalSyncEnd; /* Vertical sync end in lines */
- CARD8 Flags; /* Flags (Interlaced, Double Scan etc) */
- CARD32 PixelClock; /* Pixel clock in units of Hz */
- CARD16 RefreshRate; /* Refresh rate in units of 0.01 Hz */
- CARD8 Reserved[40]; /* remainder of ModeInfoBlock */
-} __attribute__((packed));
-/* VbeCRTCInfoBlock is in the VESA 3.0 specs */
-
-extern _X_EXPORT Bool VBESetVBEMode(vbeInfoPtr pVbe, int mode, VbeCRTCInfoBlock *crtc);
-
-/*
- * INT 3
- */
-
-extern _X_EXPORT Bool VBEGetVBEMode(vbeInfoPtr pVbe, int *mode);
-
-/*
- * INT 4
- */
-
-/* Save/Restore Super VGA video state */
-/* function values are (values stored in VESAPtr):
- * 0 := query & allocate amount of memory to save state
- * 1 := save state
- * 2 := restore state
- *
- * function 0 called automatically if function 1 called without
- * a previous call to function 0.
- */
-
-typedef enum {
- MODE_QUERY,
- MODE_SAVE,
- MODE_RESTORE
-} vbeSaveRestoreFunction;
-
-extern _X_EXPORT Bool
-VBESaveRestore(vbeInfoPtr pVbe, vbeSaveRestoreFunction fuction,
- pointer *memory, int *size, int *real_mode_pages);
-
-/*
- * INT 5
- */
-
-extern _X_EXPORT Bool
-VBEBankSwitch(vbeInfoPtr pVbe, unsigned int iBank, int window);
-
-/*
- * INT 6
- */
-
-typedef enum {
- SCANWID_SET,
- SCANWID_GET,
- SCANWID_SET_BYTES,
- SCANWID_GET_MAX
-} vbeScanwidthCommand;
-
-#define VBESetLogicalScanline(pVbe, width) \
- VBESetGetLogicalScanlineLength(pVbe, SCANWID_SET, width, \
- NULL, NULL, NULL)
-#define VBESetLogicalScanlineBytes(pVbe, width) \
- VBESetGetLogicalScanlineLength(pVbe, SCANWID_SET_BYTES, width, \
- NULL, NULL, NULL)
-#define VBEGetLogicalScanline(pVbe, pixels, bytes, max) \
- VBESetGetLogicalScanlineLength(pVbe, SCANWID_GET, 0, \
- pixels, bytes, max)
-#define VBEGetMaxLogicalScanline(pVbe, pixels, bytes, max) \
- VBESetGetLogicalScanlineLength(pVbe, SCANWID_GET_MAX, 0, \
- pixels, bytes, max)
-extern _X_EXPORT Bool VBESetGetLogicalScanlineLength(vbeInfoPtr pVbe,
- vbeScanwidthCommand command, int width,
- int *pixels, int *bytes, int *max);
-
-/*
- * INT 7
- */
-
-/* 16 bit code */
-extern _X_EXPORT Bool VBESetDisplayStart(vbeInfoPtr pVbe, int x, int y, Bool wait_retrace);
-extern _X_EXPORT Bool VBEGetDisplayStart(vbeInfoPtr pVbe, int *x, int *y);
-
-/*
- * INT 8
- */
-
-/* if bits is 0, then it is a GET */
-extern _X_EXPORT int VBESetGetDACPaletteFormat(vbeInfoPtr pVbe, int bits);
-
-/*
- * INT 9
- */
-
-/*
- * If getting a palette, the data argument is not used. It will return
- * the data.
- * If setting a palette, it will return the pointer received on success,
- * NULL on failure.
- */
-extern _X_EXPORT CARD32 *VBESetGetPaletteData(vbeInfoPtr pVbe, Bool set, int first, int num,
- CARD32 *data, Bool secondary, Bool wait_retrace);
-#define VBEFreePaletteData(data) xfree(data)
-
-/*
- * INT A
- */
-
-typedef struct _VBEpmi {
- int seg_tbl;
- int tbl_off;
- int tbl_len;
-} VBEpmi;
-
-extern _X_EXPORT VBEpmi *VBEGetVBEpmi(vbeInfoPtr pVbe);
-#define VESAFreeVBEpmi(pmi) xfree(pmi)
-
-/* high level helper functions */
-
-typedef struct _vbeModeInfoRec {
- int width;
- int height;
- int bpp;
- int n;
- struct _vbeModeInfoRec *next;
-} vbeModeInfoRec, *vbeModeInfoPtr;
-
-typedef struct {
- CARD8 *state;
- CARD8 *pstate;
- int statePage;
- int stateSize;
- int stateMode;
-} vbeSaveRestoreRec, *vbeSaveRestorePtr;
-
-extern _X_EXPORT void
-VBEVesaSaveRestore(vbeInfoPtr pVbe, vbeSaveRestorePtr vbe_sr,
- vbeSaveRestoreFunction function);
-
-extern _X_EXPORT int VBEGetPixelClock(vbeInfoPtr pVbe, int mode, int Clock);
-extern _X_EXPORT Bool VBEDPMSSet(vbeInfoPtr pVbe, int mode);
-
-struct vbePanelID {
- short hsize;
- short vsize;
- short fptype;
- char redbpp;
- char greenbpp;
- char bluebpp;
- char reservedbpp;
- int reserved_offscreen_mem_size;
- int reserved_offscreen_mem_pointer;
- char reserved[14];
-};
-
-extern _X_EXPORT void VBEInterpretPanelID(int scrnIndex, struct vbePanelID *data);
-extern _X_EXPORT struct vbePanelID *VBEReadPanelID(vbeInfoPtr pVbe);
-
-#endif
+
+/*
+ * XFree86 vbe module
+ * Copyright 2000 Egbert Eich
+ *
+ * The mode query/save/set/restore functions from the vesa driver
+ * have been moved here.
+ * Copyright (c) 2000 by Conectiva S.A. (http://www.conectiva.com)
+ * Authors: Paulo César Pereira de Andrade <pcpa@conectiva.com.br>
+ */
+
+#ifndef _VBE_H
+#define _VBE_H
+#include "xf86int10.h"
+#include "xf86DDC.h"
+
+typedef enum {
+ DDC_UNCHECKED,
+ DDC_NONE,
+ DDC_1,
+ DDC_2,
+ DDC_1_2
+}
+ddc_lvl;
+
+typedef struct {
+ xf86Int10InfoPtr pInt10;
+ int version;
+ pointer memory;
+ int real_mode_base;
+ int num_pages;
+ Bool init_int10;
+ ddc_lvl ddc;
+ Bool ddc_blank;
+} vbeInfoRec, *vbeInfoPtr;
+
+#define VBE_VERSION_MAJOR(x) *((CARD8*)(&x) + 1)
+#define VBE_VERSION_MINOR(x) (CARD8)(x)
+
+extern _X_EXPORT vbeInfoPtr VBEInit(xf86Int10InfoPtr pInt, int entityIndex);
+extern _X_EXPORT vbeInfoPtr VBEExtendedInit(xf86Int10InfoPtr pInt, int entityIndex, int Flags);
+extern _X_EXPORT void vbeFree(vbeInfoPtr pVbe);
+extern _X_EXPORT xf86MonPtr vbeDoEDID(vbeInfoPtr pVbe, pointer pDDCModule);
+
+#pragma pack(1)
+
+typedef struct vbeControllerInfoBlock {
+ CARD8 VbeSignature[4];
+ CARD16 VbeVersion;
+ CARD32 OemStringPtr;
+ CARD8 Capabilities[4];
+ CARD32 VideoModePtr;
+ CARD16 TotalMem;
+ CARD16 OemSoftwareRev;
+ CARD32 OemVendorNamePtr;
+ CARD32 OemProductNamePtr;
+ CARD32 OemProductRevPtr;
+ CARD8 Scratch[222];
+ CARD8 OemData[256];
+} vbeControllerInfoRec, *vbeControllerInfoPtr;
+
+#if defined(__GNUC__) || defined(__USLC__) || defined(__SUNPRO_C)
+#pragma pack() /* All GCC versions recognise this syntax */
+#else
+#pragma pack(0)
+#endif
+
+#ifndef __GNUC__
+#define __attribute__(a)
+#endif
+
+typedef struct _VbeInfoBlock VbeInfoBlock;
+typedef struct _VbeModeInfoBlock VbeModeInfoBlock;
+typedef struct _VbeCRTCInfoBlock VbeCRTCInfoBlock;
+
+/*
+ * INT 0
+ */
+
+struct _VbeInfoBlock {
+ /* VESA 1.2 fields */
+ CARD8 VESASignature[4]; /* VESA */
+ CARD16 VESAVersion; /* Higher byte major, lower byte minor */
+ /*CARD32*/char *OEMStringPtr; /* Pointer to OEM string */
+ CARD8 Capabilities[4]; /* Capabilities of the video environment */
+
+ /*CARD32*/CARD16 *VideoModePtr; /* pointer to supported Super VGA modes */
+
+ CARD16 TotalMemory; /* Number of 64kb memory blocks on board */
+ /* if not VESA 2, 236 scratch bytes follow (256 bytes total size) */
+
+ /* VESA 2 fields */
+ CARD16 OemSoftwareRev; /* VBE implementation Software revision */
+ /*CARD32*/char *OemVendorNamePtr; /* Pointer to Vendor Name String */
+ /*CARD32*/char *OemProductNamePtr; /* Pointer to Product Name String */
+ /*CARD32*/char *OemProductRevPtr; /* Pointer to Product Revision String */
+ CARD8 Reserved[222]; /* Reserved for VBE implementation */
+ CARD8 OemData[256]; /* Data Area for OEM Strings */
+} __attribute__((packed));
+
+/* Return Super VGA Information */
+extern _X_EXPORT VbeInfoBlock *VBEGetVBEInfo(vbeInfoPtr pVbe);
+extern _X_EXPORT void VBEFreeVBEInfo(VbeInfoBlock *block);
+
+/*
+ * INT 1
+ */
+
+struct _VbeModeInfoBlock {
+ CARD16 ModeAttributes; /* mode attributes */
+ CARD8 WinAAttributes; /* window A attributes */
+ CARD8 WinBAttributes; /* window B attributes */
+ CARD16 WinGranularity; /* window granularity */
+ CARD16 WinSize; /* window size */
+ CARD16 WinASegment; /* window A start segment */
+ CARD16 WinBSegment; /* window B start segment */
+ CARD32 WinFuncPtr; /* real mode pointer to window function */
+ CARD16 BytesPerScanline; /* bytes per scanline */
+
+ /* Mandatory information for VBE 1.2 and above */
+ CARD16 XResolution; /* horizontal resolution in pixels or characters */
+ CARD16 YResolution; /* vertical resolution in pixels or characters */
+ CARD8 XCharSize; /* character cell width in pixels */
+ CARD8 YCharSize; /* character cell height in pixels */
+ CARD8 NumberOfPlanes; /* number of memory planes */
+ CARD8 BitsPerPixel; /* bits per pixel */
+ CARD8 NumberOfBanks; /* number of banks */
+ CARD8 MemoryModel; /* memory model type */
+ CARD8 BankSize; /* bank size in KB */
+ CARD8 NumberOfImages; /* number of images */
+ CARD8 Reserved; /* 1 */ /* reserved for page function */
+
+ /* Direct color fields (required for direct/6 and YUV/7 memory models) */
+ CARD8 RedMaskSize; /* size of direct color red mask in bits */
+ CARD8 RedFieldPosition; /* bit position of lsb of red mask */
+ CARD8 GreenMaskSize; /* size of direct color green mask in bits */
+ CARD8 GreenFieldPosition; /* bit position of lsb of green mask */
+ CARD8 BlueMaskSize; /* size of direct color blue mask in bits */
+ CARD8 BlueFieldPosition; /* bit position of lsb of blue mask */
+ CARD8 RsvdMaskSize; /* size of direct color reserved mask in bits */
+ CARD8 RsvdFieldPosition; /* bit position of lsb of reserved mask */
+ CARD8 DirectColorModeInfo; /* direct color mode attributes */
+
+ /* Mandatory information for VBE 2.0 and above */
+ CARD32 PhysBasePtr; /* physical address for flat memory frame buffer */
+ CARD32 Reserved32; /* 0 */ /* Reserved - always set to 0 */
+ CARD16 Reserved16; /* 0 */ /* Reserved - always set to 0 */
+
+ /* Mandatory information for VBE 3.0 and above */
+ CARD16 LinBytesPerScanLine; /* bytes per scan line for linear modes */
+ CARD8 BnkNumberOfImagePages; /* number of images for banked modes */
+ CARD8 LinNumberOfImagePages; /* number of images for linear modes */
+ CARD8 LinRedMaskSize; /* size of direct color red mask (linear modes) */
+ CARD8 LinRedFieldPosition; /* bit position of lsb of red mask (linear modes) */
+ CARD8 LinGreenMaskSize; /* size of direct color green mask (linear modes) */
+ CARD8 LinGreenFieldPosition; /* bit position of lsb of green mask (linear modes) */
+ CARD8 LinBlueMaskSize; /* size of direct color blue mask (linear modes) */
+ CARD8 LinBlueFieldPosition; /* bit position of lsb of blue mask (linear modes) */
+ CARD8 LinRsvdMaskSize; /* size of direct color reserved mask (linear modes) */
+ CARD8 LinRsvdFieldPosition; /* bit position of lsb of reserved mask (linear modes) */
+ CARD32 MaxPixelClock; /* maximum pixel clock (in Hz) for graphics mode */
+ CARD8 Reserved2[189]; /* remainder of VbeModeInfoBlock */
+} __attribute__((packed));
+
+/* Return VBE Mode Information */
+extern _X_EXPORT VbeModeInfoBlock *VBEGetModeInfo(vbeInfoPtr pVbe, int mode);
+extern _X_EXPORT void VBEFreeModeInfo(VbeModeInfoBlock *block);
+
+/*
+ * INT2
+ */
+
+#define CRTC_DBLSCAN (1<<0)
+#define CRTC_INTERLACE (1<<1)
+#define CRTC_NHSYNC (1<<2)
+#define CRTC_NVSYNC (1<<3)
+
+struct _VbeCRTCInfoBlock {
+ CARD16 HorizontalTotal; /* Horizontal total in pixels */
+ CARD16 HorizontalSyncStart; /* Horizontal sync start in pixels */
+ CARD16 HorizontalSyncEnd; /* Horizontal sync end in pixels */
+ CARD16 VerticalTotal; /* Vertical total in lines */
+ CARD16 VerticalSyncStart; /* Vertical sync start in lines */
+ CARD16 VerticalSyncEnd; /* Vertical sync end in lines */
+ CARD8 Flags; /* Flags (Interlaced, Double Scan etc) */
+ CARD32 PixelClock; /* Pixel clock in units of Hz */
+ CARD16 RefreshRate; /* Refresh rate in units of 0.01 Hz */
+ CARD8 Reserved[40]; /* remainder of ModeInfoBlock */
+} __attribute__((packed));
+/* VbeCRTCInfoBlock is in the VESA 3.0 specs */
+
+extern _X_EXPORT Bool VBESetVBEMode(vbeInfoPtr pVbe, int mode, VbeCRTCInfoBlock *crtc);
+
+/*
+ * INT 3
+ */
+
+extern _X_EXPORT Bool VBEGetVBEMode(vbeInfoPtr pVbe, int *mode);
+
+/*
+ * INT 4
+ */
+
+/* Save/Restore Super VGA video state */
+/* function values are (values stored in VESAPtr):
+ * 0 := query & allocate amount of memory to save state
+ * 1 := save state
+ * 2 := restore state
+ *
+ * function 0 called automatically if function 1 called without
+ * a previous call to function 0.
+ */
+
+typedef enum {
+ MODE_QUERY,
+ MODE_SAVE,
+ MODE_RESTORE
+} vbeSaveRestoreFunction;
+
+extern _X_EXPORT Bool
+VBESaveRestore(vbeInfoPtr pVbe, vbeSaveRestoreFunction fuction,
+ pointer *memory, int *size, int *real_mode_pages);
+
+/*
+ * INT 5
+ */
+
+extern _X_EXPORT Bool
+VBEBankSwitch(vbeInfoPtr pVbe, unsigned int iBank, int window);
+
+/*
+ * INT 6
+ */
+
+typedef enum {
+ SCANWID_SET,
+ SCANWID_GET,
+ SCANWID_SET_BYTES,
+ SCANWID_GET_MAX
+} vbeScanwidthCommand;
+
+#define VBESetLogicalScanline(pVbe, width) \
+ VBESetGetLogicalScanlineLength(pVbe, SCANWID_SET, width, \
+ NULL, NULL, NULL)
+#define VBESetLogicalScanlineBytes(pVbe, width) \
+ VBESetGetLogicalScanlineLength(pVbe, SCANWID_SET_BYTES, width, \
+ NULL, NULL, NULL)
+#define VBEGetLogicalScanline(pVbe, pixels, bytes, max) \
+ VBESetGetLogicalScanlineLength(pVbe, SCANWID_GET, 0, \
+ pixels, bytes, max)
+#define VBEGetMaxLogicalScanline(pVbe, pixels, bytes, max) \
+ VBESetGetLogicalScanlineLength(pVbe, SCANWID_GET_MAX, 0, \
+ pixels, bytes, max)
+extern _X_EXPORT Bool VBESetGetLogicalScanlineLength(vbeInfoPtr pVbe,
+ vbeScanwidthCommand command, int width,
+ int *pixels, int *bytes, int *max);
+
+/*
+ * INT 7
+ */
+
+/* 16 bit code */
+extern _X_EXPORT Bool VBESetDisplayStart(vbeInfoPtr pVbe, int x, int y, Bool wait_retrace);
+extern _X_EXPORT Bool VBEGetDisplayStart(vbeInfoPtr pVbe, int *x, int *y);
+
+/*
+ * INT 8
+ */
+
+/* if bits is 0, then it is a GET */
+extern _X_EXPORT int VBESetGetDACPaletteFormat(vbeInfoPtr pVbe, int bits);
+
+/*
+ * INT 9
+ */
+
+/*
+ * If getting a palette, the data argument is not used. It will return
+ * the data.
+ * If setting a palette, it will return the pointer received on success,
+ * NULL on failure.
+ */
+extern _X_EXPORT CARD32 *VBESetGetPaletteData(vbeInfoPtr pVbe, Bool set, int first, int num,
+ CARD32 *data, Bool secondary, Bool wait_retrace);
+#define VBEFreePaletteData(data) free(data)
+
+/*
+ * INT A
+ */
+
+typedef struct _VBEpmi {
+ int seg_tbl;
+ int tbl_off;
+ int tbl_len;
+} VBEpmi;
+
+extern _X_EXPORT VBEpmi *VBEGetVBEpmi(vbeInfoPtr pVbe);
+#define VESAFreeVBEpmi(pmi) free(pmi)
+
+/* high level helper functions */
+
+typedef struct _vbeModeInfoRec {
+ int width;
+ int height;
+ int bpp;
+ int n;
+ struct _vbeModeInfoRec *next;
+} vbeModeInfoRec, *vbeModeInfoPtr;
+
+typedef struct {
+ CARD8 *state;
+ CARD8 *pstate;
+ int statePage;
+ int stateSize;
+ int stateMode;
+} vbeSaveRestoreRec, *vbeSaveRestorePtr;
+
+extern _X_EXPORT void
+VBEVesaSaveRestore(vbeInfoPtr pVbe, vbeSaveRestorePtr vbe_sr,
+ vbeSaveRestoreFunction function);
+
+extern _X_EXPORT int VBEGetPixelClock(vbeInfoPtr pVbe, int mode, int Clock);
+extern _X_EXPORT Bool VBEDPMSSet(vbeInfoPtr pVbe, int mode);
+
+struct vbePanelID {
+ short hsize;
+ short vsize;
+ short fptype;
+ char redbpp;
+ char greenbpp;
+ char bluebpp;
+ char reservedbpp;
+ int reserved_offscreen_mem_size;
+ int reserved_offscreen_mem_pointer;
+ char reserved[14];
+};
+
+extern _X_EXPORT void VBEInterpretPanelID(int scrnIndex, struct vbePanelID *data);
+extern _X_EXPORT struct vbePanelID *VBEReadPanelID(vbeInfoPtr pVbe);
+
+#endif
diff --git a/xorg-server/hw/xfree86/vbe/vbeModes.c b/xorg-server/hw/xfree86/vbe/vbeModes.c
index 1a4d2407c..5b69b0096 100644
--- a/xorg-server/hw/xfree86/vbe/vbeModes.c
+++ b/xorg-server/hw/xfree86/vbe/vbeModes.c
@@ -1,451 +1,451 @@
-#define DEBUG_VERB 2
-/*
- * Copyright © 2002 David Dawes
- *
- * 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 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 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 author(s).
- *
- * Authors: David Dawes <dawes@xfree86.org>
- *
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <stdio.h>
-#include <string.h>
-
-#include "xf86.h"
-#include "vbe.h"
-#include "vbeModes.h"
-
-static int
-GetDepthFlag(vbeInfoPtr pVbe, int id)
-{
- VbeModeInfoBlock *mode;
- int bpp;
-
- if ((mode = VBEGetModeInfo(pVbe, id)) == NULL)
- return 0;
-
- if (VBE_MODE_USABLE(mode, 0)) {
- int depth;
-
- if (VBE_MODE_COLOR(mode)) {
- depth = mode->RedMaskSize + mode->GreenMaskSize +
- mode->BlueMaskSize;
- } else {
- depth = 1;
- }
- bpp = mode->BitsPerPixel;
- VBEFreeModeInfo(mode);
- mode = NULL;
- switch (depth) {
- case 1:
- return V_DEPTH_1;
- case 4:
- return V_DEPTH_4;
- case 8:
- return V_DEPTH_8;
- case 15:
- return V_DEPTH_15;
- case 16:
- return V_DEPTH_16;
- case 24:
- switch (bpp) {
- case 24:
- return V_DEPTH_24_24;
- case 32:
- return V_DEPTH_24_32;
- }
- }
- }
- if (mode)
- VBEFreeModeInfo(mode);
- return 0;
-}
-
-/*
- * Find supported mode depths.
- */
-int
-VBEFindSupportedDepths(vbeInfoPtr pVbe, VbeInfoBlock *vbe, int *flags24,
- int modeTypes)
-{
- int i = 0;
- int depths = 0;
-
- if (modeTypes & V_MODETYPE_VBE) {
- while (vbe->VideoModePtr[i] != 0xffff) {
- depths |= GetDepthFlag(pVbe, vbe->VideoModePtr[i++]);
- }
- }
-
- /*
- * XXX This possibly only works with VBE 3.0 and later.
- */
- if (modeTypes & V_MODETYPE_VGA) {
- for (i = 0; i < 0x7F; i++) {
- depths |= GetDepthFlag(pVbe, i);
- }
- }
-
- if (flags24) {
- if (depths & V_DEPTH_24_24)
- *flags24 |= Support24bppFb;
- if (depths & V_DEPTH_24_32)
- *flags24 |= Support32bppFb;
- }
-
- return depths;
-}
-
-static DisplayModePtr
-CheckMode(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe, int id,
- int flags)
-{
- CARD16 major;
- VbeModeInfoBlock *mode;
- DisplayModePtr pMode;
- VbeModeInfoData *data;
- Bool modeOK = FALSE;
-
- major = (unsigned)(vbe->VESAVersion >> 8);
-
- if ((mode = VBEGetModeInfo(pVbe, id)) == NULL)
- return NULL;
-
- /* Does the mode match the depth/bpp? */
- /* Some BIOS's set BitsPerPixel to 15 instead of 16 for 15/16 */
- if (VBE_MODE_USABLE(mode, flags) &&
- ((pScrn->bitsPerPixel == 1 && !VBE_MODE_COLOR(mode)) ||
- (mode->BitsPerPixel > 8 &&
- (mode->RedMaskSize + mode->GreenMaskSize +
- mode->BlueMaskSize) == pScrn->depth &&
- mode->BitsPerPixel == pScrn->bitsPerPixel) ||
- (mode->BitsPerPixel == 15 && pScrn->depth == 15) ||
- (mode->BitsPerPixel <= 8 &&
- mode->BitsPerPixel == pScrn->bitsPerPixel))) {
- modeOK = TRUE;
- xf86ErrorFVerb(DEBUG_VERB, "*");
- }
-
- xf86ErrorFVerb(DEBUG_VERB,
- "Mode: %x (%dx%d)\n", id, mode->XResolution, mode->YResolution);
- xf86ErrorFVerb(DEBUG_VERB,
- " ModeAttributes: 0x%x\n", mode->ModeAttributes);
- xf86ErrorFVerb(DEBUG_VERB,
- " WinAAttributes: 0x%x\n", mode->WinAAttributes);
- xf86ErrorFVerb(DEBUG_VERB,
- " WinBAttributes: 0x%x\n", mode->WinBAttributes);
- xf86ErrorFVerb(DEBUG_VERB,
- " WinGranularity: %d\n", mode->WinGranularity);
- xf86ErrorFVerb(DEBUG_VERB,
- " WinSize: %d\n", mode->WinSize);
- xf86ErrorFVerb(DEBUG_VERB,
- " WinASegment: 0x%x\n", mode->WinASegment);
- xf86ErrorFVerb(DEBUG_VERB,
- " WinBSegment: 0x%x\n", mode->WinBSegment);
- xf86ErrorFVerb(DEBUG_VERB,
- " WinFuncPtr: 0x%lx\n", (unsigned long)mode->WinFuncPtr);
- xf86ErrorFVerb(DEBUG_VERB,
- " BytesPerScanline: %d\n", mode->BytesPerScanline);
- xf86ErrorFVerb(DEBUG_VERB,
- " XResolution: %d\n", mode->XResolution);
- xf86ErrorFVerb(DEBUG_VERB,
- " YResolution: %d\n", mode->YResolution);
- xf86ErrorFVerb(DEBUG_VERB,
- " XCharSize: %d\n", mode->XCharSize);
- xf86ErrorFVerb(DEBUG_VERB,
- " YCharSize: %d\n", mode->YCharSize);
- xf86ErrorFVerb(DEBUG_VERB,
- " NumberOfPlanes: %d\n", mode->NumberOfPlanes);
- xf86ErrorFVerb(DEBUG_VERB,
- " BitsPerPixel: %d\n", mode->BitsPerPixel);
- xf86ErrorFVerb(DEBUG_VERB,
- " NumberOfBanks: %d\n", mode->NumberOfBanks);
- xf86ErrorFVerb(DEBUG_VERB,
- " MemoryModel: %d\n", mode->MemoryModel);
- xf86ErrorFVerb(DEBUG_VERB,
- " BankSize: %d\n", mode->BankSize);
- xf86ErrorFVerb(DEBUG_VERB,
- " NumberOfImages: %d\n", mode->NumberOfImages);
- xf86ErrorFVerb(DEBUG_VERB,
- " RedMaskSize: %d\n", mode->RedMaskSize);
- xf86ErrorFVerb(DEBUG_VERB,
- " RedFieldPosition: %d\n", mode->RedFieldPosition);
- xf86ErrorFVerb(DEBUG_VERB,
- " GreenMaskSize: %d\n", mode->GreenMaskSize);
- xf86ErrorFVerb(DEBUG_VERB,
- " GreenFieldPosition: %d\n", mode->GreenFieldPosition);
- xf86ErrorFVerb(DEBUG_VERB,
- " BlueMaskSize: %d\n", mode->BlueMaskSize);
- xf86ErrorFVerb(DEBUG_VERB,
- " BlueFieldPosition: %d\n", mode->BlueFieldPosition);
- xf86ErrorFVerb(DEBUG_VERB,
- " RsvdMaskSize: %d\n", mode->RsvdMaskSize);
- xf86ErrorFVerb(DEBUG_VERB,
- " RsvdFieldPosition: %d\n", mode->RsvdFieldPosition);
- xf86ErrorFVerb(DEBUG_VERB,
- " DirectColorModeInfo: %d\n", mode->DirectColorModeInfo);
- if (major >= 2) {
- xf86ErrorFVerb(DEBUG_VERB,
- " PhysBasePtr: 0x%lx\n",
- (unsigned long)mode->PhysBasePtr);
- if (major >= 3) {
- xf86ErrorFVerb(DEBUG_VERB,
- " LinBytesPerScanLine: %d\n", mode->LinBytesPerScanLine);
- xf86ErrorFVerb(DEBUG_VERB,
- " BnkNumberOfImagePages: %d\n", mode->BnkNumberOfImagePages);
- xf86ErrorFVerb(DEBUG_VERB,
- " LinNumberOfImagePages: %d\n", mode->LinNumberOfImagePages);
- xf86ErrorFVerb(DEBUG_VERB,
- " LinRedMaskSize: %d\n", mode->LinRedMaskSize);
- xf86ErrorFVerb(DEBUG_VERB,
- " LinRedFieldPosition: %d\n", mode->LinRedFieldPosition);
- xf86ErrorFVerb(DEBUG_VERB,
- " LinGreenMaskSize: %d\n", mode->LinGreenMaskSize);
- xf86ErrorFVerb(DEBUG_VERB,
- " LinGreenFieldPosition: %d\n", mode->LinGreenFieldPosition);
- xf86ErrorFVerb(DEBUG_VERB,
- " LinBlueMaskSize: %d\n", mode->LinBlueMaskSize);
- xf86ErrorFVerb(DEBUG_VERB,
- " LinBlueFieldPosition: %d\n", mode->LinBlueFieldPosition);
- xf86ErrorFVerb(DEBUG_VERB,
- " LinRsvdMaskSize: %d\n", mode->LinRsvdMaskSize);
- xf86ErrorFVerb(DEBUG_VERB,
- " LinRsvdFieldPosition: %d\n", mode->LinRsvdFieldPosition);
- xf86ErrorFVerb(DEBUG_VERB,
- " MaxPixelClock: %ld\n", (unsigned long)mode->MaxPixelClock);
- }
- }
-
- if (!modeOK) {
- VBEFreeModeInfo(mode);
- return NULL;
- }
- pMode = xnfcalloc(sizeof(DisplayModeRec), 1);
-
- pMode->status = MODE_OK;
- pMode->type = M_T_BUILTIN;
-
- /* for adjust frame */
- pMode->HDisplay = mode->XResolution;
- pMode->VDisplay = mode->YResolution;
-
- data = xnfcalloc(sizeof(VbeModeInfoData), 1);
- data->mode = id;
- data->data = mode;
- pMode->PrivSize = sizeof(VbeModeInfoData);
- pMode->Private = (INT32*)data;
- pMode->next = NULL;
- return pMode;
-}
-
-/*
- * Check the available BIOS modes, and extract those that match the
- * requirements into the modePool. Note: modePool is a NULL-terminated
- * list.
- */
-
-DisplayModePtr
-VBEGetModePool(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe,
- int modeTypes)
-{
- DisplayModePtr pMode, p = NULL, modePool = NULL;
- int i = 0;
-
- if (modeTypes & V_MODETYPE_VBE) {
- while (vbe->VideoModePtr[i] != 0xffff) {
- int id = vbe->VideoModePtr[i++];
-
- if ((pMode = CheckMode(pScrn, pVbe, vbe, id, modeTypes)) != NULL) {
- ModeStatus status = MODE_OK;
-
- /* Check the mode against a specified virtual size (if any) */
- if (pScrn->display->virtualX > 0 &&
- pMode->HDisplay > pScrn->display->virtualX) {
- status = MODE_VIRTUAL_X;
- }
- if (pScrn->display->virtualY > 0 &&
- pMode->VDisplay > pScrn->display->virtualY) {
- status = MODE_VIRTUAL_Y;
- }
- if (status != MODE_OK) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Not using mode \"%dx%d\" (%s)\n",
- pMode->HDisplay, pMode->VDisplay,
- xf86ModeStatusToString(status));
- } else {
- if (p == NULL) {
- modePool = pMode;
- } else {
- p->next = pMode;
- }
- pMode->prev = NULL;
- p = pMode;
- }
- }
- }
- }
- if (modeTypes & V_MODETYPE_VGA) {
- for (i = 0; i < 0x7F; i++) {
- if ((pMode = CheckMode(pScrn, pVbe, vbe, i, modeTypes)) != NULL) {
- ModeStatus status = MODE_OK;
-
- /* Check the mode against a specified virtual size (if any) */
- if (pScrn->display->virtualX > 0 &&
- pMode->HDisplay > pScrn->display->virtualX) {
- status = MODE_VIRTUAL_X;
- }
- if (pScrn->display->virtualY > 0 &&
- pMode->VDisplay > pScrn->display->virtualY) {
- status = MODE_VIRTUAL_Y;
- }
- if (status != MODE_OK) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Not using mode \"%dx%d\" (%s)\n",
- pMode->HDisplay, pMode->VDisplay,
- xf86ModeStatusToString(status));
- } else {
- if (p == NULL) {
- modePool = pMode;
- } else {
- p->next = pMode;
- }
- pMode->prev = NULL;
- p = pMode;
- }
- }
- }
- }
- return modePool;
-}
-
-void
-VBESetModeNames(DisplayModePtr pMode)
-{
- if (!pMode)
- return;
-
- do {
- if (!pMode->name) {
- /* Catch "bad" modes. */
- if (pMode->HDisplay > 10000 || pMode->HDisplay < 0 ||
- pMode->VDisplay > 10000 || pMode->VDisplay < 0) {
- pMode->name = strdup("BADMODE");
- } else {
- pMode->name = xnfalloc(4 + 1 + 4 + 1);
- sprintf(pMode->name, "%dx%d", pMode->HDisplay, pMode->VDisplay);
- }
- }
- pMode = pMode->next;
- } while (pMode);
-}
-
-/*
- * Go through the monitor modes and selecting the best set of
- * parameters for each BIOS mode. Note: This is only supported in
- * VBE version 3.0 or later.
- */
-void
-VBESetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe)
-{
- DisplayModePtr pMode;
- VbeModeInfoData *data;
-
- pMode = pScrn->modes;
- do {
- DisplayModePtr p, best = NULL;
- ModeStatus status;
-
- for (p = pScrn->monitor->Modes; p != NULL; p = p->next) {
- if ((p->HDisplay != pMode->HDisplay) ||
- (p->VDisplay != pMode->VDisplay) ||
- (p->Flags & (V_INTERLACE | V_DBLSCAN | V_CLKDIV2)))
- continue;
- /* XXX could support the various V_ flags */
- status = xf86CheckModeForMonitor(p, pScrn->monitor);
- if (status != MODE_OK)
- continue;
- if (!best || (p->Clock > best->Clock))
- best = p;
- }
-
- if (best) {
- int clock;
-
- data = (VbeModeInfoData*)pMode->Private;
- pMode->HSync = (float)best->Clock * 1000.0 / best->HTotal + 0.5;
- pMode->VRefresh = pMode->HSync / best->VTotal + 0.5;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Attempting to use %dHz refresh for mode \"%s\" (%x)\n",
- (int)pMode->VRefresh, pMode->name, data->mode);
- data->block = xcalloc(sizeof(VbeCRTCInfoBlock), 1);
- data->block->HorizontalTotal = best->HTotal;
- data->block->HorizontalSyncStart = best->HSyncStart;
- data->block->HorizontalSyncEnd = best->HSyncEnd;
- data->block->VerticalTotal = best->VTotal;
- data->block->VerticalSyncStart = best->VSyncStart;
- data->block->VerticalSyncEnd = best->VSyncEnd;
- data->block->Flags = ((best->Flags & V_NHSYNC) ? CRTC_NHSYNC : 0) |
- ((best->Flags & V_NVSYNC) ? CRTC_NVSYNC : 0);
- data->block->PixelClock = best->Clock * 1000;
- /* XXX May not have this. */
- clock = VBEGetPixelClock(pVbe, data->mode, data->block->PixelClock);
- DebugF("Setting clock %.2fMHz, closest is %.2fMHz\n",
- (double)data->block->PixelClock / 1000000.0,
- (double)clock / 1000000.0);
- if (clock)
- data->block->PixelClock = clock;
- data->mode |= (1 << 11);
- data->block->RefreshRate = ((double)(data->block->PixelClock) /
- (double)(best->HTotal * best->VTotal)) * 100;
- }
- pMode = pMode->next;
- } while (pMode != pScrn->modes);
-}
-
-/*
- * These wrappers are to allow (temporary) funtionality divergences.
- */
-int
-VBEValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes,
- char **modeNames, ClockRangePtr clockRanges,
- int *linePitches, int minPitch, int maxPitch, int pitchInc,
- int minHeight, int maxHeight, int virtualX, int virtualY,
- int apertureSize, LookupModeFlags strategy)
-{
- return xf86ValidateModes(scrp, availModes, modeNames, clockRanges,
- linePitches, minPitch, maxPitch, pitchInc,
- minHeight, maxHeight, virtualX, virtualY,
- apertureSize, strategy);
-}
-
-void
-VBEPrintModes(ScrnInfoPtr scrp)
-{
- xf86PrintModes(scrp);
-}
-
+#define DEBUG_VERB 2
+/*
+ * Copyright © 2002 David Dawes
+ *
+ * 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 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 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 author(s).
+ *
+ * Authors: David Dawes <dawes@xfree86.org>
+ *
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include "xf86.h"
+#include "vbe.h"
+#include "vbeModes.h"
+
+static int
+GetDepthFlag(vbeInfoPtr pVbe, int id)
+{
+ VbeModeInfoBlock *mode;
+ int bpp;
+
+ if ((mode = VBEGetModeInfo(pVbe, id)) == NULL)
+ return 0;
+
+ if (VBE_MODE_USABLE(mode, 0)) {
+ int depth;
+
+ if (VBE_MODE_COLOR(mode)) {
+ depth = mode->RedMaskSize + mode->GreenMaskSize +
+ mode->BlueMaskSize;
+ } else {
+ depth = 1;
+ }
+ bpp = mode->BitsPerPixel;
+ VBEFreeModeInfo(mode);
+ mode = NULL;
+ switch (depth) {
+ case 1:
+ return V_DEPTH_1;
+ case 4:
+ return V_DEPTH_4;
+ case 8:
+ return V_DEPTH_8;
+ case 15:
+ return V_DEPTH_15;
+ case 16:
+ return V_DEPTH_16;
+ case 24:
+ switch (bpp) {
+ case 24:
+ return V_DEPTH_24_24;
+ case 32:
+ return V_DEPTH_24_32;
+ }
+ }
+ }
+ if (mode)
+ VBEFreeModeInfo(mode);
+ return 0;
+}
+
+/*
+ * Find supported mode depths.
+ */
+int
+VBEFindSupportedDepths(vbeInfoPtr pVbe, VbeInfoBlock *vbe, int *flags24,
+ int modeTypes)
+{
+ int i = 0;
+ int depths = 0;
+
+ if (modeTypes & V_MODETYPE_VBE) {
+ while (vbe->VideoModePtr[i] != 0xffff) {
+ depths |= GetDepthFlag(pVbe, vbe->VideoModePtr[i++]);
+ }
+ }
+
+ /*
+ * XXX This possibly only works with VBE 3.0 and later.
+ */
+ if (modeTypes & V_MODETYPE_VGA) {
+ for (i = 0; i < 0x7F; i++) {
+ depths |= GetDepthFlag(pVbe, i);
+ }
+ }
+
+ if (flags24) {
+ if (depths & V_DEPTH_24_24)
+ *flags24 |= Support24bppFb;
+ if (depths & V_DEPTH_24_32)
+ *flags24 |= Support32bppFb;
+ }
+
+ return depths;
+}
+
+static DisplayModePtr
+CheckMode(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe, int id,
+ int flags)
+{
+ CARD16 major;
+ VbeModeInfoBlock *mode;
+ DisplayModePtr pMode;
+ VbeModeInfoData *data;
+ Bool modeOK = FALSE;
+
+ major = (unsigned)(vbe->VESAVersion >> 8);
+
+ if ((mode = VBEGetModeInfo(pVbe, id)) == NULL)
+ return NULL;
+
+ /* Does the mode match the depth/bpp? */
+ /* Some BIOS's set BitsPerPixel to 15 instead of 16 for 15/16 */
+ if (VBE_MODE_USABLE(mode, flags) &&
+ ((pScrn->bitsPerPixel == 1 && !VBE_MODE_COLOR(mode)) ||
+ (mode->BitsPerPixel > 8 &&
+ (mode->RedMaskSize + mode->GreenMaskSize +
+ mode->BlueMaskSize) == pScrn->depth &&
+ mode->BitsPerPixel == pScrn->bitsPerPixel) ||
+ (mode->BitsPerPixel == 15 && pScrn->depth == 15) ||
+ (mode->BitsPerPixel <= 8 &&
+ mode->BitsPerPixel == pScrn->bitsPerPixel))) {
+ modeOK = TRUE;
+ xf86ErrorFVerb(DEBUG_VERB, "*");
+ }
+
+ xf86ErrorFVerb(DEBUG_VERB,
+ "Mode: %x (%dx%d)\n", id, mode->XResolution, mode->YResolution);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " ModeAttributes: 0x%x\n", mode->ModeAttributes);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " WinAAttributes: 0x%x\n", mode->WinAAttributes);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " WinBAttributes: 0x%x\n", mode->WinBAttributes);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " WinGranularity: %d\n", mode->WinGranularity);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " WinSize: %d\n", mode->WinSize);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " WinASegment: 0x%x\n", mode->WinASegment);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " WinBSegment: 0x%x\n", mode->WinBSegment);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " WinFuncPtr: 0x%lx\n", (unsigned long)mode->WinFuncPtr);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " BytesPerScanline: %d\n", mode->BytesPerScanline);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " XResolution: %d\n", mode->XResolution);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " YResolution: %d\n", mode->YResolution);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " XCharSize: %d\n", mode->XCharSize);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " YCharSize: %d\n", mode->YCharSize);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " NumberOfPlanes: %d\n", mode->NumberOfPlanes);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " BitsPerPixel: %d\n", mode->BitsPerPixel);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " NumberOfBanks: %d\n", mode->NumberOfBanks);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " MemoryModel: %d\n", mode->MemoryModel);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " BankSize: %d\n", mode->BankSize);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " NumberOfImages: %d\n", mode->NumberOfImages);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " RedMaskSize: %d\n", mode->RedMaskSize);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " RedFieldPosition: %d\n", mode->RedFieldPosition);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " GreenMaskSize: %d\n", mode->GreenMaskSize);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " GreenFieldPosition: %d\n", mode->GreenFieldPosition);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " BlueMaskSize: %d\n", mode->BlueMaskSize);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " BlueFieldPosition: %d\n", mode->BlueFieldPosition);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " RsvdMaskSize: %d\n", mode->RsvdMaskSize);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " RsvdFieldPosition: %d\n", mode->RsvdFieldPosition);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " DirectColorModeInfo: %d\n", mode->DirectColorModeInfo);
+ if (major >= 2) {
+ xf86ErrorFVerb(DEBUG_VERB,
+ " PhysBasePtr: 0x%lx\n",
+ (unsigned long)mode->PhysBasePtr);
+ if (major >= 3) {
+ xf86ErrorFVerb(DEBUG_VERB,
+ " LinBytesPerScanLine: %d\n", mode->LinBytesPerScanLine);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " BnkNumberOfImagePages: %d\n", mode->BnkNumberOfImagePages);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " LinNumberOfImagePages: %d\n", mode->LinNumberOfImagePages);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " LinRedMaskSize: %d\n", mode->LinRedMaskSize);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " LinRedFieldPosition: %d\n", mode->LinRedFieldPosition);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " LinGreenMaskSize: %d\n", mode->LinGreenMaskSize);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " LinGreenFieldPosition: %d\n", mode->LinGreenFieldPosition);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " LinBlueMaskSize: %d\n", mode->LinBlueMaskSize);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " LinBlueFieldPosition: %d\n", mode->LinBlueFieldPosition);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " LinRsvdMaskSize: %d\n", mode->LinRsvdMaskSize);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " LinRsvdFieldPosition: %d\n", mode->LinRsvdFieldPosition);
+ xf86ErrorFVerb(DEBUG_VERB,
+ " MaxPixelClock: %ld\n", (unsigned long)mode->MaxPixelClock);
+ }
+ }
+
+ if (!modeOK) {
+ VBEFreeModeInfo(mode);
+ return NULL;
+ }
+ pMode = xnfcalloc(sizeof(DisplayModeRec), 1);
+
+ pMode->status = MODE_OK;
+ pMode->type = M_T_BUILTIN;
+
+ /* for adjust frame */
+ pMode->HDisplay = mode->XResolution;
+ pMode->VDisplay = mode->YResolution;
+
+ data = xnfcalloc(sizeof(VbeModeInfoData), 1);
+ data->mode = id;
+ data->data = mode;
+ pMode->PrivSize = sizeof(VbeModeInfoData);
+ pMode->Private = (INT32*)data;
+ pMode->next = NULL;
+ return pMode;
+}
+
+/*
+ * Check the available BIOS modes, and extract those that match the
+ * requirements into the modePool. Note: modePool is a NULL-terminated
+ * list.
+ */
+
+DisplayModePtr
+VBEGetModePool(ScrnInfoPtr pScrn, vbeInfoPtr pVbe, VbeInfoBlock *vbe,
+ int modeTypes)
+{
+ DisplayModePtr pMode, p = NULL, modePool = NULL;
+ int i = 0;
+
+ if (modeTypes & V_MODETYPE_VBE) {
+ while (vbe->VideoModePtr[i] != 0xffff) {
+ int id = vbe->VideoModePtr[i++];
+
+ if ((pMode = CheckMode(pScrn, pVbe, vbe, id, modeTypes)) != NULL) {
+ ModeStatus status = MODE_OK;
+
+ /* Check the mode against a specified virtual size (if any) */
+ if (pScrn->display->virtualX > 0 &&
+ pMode->HDisplay > pScrn->display->virtualX) {
+ status = MODE_VIRTUAL_X;
+ }
+ if (pScrn->display->virtualY > 0 &&
+ pMode->VDisplay > pScrn->display->virtualY) {
+ status = MODE_VIRTUAL_Y;
+ }
+ if (status != MODE_OK) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Not using mode \"%dx%d\" (%s)\n",
+ pMode->HDisplay, pMode->VDisplay,
+ xf86ModeStatusToString(status));
+ } else {
+ if (p == NULL) {
+ modePool = pMode;
+ } else {
+ p->next = pMode;
+ }
+ pMode->prev = NULL;
+ p = pMode;
+ }
+ }
+ }
+ }
+ if (modeTypes & V_MODETYPE_VGA) {
+ for (i = 0; i < 0x7F; i++) {
+ if ((pMode = CheckMode(pScrn, pVbe, vbe, i, modeTypes)) != NULL) {
+ ModeStatus status = MODE_OK;
+
+ /* Check the mode against a specified virtual size (if any) */
+ if (pScrn->display->virtualX > 0 &&
+ pMode->HDisplay > pScrn->display->virtualX) {
+ status = MODE_VIRTUAL_X;
+ }
+ if (pScrn->display->virtualY > 0 &&
+ pMode->VDisplay > pScrn->display->virtualY) {
+ status = MODE_VIRTUAL_Y;
+ }
+ if (status != MODE_OK) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Not using mode \"%dx%d\" (%s)\n",
+ pMode->HDisplay, pMode->VDisplay,
+ xf86ModeStatusToString(status));
+ } else {
+ if (p == NULL) {
+ modePool = pMode;
+ } else {
+ p->next = pMode;
+ }
+ pMode->prev = NULL;
+ p = pMode;
+ }
+ }
+ }
+ }
+ return modePool;
+}
+
+void
+VBESetModeNames(DisplayModePtr pMode)
+{
+ if (!pMode)
+ return;
+
+ do {
+ if (!pMode->name) {
+ /* Catch "bad" modes. */
+ if (pMode->HDisplay > 10000 || pMode->HDisplay < 0 ||
+ pMode->VDisplay > 10000 || pMode->VDisplay < 0) {
+ pMode->name = strdup("BADMODE");
+ } else {
+ pMode->name = xnfalloc(4 + 1 + 4 + 1);
+ sprintf(pMode->name, "%dx%d", pMode->HDisplay, pMode->VDisplay);
+ }
+ }
+ pMode = pMode->next;
+ } while (pMode);
+}
+
+/*
+ * Go through the monitor modes and selecting the best set of
+ * parameters for each BIOS mode. Note: This is only supported in
+ * VBE version 3.0 or later.
+ */
+void
+VBESetModeParameters(ScrnInfoPtr pScrn, vbeInfoPtr pVbe)
+{
+ DisplayModePtr pMode;
+ VbeModeInfoData *data;
+
+ pMode = pScrn->modes;
+ do {
+ DisplayModePtr p, best = NULL;
+ ModeStatus status;
+
+ for (p = pScrn->monitor->Modes; p != NULL; p = p->next) {
+ if ((p->HDisplay != pMode->HDisplay) ||
+ (p->VDisplay != pMode->VDisplay) ||
+ (p->Flags & (V_INTERLACE | V_DBLSCAN | V_CLKDIV2)))
+ continue;
+ /* XXX could support the various V_ flags */
+ status = xf86CheckModeForMonitor(p, pScrn->monitor);
+ if (status != MODE_OK)
+ continue;
+ if (!best || (p->Clock > best->Clock))
+ best = p;
+ }
+
+ if (best) {
+ int clock;
+
+ data = (VbeModeInfoData*)pMode->Private;
+ pMode->HSync = (float)best->Clock * 1000.0 / best->HTotal + 0.5;
+ pMode->VRefresh = pMode->HSync / best->VTotal + 0.5;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Attempting to use %dHz refresh for mode \"%s\" (%x)\n",
+ (int)pMode->VRefresh, pMode->name, data->mode);
+ data->block = calloc(sizeof(VbeCRTCInfoBlock), 1);
+ data->block->HorizontalTotal = best->HTotal;
+ data->block->HorizontalSyncStart = best->HSyncStart;
+ data->block->HorizontalSyncEnd = best->HSyncEnd;
+ data->block->VerticalTotal = best->VTotal;
+ data->block->VerticalSyncStart = best->VSyncStart;
+ data->block->VerticalSyncEnd = best->VSyncEnd;
+ data->block->Flags = ((best->Flags & V_NHSYNC) ? CRTC_NHSYNC : 0) |
+ ((best->Flags & V_NVSYNC) ? CRTC_NVSYNC : 0);
+ data->block->PixelClock = best->Clock * 1000;
+ /* XXX May not have this. */
+ clock = VBEGetPixelClock(pVbe, data->mode, data->block->PixelClock);
+ DebugF("Setting clock %.2fMHz, closest is %.2fMHz\n",
+ (double)data->block->PixelClock / 1000000.0,
+ (double)clock / 1000000.0);
+ if (clock)
+ data->block->PixelClock = clock;
+ data->mode |= (1 << 11);
+ data->block->RefreshRate = ((double)(data->block->PixelClock) /
+ (double)(best->HTotal * best->VTotal)) * 100;
+ }
+ pMode = pMode->next;
+ } while (pMode != pScrn->modes);
+}
+
+/*
+ * These wrappers are to allow (temporary) funtionality divergences.
+ */
+int
+VBEValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes,
+ char **modeNames, ClockRangePtr clockRanges,
+ int *linePitches, int minPitch, int maxPitch, int pitchInc,
+ int minHeight, int maxHeight, int virtualX, int virtualY,
+ int apertureSize, LookupModeFlags strategy)
+{
+ return xf86ValidateModes(scrp, availModes, modeNames, clockRanges,
+ linePitches, minPitch, maxPitch, pitchInc,
+ minHeight, maxHeight, virtualX, virtualY,
+ apertureSize, strategy);
+}
+
+void
+VBEPrintModes(ScrnInfoPtr scrp)
+{
+ xf86PrintModes(scrp);
+}
+
diff --git a/xorg-server/hw/xfree86/vgahw/vgaCmap.c b/xorg-server/hw/xfree86/vgahw/vgaCmap.c
index 06eeb4ce1..e337b42c0 100644
--- a/xorg-server/hw/xfree86/vgahw/vgaCmap.c
+++ b/xorg-server/hw/xfree86/vgahw/vgaCmap.c
@@ -1,301 +1,301 @@
-/*
- * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Thomas Roell not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Thomas Roell makes no representations
- * about the suitability of this software for any purpose. It is provided
- * "as is" without express or implied warranty.
- *
- * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- *
- */
-
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "windowstr.h"
-#include "compiler.h"
-#include "mipointer.h"
-#include "micmap.h"
-
-#include "xf86.h"
-#include "vgaHW.h"
-
-#include <X11/extensions/xf86dgaproto.h>
-#include "dgaproc.h"
-
-
-#define NOMAPYET (ColormapPtr) 0
-
-int
-vgaListInstalledColormaps(pScreen, pmaps)
- ScreenPtr pScreen;
- Colormap *pmaps;
-{
- /* By the time we are processing requests, we can guarantee that there
- * is always a colormap installed */
-
- *pmaps = GetInstalledmiColormap(pScreen)->mid;
- return(1);
-}
-
-int
-vgaGetInstalledColormaps(pScreen, pmaps)
- ScreenPtr pScreen;
- ColormapPtr *pmaps;
-{
- /* By the time we are processing requests, we can guarantee that there
- * is always a colormap installed */
-
- *pmaps = GetInstalledmiColormap(pScreen);
- return(1);
-}
-
-int vgaCheckColorMap(ColormapPtr pmap)
-{
- return (pmap != GetInstalledmiColormap(pmap->pScreen));
-}
-
-
-void
-vgaStoreColors(pmap, ndef, pdefs)
- ColormapPtr pmap;
- int ndef;
- xColorItem *pdefs;
-{
- int i;
- unsigned char *cmap, *tmp = NULL;
- xColorItem directDefs[256];
- Bool new_overscan = FALSE;
- Bool writeColormap;
-
- /* This can get called before the ScrnInfoRec is installed so we
- can't rely on getting it with XF86SCRNINFO() */
- int scrnIndex = pmap->pScreen->myNum;
- ScrnInfoPtr scrninfp = xf86Screens[scrnIndex];
- vgaHWPtr hwp = VGAHWPTR(scrninfp);
-
- unsigned char overscan = hwp->ModeReg.Attribute[OVERSCAN];
- unsigned char tmp_overscan = 0;
-
- if (vgaCheckColorMap(pmap))
- return;
-
- if ((pmap->pVisual->class | DynamicClass) == DirectColor)
- {
- ndef = miExpandDirectColors (pmap, ndef, pdefs, directDefs);
- pdefs = directDefs;
- }
-
- writeColormap = scrninfp->vtSema;
- if (DGAAvailable(scrnIndex))
- {
- writeColormap = writeColormap ||
- (DGAGetDirectMode(scrnIndex) &&
- !(DGAGetFlags(scrnIndex) & XF86DGADirectColormap)) ||
- (DGAGetFlags(scrnIndex) & XF86DGAHasColormap);
- }
-
- if (writeColormap)
- hwp->enablePalette(hwp);
-
- for(i = 0; i < ndef; i++)
- {
- if (pdefs[i].pixel == overscan)
- {
- new_overscan = TRUE;
- }
- cmap = &(hwp->ModeReg.DAC[pdefs[i].pixel*3]);
- if (scrninfp->rgbBits == 8) {
- cmap[0] = pdefs[i].red >> 8;
- cmap[1] = pdefs[i].green >> 8;
- cmap[2] = pdefs[i].blue >> 8;
- }
- else {
- cmap[0] = pdefs[i].red >> 10;
- cmap[1] = pdefs[i].green >> 10;
- cmap[2] = pdefs[i].blue >> 10;
- }
-#if 0
- if (clgd6225Lcd)
- {
- /* The LCD doesn't like white */
- if (cmap[0] == 63) cmap[0]= 62;
- if (cmap[1] == 63) cmap[1]= 62;
- if (cmap[2] == 63) cmap[2]= 62;
- }
-#endif
-
- if (writeColormap)
- {
- if (hwp->ShowOverscan && i == 255)
- continue;
- hwp->writeDacWriteAddr(hwp, pdefs[i].pixel);
- DACDelay(hwp);
- hwp->writeDacData(hwp, cmap[0]);
- DACDelay(hwp);
- hwp->writeDacData(hwp, cmap[1]);
- DACDelay(hwp);
- hwp->writeDacData(hwp, cmap[2]);
- DACDelay(hwp);
- }
- }
- if (new_overscan && !hwp->ShowOverscan)
- {
- new_overscan = FALSE;
- for(i = 0; i < ndef; i++)
- {
- if (pdefs[i].pixel == overscan)
- {
- if ((pdefs[i].red != 0) ||
- (pdefs[i].green != 0) ||
- (pdefs[i].blue != 0))
- {
- new_overscan = TRUE;
- tmp_overscan = overscan;
- tmp = &(hwp->ModeReg.DAC[pdefs[i].pixel*3]);
- }
- break;
- }
- }
- if (new_overscan)
- {
- /*
- * Find a black pixel, or the nearest match.
- */
- for (i=255; i >= 0; i--)
- {
- cmap = &(hwp->ModeReg.DAC[i*3]);
- if ((cmap[0] == 0) && (cmap[1] == 0) && (cmap[2] == 0))
- {
- overscan = i;
- break;
- }
- else
- {
- if ((cmap[0] < tmp[0]) &&
- (cmap[1] < tmp[1]) && (cmap[2] < tmp[2]))
- {
- tmp = cmap;
- tmp_overscan = i;
- }
- }
- }
- if (i < 0)
- {
- overscan = tmp_overscan;
- }
- hwp->ModeReg.Attribute[OVERSCAN] = overscan;
- if (writeColormap)
- {
- hwp->writeAttr(hwp, OVERSCAN, overscan);
- }
- }
- }
-
- if (writeColormap)
- hwp->disablePalette(hwp);
-}
-
-
-void
-vgaInstallColormap(pmap)
- ColormapPtr pmap;
-{
- ColormapPtr oldmap = GetInstalledmiColormap(pmap->pScreen);
- int entries;
- Pixel * ppix;
- xrgb * prgb;
- xColorItem *defs;
- int i;
-
-
- if (pmap == oldmap)
- return;
-
- if ((pmap->pVisual->class | DynamicClass) == DirectColor)
- entries = (pmap->pVisual->redMask |
- pmap->pVisual->greenMask |
- pmap->pVisual->blueMask) + 1;
- else
- entries = pmap->pVisual->ColormapEntries;
-
- ppix = (Pixel *)xalloc( entries * sizeof(Pixel));
- prgb = (xrgb *)xalloc( entries * sizeof(xrgb));
- defs = (xColorItem *)xalloc(entries * sizeof(xColorItem));
-
- if ( oldmap != NOMAPYET)
- WalkTree( pmap->pScreen, TellLostMap, &oldmap->mid);
-
- SetInstalledmiColormap(pmap->pScreen, pmap);
-
- for ( i=0; i<entries; i++) ppix[i] = i;
-
- QueryColors( pmap, entries, ppix, prgb);
-
- for ( i=0; i<entries; i++) /* convert xrgbs to xColorItems */
- {
- defs[i].pixel = ppix[i];
- defs[i].red = prgb[i].red;
- defs[i].green = prgb[i].green;
- defs[i].blue = prgb[i].blue;
- defs[i].flags = DoRed|DoGreen|DoBlue;
- }
- pmap->pScreen->StoreColors(pmap, entries, defs);
-
- WalkTree(pmap->pScreen, TellGainedMap, &pmap->mid);
-
- xfree(ppix);
- xfree(prgb);
- xfree(defs);
-}
-
-
-void
-vgaUninstallColormap(pmap)
- ColormapPtr pmap;
-{
-
- ColormapPtr defColormap;
-
- if ( pmap != GetInstalledmiColormap(pmap->pScreen))
- return;
-
- dixLookupResourceByType((pointer *)&defColormap, pmap->pScreen->defColormap,
- RT_COLORMAP, serverClient, DixInstallAccess);
-
- if (defColormap == GetInstalledmiColormap(pmap->pScreen))
- return;
-
- (*pmap->pScreen->InstallColormap) (defColormap);
-}
-
-
-void
-vgaHandleColormaps(ScreenPtr pScreen, ScrnInfoPtr scrnp)
-{
- if (scrnp->bitsPerPixel > 1) {
- if (scrnp->bitsPerPixel <= 8) { /* For 8bpp SVGA and VGA16 */
- pScreen->InstallColormap = vgaInstallColormap;
- pScreen->UninstallColormap = vgaUninstallColormap;
- pScreen->ListInstalledColormaps = vgaListInstalledColormaps;
- pScreen->StoreColors = vgaStoreColors;
- }
- }
-}
-
+/*
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Thomas Roell not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Thomas Roell makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THOMAS ROELL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ *
+ */
+
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "windowstr.h"
+#include "compiler.h"
+#include "mipointer.h"
+#include "micmap.h"
+
+#include "xf86.h"
+#include "vgaHW.h"
+
+#include <X11/extensions/xf86dgaproto.h>
+#include "dgaproc.h"
+
+
+#define NOMAPYET (ColormapPtr) 0
+
+int
+vgaListInstalledColormaps(pScreen, pmaps)
+ ScreenPtr pScreen;
+ Colormap *pmaps;
+{
+ /* By the time we are processing requests, we can guarantee that there
+ * is always a colormap installed */
+
+ *pmaps = GetInstalledmiColormap(pScreen)->mid;
+ return(1);
+}
+
+int
+vgaGetInstalledColormaps(pScreen, pmaps)
+ ScreenPtr pScreen;
+ ColormapPtr *pmaps;
+{
+ /* By the time we are processing requests, we can guarantee that there
+ * is always a colormap installed */
+
+ *pmaps = GetInstalledmiColormap(pScreen);
+ return(1);
+}
+
+int vgaCheckColorMap(ColormapPtr pmap)
+{
+ return (pmap != GetInstalledmiColormap(pmap->pScreen));
+}
+
+
+void
+vgaStoreColors(pmap, ndef, pdefs)
+ ColormapPtr pmap;
+ int ndef;
+ xColorItem *pdefs;
+{
+ int i;
+ unsigned char *cmap, *tmp = NULL;
+ xColorItem directDefs[256];
+ Bool new_overscan = FALSE;
+ Bool writeColormap;
+
+ /* This can get called before the ScrnInfoRec is installed so we
+ can't rely on getting it with XF86SCRNINFO() */
+ int scrnIndex = pmap->pScreen->myNum;
+ ScrnInfoPtr scrninfp = xf86Screens[scrnIndex];
+ vgaHWPtr hwp = VGAHWPTR(scrninfp);
+
+ unsigned char overscan = hwp->ModeReg.Attribute[OVERSCAN];
+ unsigned char tmp_overscan = 0;
+
+ if (vgaCheckColorMap(pmap))
+ return;
+
+ if ((pmap->pVisual->class | DynamicClass) == DirectColor)
+ {
+ ndef = miExpandDirectColors (pmap, ndef, pdefs, directDefs);
+ pdefs = directDefs;
+ }
+
+ writeColormap = scrninfp->vtSema;
+ if (DGAAvailable(scrnIndex))
+ {
+ writeColormap = writeColormap ||
+ (DGAGetDirectMode(scrnIndex) &&
+ !(DGAGetFlags(scrnIndex) & XF86DGADirectColormap)) ||
+ (DGAGetFlags(scrnIndex) & XF86DGAHasColormap);
+ }
+
+ if (writeColormap)
+ hwp->enablePalette(hwp);
+
+ for(i = 0; i < ndef; i++)
+ {
+ if (pdefs[i].pixel == overscan)
+ {
+ new_overscan = TRUE;
+ }
+ cmap = &(hwp->ModeReg.DAC[pdefs[i].pixel*3]);
+ if (scrninfp->rgbBits == 8) {
+ cmap[0] = pdefs[i].red >> 8;
+ cmap[1] = pdefs[i].green >> 8;
+ cmap[2] = pdefs[i].blue >> 8;
+ }
+ else {
+ cmap[0] = pdefs[i].red >> 10;
+ cmap[1] = pdefs[i].green >> 10;
+ cmap[2] = pdefs[i].blue >> 10;
+ }
+#if 0
+ if (clgd6225Lcd)
+ {
+ /* The LCD doesn't like white */
+ if (cmap[0] == 63) cmap[0]= 62;
+ if (cmap[1] == 63) cmap[1]= 62;
+ if (cmap[2] == 63) cmap[2]= 62;
+ }
+#endif
+
+ if (writeColormap)
+ {
+ if (hwp->ShowOverscan && i == 255)
+ continue;
+ hwp->writeDacWriteAddr(hwp, pdefs[i].pixel);
+ DACDelay(hwp);
+ hwp->writeDacData(hwp, cmap[0]);
+ DACDelay(hwp);
+ hwp->writeDacData(hwp, cmap[1]);
+ DACDelay(hwp);
+ hwp->writeDacData(hwp, cmap[2]);
+ DACDelay(hwp);
+ }
+ }
+ if (new_overscan && !hwp->ShowOverscan)
+ {
+ new_overscan = FALSE;
+ for(i = 0; i < ndef; i++)
+ {
+ if (pdefs[i].pixel == overscan)
+ {
+ if ((pdefs[i].red != 0) ||
+ (pdefs[i].green != 0) ||
+ (pdefs[i].blue != 0))
+ {
+ new_overscan = TRUE;
+ tmp_overscan = overscan;
+ tmp = &(hwp->ModeReg.DAC[pdefs[i].pixel*3]);
+ }
+ break;
+ }
+ }
+ if (new_overscan)
+ {
+ /*
+ * Find a black pixel, or the nearest match.
+ */
+ for (i=255; i >= 0; i--)
+ {
+ cmap = &(hwp->ModeReg.DAC[i*3]);
+ if ((cmap[0] == 0) && (cmap[1] == 0) && (cmap[2] == 0))
+ {
+ overscan = i;
+ break;
+ }
+ else
+ {
+ if ((cmap[0] < tmp[0]) &&
+ (cmap[1] < tmp[1]) && (cmap[2] < tmp[2]))
+ {
+ tmp = cmap;
+ tmp_overscan = i;
+ }
+ }
+ }
+ if (i < 0)
+ {
+ overscan = tmp_overscan;
+ }
+ hwp->ModeReg.Attribute[OVERSCAN] = overscan;
+ if (writeColormap)
+ {
+ hwp->writeAttr(hwp, OVERSCAN, overscan);
+ }
+ }
+ }
+
+ if (writeColormap)
+ hwp->disablePalette(hwp);
+}
+
+
+void
+vgaInstallColormap(pmap)
+ ColormapPtr pmap;
+{
+ ColormapPtr oldmap = GetInstalledmiColormap(pmap->pScreen);
+ int entries;
+ Pixel * ppix;
+ xrgb * prgb;
+ xColorItem *defs;
+ int i;
+
+
+ if (pmap == oldmap)
+ return;
+
+ if ((pmap->pVisual->class | DynamicClass) == DirectColor)
+ entries = (pmap->pVisual->redMask |
+ pmap->pVisual->greenMask |
+ pmap->pVisual->blueMask) + 1;
+ else
+ entries = pmap->pVisual->ColormapEntries;
+
+ ppix = (Pixel *)malloc( entries * sizeof(Pixel));
+ prgb = (xrgb *)malloc( entries * sizeof(xrgb));
+ defs = (xColorItem *)malloc(entries * sizeof(xColorItem));
+
+ if ( oldmap != NOMAPYET)
+ WalkTree( pmap->pScreen, TellLostMap, &oldmap->mid);
+
+ SetInstalledmiColormap(pmap->pScreen, pmap);
+
+ for ( i=0; i<entries; i++) ppix[i] = i;
+
+ QueryColors(pmap, entries, ppix, prgb, serverClient);
+
+ for ( i=0; i<entries; i++) /* convert xrgbs to xColorItems */
+ {
+ defs[i].pixel = ppix[i];
+ defs[i].red = prgb[i].red;
+ defs[i].green = prgb[i].green;
+ defs[i].blue = prgb[i].blue;
+ defs[i].flags = DoRed|DoGreen|DoBlue;
+ }
+ pmap->pScreen->StoreColors(pmap, entries, defs);
+
+ WalkTree(pmap->pScreen, TellGainedMap, &pmap->mid);
+
+ free(ppix);
+ free(prgb);
+ free(defs);
+}
+
+
+void
+vgaUninstallColormap(pmap)
+ ColormapPtr pmap;
+{
+
+ ColormapPtr defColormap;
+
+ if ( pmap != GetInstalledmiColormap(pmap->pScreen))
+ return;
+
+ dixLookupResourceByType((pointer *)&defColormap, pmap->pScreen->defColormap,
+ RT_COLORMAP, serverClient, DixInstallAccess);
+
+ if (defColormap == GetInstalledmiColormap(pmap->pScreen))
+ return;
+
+ (*pmap->pScreen->InstallColormap) (defColormap);
+}
+
+
+void
+vgaHandleColormaps(ScreenPtr pScreen, ScrnInfoPtr scrnp)
+{
+ if (scrnp->bitsPerPixel > 1) {
+ if (scrnp->bitsPerPixel <= 8) { /* For 8bpp SVGA and VGA16 */
+ pScreen->InstallColormap = vgaInstallColormap;
+ pScreen->UninstallColormap = vgaUninstallColormap;
+ pScreen->ListInstalledColormaps = vgaListInstalledColormaps;
+ pScreen->StoreColors = vgaStoreColors;
+ }
+ }
+}
+
diff --git a/xorg-server/hw/xfree86/vgahw/vgaHW.c b/xorg-server/hw/xfree86/vgahw/vgaHW.c
index 004376b75..396a3cc62 100644
--- a/xorg-server/hw/xfree86/vgahw/vgaHW.c
+++ b/xorg-server/hw/xfree86/vgahw/vgaHW.c
@@ -1,1995 +1,1995 @@
-
-/*
- *
- * Copyright 1991-1999 by The XFree86 Project, Inc.
- *
- * Loosely based on code bearing the following copyright:
- *
- * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
- *
- */
-
-#define _NEED_SYSI86
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <X11/X.h>
-#include "misc.h"
-
-#include "xf86.h"
-#include "xf86_OSproc.h"
-#include "vgaHW.h"
-
-#include "compiler.h"
-
-#include "xf86cmap.h"
-
-#include "Pci.h"
-
-#ifndef SAVE_FONT1
-#define SAVE_FONT1 1
-#endif
-
-/*
- * These used to be OS-specific, which made this module have an undesirable
- * OS dependency. Define them by default for all platforms.
- */
-#ifndef NEED_SAVED_CMAP
-#define NEED_SAVED_CMAP
-#endif
-#ifndef SAVE_TEXT
-#define SAVE_TEXT 1
-#endif
-#ifndef SAVE_FONT2
-#define SAVE_FONT2 1
-#endif
-
-/* bytes per plane to save for text */
-#define TEXT_AMOUNT 16384
-
-/* bytes per plane to save for font data */
-#define FONT_AMOUNT (8*8192)
-
-#if 0
-/* Override all of these for now */
-#undef SAVE_FONT1
-#define SAVE_FONT1 1
-#undef SAVE_FONT2
-#define SAVE_FONT2 1
-#undef SAVE_TEST
-#define SAVE_TEST 1
-#undef FONT_AMOUNT
-#define FONT_AMOUNT 65536
-#undef TEXT_AMOUNT
-#define TEXT_AMOUNT 65536
-#endif
-
-/* DAC indices for white and black */
-#define WHITE_VALUE 0x3F
-#define BLACK_VALUE 0x00
-#define OVERSCAN_VALUE 0x01
-
-
-/* Use a private definition of this here */
-#undef VGAHWPTR
-#define VGAHWPTRLVAL(p) (p)->privates[vgaHWPrivateIndex].ptr
-#define VGAHWPTR(p) ((vgaHWPtr)(VGAHWPTRLVAL(p)))
-
-static int vgaHWPrivateIndex = -1;
-
-#define DAC_TEST_MASK 0x3F
-
-#ifdef NEED_SAVED_CMAP
-/* This default colourmap is used only when it can't be read from the VGA */
-
-static CARD8 defaultDAC[768] =
-{
- 0, 0, 0, 0, 0, 42, 0, 42, 0, 0, 42, 42,
- 42, 0, 0, 42, 0, 42, 42, 21, 0, 42, 42, 42,
- 21, 21, 21, 21, 21, 63, 21, 63, 21, 21, 63, 63,
- 63, 21, 21, 63, 21, 63, 63, 63, 21, 63, 63, 63,
- 0, 0, 0, 5, 5, 5, 8, 8, 8, 11, 11, 11,
- 14, 14, 14, 17, 17, 17, 20, 20, 20, 24, 24, 24,
- 28, 28, 28, 32, 32, 32, 36, 36, 36, 40, 40, 40,
- 45, 45, 45, 50, 50, 50, 56, 56, 56, 63, 63, 63,
- 0, 0, 63, 16, 0, 63, 31, 0, 63, 47, 0, 63,
- 63, 0, 63, 63, 0, 47, 63, 0, 31, 63, 0, 16,
- 63, 0, 0, 63, 16, 0, 63, 31, 0, 63, 47, 0,
- 63, 63, 0, 47, 63, 0, 31, 63, 0, 16, 63, 0,
- 0, 63, 0, 0, 63, 16, 0, 63, 31, 0, 63, 47,
- 0, 63, 63, 0, 47, 63, 0, 31, 63, 0, 16, 63,
- 31, 31, 63, 39, 31, 63, 47, 31, 63, 55, 31, 63,
- 63, 31, 63, 63, 31, 55, 63, 31, 47, 63, 31, 39,
- 63, 31, 31, 63, 39, 31, 63, 47, 31, 63, 55, 31,
- 63, 63, 31, 55, 63, 31, 47, 63, 31, 39, 63, 31,
- 31, 63, 31, 31, 63, 39, 31, 63, 47, 31, 63, 55,
- 31, 63, 63, 31, 55, 63, 31, 47, 63, 31, 39, 63,
- 45, 45, 63, 49, 45, 63, 54, 45, 63, 58, 45, 63,
- 63, 45, 63, 63, 45, 58, 63, 45, 54, 63, 45, 49,
- 63, 45, 45, 63, 49, 45, 63, 54, 45, 63, 58, 45,
- 63, 63, 45, 58, 63, 45, 54, 63, 45, 49, 63, 45,
- 45, 63, 45, 45, 63, 49, 45, 63, 54, 45, 63, 58,
- 45, 63, 63, 45, 58, 63, 45, 54, 63, 45, 49, 63,
- 0, 0, 28, 7, 0, 28, 14, 0, 28, 21, 0, 28,
- 28, 0, 28, 28, 0, 21, 28, 0, 14, 28, 0, 7,
- 28, 0, 0, 28, 7, 0, 28, 14, 0, 28, 21, 0,
- 28, 28, 0, 21, 28, 0, 14, 28, 0, 7, 28, 0,
- 0, 28, 0, 0, 28, 7, 0, 28, 14, 0, 28, 21,
- 0, 28, 28, 0, 21, 28, 0, 14, 28, 0, 7, 28,
- 14, 14, 28, 17, 14, 28, 21, 14, 28, 24, 14, 28,
- 28, 14, 28, 28, 14, 24, 28, 14, 21, 28, 14, 17,
- 28, 14, 14, 28, 17, 14, 28, 21, 14, 28, 24, 14,
- 28, 28, 14, 24, 28, 14, 21, 28, 14, 17, 28, 14,
- 14, 28, 14, 14, 28, 17, 14, 28, 21, 14, 28, 24,
- 14, 28, 28, 14, 24, 28, 14, 21, 28, 14, 17, 28,
- 20, 20, 28, 22, 20, 28, 24, 20, 28, 26, 20, 28,
- 28, 20, 28, 28, 20, 26, 28, 20, 24, 28, 20, 22,
- 28, 20, 20, 28, 22, 20, 28, 24, 20, 28, 26, 20,
- 28, 28, 20, 26, 28, 20, 24, 28, 20, 22, 28, 20,
- 20, 28, 20, 20, 28, 22, 20, 28, 24, 20, 28, 26,
- 20, 28, 28, 20, 26, 28, 20, 24, 28, 20, 22, 28,
- 0, 0, 16, 4, 0, 16, 8, 0, 16, 12, 0, 16,
- 16, 0, 16, 16, 0, 12, 16, 0, 8, 16, 0, 4,
- 16, 0, 0, 16, 4, 0, 16, 8, 0, 16, 12, 0,
- 16, 16, 0, 12, 16, 0, 8, 16, 0, 4, 16, 0,
- 0, 16, 0, 0, 16, 4, 0, 16, 8, 0, 16, 12,
- 0, 16, 16, 0, 12, 16, 0, 8, 16, 0, 4, 16,
- 8, 8, 16, 10, 8, 16, 12, 8, 16, 14, 8, 16,
- 16, 8, 16, 16, 8, 14, 16, 8, 12, 16, 8, 10,
- 16, 8, 8, 16, 10, 8, 16, 12, 8, 16, 14, 8,
- 16, 16, 8, 14, 16, 8, 12, 16, 8, 10, 16, 8,
- 8, 16, 8, 8, 16, 10, 8, 16, 12, 8, 16, 14,
- 8, 16, 16, 8, 14, 16, 8, 12, 16, 8, 10, 16,
- 11, 11, 16, 12, 11, 16, 13, 11, 16, 15, 11, 16,
- 16, 11, 16, 16, 11, 15, 16, 11, 13, 16, 11, 12,
- 16, 11, 11, 16, 12, 11, 16, 13, 11, 16, 15, 11,
- 16, 16, 11, 15, 16, 11, 13, 16, 11, 12, 16, 11,
- 11, 16, 11, 11, 16, 12, 11, 16, 13, 11, 16, 15,
- 11, 16, 16, 11, 15, 16, 11, 13, 16, 11, 12, 16,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-};
-#endif /* NEED_SAVED_CMAP */
-
-/*
- * Standard VGA versions of the register access functions.
- */
-static void
-stdWriteCrtc(vgaHWPtr hwp, CARD8 index, CARD8 value)
-{
- outb(hwp->IOBase + hwp->PIOOffset + VGA_CRTC_INDEX_OFFSET, index);
- outb(hwp->IOBase + hwp->PIOOffset + VGA_CRTC_DATA_OFFSET, value);
-}
-
-static CARD8
-stdReadCrtc(vgaHWPtr hwp, CARD8 index)
-{
- outb(hwp->IOBase + hwp->PIOOffset + VGA_CRTC_INDEX_OFFSET, index);
- return inb(hwp->IOBase + hwp->PIOOffset + VGA_CRTC_DATA_OFFSET);
-}
-
-static void
-stdWriteGr(vgaHWPtr hwp, CARD8 index, CARD8 value)
-{
- outb(hwp->PIOOffset + VGA_GRAPH_INDEX, index);
- outb(hwp->PIOOffset + VGA_GRAPH_DATA, value);
-}
-
-static CARD8
-stdReadGr(vgaHWPtr hwp, CARD8 index)
-{
- outb(hwp->PIOOffset + VGA_GRAPH_INDEX, index);
- return inb(hwp->PIOOffset + VGA_GRAPH_DATA);
-}
-
-static void
-stdWriteSeq(vgaHWPtr hwp, CARD8 index, CARD8 value)
-{
- outb(hwp->PIOOffset + VGA_SEQ_INDEX, index);
- outb(hwp->PIOOffset + VGA_SEQ_DATA, value);
-}
-
-static CARD8
-stdReadSeq(vgaHWPtr hwp, CARD8 index)
-{
- outb(hwp->PIOOffset + VGA_SEQ_INDEX, index);
- return inb(hwp->PIOOffset + VGA_SEQ_DATA);
-}
-
-static CARD8
-stdReadST00(vgaHWPtr hwp)
-{
- return inb(hwp->PIOOffset + VGA_IN_STAT_0);
-}
-
-static CARD8
-stdReadST01(vgaHWPtr hwp)
-{
- return inb(hwp->IOBase + hwp->PIOOffset + VGA_IN_STAT_1_OFFSET);
-}
-
-static CARD8
-stdReadFCR(vgaHWPtr hwp)
-{
- return inb(hwp->PIOOffset + VGA_FEATURE_R);
-}
-
-static void
-stdWriteFCR(vgaHWPtr hwp, CARD8 value)
-{
- outb(hwp->IOBase + hwp->PIOOffset + VGA_FEATURE_W_OFFSET,value);
-}
-
-static void
-stdWriteAttr(vgaHWPtr hwp, CARD8 index, CARD8 value)
-{
- if (hwp->paletteEnabled)
- index &= ~0x20;
- else
- index |= 0x20;
-
- (void) inb(hwp->IOBase + hwp->PIOOffset + VGA_IN_STAT_1_OFFSET);
- outb(hwp->PIOOffset + VGA_ATTR_INDEX, index);
- outb(hwp->PIOOffset + VGA_ATTR_DATA_W, value);
-}
-
-static CARD8
-stdReadAttr(vgaHWPtr hwp, CARD8 index)
-{
- if (hwp->paletteEnabled)
- index &= ~0x20;
- else
- index |= 0x20;
-
- (void) inb(hwp->IOBase + hwp->PIOOffset + VGA_IN_STAT_1_OFFSET);
- outb(hwp->PIOOffset + VGA_ATTR_INDEX, index);
- return inb(hwp->PIOOffset + VGA_ATTR_DATA_R);
-}
-
-static void
-stdWriteMiscOut(vgaHWPtr hwp, CARD8 value)
-{
- outb(hwp->PIOOffset + VGA_MISC_OUT_W, value);
-}
-
-static CARD8
-stdReadMiscOut(vgaHWPtr hwp)
-{
- return inb(hwp->PIOOffset + VGA_MISC_OUT_R);
-}
-
-static void
-stdEnablePalette(vgaHWPtr hwp)
-{
- (void) inb(hwp->IOBase + hwp->PIOOffset + VGA_IN_STAT_1_OFFSET);
- outb(hwp->PIOOffset + VGA_ATTR_INDEX, 0x00);
- hwp->paletteEnabled = TRUE;
-}
-
-static void
-stdDisablePalette(vgaHWPtr hwp)
-{
- (void) inb(hwp->IOBase + hwp->PIOOffset + VGA_IN_STAT_1_OFFSET);
- outb(hwp->PIOOffset + VGA_ATTR_INDEX, 0x20);
- hwp->paletteEnabled = FALSE;
-}
-
-static void
-stdWriteDacMask(vgaHWPtr hwp, CARD8 value)
-{
- outb(hwp->PIOOffset + VGA_DAC_MASK, value);
-}
-
-static CARD8
-stdReadDacMask(vgaHWPtr hwp)
-{
- return inb(hwp->PIOOffset + VGA_DAC_MASK);
-}
-
-static void
-stdWriteDacReadAddr(vgaHWPtr hwp, CARD8 value)
-{
- outb(hwp->PIOOffset + VGA_DAC_READ_ADDR, value);
-}
-
-static void
-stdWriteDacWriteAddr(vgaHWPtr hwp, CARD8 value)
-{
- outb(hwp->PIOOffset + VGA_DAC_WRITE_ADDR, value);
-}
-
-static void
-stdWriteDacData(vgaHWPtr hwp, CARD8 value)
-{
- outb(hwp->PIOOffset + VGA_DAC_DATA, value);
-}
-
-static CARD8
-stdReadDacData(vgaHWPtr hwp)
-{
- return inb(hwp->PIOOffset + VGA_DAC_DATA);
-}
-
-static CARD8
-stdReadEnable(vgaHWPtr hwp)
-{
- return inb(hwp->PIOOffset + VGA_ENABLE);
-}
-
-static void
-stdWriteEnable(vgaHWPtr hwp, CARD8 value)
-{
- outb(hwp->PIOOffset + VGA_ENABLE, value);
-}
-
-void
-vgaHWSetStdFuncs(vgaHWPtr hwp)
-{
- hwp->writeCrtc = stdWriteCrtc;
- hwp->readCrtc = stdReadCrtc;
- hwp->writeGr = stdWriteGr;
- hwp->readGr = stdReadGr;
- hwp->readST00 = stdReadST00;
- hwp->readST01 = stdReadST01;
- hwp->readFCR = stdReadFCR;
- hwp->writeFCR = stdWriteFCR;
- hwp->writeAttr = stdWriteAttr;
- hwp->readAttr = stdReadAttr;
- hwp->writeSeq = stdWriteSeq;
- hwp->readSeq = stdReadSeq;
- hwp->writeMiscOut = stdWriteMiscOut;
- hwp->readMiscOut = stdReadMiscOut;
- hwp->enablePalette = stdEnablePalette;
- hwp->disablePalette = stdDisablePalette;
- hwp->writeDacMask = stdWriteDacMask;
- hwp->readDacMask = stdReadDacMask;
- hwp->writeDacWriteAddr = stdWriteDacWriteAddr;
- hwp->writeDacReadAddr = stdWriteDacReadAddr;
- hwp->writeDacData = stdWriteDacData;
- hwp->readDacData = stdReadDacData;
- hwp->PIOOffset = 0;
- hwp->readEnable = stdReadEnable;
- hwp->writeEnable = stdWriteEnable;
-}
-
-/*
- * MMIO versions of the register access functions. These require
- * hwp->MemBase to be set in such a way that when the standard VGA port
- * adderss is added the correct memory address results.
- */
-
-#define minb(p) MMIO_IN8(hwp->MMIOBase, (hwp->MMIOOffset + (p)))
-#define moutb(p,v) MMIO_OUT8(hwp->MMIOBase, (hwp->MMIOOffset + (p)),(v))
-
-static void
-mmioWriteCrtc(vgaHWPtr hwp, CARD8 index, CARD8 value)
-{
- moutb(hwp->IOBase + VGA_CRTC_INDEX_OFFSET, index);
- moutb(hwp->IOBase + VGA_CRTC_DATA_OFFSET, value);
-}
-
-static CARD8
-mmioReadCrtc(vgaHWPtr hwp, CARD8 index)
-{
- moutb(hwp->IOBase + VGA_CRTC_INDEX_OFFSET, index);
- return minb(hwp->IOBase + VGA_CRTC_DATA_OFFSET);
-}
-
-static void
-mmioWriteGr(vgaHWPtr hwp, CARD8 index, CARD8 value)
-{
- moutb(VGA_GRAPH_INDEX, index);
- moutb(VGA_GRAPH_DATA, value);
-}
-
-static CARD8
-mmioReadGr(vgaHWPtr hwp, CARD8 index)
-{
- moutb(VGA_GRAPH_INDEX, index);
- return minb(VGA_GRAPH_DATA);
-}
-
-static void
-mmioWriteSeq(vgaHWPtr hwp, CARD8 index, CARD8 value)
-{
- moutb(VGA_SEQ_INDEX, index);
- moutb(VGA_SEQ_DATA, value);
-}
-
-static CARD8
-mmioReadSeq(vgaHWPtr hwp, CARD8 index)
-{
- moutb(VGA_SEQ_INDEX, index);
- return minb(VGA_SEQ_DATA);
-}
-
-static CARD8
-mmioReadST00(vgaHWPtr hwp)
-{
- return minb(VGA_IN_STAT_0);
-}
-
-static CARD8
-mmioReadST01(vgaHWPtr hwp)
-{
- return minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
-}
-
-static CARD8
-mmioReadFCR(vgaHWPtr hwp)
-{
- return minb(VGA_FEATURE_R);
-}
-
-static void
-mmioWriteFCR(vgaHWPtr hwp, CARD8 value)
-{
- moutb(hwp->IOBase + VGA_FEATURE_W_OFFSET,value);
-}
-
-static void
-mmioWriteAttr(vgaHWPtr hwp, CARD8 index, CARD8 value)
-{
- if (hwp->paletteEnabled)
- index &= ~0x20;
- else
- index |= 0x20;
-
- (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
- moutb(VGA_ATTR_INDEX, index);
- moutb(VGA_ATTR_DATA_W, value);
-}
-
-static CARD8
-mmioReadAttr(vgaHWPtr hwp, CARD8 index)
-{
- if (hwp->paletteEnabled)
- index &= ~0x20;
- else
- index |= 0x20;
-
- (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
- moutb(VGA_ATTR_INDEX, index);
- return minb(VGA_ATTR_DATA_R);
-}
-
-static void
-mmioWriteMiscOut(vgaHWPtr hwp, CARD8 value)
-{
- moutb(VGA_MISC_OUT_W, value);
-}
-
-static CARD8
-mmioReadMiscOut(vgaHWPtr hwp)
-{
- return minb(VGA_MISC_OUT_R);
-}
-
-static void
-mmioEnablePalette(vgaHWPtr hwp)
-{
- (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
- moutb(VGA_ATTR_INDEX, 0x00);
- hwp->paletteEnabled = TRUE;
-}
-
-static void
-mmioDisablePalette(vgaHWPtr hwp)
-{
- (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
- moutb(VGA_ATTR_INDEX, 0x20);
- hwp->paletteEnabled = FALSE;
-}
-
-static void
-mmioWriteDacMask(vgaHWPtr hwp, CARD8 value)
-{
- moutb(VGA_DAC_MASK, value);
-}
-
-static CARD8
-mmioReadDacMask(vgaHWPtr hwp)
-{
- return minb(VGA_DAC_MASK);
-}
-
-static void
-mmioWriteDacReadAddr(vgaHWPtr hwp, CARD8 value)
-{
- moutb(VGA_DAC_READ_ADDR, value);
-}
-
-static void
-mmioWriteDacWriteAddr(vgaHWPtr hwp, CARD8 value)
-{
- moutb(VGA_DAC_WRITE_ADDR, value);
-}
-
-static void
-mmioWriteDacData(vgaHWPtr hwp, CARD8 value)
-{
- moutb(VGA_DAC_DATA, value);
-}
-
-static CARD8
-mmioReadDacData(vgaHWPtr hwp)
-{
- return minb(VGA_DAC_DATA);
-}
-
-static CARD8
-mmioReadEnable(vgaHWPtr hwp)
-{
- return minb(VGA_ENABLE);
-}
-
-static void
-mmioWriteEnable(vgaHWPtr hwp, CARD8 value)
-{
- moutb(VGA_ENABLE, value);
-}
-
-void
-vgaHWSetMmioFuncs(vgaHWPtr hwp, CARD8 *base, int offset)
-{
- hwp->writeCrtc = mmioWriteCrtc;
- hwp->readCrtc = mmioReadCrtc;
- hwp->writeGr = mmioWriteGr;
- hwp->readGr = mmioReadGr;
- hwp->readST00 = mmioReadST00;
- hwp->readST01 = mmioReadST01;
- hwp->readFCR = mmioReadFCR;
- hwp->writeFCR = mmioWriteFCR;
- hwp->writeAttr = mmioWriteAttr;
- hwp->readAttr = mmioReadAttr;
- hwp->writeSeq = mmioWriteSeq;
- hwp->readSeq = mmioReadSeq;
- hwp->writeMiscOut = mmioWriteMiscOut;
- hwp->readMiscOut = mmioReadMiscOut;
- hwp->enablePalette = mmioEnablePalette;
- hwp->disablePalette = mmioDisablePalette;
- hwp->writeDacMask = mmioWriteDacMask;
- hwp->readDacMask = mmioReadDacMask;
- hwp->writeDacWriteAddr = mmioWriteDacWriteAddr;
- hwp->writeDacReadAddr = mmioWriteDacReadAddr;
- hwp->writeDacData = mmioWriteDacData;
- hwp->readDacData = mmioReadDacData;
- hwp->MMIOBase = base;
- hwp->MMIOOffset = offset;
- hwp->readEnable = mmioReadEnable;
- hwp->writeEnable = mmioWriteEnable;
-}
-
-/*
- * vgaHWProtect --
- * Protect VGA registers and memory from corruption during loads.
- */
-
-void
-vgaHWProtect(ScrnInfoPtr pScrn, Bool on)
-{
- vgaHWPtr hwp = VGAHWPTR(pScrn);
-
- unsigned char tmp;
-
- if (pScrn->vtSema) {
- if (on) {
- /*
- * Turn off screen and disable sequencer.
- */
- tmp = hwp->readSeq(hwp, 0x01);
-
- vgaHWSeqReset(hwp, TRUE); /* start synchronous reset */
- hwp->writeSeq(hwp, 0x01, tmp | 0x20); /* disable the display */
-
- hwp->enablePalette(hwp);
- } else {
- /*
- * Reenable sequencer, then turn on screen.
- */
-
- tmp = hwp->readSeq(hwp, 0x01);
-
- hwp->writeSeq(hwp, 0x01, tmp & ~0x20); /* reenable display */
- vgaHWSeqReset(hwp, FALSE); /* clear synchronousreset */
-
- hwp->disablePalette(hwp);
- }
- }
-}
-
-vgaHWProtectProc *vgaHWProtectWeak(void) {
- return vgaHWProtect;
-}
-
-/*
- * vgaHWBlankScreen -- blank the screen.
- */
-
-void
-vgaHWBlankScreen(ScrnInfoPtr pScrn, Bool on)
-{
- vgaHWPtr hwp = VGAHWPTR(pScrn);
- unsigned char scrn;
-
- scrn = hwp->readSeq(hwp, 0x01);
-
- if (on) {
- scrn &= ~0x20; /* enable screen */
- } else {
- scrn |= 0x20; /* blank screen */
- }
-
- vgaHWSeqReset(hwp, TRUE);
- hwp->writeSeq(hwp, 0x01, scrn); /* change mode */
- vgaHWSeqReset(hwp, FALSE);
-}
-
-vgaHWBlankScreenProc *vgaHWBlankScreenWeak(void) {
- return vgaHWBlankScreen;
-}
-
-/*
- * vgaHWSaveScreen -- blank the screen.
- */
-
-Bool
-vgaHWSaveScreen(ScreenPtr pScreen, int mode)
-{
- ScrnInfoPtr pScrn = NULL;
- Bool on;
-
- if (pScreen != NULL)
- pScrn = xf86Screens[pScreen->myNum];
-
- on = xf86IsUnblank(mode);
-
-#if 0
- if (on)
- SetTimeSinceLastInputEvent();
-#endif
-
- if ((pScrn != NULL) && pScrn->vtSema) {
- vgaHWBlankScreen(pScrn, on);
- }
- return (TRUE);
-}
-
-
-/*
- * vgaHWDPMSSet -- Sets VESA Display Power Management Signaling (DPMS) Mode
- *
- * This generic VGA function can only set the Off and On modes. If the
- * Standby and Suspend modes are to be supported, a chip specific replacement
- * for this function must be written.
- */
-
-void
-vgaHWDPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
-{
- unsigned char seq1 = 0, crtc17 = 0;
- vgaHWPtr hwp = VGAHWPTR(pScrn);
-
- if (!pScrn->vtSema) return;
-
- switch (PowerManagementMode) {
- case DPMSModeOn:
- /* Screen: On; HSync: On, VSync: On */
- seq1 = 0x00;
- crtc17 = 0x80;
- break;
- case DPMSModeStandby:
- /* Screen: Off; HSync: Off, VSync: On -- Not Supported */
- seq1 = 0x20;
- crtc17 = 0x80;
- break;
- case DPMSModeSuspend:
- /* Screen: Off; HSync: On, VSync: Off -- Not Supported */
- seq1 = 0x20;
- crtc17 = 0x80;
- break;
- case DPMSModeOff:
- /* Screen: Off; HSync: Off, VSync: Off */
- seq1 = 0x20;
- crtc17 = 0x00;
- break;
- }
- hwp->writeSeq(hwp, 0x00, 0x01); /* Synchronous Reset */
- seq1 |= hwp->readSeq(hwp, 0x01) & ~0x20;
- hwp->writeSeq(hwp, 0x01, seq1);
- crtc17 |= hwp->readCrtc(hwp, 0x17) & ~0x80;
- usleep(10000);
- hwp->writeCrtc(hwp, 0x17, crtc17);
- hwp->writeSeq(hwp, 0x00, 0x03); /* End Reset */
-}
-
-
-/*
- * vgaHWSeqReset
- * perform a sequencer reset.
- */
-
-void
-vgaHWSeqReset(vgaHWPtr hwp, Bool start)
-{
- if (start)
- hwp->writeSeq(hwp, 0x00, 0x01); /* Synchronous Reset */
- else
- hwp->writeSeq(hwp, 0x00, 0x03); /* End Reset */
-}
-
-
-void
-vgaHWRestoreFonts(ScrnInfoPtr scrninfp, vgaRegPtr restore)
-{
-#if SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2
- vgaHWPtr hwp = VGAHWPTR(scrninfp);
- int savedIOBase;
- unsigned char miscOut, attr10, gr1, gr3, gr4, gr5, gr6, gr8, seq2, seq4;
- Bool doMap = FALSE;
-
- /* If nothing to do, return now */
- if (!hwp->FontInfo1 && !hwp->FontInfo2 && !hwp->TextInfo)
- return;
-
- if (hwp->Base == NULL) {
- doMap = TRUE;
- if (!vgaHWMapMem(scrninfp)) {
- xf86DrvMsg(scrninfp->scrnIndex, X_ERROR,
- "vgaHWRestoreFonts: vgaHWMapMem() failed\n");
- return;
- }
- }
-
- /* save the registers that are needed here */
- miscOut = hwp->readMiscOut(hwp);
- attr10 = hwp->readAttr(hwp, 0x10);
- gr1 = hwp->readGr(hwp, 0x01);
- gr3 = hwp->readGr(hwp, 0x03);
- gr4 = hwp->readGr(hwp, 0x04);
- gr5 = hwp->readGr(hwp, 0x05);
- gr6 = hwp->readGr(hwp, 0x06);
- gr8 = hwp->readGr(hwp, 0x08);
- seq2 = hwp->readSeq(hwp, 0x02);
- seq4 = hwp->readSeq(hwp, 0x04);
-
- /* save hwp->IOBase and temporarily set it for colour mode */
- savedIOBase = hwp->IOBase;
- hwp->IOBase = VGA_IOBASE_COLOR;
-
- /* Force into colour mode */
- hwp->writeMiscOut(hwp, miscOut | 0x01);
-
- vgaHWBlankScreen(scrninfp, FALSE);
-
- /*
- * here we temporarily switch to 16 colour planar mode, to simply
- * copy the font-info and saved text.
- *
- * BUG ALERT: The (S)VGA's segment-select register MUST be set correctly!
- */
-#if 0
- hwp->writeAttr(hwp, 0x10, 0x01); /* graphics mode */
-#endif
-
- hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */
- hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */
- hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */
-
- if (scrninfp->depth == 4) {
- /* GJA */
- hwp->writeGr(hwp, 0x03, 0x00); /* don't rotate, write unmodified */
- hwp->writeGr(hwp, 0x08, 0xFF); /* write all bits in a byte */
- hwp->writeGr(hwp, 0x01, 0x00); /* all planes come from CPU */
- }
-
-#if SAVE_FONT1
- if (hwp->FontInfo1) {
- hwp->writeSeq(hwp, 0x02, 0x04); /* write to plane 2 */
- hwp->writeGr(hwp, 0x04, 0x02); /* read plane 2 */
- slowbcopy_tobus(hwp->FontInfo1, hwp->Base, FONT_AMOUNT);
- }
-#endif
-
-#if SAVE_FONT2
- if (hwp->FontInfo2) {
- hwp->writeSeq(hwp, 0x02, 0x08); /* write to plane 3 */
- hwp->writeGr(hwp, 0x04, 0x03); /* read plane 3 */
- slowbcopy_tobus(hwp->FontInfo2, hwp->Base, FONT_AMOUNT);
- }
-#endif
-
-#if SAVE_TEXT
- if (hwp->TextInfo) {
- hwp->writeSeq(hwp, 0x02, 0x01); /* write to plane 0 */
- hwp->writeGr(hwp, 0x04, 0x00); /* read plane 0 */
- slowbcopy_tobus(hwp->TextInfo, hwp->Base, TEXT_AMOUNT);
- hwp->writeSeq(hwp, 0x02, 0x02); /* write to plane 1 */
- hwp->writeGr(hwp, 0x04, 0x01); /* read plane 1 */
- slowbcopy_tobus((unsigned char *)hwp->TextInfo + TEXT_AMOUNT,
- hwp->Base, TEXT_AMOUNT);
- }
-#endif
-
- vgaHWBlankScreen(scrninfp, TRUE);
-
- /* restore the registers that were changed */
- hwp->writeMiscOut(hwp, miscOut);
- hwp->writeAttr(hwp, 0x10, attr10);
- hwp->writeGr(hwp, 0x01, gr1);
- hwp->writeGr(hwp, 0x03, gr3);
- hwp->writeGr(hwp, 0x04, gr4);
- hwp->writeGr(hwp, 0x05, gr5);
- hwp->writeGr(hwp, 0x06, gr6);
- hwp->writeGr(hwp, 0x08, gr8);
- hwp->writeSeq(hwp, 0x02, seq2);
- hwp->writeSeq(hwp, 0x04, seq4);
- hwp->IOBase = savedIOBase;
-
- if (doMap)
- vgaHWUnmapMem(scrninfp);
-
-#endif /* SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2 */
-}
-
-
-void
-vgaHWRestoreMode(ScrnInfoPtr scrninfp, vgaRegPtr restore)
-{
- vgaHWPtr hwp = VGAHWPTR(scrninfp);
- int i;
-
- if (restore->MiscOutReg & 0x01)
- hwp->IOBase = VGA_IOBASE_COLOR;
- else
- hwp->IOBase = VGA_IOBASE_MONO;
-
- hwp->writeMiscOut(hwp, restore->MiscOutReg);
-
- for (i = 1; i < restore->numSequencer; i++)
- hwp->writeSeq(hwp, i, restore->Sequencer[i]);
-
- /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */
- hwp->writeCrtc(hwp, 17, restore->CRTC[17] & ~0x80);
-
- for (i = 0; i < restore->numCRTC; i++)
- hwp->writeCrtc(hwp, i, restore->CRTC[i]);
-
- for (i = 0; i < restore->numGraphics; i++)
- hwp->writeGr(hwp, i, restore->Graphics[i]);
-
- hwp->enablePalette(hwp);
- for (i = 0; i < restore->numAttribute; i++)
- hwp->writeAttr(hwp, i, restore->Attribute[i]);
- hwp->disablePalette(hwp);
-}
-
-
-void
-vgaHWRestoreColormap(ScrnInfoPtr scrninfp, vgaRegPtr restore)
-{
- vgaHWPtr hwp = VGAHWPTR(scrninfp);
- int i;
-
-#if 0
- hwp->enablePalette(hwp);
-#endif
-
- hwp->writeDacMask(hwp, 0xFF);
- hwp->writeDacWriteAddr(hwp, 0x00);
- for (i = 0; i < 768; i++) {
- hwp->writeDacData(hwp, restore->DAC[i]);
- DACDelay(hwp);
- }
-
- hwp->disablePalette(hwp);
-}
-
-
-/*
- * vgaHWRestore --
- * restore the VGA state
- */
-
-void
-vgaHWRestore(ScrnInfoPtr scrninfp, vgaRegPtr restore, int flags)
-{
- if (flags & VGA_SR_MODE)
- vgaHWRestoreMode(scrninfp, restore);
-
- if (flags & VGA_SR_FONTS)
- vgaHWRestoreFonts(scrninfp, restore);
-
- if (flags & VGA_SR_CMAP)
- vgaHWRestoreColormap(scrninfp, restore);
-}
-
-void
-vgaHWSaveFonts(ScrnInfoPtr scrninfp, vgaRegPtr save)
-{
-#if SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2
- vgaHWPtr hwp = VGAHWPTR(scrninfp);
- int savedIOBase;
- unsigned char miscOut, attr10, gr4, gr5, gr6, seq2, seq4;
- Bool doMap = FALSE;
-
- if (hwp->Base == NULL) {
- doMap = TRUE;
- if (!vgaHWMapMem(scrninfp)) {
- xf86DrvMsg(scrninfp->scrnIndex, X_ERROR,
- "vgaHWSaveFonts: vgaHWMapMem() failed\n");
- return;
- }
- }
-
- /* If in graphics mode, don't save anything */
- attr10 = hwp->readAttr(hwp, 0x10);
- if (attr10 & 0x01)
- return;
-
- /* save the registers that are needed here */
- miscOut = hwp->readMiscOut(hwp);
- gr4 = hwp->readGr(hwp, 0x04);
- gr5 = hwp->readGr(hwp, 0x05);
- gr6 = hwp->readGr(hwp, 0x06);
- seq2 = hwp->readSeq(hwp, 0x02);
- seq4 = hwp->readSeq(hwp, 0x04);
-
- /* save hwp->IOBase and temporarily set it for colour mode */
- savedIOBase = hwp->IOBase;
- hwp->IOBase = VGA_IOBASE_COLOR;
-
- /* Force into colour mode */
- hwp->writeMiscOut(hwp, miscOut | 0x01);
-
- vgaHWBlankScreen(scrninfp, FALSE);
-
- /*
- * get the character sets, and text screen if required
- */
- /*
- * Here we temporarily switch to 16 colour planar mode, to simply
- * copy the font-info
- *
- * BUG ALERT: The (S)VGA's segment-select register MUST be set correctly!
- */
-#if 0
- hwp->writeAttr(hwp, 0x10, 0x01); /* graphics mode */
-#endif
-
- hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */
- hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */
- hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */
-
-#if SAVE_FONT1
- if (hwp->FontInfo1 || (hwp->FontInfo1 = xalloc(FONT_AMOUNT))) {
- hwp->writeSeq(hwp, 0x02, 0x04); /* write to plane 2 */
- hwp->writeGr(hwp, 0x04, 0x02); /* read plane 2 */
- slowbcopy_frombus(hwp->Base, hwp->FontInfo1, FONT_AMOUNT);
- }
-#endif /* SAVE_FONT1 */
-#if SAVE_FONT2
- if (hwp->FontInfo2 || (hwp->FontInfo2 = xalloc(FONT_AMOUNT))) {
- hwp->writeSeq(hwp, 0x02, 0x08); /* write to plane 3 */
- hwp->writeGr(hwp, 0x04, 0x03); /* read plane 3 */
- slowbcopy_frombus(hwp->Base, hwp->FontInfo2, FONT_AMOUNT);
- }
-#endif /* SAVE_FONT2 */
-#if SAVE_TEXT
- if (hwp->TextInfo || (hwp->TextInfo = xalloc(2 * TEXT_AMOUNT))) {
- hwp->writeSeq(hwp, 0x02, 0x01); /* write to plane 0 */
- hwp->writeGr(hwp, 0x04, 0x00); /* read plane 0 */
- slowbcopy_frombus(hwp->Base, hwp->TextInfo, TEXT_AMOUNT);
- hwp->writeSeq(hwp, 0x02, 0x02); /* write to plane 1 */
- hwp->writeGr(hwp, 0x04, 0x01); /* read plane 1 */
- slowbcopy_frombus(hwp->Base,
- (unsigned char *)hwp->TextInfo + TEXT_AMOUNT, TEXT_AMOUNT);
- }
-#endif /* SAVE_TEXT */
-
- /* Restore clobbered registers */
- hwp->writeAttr(hwp, 0x10, attr10);
- hwp->writeSeq(hwp, 0x02, seq2);
- hwp->writeSeq(hwp, 0x04, seq4);
- hwp->writeGr(hwp, 0x04, gr4);
- hwp->writeGr(hwp, 0x05, gr5);
- hwp->writeGr(hwp, 0x06, gr6);
- hwp->writeMiscOut(hwp, miscOut);
- hwp->IOBase = savedIOBase;
-
- vgaHWBlankScreen(scrninfp, TRUE);
-
- if (doMap)
- vgaHWUnmapMem(scrninfp);
-
-#endif /* SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2 */
-}
-
-void
-vgaHWSaveMode(ScrnInfoPtr scrninfp, vgaRegPtr save)
-{
- vgaHWPtr hwp = VGAHWPTR(scrninfp);
- int i;
-
- save->MiscOutReg = hwp->readMiscOut(hwp);
- if (save->MiscOutReg & 0x01)
- hwp->IOBase = VGA_IOBASE_COLOR;
- else
- hwp->IOBase = VGA_IOBASE_MONO;
-
- for (i = 0; i < save->numCRTC; i++) {
- save->CRTC[i] = hwp->readCrtc(hwp, i);
- DebugF("CRTC[0x%02x] = 0x%02x\n", i, save->CRTC[i]);
- }
-
- hwp->enablePalette(hwp);
- for (i = 0; i < save->numAttribute; i++) {
- save->Attribute[i] = hwp->readAttr(hwp, i);
- DebugF("Attribute[0x%02x] = 0x%02x\n", i, save->Attribute[i]);
- }
- hwp->disablePalette(hwp);
-
- for (i = 0; i < save->numGraphics; i++) {
- save->Graphics[i] = hwp->readGr(hwp, i);
- DebugF("Graphics[0x%02x] = 0x%02x\n", i, save->Graphics[i]);
- }
-
- for (i = 1; i < save->numSequencer; i++) {
- save->Sequencer[i] = hwp->readSeq(hwp, i);
- DebugF("Sequencer[0x%02x] = 0x%02x\n", i, save->Sequencer[i]);
- }
-}
-
-
-void
-vgaHWSaveColormap(ScrnInfoPtr scrninfp, vgaRegPtr save)
-{
- vgaHWPtr hwp = VGAHWPTR(scrninfp);
- Bool readError = FALSE;
- int i;
-
-#ifdef NEED_SAVED_CMAP
- /*
- * Some ET4000 chips from 1991 have a HW bug that prevents the reading
- * of the color lookup table. Mask rev 9042EAI is known to have this bug.
- *
- * If the colourmap is not readable, we set the saved map to a default
- * map (taken from Ferraro's "Programmer's Guide to the EGA and VGA
- * Cards" 2nd ed).
- */
-
- /* Only save it once */
- if (hwp->cmapSaved)
- return;
-
-#if 0
- hwp->enablePalette(hwp);
-#endif
-
- hwp->writeDacMask(hwp, 0xFF);
-
- /*
- * check if we can read the lookup table
- */
- hwp->writeDacReadAddr(hwp, 0x00);
- for (i = 0; i < 6; i++) {
- save->DAC[i] = hwp->readDacData(hwp);
- switch (i % 3) {
- case 0:
- DebugF("DAC[0x%02x] = 0x%02x, ", i / 3, save->DAC[i]);
- break;
- case 1:
- DebugF("0x%02x, ", save->DAC[i]);
- break;
- case 2:
- DebugF("0x%02x\n", save->DAC[i]);
- }
- }
-
- /*
- * Check if we can read the palette -
- * use foreground color to prevent flashing.
- */
- hwp->writeDacWriteAddr(hwp, 0x01);
- for (i = 3; i < 6; i++)
- hwp->writeDacData(hwp, ~save->DAC[i] & DAC_TEST_MASK);
- hwp->writeDacReadAddr(hwp, 0x01);
- for (i = 3; i < 6; i++) {
- if (hwp->readDacData(hwp) != (~save->DAC[i] & DAC_TEST_MASK))
- readError = TRUE;
- }
- hwp->writeDacWriteAddr(hwp, 0x01);
- for (i = 3; i < 6; i++)
- hwp->writeDacData(hwp, save->DAC[i]);
-
- if (readError) {
- /*
- * save the default lookup table
- */
- memmove(save->DAC, defaultDAC, 768);
- xf86DrvMsg(scrninfp->scrnIndex, X_WARNING,
- "Cannot read colourmap from VGA. Will restore with default\n");
- } else {
- /* save the colourmap */
- hwp->writeDacReadAddr(hwp, 0x02);
- for (i = 6; i < 768; i++) {
- save->DAC[i] = hwp->readDacData(hwp);
- DACDelay(hwp);
- switch (i % 3) {
- case 0:
- DebugF("DAC[0x%02x] = 0x%02x, ", i / 3, save->DAC[i]);
- break;
- case 1:
- DebugF("0x%02x, ", save->DAC[i]);
- break;
- case 2:
- DebugF("0x%02x\n", save->DAC[i]);
- }
- }
- }
-
- hwp->disablePalette(hwp);
- hwp->cmapSaved = TRUE;
-#endif
-}
-
-/*
- * vgaHWSave --
- * save the current VGA state
- */
-
-void
-vgaHWSave(ScrnInfoPtr scrninfp, vgaRegPtr save, int flags)
-{
- if (save == NULL)
- return;
-
- if (flags & VGA_SR_CMAP)
- vgaHWSaveColormap(scrninfp, save);
-
- if (flags & VGA_SR_MODE)
- vgaHWSaveMode(scrninfp, save);
-
- if (flags & VGA_SR_FONTS)
- vgaHWSaveFonts(scrninfp, save);
-}
-
-
-/*
- * vgaHWInit --
- * Handle the initialization, etc. of a screen.
- * Return FALSE on failure.
- */
-
-Bool
-vgaHWInit(ScrnInfoPtr scrninfp, DisplayModePtr mode)
-{
- unsigned int i;
- vgaHWPtr hwp;
- vgaRegPtr regp;
- int depth = scrninfp->depth;
-
- /*
- * make sure the vgaHWRec is allocated
- */
- if (!vgaHWGetHWRec(scrninfp))
- return FALSE;
- hwp = VGAHWPTR(scrninfp);
- regp = &hwp->ModeReg;
-
- /*
- * compute correct Hsync & Vsync polarity
- */
- if ((mode->Flags & (V_PHSYNC | V_NHSYNC))
- && (mode->Flags & (V_PVSYNC | V_NVSYNC)))
- {
- regp->MiscOutReg = 0x23;
- if (mode->Flags & V_NHSYNC) regp->MiscOutReg |= 0x40;
- if (mode->Flags & V_NVSYNC) regp->MiscOutReg |= 0x80;
- }
- else
- {
- int VDisplay = mode->VDisplay;
- if (mode->Flags & V_DBLSCAN)
- VDisplay *= 2;
- if (mode->VScan > 1)
- VDisplay *= mode->VScan;
- if (VDisplay < 400)
- regp->MiscOutReg = 0xA3; /* +hsync -vsync */
- else if (VDisplay < 480)
- regp->MiscOutReg = 0x63; /* -hsync +vsync */
- else if (VDisplay < 768)
- regp->MiscOutReg = 0xE3; /* -hsync -vsync */
- else
- regp->MiscOutReg = 0x23; /* +hsync +vsync */
- }
-
- regp->MiscOutReg |= (mode->ClockIndex & 0x03) << 2;
-
- /*
- * Time Sequencer
- */
- if (depth == 4)
- regp->Sequencer[0] = 0x02;
- else
- regp->Sequencer[0] = 0x00;
- if (mode->Flags & V_CLKDIV2)
- regp->Sequencer[1] = 0x09;
- else
- regp->Sequencer[1] = 0x01;
- if (depth == 1)
- regp->Sequencer[2] = 1 << BIT_PLANE;
- else
- regp->Sequencer[2] = 0x0F;
- regp->Sequencer[3] = 0x00; /* Font select */
- if (depth < 8)
- regp->Sequencer[4] = 0x06; /* Misc */
- else
- regp->Sequencer[4] = 0x0E; /* Misc */
-
- /*
- * CRTC Controller
- */
- regp->CRTC[0] = (mode->CrtcHTotal >> 3) - 5;
- regp->CRTC[1] = (mode->CrtcHDisplay >> 3) - 1;
- regp->CRTC[2] = (mode->CrtcHBlankStart >> 3) - 1;
- regp->CRTC[3] = (((mode->CrtcHBlankEnd >> 3) - 1) & 0x1F) | 0x80;
- i = (((mode->CrtcHSkew << 2) + 0x10) & ~0x1F);
- if (i < 0x80)
- regp->CRTC[3] |= i;
- regp->CRTC[4] = (mode->CrtcHSyncStart >> 3);
- regp->CRTC[5] = ((((mode->CrtcHBlankEnd >> 3) - 1) & 0x20) << 2)
- | (((mode->CrtcHSyncEnd >> 3)) & 0x1F);
- regp->CRTC[6] = (mode->CrtcVTotal - 2) & 0xFF;
- regp->CRTC[7] = (((mode->CrtcVTotal - 2) & 0x100) >> 8)
- | (((mode->CrtcVDisplay - 1) & 0x100) >> 7)
- | ((mode->CrtcVSyncStart & 0x100) >> 6)
- | (((mode->CrtcVBlankStart - 1) & 0x100) >> 5)
- | 0x10
- | (((mode->CrtcVTotal - 2) & 0x200) >> 4)
- | (((mode->CrtcVDisplay - 1) & 0x200) >> 3)
- | ((mode->CrtcVSyncStart & 0x200) >> 2);
- regp->CRTC[8] = 0x00;
- regp->CRTC[9] = (((mode->CrtcVBlankStart - 1) & 0x200) >> 4) | 0x40;
- if (mode->Flags & V_DBLSCAN)
- regp->CRTC[9] |= 0x80;
- if (mode->VScan >= 32)
- regp->CRTC[9] |= 0x1F;
- else if (mode->VScan > 1)
- regp->CRTC[9] |= mode->VScan - 1;
- regp->CRTC[10] = 0x00;
- regp->CRTC[11] = 0x00;
- regp->CRTC[12] = 0x00;
- regp->CRTC[13] = 0x00;
- regp->CRTC[14] = 0x00;
- regp->CRTC[15] = 0x00;
- regp->CRTC[16] = mode->CrtcVSyncStart & 0xFF;
- regp->CRTC[17] = (mode->CrtcVSyncEnd & 0x0F) | 0x20;
- regp->CRTC[18] = (mode->CrtcVDisplay - 1) & 0xFF;
- regp->CRTC[19] = scrninfp->displayWidth >> 4; /* just a guess */
- regp->CRTC[20] = 0x00;
- regp->CRTC[21] = (mode->CrtcVBlankStart - 1) & 0xFF;
- regp->CRTC[22] = (mode->CrtcVBlankEnd - 1) & 0xFF;
- if (depth < 8)
- regp->CRTC[23] = 0xE3;
- else
- regp->CRTC[23] = 0xC3;
- regp->CRTC[24] = 0xFF;
-
- vgaHWHBlankKGA(mode, regp, 0, KGA_FIX_OVERSCAN | KGA_ENABLE_ON_ZERO);
- vgaHWVBlankKGA(mode, regp, 0, KGA_FIX_OVERSCAN | KGA_ENABLE_ON_ZERO);
-
- /*
- * Theory resumes here....
- */
-
- /*
- * Graphics Display Controller
- */
- regp->Graphics[0] = 0x00;
- regp->Graphics[1] = 0x00;
- regp->Graphics[2] = 0x00;
- regp->Graphics[3] = 0x00;
- if (depth == 1) {
- regp->Graphics[4] = BIT_PLANE;
- regp->Graphics[5] = 0x00;
- } else {
- regp->Graphics[4] = 0x00;
- if (depth == 4)
- regp->Graphics[5] = 0x02;
- else
- regp->Graphics[5] = 0x40;
- }
- regp->Graphics[6] = 0x05; /* only map 64k VGA memory !!!! */
- regp->Graphics[7] = 0x0F;
- regp->Graphics[8] = 0xFF;
-
- if (depth == 1) {
- /* Initialise the Mono map according to which bit-plane gets used */
-
- Bool flipPixels = xf86GetFlipPixels();
-
- for (i=0; i<16; i++)
- if (((i & (1 << BIT_PLANE)) != 0) != flipPixels)
- regp->Attribute[i] = WHITE_VALUE;
- else
- regp->Attribute[i] = BLACK_VALUE;
-
- regp->Attribute[16] = 0x01; /* -VGA2- */ /* wrong for the ET4000 */
- if (!hwp->ShowOverscan)
- regp->Attribute[OVERSCAN] = OVERSCAN_VALUE; /* -VGA2- */
- } else {
- regp->Attribute[0] = 0x00; /* standard colormap translation */
- regp->Attribute[1] = 0x01;
- regp->Attribute[2] = 0x02;
- regp->Attribute[3] = 0x03;
- regp->Attribute[4] = 0x04;
- regp->Attribute[5] = 0x05;
- regp->Attribute[6] = 0x06;
- regp->Attribute[7] = 0x07;
- regp->Attribute[8] = 0x08;
- regp->Attribute[9] = 0x09;
- regp->Attribute[10] = 0x0A;
- regp->Attribute[11] = 0x0B;
- regp->Attribute[12] = 0x0C;
- regp->Attribute[13] = 0x0D;
- regp->Attribute[14] = 0x0E;
- regp->Attribute[15] = 0x0F;
- if (depth == 4)
- regp->Attribute[16] = 0x81; /* wrong for the ET4000 */
- else
- regp->Attribute[16] = 0x41; /* wrong for the ET4000 */
- /* Attribute[17] (overscan) initialised in vgaHWGetHWRec() */
- }
- regp->Attribute[18] = 0x0F;
- regp->Attribute[19] = 0x00;
- regp->Attribute[20] = 0x00;
-
- return(TRUE);
-}
-
- /*
- * OK, so much for theory. Now, let's deal with the >real< world...
- *
- * The above CRTC settings are precise in theory, except that many, if not
- * most, VGA clones fail to reset the blanking signal when the character or
- * line counter reaches [HV]Total. In this case, the signal is only
- * unblanked when the counter reaches [HV]BlankEnd (mod 64, 128 or 256 as
- * the case may be) at the start of the >next< scanline or frame, which
- * means only part of the screen shows. This affects how null overscans
- * are to be implemented on such adapters.
- *
- * Henceforth, VGA cores that implement this broken, but unfortunately
- * common, behaviour are to be designated as KGA's, in honour of Koen
- * Gadeyne, whose zeal to eliminate overscans (read: fury) set in motion
- * a series of events that led to the discovery of this problem.
- *
- * Some VGA's are KGA's only in the horizontal, or only in the vertical,
- * some in both, others in neither. Don't let anyone tell you there is
- * such a thing as a VGA "standard"... And, thank the Creator for the fact
- * that Hilbert spaces are not yet implemented in this industry.
- *
- * The following implements a trick suggested by David Dawes. This sets
- * [HV]BlankEnd to zero if the blanking interval does not already contain a
- * 0-point, and decrements it by one otherwise. In the latter case, this
- * will produce a left and/or top overscan which the colourmap code will
- * (still) need to ensure is as close to black as possible. This will make
- * the behaviour consistent across all chipsets, while allowing all
- * chipsets to display the entire screen. Non-KGA drivers can ignore the
- * following in their own copy of this code.
- *
- * -- TSI @ UQV, 1998.08.21
- */
-
-CARD32
-vgaHWHBlankKGA(DisplayModePtr mode, vgaRegPtr regp, int nBits,
- unsigned int Flags)
-{
- int nExtBits = (nBits < 6) ? 0 : nBits - 6;
- CARD32 ExtBits;
- CARD32 ExtBitMask = ((1 << nExtBits) - 1) << 6;
-
- regp->CRTC[3] = (regp->CRTC[3] & ~0x1F)
- | (((mode->CrtcHBlankEnd >> 3) - 1) & 0x1F);
- regp->CRTC[5] = (regp->CRTC[5] & ~0x80)
- | ((((mode->CrtcHBlankEnd >> 3) - 1) & 0x20) << 2);
- ExtBits = ((mode->CrtcHBlankEnd >> 3) - 1) & ExtBitMask;
-
- /* First the horizontal case */
- if ((Flags & KGA_FIX_OVERSCAN)
- && ((mode->CrtcHBlankEnd >> 3) == (mode->CrtcHTotal >> 3)))
- {
- int i = (regp->CRTC[3] & 0x1F)
- | ((regp->CRTC[5] & 0x80) >> 2)
- | ExtBits;
- if (Flags & KGA_ENABLE_ON_ZERO) {
- if ((i-- > (((mode->CrtcHBlankStart >> 3) - 1)
- & (0x3F | ExtBitMask)))
- && (mode->CrtcHBlankEnd == mode->CrtcHTotal))
- i = 0;
- } else if (Flags & KGA_BE_TOT_DEC)
- i--;
- regp->CRTC[3] = (regp->CRTC[3] & ~0x1F) | (i & 0x1F);
- regp->CRTC[5] = (regp->CRTC[5] & ~0x80) | ((i << 2) & 0x80);
- ExtBits = i & ExtBitMask;
- }
- return ExtBits >> 6;
-}
-
- /*
- * The vertical case is a little trickier. Some VGA's ignore bit 0x80 of
- * CRTC[22]. Also, in some cases, a zero CRTC[22] will still blank the
- * very first scanline in a double- or multi-scanned mode. This last case
- * needs further investigation.
- */
-CARD32
-vgaHWVBlankKGA(DisplayModePtr mode, vgaRegPtr regp, int nBits,
- unsigned int Flags)
-{
- CARD32 ExtBits;
- CARD32 nExtBits = (nBits < 8) ? 0 : (nBits - 8);
- CARD32 ExtBitMask = ((1 << nExtBits) - 1) << 8;
- /* If width is not known nBits should be 0. In this
- * case BitMask is set to 0 so we can check for it. */
- CARD32 BitMask = (nBits < 7) ? 0 : ((1 << nExtBits) - 1);
- int VBlankStart = (mode->CrtcVBlankStart - 1) & 0xFF;
- regp->CRTC[22] = (mode->CrtcVBlankEnd - 1) & 0xFF;
- ExtBits = (mode->CrtcVBlankEnd - 1) & ExtBitMask;
-
- if ((Flags & KGA_FIX_OVERSCAN)
- && (mode->CrtcVBlankEnd == mode->CrtcVTotal))
- /* Null top overscan */
- {
- int i = regp->CRTC[22] | ExtBits;
- if (Flags & KGA_ENABLE_ON_ZERO) {
- if (((BitMask && ((i & BitMask) > (VBlankStart & BitMask)))
- || ((i > VBlankStart) && /* 8-bit case */
- ((i & 0x7F) > (VBlankStart & 0x7F)))) && /* 7-bit case */
- !(regp->CRTC[9] & 0x9F)) /* 1 scanline/row */
- i = 0;
- else
- i = (i - 1);
- } else if (Flags & KGA_BE_TOT_DEC)
- i = (i - 1);
-
- regp->CRTC[22] = i & 0xFF;
- ExtBits = i & 0xFF00;
- }
- return ExtBits >> 8;
-}
-
-/*
- * these are some more hardware specific helpers, formerly in vga.c
- */
-static void
-vgaHWGetHWRecPrivate(void)
-{
- if (vgaHWPrivateIndex < 0)
- vgaHWPrivateIndex = xf86AllocateScrnInfoPrivateIndex();
- return;
-}
-
-
-static void
-vgaHWFreeRegs(vgaRegPtr regp)
-{
- if (regp->CRTC)
- xfree (regp->CRTC);
-
- regp->CRTC =
- regp->Sequencer =
- regp->Graphics =
- regp->Attribute = NULL;
-
- regp->numCRTC =
- regp->numSequencer =
- regp->numGraphics =
- regp->numAttribute = 0;
-}
-
-
-
-static Bool
-vgaHWAllocRegs(vgaRegPtr regp)
-{
- unsigned char *buf;
-
- if ((regp->numCRTC + regp->numSequencer + regp->numGraphics +
- regp->numAttribute) == 0)
- return FALSE;
-
- buf = xcalloc(regp->numCRTC +
- regp->numSequencer +
- regp->numGraphics +
- regp->numAttribute, 1);
- if (!buf)
- return FALSE;
-
- regp->CRTC = buf;
- regp->Sequencer = regp->CRTC + regp->numCRTC;
- regp->Graphics = regp->Sequencer + regp->numSequencer;
- regp->Attribute = regp->Graphics + regp->numGraphics;
-
- return TRUE;
-}
-
-
-Bool
-vgaHWAllocDefaultRegs(vgaRegPtr regp)
-{
- regp->numCRTC = VGA_NUM_CRTC;
- regp->numSequencer = VGA_NUM_SEQ;
- regp->numGraphics = VGA_NUM_GFX;
- regp->numAttribute = VGA_NUM_ATTR;
-
- return vgaHWAllocRegs(regp);
-}
-
-
-Bool
-vgaHWSetRegCounts(ScrnInfoPtr scrp, int numCRTC, int numSequencer,
- int numGraphics, int numAttribute)
-{
-#define VGAHWMINNUM(regtype) \
- ((newMode.num##regtype < regp->num##regtype) ? \
- (newMode.num##regtype) : (regp->num##regtype))
-#define VGAHWCOPYREGSET(regtype) \
- memcpy (newMode.regtype, regp->regtype, VGAHWMINNUM(regtype))
-
- vgaRegRec newMode, newSaved;
- vgaRegPtr regp;
-
- regp = &VGAHWPTR(scrp)->ModeReg;
- memcpy (&newMode, regp, sizeof(vgaRegRec));
-
- /* allocate space for new registers */
-
- regp = &newMode;
- regp->numCRTC = numCRTC;
- regp->numSequencer = numSequencer;
- regp->numGraphics = numGraphics;
- regp->numAttribute = numAttribute;
- if (!vgaHWAllocRegs(regp))
- return FALSE;
-
- regp = &VGAHWPTR(scrp)->SavedReg;
- memcpy (&newSaved, regp, sizeof(vgaRegRec));
-
- regp = &newSaved;
- regp->numCRTC = numCRTC;
- regp->numSequencer = numSequencer;
- regp->numGraphics = numGraphics;
- regp->numAttribute = numAttribute;
- if (!vgaHWAllocRegs(regp)) {
- vgaHWFreeRegs(&newMode);
- return FALSE;
- }
-
- /* allocations succeeded, copy register data into new space */
-
- regp = &VGAHWPTR(scrp)->ModeReg;
- VGAHWCOPYREGSET(CRTC);
- VGAHWCOPYREGSET(Sequencer);
- VGAHWCOPYREGSET(Graphics);
- VGAHWCOPYREGSET(Attribute);
-
- regp = &VGAHWPTR(scrp)->SavedReg;
- VGAHWCOPYREGSET(CRTC);
- VGAHWCOPYREGSET(Sequencer);
- VGAHWCOPYREGSET(Graphics);
- VGAHWCOPYREGSET(Attribute);
-
- /* free old register arrays */
-
- regp = &VGAHWPTR(scrp)->ModeReg;
- vgaHWFreeRegs(regp);
- memcpy(regp, &newMode, sizeof(vgaRegRec));
-
- regp = &VGAHWPTR(scrp)->SavedReg;
- vgaHWFreeRegs(regp);
- memcpy(regp, &newSaved, sizeof(vgaRegRec));
-
- return TRUE;
-
-#undef VGAHWMINNUM
-#undef VGAHWCOPYREGSET
-}
-
-
-Bool
-vgaHWCopyReg(vgaRegPtr dst, vgaRegPtr src)
-{
- vgaHWFreeRegs(dst);
-
- memcpy(dst, src, sizeof(vgaRegRec));
-
- if (!vgaHWAllocRegs(dst))
- return FALSE;
-
- memcpy(dst->CRTC, src->CRTC, src->numCRTC);
- memcpy(dst->Sequencer, src->Sequencer, src->numSequencer);
- memcpy(dst->Graphics, src->Graphics, src->numGraphics);
- memcpy(dst->Attribute, src->Attribute, src->numAttribute);
-
- return TRUE;
-}
-
-
-Bool
-vgaHWGetHWRec(ScrnInfoPtr scrp)
-{
- vgaRegPtr regp;
- vgaHWPtr hwp;
- int i;
-
- /*
- * Let's make sure that the private exists and allocate one.
- */
- vgaHWGetHWRecPrivate();
- /*
- * New privates are always set to NULL, so we can check if the allocation
- * has already been done.
- */
- if (VGAHWPTR(scrp))
- return TRUE;
- hwp = VGAHWPTRLVAL(scrp) = xnfcalloc(sizeof(vgaHWRec), 1);
- regp = &VGAHWPTR(scrp)->ModeReg;
-
- if ((!vgaHWAllocDefaultRegs(&VGAHWPTR(scrp)->SavedReg)) ||
- (!vgaHWAllocDefaultRegs(&VGAHWPTR(scrp)->ModeReg))) {
- xfree(hwp);
- return FALSE;
- }
-
- if (scrp->bitsPerPixel == 1) {
- rgb blackColour = scrp->display->blackColour,
- whiteColour = scrp->display->whiteColour;
-
- if (blackColour.red > 0x3F) blackColour.red = 0x3F;
- if (blackColour.green > 0x3F) blackColour.green = 0x3F;
- if (blackColour.blue > 0x3F) blackColour.blue = 0x3F;
-
- if (whiteColour.red > 0x3F) whiteColour.red = 0x3F;
- if (whiteColour.green > 0x3F) whiteColour.green = 0x3F;
- if (whiteColour.blue > 0x3F) whiteColour.blue = 0x3F;
-
- if ((blackColour.red == whiteColour.red ) &&
- (blackColour.green == whiteColour.green) &&
- (blackColour.blue == whiteColour.blue )) {
- blackColour.red ^= 0x3F;
- blackColour.green ^= 0x3F;
- blackColour.blue ^= 0x3F;
- }
-
- /*
- * initialize default colormap for monochrome
- */
- for (i=0; i<3; i++) regp->DAC[i] = 0x00;
- for (i=3; i<768; i++) regp->DAC[i] = 0x3F;
- i = BLACK_VALUE * 3;
- regp->DAC[i++] = blackColour.red;
- regp->DAC[i++] = blackColour.green;
- regp->DAC[i] = blackColour.blue;
- i = WHITE_VALUE * 3;
- regp->DAC[i++] = whiteColour.red;
- regp->DAC[i++] = whiteColour.green;
- regp->DAC[i] = whiteColour.blue;
- i = OVERSCAN_VALUE * 3;
- regp->DAC[i++] = 0x00;
- regp->DAC[i++] = 0x00;
- regp->DAC[i] = 0x00;
- } else {
- /* Set all colours to black */
- for (i=0; i<768; i++) regp->DAC[i] = 0x00;
- /* ... and the overscan */
- if (scrp->depth >= 4)
- regp->Attribute[OVERSCAN] = 0xFF;
- }
- if (xf86FindOption(scrp->confScreen->options, "ShowOverscan")) {
- xf86MarkOptionUsedByName(scrp->confScreen->options, "ShowOverscan");
- xf86DrvMsg(scrp->scrnIndex, X_CONFIG, "Showing overscan area\n");
- regp->DAC[765] = 0x3F;
- regp->DAC[766] = 0x00;
- regp->DAC[767] = 0x3F;
- regp->Attribute[OVERSCAN] = 0xFF;
- hwp->ShowOverscan = TRUE;
- } else
- hwp->ShowOverscan = FALSE;
-
- hwp->paletteEnabled = FALSE;
- hwp->cmapSaved = FALSE;
- hwp->MapSize = 0;
- hwp->pScrn = scrp;
-
- /* Initialise the function pointers with the standard VGA versions */
- vgaHWSetStdFuncs(hwp);
-
- hwp->PIOOffset = scrp->domainIOBase;
- hwp->dev = xf86GetPciInfoForEntity(scrp->entityList[0]);
-
- return TRUE;
-}
-
-
-void
-vgaHWFreeHWRec(ScrnInfoPtr scrp)
-{
- if (vgaHWPrivateIndex >= 0) {
- vgaHWPtr hwp = VGAHWPTR(scrp);
-
- if (!hwp)
- return;
-
- xfree(hwp->FontInfo1);
- xfree(hwp->FontInfo2);
- xfree(hwp->TextInfo);
-
- vgaHWFreeRegs (&hwp->ModeReg);
- vgaHWFreeRegs (&hwp->SavedReg);
-
- xfree(hwp);
- VGAHWPTRLVAL(scrp) = NULL;
- }
-}
-
-
-Bool
-vgaHWMapMem(ScrnInfoPtr scrp)
-{
- vgaHWPtr hwp = VGAHWPTR(scrp);
- int scr_index = scrp->scrnIndex;
-
- if (hwp->Base)
- return TRUE;
-
- /* If not set, initialise with the defaults */
- if (hwp->MapSize == 0)
- hwp->MapSize = VGA_DEFAULT_MEM_SIZE;
- if (hwp->MapPhys == 0)
- hwp->MapPhys = VGA_DEFAULT_PHYS_ADDR;
-
- /*
- * Map as VIDMEM_MMIO_32BIT because WC
- * is bad when there is page flipping.
- * XXX This is not correct but we do it
- * for now.
- */
- DebugF("Mapping VGAMem\n");
- hwp->Base = xf86MapDomainMemory(scr_index, VIDMEM_MMIO_32BIT, hwp->dev,
- hwp->MapPhys, hwp->MapSize);
- return hwp->Base != NULL;
-}
-
-
-void
-vgaHWUnmapMem(ScrnInfoPtr scrp)
-{
- vgaHWPtr hwp = VGAHWPTR(scrp);
- int scr_index = scrp->scrnIndex;
-
- if (hwp->Base == NULL)
- return;
-
- DebugF("Unmapping VGAMem\n");
- xf86UnMapVidMem(scr_index, hwp->Base, hwp->MapSize);
- hwp->Base = NULL;
-}
-
-int
-vgaHWGetIndex(void)
-{
- return vgaHWPrivateIndex;
-}
-
-
-void
-vgaHWGetIOBase(vgaHWPtr hwp)
-{
- hwp->IOBase = (hwp->readMiscOut(hwp) & 0x01) ?
- VGA_IOBASE_COLOR : VGA_IOBASE_MONO;
- xf86DrvMsgVerb(hwp->pScrn->scrnIndex, X_INFO, 3,
- "vgaHWGetIOBase: hwp->IOBase is 0x%04x, hwp->PIOOffset is 0x%04lx\n",
- hwp->IOBase, hwp->PIOOffset);
-}
-
-
-void
-vgaHWLock(vgaHWPtr hwp)
-{
- /* Protect CRTC[0-7] */
- hwp->writeCrtc(hwp, 0x11, hwp->readCrtc(hwp, 0x11) | 0x80);
-}
-
-void
-vgaHWUnlock(vgaHWPtr hwp)
-{
- /* Unprotect CRTC[0-7] */
- hwp->writeCrtc(hwp, 0x11, hwp->readCrtc(hwp, 0x11) & ~0x80);
-}
-
-
-void
-vgaHWEnable(vgaHWPtr hwp)
-{
- hwp->writeEnable(hwp, hwp->readEnable(hwp) | 0x01);
-}
-
-
-void
-vgaHWDisable(vgaHWPtr hwp)
-{
- hwp->writeEnable(hwp, hwp->readEnable(hwp) & ~0x01);
-}
-
-
-static void
-vgaHWLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
- VisualPtr pVisual)
-{
- vgaHWPtr hwp = VGAHWPTR(pScrn);
- int i, index;
-
- for (i = 0; i < numColors; i++) {
- index = indices[i];
- hwp->writeDacWriteAddr(hwp, index);
- DACDelay(hwp);
- hwp->writeDacData(hwp, colors[index].red);
- DACDelay(hwp);
- hwp->writeDacData(hwp, colors[index].green);
- DACDelay(hwp);
- hwp->writeDacData(hwp, colors[index].blue);
- DACDelay(hwp);
- }
-
- /* This shouldn't be necessary, but we'll play safe. */
- hwp->disablePalette(hwp);
-}
-
-
-static void
-vgaHWSetOverscan(ScrnInfoPtr pScrn, int overscan)
-{
- vgaHWPtr hwp = VGAHWPTR(pScrn);
-
- if (overscan < 0 || overscan > 255)
- return;
-
- hwp->enablePalette(hwp);
- hwp->writeAttr(hwp, OVERSCAN, overscan);
-
-#ifdef DEBUGOVERSCAN
- {
- int ov = hwp->readAttr(hwp, OVERSCAN);
- int red, green, blue;
-
- hwp->writeDacReadAddr(hwp, ov);
- red = hwp->readDacData(hwp);
- green = hwp->readDacData(hwp);
- blue = hwp->readDacData(hwp);
- ErrorF("Overscan index is 0x%02x, colours are #%02x%02x%02x\n",
- ov, red, green, blue);
- }
-#endif
-
- hwp->disablePalette(hwp);
-}
-
-
-Bool
-vgaHWHandleColormaps(ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-
- if (pScrn->depth > 1 && pScrn->depth <= 8) {
- return xf86HandleColormaps(pScreen, 1 << pScrn->depth,
- pScrn->rgbBits, vgaHWLoadPalette,
- pScrn->depth > 4 ? vgaHWSetOverscan : NULL,
- CMAP_RELOAD_ON_MODE_SWITCH);
- }
- return TRUE;
-}
-
-/* ----------------------- DDC support ------------------------*/
-/*
- * Adjust v_active, v_blank, v_sync, v_sync_end, v_blank_end, v_total
- * to read out EDID at a faster rate. Allowed maximum is 25kHz with
- * 20 usec v_sync active. Set positive v_sync polarity, turn off lightpen
- * readback, enable access to cr00-cr07.
- */
-
-/* vertical timings */
-#define DISPLAY_END 0x04
-#define BLANK_START DISPLAY_END
-#define SYNC_START BLANK_START
-#define SYNC_END 0x09
-#define BLANK_END SYNC_END
-#define V_TOTAL BLANK_END
-/* this function doesn't have to be reentrant for our purposes */
-struct _vgaDdcSave {
- unsigned char cr03;
- unsigned char cr06;
- unsigned char cr07;
- unsigned char cr09;
- unsigned char cr10;
- unsigned char cr11;
- unsigned char cr12;
- unsigned char cr15;
- unsigned char cr16;
- unsigned char msr;
-};
-
-void
-vgaHWddc1SetSpeed(ScrnInfoPtr pScrn, xf86ddcSpeed speed)
-{
- vgaHWPtr hwp = VGAHWPTR(pScrn);
- unsigned char tmp;
- struct _vgaDdcSave* save;
- switch (speed) {
- case DDC_FAST:
-
- if (hwp->ddc != NULL) break;
- hwp->ddc = xnfcalloc(sizeof(struct _vgaDdcSave),1);
- save = (struct _vgaDdcSave *)hwp->ddc;
- /* Lightpen register disable - allow access to cr10 & 11; just in case */
- save->cr03 = hwp->readCrtc(hwp, 0x03);
- hwp->writeCrtc(hwp,0x03,(save->cr03 |0x80));
- save->cr12 = hwp->readCrtc(hwp, 0x12);
- hwp->writeCrtc(hwp,0x12,DISPLAY_END);
- save->cr15 = hwp->readCrtc(hwp, 0x15);
- hwp->writeCrtc(hwp,0x15,BLANK_START);
- save->cr10 = hwp->readCrtc(hwp, 0x10);
- hwp->writeCrtc(hwp,0x10,SYNC_START);
- save->cr11 = hwp->readCrtc(hwp, 0x11);
- /* unprotect group 1 registers; just in case ...*/
- hwp->writeCrtc(hwp,0x11,((save->cr11 & 0x70) | SYNC_END));
- save->cr16 = hwp->readCrtc(hwp, 0x16);
- hwp->writeCrtc(hwp,0x16,BLANK_END);
- save->cr06 = hwp->readCrtc(hwp, 0x06);
- hwp->writeCrtc(hwp,0x06,V_TOTAL);
- /* all values have less than 8 bit - mask out 9th and 10th bits */
- save->cr09 = hwp->readCrtc(hwp, 0x09);
- hwp->writeCrtc(hwp,0x09,(save->cr09 &0xDF));
- save->cr07 = hwp->readCrtc(hwp, 0x07);
- hwp->writeCrtc(hwp,0x07,(save->cr07 &0x10));
- /* vsync polarity negativ & ensure a 25MHz clock */
- save->msr = hwp->readMiscOut(hwp);
- hwp->writeMiscOut(hwp,((save->msr & 0xF3) | 0x80));
- break;
- case DDC_SLOW:
- if (hwp->ddc == NULL) break;
- save = (struct _vgaDdcSave *)hwp->ddc;
- hwp->writeMiscOut(hwp,save->msr);
- hwp->writeCrtc(hwp,0x07,save->cr07);
- tmp = hwp->readCrtc(hwp, 0x09);
- hwp->writeCrtc(hwp,0x09,((save->cr09 & 0x20) | (tmp & 0xDF)));
- hwp->writeCrtc(hwp,0x06,save->cr06);
- hwp->writeCrtc(hwp,0x16,save->cr16);
- hwp->writeCrtc(hwp,0x11,save->cr11);
- hwp->writeCrtc(hwp,0x10,save->cr10);
- hwp->writeCrtc(hwp,0x15,save->cr15);
- hwp->writeCrtc(hwp,0x12,save->cr12);
- hwp->writeCrtc(hwp,0x03,save->cr03);
- xfree(save);
- hwp->ddc = NULL;
- break;
- default:
- break;
- }
-}
-
-DDC1SetSpeedProc
-vgaHWddc1SetSpeedWeak(void)
-{
- return vgaHWddc1SetSpeed;
-}
-
-SaveScreenProcPtr vgaHWSaveScreenWeak(void)
-{
- return vgaHWSaveScreen;
-}
+
+/*
+ *
+ * Copyright 1991-1999 by The XFree86 Project, Inc.
+ *
+ * Loosely based on code bearing the following copyright:
+ *
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+ *
+ */
+
+#define _NEED_SYSI86
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <X11/X.h>
+#include "misc.h"
+
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "vgaHW.h"
+
+#include "compiler.h"
+
+#include "xf86cmap.h"
+
+#include "Pci.h"
+
+#ifndef SAVE_FONT1
+#define SAVE_FONT1 1
+#endif
+
+/*
+ * These used to be OS-specific, which made this module have an undesirable
+ * OS dependency. Define them by default for all platforms.
+ */
+#ifndef NEED_SAVED_CMAP
+#define NEED_SAVED_CMAP
+#endif
+#ifndef SAVE_TEXT
+#define SAVE_TEXT 1
+#endif
+#ifndef SAVE_FONT2
+#define SAVE_FONT2 1
+#endif
+
+/* bytes per plane to save for text */
+#define TEXT_AMOUNT 16384
+
+/* bytes per plane to save for font data */
+#define FONT_AMOUNT (8*8192)
+
+#if 0
+/* Override all of these for now */
+#undef SAVE_FONT1
+#define SAVE_FONT1 1
+#undef SAVE_FONT2
+#define SAVE_FONT2 1
+#undef SAVE_TEST
+#define SAVE_TEST 1
+#undef FONT_AMOUNT
+#define FONT_AMOUNT 65536
+#undef TEXT_AMOUNT
+#define TEXT_AMOUNT 65536
+#endif
+
+/* DAC indices for white and black */
+#define WHITE_VALUE 0x3F
+#define BLACK_VALUE 0x00
+#define OVERSCAN_VALUE 0x01
+
+
+/* Use a private definition of this here */
+#undef VGAHWPTR
+#define VGAHWPTRLVAL(p) (p)->privates[vgaHWPrivateIndex].ptr
+#define VGAHWPTR(p) ((vgaHWPtr)(VGAHWPTRLVAL(p)))
+
+static int vgaHWPrivateIndex = -1;
+
+#define DAC_TEST_MASK 0x3F
+
+#ifdef NEED_SAVED_CMAP
+/* This default colourmap is used only when it can't be read from the VGA */
+
+static CARD8 defaultDAC[768] =
+{
+ 0, 0, 0, 0, 0, 42, 0, 42, 0, 0, 42, 42,
+ 42, 0, 0, 42, 0, 42, 42, 21, 0, 42, 42, 42,
+ 21, 21, 21, 21, 21, 63, 21, 63, 21, 21, 63, 63,
+ 63, 21, 21, 63, 21, 63, 63, 63, 21, 63, 63, 63,
+ 0, 0, 0, 5, 5, 5, 8, 8, 8, 11, 11, 11,
+ 14, 14, 14, 17, 17, 17, 20, 20, 20, 24, 24, 24,
+ 28, 28, 28, 32, 32, 32, 36, 36, 36, 40, 40, 40,
+ 45, 45, 45, 50, 50, 50, 56, 56, 56, 63, 63, 63,
+ 0, 0, 63, 16, 0, 63, 31, 0, 63, 47, 0, 63,
+ 63, 0, 63, 63, 0, 47, 63, 0, 31, 63, 0, 16,
+ 63, 0, 0, 63, 16, 0, 63, 31, 0, 63, 47, 0,
+ 63, 63, 0, 47, 63, 0, 31, 63, 0, 16, 63, 0,
+ 0, 63, 0, 0, 63, 16, 0, 63, 31, 0, 63, 47,
+ 0, 63, 63, 0, 47, 63, 0, 31, 63, 0, 16, 63,
+ 31, 31, 63, 39, 31, 63, 47, 31, 63, 55, 31, 63,
+ 63, 31, 63, 63, 31, 55, 63, 31, 47, 63, 31, 39,
+ 63, 31, 31, 63, 39, 31, 63, 47, 31, 63, 55, 31,
+ 63, 63, 31, 55, 63, 31, 47, 63, 31, 39, 63, 31,
+ 31, 63, 31, 31, 63, 39, 31, 63, 47, 31, 63, 55,
+ 31, 63, 63, 31, 55, 63, 31, 47, 63, 31, 39, 63,
+ 45, 45, 63, 49, 45, 63, 54, 45, 63, 58, 45, 63,
+ 63, 45, 63, 63, 45, 58, 63, 45, 54, 63, 45, 49,
+ 63, 45, 45, 63, 49, 45, 63, 54, 45, 63, 58, 45,
+ 63, 63, 45, 58, 63, 45, 54, 63, 45, 49, 63, 45,
+ 45, 63, 45, 45, 63, 49, 45, 63, 54, 45, 63, 58,
+ 45, 63, 63, 45, 58, 63, 45, 54, 63, 45, 49, 63,
+ 0, 0, 28, 7, 0, 28, 14, 0, 28, 21, 0, 28,
+ 28, 0, 28, 28, 0, 21, 28, 0, 14, 28, 0, 7,
+ 28, 0, 0, 28, 7, 0, 28, 14, 0, 28, 21, 0,
+ 28, 28, 0, 21, 28, 0, 14, 28, 0, 7, 28, 0,
+ 0, 28, 0, 0, 28, 7, 0, 28, 14, 0, 28, 21,
+ 0, 28, 28, 0, 21, 28, 0, 14, 28, 0, 7, 28,
+ 14, 14, 28, 17, 14, 28, 21, 14, 28, 24, 14, 28,
+ 28, 14, 28, 28, 14, 24, 28, 14, 21, 28, 14, 17,
+ 28, 14, 14, 28, 17, 14, 28, 21, 14, 28, 24, 14,
+ 28, 28, 14, 24, 28, 14, 21, 28, 14, 17, 28, 14,
+ 14, 28, 14, 14, 28, 17, 14, 28, 21, 14, 28, 24,
+ 14, 28, 28, 14, 24, 28, 14, 21, 28, 14, 17, 28,
+ 20, 20, 28, 22, 20, 28, 24, 20, 28, 26, 20, 28,
+ 28, 20, 28, 28, 20, 26, 28, 20, 24, 28, 20, 22,
+ 28, 20, 20, 28, 22, 20, 28, 24, 20, 28, 26, 20,
+ 28, 28, 20, 26, 28, 20, 24, 28, 20, 22, 28, 20,
+ 20, 28, 20, 20, 28, 22, 20, 28, 24, 20, 28, 26,
+ 20, 28, 28, 20, 26, 28, 20, 24, 28, 20, 22, 28,
+ 0, 0, 16, 4, 0, 16, 8, 0, 16, 12, 0, 16,
+ 16, 0, 16, 16, 0, 12, 16, 0, 8, 16, 0, 4,
+ 16, 0, 0, 16, 4, 0, 16, 8, 0, 16, 12, 0,
+ 16, 16, 0, 12, 16, 0, 8, 16, 0, 4, 16, 0,
+ 0, 16, 0, 0, 16, 4, 0, 16, 8, 0, 16, 12,
+ 0, 16, 16, 0, 12, 16, 0, 8, 16, 0, 4, 16,
+ 8, 8, 16, 10, 8, 16, 12, 8, 16, 14, 8, 16,
+ 16, 8, 16, 16, 8, 14, 16, 8, 12, 16, 8, 10,
+ 16, 8, 8, 16, 10, 8, 16, 12, 8, 16, 14, 8,
+ 16, 16, 8, 14, 16, 8, 12, 16, 8, 10, 16, 8,
+ 8, 16, 8, 8, 16, 10, 8, 16, 12, 8, 16, 14,
+ 8, 16, 16, 8, 14, 16, 8, 12, 16, 8, 10, 16,
+ 11, 11, 16, 12, 11, 16, 13, 11, 16, 15, 11, 16,
+ 16, 11, 16, 16, 11, 15, 16, 11, 13, 16, 11, 12,
+ 16, 11, 11, 16, 12, 11, 16, 13, 11, 16, 15, 11,
+ 16, 16, 11, 15, 16, 11, 13, 16, 11, 12, 16, 11,
+ 11, 16, 11, 11, 16, 12, 11, 16, 13, 11, 16, 15,
+ 11, 16, 16, 11, 15, 16, 11, 13, 16, 11, 12, 16,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+#endif /* NEED_SAVED_CMAP */
+
+/*
+ * Standard VGA versions of the register access functions.
+ */
+static void
+stdWriteCrtc(vgaHWPtr hwp, CARD8 index, CARD8 value)
+{
+ outb(hwp->IOBase + hwp->PIOOffset + VGA_CRTC_INDEX_OFFSET, index);
+ outb(hwp->IOBase + hwp->PIOOffset + VGA_CRTC_DATA_OFFSET, value);
+}
+
+static CARD8
+stdReadCrtc(vgaHWPtr hwp, CARD8 index)
+{
+ outb(hwp->IOBase + hwp->PIOOffset + VGA_CRTC_INDEX_OFFSET, index);
+ return inb(hwp->IOBase + hwp->PIOOffset + VGA_CRTC_DATA_OFFSET);
+}
+
+static void
+stdWriteGr(vgaHWPtr hwp, CARD8 index, CARD8 value)
+{
+ outb(hwp->PIOOffset + VGA_GRAPH_INDEX, index);
+ outb(hwp->PIOOffset + VGA_GRAPH_DATA, value);
+}
+
+static CARD8
+stdReadGr(vgaHWPtr hwp, CARD8 index)
+{
+ outb(hwp->PIOOffset + VGA_GRAPH_INDEX, index);
+ return inb(hwp->PIOOffset + VGA_GRAPH_DATA);
+}
+
+static void
+stdWriteSeq(vgaHWPtr hwp, CARD8 index, CARD8 value)
+{
+ outb(hwp->PIOOffset + VGA_SEQ_INDEX, index);
+ outb(hwp->PIOOffset + VGA_SEQ_DATA, value);
+}
+
+static CARD8
+stdReadSeq(vgaHWPtr hwp, CARD8 index)
+{
+ outb(hwp->PIOOffset + VGA_SEQ_INDEX, index);
+ return inb(hwp->PIOOffset + VGA_SEQ_DATA);
+}
+
+static CARD8
+stdReadST00(vgaHWPtr hwp)
+{
+ return inb(hwp->PIOOffset + VGA_IN_STAT_0);
+}
+
+static CARD8
+stdReadST01(vgaHWPtr hwp)
+{
+ return inb(hwp->IOBase + hwp->PIOOffset + VGA_IN_STAT_1_OFFSET);
+}
+
+static CARD8
+stdReadFCR(vgaHWPtr hwp)
+{
+ return inb(hwp->PIOOffset + VGA_FEATURE_R);
+}
+
+static void
+stdWriteFCR(vgaHWPtr hwp, CARD8 value)
+{
+ outb(hwp->IOBase + hwp->PIOOffset + VGA_FEATURE_W_OFFSET,value);
+}
+
+static void
+stdWriteAttr(vgaHWPtr hwp, CARD8 index, CARD8 value)
+{
+ if (hwp->paletteEnabled)
+ index &= ~0x20;
+ else
+ index |= 0x20;
+
+ (void) inb(hwp->IOBase + hwp->PIOOffset + VGA_IN_STAT_1_OFFSET);
+ outb(hwp->PIOOffset + VGA_ATTR_INDEX, index);
+ outb(hwp->PIOOffset + VGA_ATTR_DATA_W, value);
+}
+
+static CARD8
+stdReadAttr(vgaHWPtr hwp, CARD8 index)
+{
+ if (hwp->paletteEnabled)
+ index &= ~0x20;
+ else
+ index |= 0x20;
+
+ (void) inb(hwp->IOBase + hwp->PIOOffset + VGA_IN_STAT_1_OFFSET);
+ outb(hwp->PIOOffset + VGA_ATTR_INDEX, index);
+ return inb(hwp->PIOOffset + VGA_ATTR_DATA_R);
+}
+
+static void
+stdWriteMiscOut(vgaHWPtr hwp, CARD8 value)
+{
+ outb(hwp->PIOOffset + VGA_MISC_OUT_W, value);
+}
+
+static CARD8
+stdReadMiscOut(vgaHWPtr hwp)
+{
+ return inb(hwp->PIOOffset + VGA_MISC_OUT_R);
+}
+
+static void
+stdEnablePalette(vgaHWPtr hwp)
+{
+ (void) inb(hwp->IOBase + hwp->PIOOffset + VGA_IN_STAT_1_OFFSET);
+ outb(hwp->PIOOffset + VGA_ATTR_INDEX, 0x00);
+ hwp->paletteEnabled = TRUE;
+}
+
+static void
+stdDisablePalette(vgaHWPtr hwp)
+{
+ (void) inb(hwp->IOBase + hwp->PIOOffset + VGA_IN_STAT_1_OFFSET);
+ outb(hwp->PIOOffset + VGA_ATTR_INDEX, 0x20);
+ hwp->paletteEnabled = FALSE;
+}
+
+static void
+stdWriteDacMask(vgaHWPtr hwp, CARD8 value)
+{
+ outb(hwp->PIOOffset + VGA_DAC_MASK, value);
+}
+
+static CARD8
+stdReadDacMask(vgaHWPtr hwp)
+{
+ return inb(hwp->PIOOffset + VGA_DAC_MASK);
+}
+
+static void
+stdWriteDacReadAddr(vgaHWPtr hwp, CARD8 value)
+{
+ outb(hwp->PIOOffset + VGA_DAC_READ_ADDR, value);
+}
+
+static void
+stdWriteDacWriteAddr(vgaHWPtr hwp, CARD8 value)
+{
+ outb(hwp->PIOOffset + VGA_DAC_WRITE_ADDR, value);
+}
+
+static void
+stdWriteDacData(vgaHWPtr hwp, CARD8 value)
+{
+ outb(hwp->PIOOffset + VGA_DAC_DATA, value);
+}
+
+static CARD8
+stdReadDacData(vgaHWPtr hwp)
+{
+ return inb(hwp->PIOOffset + VGA_DAC_DATA);
+}
+
+static CARD8
+stdReadEnable(vgaHWPtr hwp)
+{
+ return inb(hwp->PIOOffset + VGA_ENABLE);
+}
+
+static void
+stdWriteEnable(vgaHWPtr hwp, CARD8 value)
+{
+ outb(hwp->PIOOffset + VGA_ENABLE, value);
+}
+
+void
+vgaHWSetStdFuncs(vgaHWPtr hwp)
+{
+ hwp->writeCrtc = stdWriteCrtc;
+ hwp->readCrtc = stdReadCrtc;
+ hwp->writeGr = stdWriteGr;
+ hwp->readGr = stdReadGr;
+ hwp->readST00 = stdReadST00;
+ hwp->readST01 = stdReadST01;
+ hwp->readFCR = stdReadFCR;
+ hwp->writeFCR = stdWriteFCR;
+ hwp->writeAttr = stdWriteAttr;
+ hwp->readAttr = stdReadAttr;
+ hwp->writeSeq = stdWriteSeq;
+ hwp->readSeq = stdReadSeq;
+ hwp->writeMiscOut = stdWriteMiscOut;
+ hwp->readMiscOut = stdReadMiscOut;
+ hwp->enablePalette = stdEnablePalette;
+ hwp->disablePalette = stdDisablePalette;
+ hwp->writeDacMask = stdWriteDacMask;
+ hwp->readDacMask = stdReadDacMask;
+ hwp->writeDacWriteAddr = stdWriteDacWriteAddr;
+ hwp->writeDacReadAddr = stdWriteDacReadAddr;
+ hwp->writeDacData = stdWriteDacData;
+ hwp->readDacData = stdReadDacData;
+ hwp->PIOOffset = 0;
+ hwp->readEnable = stdReadEnable;
+ hwp->writeEnable = stdWriteEnable;
+}
+
+/*
+ * MMIO versions of the register access functions. These require
+ * hwp->MemBase to be set in such a way that when the standard VGA port
+ * adderss is added the correct memory address results.
+ */
+
+#define minb(p) MMIO_IN8(hwp->MMIOBase, (hwp->MMIOOffset + (p)))
+#define moutb(p,v) MMIO_OUT8(hwp->MMIOBase, (hwp->MMIOOffset + (p)),(v))
+
+static void
+mmioWriteCrtc(vgaHWPtr hwp, CARD8 index, CARD8 value)
+{
+ moutb(hwp->IOBase + VGA_CRTC_INDEX_OFFSET, index);
+ moutb(hwp->IOBase + VGA_CRTC_DATA_OFFSET, value);
+}
+
+static CARD8
+mmioReadCrtc(vgaHWPtr hwp, CARD8 index)
+{
+ moutb(hwp->IOBase + VGA_CRTC_INDEX_OFFSET, index);
+ return minb(hwp->IOBase + VGA_CRTC_DATA_OFFSET);
+}
+
+static void
+mmioWriteGr(vgaHWPtr hwp, CARD8 index, CARD8 value)
+{
+ moutb(VGA_GRAPH_INDEX, index);
+ moutb(VGA_GRAPH_DATA, value);
+}
+
+static CARD8
+mmioReadGr(vgaHWPtr hwp, CARD8 index)
+{
+ moutb(VGA_GRAPH_INDEX, index);
+ return minb(VGA_GRAPH_DATA);
+}
+
+static void
+mmioWriteSeq(vgaHWPtr hwp, CARD8 index, CARD8 value)
+{
+ moutb(VGA_SEQ_INDEX, index);
+ moutb(VGA_SEQ_DATA, value);
+}
+
+static CARD8
+mmioReadSeq(vgaHWPtr hwp, CARD8 index)
+{
+ moutb(VGA_SEQ_INDEX, index);
+ return minb(VGA_SEQ_DATA);
+}
+
+static CARD8
+mmioReadST00(vgaHWPtr hwp)
+{
+ return minb(VGA_IN_STAT_0);
+}
+
+static CARD8
+mmioReadST01(vgaHWPtr hwp)
+{
+ return minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
+}
+
+static CARD8
+mmioReadFCR(vgaHWPtr hwp)
+{
+ return minb(VGA_FEATURE_R);
+}
+
+static void
+mmioWriteFCR(vgaHWPtr hwp, CARD8 value)
+{
+ moutb(hwp->IOBase + VGA_FEATURE_W_OFFSET,value);
+}
+
+static void
+mmioWriteAttr(vgaHWPtr hwp, CARD8 index, CARD8 value)
+{
+ if (hwp->paletteEnabled)
+ index &= ~0x20;
+ else
+ index |= 0x20;
+
+ (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
+ moutb(VGA_ATTR_INDEX, index);
+ moutb(VGA_ATTR_DATA_W, value);
+}
+
+static CARD8
+mmioReadAttr(vgaHWPtr hwp, CARD8 index)
+{
+ if (hwp->paletteEnabled)
+ index &= ~0x20;
+ else
+ index |= 0x20;
+
+ (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
+ moutb(VGA_ATTR_INDEX, index);
+ return minb(VGA_ATTR_DATA_R);
+}
+
+static void
+mmioWriteMiscOut(vgaHWPtr hwp, CARD8 value)
+{
+ moutb(VGA_MISC_OUT_W, value);
+}
+
+static CARD8
+mmioReadMiscOut(vgaHWPtr hwp)
+{
+ return minb(VGA_MISC_OUT_R);
+}
+
+static void
+mmioEnablePalette(vgaHWPtr hwp)
+{
+ (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
+ moutb(VGA_ATTR_INDEX, 0x00);
+ hwp->paletteEnabled = TRUE;
+}
+
+static void
+mmioDisablePalette(vgaHWPtr hwp)
+{
+ (void) minb(hwp->IOBase + VGA_IN_STAT_1_OFFSET);
+ moutb(VGA_ATTR_INDEX, 0x20);
+ hwp->paletteEnabled = FALSE;
+}
+
+static void
+mmioWriteDacMask(vgaHWPtr hwp, CARD8 value)
+{
+ moutb(VGA_DAC_MASK, value);
+}
+
+static CARD8
+mmioReadDacMask(vgaHWPtr hwp)
+{
+ return minb(VGA_DAC_MASK);
+}
+
+static void
+mmioWriteDacReadAddr(vgaHWPtr hwp, CARD8 value)
+{
+ moutb(VGA_DAC_READ_ADDR, value);
+}
+
+static void
+mmioWriteDacWriteAddr(vgaHWPtr hwp, CARD8 value)
+{
+ moutb(VGA_DAC_WRITE_ADDR, value);
+}
+
+static void
+mmioWriteDacData(vgaHWPtr hwp, CARD8 value)
+{
+ moutb(VGA_DAC_DATA, value);
+}
+
+static CARD8
+mmioReadDacData(vgaHWPtr hwp)
+{
+ return minb(VGA_DAC_DATA);
+}
+
+static CARD8
+mmioReadEnable(vgaHWPtr hwp)
+{
+ return minb(VGA_ENABLE);
+}
+
+static void
+mmioWriteEnable(vgaHWPtr hwp, CARD8 value)
+{
+ moutb(VGA_ENABLE, value);
+}
+
+void
+vgaHWSetMmioFuncs(vgaHWPtr hwp, CARD8 *base, int offset)
+{
+ hwp->writeCrtc = mmioWriteCrtc;
+ hwp->readCrtc = mmioReadCrtc;
+ hwp->writeGr = mmioWriteGr;
+ hwp->readGr = mmioReadGr;
+ hwp->readST00 = mmioReadST00;
+ hwp->readST01 = mmioReadST01;
+ hwp->readFCR = mmioReadFCR;
+ hwp->writeFCR = mmioWriteFCR;
+ hwp->writeAttr = mmioWriteAttr;
+ hwp->readAttr = mmioReadAttr;
+ hwp->writeSeq = mmioWriteSeq;
+ hwp->readSeq = mmioReadSeq;
+ hwp->writeMiscOut = mmioWriteMiscOut;
+ hwp->readMiscOut = mmioReadMiscOut;
+ hwp->enablePalette = mmioEnablePalette;
+ hwp->disablePalette = mmioDisablePalette;
+ hwp->writeDacMask = mmioWriteDacMask;
+ hwp->readDacMask = mmioReadDacMask;
+ hwp->writeDacWriteAddr = mmioWriteDacWriteAddr;
+ hwp->writeDacReadAddr = mmioWriteDacReadAddr;
+ hwp->writeDacData = mmioWriteDacData;
+ hwp->readDacData = mmioReadDacData;
+ hwp->MMIOBase = base;
+ hwp->MMIOOffset = offset;
+ hwp->readEnable = mmioReadEnable;
+ hwp->writeEnable = mmioWriteEnable;
+}
+
+/*
+ * vgaHWProtect --
+ * Protect VGA registers and memory from corruption during loads.
+ */
+
+void
+vgaHWProtect(ScrnInfoPtr pScrn, Bool on)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+ unsigned char tmp;
+
+ if (pScrn->vtSema) {
+ if (on) {
+ /*
+ * Turn off screen and disable sequencer.
+ */
+ tmp = hwp->readSeq(hwp, 0x01);
+
+ vgaHWSeqReset(hwp, TRUE); /* start synchronous reset */
+ hwp->writeSeq(hwp, 0x01, tmp | 0x20); /* disable the display */
+
+ hwp->enablePalette(hwp);
+ } else {
+ /*
+ * Reenable sequencer, then turn on screen.
+ */
+
+ tmp = hwp->readSeq(hwp, 0x01);
+
+ hwp->writeSeq(hwp, 0x01, tmp & ~0x20); /* reenable display */
+ vgaHWSeqReset(hwp, FALSE); /* clear synchronousreset */
+
+ hwp->disablePalette(hwp);
+ }
+ }
+}
+
+vgaHWProtectProc *vgaHWProtectWeak(void) {
+ return vgaHWProtect;
+}
+
+/*
+ * vgaHWBlankScreen -- blank the screen.
+ */
+
+void
+vgaHWBlankScreen(ScrnInfoPtr pScrn, Bool on)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ unsigned char scrn;
+
+ scrn = hwp->readSeq(hwp, 0x01);
+
+ if (on) {
+ scrn &= ~0x20; /* enable screen */
+ } else {
+ scrn |= 0x20; /* blank screen */
+ }
+
+ vgaHWSeqReset(hwp, TRUE);
+ hwp->writeSeq(hwp, 0x01, scrn); /* change mode */
+ vgaHWSeqReset(hwp, FALSE);
+}
+
+vgaHWBlankScreenProc *vgaHWBlankScreenWeak(void) {
+ return vgaHWBlankScreen;
+}
+
+/*
+ * vgaHWSaveScreen -- blank the screen.
+ */
+
+Bool
+vgaHWSaveScreen(ScreenPtr pScreen, int mode)
+{
+ ScrnInfoPtr pScrn = NULL;
+ Bool on;
+
+ if (pScreen != NULL)
+ pScrn = xf86Screens[pScreen->myNum];
+
+ on = xf86IsUnblank(mode);
+
+#if 0
+ if (on)
+ SetTimeSinceLastInputEvent();
+#endif
+
+ if ((pScrn != NULL) && pScrn->vtSema) {
+ vgaHWBlankScreen(pScrn, on);
+ }
+ return (TRUE);
+}
+
+
+/*
+ * vgaHWDPMSSet -- Sets VESA Display Power Management Signaling (DPMS) Mode
+ *
+ * This generic VGA function can only set the Off and On modes. If the
+ * Standby and Suspend modes are to be supported, a chip specific replacement
+ * for this function must be written.
+ */
+
+void
+vgaHWDPMSSet(ScrnInfoPtr pScrn, int PowerManagementMode, int flags)
+{
+ unsigned char seq1 = 0, crtc17 = 0;
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+ if (!pScrn->vtSema) return;
+
+ switch (PowerManagementMode) {
+ case DPMSModeOn:
+ /* Screen: On; HSync: On, VSync: On */
+ seq1 = 0x00;
+ crtc17 = 0x80;
+ break;
+ case DPMSModeStandby:
+ /* Screen: Off; HSync: Off, VSync: On -- Not Supported */
+ seq1 = 0x20;
+ crtc17 = 0x80;
+ break;
+ case DPMSModeSuspend:
+ /* Screen: Off; HSync: On, VSync: Off -- Not Supported */
+ seq1 = 0x20;
+ crtc17 = 0x80;
+ break;
+ case DPMSModeOff:
+ /* Screen: Off; HSync: Off, VSync: Off */
+ seq1 = 0x20;
+ crtc17 = 0x00;
+ break;
+ }
+ hwp->writeSeq(hwp, 0x00, 0x01); /* Synchronous Reset */
+ seq1 |= hwp->readSeq(hwp, 0x01) & ~0x20;
+ hwp->writeSeq(hwp, 0x01, seq1);
+ crtc17 |= hwp->readCrtc(hwp, 0x17) & ~0x80;
+ usleep(10000);
+ hwp->writeCrtc(hwp, 0x17, crtc17);
+ hwp->writeSeq(hwp, 0x00, 0x03); /* End Reset */
+}
+
+
+/*
+ * vgaHWSeqReset
+ * perform a sequencer reset.
+ */
+
+void
+vgaHWSeqReset(vgaHWPtr hwp, Bool start)
+{
+ if (start)
+ hwp->writeSeq(hwp, 0x00, 0x01); /* Synchronous Reset */
+ else
+ hwp->writeSeq(hwp, 0x00, 0x03); /* End Reset */
+}
+
+
+void
+vgaHWRestoreFonts(ScrnInfoPtr scrninfp, vgaRegPtr restore)
+{
+#if SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2
+ vgaHWPtr hwp = VGAHWPTR(scrninfp);
+ int savedIOBase;
+ unsigned char miscOut, attr10, gr1, gr3, gr4, gr5, gr6, gr8, seq2, seq4;
+ Bool doMap = FALSE;
+
+ /* If nothing to do, return now */
+ if (!hwp->FontInfo1 && !hwp->FontInfo2 && !hwp->TextInfo)
+ return;
+
+ if (hwp->Base == NULL) {
+ doMap = TRUE;
+ if (!vgaHWMapMem(scrninfp)) {
+ xf86DrvMsg(scrninfp->scrnIndex, X_ERROR,
+ "vgaHWRestoreFonts: vgaHWMapMem() failed\n");
+ return;
+ }
+ }
+
+ /* save the registers that are needed here */
+ miscOut = hwp->readMiscOut(hwp);
+ attr10 = hwp->readAttr(hwp, 0x10);
+ gr1 = hwp->readGr(hwp, 0x01);
+ gr3 = hwp->readGr(hwp, 0x03);
+ gr4 = hwp->readGr(hwp, 0x04);
+ gr5 = hwp->readGr(hwp, 0x05);
+ gr6 = hwp->readGr(hwp, 0x06);
+ gr8 = hwp->readGr(hwp, 0x08);
+ seq2 = hwp->readSeq(hwp, 0x02);
+ seq4 = hwp->readSeq(hwp, 0x04);
+
+ /* save hwp->IOBase and temporarily set it for colour mode */
+ savedIOBase = hwp->IOBase;
+ hwp->IOBase = VGA_IOBASE_COLOR;
+
+ /* Force into colour mode */
+ hwp->writeMiscOut(hwp, miscOut | 0x01);
+
+ vgaHWBlankScreen(scrninfp, FALSE);
+
+ /*
+ * here we temporarily switch to 16 colour planar mode, to simply
+ * copy the font-info and saved text.
+ *
+ * BUG ALERT: The (S)VGA's segment-select register MUST be set correctly!
+ */
+#if 0
+ hwp->writeAttr(hwp, 0x10, 0x01); /* graphics mode */
+#endif
+
+ hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */
+ hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */
+ hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */
+
+ if (scrninfp->depth == 4) {
+ /* GJA */
+ hwp->writeGr(hwp, 0x03, 0x00); /* don't rotate, write unmodified */
+ hwp->writeGr(hwp, 0x08, 0xFF); /* write all bits in a byte */
+ hwp->writeGr(hwp, 0x01, 0x00); /* all planes come from CPU */
+ }
+
+#if SAVE_FONT1
+ if (hwp->FontInfo1) {
+ hwp->writeSeq(hwp, 0x02, 0x04); /* write to plane 2 */
+ hwp->writeGr(hwp, 0x04, 0x02); /* read plane 2 */
+ slowbcopy_tobus(hwp->FontInfo1, hwp->Base, FONT_AMOUNT);
+ }
+#endif
+
+#if SAVE_FONT2
+ if (hwp->FontInfo2) {
+ hwp->writeSeq(hwp, 0x02, 0x08); /* write to plane 3 */
+ hwp->writeGr(hwp, 0x04, 0x03); /* read plane 3 */
+ slowbcopy_tobus(hwp->FontInfo2, hwp->Base, FONT_AMOUNT);
+ }
+#endif
+
+#if SAVE_TEXT
+ if (hwp->TextInfo) {
+ hwp->writeSeq(hwp, 0x02, 0x01); /* write to plane 0 */
+ hwp->writeGr(hwp, 0x04, 0x00); /* read plane 0 */
+ slowbcopy_tobus(hwp->TextInfo, hwp->Base, TEXT_AMOUNT);
+ hwp->writeSeq(hwp, 0x02, 0x02); /* write to plane 1 */
+ hwp->writeGr(hwp, 0x04, 0x01); /* read plane 1 */
+ slowbcopy_tobus((unsigned char *)hwp->TextInfo + TEXT_AMOUNT,
+ hwp->Base, TEXT_AMOUNT);
+ }
+#endif
+
+ vgaHWBlankScreen(scrninfp, TRUE);
+
+ /* restore the registers that were changed */
+ hwp->writeMiscOut(hwp, miscOut);
+ hwp->writeAttr(hwp, 0x10, attr10);
+ hwp->writeGr(hwp, 0x01, gr1);
+ hwp->writeGr(hwp, 0x03, gr3);
+ hwp->writeGr(hwp, 0x04, gr4);
+ hwp->writeGr(hwp, 0x05, gr5);
+ hwp->writeGr(hwp, 0x06, gr6);
+ hwp->writeGr(hwp, 0x08, gr8);
+ hwp->writeSeq(hwp, 0x02, seq2);
+ hwp->writeSeq(hwp, 0x04, seq4);
+ hwp->IOBase = savedIOBase;
+
+ if (doMap)
+ vgaHWUnmapMem(scrninfp);
+
+#endif /* SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2 */
+}
+
+
+void
+vgaHWRestoreMode(ScrnInfoPtr scrninfp, vgaRegPtr restore)
+{
+ vgaHWPtr hwp = VGAHWPTR(scrninfp);
+ int i;
+
+ if (restore->MiscOutReg & 0x01)
+ hwp->IOBase = VGA_IOBASE_COLOR;
+ else
+ hwp->IOBase = VGA_IOBASE_MONO;
+
+ hwp->writeMiscOut(hwp, restore->MiscOutReg);
+
+ for (i = 1; i < restore->numSequencer; i++)
+ hwp->writeSeq(hwp, i, restore->Sequencer[i]);
+
+ /* Ensure CRTC registers 0-7 are unlocked by clearing bit 7 of CRTC[17] */
+ hwp->writeCrtc(hwp, 17, restore->CRTC[17] & ~0x80);
+
+ for (i = 0; i < restore->numCRTC; i++)
+ hwp->writeCrtc(hwp, i, restore->CRTC[i]);
+
+ for (i = 0; i < restore->numGraphics; i++)
+ hwp->writeGr(hwp, i, restore->Graphics[i]);
+
+ hwp->enablePalette(hwp);
+ for (i = 0; i < restore->numAttribute; i++)
+ hwp->writeAttr(hwp, i, restore->Attribute[i]);
+ hwp->disablePalette(hwp);
+}
+
+
+void
+vgaHWRestoreColormap(ScrnInfoPtr scrninfp, vgaRegPtr restore)
+{
+ vgaHWPtr hwp = VGAHWPTR(scrninfp);
+ int i;
+
+#if 0
+ hwp->enablePalette(hwp);
+#endif
+
+ hwp->writeDacMask(hwp, 0xFF);
+ hwp->writeDacWriteAddr(hwp, 0x00);
+ for (i = 0; i < 768; i++) {
+ hwp->writeDacData(hwp, restore->DAC[i]);
+ DACDelay(hwp);
+ }
+
+ hwp->disablePalette(hwp);
+}
+
+
+/*
+ * vgaHWRestore --
+ * restore the VGA state
+ */
+
+void
+vgaHWRestore(ScrnInfoPtr scrninfp, vgaRegPtr restore, int flags)
+{
+ if (flags & VGA_SR_MODE)
+ vgaHWRestoreMode(scrninfp, restore);
+
+ if (flags & VGA_SR_FONTS)
+ vgaHWRestoreFonts(scrninfp, restore);
+
+ if (flags & VGA_SR_CMAP)
+ vgaHWRestoreColormap(scrninfp, restore);
+}
+
+void
+vgaHWSaveFonts(ScrnInfoPtr scrninfp, vgaRegPtr save)
+{
+#if SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2
+ vgaHWPtr hwp = VGAHWPTR(scrninfp);
+ int savedIOBase;
+ unsigned char miscOut, attr10, gr4, gr5, gr6, seq2, seq4;
+ Bool doMap = FALSE;
+
+ if (hwp->Base == NULL) {
+ doMap = TRUE;
+ if (!vgaHWMapMem(scrninfp)) {
+ xf86DrvMsg(scrninfp->scrnIndex, X_ERROR,
+ "vgaHWSaveFonts: vgaHWMapMem() failed\n");
+ return;
+ }
+ }
+
+ /* If in graphics mode, don't save anything */
+ attr10 = hwp->readAttr(hwp, 0x10);
+ if (attr10 & 0x01)
+ return;
+
+ /* save the registers that are needed here */
+ miscOut = hwp->readMiscOut(hwp);
+ gr4 = hwp->readGr(hwp, 0x04);
+ gr5 = hwp->readGr(hwp, 0x05);
+ gr6 = hwp->readGr(hwp, 0x06);
+ seq2 = hwp->readSeq(hwp, 0x02);
+ seq4 = hwp->readSeq(hwp, 0x04);
+
+ /* save hwp->IOBase and temporarily set it for colour mode */
+ savedIOBase = hwp->IOBase;
+ hwp->IOBase = VGA_IOBASE_COLOR;
+
+ /* Force into colour mode */
+ hwp->writeMiscOut(hwp, miscOut | 0x01);
+
+ vgaHWBlankScreen(scrninfp, FALSE);
+
+ /*
+ * get the character sets, and text screen if required
+ */
+ /*
+ * Here we temporarily switch to 16 colour planar mode, to simply
+ * copy the font-info
+ *
+ * BUG ALERT: The (S)VGA's segment-select register MUST be set correctly!
+ */
+#if 0
+ hwp->writeAttr(hwp, 0x10, 0x01); /* graphics mode */
+#endif
+
+ hwp->writeSeq(hwp, 0x04, 0x06); /* enable plane graphics */
+ hwp->writeGr(hwp, 0x05, 0x00); /* write mode 0, read mode 0 */
+ hwp->writeGr(hwp, 0x06, 0x05); /* set graphics */
+
+#if SAVE_FONT1
+ if (hwp->FontInfo1 || (hwp->FontInfo1 = malloc(FONT_AMOUNT))) {
+ hwp->writeSeq(hwp, 0x02, 0x04); /* write to plane 2 */
+ hwp->writeGr(hwp, 0x04, 0x02); /* read plane 2 */
+ slowbcopy_frombus(hwp->Base, hwp->FontInfo1, FONT_AMOUNT);
+ }
+#endif /* SAVE_FONT1 */
+#if SAVE_FONT2
+ if (hwp->FontInfo2 || (hwp->FontInfo2 = malloc(FONT_AMOUNT))) {
+ hwp->writeSeq(hwp, 0x02, 0x08); /* write to plane 3 */
+ hwp->writeGr(hwp, 0x04, 0x03); /* read plane 3 */
+ slowbcopy_frombus(hwp->Base, hwp->FontInfo2, FONT_AMOUNT);
+ }
+#endif /* SAVE_FONT2 */
+#if SAVE_TEXT
+ if (hwp->TextInfo || (hwp->TextInfo = malloc(2 * TEXT_AMOUNT))) {
+ hwp->writeSeq(hwp, 0x02, 0x01); /* write to plane 0 */
+ hwp->writeGr(hwp, 0x04, 0x00); /* read plane 0 */
+ slowbcopy_frombus(hwp->Base, hwp->TextInfo, TEXT_AMOUNT);
+ hwp->writeSeq(hwp, 0x02, 0x02); /* write to plane 1 */
+ hwp->writeGr(hwp, 0x04, 0x01); /* read plane 1 */
+ slowbcopy_frombus(hwp->Base,
+ (unsigned char *)hwp->TextInfo + TEXT_AMOUNT, TEXT_AMOUNT);
+ }
+#endif /* SAVE_TEXT */
+
+ /* Restore clobbered registers */
+ hwp->writeAttr(hwp, 0x10, attr10);
+ hwp->writeSeq(hwp, 0x02, seq2);
+ hwp->writeSeq(hwp, 0x04, seq4);
+ hwp->writeGr(hwp, 0x04, gr4);
+ hwp->writeGr(hwp, 0x05, gr5);
+ hwp->writeGr(hwp, 0x06, gr6);
+ hwp->writeMiscOut(hwp, miscOut);
+ hwp->IOBase = savedIOBase;
+
+ vgaHWBlankScreen(scrninfp, TRUE);
+
+ if (doMap)
+ vgaHWUnmapMem(scrninfp);
+
+#endif /* SAVE_TEXT || SAVE_FONT1 || SAVE_FONT2 */
+}
+
+void
+vgaHWSaveMode(ScrnInfoPtr scrninfp, vgaRegPtr save)
+{
+ vgaHWPtr hwp = VGAHWPTR(scrninfp);
+ int i;
+
+ save->MiscOutReg = hwp->readMiscOut(hwp);
+ if (save->MiscOutReg & 0x01)
+ hwp->IOBase = VGA_IOBASE_COLOR;
+ else
+ hwp->IOBase = VGA_IOBASE_MONO;
+
+ for (i = 0; i < save->numCRTC; i++) {
+ save->CRTC[i] = hwp->readCrtc(hwp, i);
+ DebugF("CRTC[0x%02x] = 0x%02x\n", i, save->CRTC[i]);
+ }
+
+ hwp->enablePalette(hwp);
+ for (i = 0; i < save->numAttribute; i++) {
+ save->Attribute[i] = hwp->readAttr(hwp, i);
+ DebugF("Attribute[0x%02x] = 0x%02x\n", i, save->Attribute[i]);
+ }
+ hwp->disablePalette(hwp);
+
+ for (i = 0; i < save->numGraphics; i++) {
+ save->Graphics[i] = hwp->readGr(hwp, i);
+ DebugF("Graphics[0x%02x] = 0x%02x\n", i, save->Graphics[i]);
+ }
+
+ for (i = 1; i < save->numSequencer; i++) {
+ save->Sequencer[i] = hwp->readSeq(hwp, i);
+ DebugF("Sequencer[0x%02x] = 0x%02x\n", i, save->Sequencer[i]);
+ }
+}
+
+
+void
+vgaHWSaveColormap(ScrnInfoPtr scrninfp, vgaRegPtr save)
+{
+ vgaHWPtr hwp = VGAHWPTR(scrninfp);
+ Bool readError = FALSE;
+ int i;
+
+#ifdef NEED_SAVED_CMAP
+ /*
+ * Some ET4000 chips from 1991 have a HW bug that prevents the reading
+ * of the color lookup table. Mask rev 9042EAI is known to have this bug.
+ *
+ * If the colourmap is not readable, we set the saved map to a default
+ * map (taken from Ferraro's "Programmer's Guide to the EGA and VGA
+ * Cards" 2nd ed).
+ */
+
+ /* Only save it once */
+ if (hwp->cmapSaved)
+ return;
+
+#if 0
+ hwp->enablePalette(hwp);
+#endif
+
+ hwp->writeDacMask(hwp, 0xFF);
+
+ /*
+ * check if we can read the lookup table
+ */
+ hwp->writeDacReadAddr(hwp, 0x00);
+ for (i = 0; i < 6; i++) {
+ save->DAC[i] = hwp->readDacData(hwp);
+ switch (i % 3) {
+ case 0:
+ DebugF("DAC[0x%02x] = 0x%02x, ", i / 3, save->DAC[i]);
+ break;
+ case 1:
+ DebugF("0x%02x, ", save->DAC[i]);
+ break;
+ case 2:
+ DebugF("0x%02x\n", save->DAC[i]);
+ }
+ }
+
+ /*
+ * Check if we can read the palette -
+ * use foreground color to prevent flashing.
+ */
+ hwp->writeDacWriteAddr(hwp, 0x01);
+ for (i = 3; i < 6; i++)
+ hwp->writeDacData(hwp, ~save->DAC[i] & DAC_TEST_MASK);
+ hwp->writeDacReadAddr(hwp, 0x01);
+ for (i = 3; i < 6; i++) {
+ if (hwp->readDacData(hwp) != (~save->DAC[i] & DAC_TEST_MASK))
+ readError = TRUE;
+ }
+ hwp->writeDacWriteAddr(hwp, 0x01);
+ for (i = 3; i < 6; i++)
+ hwp->writeDacData(hwp, save->DAC[i]);
+
+ if (readError) {
+ /*
+ * save the default lookup table
+ */
+ memmove(save->DAC, defaultDAC, 768);
+ xf86DrvMsg(scrninfp->scrnIndex, X_WARNING,
+ "Cannot read colourmap from VGA. Will restore with default\n");
+ } else {
+ /* save the colourmap */
+ hwp->writeDacReadAddr(hwp, 0x02);
+ for (i = 6; i < 768; i++) {
+ save->DAC[i] = hwp->readDacData(hwp);
+ DACDelay(hwp);
+ switch (i % 3) {
+ case 0:
+ DebugF("DAC[0x%02x] = 0x%02x, ", i / 3, save->DAC[i]);
+ break;
+ case 1:
+ DebugF("0x%02x, ", save->DAC[i]);
+ break;
+ case 2:
+ DebugF("0x%02x\n", save->DAC[i]);
+ }
+ }
+ }
+
+ hwp->disablePalette(hwp);
+ hwp->cmapSaved = TRUE;
+#endif
+}
+
+/*
+ * vgaHWSave --
+ * save the current VGA state
+ */
+
+void
+vgaHWSave(ScrnInfoPtr scrninfp, vgaRegPtr save, int flags)
+{
+ if (save == NULL)
+ return;
+
+ if (flags & VGA_SR_CMAP)
+ vgaHWSaveColormap(scrninfp, save);
+
+ if (flags & VGA_SR_MODE)
+ vgaHWSaveMode(scrninfp, save);
+
+ if (flags & VGA_SR_FONTS)
+ vgaHWSaveFonts(scrninfp, save);
+}
+
+
+/*
+ * vgaHWInit --
+ * Handle the initialization, etc. of a screen.
+ * Return FALSE on failure.
+ */
+
+Bool
+vgaHWInit(ScrnInfoPtr scrninfp, DisplayModePtr mode)
+{
+ unsigned int i;
+ vgaHWPtr hwp;
+ vgaRegPtr regp;
+ int depth = scrninfp->depth;
+
+ /*
+ * make sure the vgaHWRec is allocated
+ */
+ if (!vgaHWGetHWRec(scrninfp))
+ return FALSE;
+ hwp = VGAHWPTR(scrninfp);
+ regp = &hwp->ModeReg;
+
+ /*
+ * compute correct Hsync & Vsync polarity
+ */
+ if ((mode->Flags & (V_PHSYNC | V_NHSYNC))
+ && (mode->Flags & (V_PVSYNC | V_NVSYNC)))
+ {
+ regp->MiscOutReg = 0x23;
+ if (mode->Flags & V_NHSYNC) regp->MiscOutReg |= 0x40;
+ if (mode->Flags & V_NVSYNC) regp->MiscOutReg |= 0x80;
+ }
+ else
+ {
+ int VDisplay = mode->VDisplay;
+ if (mode->Flags & V_DBLSCAN)
+ VDisplay *= 2;
+ if (mode->VScan > 1)
+ VDisplay *= mode->VScan;
+ if (VDisplay < 400)
+ regp->MiscOutReg = 0xA3; /* +hsync -vsync */
+ else if (VDisplay < 480)
+ regp->MiscOutReg = 0x63; /* -hsync +vsync */
+ else if (VDisplay < 768)
+ regp->MiscOutReg = 0xE3; /* -hsync -vsync */
+ else
+ regp->MiscOutReg = 0x23; /* +hsync +vsync */
+ }
+
+ regp->MiscOutReg |= (mode->ClockIndex & 0x03) << 2;
+
+ /*
+ * Time Sequencer
+ */
+ if (depth == 4)
+ regp->Sequencer[0] = 0x02;
+ else
+ regp->Sequencer[0] = 0x00;
+ if (mode->Flags & V_CLKDIV2)
+ regp->Sequencer[1] = 0x09;
+ else
+ regp->Sequencer[1] = 0x01;
+ if (depth == 1)
+ regp->Sequencer[2] = 1 << BIT_PLANE;
+ else
+ regp->Sequencer[2] = 0x0F;
+ regp->Sequencer[3] = 0x00; /* Font select */
+ if (depth < 8)
+ regp->Sequencer[4] = 0x06; /* Misc */
+ else
+ regp->Sequencer[4] = 0x0E; /* Misc */
+
+ /*
+ * CRTC Controller
+ */
+ regp->CRTC[0] = (mode->CrtcHTotal >> 3) - 5;
+ regp->CRTC[1] = (mode->CrtcHDisplay >> 3) - 1;
+ regp->CRTC[2] = (mode->CrtcHBlankStart >> 3) - 1;
+ regp->CRTC[3] = (((mode->CrtcHBlankEnd >> 3) - 1) & 0x1F) | 0x80;
+ i = (((mode->CrtcHSkew << 2) + 0x10) & ~0x1F);
+ if (i < 0x80)
+ regp->CRTC[3] |= i;
+ regp->CRTC[4] = (mode->CrtcHSyncStart >> 3);
+ regp->CRTC[5] = ((((mode->CrtcHBlankEnd >> 3) - 1) & 0x20) << 2)
+ | (((mode->CrtcHSyncEnd >> 3)) & 0x1F);
+ regp->CRTC[6] = (mode->CrtcVTotal - 2) & 0xFF;
+ regp->CRTC[7] = (((mode->CrtcVTotal - 2) & 0x100) >> 8)
+ | (((mode->CrtcVDisplay - 1) & 0x100) >> 7)
+ | ((mode->CrtcVSyncStart & 0x100) >> 6)
+ | (((mode->CrtcVBlankStart - 1) & 0x100) >> 5)
+ | 0x10
+ | (((mode->CrtcVTotal - 2) & 0x200) >> 4)
+ | (((mode->CrtcVDisplay - 1) & 0x200) >> 3)
+ | ((mode->CrtcVSyncStart & 0x200) >> 2);
+ regp->CRTC[8] = 0x00;
+ regp->CRTC[9] = (((mode->CrtcVBlankStart - 1) & 0x200) >> 4) | 0x40;
+ if (mode->Flags & V_DBLSCAN)
+ regp->CRTC[9] |= 0x80;
+ if (mode->VScan >= 32)
+ regp->CRTC[9] |= 0x1F;
+ else if (mode->VScan > 1)
+ regp->CRTC[9] |= mode->VScan - 1;
+ regp->CRTC[10] = 0x00;
+ regp->CRTC[11] = 0x00;
+ regp->CRTC[12] = 0x00;
+ regp->CRTC[13] = 0x00;
+ regp->CRTC[14] = 0x00;
+ regp->CRTC[15] = 0x00;
+ regp->CRTC[16] = mode->CrtcVSyncStart & 0xFF;
+ regp->CRTC[17] = (mode->CrtcVSyncEnd & 0x0F) | 0x20;
+ regp->CRTC[18] = (mode->CrtcVDisplay - 1) & 0xFF;
+ regp->CRTC[19] = scrninfp->displayWidth >> 4; /* just a guess */
+ regp->CRTC[20] = 0x00;
+ regp->CRTC[21] = (mode->CrtcVBlankStart - 1) & 0xFF;
+ regp->CRTC[22] = (mode->CrtcVBlankEnd - 1) & 0xFF;
+ if (depth < 8)
+ regp->CRTC[23] = 0xE3;
+ else
+ regp->CRTC[23] = 0xC3;
+ regp->CRTC[24] = 0xFF;
+
+ vgaHWHBlankKGA(mode, regp, 0, KGA_FIX_OVERSCAN | KGA_ENABLE_ON_ZERO);
+ vgaHWVBlankKGA(mode, regp, 0, KGA_FIX_OVERSCAN | KGA_ENABLE_ON_ZERO);
+
+ /*
+ * Theory resumes here....
+ */
+
+ /*
+ * Graphics Display Controller
+ */
+ regp->Graphics[0] = 0x00;
+ regp->Graphics[1] = 0x00;
+ regp->Graphics[2] = 0x00;
+ regp->Graphics[3] = 0x00;
+ if (depth == 1) {
+ regp->Graphics[4] = BIT_PLANE;
+ regp->Graphics[5] = 0x00;
+ } else {
+ regp->Graphics[4] = 0x00;
+ if (depth == 4)
+ regp->Graphics[5] = 0x02;
+ else
+ regp->Graphics[5] = 0x40;
+ }
+ regp->Graphics[6] = 0x05; /* only map 64k VGA memory !!!! */
+ regp->Graphics[7] = 0x0F;
+ regp->Graphics[8] = 0xFF;
+
+ if (depth == 1) {
+ /* Initialise the Mono map according to which bit-plane gets used */
+
+ Bool flipPixels = xf86GetFlipPixels();
+
+ for (i=0; i<16; i++)
+ if (((i & (1 << BIT_PLANE)) != 0) != flipPixels)
+ regp->Attribute[i] = WHITE_VALUE;
+ else
+ regp->Attribute[i] = BLACK_VALUE;
+
+ regp->Attribute[16] = 0x01; /* -VGA2- */ /* wrong for the ET4000 */
+ if (!hwp->ShowOverscan)
+ regp->Attribute[OVERSCAN] = OVERSCAN_VALUE; /* -VGA2- */
+ } else {
+ regp->Attribute[0] = 0x00; /* standard colormap translation */
+ regp->Attribute[1] = 0x01;
+ regp->Attribute[2] = 0x02;
+ regp->Attribute[3] = 0x03;
+ regp->Attribute[4] = 0x04;
+ regp->Attribute[5] = 0x05;
+ regp->Attribute[6] = 0x06;
+ regp->Attribute[7] = 0x07;
+ regp->Attribute[8] = 0x08;
+ regp->Attribute[9] = 0x09;
+ regp->Attribute[10] = 0x0A;
+ regp->Attribute[11] = 0x0B;
+ regp->Attribute[12] = 0x0C;
+ regp->Attribute[13] = 0x0D;
+ regp->Attribute[14] = 0x0E;
+ regp->Attribute[15] = 0x0F;
+ if (depth == 4)
+ regp->Attribute[16] = 0x81; /* wrong for the ET4000 */
+ else
+ regp->Attribute[16] = 0x41; /* wrong for the ET4000 */
+ /* Attribute[17] (overscan) initialised in vgaHWGetHWRec() */
+ }
+ regp->Attribute[18] = 0x0F;
+ regp->Attribute[19] = 0x00;
+ regp->Attribute[20] = 0x00;
+
+ return(TRUE);
+}
+
+ /*
+ * OK, so much for theory. Now, let's deal with the >real< world...
+ *
+ * The above CRTC settings are precise in theory, except that many, if not
+ * most, VGA clones fail to reset the blanking signal when the character or
+ * line counter reaches [HV]Total. In this case, the signal is only
+ * unblanked when the counter reaches [HV]BlankEnd (mod 64, 128 or 256 as
+ * the case may be) at the start of the >next< scanline or frame, which
+ * means only part of the screen shows. This affects how null overscans
+ * are to be implemented on such adapters.
+ *
+ * Henceforth, VGA cores that implement this broken, but unfortunately
+ * common, behaviour are to be designated as KGA's, in honour of Koen
+ * Gadeyne, whose zeal to eliminate overscans (read: fury) set in motion
+ * a series of events that led to the discovery of this problem.
+ *
+ * Some VGA's are KGA's only in the horizontal, or only in the vertical,
+ * some in both, others in neither. Don't let anyone tell you there is
+ * such a thing as a VGA "standard"... And, thank the Creator for the fact
+ * that Hilbert spaces are not yet implemented in this industry.
+ *
+ * The following implements a trick suggested by David Dawes. This sets
+ * [HV]BlankEnd to zero if the blanking interval does not already contain a
+ * 0-point, and decrements it by one otherwise. In the latter case, this
+ * will produce a left and/or top overscan which the colourmap code will
+ * (still) need to ensure is as close to black as possible. This will make
+ * the behaviour consistent across all chipsets, while allowing all
+ * chipsets to display the entire screen. Non-KGA drivers can ignore the
+ * following in their own copy of this code.
+ *
+ * -- TSI @ UQV, 1998.08.21
+ */
+
+CARD32
+vgaHWHBlankKGA(DisplayModePtr mode, vgaRegPtr regp, int nBits,
+ unsigned int Flags)
+{
+ int nExtBits = (nBits < 6) ? 0 : nBits - 6;
+ CARD32 ExtBits;
+ CARD32 ExtBitMask = ((1 << nExtBits) - 1) << 6;
+
+ regp->CRTC[3] = (regp->CRTC[3] & ~0x1F)
+ | (((mode->CrtcHBlankEnd >> 3) - 1) & 0x1F);
+ regp->CRTC[5] = (regp->CRTC[5] & ~0x80)
+ | ((((mode->CrtcHBlankEnd >> 3) - 1) & 0x20) << 2);
+ ExtBits = ((mode->CrtcHBlankEnd >> 3) - 1) & ExtBitMask;
+
+ /* First the horizontal case */
+ if ((Flags & KGA_FIX_OVERSCAN)
+ && ((mode->CrtcHBlankEnd >> 3) == (mode->CrtcHTotal >> 3)))
+ {
+ int i = (regp->CRTC[3] & 0x1F)
+ | ((regp->CRTC[5] & 0x80) >> 2)
+ | ExtBits;
+ if (Flags & KGA_ENABLE_ON_ZERO) {
+ if ((i-- > (((mode->CrtcHBlankStart >> 3) - 1)
+ & (0x3F | ExtBitMask)))
+ && (mode->CrtcHBlankEnd == mode->CrtcHTotal))
+ i = 0;
+ } else if (Flags & KGA_BE_TOT_DEC)
+ i--;
+ regp->CRTC[3] = (regp->CRTC[3] & ~0x1F) | (i & 0x1F);
+ regp->CRTC[5] = (regp->CRTC[5] & ~0x80) | ((i << 2) & 0x80);
+ ExtBits = i & ExtBitMask;
+ }
+ return ExtBits >> 6;
+}
+
+ /*
+ * The vertical case is a little trickier. Some VGA's ignore bit 0x80 of
+ * CRTC[22]. Also, in some cases, a zero CRTC[22] will still blank the
+ * very first scanline in a double- or multi-scanned mode. This last case
+ * needs further investigation.
+ */
+CARD32
+vgaHWVBlankKGA(DisplayModePtr mode, vgaRegPtr regp, int nBits,
+ unsigned int Flags)
+{
+ CARD32 ExtBits;
+ CARD32 nExtBits = (nBits < 8) ? 0 : (nBits - 8);
+ CARD32 ExtBitMask = ((1 << nExtBits) - 1) << 8;
+ /* If width is not known nBits should be 0. In this
+ * case BitMask is set to 0 so we can check for it. */
+ CARD32 BitMask = (nBits < 7) ? 0 : ((1 << nExtBits) - 1);
+ int VBlankStart = (mode->CrtcVBlankStart - 1) & 0xFF;
+ regp->CRTC[22] = (mode->CrtcVBlankEnd - 1) & 0xFF;
+ ExtBits = (mode->CrtcVBlankEnd - 1) & ExtBitMask;
+
+ if ((Flags & KGA_FIX_OVERSCAN)
+ && (mode->CrtcVBlankEnd == mode->CrtcVTotal))
+ /* Null top overscan */
+ {
+ int i = regp->CRTC[22] | ExtBits;
+ if (Flags & KGA_ENABLE_ON_ZERO) {
+ if (((BitMask && ((i & BitMask) > (VBlankStart & BitMask)))
+ || ((i > VBlankStart) && /* 8-bit case */
+ ((i & 0x7F) > (VBlankStart & 0x7F)))) && /* 7-bit case */
+ !(regp->CRTC[9] & 0x9F)) /* 1 scanline/row */
+ i = 0;
+ else
+ i = (i - 1);
+ } else if (Flags & KGA_BE_TOT_DEC)
+ i = (i - 1);
+
+ regp->CRTC[22] = i & 0xFF;
+ ExtBits = i & 0xFF00;
+ }
+ return ExtBits >> 8;
+}
+
+/*
+ * these are some more hardware specific helpers, formerly in vga.c
+ */
+static void
+vgaHWGetHWRecPrivate(void)
+{
+ if (vgaHWPrivateIndex < 0)
+ vgaHWPrivateIndex = xf86AllocateScrnInfoPrivateIndex();
+ return;
+}
+
+
+static void
+vgaHWFreeRegs(vgaRegPtr regp)
+{
+ if (regp->CRTC)
+ free(regp->CRTC);
+
+ regp->CRTC =
+ regp->Sequencer =
+ regp->Graphics =
+ regp->Attribute = NULL;
+
+ regp->numCRTC =
+ regp->numSequencer =
+ regp->numGraphics =
+ regp->numAttribute = 0;
+}
+
+
+
+static Bool
+vgaHWAllocRegs(vgaRegPtr regp)
+{
+ unsigned char *buf;
+
+ if ((regp->numCRTC + regp->numSequencer + regp->numGraphics +
+ regp->numAttribute) == 0)
+ return FALSE;
+
+ buf = calloc(regp->numCRTC +
+ regp->numSequencer +
+ regp->numGraphics +
+ regp->numAttribute, 1);
+ if (!buf)
+ return FALSE;
+
+ regp->CRTC = buf;
+ regp->Sequencer = regp->CRTC + regp->numCRTC;
+ regp->Graphics = regp->Sequencer + regp->numSequencer;
+ regp->Attribute = regp->Graphics + regp->numGraphics;
+
+ return TRUE;
+}
+
+
+Bool
+vgaHWAllocDefaultRegs(vgaRegPtr regp)
+{
+ regp->numCRTC = VGA_NUM_CRTC;
+ regp->numSequencer = VGA_NUM_SEQ;
+ regp->numGraphics = VGA_NUM_GFX;
+ regp->numAttribute = VGA_NUM_ATTR;
+
+ return vgaHWAllocRegs(regp);
+}
+
+
+Bool
+vgaHWSetRegCounts(ScrnInfoPtr scrp, int numCRTC, int numSequencer,
+ int numGraphics, int numAttribute)
+{
+#define VGAHWMINNUM(regtype) \
+ ((newMode.num##regtype < regp->num##regtype) ? \
+ (newMode.num##regtype) : (regp->num##regtype))
+#define VGAHWCOPYREGSET(regtype) \
+ memcpy (newMode.regtype, regp->regtype, VGAHWMINNUM(regtype))
+
+ vgaRegRec newMode, newSaved;
+ vgaRegPtr regp;
+
+ regp = &VGAHWPTR(scrp)->ModeReg;
+ memcpy (&newMode, regp, sizeof(vgaRegRec));
+
+ /* allocate space for new registers */
+
+ regp = &newMode;
+ regp->numCRTC = numCRTC;
+ regp->numSequencer = numSequencer;
+ regp->numGraphics = numGraphics;
+ regp->numAttribute = numAttribute;
+ if (!vgaHWAllocRegs(regp))
+ return FALSE;
+
+ regp = &VGAHWPTR(scrp)->SavedReg;
+ memcpy (&newSaved, regp, sizeof(vgaRegRec));
+
+ regp = &newSaved;
+ regp->numCRTC = numCRTC;
+ regp->numSequencer = numSequencer;
+ regp->numGraphics = numGraphics;
+ regp->numAttribute = numAttribute;
+ if (!vgaHWAllocRegs(regp)) {
+ vgaHWFreeRegs(&newMode);
+ return FALSE;
+ }
+
+ /* allocations succeeded, copy register data into new space */
+
+ regp = &VGAHWPTR(scrp)->ModeReg;
+ VGAHWCOPYREGSET(CRTC);
+ VGAHWCOPYREGSET(Sequencer);
+ VGAHWCOPYREGSET(Graphics);
+ VGAHWCOPYREGSET(Attribute);
+
+ regp = &VGAHWPTR(scrp)->SavedReg;
+ VGAHWCOPYREGSET(CRTC);
+ VGAHWCOPYREGSET(Sequencer);
+ VGAHWCOPYREGSET(Graphics);
+ VGAHWCOPYREGSET(Attribute);
+
+ /* free old register arrays */
+
+ regp = &VGAHWPTR(scrp)->ModeReg;
+ vgaHWFreeRegs(regp);
+ memcpy(regp, &newMode, sizeof(vgaRegRec));
+
+ regp = &VGAHWPTR(scrp)->SavedReg;
+ vgaHWFreeRegs(regp);
+ memcpy(regp, &newSaved, sizeof(vgaRegRec));
+
+ return TRUE;
+
+#undef VGAHWMINNUM
+#undef VGAHWCOPYREGSET
+}
+
+
+Bool
+vgaHWCopyReg(vgaRegPtr dst, vgaRegPtr src)
+{
+ vgaHWFreeRegs(dst);
+
+ memcpy(dst, src, sizeof(vgaRegRec));
+
+ if (!vgaHWAllocRegs(dst))
+ return FALSE;
+
+ memcpy(dst->CRTC, src->CRTC, src->numCRTC);
+ memcpy(dst->Sequencer, src->Sequencer, src->numSequencer);
+ memcpy(dst->Graphics, src->Graphics, src->numGraphics);
+ memcpy(dst->Attribute, src->Attribute, src->numAttribute);
+
+ return TRUE;
+}
+
+
+Bool
+vgaHWGetHWRec(ScrnInfoPtr scrp)
+{
+ vgaRegPtr regp;
+ vgaHWPtr hwp;
+ int i;
+
+ /*
+ * Let's make sure that the private exists and allocate one.
+ */
+ vgaHWGetHWRecPrivate();
+ /*
+ * New privates are always set to NULL, so we can check if the allocation
+ * has already been done.
+ */
+ if (VGAHWPTR(scrp))
+ return TRUE;
+ hwp = VGAHWPTRLVAL(scrp) = xnfcalloc(sizeof(vgaHWRec), 1);
+ regp = &VGAHWPTR(scrp)->ModeReg;
+
+ if ((!vgaHWAllocDefaultRegs(&VGAHWPTR(scrp)->SavedReg)) ||
+ (!vgaHWAllocDefaultRegs(&VGAHWPTR(scrp)->ModeReg))) {
+ free(hwp);
+ return FALSE;
+ }
+
+ if (scrp->bitsPerPixel == 1) {
+ rgb blackColour = scrp->display->blackColour,
+ whiteColour = scrp->display->whiteColour;
+
+ if (blackColour.red > 0x3F) blackColour.red = 0x3F;
+ if (blackColour.green > 0x3F) blackColour.green = 0x3F;
+ if (blackColour.blue > 0x3F) blackColour.blue = 0x3F;
+
+ if (whiteColour.red > 0x3F) whiteColour.red = 0x3F;
+ if (whiteColour.green > 0x3F) whiteColour.green = 0x3F;
+ if (whiteColour.blue > 0x3F) whiteColour.blue = 0x3F;
+
+ if ((blackColour.red == whiteColour.red ) &&
+ (blackColour.green == whiteColour.green) &&
+ (blackColour.blue == whiteColour.blue )) {
+ blackColour.red ^= 0x3F;
+ blackColour.green ^= 0x3F;
+ blackColour.blue ^= 0x3F;
+ }
+
+ /*
+ * initialize default colormap for monochrome
+ */
+ for (i=0; i<3; i++) regp->DAC[i] = 0x00;
+ for (i=3; i<768; i++) regp->DAC[i] = 0x3F;
+ i = BLACK_VALUE * 3;
+ regp->DAC[i++] = blackColour.red;
+ regp->DAC[i++] = blackColour.green;
+ regp->DAC[i] = blackColour.blue;
+ i = WHITE_VALUE * 3;
+ regp->DAC[i++] = whiteColour.red;
+ regp->DAC[i++] = whiteColour.green;
+ regp->DAC[i] = whiteColour.blue;
+ i = OVERSCAN_VALUE * 3;
+ regp->DAC[i++] = 0x00;
+ regp->DAC[i++] = 0x00;
+ regp->DAC[i] = 0x00;
+ } else {
+ /* Set all colours to black */
+ for (i=0; i<768; i++) regp->DAC[i] = 0x00;
+ /* ... and the overscan */
+ if (scrp->depth >= 4)
+ regp->Attribute[OVERSCAN] = 0xFF;
+ }
+ if (xf86FindOption(scrp->confScreen->options, "ShowOverscan")) {
+ xf86MarkOptionUsedByName(scrp->confScreen->options, "ShowOverscan");
+ xf86DrvMsg(scrp->scrnIndex, X_CONFIG, "Showing overscan area\n");
+ regp->DAC[765] = 0x3F;
+ regp->DAC[766] = 0x00;
+ regp->DAC[767] = 0x3F;
+ regp->Attribute[OVERSCAN] = 0xFF;
+ hwp->ShowOverscan = TRUE;
+ } else
+ hwp->ShowOverscan = FALSE;
+
+ hwp->paletteEnabled = FALSE;
+ hwp->cmapSaved = FALSE;
+ hwp->MapSize = 0;
+ hwp->pScrn = scrp;
+
+ /* Initialise the function pointers with the standard VGA versions */
+ vgaHWSetStdFuncs(hwp);
+
+ hwp->PIOOffset = scrp->domainIOBase;
+ hwp->dev = xf86GetPciInfoForEntity(scrp->entityList[0]);
+
+ return TRUE;
+}
+
+
+void
+vgaHWFreeHWRec(ScrnInfoPtr scrp)
+{
+ if (vgaHWPrivateIndex >= 0) {
+ vgaHWPtr hwp = VGAHWPTR(scrp);
+
+ if (!hwp)
+ return;
+
+ free(hwp->FontInfo1);
+ free(hwp->FontInfo2);
+ free(hwp->TextInfo);
+
+ vgaHWFreeRegs (&hwp->ModeReg);
+ vgaHWFreeRegs (&hwp->SavedReg);
+
+ free(hwp);
+ VGAHWPTRLVAL(scrp) = NULL;
+ }
+}
+
+
+Bool
+vgaHWMapMem(ScrnInfoPtr scrp)
+{
+ vgaHWPtr hwp = VGAHWPTR(scrp);
+ int scr_index = scrp->scrnIndex;
+
+ if (hwp->Base)
+ return TRUE;
+
+ /* If not set, initialise with the defaults */
+ if (hwp->MapSize == 0)
+ hwp->MapSize = VGA_DEFAULT_MEM_SIZE;
+ if (hwp->MapPhys == 0)
+ hwp->MapPhys = VGA_DEFAULT_PHYS_ADDR;
+
+ /*
+ * Map as VIDMEM_MMIO_32BIT because WC
+ * is bad when there is page flipping.
+ * XXX This is not correct but we do it
+ * for now.
+ */
+ DebugF("Mapping VGAMem\n");
+ hwp->Base = xf86MapDomainMemory(scr_index, VIDMEM_MMIO_32BIT, hwp->dev,
+ hwp->MapPhys, hwp->MapSize);
+ return hwp->Base != NULL;
+}
+
+
+void
+vgaHWUnmapMem(ScrnInfoPtr scrp)
+{
+ vgaHWPtr hwp = VGAHWPTR(scrp);
+ int scr_index = scrp->scrnIndex;
+
+ if (hwp->Base == NULL)
+ return;
+
+ DebugF("Unmapping VGAMem\n");
+ xf86UnMapVidMem(scr_index, hwp->Base, hwp->MapSize);
+ hwp->Base = NULL;
+}
+
+int
+vgaHWGetIndex(void)
+{
+ return vgaHWPrivateIndex;
+}
+
+
+void
+vgaHWGetIOBase(vgaHWPtr hwp)
+{
+ hwp->IOBase = (hwp->readMiscOut(hwp) & 0x01) ?
+ VGA_IOBASE_COLOR : VGA_IOBASE_MONO;
+ xf86DrvMsgVerb(hwp->pScrn->scrnIndex, X_INFO, 3,
+ "vgaHWGetIOBase: hwp->IOBase is 0x%04x, hwp->PIOOffset is 0x%04lx\n",
+ hwp->IOBase, hwp->PIOOffset);
+}
+
+
+void
+vgaHWLock(vgaHWPtr hwp)
+{
+ /* Protect CRTC[0-7] */
+ hwp->writeCrtc(hwp, 0x11, hwp->readCrtc(hwp, 0x11) | 0x80);
+}
+
+void
+vgaHWUnlock(vgaHWPtr hwp)
+{
+ /* Unprotect CRTC[0-7] */
+ hwp->writeCrtc(hwp, 0x11, hwp->readCrtc(hwp, 0x11) & ~0x80);
+}
+
+
+void
+vgaHWEnable(vgaHWPtr hwp)
+{
+ hwp->writeEnable(hwp, hwp->readEnable(hwp) | 0x01);
+}
+
+
+void
+vgaHWDisable(vgaHWPtr hwp)
+{
+ hwp->writeEnable(hwp, hwp->readEnable(hwp) & ~0x01);
+}
+
+
+static void
+vgaHWLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors,
+ VisualPtr pVisual)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ int i, index;
+
+ for (i = 0; i < numColors; i++) {
+ index = indices[i];
+ hwp->writeDacWriteAddr(hwp, index);
+ DACDelay(hwp);
+ hwp->writeDacData(hwp, colors[index].red);
+ DACDelay(hwp);
+ hwp->writeDacData(hwp, colors[index].green);
+ DACDelay(hwp);
+ hwp->writeDacData(hwp, colors[index].blue);
+ DACDelay(hwp);
+ }
+
+ /* This shouldn't be necessary, but we'll play safe. */
+ hwp->disablePalette(hwp);
+}
+
+
+static void
+vgaHWSetOverscan(ScrnInfoPtr pScrn, int overscan)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+
+ if (overscan < 0 || overscan > 255)
+ return;
+
+ hwp->enablePalette(hwp);
+ hwp->writeAttr(hwp, OVERSCAN, overscan);
+
+#ifdef DEBUGOVERSCAN
+ {
+ int ov = hwp->readAttr(hwp, OVERSCAN);
+ int red, green, blue;
+
+ hwp->writeDacReadAddr(hwp, ov);
+ red = hwp->readDacData(hwp);
+ green = hwp->readDacData(hwp);
+ blue = hwp->readDacData(hwp);
+ ErrorF("Overscan index is 0x%02x, colours are #%02x%02x%02x\n",
+ ov, red, green, blue);
+ }
+#endif
+
+ hwp->disablePalette(hwp);
+}
+
+
+Bool
+vgaHWHandleColormaps(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+
+ if (pScrn->depth > 1 && pScrn->depth <= 8) {
+ return xf86HandleColormaps(pScreen, 1 << pScrn->depth,
+ pScrn->rgbBits, vgaHWLoadPalette,
+ pScrn->depth > 4 ? vgaHWSetOverscan : NULL,
+ CMAP_RELOAD_ON_MODE_SWITCH);
+ }
+ return TRUE;
+}
+
+/* ----------------------- DDC support ------------------------*/
+/*
+ * Adjust v_active, v_blank, v_sync, v_sync_end, v_blank_end, v_total
+ * to read out EDID at a faster rate. Allowed maximum is 25kHz with
+ * 20 usec v_sync active. Set positive v_sync polarity, turn off lightpen
+ * readback, enable access to cr00-cr07.
+ */
+
+/* vertical timings */
+#define DISPLAY_END 0x04
+#define BLANK_START DISPLAY_END
+#define SYNC_START BLANK_START
+#define SYNC_END 0x09
+#define BLANK_END SYNC_END
+#define V_TOTAL BLANK_END
+/* this function doesn't have to be reentrant for our purposes */
+struct _vgaDdcSave {
+ unsigned char cr03;
+ unsigned char cr06;
+ unsigned char cr07;
+ unsigned char cr09;
+ unsigned char cr10;
+ unsigned char cr11;
+ unsigned char cr12;
+ unsigned char cr15;
+ unsigned char cr16;
+ unsigned char msr;
+};
+
+void
+vgaHWddc1SetSpeed(ScrnInfoPtr pScrn, xf86ddcSpeed speed)
+{
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ unsigned char tmp;
+ struct _vgaDdcSave* save;
+ switch (speed) {
+ case DDC_FAST:
+
+ if (hwp->ddc != NULL) break;
+ hwp->ddc = xnfcalloc(sizeof(struct _vgaDdcSave),1);
+ save = (struct _vgaDdcSave *)hwp->ddc;
+ /* Lightpen register disable - allow access to cr10 & 11; just in case */
+ save->cr03 = hwp->readCrtc(hwp, 0x03);
+ hwp->writeCrtc(hwp,0x03,(save->cr03 |0x80));
+ save->cr12 = hwp->readCrtc(hwp, 0x12);
+ hwp->writeCrtc(hwp,0x12,DISPLAY_END);
+ save->cr15 = hwp->readCrtc(hwp, 0x15);
+ hwp->writeCrtc(hwp,0x15,BLANK_START);
+ save->cr10 = hwp->readCrtc(hwp, 0x10);
+ hwp->writeCrtc(hwp,0x10,SYNC_START);
+ save->cr11 = hwp->readCrtc(hwp, 0x11);
+ /* unprotect group 1 registers; just in case ...*/
+ hwp->writeCrtc(hwp,0x11,((save->cr11 & 0x70) | SYNC_END));
+ save->cr16 = hwp->readCrtc(hwp, 0x16);
+ hwp->writeCrtc(hwp,0x16,BLANK_END);
+ save->cr06 = hwp->readCrtc(hwp, 0x06);
+ hwp->writeCrtc(hwp,0x06,V_TOTAL);
+ /* all values have less than 8 bit - mask out 9th and 10th bits */
+ save->cr09 = hwp->readCrtc(hwp, 0x09);
+ hwp->writeCrtc(hwp,0x09,(save->cr09 &0xDF));
+ save->cr07 = hwp->readCrtc(hwp, 0x07);
+ hwp->writeCrtc(hwp,0x07,(save->cr07 &0x10));
+ /* vsync polarity negativ & ensure a 25MHz clock */
+ save->msr = hwp->readMiscOut(hwp);
+ hwp->writeMiscOut(hwp,((save->msr & 0xF3) | 0x80));
+ break;
+ case DDC_SLOW:
+ if (hwp->ddc == NULL) break;
+ save = (struct _vgaDdcSave *)hwp->ddc;
+ hwp->writeMiscOut(hwp,save->msr);
+ hwp->writeCrtc(hwp,0x07,save->cr07);
+ tmp = hwp->readCrtc(hwp, 0x09);
+ hwp->writeCrtc(hwp,0x09,((save->cr09 & 0x20) | (tmp & 0xDF)));
+ hwp->writeCrtc(hwp,0x06,save->cr06);
+ hwp->writeCrtc(hwp,0x16,save->cr16);
+ hwp->writeCrtc(hwp,0x11,save->cr11);
+ hwp->writeCrtc(hwp,0x10,save->cr10);
+ hwp->writeCrtc(hwp,0x15,save->cr15);
+ hwp->writeCrtc(hwp,0x12,save->cr12);
+ hwp->writeCrtc(hwp,0x03,save->cr03);
+ free(save);
+ hwp->ddc = NULL;
+ break;
+ default:
+ break;
+ }
+}
+
+DDC1SetSpeedProc
+vgaHWddc1SetSpeedWeak(void)
+{
+ return vgaHWddc1SetSpeed;
+}
+
+SaveScreenProcPtr vgaHWSaveScreenWeak(void)
+{
+ return vgaHWSaveScreen;
+}
diff --git a/xorg-server/hw/xfree86/xaa/xaaBitBlt.c b/xorg-server/hw/xfree86/xaa/xaaBitBlt.c
index ebba74e55..b1fda1cd6 100644
--- a/xorg-server/hw/xfree86/xaa/xaaBitBlt.c
+++ b/xorg-server/hw/xfree86/xaa/xaaBitBlt.c
@@ -1,221 +1,221 @@
-
-/*
- This is a lighter version of cfbBitBlt. We calculate the boxes
- when accelerating pixmap->screen and screen->screen copies.
- We also pass the GC to the doBitBlt function so that it has access
- to the fg and bg so CopyPlane can use this.
-*/
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "misc.h"
-#include "xf86.h"
-#include "xf86_OSproc.h"
-
-#include <X11/X.h>
-#include "mi.h"
-#include "pixmapstr.h"
-#include "gcstruct.h"
-#include "windowstr.h"
-#include "xaalocal.h"
-
-
-RegionPtr
-XAABitBlt(
- DrawablePtr pSrcDrawable,
- DrawablePtr pDstDrawable,
- GC *pGC,
- int srcx, int srcy,
- int width, int height,
- int dstx, int dsty,
- void (*doBitBlt)(DrawablePtr, DrawablePtr, GCPtr, RegionPtr, DDXPointPtr),
- unsigned long bitPlane )
-{
-
- RegionPtr prgnSrcClip = NULL; /* may be a new region, or just a copy */
- RegionPtr prgnExposed;
- Bool freeSrcClip = FALSE;
- RegionRec rgnDst;
- DDXPointPtr pptSrc, ppt;
- DDXPointRec origDest;
- BoxPtr pbox;
- BoxRec fastBox;
- int i, dx, dy, numRects;
- xRectangle origSource;
- int fastClip = 0; /* for fast clipping with pixmap source */
- int fastExpose = 0; /* for fast exposures with pixmap source */
-
- origSource.x = srcx;
- origSource.y = srcy;
- origSource.width = width;
- origSource.height = height;
- origDest.x = dstx;
- origDest.y = dsty;
-
- if((pSrcDrawable != pDstDrawable) &&
- pSrcDrawable->pScreen->SourceValidate) {
- (*pSrcDrawable->pScreen->SourceValidate) (
- pSrcDrawable, srcx, srcy, width, height);
- }
-
- srcx += pSrcDrawable->x;
- srcy += pSrcDrawable->y;
-
- /* clip the source */
- if (pSrcDrawable->type == DRAWABLE_PIXMAP) {
- if ((pSrcDrawable == pDstDrawable) && (pGC->clientClipType == CT_NONE))
- prgnSrcClip = pGC->pCompositeClip;
- else
- fastClip = 1;
- } else { /* Window */
- if (pGC->subWindowMode == IncludeInferiors) {
- if (!((WindowPtr) pSrcDrawable)->parent) {
- /*
- * special case bitblt from root window in
- * IncludeInferiors mode; just like from a pixmap
- */
- fastClip = 1;
- } else if ((pSrcDrawable == pDstDrawable) &&
- (pGC->clientClipType == CT_NONE)) {
- prgnSrcClip = pGC->pCompositeClip;
- } else {
- prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable);
- freeSrcClip = TRUE;
- }
- } else {
- prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList;
- }
- }
-
- fastBox.x1 = srcx;
- fastBox.y1 = srcy;
- fastBox.x2 = srcx + width;
- fastBox.y2 = srcy + height;
-
- /* Don't create a source region if we are doing a fast clip */
- if (fastClip) {
- fastExpose = 1;
- /*
- * clip the source; if regions extend beyond the source size,
- * make sure exposure events get sent
- */
- if (fastBox.x1 < pSrcDrawable->x) {
- fastBox.x1 = pSrcDrawable->x;
- fastExpose = 0;
- }
- if (fastBox.y1 < pSrcDrawable->y) {
- fastBox.y1 = pSrcDrawable->y;
- fastExpose = 0;
- }
- if (fastBox.x2 > pSrcDrawable->x + (int) pSrcDrawable->width) {
- fastBox.x2 = pSrcDrawable->x + (int) pSrcDrawable->width;
- fastExpose = 0;
- }
- if (fastBox.y2 > pSrcDrawable->y + (int) pSrcDrawable->height) {
- fastBox.y2 = pSrcDrawable->y + (int) pSrcDrawable->height;
- fastExpose = 0;
- }
- } else {
- REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
- REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, prgnSrcClip);
- }
-
- dstx += pDstDrawable->x;
- dsty += pDstDrawable->y;
-
- if (pDstDrawable->type == DRAWABLE_WINDOW) {
- if (!((WindowPtr)pDstDrawable)->realized) {
- if (!fastClip)
- REGION_UNINIT(pGC->pScreen, &rgnDst);
- if (freeSrcClip)
- REGION_DESTROY(pGC->pScreen, prgnSrcClip);
- return NULL;
- }
- }
-
- dx = srcx - dstx;
- dy = srcy - dsty;
-
- /* Translate and clip the dst to the destination composite clip */
- if (fastClip) {
- RegionPtr cclip;
-
- /* Translate the region directly */
- fastBox.x1 -= dx;
- fastBox.x2 -= dx;
- fastBox.y1 -= dy;
- fastBox.y2 -= dy;
-
- /* If the destination composite clip is one rectangle we can
- do the clip directly. Otherwise we have to create a full
- blown region and call intersect */
-
- cclip = pGC->pCompositeClip;
- if (REGION_NUM_RECTS(cclip) == 1) {
- BoxPtr pBox = REGION_RECTS(cclip);
-
- if (fastBox.x1 < pBox->x1) fastBox.x1 = pBox->x1;
- if (fastBox.x2 > pBox->x2) fastBox.x2 = pBox->x2;
- if (fastBox.y1 < pBox->y1) fastBox.y1 = pBox->y1;
- if (fastBox.y2 > pBox->y2) fastBox.y2 = pBox->y2;
-
- /* Check to see if the region is empty */
- if (fastBox.x1 >= fastBox.x2 || fastBox.y1 >= fastBox.y2) {
- REGION_NULL(pGC->pScreen, &rgnDst);
- } else {
- REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
- }
- } else {
- /* We must turn off fastClip now, since we must create
- a full blown region. It is intersected with the
- composite clip below. */
- fastClip = 0;
- REGION_INIT(pGC->pScreen, &rgnDst, &fastBox,1);
- }
- } else {
- REGION_TRANSLATE(pGC->pScreen, &rgnDst, -dx, -dy);
- }
-
- if (!fastClip) {
- REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst,
- pGC->pCompositeClip);
- }
-
- /* Do bit blitting */
- numRects = REGION_NUM_RECTS(&rgnDst);
- if (numRects && width && height) {
- if(!(pptSrc = (DDXPointPtr)xalloc(numRects *
- sizeof(DDXPointRec)))) {
- REGION_UNINIT(pGC->pScreen, &rgnDst);
- if (freeSrcClip)
- REGION_DESTROY(pGC->pScreen, prgnSrcClip);
- return NULL;
- }
- pbox = REGION_RECTS(&rgnDst);
- ppt = pptSrc;
- for (i = numRects; --i >= 0; pbox++, ppt++) {
- ppt->x = pbox->x1 + dx;
- ppt->y = pbox->y1 + dy;
- }
-
- (*doBitBlt) (pSrcDrawable, pDstDrawable, pGC, &rgnDst, pptSrc);
- xfree(pptSrc);
- }
-
- prgnExposed = NULL;
- if (pGC->fExpose) {
- /* Pixmap sources generate a NoExposed (we return NULL to do this) */
- if (!fastExpose)
- prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
- origSource.x, origSource.y,
- (int)origSource.width,
- (int)origSource.height,
- origDest.x, origDest.y, bitPlane);
- }
- REGION_UNINIT(pGC->pScreen, &rgnDst);
- if (freeSrcClip)
- REGION_DESTROY(pGC->pScreen, prgnSrcClip);
- return prgnExposed;
-}
+
+/*
+ This is a lighter version of cfbBitBlt. We calculate the boxes
+ when accelerating pixmap->screen and screen->screen copies.
+ We also pass the GC to the doBitBlt function so that it has access
+ to the fg and bg so CopyPlane can use this.
+*/
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include <X11/X.h>
+#include "mi.h"
+#include "pixmapstr.h"
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "xaalocal.h"
+
+
+RegionPtr
+XAABitBlt(
+ DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GC *pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty,
+ void (*doBitBlt)(DrawablePtr, DrawablePtr, GCPtr, RegionPtr, DDXPointPtr),
+ unsigned long bitPlane )
+{
+
+ RegionPtr prgnSrcClip = NULL; /* may be a new region, or just a copy */
+ RegionPtr prgnExposed;
+ Bool freeSrcClip = FALSE;
+ RegionRec rgnDst;
+ DDXPointPtr pptSrc, ppt;
+ DDXPointRec origDest;
+ BoxPtr pbox;
+ BoxRec fastBox;
+ int i, dx, dy, numRects;
+ xRectangle origSource;
+ int fastClip = 0; /* for fast clipping with pixmap source */
+ int fastExpose = 0; /* for fast exposures with pixmap source */
+
+ origSource.x = srcx;
+ origSource.y = srcy;
+ origSource.width = width;
+ origSource.height = height;
+ origDest.x = dstx;
+ origDest.y = dsty;
+
+ if((pSrcDrawable != pDstDrawable) &&
+ pSrcDrawable->pScreen->SourceValidate) {
+ (*pSrcDrawable->pScreen->SourceValidate) (
+ pSrcDrawable, srcx, srcy, width, height);
+ }
+
+ srcx += pSrcDrawable->x;
+ srcy += pSrcDrawable->y;
+
+ /* clip the source */
+ if (pSrcDrawable->type == DRAWABLE_PIXMAP) {
+ if ((pSrcDrawable == pDstDrawable) && (pGC->clientClipType == CT_NONE))
+ prgnSrcClip = pGC->pCompositeClip;
+ else
+ fastClip = 1;
+ } else { /* Window */
+ if (pGC->subWindowMode == IncludeInferiors) {
+ if (!((WindowPtr) pSrcDrawable)->parent) {
+ /*
+ * special case bitblt from root window in
+ * IncludeInferiors mode; just like from a pixmap
+ */
+ fastClip = 1;
+ } else if ((pSrcDrawable == pDstDrawable) &&
+ (pGC->clientClipType == CT_NONE)) {
+ prgnSrcClip = pGC->pCompositeClip;
+ } else {
+ prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable);
+ freeSrcClip = TRUE;
+ }
+ } else {
+ prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList;
+ }
+ }
+
+ fastBox.x1 = srcx;
+ fastBox.y1 = srcy;
+ fastBox.x2 = srcx + width;
+ fastBox.y2 = srcy + height;
+
+ /* Don't create a source region if we are doing a fast clip */
+ if (fastClip) {
+ fastExpose = 1;
+ /*
+ * clip the source; if regions extend beyond the source size,
+ * make sure exposure events get sent
+ */
+ if (fastBox.x1 < pSrcDrawable->x) {
+ fastBox.x1 = pSrcDrawable->x;
+ fastExpose = 0;
+ }
+ if (fastBox.y1 < pSrcDrawable->y) {
+ fastBox.y1 = pSrcDrawable->y;
+ fastExpose = 0;
+ }
+ if (fastBox.x2 > pSrcDrawable->x + (int) pSrcDrawable->width) {
+ fastBox.x2 = pSrcDrawable->x + (int) pSrcDrawable->width;
+ fastExpose = 0;
+ }
+ if (fastBox.y2 > pSrcDrawable->y + (int) pSrcDrawable->height) {
+ fastBox.y2 = pSrcDrawable->y + (int) pSrcDrawable->height;
+ fastExpose = 0;
+ }
+ } else {
+ REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
+ REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst, prgnSrcClip);
+ }
+
+ dstx += pDstDrawable->x;
+ dsty += pDstDrawable->y;
+
+ if (pDstDrawable->type == DRAWABLE_WINDOW) {
+ if (!((WindowPtr)pDstDrawable)->realized) {
+ if (!fastClip)
+ REGION_UNINIT(pGC->pScreen, &rgnDst);
+ if (freeSrcClip)
+ REGION_DESTROY(pGC->pScreen, prgnSrcClip);
+ return NULL;
+ }
+ }
+
+ dx = srcx - dstx;
+ dy = srcy - dsty;
+
+ /* Translate and clip the dst to the destination composite clip */
+ if (fastClip) {
+ RegionPtr cclip;
+
+ /* Translate the region directly */
+ fastBox.x1 -= dx;
+ fastBox.x2 -= dx;
+ fastBox.y1 -= dy;
+ fastBox.y2 -= dy;
+
+ /* If the destination composite clip is one rectangle we can
+ do the clip directly. Otherwise we have to create a full
+ blown region and call intersect */
+
+ cclip = pGC->pCompositeClip;
+ if (REGION_NUM_RECTS(cclip) == 1) {
+ BoxPtr pBox = REGION_RECTS(cclip);
+
+ if (fastBox.x1 < pBox->x1) fastBox.x1 = pBox->x1;
+ if (fastBox.x2 > pBox->x2) fastBox.x2 = pBox->x2;
+ if (fastBox.y1 < pBox->y1) fastBox.y1 = pBox->y1;
+ if (fastBox.y2 > pBox->y2) fastBox.y2 = pBox->y2;
+
+ /* Check to see if the region is empty */
+ if (fastBox.x1 >= fastBox.x2 || fastBox.y1 >= fastBox.y2) {
+ REGION_NULL(pGC->pScreen, &rgnDst);
+ } else {
+ REGION_INIT(pGC->pScreen, &rgnDst, &fastBox, 1);
+ }
+ } else {
+ /* We must turn off fastClip now, since we must create
+ a full blown region. It is intersected with the
+ composite clip below. */
+ fastClip = 0;
+ REGION_INIT(pGC->pScreen, &rgnDst, &fastBox,1);
+ }
+ } else {
+ REGION_TRANSLATE(pGC->pScreen, &rgnDst, -dx, -dy);
+ }
+
+ if (!fastClip) {
+ REGION_INTERSECT(pGC->pScreen, &rgnDst, &rgnDst,
+ pGC->pCompositeClip);
+ }
+
+ /* Do bit blitting */
+ numRects = REGION_NUM_RECTS(&rgnDst);
+ if (numRects && width && height) {
+ if(!(pptSrc = (DDXPointPtr)malloc(numRects *
+ sizeof(DDXPointRec)))) {
+ REGION_UNINIT(pGC->pScreen, &rgnDst);
+ if (freeSrcClip)
+ REGION_DESTROY(pGC->pScreen, prgnSrcClip);
+ return NULL;
+ }
+ pbox = REGION_RECTS(&rgnDst);
+ ppt = pptSrc;
+ for (i = numRects; --i >= 0; pbox++, ppt++) {
+ ppt->x = pbox->x1 + dx;
+ ppt->y = pbox->y1 + dy;
+ }
+
+ (*doBitBlt) (pSrcDrawable, pDstDrawable, pGC, &rgnDst, pptSrc);
+ free(pptSrc);
+ }
+
+ prgnExposed = NULL;
+ if (pGC->fExpose) {
+ /* Pixmap sources generate a NoExposed (we return NULL to do this) */
+ if (!fastExpose)
+ prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
+ origSource.x, origSource.y,
+ (int)origSource.width,
+ (int)origSource.height,
+ origDest.x, origDest.y, bitPlane);
+ }
+ REGION_UNINIT(pGC->pScreen, &rgnDst);
+ if (freeSrcClip)
+ REGION_DESTROY(pGC->pScreen, prgnSrcClip);
+ return prgnExposed;
+}
diff --git a/xorg-server/hw/xfree86/xaa/xaaCpyArea.c b/xorg-server/hw/xfree86/xaa/xaaCpyArea.c
index 6a898cd5f..eefd8d38d 100644
--- a/xorg-server/hw/xfree86/xaa/xaaCpyArea.c
+++ b/xorg-server/hw/xfree86/xaa/xaaCpyArea.c
@@ -1,387 +1,387 @@
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "misc.h"
-#include "xf86.h"
-#include "xf86_OSproc.h"
-
-#include <X11/X.h>
-#include "scrnintstr.h"
-#include "xf86str.h"
-#include "xaa.h"
-#include "xaalocal.h"
-#include "migc.h"
-#include "gcstruct.h"
-#include "pixmapstr.h"
-
-/*
- Written mostly by Harm Hanemaayer (H.Hanemaayer@inter.nl.net).
- */
-
-
-RegionPtr
-XAACopyArea(
- DrawablePtr pSrcDrawable,
- DrawablePtr pDstDrawable,
- GC *pGC,
- int srcx, int srcy,
- int width, int height,
- int dstx, int dsty )
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
-
- if(pDstDrawable->type == DRAWABLE_WINDOW) {
- if((pSrcDrawable->type == DRAWABLE_WINDOW) ||
- IS_OFFSCREEN_PIXMAP(pSrcDrawable)){
- if(infoRec->ScreenToScreenBitBlt &&
- CHECK_ROP(pGC,infoRec->ScreenToScreenBitBltFlags) &&
- CHECK_ROPSRC(pGC,infoRec->ScreenToScreenBitBltFlags) &&
- CHECK_PLANEMASK(pGC,infoRec->ScreenToScreenBitBltFlags))
- return (XAABitBlt( pSrcDrawable, pDstDrawable,
- pGC, srcx, srcy, width, height, dstx, dsty,
- XAADoBitBlt, 0L));
- } else {
- if(infoRec->WritePixmap &&
- ((pDstDrawable->bitsPerPixel == pSrcDrawable->bitsPerPixel) ||
- ((pDstDrawable->bitsPerPixel == 24) &&
- (pSrcDrawable->bitsPerPixel == 32) &&
- (infoRec->WritePixmapFlags & CONVERT_32BPP_TO_24BPP))) &&
- CHECK_ROP(pGC,infoRec->WritePixmapFlags) &&
- CHECK_ROPSRC(pGC,infoRec->WritePixmapFlags) &&
- CHECK_PLANEMASK(pGC,infoRec->WritePixmapFlags) &&
- CHECK_NO_GXCOPY(pGC,infoRec->WritePixmapFlags))
- return (XAABitBlt( pSrcDrawable, pDstDrawable,
- pGC, srcx, srcy, width, height, dstx, dsty,
- XAADoImageWrite, 0L));
- }
- } else if(IS_OFFSCREEN_PIXMAP(pDstDrawable)){
- if((pSrcDrawable->type == DRAWABLE_WINDOW) ||
- IS_OFFSCREEN_PIXMAP(pSrcDrawable)){
- if(infoRec->ScreenToScreenBitBlt &&
- CHECK_ROP(pGC,infoRec->ScreenToScreenBitBltFlags) &&
- CHECK_ROPSRC(pGC,infoRec->ScreenToScreenBitBltFlags) &&
- CHECK_PLANEMASK(pGC,infoRec->ScreenToScreenBitBltFlags))
- return (XAABitBlt( pSrcDrawable, pDstDrawable,
- pGC, srcx, srcy, width, height, dstx, dsty,
- XAADoBitBlt, 0L));
- }
- }
-
- return (XAAFallbackOps.CopyArea(pSrcDrawable, pDstDrawable, pGC,
- srcx, srcy, width, height, dstx, dsty));
-}
-
-
-void
-XAADoBitBlt(
- DrawablePtr pSrc,
- DrawablePtr pDst,
- GC *pGC,
- RegionPtr prgnDst,
- DDXPointPtr pptSrc )
-{
- int nbox, careful;
- BoxPtr pbox, pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2;
- DDXPointPtr pptTmp, pptNew1, pptNew2;
- int xdir, ydir;
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
-
- /* XXX we have to err on the side of safety when both are windows,
- * because we don't know if IncludeInferiors is being used.
- */
- careful = ((pSrc == pDst) ||
- ((pSrc->type == DRAWABLE_WINDOW) &&
- (pDst->type == DRAWABLE_WINDOW)));
-
- pbox = REGION_RECTS(prgnDst);
- nbox = REGION_NUM_RECTS(prgnDst);
-
- pboxNew1 = NULL;
- pptNew1 = NULL;
- pboxNew2 = NULL;
- pptNew2 = NULL;
- if (careful && (pptSrc->y < pbox->y1)) {
- /* walk source botttom to top */
- ydir = -1;
-
- if (nbox > 1) {
- /* keep ordering in each band, reverse order of bands */
- pboxNew1 = (BoxPtr)xalloc(sizeof(BoxRec) * nbox);
- if(!pboxNew1)
- return;
- pptNew1 = (DDXPointPtr)xalloc(sizeof(DDXPointRec) * nbox);
- if(!pptNew1) {
- xfree(pboxNew1);
- return;
- }
- pboxBase = pboxNext = pbox+nbox-1;
- while (pboxBase >= pbox) {
- while ((pboxNext >= pbox) &&
- (pboxBase->y1 == pboxNext->y1))
- pboxNext--;
- pboxTmp = pboxNext+1;
- pptTmp = pptSrc + (pboxTmp - pbox);
- while (pboxTmp <= pboxBase) {
- *pboxNew1++ = *pboxTmp++;
- *pptNew1++ = *pptTmp++;
- }
- pboxBase = pboxNext;
- }
- pboxNew1 -= nbox;
- pbox = pboxNew1;
- pptNew1 -= nbox;
- pptSrc = pptNew1;
- }
- } else {
- /* walk source top to bottom */
- ydir = 1;
- }
-
- if (careful && (pptSrc->x < pbox->x1)) {
- /* walk source right to left */
- xdir = -1;
-
- if (nbox > 1) {
- /* reverse order of rects in each band */
- pboxNew2 = (BoxPtr)xalloc(sizeof(BoxRec) * nbox);
- pptNew2 = (DDXPointPtr)xalloc(sizeof(DDXPointRec) * nbox);
- if(!pboxNew2 || !pptNew2) {
- if (pptNew2) xfree(pptNew2);
- if (pboxNew2) xfree(pboxNew2);
- if (pboxNew1) {
- xfree(pptNew1);
- xfree(pboxNew1);
- }
- return;
- }
- pboxBase = pboxNext = pbox;
- while (pboxBase < pbox+nbox) {
- while ((pboxNext < pbox+nbox) &&
- (pboxNext->y1 == pboxBase->y1))
- pboxNext++;
- pboxTmp = pboxNext;
- pptTmp = pptSrc + (pboxTmp - pbox);
- while (pboxTmp != pboxBase) {
- *pboxNew2++ = *--pboxTmp;
- *pptNew2++ = *--pptTmp;
- }
- pboxBase = pboxNext;
- }
- pboxNew2 -= nbox;
- pbox = pboxNew2;
- pptNew2 -= nbox;
- pptSrc = pptNew2;
- }
- } else {
- /* walk source left to right */
- xdir = 1;
- }
-
- (*infoRec->ScreenToScreenBitBlt)(infoRec->pScrn, nbox, pptSrc, pbox,
- xdir, ydir, pGC->alu, pGC->planemask);
-
- if (pboxNew2) {
- xfree(pptNew2);
- xfree(pboxNew2);
- }
- if (pboxNew1) {
- xfree(pptNew1);
- xfree(pboxNew1);
- }
-
-}
-
-void
-XAADoImageWrite(
- DrawablePtr pSrc,
- DrawablePtr pDst,
- GC *pGC,
- RegionPtr prgnDst,
- DDXPointPtr pptSrc )
-{
- int srcwidth;
- unsigned char* psrcBase; /* start of image */
- unsigned char* srcPntr; /* index into the image */
- BoxPtr pbox = REGION_RECTS(prgnDst);
- int nbox = REGION_NUM_RECTS(prgnDst);
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
- int Bpp = pSrc->bitsPerPixel >> 3;
-
- psrcBase = (unsigned char *)((PixmapPtr)pSrc)->devPrivate.ptr;
- srcwidth = (int)((PixmapPtr)pSrc)->devKind;
-
- for(; nbox; pbox++, pptSrc++, nbox--) {
- srcPntr = psrcBase + (pptSrc->y * srcwidth) + (pptSrc->x * Bpp);
-
- (*infoRec->WritePixmap)(infoRec->pScrn, pbox->x1, pbox->y1,
- pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, srcPntr, srcwidth,
- pGC->alu, pGC->planemask, -1, pSrc->bitsPerPixel, pSrc->depth);
- }
-}
-
-
-void
-XAADoImageRead(
- DrawablePtr pSrc,
- DrawablePtr pDst,
- GC *pGC,
- RegionPtr prgnDst,
- DDXPointPtr pptSrc )
-{
- int dstwidth;
- unsigned char* pdstBase; /* start of image */
- unsigned char* dstPntr; /* index into the image */
- BoxPtr pbox = REGION_RECTS(prgnDst);
- int nbox = REGION_NUM_RECTS(prgnDst);
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
- int Bpp = pSrc->bitsPerPixel >> 3; /* wouldn't get here unless both
- src and dst have same bpp */
-
- pdstBase = (unsigned char *)((PixmapPtr)pDst)->devPrivate.ptr;
- dstwidth = (int)((PixmapPtr)pDst)->devKind;
-
- for(; nbox; pbox++, pptSrc++, nbox--) {
- dstPntr = pdstBase + (pbox->y1 * dstwidth) + (pbox->x1 * Bpp);
-
- (*infoRec->ReadPixmap)(infoRec->pScrn, pptSrc->x, pptSrc->y,
- pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, dstPntr, dstwidth,
- pSrc->bitsPerPixel, pSrc->depth);
- }
-}
-
-
-void
-XAAScreenToScreenBitBlt(
- ScrnInfoPtr pScrn,
- int nbox,
- DDXPointPtr pptSrc,
- BoxPtr pbox,
- int xdir, int ydir,
- int alu,
- unsigned int planemask )
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
- int dirsetup;
-
- if ((!(infoRec->CopyAreaFlags & ONLY_TWO_BITBLT_DIRECTIONS)
- || (xdir == ydir)) &&
- (!(infoRec->CopyAreaFlags & ONLY_LEFT_TO_RIGHT_BITBLT)
- || (xdir == 1))) {
- (*infoRec->SetupForScreenToScreenCopy)(pScrn,
- xdir, ydir, alu, planemask, -1);
- for (; nbox; pbox++, pptSrc++, nbox--)
- (*infoRec->SubsequentScreenToScreenCopy)(pScrn,pptSrc->x, pptSrc->y,
- pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
- SET_SYNC_FLAG(infoRec);
- return;
- }
-
- if (infoRec->CopyAreaFlags & ONLY_LEFT_TO_RIGHT_BITBLT) {
- /*
- * This is the case of a chip that only supports xdir = 1,
- * with ydir = 1 or ydir = -1, but we have xdir = -1.
- */
- (*infoRec->SetupForScreenToScreenCopy)(pScrn,
- 1, ydir, alu, planemask, -1);
- for (; nbox; pbox++, pptSrc++, nbox--)
- if (pptSrc->y != pbox->y1 || pptSrc->x >= pbox->x1)
- /* No problem. Do a xdir = 1 blit instead. */
- (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
- pptSrc->x, pptSrc->y, pbox->x1, pbox->y1,
- pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
- else
- {
- /*
- * This is the difficult case. Needs striping into
- * non-overlapping horizontal chunks.
- */
- int stripeWidth, w, fullStripes, extra, i;
- stripeWidth = 16;
- w = pbox->x2 - pbox->x1;
- if (pbox->x1 - pptSrc->x < stripeWidth)
- stripeWidth = pbox->x1 - pptSrc->x;
- fullStripes = w / stripeWidth;
- extra = w % stripeWidth;
-
- /* First, take care of the little bit on the far right */
- if (extra)
- (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
- pptSrc->x + fullStripes * stripeWidth, pptSrc->y,
- pbox->x1 + fullStripes * stripeWidth, pbox->y1,
- extra, pbox->y2 - pbox->y1);
-
- /* Now, take care of the rest of the blit */
- for (i = fullStripes - 1; i >= 0; i--)
- (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
- pptSrc->x + i * stripeWidth, pptSrc->y,
- pbox->x1 + i * stripeWidth, pbox->y1,
- stripeWidth, pbox->y2 - pbox->y1);
- }
- SET_SYNC_FLAG(infoRec);
- return;
- }
-
- /*
- * Now the case of a chip that only supports xdir = ydir = 1 or
- * xdir = ydir = -1, but we have xdir != ydir.
- */
- dirsetup = 0; /* No direction set up yet. */
- for (; nbox; pbox++, pptSrc++, nbox--) {
- if (xdir == 1 && pptSrc->y != pbox->y1) {
- /* Do a xdir = ydir = -1 blit instead. */
- if (dirsetup != -1) {
- (*infoRec->SetupForScreenToScreenCopy)(pScrn,
- -1, -1, alu, planemask, -1);
- dirsetup = -1;
- }
- (*infoRec->SubsequentScreenToScreenCopy)(pScrn,pptSrc->x, pptSrc->y,
- pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
- }
- else if (xdir == -1 && pptSrc->y != pbox->y1) {
- /* Do a xdir = ydir = 1 blit instead. */
- if (dirsetup != 1) {
- (*infoRec->SetupForScreenToScreenCopy)(pScrn,
- 1, 1, alu, planemask, -1);
- dirsetup = 1;
- }
- (*infoRec->SubsequentScreenToScreenCopy)(pScrn,pptSrc->x, pptSrc->y,
- pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
- }
- else
- if (xdir == 1) {
- /*
- * xdir = 1, ydir = -1.
- * Perform line-by-line xdir = ydir = 1 blits, going up.
- */
- int i;
- if (dirsetup != 1) {
- (*infoRec->SetupForScreenToScreenCopy)(pScrn,
- 1, 1, alu, planemask, -1);
- dirsetup = 1;
- }
- for (i = pbox->y2 - pbox->y1 - 1; i >= 0; i--)
- (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
- pptSrc->x, pptSrc->y + i, pbox->x1, pbox->y1 + i,
- pbox->x2 - pbox->x1, 1);
- }
- else {
- /*
- * xdir = -1, ydir = 1.
- * Perform line-by-line xdir = ydir = -1 blits, going down.
- */
- int i;
- if (dirsetup != -1) {
- (*infoRec->SetupForScreenToScreenCopy)(pScrn,
- -1, -1, alu, planemask, -1);
- dirsetup = -1;
- }
- for (i = 0; i < pbox->y2 - pbox->y1; i++)
- (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
- pptSrc->x, pptSrc->y + i, pbox->x1, pbox->y1 + i,
- pbox->x2 - pbox->x1, 1);
- }
- } /* next box */
- SET_SYNC_FLAG(infoRec);
-}
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include <X11/X.h>
+#include "scrnintstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "migc.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+
+/*
+ Written mostly by Harm Hanemaayer (H.Hanemaayer@inter.nl.net).
+ */
+
+
+RegionPtr
+XAACopyArea(
+ DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GC *pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ if(pDstDrawable->type == DRAWABLE_WINDOW) {
+ if((pSrcDrawable->type == DRAWABLE_WINDOW) ||
+ IS_OFFSCREEN_PIXMAP(pSrcDrawable)){
+ if(infoRec->ScreenToScreenBitBlt &&
+ CHECK_ROP(pGC,infoRec->ScreenToScreenBitBltFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->ScreenToScreenBitBltFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->ScreenToScreenBitBltFlags))
+ return (XAABitBlt( pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty,
+ XAADoBitBlt, 0L));
+ } else {
+ if(infoRec->WritePixmap &&
+ ((pDstDrawable->bitsPerPixel == pSrcDrawable->bitsPerPixel) ||
+ ((pDstDrawable->bitsPerPixel == 24) &&
+ (pSrcDrawable->bitsPerPixel == 32) &&
+ (infoRec->WritePixmapFlags & CONVERT_32BPP_TO_24BPP))) &&
+ CHECK_ROP(pGC,infoRec->WritePixmapFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->WritePixmapFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->WritePixmapFlags) &&
+ CHECK_NO_GXCOPY(pGC,infoRec->WritePixmapFlags))
+ return (XAABitBlt( pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty,
+ XAADoImageWrite, 0L));
+ }
+ } else if(IS_OFFSCREEN_PIXMAP(pDstDrawable)){
+ if((pSrcDrawable->type == DRAWABLE_WINDOW) ||
+ IS_OFFSCREEN_PIXMAP(pSrcDrawable)){
+ if(infoRec->ScreenToScreenBitBlt &&
+ CHECK_ROP(pGC,infoRec->ScreenToScreenBitBltFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->ScreenToScreenBitBltFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->ScreenToScreenBitBltFlags))
+ return (XAABitBlt( pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height, dstx, dsty,
+ XAADoBitBlt, 0L));
+ }
+ }
+
+ return (XAAFallbackOps.CopyArea(pSrcDrawable, pDstDrawable, pGC,
+ srcx, srcy, width, height, dstx, dsty));
+}
+
+
+void
+XAADoBitBlt(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc )
+{
+ int nbox, careful;
+ BoxPtr pbox, pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2;
+ DDXPointPtr pptTmp, pptNew1, pptNew2;
+ int xdir, ydir;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ /* XXX we have to err on the side of safety when both are windows,
+ * because we don't know if IncludeInferiors is being used.
+ */
+ careful = ((pSrc == pDst) ||
+ ((pSrc->type == DRAWABLE_WINDOW) &&
+ (pDst->type == DRAWABLE_WINDOW)));
+
+ pbox = REGION_RECTS(prgnDst);
+ nbox = REGION_NUM_RECTS(prgnDst);
+
+ pboxNew1 = NULL;
+ pptNew1 = NULL;
+ pboxNew2 = NULL;
+ pptNew2 = NULL;
+ if (careful && (pptSrc->y < pbox->y1)) {
+ /* walk source botttom to top */
+ ydir = -1;
+
+ if (nbox > 1) {
+ /* keep ordering in each band, reverse order of bands */
+ pboxNew1 = (BoxPtr)malloc(sizeof(BoxRec) * nbox);
+ if(!pboxNew1)
+ return;
+ pptNew1 = (DDXPointPtr)malloc(sizeof(DDXPointRec) * nbox);
+ if(!pptNew1) {
+ free(pboxNew1);
+ return;
+ }
+ pboxBase = pboxNext = pbox+nbox-1;
+ while (pboxBase >= pbox) {
+ while ((pboxNext >= pbox) &&
+ (pboxBase->y1 == pboxNext->y1))
+ pboxNext--;
+ pboxTmp = pboxNext+1;
+ pptTmp = pptSrc + (pboxTmp - pbox);
+ while (pboxTmp <= pboxBase) {
+ *pboxNew1++ = *pboxTmp++;
+ *pptNew1++ = *pptTmp++;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew1 -= nbox;
+ pbox = pboxNew1;
+ pptNew1 -= nbox;
+ pptSrc = pptNew1;
+ }
+ } else {
+ /* walk source top to bottom */
+ ydir = 1;
+ }
+
+ if (careful && (pptSrc->x < pbox->x1)) {
+ /* walk source right to left */
+ xdir = -1;
+
+ if (nbox > 1) {
+ /* reverse order of rects in each band */
+ pboxNew2 = (BoxPtr)malloc(sizeof(BoxRec) * nbox);
+ pptNew2 = (DDXPointPtr)malloc(sizeof(DDXPointRec) * nbox);
+ if(!pboxNew2 || !pptNew2) {
+ if (pptNew2) free(pptNew2);
+ if (pboxNew2) free(pboxNew2);
+ if (pboxNew1) {
+ free(pptNew1);
+ free(pboxNew1);
+ }
+ return;
+ }
+ pboxBase = pboxNext = pbox;
+ while (pboxBase < pbox+nbox) {
+ while ((pboxNext < pbox+nbox) &&
+ (pboxNext->y1 == pboxBase->y1))
+ pboxNext++;
+ pboxTmp = pboxNext;
+ pptTmp = pptSrc + (pboxTmp - pbox);
+ while (pboxTmp != pboxBase) {
+ *pboxNew2++ = *--pboxTmp;
+ *pptNew2++ = *--pptTmp;
+ }
+ pboxBase = pboxNext;
+ }
+ pboxNew2 -= nbox;
+ pbox = pboxNew2;
+ pptNew2 -= nbox;
+ pptSrc = pptNew2;
+ }
+ } else {
+ /* walk source left to right */
+ xdir = 1;
+ }
+
+ (*infoRec->ScreenToScreenBitBlt)(infoRec->pScrn, nbox, pptSrc, pbox,
+ xdir, ydir, pGC->alu, pGC->planemask);
+
+ if (pboxNew2) {
+ free(pptNew2);
+ free(pboxNew2);
+ }
+ if (pboxNew1) {
+ free(pptNew1);
+ free(pboxNew1);
+ }
+
+}
+
+void
+XAADoImageWrite(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc )
+{
+ int srcwidth;
+ unsigned char* psrcBase; /* start of image */
+ unsigned char* srcPntr; /* index into the image */
+ BoxPtr pbox = REGION_RECTS(prgnDst);
+ int nbox = REGION_NUM_RECTS(prgnDst);
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int Bpp = pSrc->bitsPerPixel >> 3;
+
+ psrcBase = (unsigned char *)((PixmapPtr)pSrc)->devPrivate.ptr;
+ srcwidth = (int)((PixmapPtr)pSrc)->devKind;
+
+ for(; nbox; pbox++, pptSrc++, nbox--) {
+ srcPntr = psrcBase + (pptSrc->y * srcwidth) + (pptSrc->x * Bpp);
+
+ (*infoRec->WritePixmap)(infoRec->pScrn, pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, srcPntr, srcwidth,
+ pGC->alu, pGC->planemask, -1, pSrc->bitsPerPixel, pSrc->depth);
+ }
+}
+
+
+void
+XAADoImageRead(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc )
+{
+ int dstwidth;
+ unsigned char* pdstBase; /* start of image */
+ unsigned char* dstPntr; /* index into the image */
+ BoxPtr pbox = REGION_RECTS(prgnDst);
+ int nbox = REGION_NUM_RECTS(prgnDst);
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int Bpp = pSrc->bitsPerPixel >> 3; /* wouldn't get here unless both
+ src and dst have same bpp */
+
+ pdstBase = (unsigned char *)((PixmapPtr)pDst)->devPrivate.ptr;
+ dstwidth = (int)((PixmapPtr)pDst)->devKind;
+
+ for(; nbox; pbox++, pptSrc++, nbox--) {
+ dstPntr = pdstBase + (pbox->y1 * dstwidth) + (pbox->x1 * Bpp);
+
+ (*infoRec->ReadPixmap)(infoRec->pScrn, pptSrc->x, pptSrc->y,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, dstPntr, dstwidth,
+ pSrc->bitsPerPixel, pSrc->depth);
+ }
+}
+
+
+void
+XAAScreenToScreenBitBlt(
+ ScrnInfoPtr pScrn,
+ int nbox,
+ DDXPointPtr pptSrc,
+ BoxPtr pbox,
+ int xdir, int ydir,
+ int alu,
+ unsigned int planemask )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int dirsetup;
+
+ if ((!(infoRec->CopyAreaFlags & ONLY_TWO_BITBLT_DIRECTIONS)
+ || (xdir == ydir)) &&
+ (!(infoRec->CopyAreaFlags & ONLY_LEFT_TO_RIGHT_BITBLT)
+ || (xdir == 1))) {
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn,
+ xdir, ydir, alu, planemask, -1);
+ for (; nbox; pbox++, pptSrc++, nbox--)
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,pptSrc->x, pptSrc->y,
+ pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+ SET_SYNC_FLAG(infoRec);
+ return;
+ }
+
+ if (infoRec->CopyAreaFlags & ONLY_LEFT_TO_RIGHT_BITBLT) {
+ /*
+ * This is the case of a chip that only supports xdir = 1,
+ * with ydir = 1 or ydir = -1, but we have xdir = -1.
+ */
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn,
+ 1, ydir, alu, planemask, -1);
+ for (; nbox; pbox++, pptSrc++, nbox--)
+ if (pptSrc->y != pbox->y1 || pptSrc->x >= pbox->x1)
+ /* No problem. Do a xdir = 1 blit instead. */
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pptSrc->x, pptSrc->y, pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+ else
+ {
+ /*
+ * This is the difficult case. Needs striping into
+ * non-overlapping horizontal chunks.
+ */
+ int stripeWidth, w, fullStripes, extra, i;
+ stripeWidth = 16;
+ w = pbox->x2 - pbox->x1;
+ if (pbox->x1 - pptSrc->x < stripeWidth)
+ stripeWidth = pbox->x1 - pptSrc->x;
+ fullStripes = w / stripeWidth;
+ extra = w % stripeWidth;
+
+ /* First, take care of the little bit on the far right */
+ if (extra)
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pptSrc->x + fullStripes * stripeWidth, pptSrc->y,
+ pbox->x1 + fullStripes * stripeWidth, pbox->y1,
+ extra, pbox->y2 - pbox->y1);
+
+ /* Now, take care of the rest of the blit */
+ for (i = fullStripes - 1; i >= 0; i--)
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pptSrc->x + i * stripeWidth, pptSrc->y,
+ pbox->x1 + i * stripeWidth, pbox->y1,
+ stripeWidth, pbox->y2 - pbox->y1);
+ }
+ SET_SYNC_FLAG(infoRec);
+ return;
+ }
+
+ /*
+ * Now the case of a chip that only supports xdir = ydir = 1 or
+ * xdir = ydir = -1, but we have xdir != ydir.
+ */
+ dirsetup = 0; /* No direction set up yet. */
+ for (; nbox; pbox++, pptSrc++, nbox--) {
+ if (xdir == 1 && pptSrc->y != pbox->y1) {
+ /* Do a xdir = ydir = -1 blit instead. */
+ if (dirsetup != -1) {
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn,
+ -1, -1, alu, planemask, -1);
+ dirsetup = -1;
+ }
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,pptSrc->x, pptSrc->y,
+ pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+ }
+ else if (xdir == -1 && pptSrc->y != pbox->y1) {
+ /* Do a xdir = ydir = 1 blit instead. */
+ if (dirsetup != 1) {
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn,
+ 1, 1, alu, planemask, -1);
+ dirsetup = 1;
+ }
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,pptSrc->x, pptSrc->y,
+ pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+ }
+ else
+ if (xdir == 1) {
+ /*
+ * xdir = 1, ydir = -1.
+ * Perform line-by-line xdir = ydir = 1 blits, going up.
+ */
+ int i;
+ if (dirsetup != 1) {
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn,
+ 1, 1, alu, planemask, -1);
+ dirsetup = 1;
+ }
+ for (i = pbox->y2 - pbox->y1 - 1; i >= 0; i--)
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pptSrc->x, pptSrc->y + i, pbox->x1, pbox->y1 + i,
+ pbox->x2 - pbox->x1, 1);
+ }
+ else {
+ /*
+ * xdir = -1, ydir = 1.
+ * Perform line-by-line xdir = ydir = -1 blits, going down.
+ */
+ int i;
+ if (dirsetup != -1) {
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn,
+ -1, -1, alu, planemask, -1);
+ dirsetup = -1;
+ }
+ for (i = 0; i < pbox->y2 - pbox->y1; i++)
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn,
+ pptSrc->x, pptSrc->y + i, pbox->x1, pbox->y1 + i,
+ pbox->x2 - pbox->x1, 1);
+ }
+ } /* next box */
+ SET_SYNC_FLAG(infoRec);
+}
diff --git a/xorg-server/hw/xfree86/xaa/xaaCpyPlane.c b/xorg-server/hw/xfree86/xaa/xaaCpyPlane.c
index aa4c0407c..358cb6fb2 100644
--- a/xorg-server/hw/xfree86/xaa/xaaCpyPlane.c
+++ b/xorg-server/hw/xfree86/xaa/xaaCpyPlane.c
@@ -1,208 +1,208 @@
-
-/*
- A CopyPlane function that handles bitmap->screen copies and
- sends anything else to the Fallback.
-
- Also, a PushPixels for solid fill styles.
-
- Written by Mark Vojkovich (markv@valinux.com)
-
-*/
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <string.h>
-
-#include "misc.h"
-#include "xf86.h"
-#include "xf86_OSproc.h"
-#include "servermd.h"
-
-#include <X11/X.h>
-#include "scrnintstr.h"
-#include "mi.h"
-#include "pixmapstr.h"
-#include "xf86str.h"
-#include "xaa.h"
-#include "xaalocal.h"
-#include "xaawrap.h"
-
-static void XAACopyPlane1toNColorExpand(DrawablePtr pSrc, DrawablePtr pDst,
- GCPtr pGC, RegionPtr rgnDst,
- DDXPointPtr pptSrc);
-static void XAACopyPlaneNtoNColorExpand(DrawablePtr pSrc, DrawablePtr pDst,
- GCPtr pGC, RegionPtr rgnDst,
- DDXPointPtr pptSrc);
-
-
-static unsigned long TmpBitPlane;
-
-RegionPtr
-XAACopyPlaneColorExpansion(
- DrawablePtr pSrc,
- DrawablePtr pDst,
- GCPtr pGC,
- int srcx, int srcy,
- int width, int height,
- int dstx, int dsty,
- unsigned long bitPlane
-){
- if((pSrc->type == DRAWABLE_PIXMAP) && !XAA_DEPTH_BUG(pGC)) {
- if(pSrc->bitsPerPixel == 1) {
- return(XAABitBlt(pSrc, pDst, pGC, srcx, srcy,
- width, height, dstx, dsty,
- XAACopyPlane1toNColorExpand, bitPlane));
- } else if(bitPlane < (1 << pDst->depth)){
- TmpBitPlane = bitPlane;
- return(XAABitBlt(pSrc, pDst, pGC, srcx, srcy,
- width, height, dstx, dsty,
- XAACopyPlaneNtoNColorExpand, bitPlane));
- }
- }
-
- return (XAAFallbackOps.CopyPlane(pSrc, pDst, pGC, srcx, srcy,
- width, height, dstx, dsty, bitPlane));
-}
-
-
-static void
-XAACopyPlane1toNColorExpand(
- DrawablePtr pSrc,
- DrawablePtr pDst,
- GCPtr pGC,
- RegionPtr rgnDst,
- DDXPointPtr pptSrc )
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
- BoxPtr pbox = REGION_RECTS(rgnDst);
- int numrects = REGION_NUM_RECTS(rgnDst);
- unsigned char *src = ((PixmapPtr)pSrc)->devPrivate.ptr;
- int srcwidth = ((PixmapPtr)pSrc)->devKind;
-
- while(numrects--) {
- (*infoRec->WriteBitmap)(infoRec->pScrn, pbox->x1, pbox->y1,
- pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
- src + (srcwidth * pptSrc->y) + ((pptSrc->x >> 5) << 2),
- srcwidth, pptSrc->x & 31,
- pGC->fgPixel, pGC->bgPixel, pGC->alu, pGC->planemask);
- pbox++; pptSrc++;
- }
-}
-
-
-static void
-XAACopyPlaneNtoNColorExpand(
- DrawablePtr pSrc,
- DrawablePtr pDst,
- GCPtr pGC,
- RegionPtr rgnDst,
- DDXPointPtr pptSrc
-){
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
- BoxPtr pbox = REGION_RECTS(rgnDst);
- int numrects = REGION_NUM_RECTS(rgnDst);
- unsigned char *src = ((PixmapPtr)pSrc)->devPrivate.ptr;
- unsigned char *data, *srcPtr, *dataPtr;
- int srcwidth = ((PixmapPtr)pSrc)->devKind;
- int pitch, width, height, h, i, index, offset;
- int Bpp = pSrc->bitsPerPixel >> 3;
- unsigned long mask = TmpBitPlane;
-
- if(TmpBitPlane < (1 << 8)) {
- offset = 0;
- } else if(TmpBitPlane < (1 << 16)) {
- offset = 1;
- mask >>= 8;
- } else if(TmpBitPlane < (1 << 24)) {
- offset = 2;
- mask >>= 16;
- } else {
- offset = 3;
- mask >>= 24;
- }
-
- if(IS_OFFSCREEN_PIXMAP(pSrc))
- SYNC_CHECK(pSrc);
-
- while(numrects--) {
- width = pbox->x2 - pbox->x1;
- h = height = pbox->y2 - pbox->y1;
- pitch = BitmapBytePad(width);
-
- if(!(data = xcalloc(height, pitch)))
- goto ALLOC_FAILED;
-
- dataPtr = data;
- srcPtr = ((pptSrc->y) * srcwidth) + src +
- ((pptSrc->x) * Bpp) + offset;
-
- while(h--) {
- for(i = index = 0; i < width; i++, index += Bpp) {
- if(mask & srcPtr[index])
- dataPtr[i >> 3] |= (1 << (i & 7));
- }
- dataPtr += pitch;
- srcPtr += srcwidth;
- }
-
- (*infoRec->WriteBitmap)(infoRec->pScrn,
- pbox->x1, pbox->y1, width, height, data, pitch, 0,
- pGC->fgPixel, pGC->bgPixel, pGC->alu, pGC->planemask);
-
- xfree(data);
-
-ALLOC_FAILED:
-
- pbox++; pptSrc++;
- }
-}
-
-void
-XAAPushPixelsSolidColorExpansion(
- GCPtr pGC,
- PixmapPtr pBitMap,
- DrawablePtr pDraw,
- int dx, int dy,
- int xOrg, int yOrg )
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
- int MaxBoxes = REGION_NUM_RECTS(pGC->pCompositeClip);
- BoxPtr pbox, pClipBoxes;
- int nboxes, srcx, srcy;
- xRectangle TheRect;
- unsigned char *src = pBitMap->devPrivate.ptr;
- int srcwidth = pBitMap->devKind;
-
- if(!REGION_NUM_RECTS(pGC->pCompositeClip))
- return;
-
- TheRect.x = xOrg;
- TheRect.y = yOrg;
- TheRect.width = dx;
- TheRect.height = dy;
-
- if(MaxBoxes > (infoRec->PreAllocSize/sizeof(BoxRec))) {
- pClipBoxes = xalloc(MaxBoxes * sizeof(BoxRec));
- if(!pClipBoxes) return;
- } else pClipBoxes = (BoxPtr)infoRec->PreAllocMem;
-
- nboxes = XAAGetRectClipBoxes(pGC, pClipBoxes, 1, &TheRect);
- pbox = pClipBoxes;
-
- while(nboxes--) {
- srcx = pbox->x1 - xOrg;
- srcy = pbox->y1 - yOrg;
- (*infoRec->WriteBitmap)(infoRec->pScrn, pbox->x1, pbox->y1,
- pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
- src + (srcwidth * srcy) + ((srcx >> 5) << 2),
- srcwidth, srcx & 31,
- pGC->fgPixel, -1, pGC->alu, pGC->planemask);
- pbox++;
- }
-
- if(pClipBoxes != (BoxPtr)infoRec->PreAllocMem)
- xfree(pClipBoxes);
-}
-
+
+/*
+ A CopyPlane function that handles bitmap->screen copies and
+ sends anything else to the Fallback.
+
+ Also, a PushPixels for solid fill styles.
+
+ Written by Mark Vojkovich (markv@valinux.com)
+
+*/
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <string.h>
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "servermd.h"
+
+#include <X11/X.h>
+#include "scrnintstr.h"
+#include "mi.h"
+#include "pixmapstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xaawrap.h"
+
+static void XAACopyPlane1toNColorExpand(DrawablePtr pSrc, DrawablePtr pDst,
+ GCPtr pGC, RegionPtr rgnDst,
+ DDXPointPtr pptSrc);
+static void XAACopyPlaneNtoNColorExpand(DrawablePtr pSrc, DrawablePtr pDst,
+ GCPtr pGC, RegionPtr rgnDst,
+ DDXPointPtr pptSrc);
+
+
+static unsigned long TmpBitPlane;
+
+RegionPtr
+XAACopyPlaneColorExpansion(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty,
+ unsigned long bitPlane
+){
+ if((pSrc->type == DRAWABLE_PIXMAP) && !XAA_DEPTH_BUG(pGC)) {
+ if(pSrc->bitsPerPixel == 1) {
+ return(XAABitBlt(pSrc, pDst, pGC, srcx, srcy,
+ width, height, dstx, dsty,
+ XAACopyPlane1toNColorExpand, bitPlane));
+ } else if(bitPlane < (1 << pDst->depth)){
+ TmpBitPlane = bitPlane;
+ return(XAABitBlt(pSrc, pDst, pGC, srcx, srcy,
+ width, height, dstx, dsty,
+ XAACopyPlaneNtoNColorExpand, bitPlane));
+ }
+ }
+
+ return (XAAFallbackOps.CopyPlane(pSrc, pDst, pGC, srcx, srcy,
+ width, height, dstx, dsty, bitPlane));
+}
+
+
+static void
+XAACopyPlane1toNColorExpand(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ RegionPtr rgnDst,
+ DDXPointPtr pptSrc )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ BoxPtr pbox = REGION_RECTS(rgnDst);
+ int numrects = REGION_NUM_RECTS(rgnDst);
+ unsigned char *src = ((PixmapPtr)pSrc)->devPrivate.ptr;
+ int srcwidth = ((PixmapPtr)pSrc)->devKind;
+
+ while(numrects--) {
+ (*infoRec->WriteBitmap)(infoRec->pScrn, pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
+ src + (srcwidth * pptSrc->y) + ((pptSrc->x >> 5) << 2),
+ srcwidth, pptSrc->x & 31,
+ pGC->fgPixel, pGC->bgPixel, pGC->alu, pGC->planemask);
+ pbox++; pptSrc++;
+ }
+}
+
+
+static void
+XAACopyPlaneNtoNColorExpand(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ RegionPtr rgnDst,
+ DDXPointPtr pptSrc
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ BoxPtr pbox = REGION_RECTS(rgnDst);
+ int numrects = REGION_NUM_RECTS(rgnDst);
+ unsigned char *src = ((PixmapPtr)pSrc)->devPrivate.ptr;
+ unsigned char *data, *srcPtr, *dataPtr;
+ int srcwidth = ((PixmapPtr)pSrc)->devKind;
+ int pitch, width, height, h, i, index, offset;
+ int Bpp = pSrc->bitsPerPixel >> 3;
+ unsigned long mask = TmpBitPlane;
+
+ if(TmpBitPlane < (1 << 8)) {
+ offset = 0;
+ } else if(TmpBitPlane < (1 << 16)) {
+ offset = 1;
+ mask >>= 8;
+ } else if(TmpBitPlane < (1 << 24)) {
+ offset = 2;
+ mask >>= 16;
+ } else {
+ offset = 3;
+ mask >>= 24;
+ }
+
+ if(IS_OFFSCREEN_PIXMAP(pSrc))
+ SYNC_CHECK(pSrc);
+
+ while(numrects--) {
+ width = pbox->x2 - pbox->x1;
+ h = height = pbox->y2 - pbox->y1;
+ pitch = BitmapBytePad(width);
+
+ if(!(data = calloc(height, pitch)))
+ goto ALLOC_FAILED;
+
+ dataPtr = data;
+ srcPtr = ((pptSrc->y) * srcwidth) + src +
+ ((pptSrc->x) * Bpp) + offset;
+
+ while(h--) {
+ for(i = index = 0; i < width; i++, index += Bpp) {
+ if(mask & srcPtr[index])
+ dataPtr[i >> 3] |= (1 << (i & 7));
+ }
+ dataPtr += pitch;
+ srcPtr += srcwidth;
+ }
+
+ (*infoRec->WriteBitmap)(infoRec->pScrn,
+ pbox->x1, pbox->y1, width, height, data, pitch, 0,
+ pGC->fgPixel, pGC->bgPixel, pGC->alu, pGC->planemask);
+
+ free(data);
+
+ALLOC_FAILED:
+
+ pbox++; pptSrc++;
+ }
+}
+
+void
+XAAPushPixelsSolidColorExpansion(
+ GCPtr pGC,
+ PixmapPtr pBitMap,
+ DrawablePtr pDraw,
+ int dx, int dy,
+ int xOrg, int yOrg )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int MaxBoxes = REGION_NUM_RECTS(pGC->pCompositeClip);
+ BoxPtr pbox, pClipBoxes;
+ int nboxes, srcx, srcy;
+ xRectangle TheRect;
+ unsigned char *src = pBitMap->devPrivate.ptr;
+ int srcwidth = pBitMap->devKind;
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ TheRect.x = xOrg;
+ TheRect.y = yOrg;
+ TheRect.width = dx;
+ TheRect.height = dy;
+
+ if(MaxBoxes > (infoRec->PreAllocSize/sizeof(BoxRec))) {
+ pClipBoxes = malloc(MaxBoxes * sizeof(BoxRec));
+ if(!pClipBoxes) return;
+ } else pClipBoxes = (BoxPtr)infoRec->PreAllocMem;
+
+ nboxes = XAAGetRectClipBoxes(pGC, pClipBoxes, 1, &TheRect);
+ pbox = pClipBoxes;
+
+ while(nboxes--) {
+ srcx = pbox->x1 - xOrg;
+ srcy = pbox->y1 - yOrg;
+ (*infoRec->WriteBitmap)(infoRec->pScrn, pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
+ src + (srcwidth * srcy) + ((srcx >> 5) << 2),
+ srcwidth, srcx & 31,
+ pGC->fgPixel, -1, pGC->alu, pGC->planemask);
+ pbox++;
+ }
+
+ if(pClipBoxes != (BoxPtr)infoRec->PreAllocMem)
+ free(pClipBoxes);
+}
+
diff --git a/xorg-server/hw/xfree86/xaa/xaaCpyWin.c b/xorg-server/hw/xfree86/xaa/xaaCpyWin.c
index 31c421e65..34f460f24 100644
--- a/xorg-server/hw/xfree86/xaa/xaaCpyWin.c
+++ b/xorg-server/hw/xfree86/xaa/xaaCpyWin.c
@@ -1,82 +1,82 @@
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "misc.h"
-#include "xf86.h"
-#include "xf86_OSproc.h"
-
-#include <X11/X.h>
-#include "scrnintstr.h"
-#include "windowstr.h"
-#include "xf86str.h"
-#include "xaa.h"
-#include "xaalocal.h"
-#include "gcstruct.h"
-#include "pixmapstr.h"
-#include "xaawrap.h"
-
-/*
- Written by Harm Hanemaayer (H.Hanemaayer@inter.nl.net).
-*/
-
-void
-XAACopyWindow(
- WindowPtr pWin,
- DDXPointRec ptOldOrg,
- RegionPtr prgnSrc )
-{
- DDXPointPtr pptSrc, ppt;
- RegionRec rgnDst;
- BoxPtr pbox;
- int dx, dy, nbox;
- WindowPtr pwinRoot;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- XAAInfoRecPtr infoRec =
- GET_XAAINFORECPTR_FROM_DRAWABLE((&pWin->drawable));
-
- if (!infoRec->pScrn->vtSema || !infoRec->ScreenToScreenBitBlt) {
- XAA_SCREEN_PROLOGUE (pScreen, CopyWindow);
- if(infoRec->pScrn->vtSema && infoRec->NeedToSync) {
- (*infoRec->Sync)(infoRec->pScrn);
- infoRec->NeedToSync = FALSE;
- }
- (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
- XAA_SCREEN_EPILOGUE (pScreen, CopyWindow, XAACopyWindow);
- return;
- }
-
- pwinRoot = WindowTable[pScreen->myNum];
-
- REGION_NULL(pScreen, &rgnDst);
-
- dx = ptOldOrg.x - pWin->drawable.x;
- dy = ptOldOrg.y - pWin->drawable.y;
- REGION_TRANSLATE(pScreen, prgnSrc, -dx, -dy);
- REGION_INTERSECT(pScreen, &rgnDst, &pWin->borderClip, prgnSrc);
-
- pbox = REGION_RECTS(&rgnDst);
- nbox = REGION_NUM_RECTS(&rgnDst);
- if(!nbox ||
- !(pptSrc = (DDXPointPtr )xalloc(nbox * sizeof(DDXPointRec)))) {
- REGION_UNINIT(pScreen, &rgnDst);
- return;
- }
- ppt = pptSrc;
-
- while(nbox--) {
- ppt->x = pbox->x1 + dx;
- ppt->y = pbox->y1 + dy;
- ppt++; pbox++;
- }
-
- infoRec->ScratchGC.planemask = ~0L;
- infoRec->ScratchGC.alu = GXcopy;
-
- XAADoBitBlt((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot,
- &(infoRec->ScratchGC), &rgnDst, pptSrc);
-
- xfree(pptSrc);
- REGION_UNINIT(pScreen, &rgnDst);
-}
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include <X11/X.h>
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "xaawrap.h"
+
+/*
+ Written by Harm Hanemaayer (H.Hanemaayer@inter.nl.net).
+*/
+
+void
+XAACopyWindow(
+ WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc )
+{
+ DDXPointPtr pptSrc, ppt;
+ RegionRec rgnDst;
+ BoxPtr pbox;
+ int dx, dy, nbox;
+ WindowPtr pwinRoot;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ XAAInfoRecPtr infoRec =
+ GET_XAAINFORECPTR_FROM_DRAWABLE((&pWin->drawable));
+
+ if (!infoRec->pScrn->vtSema || !infoRec->ScreenToScreenBitBlt) {
+ XAA_SCREEN_PROLOGUE (pScreen, CopyWindow);
+ if(infoRec->pScrn->vtSema && infoRec->NeedToSync) {
+ (*infoRec->Sync)(infoRec->pScrn);
+ infoRec->NeedToSync = FALSE;
+ }
+ (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
+ XAA_SCREEN_EPILOGUE (pScreen, CopyWindow, XAACopyWindow);
+ return;
+ }
+
+ pwinRoot = WindowTable[pScreen->myNum];
+
+ REGION_NULL(pScreen, &rgnDst);
+
+ dx = ptOldOrg.x - pWin->drawable.x;
+ dy = ptOldOrg.y - pWin->drawable.y;
+ REGION_TRANSLATE(pScreen, prgnSrc, -dx, -dy);
+ REGION_INTERSECT(pScreen, &rgnDst, &pWin->borderClip, prgnSrc);
+
+ pbox = REGION_RECTS(&rgnDst);
+ nbox = REGION_NUM_RECTS(&rgnDst);
+ if(!nbox ||
+ !(pptSrc = (DDXPointPtr )malloc(nbox * sizeof(DDXPointRec)))) {
+ REGION_UNINIT(pScreen, &rgnDst);
+ return;
+ }
+ ppt = pptSrc;
+
+ while(nbox--) {
+ ppt->x = pbox->x1 + dx;
+ ppt->y = pbox->y1 + dy;
+ ppt++; pbox++;
+ }
+
+ infoRec->ScratchGC.planemask = ~0L;
+ infoRec->ScratchGC.alu = GXcopy;
+
+ XAADoBitBlt((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot,
+ &(infoRec->ScratchGC), &rgnDst, pptSrc);
+
+ free(pptSrc);
+ REGION_UNINIT(pScreen, &rgnDst);
+}
diff --git a/xorg-server/hw/xfree86/xaa/xaaGC.c b/xorg-server/hw/xfree86/xaa/xaaGC.c
index e6083d529..d029d982b 100644
--- a/xorg-server/hw/xfree86/xaa/xaaGC.c
+++ b/xorg-server/hw/xfree86/xaa/xaaGC.c
@@ -1,656 +1,656 @@
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <string.h>
-
-#include "misc.h"
-#include "xf86.h"
-#include "xf86_OSproc.h"
-
-#include <X11/X.h>
-#include "scrnintstr.h"
-#include "xf86str.h"
-#include "xaa.h"
-#include "xaalocal.h"
-#include "migc.h"
-#include "gcstruct.h"
-#include "pixmapstr.h"
-#include "xaawrap.h"
-
-static void XAAValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDraw);
-static void XAAChangeGC(GCPtr pGC, unsigned long mask);
-static void XAACopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
-static void XAADestroyGC(GCPtr pGC);
-static void XAAChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects);
-static void XAADestroyClip(GCPtr pGC);
-static void XAACopyClip(GCPtr pgcDst, GCPtr pgcSrc);
-
-GCFuncs XAAGCFuncs = {
- XAAValidateGC, XAAChangeGC, XAACopyGC, XAADestroyGC,
- XAAChangeClip, XAADestroyClip, XAACopyClip
-};
-
-extern GCOps XAAPixmapOps;
-
-Bool
-XAACreateGC(GCPtr pGC)
-{
- ScreenPtr pScreen = pGC->pScreen;
- XAAGCPtr pGCPriv = (XAAGCPtr)dixLookupPrivate(&pGC->devPrivates,
- XAAGetGCKey());
- Bool ret;
-
- XAA_SCREEN_PROLOGUE(pScreen,CreateGC);
-
- if((ret = (*pScreen->CreateGC)(pGC))) {
- pGCPriv->wrapOps = NULL;
- pGCPriv->wrapFuncs = pGC->funcs;
- pGCPriv->XAAOps = &XAAFallbackOps;
- pGCPriv->flags = 0;
- pGCPriv->DashLength = 0;
- pGCPriv->DashPattern = NULL;
- pGCPriv->changes = 0;
- /* initialize any other private fields here */
- pGC->funcs = &XAAGCFuncs;
- }
-
- XAA_SCREEN_EPILOGUE(pScreen,CreateGC,XAACreateGC);
-
- return ret;
-}
-
-
-static void
-XAAValidateGC(
- GCPtr pGC,
- unsigned long changes,
- DrawablePtr pDraw
-){
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
- XAA_GC_FUNC_PROLOGUE(pGC);
-
- (*pGC->funcs->ValidateGC)(pGC, changes, pDraw);
-
- if((changes & GCPlaneMask) &&
- ((pGC->planemask & infoRec->FullPlanemasks[pGC->depth - 1]) ==
- infoRec->FullPlanemasks[pGC->depth - 1]))
- {
- pGC->planemask = ~0;
- }
-
- if(pGC->depth != 32) {
- /* 0xffffffff is reserved for transparency */
- if(pGC->bgPixel == 0xffffffff)
- pGC->bgPixel = 0x7fffffff;
- if(pGC->fgPixel == 0xffffffff)
- pGC->fgPixel = 0x7fffffff;
- }
-
- if((pDraw->type == DRAWABLE_PIXMAP) && !IS_OFFSCREEN_PIXMAP(pDraw)){
- pGCPriv->flags = OPS_ARE_PIXMAP;
- pGCPriv->changes |= changes;
-
- /* make sure we're not using videomemory pixmaps to render
- onto system memory drawables */
-
- if((pGC->fillStyle == FillTiled) &&
- IS_OFFSCREEN_PIXMAP(pGC->tile.pixmap) &&
- !OFFSCREEN_PIXMAP_LOCKED(pGC->tile.pixmap)) {
-
- XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
- FBAreaPtr area = pPriv->offscreenArea;
-
- XAARemoveAreaCallback(area); /* clobbers pPriv->offscreenArea */
- xf86FreeOffscreenArea(area);
- }
- }
- else if(!infoRec->pScrn->vtSema && (pDraw->type == DRAWABLE_WINDOW)) {
- pGCPriv->flags = 0;
- pGCPriv->changes |= changes;
- }
- else {
- if(!(pGCPriv->flags & OPS_ARE_ACCEL)) {
- changes |= pGCPriv->changes;
- pGCPriv->changes = 0;
- }
- pGCPriv->flags = OPS_ARE_ACCEL;
-
-#if 1
- /* Ugh. If we can't use the blitter on offscreen pixmaps used
- as tiles, then we need to move them out as cfb can't handle
- tiles with non-zero origins */
-
- if((pGC->fillStyle == FillTiled) &&
- IS_OFFSCREEN_PIXMAP(pGC->tile.pixmap) &&
- (DO_PIXMAP_COPY != (*infoRec->TiledFillChooser)(pGC))) {
-
- XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
- FBAreaPtr area = pPriv->offscreenArea;
-
- XAARemoveAreaCallback(area); /* clobbers pPriv->offscreenArea */
- xf86FreeOffscreenArea(area);
- }
-#endif
- }
-
- XAA_GC_FUNC_EPILOGUE(pGC);
-
- if(!(pGCPriv->flags & OPS_ARE_ACCEL)) return;
-
- if((changes & GCTile) && !pGC->tileIsPixel && pGC->tile.pixmap){
- XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
-
- if(pixPriv->flags & DIRTY) {
- pixPriv->flags &= ~(DIRTY | REDUCIBILITY_MASK);
- pGC->tile.pixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
- }
- }
- if((changes & GCStipple) && pGC->stipple){
- XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple);
-
- if(pixPriv->flags & DIRTY) {
- pixPriv->flags &= ~(DIRTY | REDUCIBILITY_MASK);
- pGC->stipple->drawable.serialNumber = NEXT_SERIAL_NUMBER;
- }
- }
-
- /* If our Ops are still the default ones we need to allocate new ones */
- if(pGC->ops == &XAAFallbackOps) {
- if(!(pGCPriv->XAAOps = xalloc(sizeof(GCOps)))) {
- pGCPriv->XAAOps = &XAAFallbackOps;
- return;
- }
- /* make a modifiable copy of the default ops */
- memcpy(pGCPriv->XAAOps, &XAAFallbackOps, sizeof(GCOps));
- pGC->ops = pGCPriv->XAAOps;
- changes = ~0;
- }
-
- if(!changes) return;
-
- if((changes & GCDashList) && infoRec->ComputeDash)
- infoRec->ComputeDash(pGC);
-
- if(changes & infoRec->FillSpansMask)
- (*infoRec->ValidateFillSpans)(pGC, changes, pDraw);
-
- if(changes & infoRec->SetSpansMask)
- (*infoRec->ValidateSetSpans)(pGC, changes, pDraw);
-
- if(changes & infoRec->PutImageMask)
- (*infoRec->ValidatePutImage)(pGC, changes, pDraw);
-
- if(changes & infoRec->CopyAreaMask)
- (*infoRec->ValidateCopyArea)(pGC, changes, pDraw);
-
- if(changes & infoRec->CopyPlaneMask)
- (*infoRec->ValidateCopyPlane)(pGC, changes, pDraw);
-
- if(changes & infoRec->PolyPointMask)
- (*infoRec->ValidatePolyPoint)(pGC, changes, pDraw);
-
- if(changes & infoRec->PolylinesMask)
- (*infoRec->ValidatePolylines)(pGC, changes, pDraw);
-
- if(changes & infoRec->PolySegmentMask)
- (*infoRec->ValidatePolySegment)(pGC, changes, pDraw);
-
- if(changes & infoRec->PolyRectangleMask)
- (*infoRec->ValidatePolyRectangle)(pGC, changes, pDraw);
-
- if(changes & infoRec->PolyArcMask)
- (*infoRec->ValidatePolyArc)(pGC, changes, pDraw);
-
- if(changes & infoRec->FillPolygonMask)
- (*infoRec->ValidateFillPolygon)(pGC, changes, pDraw);
-
- if(changes & infoRec->PolyFillRectMask)
- (*infoRec->ValidatePolyFillRect)(pGC, changes, pDraw);
-
- if(changes & infoRec->PolyFillArcMask)
- (*infoRec->ValidatePolyFillArc)(pGC, changes, pDraw);
-
- if(changes & infoRec->PolyGlyphBltMask)
- (*infoRec->ValidatePolyGlyphBlt)(pGC, changes, pDraw);
-
- if(changes & infoRec->ImageGlyphBltMask)
- (*infoRec->ValidateImageGlyphBlt)(pGC, changes, pDraw);
-
- if(changes & infoRec->PolyText8Mask)
- (*infoRec->ValidatePolyText8)(pGC, changes, pDraw);
-
- if(changes & infoRec->PolyText16Mask)
- (*infoRec->ValidatePolyText16)(pGC, changes, pDraw);
-
- if(changes & infoRec->ImageText8Mask)
- (*infoRec->ValidateImageText8)(pGC, changes, pDraw);
-
- if(changes & infoRec->ImageText16Mask)
- (*infoRec->ValidateImageText16)(pGC, changes, pDraw);
-
- if(changes & infoRec->PushPixelsMask)
- (*infoRec->ValidatePushPixels)(pGC, changes, pDraw);
-}
-
-
-static void
-XAADestroyGC(GCPtr pGC)
-{
- XAA_GC_FUNC_PROLOGUE (pGC);
-
- if(pGCPriv->XAAOps != &XAAFallbackOps)
- xfree(pGCPriv->XAAOps);
-
- if(pGCPriv->DashPattern)
- xfree(pGCPriv->DashPattern);
-
- (*pGC->funcs->DestroyGC)(pGC);
- XAA_GC_FUNC_EPILOGUE (pGC);
-}
-
-static void
-XAAChangeGC (
- GCPtr pGC,
- unsigned long mask
-)
-{
- XAA_GC_FUNC_PROLOGUE (pGC);
- (*pGC->funcs->ChangeGC) (pGC, mask);
- XAA_GC_FUNC_EPILOGUE (pGC);
-
- /* we have to assume that shared memory pixmaps are dirty
- because we can't wrap all operations on them */
-
- if((mask & GCTile) && !pGC->tileIsPixel &&
- PIXMAP_IS_SHARED(pGC->tile.pixmap))
- {
- XAAPixmapPtr pPixPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
- pPixPriv->flags |= DIRTY;
- }
-
- if((mask & GCStipple) && PIXMAP_IS_SHARED(pGC->stipple)){
- XAAPixmapPtr pPixPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple);
- pPixPriv->flags |= DIRTY;
- }
-}
-
-static void
-XAACopyGC (
- GCPtr pGCSrc,
- unsigned long mask,
- GCPtr pGCDst)
-{
- XAA_GC_FUNC_PROLOGUE (pGCDst);
- (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
- XAA_GC_FUNC_EPILOGUE (pGCDst);
-}
-static void
-XAAChangeClip (
- GCPtr pGC,
- int type,
- pointer pvalue,
- int nrects )
-{
- XAA_GC_FUNC_PROLOGUE (pGC);
- (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
- XAA_GC_FUNC_EPILOGUE (pGC);
-}
-
-static void
-XAACopyClip(GCPtr pgcDst, GCPtr pgcSrc)
-{
- XAA_GC_FUNC_PROLOGUE (pgcDst);
- (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
- XAA_GC_FUNC_EPILOGUE (pgcDst);
-}
-
-static void
-XAADestroyClip(GCPtr pGC)
-{
- XAA_GC_FUNC_PROLOGUE (pGC);
- (* pGC->funcs->DestroyClip)(pGC);
- XAA_GC_FUNC_EPILOGUE (pGC);
-}
-
-/**** Pixmap Wrappers ****/
-
-
-
-static void
-XAAFillSpansPixmap(
- DrawablePtr pDraw,
- GC *pGC,
- int nInit,
- DDXPointPtr pptInit,
- int *pwidthInit,
- int fSorted
-){
- XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
- (*pGC->ops->FillSpans)(pDraw, pGC, nInit, pptInit, pwidthInit, fSorted);
- XAA_PIXMAP_OP_EPILOGUE(pGC);
-}
-
-static void
-XAASetSpansPixmap(
- DrawablePtr pDraw,
- GCPtr pGC,
- char *pcharsrc,
- register DDXPointPtr ppt,
- int *pwidth,
- int nspans,
- int fSorted
-){
- XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
- (*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, ppt, pwidth, nspans, fSorted);
- XAA_PIXMAP_OP_EPILOGUE(pGC);
-}
-
-static void
-XAAPutImagePixmap(
- DrawablePtr pDraw,
- GCPtr pGC,
- int depth,
- int x, int y, int w, int h,
- int leftPad,
- int format,
- char *pImage
-){
- XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
- (*pGC->ops->PutImage)(pDraw, pGC, depth, x, y, w, h,
- leftPad, format, pImage);
- XAA_PIXMAP_OP_EPILOGUE(pGC);
-}
-
-static RegionPtr
-XAACopyAreaPixmap(
- DrawablePtr pSrc,
- DrawablePtr pDst,
- GC *pGC,
- int srcx, int srcy,
- int width, int height,
- int dstx, int dsty
-){
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
- RegionPtr ret;
-
- if(infoRec->pScrn->vtSema &&
- ((pSrc->type == DRAWABLE_WINDOW) || IS_OFFSCREEN_PIXMAP(pSrc)))
- {
- if(infoRec->ReadPixmap && (pGC->alu == GXcopy) &&
- (pSrc->bitsPerPixel == pDst->bitsPerPixel) &&
- ((pGC->planemask & infoRec->FullPlanemasks[pSrc->depth - 1])
- == infoRec->FullPlanemasks[pSrc->depth - 1]))
- {
- XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pDst));
- pixPriv->flags |= DIRTY;
-
- return (XAABitBlt( pSrc, pDst, pGC,
- srcx, srcy, width, height, dstx, dsty,
- XAADoImageRead, 0L));
- } else
- if(infoRec->NeedToSync) {
- (*infoRec->Sync)(infoRec->pScrn);
- infoRec->NeedToSync = FALSE;
- }
- }
-
- {
- XAA_PIXMAP_OP_PROLOGUE(pGC, pDst);
- ret = (*pGC->ops->CopyArea)(pSrc, pDst,
- pGC, srcx, srcy, width, height, dstx, dsty);
- XAA_PIXMAP_OP_EPILOGUE(pGC);
- }
- return ret;
-}
-
-static RegionPtr
-XAACopyPlanePixmap(
- DrawablePtr pSrc,
- DrawablePtr pDst,
- GCPtr pGC,
- int srcx, int srcy,
- int width, int height,
- int dstx, int dsty,
- unsigned long bitPlane
-){
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
- RegionPtr ret;
-
- XAA_PIXMAP_OP_PROLOGUE(pGC, pDst);
-
- if(infoRec->pScrn->vtSema &&
- ((pSrc->type == DRAWABLE_WINDOW) || IS_OFFSCREEN_PIXMAP(pSrc))){
- if(infoRec->NeedToSync) {
- (*infoRec->Sync)(infoRec->pScrn);
- infoRec->NeedToSync = FALSE;
- }
- }
-
- ret = (*pGC->ops->CopyPlane)(pSrc, pDst,
- pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
- XAA_PIXMAP_OP_EPILOGUE(pGC);
- return ret;
-}
-
-static void
-XAAPolyPointPixmap(
- DrawablePtr pDraw,
- GCPtr pGC,
- int mode,
- int npt,
- xPoint *pptInit
-){
- XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
- (*pGC->ops->PolyPoint)(pDraw, pGC, mode, npt, pptInit);
- XAA_PIXMAP_OP_EPILOGUE(pGC);
-}
-
-
-static void
-XAAPolylinesPixmap(
- DrawablePtr pDraw,
- GCPtr pGC,
- int mode,
- int npt,
- DDXPointPtr pptInit
-){
- XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
- (*pGC->ops->Polylines)(pDraw, pGC, mode, npt, pptInit);
- XAA_PIXMAP_OP_EPILOGUE(pGC);
-}
-
-static void
-XAAPolySegmentPixmap(
- DrawablePtr pDraw,
- GCPtr pGC,
- int nseg,
- xSegment *pSeg
-){
- XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
- (*pGC->ops->PolySegment)(pDraw, pGC, nseg, pSeg);
- XAA_PIXMAP_OP_EPILOGUE(pGC);
-}
-
-static void
-XAAPolyRectanglePixmap(
- DrawablePtr pDraw,
- GCPtr pGC,
- int nRectsInit,
- xRectangle *pRectsInit
-){
- XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
- (*pGC->ops->PolyRectangle)(pDraw, pGC, nRectsInit, pRectsInit);
- XAA_PIXMAP_OP_EPILOGUE(pGC);
-}
-
-static void
-XAAPolyArcPixmap(
- DrawablePtr pDraw,
- GCPtr pGC,
- int narcs,
- xArc *parcs
-){
- XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
- (*pGC->ops->PolyArc)(pDraw, pGC, narcs, parcs);
- XAA_PIXMAP_OP_EPILOGUE(pGC);
-}
-
-static void
-XAAFillPolygonPixmap(
- DrawablePtr pDraw,
- GCPtr pGC,
- int shape,
- int mode,
- int count,
- DDXPointPtr ptsIn
-){
- XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
- (*pGC->ops->FillPolygon)(pDraw, pGC, shape, mode, count, ptsIn);
- XAA_PIXMAP_OP_EPILOGUE(pGC);
-}
-
-
-static void
-XAAPolyFillRectPixmap(
- DrawablePtr pDraw,
- GCPtr pGC,
- int nrectFill,
- xRectangle *prectInit
-){
- XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
- (*pGC->ops->PolyFillRect)(pDraw, pGC, nrectFill, prectInit);
- XAA_PIXMAP_OP_EPILOGUE(pGC);
-}
-
-
-static void
-XAAPolyFillArcPixmap(
- DrawablePtr pDraw,
- GCPtr pGC,
- int narcs,
- xArc *parcs
-){
- XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
- (*pGC->ops->PolyFillArc)(pDraw, pGC, narcs, parcs);
- XAA_PIXMAP_OP_EPILOGUE(pGC);
-}
-
-static int
-XAAPolyText8Pixmap(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x,
- int y,
- int count,
- char *chars
-){
- int ret;
-
- XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
- ret = (*pGC->ops->PolyText8)(pDraw, pGC, x, y, count, chars);
- XAA_PIXMAP_OP_EPILOGUE(pGC);
- return ret;
-}
-
-static int
-XAAPolyText16Pixmap(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x,
- int y,
- int count,
- unsigned short *chars
-){
- int ret;
-
- XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
- ret = (*pGC->ops->PolyText16)(pDraw, pGC, x, y, count, chars);
- XAA_PIXMAP_OP_EPILOGUE(pGC);
- return ret;
-}
-
-static void
-XAAImageText8Pixmap(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x,
- int y,
- int count,
- char *chars
-){
- XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
- (*pGC->ops->ImageText8)(pDraw, pGC, x, y, count, chars);
- XAA_PIXMAP_OP_EPILOGUE(pGC);
-}
-static void
-XAAImageText16Pixmap(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x,
- int y,
- int count,
- unsigned short *chars
-){
- XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
- (*pGC->ops->ImageText16)(pDraw, pGC, x, y, count, chars);
- XAA_PIXMAP_OP_EPILOGUE(pGC);
-}
-
-
-static void
-XAAImageGlyphBltPixmap(
- DrawablePtr pDraw,
- GCPtr pGC,
- int xInit, int yInit,
- unsigned int nglyph,
- CharInfoPtr *ppci,
- pointer pglyphBase
-){
- XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
- (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, xInit, yInit, nglyph,
- ppci, pglyphBase);
- XAA_PIXMAP_OP_EPILOGUE(pGC);
-}
-
-static void
-XAAPolyGlyphBltPixmap(
- DrawablePtr pDraw,
- GCPtr pGC,
- int xInit, int yInit,
- unsigned int nglyph,
- CharInfoPtr *ppci,
- pointer pglyphBase
-){
- XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
- (*pGC->ops->PolyGlyphBlt)(pDraw, pGC, xInit, yInit, nglyph,
- ppci, pglyphBase);
- XAA_PIXMAP_OP_EPILOGUE(pGC);
-}
-
-static void
-XAAPushPixelsPixmap(
- GCPtr pGC,
- PixmapPtr pBitMap,
- DrawablePtr pDraw,
- int dx, int dy, int xOrg, int yOrg
-){
- XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
- (*pGC->ops->PushPixels)(pGC, pBitMap, pDraw, dx, dy, xOrg, yOrg);
- XAA_PIXMAP_OP_EPILOGUE(pGC);
-}
-
-GCOps XAAPixmapOps = {
- XAAFillSpansPixmap, XAASetSpansPixmap,
- XAAPutImagePixmap, XAACopyAreaPixmap,
- XAACopyPlanePixmap, XAAPolyPointPixmap,
- XAAPolylinesPixmap, XAAPolySegmentPixmap,
- XAAPolyRectanglePixmap, XAAPolyArcPixmap,
- XAAFillPolygonPixmap, XAAPolyFillRectPixmap,
- XAAPolyFillArcPixmap, XAAPolyText8Pixmap,
- XAAPolyText16Pixmap, XAAImageText8Pixmap,
- XAAImageText16Pixmap, XAAImageGlyphBltPixmap,
- XAAPolyGlyphBltPixmap, XAAPushPixelsPixmap,
- {NULL} /* devPrivate */
-};
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <string.h>
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include <X11/X.h>
+#include "scrnintstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "migc.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "xaawrap.h"
+
+static void XAAValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDraw);
+static void XAAChangeGC(GCPtr pGC, unsigned long mask);
+static void XAACopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
+static void XAADestroyGC(GCPtr pGC);
+static void XAAChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects);
+static void XAADestroyClip(GCPtr pGC);
+static void XAACopyClip(GCPtr pgcDst, GCPtr pgcSrc);
+
+GCFuncs XAAGCFuncs = {
+ XAAValidateGC, XAAChangeGC, XAACopyGC, XAADestroyGC,
+ XAAChangeClip, XAADestroyClip, XAACopyClip
+};
+
+extern GCOps XAAPixmapOps;
+
+Bool
+XAACreateGC(GCPtr pGC)
+{
+ ScreenPtr pScreen = pGC->pScreen;
+ XAAGCPtr pGCPriv = (XAAGCPtr)dixLookupPrivate(&pGC->devPrivates,
+ XAAGetGCKey());
+ Bool ret;
+
+ XAA_SCREEN_PROLOGUE(pScreen,CreateGC);
+
+ if((ret = (*pScreen->CreateGC)(pGC))) {
+ pGCPriv->wrapOps = NULL;
+ pGCPriv->wrapFuncs = pGC->funcs;
+ pGCPriv->XAAOps = &XAAFallbackOps;
+ pGCPriv->flags = 0;
+ pGCPriv->DashLength = 0;
+ pGCPriv->DashPattern = NULL;
+ pGCPriv->changes = 0;
+ /* initialize any other private fields here */
+ pGC->funcs = &XAAGCFuncs;
+ }
+
+ XAA_SCREEN_EPILOGUE(pScreen,CreateGC,XAACreateGC);
+
+ return ret;
+}
+
+
+static void
+XAAValidateGC(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAA_GC_FUNC_PROLOGUE(pGC);
+
+ (*pGC->funcs->ValidateGC)(pGC, changes, pDraw);
+
+ if((changes & GCPlaneMask) &&
+ ((pGC->planemask & infoRec->FullPlanemasks[pGC->depth - 1]) ==
+ infoRec->FullPlanemasks[pGC->depth - 1]))
+ {
+ pGC->planemask = ~0;
+ }
+
+ if(pGC->depth != 32) {
+ /* 0xffffffff is reserved for transparency */
+ if(pGC->bgPixel == 0xffffffff)
+ pGC->bgPixel = 0x7fffffff;
+ if(pGC->fgPixel == 0xffffffff)
+ pGC->fgPixel = 0x7fffffff;
+ }
+
+ if((pDraw->type == DRAWABLE_PIXMAP) && !IS_OFFSCREEN_PIXMAP(pDraw)){
+ pGCPriv->flags = OPS_ARE_PIXMAP;
+ pGCPriv->changes |= changes;
+
+ /* make sure we're not using videomemory pixmaps to render
+ onto system memory drawables */
+
+ if((pGC->fillStyle == FillTiled) &&
+ IS_OFFSCREEN_PIXMAP(pGC->tile.pixmap) &&
+ !OFFSCREEN_PIXMAP_LOCKED(pGC->tile.pixmap)) {
+
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
+ FBAreaPtr area = pPriv->offscreenArea;
+
+ XAARemoveAreaCallback(area); /* clobbers pPriv->offscreenArea */
+ xf86FreeOffscreenArea(area);
+ }
+ }
+ else if(!infoRec->pScrn->vtSema && (pDraw->type == DRAWABLE_WINDOW)) {
+ pGCPriv->flags = 0;
+ pGCPriv->changes |= changes;
+ }
+ else {
+ if(!(pGCPriv->flags & OPS_ARE_ACCEL)) {
+ changes |= pGCPriv->changes;
+ pGCPriv->changes = 0;
+ }
+ pGCPriv->flags = OPS_ARE_ACCEL;
+
+#if 1
+ /* Ugh. If we can't use the blitter on offscreen pixmaps used
+ as tiles, then we need to move them out as cfb can't handle
+ tiles with non-zero origins */
+
+ if((pGC->fillStyle == FillTiled) &&
+ IS_OFFSCREEN_PIXMAP(pGC->tile.pixmap) &&
+ (DO_PIXMAP_COPY != (*infoRec->TiledFillChooser)(pGC))) {
+
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
+ FBAreaPtr area = pPriv->offscreenArea;
+
+ XAARemoveAreaCallback(area); /* clobbers pPriv->offscreenArea */
+ xf86FreeOffscreenArea(area);
+ }
+#endif
+ }
+
+ XAA_GC_FUNC_EPILOGUE(pGC);
+
+ if(!(pGCPriv->flags & OPS_ARE_ACCEL)) return;
+
+ if((changes & GCTile) && !pGC->tileIsPixel && pGC->tile.pixmap){
+ XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
+
+ if(pixPriv->flags & DIRTY) {
+ pixPriv->flags &= ~(DIRTY | REDUCIBILITY_MASK);
+ pGC->tile.pixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ }
+ }
+ if((changes & GCStipple) && pGC->stipple){
+ XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple);
+
+ if(pixPriv->flags & DIRTY) {
+ pixPriv->flags &= ~(DIRTY | REDUCIBILITY_MASK);
+ pGC->stipple->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ }
+ }
+
+ /* If our Ops are still the default ones we need to allocate new ones */
+ if(pGC->ops == &XAAFallbackOps) {
+ if(!(pGCPriv->XAAOps = malloc(sizeof(GCOps)))) {
+ pGCPriv->XAAOps = &XAAFallbackOps;
+ return;
+ }
+ /* make a modifiable copy of the default ops */
+ memcpy(pGCPriv->XAAOps, &XAAFallbackOps, sizeof(GCOps));
+ pGC->ops = pGCPriv->XAAOps;
+ changes = ~0;
+ }
+
+ if(!changes) return;
+
+ if((changes & GCDashList) && infoRec->ComputeDash)
+ infoRec->ComputeDash(pGC);
+
+ if(changes & infoRec->FillSpansMask)
+ (*infoRec->ValidateFillSpans)(pGC, changes, pDraw);
+
+ if(changes & infoRec->SetSpansMask)
+ (*infoRec->ValidateSetSpans)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PutImageMask)
+ (*infoRec->ValidatePutImage)(pGC, changes, pDraw);
+
+ if(changes & infoRec->CopyAreaMask)
+ (*infoRec->ValidateCopyArea)(pGC, changes, pDraw);
+
+ if(changes & infoRec->CopyPlaneMask)
+ (*infoRec->ValidateCopyPlane)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PolyPointMask)
+ (*infoRec->ValidatePolyPoint)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PolylinesMask)
+ (*infoRec->ValidatePolylines)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PolySegmentMask)
+ (*infoRec->ValidatePolySegment)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PolyRectangleMask)
+ (*infoRec->ValidatePolyRectangle)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PolyArcMask)
+ (*infoRec->ValidatePolyArc)(pGC, changes, pDraw);
+
+ if(changes & infoRec->FillPolygonMask)
+ (*infoRec->ValidateFillPolygon)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PolyFillRectMask)
+ (*infoRec->ValidatePolyFillRect)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PolyFillArcMask)
+ (*infoRec->ValidatePolyFillArc)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PolyGlyphBltMask)
+ (*infoRec->ValidatePolyGlyphBlt)(pGC, changes, pDraw);
+
+ if(changes & infoRec->ImageGlyphBltMask)
+ (*infoRec->ValidateImageGlyphBlt)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PolyText8Mask)
+ (*infoRec->ValidatePolyText8)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PolyText16Mask)
+ (*infoRec->ValidatePolyText16)(pGC, changes, pDraw);
+
+ if(changes & infoRec->ImageText8Mask)
+ (*infoRec->ValidateImageText8)(pGC, changes, pDraw);
+
+ if(changes & infoRec->ImageText16Mask)
+ (*infoRec->ValidateImageText16)(pGC, changes, pDraw);
+
+ if(changes & infoRec->PushPixelsMask)
+ (*infoRec->ValidatePushPixels)(pGC, changes, pDraw);
+}
+
+
+static void
+XAADestroyGC(GCPtr pGC)
+{
+ XAA_GC_FUNC_PROLOGUE (pGC);
+
+ if(pGCPriv->XAAOps != &XAAFallbackOps)
+ free(pGCPriv->XAAOps);
+
+ if(pGCPriv->DashPattern)
+ free(pGCPriv->DashPattern);
+
+ (*pGC->funcs->DestroyGC)(pGC);
+ XAA_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+XAAChangeGC (
+ GCPtr pGC,
+ unsigned long mask
+)
+{
+ XAA_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->ChangeGC) (pGC, mask);
+ XAA_GC_FUNC_EPILOGUE (pGC);
+
+ /* we have to assume that shared memory pixmaps are dirty
+ because we can't wrap all operations on them */
+
+ if((mask & GCTile) && !pGC->tileIsPixel &&
+ PIXMAP_IS_SHARED(pGC->tile.pixmap))
+ {
+ XAAPixmapPtr pPixPriv = XAA_GET_PIXMAP_PRIVATE(pGC->tile.pixmap);
+ pPixPriv->flags |= DIRTY;
+ }
+
+ if((mask & GCStipple) && PIXMAP_IS_SHARED(pGC->stipple)){
+ XAAPixmapPtr pPixPriv = XAA_GET_PIXMAP_PRIVATE(pGC->stipple);
+ pPixPriv->flags |= DIRTY;
+ }
+}
+
+static void
+XAACopyGC (
+ GCPtr pGCSrc,
+ unsigned long mask,
+ GCPtr pGCDst)
+{
+ XAA_GC_FUNC_PROLOGUE (pGCDst);
+ (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
+ XAA_GC_FUNC_EPILOGUE (pGCDst);
+}
+static void
+XAAChangeClip (
+ GCPtr pGC,
+ int type,
+ pointer pvalue,
+ int nrects )
+{
+ XAA_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
+ XAA_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+XAACopyClip(GCPtr pgcDst, GCPtr pgcSrc)
+{
+ XAA_GC_FUNC_PROLOGUE (pgcDst);
+ (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
+ XAA_GC_FUNC_EPILOGUE (pgcDst);
+}
+
+static void
+XAADestroyClip(GCPtr pGC)
+{
+ XAA_GC_FUNC_PROLOGUE (pGC);
+ (* pGC->funcs->DestroyClip)(pGC);
+ XAA_GC_FUNC_EPILOGUE (pGC);
+}
+
+/**** Pixmap Wrappers ****/
+
+
+
+static void
+XAAFillSpansPixmap(
+ DrawablePtr pDraw,
+ GC *pGC,
+ int nInit,
+ DDXPointPtr pptInit,
+ int *pwidthInit,
+ int fSorted
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->FillSpans)(pDraw, pGC, nInit, pptInit, pwidthInit, fSorted);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+static void
+XAASetSpansPixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ char *pcharsrc,
+ register DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ int fSorted
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, ppt, pwidth, nspans, fSorted);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAPutImagePixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int depth,
+ int x, int y, int w, int h,
+ int leftPad,
+ int format,
+ char *pImage
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PutImage)(pDraw, pGC, depth, x, y, w, h,
+ leftPad, format, pImage);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+static RegionPtr
+XAACopyAreaPixmap(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ RegionPtr ret;
+
+ if(infoRec->pScrn->vtSema &&
+ ((pSrc->type == DRAWABLE_WINDOW) || IS_OFFSCREEN_PIXMAP(pSrc)))
+ {
+ if(infoRec->ReadPixmap && (pGC->alu == GXcopy) &&
+ (pSrc->bitsPerPixel == pDst->bitsPerPixel) &&
+ ((pGC->planemask & infoRec->FullPlanemasks[pSrc->depth - 1])
+ == infoRec->FullPlanemasks[pSrc->depth - 1]))
+ {
+ XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pDst));
+ pixPriv->flags |= DIRTY;
+
+ return (XAABitBlt( pSrc, pDst, pGC,
+ srcx, srcy, width, height, dstx, dsty,
+ XAADoImageRead, 0L));
+ } else
+ if(infoRec->NeedToSync) {
+ (*infoRec->Sync)(infoRec->pScrn);
+ infoRec->NeedToSync = FALSE;
+ }
+ }
+
+ {
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDst);
+ ret = (*pGC->ops->CopyArea)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+ }
+ return ret;
+}
+
+static RegionPtr
+XAACopyPlanePixmap(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty,
+ unsigned long bitPlane
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ RegionPtr ret;
+
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDst);
+
+ if(infoRec->pScrn->vtSema &&
+ ((pSrc->type == DRAWABLE_WINDOW) || IS_OFFSCREEN_PIXMAP(pSrc))){
+ if(infoRec->NeedToSync) {
+ (*infoRec->Sync)(infoRec->pScrn);
+ infoRec->NeedToSync = FALSE;
+ }
+ }
+
+ ret = (*pGC->ops->CopyPlane)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+ return ret;
+}
+
+static void
+XAAPolyPointPixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ xPoint *pptInit
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PolyPoint)(pDraw, pGC, mode, npt, pptInit);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+
+static void
+XAAPolylinesPixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pptInit
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->Polylines)(pDraw, pGC, mode, npt, pptInit);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAPolySegmentPixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PolySegment)(pDraw, pGC, nseg, pSeg);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAPolyRectanglePixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nRectsInit,
+ xRectangle *pRectsInit
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PolyRectangle)(pDraw, pGC, nRectsInit, pRectsInit);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAPolyArcPixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PolyArc)(pDraw, pGC, narcs, parcs);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAFillPolygonPixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->FillPolygon)(pDraw, pGC, shape, mode, count, ptsIn);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+
+static void
+XAAPolyFillRectPixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PolyFillRect)(pDraw, pGC, nrectFill, prectInit);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+
+static void
+XAAPolyFillArcPixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PolyFillArc)(pDraw, pGC, narcs, parcs);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+static int
+XAAPolyText8Pixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars
+){
+ int ret;
+
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ ret = (*pGC->ops->PolyText8)(pDraw, pGC, x, y, count, chars);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+ return ret;
+}
+
+static int
+XAAPolyText16Pixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars
+){
+ int ret;
+
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ ret = (*pGC->ops->PolyText16)(pDraw, pGC, x, y, count, chars);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+ return ret;
+}
+
+static void
+XAAImageText8Pixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->ImageText8)(pDraw, pGC, x, y, count, chars);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+static void
+XAAImageText16Pixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->ImageText16)(pDraw, pGC, x, y, count, chars);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+
+static void
+XAAImageGlyphBltPixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, xInit, yInit, nglyph,
+ ppci, pglyphBase);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAPolyGlyphBltPixmap(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PolyGlyphBlt)(pDraw, pGC, xInit, yInit, nglyph,
+ ppci, pglyphBase);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+static void
+XAAPushPixelsPixmap(
+ GCPtr pGC,
+ PixmapPtr pBitMap,
+ DrawablePtr pDraw,
+ int dx, int dy, int xOrg, int yOrg
+){
+ XAA_PIXMAP_OP_PROLOGUE(pGC, pDraw);
+ (*pGC->ops->PushPixels)(pGC, pBitMap, pDraw, dx, dy, xOrg, yOrg);
+ XAA_PIXMAP_OP_EPILOGUE(pGC);
+}
+
+GCOps XAAPixmapOps = {
+ XAAFillSpansPixmap, XAASetSpansPixmap,
+ XAAPutImagePixmap, XAACopyAreaPixmap,
+ XAACopyPlanePixmap, XAAPolyPointPixmap,
+ XAAPolylinesPixmap, XAAPolySegmentPixmap,
+ XAAPolyRectanglePixmap, XAAPolyArcPixmap,
+ XAAFillPolygonPixmap, XAAPolyFillRectPixmap,
+ XAAPolyFillArcPixmap, XAAPolyText8Pixmap,
+ XAAPolyText16Pixmap, XAAImageText8Pixmap,
+ XAAImageText16Pixmap, XAAImageGlyphBltPixmap,
+ XAAPolyGlyphBltPixmap, XAAPushPixelsPixmap,
+ {NULL} /* devPrivate */
+};
diff --git a/xorg-server/hw/xfree86/xaa/xaaImage.c b/xorg-server/hw/xfree86/xaa/xaaImage.c
index 4933beea3..c8d98c7d0 100644
--- a/xorg-server/hw/xfree86/xaa/xaaImage.c
+++ b/xorg-server/hw/xfree86/xaa/xaaImage.c
@@ -1,521 +1,521 @@
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "misc.h"
-#include "xf86.h"
-#include "xf86_OSproc.h"
-#include "servermd.h"
-
-#include <X11/X.h>
-#include "scrnintstr.h"
-#include "mi.h"
-#include "pixmapstr.h"
-#include "xf86str.h"
-#include "xaa.h"
-#include "xaalocal.h"
-
-void XAAMoveDWORDS_FixedBase(
- register CARD32* dest,
- register CARD32* src,
- register int dwords )
-{
- while(dwords & ~0x03) {
- *dest = *src;
- *dest = *(src + 1);
- *dest = *(src + 2);
- *dest = *(src + 3);
- dwords -= 4;
- src += 4;
- }
-
- if(!dwords) return;
- *dest = *src;
- if(dwords == 1) return;
- *dest = *(src + 1);
- if(dwords == 2) return;
- *dest = *(src + 2);
-}
-
-void XAAMoveDWORDS(
- register CARD32* dest,
- register CARD32* src,
- register int dwords )
-{
- while(dwords & ~0x03) {
- *dest = *src;
- *(dest + 1) = *(src + 1);
- *(dest + 2) = *(src + 2);
- *(dest + 3) = *(src + 3);
- src += 4;
- dest += 4;
- dwords -= 4;
- }
- if(!dwords) return;
- *dest = *src;
- if(dwords == 1) return;
- *(dest + 1) = *(src + 1);
- if(dwords == 2) return;
- *(dest + 2) = *(src + 2);
-}
-
-void XAAMoveDWORDS_FixedSrc(
- register CARD32* dest,
- register CARD32* src,
- register int dwords )
-{
- while(dwords & ~0x03) {
- *dest = *src;
- *(dest + 1) = *src;
- *(dest + 2) = *src;
- *(dest + 3) = *src;
- dest += 4;
- dwords -= 4;
- }
- if(!dwords) return;
- *dest = *src;
- if(dwords == 1) return;
- *(dest + 1) = *src;
- if(dwords == 2) return;
- *(dest + 2) = *src;
-}
-
-static void
-XAAWritePixmap32To24(
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned char *srcInit,
- int srcwidth, /* bytes */
- int rop,
- unsigned int planemask,
- int trans
-){
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
- int count, dwords = bytes_to_int32(w * 3);
- CARD32 *src, *dst;
- Bool PlusOne = FALSE;
-
- if((infoRec->ImageWriteFlags & CPU_TRANSFER_PAD_QWORD) &&
- ((dwords * h) & 0x01)) {
- PlusOne = TRUE;
- }
-
- (*infoRec->SetupForImageWrite)(pScrn, rop, planemask, trans, 24, 24);
- (*infoRec->SubsequentImageWriteRect)(pScrn, x, y, w, h, 0);
-
- if(dwords > infoRec->ImageWriteRange) {
- dst = (CARD32*)infoRec->ImageWriteBase;
- while(h--) {
- src = (CARD32*)srcInit;
- count = w;
-
- while(count >= 4) {
- *dst = (src[0] & 0x00ffffff) | (src[1] << 24);
- *dst = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16);
- *dst = ((src[2] >> 16) & 0x000000ff) | (src[3] << 8);
- src += 4;
- count -= 4;
- }
- switch(count) {
- case 0: break;
- case 1: *dst = src[0];
- break;
- case 2: *dst = (src[0] & 0x00ffffff) | (src[1] << 24);
- *dst = src[1] >> 8;
- break;
- default: *dst = (src[0] & 0x00ffffff) | (src[1] << 24);
- *dst = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16);
- *dst = src[2] >> 16;
- break;
- }
- srcInit += srcwidth;
- }
- } else {
- while(h--) {
- dst = (CARD32*)infoRec->ImageWriteBase;
- src = (CARD32*)srcInit;
- count = w;
-
- while(count >= 4) {
- dst[0] = (src[0] & 0x00ffffff) | (src[1] << 24);
- dst[1] = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16);
- dst[2] = ((src[2] >> 16) & 0x000000ff) | (src[3] << 8);
- dst += 3;
- src += 4;
- count -= 4;
- }
- switch(count) {
- case 0: break;
- case 1: dst[0] = src[0];
- break;
- case 2: dst[0] = (src[0] & 0x00ffffff) | (src[1] << 24);
- dst[1] = src[1] >> 8;
- break;
- default: dst[0] = (src[0] & 0x00ffffff) | (src[1] << 24);
- dst[1] = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16);
- dst[2] = src[2] >> 16;
- break;
- }
- srcInit += srcwidth;
- }
- }
-
- if(PlusOne) {
- CARD32* base = (CARD32*)infoRec->ImageWriteBase;
- *base = 0x00000000;
- }
-
- if(infoRec->ImageWriteFlags & SYNC_AFTER_IMAGE_WRITE)
- (*infoRec->Sync)(pScrn);
- else SET_SYNC_FLAG(infoRec);
-
-}
-
-void
-XAAWritePixmap (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned char *src,
- int srcwidth, /* bytes */
- int rop,
- unsigned int planemask,
- int trans,
- int bpp, int depth
-){
- XAAInfoRecPtr infoRec;
- int dwords, skipleft, Bpp;
- Bool beCareful, PlusOne;
-
- if((bpp == 32) && (pScrn->bitsPerPixel == 24)) {
- XAAWritePixmap32To24(pScrn, x, y, w, h, src, srcwidth,
- rop, planemask, trans);
- return;
- }
-
- infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
- beCareful = PlusOne = FALSE;
- Bpp = bpp >> 3;
-
- if((skipleft = (long)src & 0x03L)) {
- if(!(infoRec->ImageWriteFlags & LEFT_EDGE_CLIPPING)) {
- skipleft = 0;
- beCareful = TRUE;
- goto BAD_ALIGNMENT;
- }
-
- if(Bpp == 3)
- skipleft = 4 - skipleft;
- else
- skipleft /= Bpp;
-
- if((x < skipleft) && !(infoRec->ImageWriteFlags &
- LEFT_EDGE_CLIPPING_NEGATIVE_X)) {
- skipleft = 0;
- beCareful = TRUE;
- goto BAD_ALIGNMENT;
- }
-
- x -= skipleft;
- w += skipleft;
-
- if(Bpp == 3)
- src -= 3 * skipleft;
- else /* is this Alpha friendly ? */
- src = (unsigned char*)((long)src & ~0x03L);
- }
-
-BAD_ALIGNMENT:
-
- dwords = bytes_to_int32(w * Bpp);
-
- if((infoRec->ImageWriteFlags & CPU_TRANSFER_PAD_QWORD) &&
- ((dwords * h) & 0x01)) {
- PlusOne = TRUE;
- }
-
-
- (*infoRec->SetupForImageWrite)(pScrn, rop, planemask, trans, bpp, depth);
- (*infoRec->SubsequentImageWriteRect)(pScrn, x, y, w, h, skipleft);
-
- if(beCareful) {
- /* in cases with bad alignment we have to be careful not
- to read beyond the end of the source */
- if(((x * Bpp) + (dwords << 2)) > srcwidth) h--;
- else beCareful = FALSE;
- }
-
- if(dwords > infoRec->ImageWriteRange) {
- while(h--) {
- XAAMoveDWORDS_FixedBase((CARD32*)infoRec->ImageWriteBase,
- (CARD32*)src, dwords);
- src += srcwidth;
- }
- if(beCareful) {
- int shift = ((long)src & 0x03L) << 3;
- if(--dwords)
- XAAMoveDWORDS_FixedBase((CARD32*)infoRec->ImageWriteBase,
- (CARD32*)src, dwords);
- src = (unsigned char*)((long)(src + (dwords << 2)) & ~0x03L);
- *((CARD32*)infoRec->ImageWriteBase) = *((CARD32*)src) >> shift;
- }
- } else {
- if(srcwidth == (dwords << 2)) {
- int decrement = infoRec->ImageWriteRange/dwords;
-
- while(h > decrement) {
- XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
- (CARD32*)src, dwords * decrement);
- src += (srcwidth * decrement);
- h -= decrement;
- }
- if(h) {
- XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
- (CARD32*)src, dwords * h);
- if(beCareful) src += (srcwidth * h);
- }
- } else {
- while(h--) {
- XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
- (CARD32*)src, dwords);
- src += srcwidth;
- }
- }
-
- if(beCareful) {
- int shift = ((long)src & 0x03L) << 3;
- if(--dwords)
- XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
- (CARD32*)src, dwords);
- src = (unsigned char*)((long)(src + (dwords << 2)) & ~0x03L);
-
- ((CARD32*)infoRec->ImageWriteBase)[dwords] =
- *((CARD32*)src) >> shift;
- }
- }
-
- if(PlusOne) {
- CARD32* base = (CARD32*)infoRec->ImageWriteBase;
- *base = 0x00000000;
- }
-
- if(infoRec->ImageWriteFlags & SYNC_AFTER_IMAGE_WRITE)
- (*infoRec->Sync)(pScrn);
- else SET_SYNC_FLAG(infoRec);
-}
-
-
-void
-XAAWritePixmapScanline (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned char *src,
- int srcwidth, /* bytes */
- int rop,
- unsigned int planemask,
- int trans,
- int bpp, int depth
-){
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
- int dwords, skipleft, bufferNo = 0, Bpp = bpp >> 3;
- Bool beCareful = FALSE;
- CARD32* base;
-
- if((skipleft = (long)src & 0x03L)) {
- if(!(infoRec->ScanlineImageWriteFlags & LEFT_EDGE_CLIPPING)) {
- skipleft = 0;
- beCareful = TRUE;
- goto BAD_ALIGNMENT;
- }
-
- if(Bpp == 3)
- skipleft = 4 - skipleft;
- else
- skipleft /= Bpp;
-
- if((x < skipleft) && !(infoRec->ScanlineImageWriteFlags &
- LEFT_EDGE_CLIPPING_NEGATIVE_X)) {
- skipleft = 0;
- beCareful = TRUE;
- goto BAD_ALIGNMENT;
- }
-
- x -= skipleft;
- w += skipleft;
-
- if(Bpp == 3)
- src -= 3 * skipleft;
- else
- src = (unsigned char*)((long)src & ~0x03L);
- }
-
-BAD_ALIGNMENT:
-
- dwords = bytes_to_int32(w * Bpp);
-
- (*infoRec->SetupForScanlineImageWrite)(
- pScrn, rop, planemask, trans, bpp, depth);
- (*infoRec->SubsequentScanlineImageWriteRect)(pScrn, x, y, w, h, skipleft);
-
- if(beCareful) {
- /* in cases with bad alignment we have to be careful not
- to read beyond the end of the source */
- if(((x * Bpp) + (dwords << 2)) > srcwidth) h--;
- else beCareful = FALSE;
- }
-
- while(h--) {
- base = (CARD32*)infoRec->ScanlineImageWriteBuffers[bufferNo];
- XAAMoveDWORDS(base, (CARD32*)src, dwords);
- (*infoRec->SubsequentImageWriteScanline)(pScrn, bufferNo++);
- src += srcwidth;
- if(bufferNo >= infoRec->NumScanlineImageWriteBuffers)
- bufferNo = 0;
- }
-
- if(beCareful) {
- int shift = ((long)src & 0x03L) << 3;
- base = (CARD32*)infoRec->ScanlineImageWriteBuffers[bufferNo];
- if(--dwords)
- XAAMoveDWORDS(base,(CARD32*)src, dwords);
- src = (unsigned char*)((long)(src + (dwords << 2)) & ~0x03L);
-
- base[dwords] = *((CARD32*)src) >> shift;
- (*infoRec->SubsequentImageWriteScanline)(pScrn, bufferNo);
- }
-
- SET_SYNC_FLAG(infoRec);
-}
-
-
-void
-XAAPutImage(
- DrawablePtr pDraw,
- GCPtr pGC,
- int depth,
- int x,
- int y,
- int w,
- int h,
- int leftPad,
- int format,
- char *pImage
-){
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
- int bpp = BitsPerPixel(depth);
- Bool depthBug = FALSE;
- if(!w || !h) return;
-
- if(!REGION_NUM_RECTS(pGC->pCompositeClip))
- return;
-
- depthBug = XAA_DEPTH_BUG(pGC);
-
- if(((format == ZPixmap) && infoRec->WritePixmap &&
- ((pDraw->bitsPerPixel == bpp) ||
- ((pDraw->bitsPerPixel == 24) && (bpp == 32) &&
- (infoRec->WritePixmapFlags & CONVERT_32BPP_TO_24BPP))) &&
- CHECK_ROP(pGC,infoRec->WritePixmapFlags) &&
- CHECK_ROPSRC(pGC,infoRec->WritePixmapFlags) &&
- CHECK_PLANEMASK(pGC,infoRec->WritePixmapFlags) &&
- CHECK_NO_GXCOPY(pGC,infoRec->WritePixmapFlags)) ||
- ((format == XYBitmap) && !depthBug && infoRec->WriteBitmap &&
- CHECK_ROP(pGC,infoRec->WriteBitmapFlags) &&
- CHECK_ROPSRC(pGC,infoRec->WriteBitmapFlags) &&
- CHECK_PLANEMASK(pGC,infoRec->WriteBitmapFlags) &&
- CHECK_COLORS(pGC,infoRec->WriteBitmapFlags) &&
- !(infoRec->WriteBitmapFlags & TRANSPARENCY_ONLY)) ||
- ((format == XYPixmap) && !depthBug && infoRec->WriteBitmap &&
- CHECK_ROP(pGC,infoRec->WriteBitmapFlags) &&
- CHECK_ROPSRC(pGC,infoRec->WriteBitmapFlags) &&
- !(infoRec->WriteBitmapFlags & NO_PLANEMASK) &&
- !(infoRec->WriteBitmapFlags & TRANSPARENCY_ONLY))){
-
- int MaxBoxes = REGION_NUM_RECTS(pGC->pCompositeClip);
- BoxPtr pbox, pClipBoxes;
- int nboxes, srcx, srcy, srcwidth;
- xRectangle TheRect;
-
- TheRect.x = pDraw->x + x;
- TheRect.y = pDraw->y + y;
- TheRect.width = w;
- TheRect.height = h;
-
- if(MaxBoxes > (infoRec->PreAllocSize/sizeof(BoxRec))) {
- pClipBoxes = xalloc(MaxBoxes * sizeof(BoxRec));
- if(!pClipBoxes) return;
- } else pClipBoxes = (BoxPtr)infoRec->PreAllocMem;
-
- nboxes = XAAGetRectClipBoxes(pGC, pClipBoxes, 1, &TheRect);
- pbox = pClipBoxes;
-
- if(format == XYBitmap) {
- srcwidth = BitmapBytePad(leftPad + w);
- while(nboxes--) {
- srcx = pbox->x1 - TheRect.x + leftPad;
- srcy = pbox->y1 - TheRect.y;
- (*infoRec->WriteBitmap)(infoRec->pScrn, pbox->x1, pbox->y1,
- pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
- (unsigned char*)pImage +
- (srcwidth * srcy) + ((srcx >> 5) << 2),
- srcwidth, srcx & 31, pGC->fgPixel, pGC->bgPixel,
- pGC->alu, pGC->planemask);
- pbox++;
- }
- } else if(format == ZPixmap) {
- int Bpp = bpp >> 3;
- srcwidth = PixmapBytePad(leftPad + w, depth);
- while(nboxes--) {
- srcx = pbox->x1 - TheRect.x + leftPad;
- srcy = pbox->y1 - TheRect.y;
- (*infoRec->WritePixmap)(infoRec->pScrn, pbox->x1, pbox->y1,
- pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
- (unsigned char*)pImage +
- (srcwidth * srcy) + (srcx * Bpp),
- srcwidth, pGC->alu, pGC->planemask, -1,
- Bpp << 3, depth);
- pbox++;
- }
- } else { /* XYPixmap */
- int depth = pGC->depth;
- int numBox, increment;
- unsigned long i, mask;
- BoxPtr pntBox;
-
- srcwidth = BitmapBytePad(w + leftPad);
- increment = h * srcwidth;
- i = 1 << (depth - 1);
- mask = ~0;
-
- if((infoRec->pScrn->overlayFlags & OVERLAY_8_32_PLANAR) &&
- (pGC->depth == 8)){
- i = 0x80000000; mask = 0xff000000;
- }
-
- for(; i & mask; i >>= 1, pImage += increment) {
- if(i & pGC->planemask) {
- pntBox = pbox;
- numBox = nboxes;
- while(numBox--) {
- srcx = pntBox->x1 - TheRect.x + leftPad;
- srcy = pntBox->y1 - TheRect.y;
- (*infoRec->WriteBitmap)(infoRec->pScrn,
- pntBox->x1, pntBox->y1,
- pntBox->x2 - pntBox->x1,
- pntBox->y2 - pntBox->y1,
- (unsigned char*)pImage +
- (srcwidth * srcy) + ((srcx >> 5) << 2),
- srcwidth, srcx & 31, ~0, 0, pGC->alu, i);
- pntBox++;
- }
- }
- }
-
- }
-
- if(pClipBoxes != (BoxPtr)infoRec->PreAllocMem)
- xfree(pClipBoxes);
- } else
- XAAFallbackOps.PutImage(pDraw, pGC, depth, x, y, w, h, leftPad,
- format, pImage);
-}
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+#include "servermd.h"
+
+#include <X11/X.h>
+#include "scrnintstr.h"
+#include "mi.h"
+#include "pixmapstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+
+void XAAMoveDWORDS_FixedBase(
+ register CARD32* dest,
+ register CARD32* src,
+ register int dwords )
+{
+ while(dwords & ~0x03) {
+ *dest = *src;
+ *dest = *(src + 1);
+ *dest = *(src + 2);
+ *dest = *(src + 3);
+ dwords -= 4;
+ src += 4;
+ }
+
+ if(!dwords) return;
+ *dest = *src;
+ if(dwords == 1) return;
+ *dest = *(src + 1);
+ if(dwords == 2) return;
+ *dest = *(src + 2);
+}
+
+void XAAMoveDWORDS(
+ register CARD32* dest,
+ register CARD32* src,
+ register int dwords )
+{
+ while(dwords & ~0x03) {
+ *dest = *src;
+ *(dest + 1) = *(src + 1);
+ *(dest + 2) = *(src + 2);
+ *(dest + 3) = *(src + 3);
+ src += 4;
+ dest += 4;
+ dwords -= 4;
+ }
+ if(!dwords) return;
+ *dest = *src;
+ if(dwords == 1) return;
+ *(dest + 1) = *(src + 1);
+ if(dwords == 2) return;
+ *(dest + 2) = *(src + 2);
+}
+
+void XAAMoveDWORDS_FixedSrc(
+ register CARD32* dest,
+ register CARD32* src,
+ register int dwords )
+{
+ while(dwords & ~0x03) {
+ *dest = *src;
+ *(dest + 1) = *src;
+ *(dest + 2) = *src;
+ *(dest + 3) = *src;
+ dest += 4;
+ dwords -= 4;
+ }
+ if(!dwords) return;
+ *dest = *src;
+ if(dwords == 1) return;
+ *(dest + 1) = *src;
+ if(dwords == 2) return;
+ *(dest + 2) = *src;
+}
+
+static void
+XAAWritePixmap32To24(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *srcInit,
+ int srcwidth, /* bytes */
+ int rop,
+ unsigned int planemask,
+ int trans
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int count, dwords = bytes_to_int32(w * 3);
+ CARD32 *src, *dst;
+ Bool PlusOne = FALSE;
+
+ if((infoRec->ImageWriteFlags & CPU_TRANSFER_PAD_QWORD) &&
+ ((dwords * h) & 0x01)) {
+ PlusOne = TRUE;
+ }
+
+ (*infoRec->SetupForImageWrite)(pScrn, rop, planemask, trans, 24, 24);
+ (*infoRec->SubsequentImageWriteRect)(pScrn, x, y, w, h, 0);
+
+ if(dwords > infoRec->ImageWriteRange) {
+ dst = (CARD32*)infoRec->ImageWriteBase;
+ while(h--) {
+ src = (CARD32*)srcInit;
+ count = w;
+
+ while(count >= 4) {
+ *dst = (src[0] & 0x00ffffff) | (src[1] << 24);
+ *dst = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16);
+ *dst = ((src[2] >> 16) & 0x000000ff) | (src[3] << 8);
+ src += 4;
+ count -= 4;
+ }
+ switch(count) {
+ case 0: break;
+ case 1: *dst = src[0];
+ break;
+ case 2: *dst = (src[0] & 0x00ffffff) | (src[1] << 24);
+ *dst = src[1] >> 8;
+ break;
+ default: *dst = (src[0] & 0x00ffffff) | (src[1] << 24);
+ *dst = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16);
+ *dst = src[2] >> 16;
+ break;
+ }
+ srcInit += srcwidth;
+ }
+ } else {
+ while(h--) {
+ dst = (CARD32*)infoRec->ImageWriteBase;
+ src = (CARD32*)srcInit;
+ count = w;
+
+ while(count >= 4) {
+ dst[0] = (src[0] & 0x00ffffff) | (src[1] << 24);
+ dst[1] = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16);
+ dst[2] = ((src[2] >> 16) & 0x000000ff) | (src[3] << 8);
+ dst += 3;
+ src += 4;
+ count -= 4;
+ }
+ switch(count) {
+ case 0: break;
+ case 1: dst[0] = src[0];
+ break;
+ case 2: dst[0] = (src[0] & 0x00ffffff) | (src[1] << 24);
+ dst[1] = src[1] >> 8;
+ break;
+ default: dst[0] = (src[0] & 0x00ffffff) | (src[1] << 24);
+ dst[1] = ((src[1] >> 8) & 0x0000ffff) | (src[2] << 16);
+ dst[2] = src[2] >> 16;
+ break;
+ }
+ srcInit += srcwidth;
+ }
+ }
+
+ if(PlusOne) {
+ CARD32* base = (CARD32*)infoRec->ImageWriteBase;
+ *base = 0x00000000;
+ }
+
+ if(infoRec->ImageWriteFlags & SYNC_AFTER_IMAGE_WRITE)
+ (*infoRec->Sync)(pScrn);
+ else SET_SYNC_FLAG(infoRec);
+
+}
+
+void
+XAAWritePixmap (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth, /* bytes */
+ int rop,
+ unsigned int planemask,
+ int trans,
+ int bpp, int depth
+){
+ XAAInfoRecPtr infoRec;
+ int dwords, skipleft, Bpp;
+ Bool beCareful, PlusOne;
+
+ if((bpp == 32) && (pScrn->bitsPerPixel == 24)) {
+ XAAWritePixmap32To24(pScrn, x, y, w, h, src, srcwidth,
+ rop, planemask, trans);
+ return;
+ }
+
+ infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ beCareful = PlusOne = FALSE;
+ Bpp = bpp >> 3;
+
+ if((skipleft = (long)src & 0x03L)) {
+ if(!(infoRec->ImageWriteFlags & LEFT_EDGE_CLIPPING)) {
+ skipleft = 0;
+ beCareful = TRUE;
+ goto BAD_ALIGNMENT;
+ }
+
+ if(Bpp == 3)
+ skipleft = 4 - skipleft;
+ else
+ skipleft /= Bpp;
+
+ if((x < skipleft) && !(infoRec->ImageWriteFlags &
+ LEFT_EDGE_CLIPPING_NEGATIVE_X)) {
+ skipleft = 0;
+ beCareful = TRUE;
+ goto BAD_ALIGNMENT;
+ }
+
+ x -= skipleft;
+ w += skipleft;
+
+ if(Bpp == 3)
+ src -= 3 * skipleft;
+ else /* is this Alpha friendly ? */
+ src = (unsigned char*)((long)src & ~0x03L);
+ }
+
+BAD_ALIGNMENT:
+
+ dwords = bytes_to_int32(w * Bpp);
+
+ if((infoRec->ImageWriteFlags & CPU_TRANSFER_PAD_QWORD) &&
+ ((dwords * h) & 0x01)) {
+ PlusOne = TRUE;
+ }
+
+
+ (*infoRec->SetupForImageWrite)(pScrn, rop, planemask, trans, bpp, depth);
+ (*infoRec->SubsequentImageWriteRect)(pScrn, x, y, w, h, skipleft);
+
+ if(beCareful) {
+ /* in cases with bad alignment we have to be careful not
+ to read beyond the end of the source */
+ if(((x * Bpp) + (dwords << 2)) > srcwidth) h--;
+ else beCareful = FALSE;
+ }
+
+ if(dwords > infoRec->ImageWriteRange) {
+ while(h--) {
+ XAAMoveDWORDS_FixedBase((CARD32*)infoRec->ImageWriteBase,
+ (CARD32*)src, dwords);
+ src += srcwidth;
+ }
+ if(beCareful) {
+ int shift = ((long)src & 0x03L) << 3;
+ if(--dwords)
+ XAAMoveDWORDS_FixedBase((CARD32*)infoRec->ImageWriteBase,
+ (CARD32*)src, dwords);
+ src = (unsigned char*)((long)(src + (dwords << 2)) & ~0x03L);
+ *((CARD32*)infoRec->ImageWriteBase) = *((CARD32*)src) >> shift;
+ }
+ } else {
+ if(srcwidth == (dwords << 2)) {
+ int decrement = infoRec->ImageWriteRange/dwords;
+
+ while(h > decrement) {
+ XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
+ (CARD32*)src, dwords * decrement);
+ src += (srcwidth * decrement);
+ h -= decrement;
+ }
+ if(h) {
+ XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
+ (CARD32*)src, dwords * h);
+ if(beCareful) src += (srcwidth * h);
+ }
+ } else {
+ while(h--) {
+ XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
+ (CARD32*)src, dwords);
+ src += srcwidth;
+ }
+ }
+
+ if(beCareful) {
+ int shift = ((long)src & 0x03L) << 3;
+ if(--dwords)
+ XAAMoveDWORDS((CARD32*)infoRec->ImageWriteBase,
+ (CARD32*)src, dwords);
+ src = (unsigned char*)((long)(src + (dwords << 2)) & ~0x03L);
+
+ ((CARD32*)infoRec->ImageWriteBase)[dwords] =
+ *((CARD32*)src) >> shift;
+ }
+ }
+
+ if(PlusOne) {
+ CARD32* base = (CARD32*)infoRec->ImageWriteBase;
+ *base = 0x00000000;
+ }
+
+ if(infoRec->ImageWriteFlags & SYNC_AFTER_IMAGE_WRITE)
+ (*infoRec->Sync)(pScrn);
+ else SET_SYNC_FLAG(infoRec);
+}
+
+
+void
+XAAWritePixmapScanline (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth, /* bytes */
+ int rop,
+ unsigned int planemask,
+ int trans,
+ int bpp, int depth
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int dwords, skipleft, bufferNo = 0, Bpp = bpp >> 3;
+ Bool beCareful = FALSE;
+ CARD32* base;
+
+ if((skipleft = (long)src & 0x03L)) {
+ if(!(infoRec->ScanlineImageWriteFlags & LEFT_EDGE_CLIPPING)) {
+ skipleft = 0;
+ beCareful = TRUE;
+ goto BAD_ALIGNMENT;
+ }
+
+ if(Bpp == 3)
+ skipleft = 4 - skipleft;
+ else
+ skipleft /= Bpp;
+
+ if((x < skipleft) && !(infoRec->ScanlineImageWriteFlags &
+ LEFT_EDGE_CLIPPING_NEGATIVE_X)) {
+ skipleft = 0;
+ beCareful = TRUE;
+ goto BAD_ALIGNMENT;
+ }
+
+ x -= skipleft;
+ w += skipleft;
+
+ if(Bpp == 3)
+ src -= 3 * skipleft;
+ else
+ src = (unsigned char*)((long)src & ~0x03L);
+ }
+
+BAD_ALIGNMENT:
+
+ dwords = bytes_to_int32(w * Bpp);
+
+ (*infoRec->SetupForScanlineImageWrite)(
+ pScrn, rop, planemask, trans, bpp, depth);
+ (*infoRec->SubsequentScanlineImageWriteRect)(pScrn, x, y, w, h, skipleft);
+
+ if(beCareful) {
+ /* in cases with bad alignment we have to be careful not
+ to read beyond the end of the source */
+ if(((x * Bpp) + (dwords << 2)) > srcwidth) h--;
+ else beCareful = FALSE;
+ }
+
+ while(h--) {
+ base = (CARD32*)infoRec->ScanlineImageWriteBuffers[bufferNo];
+ XAAMoveDWORDS(base, (CARD32*)src, dwords);
+ (*infoRec->SubsequentImageWriteScanline)(pScrn, bufferNo++);
+ src += srcwidth;
+ if(bufferNo >= infoRec->NumScanlineImageWriteBuffers)
+ bufferNo = 0;
+ }
+
+ if(beCareful) {
+ int shift = ((long)src & 0x03L) << 3;
+ base = (CARD32*)infoRec->ScanlineImageWriteBuffers[bufferNo];
+ if(--dwords)
+ XAAMoveDWORDS(base,(CARD32*)src, dwords);
+ src = (unsigned char*)((long)(src + (dwords << 2)) & ~0x03L);
+
+ base[dwords] = *((CARD32*)src) >> shift;
+ (*infoRec->SubsequentImageWriteScanline)(pScrn, bufferNo);
+ }
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+
+void
+XAAPutImage(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int depth,
+ int x,
+ int y,
+ int w,
+ int h,
+ int leftPad,
+ int format,
+ char *pImage
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ int bpp = BitsPerPixel(depth);
+ Bool depthBug = FALSE;
+ if(!w || !h) return;
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ depthBug = XAA_DEPTH_BUG(pGC);
+
+ if(((format == ZPixmap) && infoRec->WritePixmap &&
+ ((pDraw->bitsPerPixel == bpp) ||
+ ((pDraw->bitsPerPixel == 24) && (bpp == 32) &&
+ (infoRec->WritePixmapFlags & CONVERT_32BPP_TO_24BPP))) &&
+ CHECK_ROP(pGC,infoRec->WritePixmapFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->WritePixmapFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->WritePixmapFlags) &&
+ CHECK_NO_GXCOPY(pGC,infoRec->WritePixmapFlags)) ||
+ ((format == XYBitmap) && !depthBug && infoRec->WriteBitmap &&
+ CHECK_ROP(pGC,infoRec->WriteBitmapFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->WriteBitmapFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->WriteBitmapFlags) &&
+ CHECK_COLORS(pGC,infoRec->WriteBitmapFlags) &&
+ !(infoRec->WriteBitmapFlags & TRANSPARENCY_ONLY)) ||
+ ((format == XYPixmap) && !depthBug && infoRec->WriteBitmap &&
+ CHECK_ROP(pGC,infoRec->WriteBitmapFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->WriteBitmapFlags) &&
+ !(infoRec->WriteBitmapFlags & NO_PLANEMASK) &&
+ !(infoRec->WriteBitmapFlags & TRANSPARENCY_ONLY))){
+
+ int MaxBoxes = REGION_NUM_RECTS(pGC->pCompositeClip);
+ BoxPtr pbox, pClipBoxes;
+ int nboxes, srcx, srcy, srcwidth;
+ xRectangle TheRect;
+
+ TheRect.x = pDraw->x + x;
+ TheRect.y = pDraw->y + y;
+ TheRect.width = w;
+ TheRect.height = h;
+
+ if(MaxBoxes > (infoRec->PreAllocSize/sizeof(BoxRec))) {
+ pClipBoxes = malloc(MaxBoxes * sizeof(BoxRec));
+ if(!pClipBoxes) return;
+ } else pClipBoxes = (BoxPtr)infoRec->PreAllocMem;
+
+ nboxes = XAAGetRectClipBoxes(pGC, pClipBoxes, 1, &TheRect);
+ pbox = pClipBoxes;
+
+ if(format == XYBitmap) {
+ srcwidth = BitmapBytePad(leftPad + w);
+ while(nboxes--) {
+ srcx = pbox->x1 - TheRect.x + leftPad;
+ srcy = pbox->y1 - TheRect.y;
+ (*infoRec->WriteBitmap)(infoRec->pScrn, pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
+ (unsigned char*)pImage +
+ (srcwidth * srcy) + ((srcx >> 5) << 2),
+ srcwidth, srcx & 31, pGC->fgPixel, pGC->bgPixel,
+ pGC->alu, pGC->planemask);
+ pbox++;
+ }
+ } else if(format == ZPixmap) {
+ int Bpp = bpp >> 3;
+ srcwidth = PixmapBytePad(leftPad + w, depth);
+ while(nboxes--) {
+ srcx = pbox->x1 - TheRect.x + leftPad;
+ srcy = pbox->y1 - TheRect.y;
+ (*infoRec->WritePixmap)(infoRec->pScrn, pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
+ (unsigned char*)pImage +
+ (srcwidth * srcy) + (srcx * Bpp),
+ srcwidth, pGC->alu, pGC->planemask, -1,
+ Bpp << 3, depth);
+ pbox++;
+ }
+ } else { /* XYPixmap */
+ int depth = pGC->depth;
+ int numBox, increment;
+ unsigned long i, mask;
+ BoxPtr pntBox;
+
+ srcwidth = BitmapBytePad(w + leftPad);
+ increment = h * srcwidth;
+ i = 1 << (depth - 1);
+ mask = ~0;
+
+ if((infoRec->pScrn->overlayFlags & OVERLAY_8_32_PLANAR) &&
+ (pGC->depth == 8)){
+ i = 0x80000000; mask = 0xff000000;
+ }
+
+ for(; i & mask; i >>= 1, pImage += increment) {
+ if(i & pGC->planemask) {
+ pntBox = pbox;
+ numBox = nboxes;
+ while(numBox--) {
+ srcx = pntBox->x1 - TheRect.x + leftPad;
+ srcy = pntBox->y1 - TheRect.y;
+ (*infoRec->WriteBitmap)(infoRec->pScrn,
+ pntBox->x1, pntBox->y1,
+ pntBox->x2 - pntBox->x1,
+ pntBox->y2 - pntBox->y1,
+ (unsigned char*)pImage +
+ (srcwidth * srcy) + ((srcx >> 5) << 2),
+ srcwidth, srcx & 31, ~0, 0, pGC->alu, i);
+ pntBox++;
+ }
+ }
+ }
+
+ }
+
+ if(pClipBoxes != (BoxPtr)infoRec->PreAllocMem)
+ free(pClipBoxes);
+ } else
+ XAAFallbackOps.PutImage(pDraw, pGC, depth, x, y, w, h, leftPad,
+ format, pImage);
+}
diff --git a/xorg-server/hw/xfree86/xaa/xaaInit.c b/xorg-server/hw/xfree86/xaa/xaaInit.c
index 7d4583dc2..58efb6a82 100644
--- a/xorg-server/hw/xfree86/xaa/xaaInit.c
+++ b/xorg-server/hw/xfree86/xaa/xaaInit.c
@@ -1,624 +1,624 @@
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "misc.h"
-#include "xf86.h"
-#include "xf86_OSproc.h"
-
-#include <X11/X.h>
-#include "scrnintstr.h"
-#include "pixmapstr.h"
-#include "windowstr.h"
-#include "xf86str.h"
-#include "mi.h"
-#include "miline.h"
-#include "xaa.h"
-#include "xaalocal.h"
-#include "xaawrap.h"
-#include "xf86fbman.h"
-#include "servermd.h"
-#ifdef COMPOSITE
-#include "cw.h"
-#endif
-
-#define MAX_PREALLOC_MEM 65536 /* MUST be >= 1024 */
-
-#define MIN_OFFPIX_SIZE (320*200)
-
-static Bool XAACloseScreen(int i, ScreenPtr pScreen);
-static void XAAGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
- unsigned int format, unsigned long planemask,
- char *pdstLine);
-static void XAAGetSpans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt,
- int *pwidth, int nspans, char *pdstStart);
-static PixmapPtr XAACreatePixmap(ScreenPtr pScreen, int w, int h, int depth,
- unsigned usage_hint);
-static Bool XAADestroyPixmap(PixmapPtr pPixmap);
-static Bool XAAEnterVT (int index, int flags);
-static void XAALeaveVT (int index, int flags);
-static int XAASetDGAMode(int index, int num, DGADevicePtr devRet);
-static void XAAEnableDisableFBAccess (int index, Bool enable);
-static Bool XAAChangeWindowAttributes (WindowPtr pWin, unsigned long mask);
-
-static int XAAScreenKeyIndex;
-static DevPrivateKey XAAScreenKey = &XAAScreenKeyIndex;
-static int XAAGCKeyIndex;
-static DevPrivateKey XAAGCKey = &XAAGCKeyIndex;
-static int XAAPixmapKeyIndex;
-static DevPrivateKey XAAPixmapKey = &XAAPixmapKeyIndex;
-
-DevPrivateKey XAAGetScreenKey(void) {
- return XAAScreenKey;
-}
-
-DevPrivateKey XAAGetGCKey(void) {
- return XAAGCKey;
-}
-
-DevPrivateKey XAAGetPixmapKey(void) {
- return XAAPixmapKey;
-}
-
-/* temp kludge */
-static Bool SwitchedOut = FALSE;
-
-XAAInfoRecPtr
-XAACreateInfoRec(void)
-{
- XAAInfoRecPtr infoRec;
-
- infoRec = xcalloc(1, sizeof(XAAInfoRec));
- if(infoRec)
- infoRec->CachePixelGranularity = -1;
-
- return infoRec;
-}
-
-void
-XAADestroyInfoRec(XAAInfoRecPtr infoRec)
-{
- if(!infoRec) return;
-
- if(infoRec->ClosePixmapCache)
- (*infoRec->ClosePixmapCache)(infoRec->pScrn->pScreen);
-
- if(infoRec->PreAllocMem)
- xfree(infoRec->PreAllocMem);
-
- if(infoRec->PixmapCachePrivate)
- xfree(infoRec->PixmapCachePrivate);
-
- xfree(infoRec);
-}
-
-
-Bool
-XAAInit(ScreenPtr pScreen, XAAInfoRecPtr infoRec)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- XAAScreenPtr pScreenPriv;
- int i;
- PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
-
- /* Return successfully if no acceleration wanted */
- if (!infoRec)
- return TRUE;
-
- if (!dixRequestPrivate(XAAGCKey, sizeof(XAAGCRec)))
- return FALSE;
-
- if (!dixRequestPrivate(XAAPixmapKey, sizeof(XAAPixmapRec)))
- return FALSE;
-
- if (!(pScreenPriv = xalloc(sizeof(XAAScreenRec))))
- return FALSE;
-
- dixSetPrivate(&pScreen->devPrivates, XAAScreenKey, pScreenPriv);
-
- if(!xf86FBManagerRunning(pScreen))
- infoRec->Flags &= ~(PIXMAP_CACHE | OFFSCREEN_PIXMAPS);
- if(!(infoRec->Flags & LINEAR_FRAMEBUFFER))
- infoRec->Flags &= ~OFFSCREEN_PIXMAPS;
-
- if(!infoRec->FullPlanemask) { /* for backwards compatibility */
- infoRec->FullPlanemask = (1 << pScrn->depth) - 1;
- infoRec->FullPlanemasks[pScrn->depth - 1] = infoRec->FullPlanemask;
- }
-
- for(i = 0; i < 32; i++) {
- if(!infoRec->FullPlanemasks[i]) /* keep any set by caller */
- infoRec->FullPlanemasks[i] = (1 << (i+1)) - 1;
- }
-
- if(!XAAInitAccel(pScreen, infoRec)) return FALSE;
- pScreenPriv->AccelInfoRec = infoRec;
- infoRec->ScratchGC.pScreen = pScreen;
-
-
- if(!infoRec->GetImage)
- infoRec->GetImage = XAAGetImage;
- if(!infoRec->GetSpans)
- infoRec->GetSpans = XAAGetSpans;
- if(!infoRec->CopyWindow)
- infoRec->CopyWindow = XAACopyWindow;
-
- pScreenPriv->CreateGC = pScreen->CreateGC;
- pScreen->CreateGC = XAACreateGC;
- pScreenPriv->CloseScreen = pScreen->CloseScreen;
- pScreen->CloseScreen = XAACloseScreen;
- pScreenPriv->GetImage = pScreen->GetImage;
- pScreen->GetImage = infoRec->GetImage;
- pScreenPriv->GetSpans = pScreen->GetSpans;
- pScreen->GetSpans = infoRec->GetSpans;
- pScreenPriv->CopyWindow = pScreen->CopyWindow;
- pScreen->CopyWindow = infoRec->CopyWindow;
- pScreenPriv->CreatePixmap = pScreen->CreatePixmap;
- pScreen->CreatePixmap = XAACreatePixmap;
- pScreenPriv->DestroyPixmap = pScreen->DestroyPixmap;
- pScreen->DestroyPixmap = XAADestroyPixmap;
- pScreenPriv->ChangeWindowAttributes = pScreen->ChangeWindowAttributes;
- pScreen->ChangeWindowAttributes = XAAChangeWindowAttributes;
-
- pScreenPriv->EnterVT = pScrn->EnterVT;
- pScrn->EnterVT = XAAEnterVT;
- pScreenPriv->LeaveVT = pScrn->LeaveVT;
- pScrn->LeaveVT = XAALeaveVT;
- pScreenPriv->SetDGAMode = pScrn->SetDGAMode;
- pScrn->SetDGAMode = XAASetDGAMode;
- pScreenPriv->EnableDisableFBAccess = pScrn->EnableDisableFBAccess;
- pScrn->EnableDisableFBAccess = XAAEnableDisableFBAccess;
-
- pScreenPriv->WindowExposures = pScreen->WindowExposures;
- if (ps)
- {
- pScreenPriv->Composite = ps->Composite;
- ps->Composite = XAAComposite;
- pScreenPriv->Glyphs = ps->Glyphs;
- ps->Glyphs = XAAGlyphs;
- }
- if(pScrn->overlayFlags & OVERLAY_8_32_PLANAR)
- XAASetupOverlay8_32Planar(pScreen);
-
- infoRec->PreAllocMem = xalloc(MAX_PREALLOC_MEM);
- if(infoRec->PreAllocMem)
- infoRec->PreAllocSize = MAX_PREALLOC_MEM;
-
- if(infoRec->Flags & PIXMAP_CACHE)
- xf86RegisterFreeBoxCallback(pScreen, infoRec->InitPixmapCache,
- (pointer)infoRec);
-
- if(infoRec->Flags & MICROSOFT_ZERO_LINE_BIAS)
- miSetZeroLineBias(pScreen, OCTANT1 | OCTANT2 | OCTANT3 | OCTANT4);
-
-#ifdef COMPOSITE
- /* Initialize the composite wrapper. This needs to happen after the
- * wrapping above (so it comes before us), but before all other extensions,
- * so it doesn't confuse them. (particularly damage).
- */
- miInitializeCompositeWrapper(pScreen);
-#endif
-
- return TRUE;
-}
-
-
-
-static Bool
-XAACloseScreen (int i, ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- XAAScreenPtr pScreenPriv =
- (XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey);
-
- pScrn->EnterVT = pScreenPriv->EnterVT;
- pScrn->LeaveVT = pScreenPriv->LeaveVT;
- pScrn->EnableDisableFBAccess = pScreenPriv->EnableDisableFBAccess;
-
- pScreen->CreateGC = pScreenPriv->CreateGC;
- pScreen->CloseScreen = pScreenPriv->CloseScreen;
- pScreen->GetImage = pScreenPriv->GetImage;
- pScreen->GetSpans = pScreenPriv->GetSpans;
- pScreen->CopyWindow = pScreenPriv->CopyWindow;
- pScreen->WindowExposures = pScreenPriv->WindowExposures;
- pScreen->CreatePixmap = pScreenPriv->CreatePixmap;
- pScreen->DestroyPixmap = pScreenPriv->DestroyPixmap;
- pScreen->ChangeWindowAttributes = pScreenPriv->ChangeWindowAttributes;
-
- /* We leave it up to the client to free the XAAInfoRec */
-
- xfree ((pointer) pScreenPriv);
-
- return (*pScreen->CloseScreen) (i, pScreen);
-}
-
-static void
-XAAGetImage (
- DrawablePtr pDraw,
- int sx, int sy, int w, int h,
- unsigned int format,
- unsigned long planemask,
- char *pdstLine
-)
-{
- ScreenPtr pScreen = pDraw->pScreen;
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
- ScrnInfoPtr pScrn = infoRec->pScrn;
-
- if(pScrn->vtSema &&
- ((pDraw->type == DRAWABLE_WINDOW) || IS_OFFSCREEN_PIXMAP(pDraw)))
- {
- if(infoRec->ReadPixmap && (format == ZPixmap) &&
- ((planemask & infoRec->FullPlanemasks[pDraw->depth - 1]) ==
- infoRec->FullPlanemasks[pDraw->depth - 1]) &&
- (pDraw->bitsPerPixel == BitsPerPixel(pDraw->depth)))
- {
- (*infoRec->ReadPixmap)(pScrn,
- sx + pDraw->x, sy + pDraw->y, w, h,
- (unsigned char *)pdstLine,
- PixmapBytePad(w, pDraw->depth),
- pDraw->bitsPerPixel, pDraw->depth);
- return;
- }
- SYNC_CHECK(pDraw);
- }
-
- XAA_SCREEN_PROLOGUE (pScreen, GetImage);
- (*pScreen->GetImage) (pDraw, sx, sy, w, h, format, planemask, pdstLine);
- XAA_SCREEN_EPILOGUE (pScreen, GetImage, XAAGetImage);
-}
-
-static void
-XAAGetSpans (
- DrawablePtr pDraw,
- int wMax,
- DDXPointPtr ppt,
- int *pwidth,
- int nspans,
- char *pdstStart
-)
-{
- ScreenPtr pScreen = pDraw->pScreen;
- XAA_SCREEN_PROLOGUE (pScreen, GetSpans);
- if(xf86Screens[pScreen->myNum]->vtSema &&
- ((pDraw->type == DRAWABLE_WINDOW) || IS_OFFSCREEN_PIXMAP(pDraw))) {
- SYNC_CHECK(pDraw);
- }
- (*pScreen->GetSpans) (pDraw, wMax, ppt, pwidth, nspans, pdstStart);
- XAA_SCREEN_EPILOGUE (pScreen, GetSpans, XAAGetSpans);
-}
-
-
-static int
-XAAPixmapBPP (ScreenPtr pScreen, int depth)
-{
- PixmapPtr pPix;
- int bpp;
- DestroyPixmapProcPtr destroyPixmap;
-
- XAA_SCREEN_PROLOGUE (pScreen, CreatePixmap);
- pPix = (*pScreen->CreatePixmap) (pScreen, 1, 1, depth,
- CREATE_PIXMAP_USAGE_SCRATCH);
- XAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, XAACreatePixmap);
- if (!pPix)
- return 0;
- bpp = pPix->drawable.bitsPerPixel;
- destroyPixmap = pScreen->DestroyPixmap;
- XAA_SCREEN_PROLOGUE (pScreen, DestroyPixmap);
- (*pScreen->DestroyPixmap) (pPix);
- XAA_SCREEN_EPILOGUE (pScreen, DestroyPixmap, destroyPixmap);
- return bpp;
-}
-
-static void
-XAAInitializeOffscreenDepths (ScreenPtr pScreen)
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- int d, dep;
-
- infoRec->offscreenDepthsInitialized = TRUE;
- infoRec->offscreenDepths = 0;
- if (infoRec->Flags & OFFSCREEN_PIXMAPS) {
- for (d = 0; d < pScreen->numDepths; d++) {
- dep = pScreen->allowedDepths[d].depth;
- if (XAAPixmapBPP (pScreen, dep) == pScrn->bitsPerPixel)
- infoRec->offscreenDepths |= (1 << (dep - 1));
- }
- }
-}
-
-static PixmapPtr
-XAACreatePixmap(ScreenPtr pScreen, int w, int h, int depth, unsigned usage_hint)
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- XAAPixmapPtr pPriv;
- PixmapPtr pPix = NULL;
- int size = w * h;
-
- if (w > 32767 || h > 32767)
- return NullPixmap;
-
- if (!infoRec->offscreenDepthsInitialized)
- XAAInitializeOffscreenDepths (pScreen);
-
- if(pScrn->vtSema &&
- (usage_hint != CREATE_PIXMAP_USAGE_GLYPH_PICTURE) &&
- (infoRec->offscreenDepths & (1 << (depth - 1))) &&
- (size >= MIN_OFFPIX_SIZE) && !SwitchedOut &&
- (!infoRec->maxOffPixWidth || (w <= infoRec->maxOffPixWidth)) &&
- (!infoRec->maxOffPixHeight || (h <= infoRec->maxOffPixHeight)) )
- {
- PixmapLinkPtr pLink;
- PixmapPtr pScreenPix;
- FBAreaPtr area;
- int gran = 0;
-
- switch(pScrn->bitsPerPixel) {
- case 24:
- case 8: gran = 4; break;
- case 16: gran = 2; break;
- case 32: gran = 1; break;
- default: break;
- }
-
- if(BITMAP_SCANLINE_PAD == 64)
- gran *= 2;
-
- if(!(area = xf86AllocateOffscreenArea(pScreen, w, h, gran, 0,
- XAARemoveAreaCallback, NULL))) {
- goto BAILOUT;
- }
-
- if(!(pLink = xalloc(sizeof(PixmapLink)))) {
- xf86FreeOffscreenArea(area);
- goto BAILOUT;
- }
-
- XAA_SCREEN_PROLOGUE (pScreen, CreatePixmap);
- pPix = (*pScreen->CreatePixmap) (pScreen, 0, 0, depth, usage_hint);
- XAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, XAACreatePixmap);
-
- if (!pPix) {
- xfree (pLink);
- xf86FreeOffscreenArea(area);
- goto BAILOUT;
- }
-
- pScreenPix = (*pScreen->GetScreenPixmap)(pScreen);
-
- pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
- pPix->drawable.x = area->box.x1;
- pPix->drawable.y = area->box.y1;
- pPix->drawable.width = w;
- pPix->drawable.height = h;
- pPix->drawable.bitsPerPixel = pScrn->bitsPerPixel;
- pPix->devKind = pScreenPix->devKind;
- pPix->devPrivate.ptr = pScreenPix->devPrivate.ptr;
- area->devPrivate.ptr = pPix;
-
- pPriv->flags = OFFSCREEN;
- pPriv->offscreenArea = area;
- pPriv->freeData = FALSE;
-
- pLink->next = infoRec->OffscreenPixmaps;
- pLink->pPix = pPix;
- infoRec->OffscreenPixmaps = pLink;
- return pPix;
- }
-BAILOUT:
- XAA_SCREEN_PROLOGUE (pScreen, CreatePixmap);
- pPix = (*pScreen->CreatePixmap) (pScreen, w, h, depth, usage_hint);
- XAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, XAACreatePixmap);
-
- if(pPix) {
- pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
- pPriv->flags = 0;
- pPriv->offscreenArea = NULL;
- pPriv->freeData = FALSE;
- if(!w || !h) /* either scratch or shared memory */
- pPriv->flags |= SHARED_PIXMAP;
- }
-
- return pPix;
-}
-
-static Bool
-XAADestroyPixmap(PixmapPtr pPix)
-{
- ScreenPtr pScreen = pPix->drawable.pScreen;
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
- XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
- Bool ret;
-
- if(pPix->refcnt == 1) {
- if(pPriv->flags & OFFSCREEN) {
- if(pPriv->flags & DGA_PIXMAP)
- xfree(pPriv->offscreenArea);
- else {
- FBAreaPtr area = pPriv->offscreenArea;
- PixmapLinkPtr pLink = infoRec->OffscreenPixmaps;
- PixmapLinkPtr prev = NULL;
-
- while(pLink->pPix != pPix) {
- prev = pLink;
- pLink = pLink->next;
- }
-
- if(prev) prev->next = pLink->next;
- else infoRec->OffscreenPixmaps = pLink->next;
-
- if(!area) area = pLink->area;
-
- xf86FreeOffscreenArea(area);
- pPriv->offscreenArea = NULL;
- xfree(pLink);
- }
- }
-
- if(pPriv->freeData) { /* pixmaps that were once in video ram */
- xfree(pPix->devPrivate.ptr);
- pPix->devPrivate.ptr = NULL;
- }
- }
-
- XAA_SCREEN_PROLOGUE (pScreen, DestroyPixmap);
- ret = (*pScreen->DestroyPixmap) (pPix);
- XAA_SCREEN_EPILOGUE (pScreen, DestroyPixmap, XAADestroyPixmap);
-
- return ret;
-}
-
-static Bool
-XAAChangeWindowAttributes (WindowPtr pWin, unsigned long mask)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- Bool ret;
-
- XAA_SCREEN_PROLOGUE (pScreen, ChangeWindowAttributes);
- ret = (*pScreen->ChangeWindowAttributes) (pWin, mask);
- XAA_SCREEN_EPILOGUE (pScreen, ChangeWindowAttributes, XAAChangeWindowAttributes);
-
- /* we have to assume that shared memory pixmaps are dirty
- because we can't wrap operations on them */
-
- if((mask & CWBackPixmap) && (pWin->backgroundState == BackgroundPixmap) &&
- PIXMAP_IS_SHARED(pWin->background.pixmap))
- {
- XAAPixmapPtr pPixPriv = XAA_GET_PIXMAP_PRIVATE(pWin->background.pixmap);
- pPixPriv->flags |= DIRTY;
- }
- if((mask & CWBorderPixmap) && !(pWin->borderIsPixel) &&
- PIXMAP_IS_SHARED(pWin->border.pixmap))
- {
- XAAPixmapPtr pPixPriv = XAA_GET_PIXMAP_PRIVATE(pWin->border.pixmap);
- pPixPriv->flags |= DIRTY;
- }
-
- return ret;
-}
-
-
-
-/* These two aren't really needed for anything */
-
-static Bool
-XAAEnterVT(int index, int flags)
-{
- ScreenPtr pScreen = screenInfo.screens[index];
- XAAScreenPtr pScreenPriv =
- (XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey);
-
- return((*pScreenPriv->EnterVT)(index, flags));
-}
-
-static void
-XAALeaveVT(int index, int flags)
-{
- ScreenPtr pScreen = screenInfo.screens[index];
- XAAScreenPtr pScreenPriv =
- (XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey);
- XAAInfoRecPtr infoRec = pScreenPriv->AccelInfoRec;
-
- if(infoRec->NeedToSync) {
- (*infoRec->Sync)(infoRec->pScrn);
- infoRec->NeedToSync = FALSE;
- }
-
- (*pScreenPriv->LeaveVT)(index, flags);
-}
-
-typedef struct {
- Bool UsingPixmapCache;
- Bool CanDoColor8x8;
- Bool CanDoMono8x8;
-} SavedCacheState, *SavedCacheStatePtr;
-
-static int
-XAASetDGAMode(int index, int num, DGADevicePtr devRet)
-{
- ScreenPtr pScreen = screenInfo.screens[index];
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
- XAAScreenPtr pScreenPriv =
- (XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey);
- int ret;
-
- if (!num && infoRec->dgaSaves) { /* restore old pixmap cache state */
- SavedCacheStatePtr state = (SavedCacheStatePtr)infoRec->dgaSaves;
-
- infoRec->UsingPixmapCache = state->UsingPixmapCache;
- infoRec->CanDoColor8x8 = state->CanDoColor8x8;
- infoRec->CanDoMono8x8 = state->CanDoMono8x8;
- xfree(infoRec->dgaSaves);
- infoRec->dgaSaves = NULL;
- }
-
- ret = (*pScreenPriv->SetDGAMode)(index, num, devRet);
- if(ret != Success) return ret;
-
- if(num && devRet->pPix) { /* accelerate this pixmap */
- XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(devRet->pPix);
- FBAreaPtr area;
-
- if((area = xalloc(sizeof(FBArea)))) {
- area->pScreen = pScreen;
- area->box.x1 = 0;
- area->box.x2 = 0;
- area->box.y1 = devRet->mode->pixmapWidth;
- area->box.y2 = devRet->mode->pixmapHeight;
- area->granularity = 0;
- area->MoveAreaCallback = 0;
- area->RemoveAreaCallback = 0;
- area->devPrivate.ptr = 0;
-
- pixPriv->flags |= OFFSCREEN | DGA_PIXMAP;
- pixPriv->offscreenArea = area;
-
- if(!infoRec->dgaSaves) { /* save pixmap cache state */
- SavedCacheStatePtr state = xalloc(sizeof(SavedCacheState));
-
- state->UsingPixmapCache = infoRec->UsingPixmapCache;
- state->CanDoColor8x8 = infoRec->CanDoColor8x8;
- state->CanDoMono8x8 = infoRec->CanDoMono8x8;
- infoRec->dgaSaves = (char*)state;
-
- infoRec->UsingPixmapCache = FALSE;
- if(infoRec->PixmapCacheFlags & CACHE_MONO_8x8)
- infoRec->CanDoMono8x8 = FALSE;
- if(infoRec->PixmapCacheFlags & CACHE_COLOR_8x8)
- infoRec->CanDoColor8x8 = FALSE;
- }
- }
- }
-
- return ret;
-}
-
-
-
-static void
-XAAEnableDisableFBAccess (int index, Bool enable)
-{
- ScreenPtr pScreen = screenInfo.screens[index];
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
- XAAScreenPtr pScreenPriv =
- (XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey);
-
- if(!enable) {
- if((infoRec->Flags & OFFSCREEN_PIXMAPS) && (infoRec->OffscreenPixmaps))
- XAAMoveOutOffscreenPixmaps(pScreen);
- if(infoRec->Flags & PIXMAP_CACHE)
- XAAInvalidatePixmapCache(pScreen);
- SwitchedOut = TRUE;
- }
-
- (*pScreenPriv->EnableDisableFBAccess)(index, enable);
-
- if(enable) {
- if((infoRec->Flags & OFFSCREEN_PIXMAPS) && (infoRec->OffscreenPixmaps))
- XAAMoveInOffscreenPixmaps(pScreen);
- SwitchedOut = FALSE;
- }
-}
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include <X11/X.h>
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "xf86str.h"
+#include "mi.h"
+#include "miline.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xaawrap.h"
+#include "xf86fbman.h"
+#include "servermd.h"
+#ifdef COMPOSITE
+#include "cw.h"
+#endif
+
+#define MAX_PREALLOC_MEM 65536 /* MUST be >= 1024 */
+
+#define MIN_OFFPIX_SIZE (320*200)
+
+static Bool XAACloseScreen(int i, ScreenPtr pScreen);
+static void XAAGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
+ unsigned int format, unsigned long planemask,
+ char *pdstLine);
+static void XAAGetSpans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt,
+ int *pwidth, int nspans, char *pdstStart);
+static PixmapPtr XAACreatePixmap(ScreenPtr pScreen, int w, int h, int depth,
+ unsigned usage_hint);
+static Bool XAADestroyPixmap(PixmapPtr pPixmap);
+static Bool XAAEnterVT (int index, int flags);
+static void XAALeaveVT (int index, int flags);
+static int XAASetDGAMode(int index, int num, DGADevicePtr devRet);
+static void XAAEnableDisableFBAccess (int index, Bool enable);
+static Bool XAAChangeWindowAttributes (WindowPtr pWin, unsigned long mask);
+
+static int XAAScreenKeyIndex;
+static DevPrivateKey XAAScreenKey = &XAAScreenKeyIndex;
+static int XAAGCKeyIndex;
+static DevPrivateKey XAAGCKey = &XAAGCKeyIndex;
+static int XAAPixmapKeyIndex;
+static DevPrivateKey XAAPixmapKey = &XAAPixmapKeyIndex;
+
+DevPrivateKey XAAGetScreenKey(void) {
+ return XAAScreenKey;
+}
+
+DevPrivateKey XAAGetGCKey(void) {
+ return XAAGCKey;
+}
+
+DevPrivateKey XAAGetPixmapKey(void) {
+ return XAAPixmapKey;
+}
+
+/* temp kludge */
+static Bool SwitchedOut = FALSE;
+
+XAAInfoRecPtr
+XAACreateInfoRec(void)
+{
+ XAAInfoRecPtr infoRec;
+
+ infoRec = calloc(1, sizeof(XAAInfoRec));
+ if(infoRec)
+ infoRec->CachePixelGranularity = -1;
+
+ return infoRec;
+}
+
+void
+XAADestroyInfoRec(XAAInfoRecPtr infoRec)
+{
+ if(!infoRec) return;
+
+ if(infoRec->ClosePixmapCache)
+ (*infoRec->ClosePixmapCache)(infoRec->pScrn->pScreen);
+
+ if(infoRec->PreAllocMem)
+ free(infoRec->PreAllocMem);
+
+ if(infoRec->PixmapCachePrivate)
+ free(infoRec->PixmapCachePrivate);
+
+ free(infoRec);
+}
+
+
+Bool
+XAAInit(ScreenPtr pScreen, XAAInfoRecPtr infoRec)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XAAScreenPtr pScreenPriv;
+ int i;
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+
+ /* Return successfully if no acceleration wanted */
+ if (!infoRec)
+ return TRUE;
+
+ if (!dixRequestPrivate(XAAGCKey, sizeof(XAAGCRec)))
+ return FALSE;
+
+ if (!dixRequestPrivate(XAAPixmapKey, sizeof(XAAPixmapRec)))
+ return FALSE;
+
+ if (!(pScreenPriv = malloc(sizeof(XAAScreenRec))))
+ return FALSE;
+
+ dixSetPrivate(&pScreen->devPrivates, XAAScreenKey, pScreenPriv);
+
+ if(!xf86FBManagerRunning(pScreen))
+ infoRec->Flags &= ~(PIXMAP_CACHE | OFFSCREEN_PIXMAPS);
+ if(!(infoRec->Flags & LINEAR_FRAMEBUFFER))
+ infoRec->Flags &= ~OFFSCREEN_PIXMAPS;
+
+ if(!infoRec->FullPlanemask) { /* for backwards compatibility */
+ infoRec->FullPlanemask = (1 << pScrn->depth) - 1;
+ infoRec->FullPlanemasks[pScrn->depth - 1] = infoRec->FullPlanemask;
+ }
+
+ for(i = 0; i < 32; i++) {
+ if(!infoRec->FullPlanemasks[i]) /* keep any set by caller */
+ infoRec->FullPlanemasks[i] = (1 << (i+1)) - 1;
+ }
+
+ if(!XAAInitAccel(pScreen, infoRec)) return FALSE;
+ pScreenPriv->AccelInfoRec = infoRec;
+ infoRec->ScratchGC.pScreen = pScreen;
+
+
+ if(!infoRec->GetImage)
+ infoRec->GetImage = XAAGetImage;
+ if(!infoRec->GetSpans)
+ infoRec->GetSpans = XAAGetSpans;
+ if(!infoRec->CopyWindow)
+ infoRec->CopyWindow = XAACopyWindow;
+
+ pScreenPriv->CreateGC = pScreen->CreateGC;
+ pScreen->CreateGC = XAACreateGC;
+ pScreenPriv->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = XAACloseScreen;
+ pScreenPriv->GetImage = pScreen->GetImage;
+ pScreen->GetImage = infoRec->GetImage;
+ pScreenPriv->GetSpans = pScreen->GetSpans;
+ pScreen->GetSpans = infoRec->GetSpans;
+ pScreenPriv->CopyWindow = pScreen->CopyWindow;
+ pScreen->CopyWindow = infoRec->CopyWindow;
+ pScreenPriv->CreatePixmap = pScreen->CreatePixmap;
+ pScreen->CreatePixmap = XAACreatePixmap;
+ pScreenPriv->DestroyPixmap = pScreen->DestroyPixmap;
+ pScreen->DestroyPixmap = XAADestroyPixmap;
+ pScreenPriv->ChangeWindowAttributes = pScreen->ChangeWindowAttributes;
+ pScreen->ChangeWindowAttributes = XAAChangeWindowAttributes;
+
+ pScreenPriv->EnterVT = pScrn->EnterVT;
+ pScrn->EnterVT = XAAEnterVT;
+ pScreenPriv->LeaveVT = pScrn->LeaveVT;
+ pScrn->LeaveVT = XAALeaveVT;
+ pScreenPriv->SetDGAMode = pScrn->SetDGAMode;
+ pScrn->SetDGAMode = XAASetDGAMode;
+ pScreenPriv->EnableDisableFBAccess = pScrn->EnableDisableFBAccess;
+ pScrn->EnableDisableFBAccess = XAAEnableDisableFBAccess;
+
+ pScreenPriv->WindowExposures = pScreen->WindowExposures;
+ if (ps)
+ {
+ pScreenPriv->Composite = ps->Composite;
+ ps->Composite = XAAComposite;
+ pScreenPriv->Glyphs = ps->Glyphs;
+ ps->Glyphs = XAAGlyphs;
+ }
+ if(pScrn->overlayFlags & OVERLAY_8_32_PLANAR)
+ XAASetupOverlay8_32Planar(pScreen);
+
+ infoRec->PreAllocMem = malloc(MAX_PREALLOC_MEM);
+ if(infoRec->PreAllocMem)
+ infoRec->PreAllocSize = MAX_PREALLOC_MEM;
+
+ if(infoRec->Flags & PIXMAP_CACHE)
+ xf86RegisterFreeBoxCallback(pScreen, infoRec->InitPixmapCache,
+ (pointer)infoRec);
+
+ if(infoRec->Flags & MICROSOFT_ZERO_LINE_BIAS)
+ miSetZeroLineBias(pScreen, OCTANT1 | OCTANT2 | OCTANT3 | OCTANT4);
+
+#ifdef COMPOSITE
+ /* Initialize the composite wrapper. This needs to happen after the
+ * wrapping above (so it comes before us), but before all other extensions,
+ * so it doesn't confuse them. (particularly damage).
+ */
+ miInitializeCompositeWrapper(pScreen);
+#endif
+
+ return TRUE;
+}
+
+
+
+static Bool
+XAACloseScreen (int i, ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XAAScreenPtr pScreenPriv =
+ (XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey);
+
+ pScrn->EnterVT = pScreenPriv->EnterVT;
+ pScrn->LeaveVT = pScreenPriv->LeaveVT;
+ pScrn->EnableDisableFBAccess = pScreenPriv->EnableDisableFBAccess;
+
+ pScreen->CreateGC = pScreenPriv->CreateGC;
+ pScreen->CloseScreen = pScreenPriv->CloseScreen;
+ pScreen->GetImage = pScreenPriv->GetImage;
+ pScreen->GetSpans = pScreenPriv->GetSpans;
+ pScreen->CopyWindow = pScreenPriv->CopyWindow;
+ pScreen->WindowExposures = pScreenPriv->WindowExposures;
+ pScreen->CreatePixmap = pScreenPriv->CreatePixmap;
+ pScreen->DestroyPixmap = pScreenPriv->DestroyPixmap;
+ pScreen->ChangeWindowAttributes = pScreenPriv->ChangeWindowAttributes;
+
+ /* We leave it up to the client to free the XAAInfoRec */
+
+ free((pointer) pScreenPriv);
+
+ return (*pScreen->CloseScreen) (i, pScreen);
+}
+
+static void
+XAAGetImage (
+ DrawablePtr pDraw,
+ int sx, int sy, int w, int h,
+ unsigned int format,
+ unsigned long planemask,
+ char *pdstLine
+)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ ScrnInfoPtr pScrn = infoRec->pScrn;
+
+ if(pScrn->vtSema &&
+ ((pDraw->type == DRAWABLE_WINDOW) || IS_OFFSCREEN_PIXMAP(pDraw)))
+ {
+ if(infoRec->ReadPixmap && (format == ZPixmap) &&
+ ((planemask & infoRec->FullPlanemasks[pDraw->depth - 1]) ==
+ infoRec->FullPlanemasks[pDraw->depth - 1]) &&
+ (pDraw->bitsPerPixel == BitsPerPixel(pDraw->depth)))
+ {
+ (*infoRec->ReadPixmap)(pScrn,
+ sx + pDraw->x, sy + pDraw->y, w, h,
+ (unsigned char *)pdstLine,
+ PixmapBytePad(w, pDraw->depth),
+ pDraw->bitsPerPixel, pDraw->depth);
+ return;
+ }
+ SYNC_CHECK(pDraw);
+ }
+
+ XAA_SCREEN_PROLOGUE (pScreen, GetImage);
+ (*pScreen->GetImage) (pDraw, sx, sy, w, h, format, planemask, pdstLine);
+ XAA_SCREEN_EPILOGUE (pScreen, GetImage, XAAGetImage);
+}
+
+static void
+XAAGetSpans (
+ DrawablePtr pDraw,
+ int wMax,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ char *pdstStart
+)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ XAA_SCREEN_PROLOGUE (pScreen, GetSpans);
+ if(xf86Screens[pScreen->myNum]->vtSema &&
+ ((pDraw->type == DRAWABLE_WINDOW) || IS_OFFSCREEN_PIXMAP(pDraw))) {
+ SYNC_CHECK(pDraw);
+ }
+ (*pScreen->GetSpans) (pDraw, wMax, ppt, pwidth, nspans, pdstStart);
+ XAA_SCREEN_EPILOGUE (pScreen, GetSpans, XAAGetSpans);
+}
+
+
+static int
+XAAPixmapBPP (ScreenPtr pScreen, int depth)
+{
+ PixmapPtr pPix;
+ int bpp;
+ DestroyPixmapProcPtr destroyPixmap;
+
+ XAA_SCREEN_PROLOGUE (pScreen, CreatePixmap);
+ pPix = (*pScreen->CreatePixmap) (pScreen, 1, 1, depth,
+ CREATE_PIXMAP_USAGE_SCRATCH);
+ XAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, XAACreatePixmap);
+ if (!pPix)
+ return 0;
+ bpp = pPix->drawable.bitsPerPixel;
+ destroyPixmap = pScreen->DestroyPixmap;
+ XAA_SCREEN_PROLOGUE (pScreen, DestroyPixmap);
+ (*pScreen->DestroyPixmap) (pPix);
+ XAA_SCREEN_EPILOGUE (pScreen, DestroyPixmap, destroyPixmap);
+ return bpp;
+}
+
+static void
+XAAInitializeOffscreenDepths (ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ int d, dep;
+
+ infoRec->offscreenDepthsInitialized = TRUE;
+ infoRec->offscreenDepths = 0;
+ if (infoRec->Flags & OFFSCREEN_PIXMAPS) {
+ for (d = 0; d < pScreen->numDepths; d++) {
+ dep = pScreen->allowedDepths[d].depth;
+ if (XAAPixmapBPP (pScreen, dep) == pScrn->bitsPerPixel)
+ infoRec->offscreenDepths |= (1 << (dep - 1));
+ }
+ }
+}
+
+static PixmapPtr
+XAACreatePixmap(ScreenPtr pScreen, int w, int h, int depth, unsigned usage_hint)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XAAPixmapPtr pPriv;
+ PixmapPtr pPix = NULL;
+ int size = w * h;
+
+ if (w > 32767 || h > 32767)
+ return NullPixmap;
+
+ if (!infoRec->offscreenDepthsInitialized)
+ XAAInitializeOffscreenDepths (pScreen);
+
+ if(pScrn->vtSema &&
+ (usage_hint != CREATE_PIXMAP_USAGE_GLYPH_PICTURE) &&
+ (infoRec->offscreenDepths & (1 << (depth - 1))) &&
+ (size >= MIN_OFFPIX_SIZE) && !SwitchedOut &&
+ (!infoRec->maxOffPixWidth || (w <= infoRec->maxOffPixWidth)) &&
+ (!infoRec->maxOffPixHeight || (h <= infoRec->maxOffPixHeight)) )
+ {
+ PixmapLinkPtr pLink;
+ PixmapPtr pScreenPix;
+ FBAreaPtr area;
+ int gran = 0;
+
+ switch(pScrn->bitsPerPixel) {
+ case 24:
+ case 8: gran = 4; break;
+ case 16: gran = 2; break;
+ case 32: gran = 1; break;
+ default: break;
+ }
+
+ if(BITMAP_SCANLINE_PAD == 64)
+ gran *= 2;
+
+ if(!(area = xf86AllocateOffscreenArea(pScreen, w, h, gran, 0,
+ XAARemoveAreaCallback, NULL))) {
+ goto BAILOUT;
+ }
+
+ if(!(pLink = malloc(sizeof(PixmapLink)))) {
+ xf86FreeOffscreenArea(area);
+ goto BAILOUT;
+ }
+
+ XAA_SCREEN_PROLOGUE (pScreen, CreatePixmap);
+ pPix = (*pScreen->CreatePixmap) (pScreen, 0, 0, depth, usage_hint);
+ XAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, XAACreatePixmap);
+
+ if (!pPix) {
+ free(pLink);
+ xf86FreeOffscreenArea(area);
+ goto BAILOUT;
+ }
+
+ pScreenPix = (*pScreen->GetScreenPixmap)(pScreen);
+
+ pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+ pPix->drawable.x = area->box.x1;
+ pPix->drawable.y = area->box.y1;
+ pPix->drawable.width = w;
+ pPix->drawable.height = h;
+ pPix->drawable.bitsPerPixel = pScrn->bitsPerPixel;
+ pPix->devKind = pScreenPix->devKind;
+ pPix->devPrivate.ptr = pScreenPix->devPrivate.ptr;
+ area->devPrivate.ptr = pPix;
+
+ pPriv->flags = OFFSCREEN;
+ pPriv->offscreenArea = area;
+ pPriv->freeData = FALSE;
+
+ pLink->next = infoRec->OffscreenPixmaps;
+ pLink->pPix = pPix;
+ infoRec->OffscreenPixmaps = pLink;
+ return pPix;
+ }
+BAILOUT:
+ XAA_SCREEN_PROLOGUE (pScreen, CreatePixmap);
+ pPix = (*pScreen->CreatePixmap) (pScreen, w, h, depth, usage_hint);
+ XAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, XAACreatePixmap);
+
+ if(pPix) {
+ pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+ pPriv->flags = 0;
+ pPriv->offscreenArea = NULL;
+ pPriv->freeData = FALSE;
+ if(!w || !h) /* either scratch or shared memory */
+ pPriv->flags |= SHARED_PIXMAP;
+ }
+
+ return pPix;
+}
+
+static Bool
+XAADestroyPixmap(PixmapPtr pPix)
+{
+ ScreenPtr pScreen = pPix->drawable.pScreen;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+ Bool ret;
+
+ if(pPix->refcnt == 1) {
+ if(pPriv->flags & OFFSCREEN) {
+ if(pPriv->flags & DGA_PIXMAP)
+ free(pPriv->offscreenArea);
+ else {
+ FBAreaPtr area = pPriv->offscreenArea;
+ PixmapLinkPtr pLink = infoRec->OffscreenPixmaps;
+ PixmapLinkPtr prev = NULL;
+
+ while(pLink->pPix != pPix) {
+ prev = pLink;
+ pLink = pLink->next;
+ }
+
+ if(prev) prev->next = pLink->next;
+ else infoRec->OffscreenPixmaps = pLink->next;
+
+ if(!area) area = pLink->area;
+
+ xf86FreeOffscreenArea(area);
+ pPriv->offscreenArea = NULL;
+ free(pLink);
+ }
+ }
+
+ if(pPriv->freeData) { /* pixmaps that were once in video ram */
+ free(pPix->devPrivate.ptr);
+ pPix->devPrivate.ptr = NULL;
+ }
+ }
+
+ XAA_SCREEN_PROLOGUE (pScreen, DestroyPixmap);
+ ret = (*pScreen->DestroyPixmap) (pPix);
+ XAA_SCREEN_EPILOGUE (pScreen, DestroyPixmap, XAADestroyPixmap);
+
+ return ret;
+}
+
+static Bool
+XAAChangeWindowAttributes (WindowPtr pWin, unsigned long mask)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ Bool ret;
+
+ XAA_SCREEN_PROLOGUE (pScreen, ChangeWindowAttributes);
+ ret = (*pScreen->ChangeWindowAttributes) (pWin, mask);
+ XAA_SCREEN_EPILOGUE (pScreen, ChangeWindowAttributes, XAAChangeWindowAttributes);
+
+ /* we have to assume that shared memory pixmaps are dirty
+ because we can't wrap operations on them */
+
+ if((mask & CWBackPixmap) && (pWin->backgroundState == BackgroundPixmap) &&
+ PIXMAP_IS_SHARED(pWin->background.pixmap))
+ {
+ XAAPixmapPtr pPixPriv = XAA_GET_PIXMAP_PRIVATE(pWin->background.pixmap);
+ pPixPriv->flags |= DIRTY;
+ }
+ if((mask & CWBorderPixmap) && !(pWin->borderIsPixel) &&
+ PIXMAP_IS_SHARED(pWin->border.pixmap))
+ {
+ XAAPixmapPtr pPixPriv = XAA_GET_PIXMAP_PRIVATE(pWin->border.pixmap);
+ pPixPriv->flags |= DIRTY;
+ }
+
+ return ret;
+}
+
+
+
+/* These two aren't really needed for anything */
+
+static Bool
+XAAEnterVT(int index, int flags)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ XAAScreenPtr pScreenPriv =
+ (XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey);
+
+ return((*pScreenPriv->EnterVT)(index, flags));
+}
+
+static void
+XAALeaveVT(int index, int flags)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ XAAScreenPtr pScreenPriv =
+ (XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey);
+ XAAInfoRecPtr infoRec = pScreenPriv->AccelInfoRec;
+
+ if(infoRec->NeedToSync) {
+ (*infoRec->Sync)(infoRec->pScrn);
+ infoRec->NeedToSync = FALSE;
+ }
+
+ (*pScreenPriv->LeaveVT)(index, flags);
+}
+
+typedef struct {
+ Bool UsingPixmapCache;
+ Bool CanDoColor8x8;
+ Bool CanDoMono8x8;
+} SavedCacheState, *SavedCacheStatePtr;
+
+static int
+XAASetDGAMode(int index, int num, DGADevicePtr devRet)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ XAAScreenPtr pScreenPriv =
+ (XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey);
+ int ret;
+
+ if (!num && infoRec->dgaSaves) { /* restore old pixmap cache state */
+ SavedCacheStatePtr state = (SavedCacheStatePtr)infoRec->dgaSaves;
+
+ infoRec->UsingPixmapCache = state->UsingPixmapCache;
+ infoRec->CanDoColor8x8 = state->CanDoColor8x8;
+ infoRec->CanDoMono8x8 = state->CanDoMono8x8;
+ free(infoRec->dgaSaves);
+ infoRec->dgaSaves = NULL;
+ }
+
+ ret = (*pScreenPriv->SetDGAMode)(index, num, devRet);
+ if(ret != Success) return ret;
+
+ if(num && devRet->pPix) { /* accelerate this pixmap */
+ XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(devRet->pPix);
+ FBAreaPtr area;
+
+ if((area = malloc(sizeof(FBArea)))) {
+ area->pScreen = pScreen;
+ area->box.x1 = 0;
+ area->box.x2 = 0;
+ area->box.y1 = devRet->mode->pixmapWidth;
+ area->box.y2 = devRet->mode->pixmapHeight;
+ area->granularity = 0;
+ area->MoveAreaCallback = 0;
+ area->RemoveAreaCallback = 0;
+ area->devPrivate.ptr = 0;
+
+ pixPriv->flags |= OFFSCREEN | DGA_PIXMAP;
+ pixPriv->offscreenArea = area;
+
+ if(!infoRec->dgaSaves) { /* save pixmap cache state */
+ SavedCacheStatePtr state = malloc(sizeof(SavedCacheState));
+
+ state->UsingPixmapCache = infoRec->UsingPixmapCache;
+ state->CanDoColor8x8 = infoRec->CanDoColor8x8;
+ state->CanDoMono8x8 = infoRec->CanDoMono8x8;
+ infoRec->dgaSaves = (char*)state;
+
+ infoRec->UsingPixmapCache = FALSE;
+ if(infoRec->PixmapCacheFlags & CACHE_MONO_8x8)
+ infoRec->CanDoMono8x8 = FALSE;
+ if(infoRec->PixmapCacheFlags & CACHE_COLOR_8x8)
+ infoRec->CanDoColor8x8 = FALSE;
+ }
+ }
+ }
+
+ return ret;
+}
+
+
+
+static void
+XAAEnableDisableFBAccess (int index, Bool enable)
+{
+ ScreenPtr pScreen = screenInfo.screens[index];
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ XAAScreenPtr pScreenPriv =
+ (XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey);
+
+ if(!enable) {
+ if((infoRec->Flags & OFFSCREEN_PIXMAPS) && (infoRec->OffscreenPixmaps))
+ XAAMoveOutOffscreenPixmaps(pScreen);
+ if(infoRec->Flags & PIXMAP_CACHE)
+ XAAInvalidatePixmapCache(pScreen);
+ SwitchedOut = TRUE;
+ }
+
+ (*pScreenPriv->EnableDisableFBAccess)(index, enable);
+
+ if(enable) {
+ if((infoRec->Flags & OFFSCREEN_PIXMAPS) && (infoRec->OffscreenPixmaps))
+ XAAMoveInOffscreenPixmaps(pScreen);
+ SwitchedOut = FALSE;
+ }
+}
diff --git a/xorg-server/hw/xfree86/xaa/xaaInitAccel.c b/xorg-server/hw/xfree86/xaa/xaaInitAccel.c
index 6f3d622e1..d24599d48 100644
--- a/xorg-server/hw/xfree86/xaa/xaaInitAccel.c
+++ b/xorg-server/hw/xfree86/xaa/xaaInitAccel.c
@@ -1,1498 +1,1498 @@
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <string.h>
-
-#include "misc.h"
-#include "xf86.h"
-#include "xf86_OSproc.h"
-
-#include <X11/X.h>
-#include "scrnintstr.h"
-#include "xf86str.h"
-#include "xaa.h"
-#include "xaalocal.h"
-#include "xf86fbman.h"
-#include "servermd.h"
-
-/*
- * XAA Config options
- */
-
-typedef enum {
- XAAOPT_SCREEN_TO_SCREEN_COPY,
- XAAOPT_SOLID_FILL_RECT,
- XAAOPT_SOLID_FILL_TRAP,
- XAAOPT_SOLID_TWO_POINT_LINE,
- XAAOPT_SOLID_BRESENHAM_LINE,
- XAAOPT_SOLID_HORVERT_LINE,
- XAAOPT_DASHED_TWO_POINT_LINE,
- XAAOPT_DASHED_BRESENHAM_LINE,
- XAAOPT_MONO_8x8_PATTERN_FILL_RECT,
- XAAOPT_MONO_8x8_PATTERN_FILL_TRAP,
- XAAOPT_COL_8x8_PATTERN_FILL_RECT,
- XAAOPT_COL_8x8_PATTERN_FILL_TRAP,
- XAAOPT_CPU_TO_SCREEN_COL_EXP_FILL,
- XAAOPT_SCANLINE_CPU_TO_SCREEN_COL_EXP_FILL,
- XAAOPT_SCREEN_TO_SCREEN_COL_EXP_FILL,
- XAAOPT_IMAGE_WRITE_RECT,
- XAAOPT_SCANLINE_IMAGE_WRITE_RECT,
- XAAOPT_WRITE_BITMAP,
- XAAOPT_WRITE_PIXMAP,
- XAAOPT_PIXMAP_CACHE,
- XAAOPT_OFFSCREEN_PIXMAPS,
- XAAOPT_HAS_DUMB_INVERTED_OPTION_SENSE
-} XAAOpts;
-
-static const OptionInfoRec XAAOptions[] = {
- {XAAOPT_SCREEN_TO_SCREEN_COPY, "XaaNoScreenToScreenCopy",
- OPTV_BOOLEAN, {0}, FALSE },
- {XAAOPT_SOLID_FILL_RECT, "XaaNoSolidFillRect",
- OPTV_BOOLEAN, {0}, FALSE },
- {XAAOPT_SOLID_FILL_TRAP, "XaaNoSolidFillTrap",
- OPTV_BOOLEAN, {0}, FALSE },
- {XAAOPT_SOLID_TWO_POINT_LINE, "XaaNoSolidTwoPointLine",
- OPTV_BOOLEAN, {0}, FALSE },
- {XAAOPT_SOLID_BRESENHAM_LINE, "XaaNoSolidBresenhamLine",
- OPTV_BOOLEAN, {0}, FALSE },
- {XAAOPT_SOLID_HORVERT_LINE, "XaaNoSolidHorVertLine",
- OPTV_BOOLEAN, {0}, FALSE },
- {XAAOPT_DASHED_TWO_POINT_LINE, "XaaNoDashedTwoPointLine",
- OPTV_BOOLEAN, {0}, FALSE },
- {XAAOPT_DASHED_BRESENHAM_LINE, "XaaNoDashedBresenhamLine",
- OPTV_BOOLEAN, {0}, FALSE },
- {XAAOPT_MONO_8x8_PATTERN_FILL_RECT, "XaaNoMono8x8PatternFillRect",
- OPTV_BOOLEAN, {0}, FALSE },
- {XAAOPT_MONO_8x8_PATTERN_FILL_TRAP, "XaaNoMono8x8PatternFillTrap",
- OPTV_BOOLEAN, {0}, FALSE },
- {XAAOPT_COL_8x8_PATTERN_FILL_RECT, "XaaNoColor8x8PatternFillRect",
- OPTV_BOOLEAN, {0}, FALSE },
- {XAAOPT_COL_8x8_PATTERN_FILL_TRAP, "XaaNoColor8x8PatternFillTrap",
- OPTV_BOOLEAN, {0}, FALSE },
- {XAAOPT_CPU_TO_SCREEN_COL_EXP_FILL, "XaaNoCPUToScreenColorExpandFill",
- OPTV_BOOLEAN, {0}, FALSE },
- {XAAOPT_SCANLINE_CPU_TO_SCREEN_COL_EXP_FILL,"XaaNoScanlineCPUToScreenColorExpandFill",
- OPTV_BOOLEAN, {0}, FALSE },
- {XAAOPT_SCREEN_TO_SCREEN_COL_EXP_FILL, "XaaNoScreenToScreenColorExpandFill",
- OPTV_BOOLEAN, {0}, FALSE },
- {XAAOPT_IMAGE_WRITE_RECT, "XaaNoImageWriteRect",
- OPTV_BOOLEAN, {0}, FALSE },
- {XAAOPT_SCANLINE_IMAGE_WRITE_RECT, "XaaNoScanlineImageWriteRect",
- OPTV_BOOLEAN, {0}, FALSE },
- {XAAOPT_WRITE_BITMAP, "XaaNoWriteBitmap",
- OPTV_BOOLEAN, {0}, FALSE },
- {XAAOPT_WRITE_PIXMAP, "XaaNoWritePixmap",
- OPTV_BOOLEAN, {0}, FALSE },
- {XAAOPT_PIXMAP_CACHE, "XaaNoPixmapCache",
- OPTV_BOOLEAN, {0}, FALSE },
- {XAAOPT_OFFSCREEN_PIXMAPS, "XaaNoOffscreenPixmaps",
- OPTV_BOOLEAN, {0}, FALSE },
- {XAAOPT_HAS_DUMB_INVERTED_OPTION_SENSE, "XaaOffscreenPixmaps",
- OPTV_BOOLEAN, {0}, FALSE },
- { -1, NULL,
- OPTV_NONE, {0}, FALSE }
-};
-
-static XF86ModuleVersionInfo xaaVersRec =
-{
- "xaa",
- MODULEVENDORSTRING,
- MODINFOSTRING1,
- MODINFOSTRING2,
- XORG_VERSION_CURRENT,
- XAA_VERSION_MAJOR,
- XAA_VERSION_MINOR,
- XAA_VERSION_RELEASE,
- ABI_CLASS_VIDEODRV, /* requires the video driver ABI */
- ABI_VIDEODRV_VERSION,
- MOD_CLASS_NONE,
- {0,0,0,0}
-};
-
-_X_EXPORT XF86ModuleData xaaModuleData = { &xaaVersRec, NULL, NULL };
-
-Bool
-XAAInitAccel(ScreenPtr pScreen, XAAInfoRecPtr infoRec)
-{
- int index = pScreen->myNum;
- ScrnInfoPtr pScrn = xf86Screens[index];
- Bool HaveScreenToScreenCopy = FALSE;
- Bool HaveColorExpansion = FALSE;
- Bool HaveScanlineColorExpansion = FALSE;
- Bool HaveSolidFillRect = FALSE;
- Bool HaveMono8x8PatternFillRect = FALSE;
- Bool HaveColor8x8PatternFillRect = FALSE;
- Bool HaveSolidFillTrap = FALSE;
- Bool HaveMono8x8PatternFillTrap = FALSE;
- Bool HaveColor8x8PatternFillTrap = FALSE;
- Bool HaveSolidTwoPointLine = FALSE;
- Bool HaveSolidBresenhamLine = FALSE;
- Bool HaveSolidHorVertLine = FALSE;
- Bool HaveDashedTwoPointLine = FALSE;
- Bool HaveDashedBresenhamLine = FALSE;
- Bool HaveImageWriteRect = FALSE;
- Bool HaveScanlineImageWriteRect = FALSE;
- Bool HaveScreenToScreenColorExpandFill = FALSE;
- OptionInfoPtr options;
- int is_shared = 0;
- int i;
-
- options = xnfalloc(sizeof(XAAOptions));
- (void)memcpy(options, XAAOptions, sizeof(XAAOptions));
- xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
-
- infoRec->pScrn = pScrn;
- infoRec->NeedToSync = FALSE;
-
- /* must have a Sync function */
- if(!infoRec->Sync) return FALSE;
- for(i = 0; i < pScrn->numEntities; i++) {
- if(xf86IsEntityShared(pScrn->entityList[i])) is_shared = 1;
- }
-
- /* If this PCI entity has IS_SHARED_ACCEL set in entityProp
- * then a RestoreAccelState function is required
- */
- if(!infoRec->RestoreAccelState && is_shared) return FALSE;
-
- if(infoRec->RestoreAccelState) {
- if(!XAAInitStateWrap(pScreen, infoRec)) return FALSE;
- }
-
- if (serverGeneration == 1)
- xf86DrvMsg(index, X_INFO,
- "Using XFree86 Acceleration Architecture (XAA)\n");
-
-
- /************** Low Level *************/
-
- if(!infoRec->SetClippingRectangle || !infoRec->DisableClipping) {
- infoRec->ClippingFlags = 0;
- infoRec->SetClippingRectangle = NULL;
- infoRec->DisableClipping = NULL;
- }
-
- /**** CopyArea ****/
-
- if(infoRec->SetupForScreenToScreenCopy &&
- infoRec->SubsequentScreenToScreenCopy &&
- !xf86ReturnOptValBool(options, XAAOPT_SCREEN_TO_SCREEN_COPY, FALSE)) {
- HaveScreenToScreenCopy = TRUE;
- } else {
- infoRec->ScreenToScreenCopyFlags = 0;
- infoRec->SetupForScreenToScreenCopy = NULL;
- infoRec->SubsequentScreenToScreenCopy = NULL;
- }
-
- /**** Solid Filled Rects ****/
-
- if(infoRec->SetupForSolidFill && infoRec->SubsequentSolidFillRect &&
- !xf86ReturnOptValBool(options, XAAOPT_SOLID_FILL_RECT, FALSE)) {
- HaveSolidFillRect = TRUE;
- if(infoRec->SubsequentSolidFillTrap &&
- !xf86ReturnOptValBool(options, XAAOPT_SOLID_FILL_TRAP, FALSE))
- HaveSolidFillTrap = TRUE;
- else
- infoRec->SubsequentSolidFillTrap = NULL;
- } else {
- infoRec->SolidFillFlags = 0;
- infoRec->SetupForSolidFill = NULL;
- infoRec->SubsequentSolidFillRect = NULL;
- infoRec->SubsequentSolidFillTrap = NULL;
- }
-
- /**** Solid lines ****/
-
- if(infoRec->SetupForSolidLine) {
- if(infoRec->SubsequentSolidTwoPointLine &&
- !xf86ReturnOptValBool(options,
- XAAOPT_SOLID_TWO_POINT_LINE, FALSE))
- HaveSolidTwoPointLine = TRUE;
- if(infoRec->SubsequentSolidBresenhamLine &&
- !xf86ReturnOptValBool(options, XAAOPT_SOLID_BRESENHAM_LINE, FALSE)) {
- HaveSolidBresenhamLine = TRUE;
-
- if(infoRec->SolidBresenhamLineErrorTermBits)
- infoRec->SolidBresenhamLineErrorTermBits =
- ~((1 << infoRec->SolidBresenhamLineErrorTermBits) - 1);
- }
-
- if(infoRec->SubsequentSolidHorVertLine &&
- !xf86ReturnOptValBool(options,
- XAAOPT_SOLID_HORVERT_LINE, FALSE))
- HaveSolidHorVertLine = TRUE;
- else if(HaveSolidTwoPointLine) {
- infoRec->SubsequentSolidHorVertLine =
- XAASolidHorVertLineAsTwoPoint;
- HaveSolidHorVertLine = TRUE;
- } else if(HaveSolidBresenhamLine) {
- infoRec->SubsequentSolidHorVertLine =
- XAASolidHorVertLineAsBresenham;
- HaveSolidHorVertLine = TRUE;
- }
- }
-
- /* XXX Should this also check for XAAOPT_SOLID_HORVERT_LINE? */
- if (!HaveSolidTwoPointLine &&
- !HaveSolidBresenhamLine &&
- !HaveSolidHorVertLine &&
- HaveSolidFillRect) {
- infoRec->SetupForSolidLine = infoRec->SetupForSolidFill;
- infoRec->SubsequentSolidHorVertLine = XAASolidHorVertLineAsRects;
- infoRec->SolidLineFlags = infoRec->SolidFillFlags;
- HaveSolidHorVertLine = TRUE;
- }
-
- if (!HaveSolidTwoPointLine)
- infoRec->SubsequentSolidTwoPointLine = NULL;
- if (!HaveSolidBresenhamLine)
- infoRec->SubsequentSolidBresenhamLine = NULL;
- if (!HaveSolidHorVertLine)
- infoRec->SubsequentSolidHorVertLine = NULL;
-
- /* Disable all if nothing left over */
- if (!HaveSolidTwoPointLine &&
- !HaveSolidBresenhamLine &&
- !HaveSolidHorVertLine) {
- infoRec->SolidLineFlags = 0;
- infoRec->SetupForSolidLine = NULL;
- }
-
- /**** 8x8 Mono Pattern Filled Rects ****/
-
- if(infoRec->SetupForMono8x8PatternFill &&
- infoRec->SubsequentMono8x8PatternFillRect &&
- !xf86ReturnOptValBool(options,
- XAAOPT_MONO_8x8_PATTERN_FILL_RECT,
- FALSE)) {
- HaveMono8x8PatternFillRect = TRUE;
- if(infoRec->SubsequentMono8x8PatternFillTrap &&
- !xf86ReturnOptValBool(options,
- XAAOPT_MONO_8x8_PATTERN_FILL_TRAP,
- FALSE))
- HaveMono8x8PatternFillTrap = TRUE;
-
- if(infoRec->Mono8x8PatternFillFlags &
- HARDWARE_PATTERN_PROGRAMMED_BITS) {
- infoRec->CanDoMono8x8 = TRUE;
- } else { /* others require caching */
- int min_pitch;
- infoRec->PixmapCacheFlags |= CACHE_MONO_8x8;
-
- switch(pScrn->bitsPerPixel) {
- case 32: min_pitch = 2; break;
- case 24: min_pitch = 3; break;
- case 16: min_pitch = 4; break;
- default: min_pitch = 8; break;
- }
-
- if(min_pitch > infoRec->MonoPatternPitch)
- infoRec->MonoPatternPitch = min_pitch;
-
- if(infoRec->Mono8x8PatternFillFlags &
- HARDWARE_PATTERN_PROGRAMMED_ORIGIN) {
- if(!infoRec->CacheWidthMono8x8Pattern ||
- !infoRec->CacheHeightMono8x8Pattern) {
- infoRec->CacheWidthMono8x8Pattern =
- infoRec->MonoPatternPitch;
- infoRec->CacheHeightMono8x8Pattern = 1;
- }
- } else {
- int numPerLine = 128/infoRec->MonoPatternPitch;
-
- if(!infoRec->CacheWidthMono8x8Pattern ||
- !infoRec->CacheHeightMono8x8Pattern) {
- infoRec->CacheWidthMono8x8Pattern =
- numPerLine * infoRec->MonoPatternPitch;
- infoRec->CacheHeightMono8x8Pattern =
- (64 + numPerLine - 1)/numPerLine;
- }
- }
- }
- } else {
- infoRec->Mono8x8PatternFillFlags = 0;
- infoRec->SetupForMono8x8PatternFill = NULL;
- infoRec->SubsequentMono8x8PatternFillRect = NULL;
- }
-
- /**** Dashed lines ****/
-
- if(infoRec->SetupForDashedLine && infoRec->DashPatternMaxLength) {
- if(infoRec->SubsequentDashedTwoPointLine &&
- !xf86ReturnOptValBool(options, XAAOPT_DASHED_TWO_POINT_LINE,
- FALSE))
- HaveDashedTwoPointLine = TRUE;
- if(infoRec->SubsequentDashedBresenhamLine &&
- !xf86ReturnOptValBool(options, XAAOPT_DASHED_BRESENHAM_LINE,
- FALSE)) {
- HaveDashedBresenhamLine = TRUE;
-
- if(infoRec->DashedBresenhamLineErrorTermBits)
- infoRec->DashedBresenhamLineErrorTermBits =
- ~((1 << infoRec->DashedBresenhamLineErrorTermBits) - 1);
- }
- }
-
- if (!HaveDashedTwoPointLine)
- infoRec->SubsequentDashedTwoPointLine = NULL;
- if (!HaveDashedBresenhamLine)
- infoRec->SubsequentDashedBresenhamLine = NULL;
-
- /* Disable all if nothing left over */
- if (!HaveDashedTwoPointLine && !HaveDashedBresenhamLine) {
- infoRec->DashedLineFlags = 0;
- infoRec->SetupForDashedLine = NULL;
- }
-
- /**** 8x8 Color Pattern Filled Rects ****/
-
- if(infoRec->SetupForColor8x8PatternFill &&
- infoRec->SubsequentColor8x8PatternFillRect &&
- !xf86ReturnOptValBool(options, XAAOPT_COL_8x8_PATTERN_FILL_RECT, FALSE)) {
- HaveColor8x8PatternFillRect = TRUE;
- if(infoRec->SubsequentColor8x8PatternFillTrap &&
- !xf86ReturnOptValBool(options, XAAOPT_COL_8x8_PATTERN_FILL_TRAP,
- FALSE))
- HaveColor8x8PatternFillTrap = TRUE;
- else
- infoRec->SubsequentColor8x8PatternFillTrap = NULL;
-
- infoRec->PixmapCacheFlags |= CACHE_COLOR_8x8;
-
- if(infoRec->Color8x8PatternFillFlags &
- HARDWARE_PATTERN_PROGRAMMED_ORIGIN) {
- if(!infoRec->CacheWidthColor8x8Pattern ||
- !infoRec->CacheHeightColor8x8Pattern) {
- infoRec->CacheWidthColor8x8Pattern = 64;
- infoRec->CacheHeightColor8x8Pattern = 1;
- }
- } else {
- if(!infoRec->CacheWidthColor8x8Pattern ||
- !infoRec->CacheHeightColor8x8Pattern) {
- infoRec->CacheWidthColor8x8Pattern = 128;
- infoRec->CacheHeightColor8x8Pattern = 8;
- }
- }
- } else {
- infoRec->Color8x8PatternFillFlags = 0;
- infoRec->SetupForColor8x8PatternFill = NULL;
- infoRec->SubsequentColor8x8PatternFillRect = NULL;
- infoRec->SubsequentColor8x8PatternFillTrap = NULL;
- }
-
- /**** Color Expansion ****/
-
- if(infoRec->SetupForCPUToScreenColorExpandFill &&
- infoRec->ColorExpandBase &&
- infoRec->SubsequentCPUToScreenColorExpandFill &&
- !xf86ReturnOptValBool(options, XAAOPT_CPU_TO_SCREEN_COL_EXP_FILL,
- FALSE)) {
- int dwordsNeeded = pScrn->virtualX;
-
- infoRec->ColorExpandRange >>= 2; /* convert to DWORDS */
- HaveColorExpansion = TRUE;
-
- if(infoRec->CPUToScreenColorExpandFillFlags &
- LEFT_EDGE_CLIPPING_NEGATIVE_X)
- dwordsNeeded += 31;
- dwordsNeeded = (dwordsNeeded + 31) >> 5;
- if(dwordsNeeded > infoRec->ColorExpandRange)
- infoRec->CPUToScreenColorExpandFillFlags |= CPU_TRANSFER_BASE_FIXED;
- } else {
- infoRec->CPUToScreenColorExpandFillFlags = 0;
- infoRec->SetupForCPUToScreenColorExpandFill = NULL;
- infoRec->SubsequentCPUToScreenColorExpandFill = NULL;
- }
-
- /**** Scanline Color Expansion ****/
-
- if(infoRec->SetupForScanlineCPUToScreenColorExpandFill &&
- infoRec->SubsequentScanlineCPUToScreenColorExpandFill &&
- infoRec->SubsequentColorExpandScanline &&
- infoRec->ScanlineColorExpandBuffers &&
- (infoRec->NumScanlineColorExpandBuffers > 0) &&
- !xf86ReturnOptValBool(options,
- XAAOPT_SCANLINE_CPU_TO_SCREEN_COL_EXP_FILL,
- FALSE)) {
- HaveScanlineColorExpansion = TRUE;
- } else {
- infoRec->ScanlineCPUToScreenColorExpandFillFlags = 0;
- infoRec->SetupForScanlineCPUToScreenColorExpandFill = NULL;
- infoRec->SubsequentScanlineCPUToScreenColorExpandFill = NULL;
- infoRec->SubsequentColorExpandScanline = NULL;
- }
-
- /**** Screen to Screen Color Expansion ****/
-
- if(infoRec->SetupForScreenToScreenColorExpandFill &&
- infoRec->SubsequentScreenToScreenColorExpandFill &&
- !xf86ReturnOptValBool(options, XAAOPT_SCREEN_TO_SCREEN_COL_EXP_FILL,
- FALSE)) {
- HaveScreenToScreenColorExpandFill = TRUE;
- if (!infoRec->CacheColorExpandDensity)
- infoRec->CacheColorExpandDensity = 1;
- } else {
- infoRec->ScreenToScreenColorExpandFillFlags = 0;
- infoRec->SetupForScreenToScreenColorExpandFill = NULL;
- infoRec->SubsequentScreenToScreenColorExpandFill = NULL;
- }
-
- /**** Image Writes ****/
-
- if(infoRec->SetupForImageWrite && infoRec->ImageWriteBase &&
- infoRec->SubsequentImageWriteRect &&
- !xf86ReturnOptValBool(options, XAAOPT_IMAGE_WRITE_RECT, FALSE)) {
-
- infoRec->ImageWriteRange >>= 2; /* convert to DWORDS */
- if(infoRec->ImageWriteFlags & CPU_TRANSFER_BASE_FIXED)
- infoRec->ImageWriteRange = 0;
- HaveImageWriteRect = TRUE;
- } else {
- infoRec->ImageWriteFlags = 0;
- infoRec->SetupForImageWrite = NULL;
- infoRec->SubsequentImageWriteRect = NULL;
- }
-
- /**** Scanline Image Writes ****/
-
- if(infoRec->SetupForScanlineImageWrite &&
- infoRec->SubsequentScanlineImageWriteRect &&
- infoRec->SubsequentImageWriteScanline &&
- infoRec->ScanlineImageWriteBuffers &&
- (infoRec->NumScanlineImageWriteBuffers > 0) &&
- !xf86ReturnOptValBool(options, XAAOPT_SCANLINE_IMAGE_WRITE_RECT,
- FALSE)) {
- HaveScanlineImageWriteRect = TRUE;
- } else {
- infoRec->ScanlineImageWriteFlags = 0;
- infoRec->SetupForScanlineImageWrite = NULL;
- infoRec->SubsequentScanlineImageWriteRect = NULL;
- infoRec->SubsequentImageWriteScanline = NULL;
- }
-
-#ifndef __i386__
- /* XAA makes some unaligned accesses when clipping is not available */
-# define CLIP_FLAGS (LEFT_EDGE_CLIPPING | LEFT_EDGE_CLIPPING_NEGATIVE_X)
- if(HaveImageWriteRect &&
- ((infoRec->ImageWriteFlags & CLIP_FLAGS) != CLIP_FLAGS))
- {
- HaveImageWriteRect = FALSE;
- }
- if(HaveScanlineImageWriteRect &&
- ((infoRec->ScanlineImageWriteFlags & CLIP_FLAGS) != CLIP_FLAGS))
- {
- HaveScanlineImageWriteRect = FALSE;
- }
-#endif
-
- if (serverGeneration == 1) {
- if(HaveScreenToScreenCopy)
- xf86ErrorF("\tScreen to screen bit blits\n");
- if(HaveSolidFillRect)
- xf86ErrorF("\tSolid filled rectangles\n");
- if(HaveSolidFillTrap)
- xf86ErrorF("\tSolid filled trapezoids\n");
- if(HaveMono8x8PatternFillRect)
- xf86ErrorF("\t8x8 mono pattern filled rectangles\n");
- if(HaveMono8x8PatternFillTrap)
- xf86ErrorF("\t8x8 mono pattern filled trapezoids\n");
- if(HaveColor8x8PatternFillRect)
- xf86ErrorF("\t8x8 color pattern filled rectangles\n");
- if(HaveColor8x8PatternFillTrap)
- xf86ErrorF("\t8x8 color pattern filled trapezoids\n");
-
- if(HaveColorExpansion)
- xf86ErrorF("\tCPU to Screen color expansion\n");
- else if(HaveScanlineColorExpansion)
- xf86ErrorF("\tIndirect CPU to Screen color expansion\n");
-
- if(HaveScreenToScreenColorExpandFill)
- xf86ErrorF("\tScreen to Screen color expansion\n");
-
- if(HaveSolidTwoPointLine || HaveSolidBresenhamLine)
- xf86ErrorF("\tSolid Lines\n");
- else if(HaveSolidHorVertLine)
- xf86ErrorF("\tSolid Horizontal and Vertical Lines\n");
-
- if(HaveDashedTwoPointLine || HaveDashedBresenhamLine)
- xf86ErrorF("\tDashed Lines\n");
-
- if(HaveImageWriteRect)
- xf86ErrorF("\tImage Writes\n");
- else if(HaveScanlineImageWriteRect)
- xf86ErrorF("\tScanline Image Writes\n");
-
- }
-
-#define XAAMSG(s) do { if (serverGeneration == 1) xf86ErrorF(s); } while (0)
-
- if((infoRec->Flags & OFFSCREEN_PIXMAPS) && HaveScreenToScreenCopy &&
- xf86ReturnOptValBool(options,
- XAAOPT_HAS_DUMB_INVERTED_OPTION_SENSE,
- FALSE))
- {
- XAAMSG("\tOffscreen Pixmaps\n");
- } else {
- infoRec->Flags &= ~OFFSCREEN_PIXMAPS;
- }
-
-
- /************** Mid Level *************/
-
- /**** ScreenToScreenBitBlt ****/
-
- if(infoRec->ScreenToScreenBitBlt) {
- XAAMSG("\tDriver provided ScreenToScreenBitBlt replacement\n");
- } else if(HaveScreenToScreenCopy) {
- infoRec->ScreenToScreenBitBlt = XAAScreenToScreenBitBlt;
- infoRec->ScreenToScreenBitBltFlags = infoRec->ScreenToScreenCopyFlags;
- }
-
- /**** FillSolidRects ****/
-
- if(infoRec->FillSolidRects) {
- XAAMSG("\tDriver provided FillSolidRects replacement\n");
- } else if(HaveSolidFillRect) {
- infoRec->FillSolidRects = XAAFillSolidRects;
- infoRec->FillSolidRectsFlags = infoRec->SolidFillFlags;
- }
-
- /**** FillSolidSpans ****/
-
- if(infoRec->FillSolidSpans) {
- XAAMSG("\tDriver provided FillSolidSpans replacement\n");
- } else if(HaveSolidFillRect) {
- infoRec->FillSolidSpans = XAAFillSolidSpans;
- infoRec->FillSolidSpansFlags = infoRec->SolidFillFlags;
- }
-
- /**** FillMono8x8PatternRects ****/
-
- if(infoRec->FillMono8x8PatternRects) {
- XAAMSG("\tDriver provided FillMono8x8PatternRects replacement\n");
- } else if(HaveMono8x8PatternFillRect) {
- infoRec->FillMono8x8PatternRects =
- (infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_SCREEN_ORIGIN) ?
- XAAFillMono8x8PatternRectsScreenOrigin :
- XAAFillMono8x8PatternRects;
-
- infoRec->FillMono8x8PatternRectsFlags =
- infoRec->Mono8x8PatternFillFlags;
- }
-
- /**** FillMono8x8PatternSpans ****/
-
- if(infoRec->FillMono8x8PatternSpans) {
- XAAMSG("\tDriver provided FillMono8x8PatternSpans replacement\n");
- } else if(HaveMono8x8PatternFillRect) {
- infoRec->FillMono8x8PatternSpans =
- (infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_SCREEN_ORIGIN) ?
- XAAFillMono8x8PatternSpansScreenOrigin:
- XAAFillMono8x8PatternSpans;
-
- infoRec->FillMono8x8PatternSpansFlags =
- infoRec->Mono8x8PatternFillFlags;
- }
-
- /**** FillColor8x8Rects ****/
-
- if(infoRec->FillColor8x8PatternRects) {
- XAAMSG("\tDriver provided FillColor8x8PatternRects replacement\n");
- } else if(HaveColor8x8PatternFillRect) {
- infoRec->FillColor8x8PatternRects =
- (infoRec->Color8x8PatternFillFlags & HARDWARE_PATTERN_SCREEN_ORIGIN) ?
- XAAFillColor8x8PatternRectsScreenOrigin :
- XAAFillColor8x8PatternRects;
-
- infoRec->FillColor8x8PatternRectsFlags =
- infoRec->Color8x8PatternFillFlags;
- }
-
- /**** FillColor8x8Spans ****/
-
- if(infoRec->FillColor8x8PatternSpans) {
- XAAMSG("\tDriver provided FillColor8x8PatternSpans replacement\n");
- } else if(HaveColor8x8PatternFillRect) {
- infoRec->FillColor8x8PatternSpans =
- (infoRec->Color8x8PatternFillFlags & HARDWARE_PATTERN_SCREEN_ORIGIN) ?
- XAAFillColor8x8PatternSpansScreenOrigin:
- XAAFillColor8x8PatternSpans;
-
- infoRec->FillColor8x8PatternSpansFlags =
- infoRec->Color8x8PatternFillFlags;
- }
-
- /**** FillCacheBltRects ****/
-
- if(infoRec->FillCacheBltRects) {
- XAAMSG("\tDriver provided FillCacheBltRects replacement\n");
- } else if(HaveScreenToScreenCopy) {
- infoRec->FillCacheBltRects = XAAFillCacheBltRects;
- infoRec->FillCacheBltRectsFlags = infoRec->ScreenToScreenCopyFlags;
- }
-
- /**** FillCacheBltSpans ****/
-
- if(infoRec->FillCacheBltSpans) {
- XAAMSG("\tDriver provided FillCacheBltSpans replacement\n");
- } else if(HaveScreenToScreenCopy) {
- infoRec->FillCacheBltSpans = XAAFillCacheBltSpans;
- infoRec->FillCacheBltSpansFlags = infoRec->ScreenToScreenCopyFlags;
- }
-
- /**** FillCacheExpandRects ****/
-
- if(infoRec->FillCacheExpandRects) {
- XAAMSG("\tDriver provided FillCacheExpandRects replacement\n");
- } else if(HaveScreenToScreenColorExpandFill) {
- infoRec->FillCacheExpandRects = XAAFillCacheExpandRects;
- infoRec->FillCacheExpandRectsFlags =
- infoRec->ScreenToScreenColorExpandFillFlags;
- }
-
- /**** FillCacheExpandSpans ****/
-
- if(infoRec->FillCacheExpandSpans) {
- XAAMSG("\tDriver provided FillCacheExpandSpans replacement\n");
- } else if(HaveScreenToScreenColorExpandFill) {
- infoRec->FillCacheExpandSpans = XAAFillCacheExpandSpans;
- infoRec->FillCacheExpandSpansFlags =
- infoRec->ScreenToScreenColorExpandFillFlags;
- }
-
- /**** FillColorExpandRects ****/
-
- if(infoRec->FillColorExpandRects) {
- XAAMSG("\tDriver provided FillColorExpandRects replacement\n");
- } else if(HaveColorExpansion) {
- if (infoRec->CPUToScreenColorExpandFillFlags & TRIPLE_BITS_24BPP) {
- if(infoRec->CPUToScreenColorExpandFillFlags &
- BIT_ORDER_IN_BYTE_MSBFIRST) {
- if(infoRec->CPUToScreenColorExpandFillFlags &
- CPU_TRANSFER_BASE_FIXED)
- infoRec->FillColorExpandRects =
- XAAFillColorExpandRects3MSBFirstFixedBase;
- else
- infoRec->FillColorExpandRects =
- XAAFillColorExpandRects3MSBFirst;
- } else {
- if(infoRec->CPUToScreenColorExpandFillFlags &
- CPU_TRANSFER_BASE_FIXED)
- infoRec->FillColorExpandRects =
- XAAFillColorExpandRects3LSBFirstFixedBase;
- else
- infoRec->FillColorExpandRects =
- XAAFillColorExpandRects3LSBFirst;
- }
- } else {
- if(infoRec->CPUToScreenColorExpandFillFlags &
- BIT_ORDER_IN_BYTE_MSBFIRST) {
- if(infoRec->CPUToScreenColorExpandFillFlags &
- CPU_TRANSFER_BASE_FIXED)
- infoRec->FillColorExpandRects =
- XAAFillColorExpandRectsMSBFirstFixedBase;
- else
- infoRec->FillColorExpandRects =
- XAAFillColorExpandRectsMSBFirst;
- } else {
- if(infoRec->CPUToScreenColorExpandFillFlags &
- CPU_TRANSFER_BASE_FIXED)
- infoRec->FillColorExpandRects =
- XAAFillColorExpandRectsLSBFirstFixedBase;
- else
- infoRec->FillColorExpandRects =
- XAAFillColorExpandRectsLSBFirst;
- }
- }
- infoRec->FillColorExpandRectsFlags =
- infoRec->CPUToScreenColorExpandFillFlags;
- } else if(HaveScanlineColorExpansion) {
- if (infoRec->ScanlineCPUToScreenColorExpandFillFlags &
- TRIPLE_BITS_24BPP) {
- if(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
- BIT_ORDER_IN_BYTE_MSBFIRST)
- infoRec->FillColorExpandRects =
- XAAFillScanlineColorExpandRects3MSBFirst;
- else
- infoRec->FillColorExpandRects =
- XAAFillScanlineColorExpandRects3LSBFirst;
- } else {
- if(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
- BIT_ORDER_IN_BYTE_MSBFIRST)
- infoRec->FillColorExpandRects =
- XAAFillScanlineColorExpandRectsMSBFirst;
- else
- infoRec->FillColorExpandRects =
- XAAFillScanlineColorExpandRectsLSBFirst;
- }
- infoRec->FillColorExpandRectsFlags =
- infoRec->ScanlineCPUToScreenColorExpandFillFlags;
- }
-
- /**** FillColorExpandSpans ****/
-
- if(infoRec->FillColorExpandSpans) {
- XAAMSG("\tDriver provided FillColorExpandSpans replacement\n");
- } else if(HaveColorExpansion) {
- if (infoRec->CPUToScreenColorExpandFillFlags & TRIPLE_BITS_24BPP) {
- if(infoRec->CPUToScreenColorExpandFillFlags &
- BIT_ORDER_IN_BYTE_MSBFIRST) {
- if(infoRec->CPUToScreenColorExpandFillFlags &
- CPU_TRANSFER_BASE_FIXED)
- infoRec->FillColorExpandSpans =
- XAAFillColorExpandSpans3MSBFirstFixedBase;
- else
- infoRec->FillColorExpandSpans =
- XAAFillColorExpandSpans3MSBFirst;
- } else {
- if(infoRec->CPUToScreenColorExpandFillFlags &
- CPU_TRANSFER_BASE_FIXED)
- infoRec->FillColorExpandSpans =
- XAAFillColorExpandSpans3LSBFirstFixedBase;
- else
- infoRec->FillColorExpandSpans =
- XAAFillColorExpandSpans3LSBFirst;
- }
- } else {
- if(infoRec->CPUToScreenColorExpandFillFlags &
- BIT_ORDER_IN_BYTE_MSBFIRST) {
- if(infoRec->CPUToScreenColorExpandFillFlags &
- CPU_TRANSFER_BASE_FIXED)
- infoRec->FillColorExpandSpans =
- XAAFillColorExpandSpansMSBFirstFixedBase;
- else
- infoRec->FillColorExpandSpans =
- XAAFillColorExpandSpansMSBFirst;
- } else {
- if(infoRec->CPUToScreenColorExpandFillFlags &
- CPU_TRANSFER_BASE_FIXED)
- infoRec->FillColorExpandSpans =
- XAAFillColorExpandSpansLSBFirstFixedBase;
- else
- infoRec->FillColorExpandSpans =
- XAAFillColorExpandSpansLSBFirst;
- }
- }
- infoRec->FillColorExpandSpansFlags =
- infoRec->CPUToScreenColorExpandFillFlags;
- } else if(HaveScanlineColorExpansion) {
- if (infoRec->ScanlineCPUToScreenColorExpandFillFlags &
- TRIPLE_BITS_24BPP) {
- if(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
- BIT_ORDER_IN_BYTE_MSBFIRST)
- infoRec->FillColorExpandSpans =
- XAAFillScanlineColorExpandSpans3MSBFirst;
- else
- infoRec->FillColorExpandSpans =
- XAAFillScanlineColorExpandSpans3LSBFirst;
- } else {
- if(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
- BIT_ORDER_IN_BYTE_MSBFIRST)
- infoRec->FillColorExpandSpans =
- XAAFillScanlineColorExpandSpansMSBFirst;
- else
- infoRec->FillColorExpandSpans =
- XAAFillScanlineColorExpandSpansLSBFirst;
- }
- infoRec->FillColorExpandSpansFlags =
- infoRec->ScanlineCPUToScreenColorExpandFillFlags;
- }
-
- /**** FillImageWriteRects ****/
-
- if(infoRec->FillImageWriteRects) {
- XAAMSG("\tDriver provided FillImageWriteRects replacement\n");
- } else if(HaveImageWriteRect &&
- (infoRec->ImageWriteFlags & LEFT_EDGE_CLIPPING_NEGATIVE_X) &&
- (infoRec->ImageWriteFlags & LEFT_EDGE_CLIPPING)) {
- infoRec->FillImageWriteRects = XAAFillImageWriteRects;
- infoRec->FillImageWriteRectsFlags = infoRec->ImageWriteFlags;
- }
-
- /**** WriteBitmap ****/
-
- if(infoRec->WriteBitmap &&
- !xf86ReturnOptValBool(options, XAAOPT_WRITE_BITMAP, FALSE)) {
- XAAMSG("\tDriver provided WriteBitmap replacement\n");
- } else if(HaveColorExpansion) {
- if (infoRec->CPUToScreenColorExpandFillFlags & TRIPLE_BITS_24BPP) {
- if(infoRec->CPUToScreenColorExpandFillFlags &
- BIT_ORDER_IN_BYTE_MSBFIRST) {
- if(infoRec->CPUToScreenColorExpandFillFlags &
- CPU_TRANSFER_BASE_FIXED)
- infoRec->WriteBitmap =
- XAAWriteBitmapColorExpand3MSBFirstFixedBase;
- else
- infoRec->WriteBitmap = XAAWriteBitmapColorExpand3MSBFirst;
- } else {
- if(infoRec->CPUToScreenColorExpandFillFlags &
- CPU_TRANSFER_BASE_FIXED)
- infoRec->WriteBitmap =
- XAAWriteBitmapColorExpand3LSBFirstFixedBase;
- else
- infoRec->WriteBitmap = XAAWriteBitmapColorExpand3LSBFirst;
- }
- } else {
- if(infoRec->CPUToScreenColorExpandFillFlags &
- BIT_ORDER_IN_BYTE_MSBFIRST) {
- if(infoRec->CPUToScreenColorExpandFillFlags &
- CPU_TRANSFER_BASE_FIXED)
- infoRec->WriteBitmap =
- XAAWriteBitmapColorExpandMSBFirstFixedBase;
- else
- infoRec->WriteBitmap = XAAWriteBitmapColorExpandMSBFirst;
- } else {
- if(infoRec->CPUToScreenColorExpandFillFlags &
- CPU_TRANSFER_BASE_FIXED)
- infoRec->WriteBitmap =
- XAAWriteBitmapColorExpandLSBFirstFixedBase;
- else
- infoRec->WriteBitmap = XAAWriteBitmapColorExpandLSBFirst;
- }
- }
- infoRec->WriteBitmapFlags = infoRec->CPUToScreenColorExpandFillFlags;
- } else if(HaveScanlineColorExpansion) {
- if (infoRec->ScanlineCPUToScreenColorExpandFillFlags &
- TRIPLE_BITS_24BPP) {
- if(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
- BIT_ORDER_IN_BYTE_MSBFIRST)
- infoRec->WriteBitmap =
- XAAWriteBitmapScanlineColorExpand3MSBFirst;
- else
- infoRec->WriteBitmap =
- XAAWriteBitmapScanlineColorExpand3LSBFirst;
- } else {
- if(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
- BIT_ORDER_IN_BYTE_MSBFIRST)
- infoRec->WriteBitmap =
- XAAWriteBitmapScanlineColorExpandMSBFirst;
- else
- infoRec->WriteBitmap =
- XAAWriteBitmapScanlineColorExpandLSBFirst;
- }
- infoRec->WriteBitmapFlags =
- infoRec->ScanlineCPUToScreenColorExpandFillFlags;
- } else
- infoRec->WriteBitmap = NULL;
-
- /**** TE Glyphs ****/
-
- if (infoRec->TEGlyphRenderer) {
- XAAMSG("\tDriver provided TEGlyphRenderer replacement\n");
- } else if (HaveColorExpansion) {
- infoRec->TEGlyphRendererFlags =
- infoRec->CPUToScreenColorExpandFillFlags;
-
- if (infoRec->TEGlyphRendererFlags & TRIPLE_BITS_24BPP) {
- if (infoRec->TEGlyphRendererFlags & BIT_ORDER_IN_BYTE_MSBFIRST) {
- if (infoRec->TEGlyphRendererFlags & CPU_TRANSFER_BASE_FIXED)
- infoRec->TEGlyphRenderer =
- XAATEGlyphRenderer3MSBFirstFixedBase;
- else
- infoRec->TEGlyphRenderer = XAATEGlyphRenderer3MSBFirst;
- } else {
- if (infoRec->TEGlyphRendererFlags & CPU_TRANSFER_BASE_FIXED)
- infoRec->TEGlyphRenderer =
- XAATEGlyphRenderer3LSBFirstFixedBase;
- else
- infoRec->TEGlyphRenderer = XAATEGlyphRenderer3LSBFirst;
- }
-
- if (!HaveSolidFillRect &&
- (infoRec->TEGlyphRendererFlags & RGB_EQUAL)) {
- infoRec->TEGlyphRendererFlags &= ~RGB_EQUAL;
- XAAMSG("WARNING: TEGlyphRenderer cannot support RGB_EQUAL"
- " without solid fills\n");
- }
- } else {
- if (infoRec->TEGlyphRendererFlags & BIT_ORDER_IN_BYTE_MSBFIRST) {
- if (infoRec->TEGlyphRendererFlags & CPU_TRANSFER_BASE_FIXED)
- infoRec->TEGlyphRenderer =
- XAATEGlyphRendererMSBFirstFixedBase;
- else
- infoRec->TEGlyphRenderer = XAATEGlyphRendererMSBFirst;
- } else {
- if (infoRec->TEGlyphRendererFlags & CPU_TRANSFER_BASE_FIXED)
- infoRec->TEGlyphRenderer =
- XAATEGlyphRendererLSBFirstFixedBase;
- else
- infoRec->TEGlyphRenderer = XAATEGlyphRendererLSBFirst;
- }
- }
-
- if (!HaveSolidFillRect &&
- (infoRec->TEGlyphRendererFlags & TRANSPARENCY_ONLY)) {
- infoRec->TEGlyphRendererFlags &= ~TRANSPARENCY_ONLY;
- XAAMSG("WARNING: TEGlyphRenderer cannot support TRANPARENCY_ONLY"
- " without solid fills\n");
- }
-
- } else if (HaveScanlineColorExpansion) {
- infoRec->TEGlyphRendererFlags =
- infoRec->ScanlineCPUToScreenColorExpandFillFlags;
-
- if (infoRec->TEGlyphRendererFlags & TRIPLE_BITS_24BPP) {
- if (infoRec->TEGlyphRendererFlags & BIT_ORDER_IN_BYTE_MSBFIRST)
- infoRec->TEGlyphRenderer = XAATEGlyphRendererScanline3MSBFirst;
- else
- infoRec->TEGlyphRenderer = XAATEGlyphRendererScanline3LSBFirst;
-
- if (!HaveSolidFillRect &&
- (infoRec->TEGlyphRendererFlags & RGB_EQUAL)) {
- infoRec->TEGlyphRendererFlags &= ~RGB_EQUAL;
- XAAMSG("WARNING: TEGlyphRenderer cannot support RGB_EQUAL"
- " without solid fills\n");
- }
- } else {
- if (infoRec->TEGlyphRendererFlags & BIT_ORDER_IN_BYTE_MSBFIRST)
- infoRec->TEGlyphRenderer = XAATEGlyphRendererScanlineMSBFirst;
- else
- infoRec->TEGlyphRenderer = XAATEGlyphRendererScanlineLSBFirst;
- }
-
- if (!HaveSolidFillRect &&
- (infoRec->TEGlyphRendererFlags & TRANSPARENCY_ONLY)) {
- infoRec->TEGlyphRendererFlags &= ~TRANSPARENCY_ONLY;
- XAAMSG("WARNING: TEGlyphRenderer cannot support TRANPARENCY_ONLY"
- " without solid fills\n");
- }
- }
-
- /**** NonTE Glyphs ****/
-
- if(infoRec->NonTEGlyphRenderer) {
- XAAMSG("\tDriver provided NonTEGlyphRenderer replacement\n");
- } else if(infoRec->WriteBitmap &&
- !(infoRec->WriteBitmapFlags & NO_TRANSPARENCY)) {
- infoRec->NonTEGlyphRenderer = XAANonTEGlyphRenderer;
- infoRec->NonTEGlyphRendererFlags = infoRec->WriteBitmapFlags;
- }
-
- /**** WritePixmap ****/
-
- if(infoRec->WritePixmap &&
- !xf86ReturnOptValBool(options, XAAOPT_WRITE_PIXMAP, FALSE)) {
- XAAMSG("\tDriver provided WritePixmap replacement\n");
- } else if(HaveImageWriteRect) {
- infoRec->WritePixmap = XAAWritePixmap;
- infoRec->WritePixmapFlags =
- infoRec->ImageWriteFlags | CONVERT_32BPP_TO_24BPP;
- } else if(HaveScanlineImageWriteRect) {
- infoRec->WritePixmap = XAAWritePixmapScanline;
- infoRec->WritePixmapFlags = infoRec->ScanlineImageWriteFlags;
- } else
- infoRec->WritePixmap = NULL;
-
- /**** ReadPixmap ****/
-
- if(infoRec->ReadPixmap) {
- XAAMSG("\tDriver provided ReadPixmap replacement\n");
- }
-
-
- /************** GC Level *************/
-
- /**** CopyArea ****/
-
- if(infoRec->CopyArea) {
- XAAMSG("\tDriver provided GC level CopyArea replacement\n");
- } else if(infoRec->ScreenToScreenBitBlt) {
- infoRec->CopyArea = XAACopyArea;
- infoRec->CopyAreaFlags = infoRec->ScreenToScreenBitBltFlags;
-
- /* most GC level primitives use one mid-level primitive so
- the GC level primitive gets the mid-level primitive flag
- and we use that at GC validation time. But CopyArea uses
- more than one mid-level primitive so we have to essentially
- do a GC validation every time that primitive is used.
- The CopyAreaFlags would only be used for filtering out the
- common denominators. Here we assume that if you don't do
- ScreenToScreenBitBlt you aren't going to do the others.
- We also assume that ScreenToScreenBitBlt has the least
- restrictions. */
- }
-
- if(infoRec->CopyPlane) {
- XAAMSG("\tDriver provided GC level CopyPlane replacement\n");
- } else if(infoRec->WriteBitmap &&
- !(infoRec->WriteBitmapFlags & TRANSPARENCY_ONLY)) {
- infoRec->CopyPlane = XAACopyPlaneColorExpansion;
- infoRec->CopyPlaneFlags = infoRec->WriteBitmapFlags;
- }
-
- if(infoRec->PushPixelsSolid) {
- XAAMSG("\tDriver provided GC level PushPixelsSolid replacement\n");
- } else if(infoRec->WriteBitmap &&
- !(infoRec->WriteBitmapFlags & NO_TRANSPARENCY)) {
- infoRec->PushPixelsSolid = XAAPushPixelsSolidColorExpansion;
- infoRec->PushPixelsFlags = infoRec->WriteBitmapFlags;
- }
-
- if(infoRec->FillSolidRects) {
- if(!infoRec->PolyFillRectSolid) {
- infoRec->PolyFillRectSolid = XAAPolyFillRect;
- infoRec->PolyFillRectSolidFlags = infoRec->FillSolidRectsFlags;
- }
- }
- if(infoRec->FillSolidSpans) {
- if(!infoRec->FillSpansSolid) {
- infoRec->FillSpansSolid = XAAFillSpans;
- infoRec->FillSpansSolidFlags = infoRec->FillSolidSpansFlags;
- }
- }
-
- if(infoRec->FillMono8x8PatternRects || infoRec->FillColor8x8PatternRects ||
- infoRec->FillCacheBltRects || infoRec->FillColorExpandRects ||
- infoRec->FillCacheExpandRects) {
- if(!infoRec->PolyFillRectStippled) {
-
- infoRec->PolyFillRectStippled = XAAPolyFillRect;
- infoRec->PolyFillRectStippledFlags = 0;
- }
- }
-
- if(infoRec->FillMono8x8PatternSpans || infoRec->FillColor8x8PatternSpans ||
- infoRec->FillCacheBltSpans || infoRec->FillColorExpandSpans ||
- infoRec->FillCacheExpandSpans) {
- if(!infoRec->FillSpansStippled) {
-
- infoRec->FillSpansStippled = XAAFillSpans;
- infoRec->FillSpansStippledFlags = 0;
- }
- }
-
- if(infoRec->FillMono8x8PatternRects || infoRec->FillColor8x8PatternRects ||
- infoRec->FillCacheBltRects || infoRec->FillColorExpandRects ||
- infoRec->FillCacheExpandRects) {
- if(!infoRec->PolyFillRectOpaqueStippled) {
-
- infoRec->PolyFillRectOpaqueStippled = XAAPolyFillRect;
- infoRec->PolyFillRectOpaqueStippledFlags = 0;
- }
- }
-
- if(infoRec->FillMono8x8PatternSpans || infoRec->FillColor8x8PatternSpans ||
- infoRec->FillCacheBltSpans || infoRec->FillColorExpandSpans ||
- infoRec->FillCacheExpandSpans) {
- if(!infoRec->FillSpansOpaqueStippled) {
-
- infoRec->FillSpansOpaqueStippled = XAAFillSpans;
- infoRec->FillSpansOpaqueStippledFlags = 0;
- }
- }
-
- if(infoRec->FillMono8x8PatternRects || infoRec->FillColor8x8PatternRects ||
- infoRec->FillCacheBltRects || infoRec->FillImageWriteRects) {
- if(!infoRec->PolyFillRectTiled) {
-
- infoRec->PolyFillRectTiled = XAAPolyFillRect;
- infoRec->PolyFillRectTiledFlags = 0;
- }
- }
-
- if(infoRec->FillMono8x8PatternSpans || infoRec->FillColor8x8PatternSpans ||
- infoRec->FillCacheBltSpans) {
- if(!infoRec->FillSpansTiled) {
-
- infoRec->FillSpansTiled = XAAFillSpans;
- infoRec->FillSpansTiledFlags = 0;
- }
- }
-
- if(infoRec->TEGlyphRenderer &&
- !(infoRec->TEGlyphRendererFlags & NO_TRANSPARENCY)) {
-
- if(!infoRec->PolyText8TE) {
- infoRec->PolyText8TE = XAAPolyText8TEColorExpansion;
- infoRec->PolyText8TEFlags = infoRec->TEGlyphRendererFlags;
- }
-
- if(!infoRec->PolyText16TE) {
- infoRec->PolyText16TE = XAAPolyText16TEColorExpansion;
- infoRec->PolyText16TEFlags = infoRec->TEGlyphRendererFlags;
- }
-
- if(!infoRec->PolyGlyphBltTE) {
- infoRec->PolyGlyphBltTE = XAAPolyGlyphBltTEColorExpansion;
- infoRec->PolyGlyphBltTEFlags = infoRec->TEGlyphRendererFlags;
- }
- }
-
- if(infoRec->TEGlyphRenderer &&
- !(infoRec->TEGlyphRendererFlags & TRANSPARENCY_ONLY)) {
-
- if(!infoRec->ImageText8TE) {
- infoRec->ImageText8TE = XAAImageText8TEColorExpansion;
- infoRec->ImageText8TEFlags = infoRec->TEGlyphRendererFlags;
- }
-
- if(!infoRec->ImageText16TE) {
- infoRec->ImageText16TE = XAAImageText16TEColorExpansion;
- infoRec->ImageText16TEFlags = infoRec->TEGlyphRendererFlags;
- }
-
- if(!infoRec->ImageGlyphBltTE) {
- infoRec->ImageGlyphBltTE = XAAImageGlyphBltTEColorExpansion;
- infoRec->ImageGlyphBltTEFlags = infoRec->TEGlyphRendererFlags;
- }
- }
-
- if(infoRec->NonTEGlyphRenderer) {
- if(!infoRec->PolyText8NonTE) {
- infoRec->PolyText8NonTE = XAAPolyText8NonTEColorExpansion;
- infoRec->PolyText8NonTEFlags = infoRec->NonTEGlyphRendererFlags;
- }
-
- if(!infoRec->PolyText16NonTE) {
- infoRec->PolyText16NonTE = XAAPolyText16NonTEColorExpansion;
- infoRec->PolyText16NonTEFlags = infoRec->NonTEGlyphRendererFlags;
- }
- if(!infoRec->PolyGlyphBltNonTE) {
- infoRec->PolyGlyphBltNonTE = XAAPolyGlyphBltNonTEColorExpansion;
- infoRec->PolyGlyphBltNonTEFlags = infoRec->NonTEGlyphRendererFlags;
- }
- }
-
- if(infoRec->NonTEGlyphRenderer && HaveSolidFillRect) {
- if(!infoRec->ImageText8NonTE) {
- infoRec->ImageText8NonTE = XAAImageText8NonTEColorExpansion;
- infoRec->ImageText8NonTEFlags = infoRec->NonTEGlyphRendererFlags;
- }
-
- if(!infoRec->ImageText16NonTE) {
- infoRec->ImageText16NonTE = XAAImageText16NonTEColorExpansion;
- infoRec->ImageText16NonTEFlags = infoRec->NonTEGlyphRendererFlags;
- }
-
- if(!infoRec->ImageGlyphBltNonTE) {
- infoRec->ImageGlyphBltNonTE = XAAImageGlyphBltNonTEColorExpansion;
- infoRec->ImageGlyphBltNonTEFlags = infoRec->NonTEGlyphRendererFlags;
- }
- }
-
- if(!infoRec->PolyRectangleThinSolid && HaveSolidHorVertLine) {
- infoRec->PolyRectangleThinSolid = XAAPolyRectangleThinSolid;
- infoRec->PolyRectangleThinSolidFlags = infoRec->SolidLineFlags;
- }
-
- if(!infoRec->FillPolygonSolid && HaveSolidFillRect) {
- infoRec->FillPolygonSolid = XAAFillPolygonSolid;
- infoRec->FillPolygonSolidFlags = infoRec->SolidFillFlags;
- }
-
- if(!infoRec->FillPolygonStippled && (HaveMono8x8PatternFillRect ||
- HaveScreenToScreenColorExpandFill || HaveScreenToScreenCopy)) {
- infoRec->FillPolygonStippled = XAAFillPolygonStippled;
- infoRec->FillPolygonStippledFlags = infoRec->SolidFillFlags;
- }
-
- if(!infoRec->FillPolygonOpaqueStippled && (HaveMono8x8PatternFillRect ||
- HaveScreenToScreenColorExpandFill || HaveScreenToScreenCopy)) {
- infoRec->FillPolygonOpaqueStippled = XAAFillPolygonStippled;
- infoRec->FillPolygonOpaqueStippledFlags = infoRec->SolidFillFlags;
- }
-
- if(!infoRec->FillPolygonTiled && (HaveMono8x8PatternFillRect ||
- HaveScreenToScreenColorExpandFill || HaveScreenToScreenCopy)) {
- infoRec->FillPolygonTiled = XAAFillPolygonTiled;
- infoRec->FillPolygonTiledFlags = infoRec->SolidFillFlags;
- }
-
-
- if(!infoRec->PolyFillArcSolid && HaveSolidFillRect) {
- infoRec->PolyFillArcSolid = XAAPolyFillArcSolid;
- infoRec->PolyFillArcSolidFlags = infoRec->SolidFillFlags;
- }
-
- if(!infoRec->PolylinesWideSolid && HaveSolidFillRect) {
- infoRec->PolylinesWideSolid = XAAPolylinesWideSolid;
- infoRec->PolylinesWideSolidFlags =
- infoRec->SolidFillFlags | GXCOPY_ONLY;
- }
-
- if(!infoRec->PutImage && (infoRec->WritePixmap ||
- (infoRec->WriteBitmap &&
- !(infoRec->WriteBitmapFlags & TRANSPARENCY_ONLY)))) {
- infoRec->PutImage = XAAPutImage;
-
- /* See comment for CopyArea above. But here we make fewer
- assumptions. The driver can provide the PutImageFlags if
- it wants too */
- }
-
- if(HaveSolidHorVertLine &&
- (HaveSolidBresenhamLine || (HaveSolidTwoPointLine &&
- (infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_LINE)))){
- if(!infoRec->PolylinesThinSolid) {
- infoRec->PolylinesThinSolid = XAAPolyLines;
- infoRec->PolylinesThinSolidFlags = infoRec->SolidLineFlags;
- }
- if(!infoRec->PolySegmentThinSolid) {
- infoRec->PolySegmentThinSolid = XAAPolySegment;
- infoRec->PolySegmentThinSolidFlags = infoRec->SolidLineFlags;
- }
- }
-
- if(HaveDashedBresenhamLine || (HaveDashedTwoPointLine &&
- (infoRec->ClippingFlags & HARDWARE_CLIP_DASHED_LINE))){
- if(!infoRec->PolylinesThinDashed) {
- infoRec->PolylinesThinDashed = XAAPolyLinesDashed;
- infoRec->PolylinesThinDashedFlags = infoRec->DashedLineFlags;
- }
- if(!infoRec->PolySegmentThinDashed) {
- infoRec->PolySegmentThinDashed = XAAPolySegmentDashed;
- infoRec->PolySegmentThinDashedFlags = infoRec->DashedLineFlags;
- }
- }
-
- if(infoRec->PolylinesThinDashed || infoRec->PolySegmentThinDashed) {
- if(!infoRec->ComputeDash)
- infoRec->ComputeDash = XAAComputeDash;
- }
-
- {
- Bool haveTexture = infoRec->CPUToScreenTextureFormats &&
- infoRec->CPUToScreenTextureDstFormats &&
- infoRec->SetupForCPUToScreenTexture2 &&
- infoRec->SubsequentCPUToScreenTexture;
- Bool haveAlphaTexture = infoRec->CPUToScreenAlphaTextureFormats &&
- infoRec->CPUToScreenAlphaTextureDstFormats &&
- infoRec->SetupForCPUToScreenAlphaTexture2 &&
- infoRec->SubsequentCPUToScreenAlphaTexture;
-
- if(!infoRec->Composite && (haveTexture || haveAlphaTexture))
- infoRec->Composite = XAADoComposite;
-
- if(!infoRec->Glyphs && infoRec->WriteBitmap &&
- !(infoRec->WriteBitmapFlags & NO_TRANSPARENCY))
- {
- infoRec->Glyphs = XAADoGlyphs;
- }
- }
-
- /************ Validation Functions **************/
-
- if(!infoRec->ValidateCopyArea && infoRec->CopyArea) {
- infoRec->CopyAreaMask = GCWhenForced;
- if((infoRec->CopyAreaFlags & GXCOPY_ONLY) ||
- (infoRec->CopyAreaFlags & ROP_NEEDS_SOURCE))
- infoRec->CopyAreaMask |= GCFunction;
- if(infoRec->CopyAreaFlags & NO_PLANEMASK)
- infoRec->CopyAreaMask |= GCPlaneMask;
- infoRec->ValidateCopyArea = XAAValidateCopyArea;
- }
-
- if(!infoRec->ValidateCopyPlane && infoRec->CopyPlane) {
- infoRec->CopyPlaneMask = GCWhenForced;
- if((infoRec->CopyPlaneFlags & GXCOPY_ONLY) ||
- (infoRec->CopyPlaneFlags & ROP_NEEDS_SOURCE))
- infoRec->CopyPlaneMask |= GCFunction;
- if(infoRec->CopyPlaneFlags & NO_PLANEMASK)
- infoRec->CopyPlaneMask |= GCPlaneMask;
- if(infoRec->CopyPlaneFlags & RGB_EQUAL)
- infoRec->CopyPlaneMask |= GCForeground | GCBackground;
- infoRec->ValidateCopyPlane = XAAValidateCopyPlane;
- }
-
- if(!infoRec->ValidatePutImage && infoRec->PutImage) {
- infoRec->PutImageMask = GCWhenForced;
- if((infoRec->PutImageFlags & GXCOPY_ONLY) ||
- (infoRec->PutImageFlags & ROP_NEEDS_SOURCE))
- infoRec->PutImageMask |= GCFunction;
- if(infoRec->PutImageFlags & NO_PLANEMASK)
- infoRec->PutImageMask |= GCPlaneMask;
- if(infoRec->PutImageFlags & RGB_EQUAL)
- infoRec->PutImageMask |= GCForeground | GCBackground;
- infoRec->ValidatePutImage = XAAValidatePutImage;
- }
-
-
- if(!infoRec->ValidatePushPixels && infoRec->PushPixelsSolid) {
- infoRec->PushPixelsMask = GCFillStyle;
- if((infoRec->PushPixelsFlags & GXCOPY_ONLY) ||
- (infoRec->PushPixelsFlags & ROP_NEEDS_SOURCE) ||
- (infoRec->PushPixelsFlags & TRANSPARENCY_GXCOPY_ONLY))
- infoRec->PushPixelsMask |= GCFunction;
- if(infoRec->PushPixelsFlags & NO_PLANEMASK)
- infoRec->PushPixelsMask |= GCPlaneMask;
- if(infoRec->PushPixelsFlags & RGB_EQUAL)
- infoRec->PushPixelsMask |= GCForeground;
- infoRec->ValidatePushPixels = XAAValidatePushPixels;
- }
-
- /* By default XAA assumes the FillSpans, PolyFillRects, FillPolygon
- and PolyFillArcs have the same restrictions. If you supply GC
- level replacements for any of these and alter this relationship
- you may need to supply replacement validation routines */
-
- if(!infoRec->ValidateFillSpans &&
- (infoRec->FillSpansSolid || infoRec->FillSpansStippled ||
- infoRec->FillSpansOpaqueStippled || infoRec->FillSpansTiled)) {
-
- int compositeFlags = infoRec->FillSpansSolidFlags |
- infoRec->FillSpansStippledFlags |
- infoRec->FillSpansOpaqueStippledFlags |
- infoRec->FillSpansTiledFlags;
-
- infoRec->FillSpansMask = GCFillStyle | GCTile | GCStipple;
-
- if((compositeFlags & GXCOPY_ONLY) ||
- (compositeFlags & ROP_NEEDS_SOURCE))
- infoRec->FillSpansMask |= GCFunction;
- if(compositeFlags & NO_PLANEMASK)
- infoRec->FillSpansMask |= GCPlaneMask;
- if(compositeFlags & RGB_EQUAL)
- infoRec->FillSpansMask |= GCForeground;
- infoRec->ValidateFillSpans = XAAValidateFillSpans;
- }
-
- /* By default XAA only provides Validations for the GlyphBlt
- functions and not the text higher up. This is because the
- Text8/16 and GlyphBlt are linked. If you break this linkage,
- you may need to have the driver supply its own Validation
- routines */
-
- if(!infoRec->ValidatePolyGlyphBlt &&
- (infoRec->PolyGlyphBltTE || infoRec->PolyGlyphBltNonTE)) {
- int compositeFlags = infoRec->PolyGlyphBltTEFlags |
- infoRec->PolyGlyphBltNonTEFlags;
-
- infoRec->PolyGlyphBltMask = GCFillStyle | GCFont;
- if((compositeFlags & GXCOPY_ONLY) ||
- (compositeFlags & ROP_NEEDS_SOURCE) ||
- (infoRec->PolyGlyphBltNonTEFlags & TRANSPARENCY_GXCOPY_ONLY))
- infoRec->PolyGlyphBltMask |= GCFunction;
- if(compositeFlags & NO_PLANEMASK)
- infoRec->PolyGlyphBltMask |= GCPlaneMask;
- if(compositeFlags & RGB_EQUAL)
- infoRec->PolyGlyphBltMask |= GCForeground;
- infoRec->ValidatePolyGlyphBlt = XAAValidatePolyGlyphBlt;
- }
-
- if(!infoRec->ValidateImageGlyphBlt &&
- (infoRec->ImageGlyphBltTE || infoRec->ImageGlyphBltNonTE)) {
- int compositeFlags = infoRec->ImageGlyphBltTEFlags |
- infoRec->ImageGlyphBltNonTEFlags;
-
- if(infoRec->ImageGlyphBltNonTE)
- compositeFlags |= infoRec->SolidFillFlags;
-
- infoRec->ImageGlyphBltMask = GCFont;
- if(compositeFlags & NO_PLANEMASK)
- infoRec->ImageGlyphBltMask |= GCPlaneMask;
- if(compositeFlags & RGB_EQUAL)
- infoRec->ImageGlyphBltMask |= GCForeground | GCBackground;
- infoRec->ValidateImageGlyphBlt = XAAValidateImageGlyphBlt;
- }
-
- /* By default XAA only provides a Validation function for the
- Polylines and does segments and polylines at the same time */
-
- if(!infoRec->ValidatePolylines && infoRec->ValidateFillSpans) {
- int compositeFlags = infoRec->PolyRectangleThinSolidFlags |
- infoRec->PolylinesWideSolidFlags |
- infoRec->PolylinesThinSolidFlags |
- infoRec->PolySegmentThinSolidFlags |
- infoRec->PolySegmentThinDashedFlags |
- infoRec->PolylinesThinDashedFlags;
-
- infoRec->ValidatePolylines = XAAValidatePolylines;
- infoRec->PolylinesMask =
- infoRec->FillSpansMask | GCLineStyle | GCLineWidth;
-
- if(infoRec->PolySegmentThinDashed || infoRec->PolylinesThinDashed)
- infoRec->PolylinesMask |= GCDashList;
- if(compositeFlags & NO_PLANEMASK)
- infoRec->PolylinesMask |= GCPlaneMask;
- if((compositeFlags & GXCOPY_ONLY) ||
- (compositeFlags & ROP_NEEDS_SOURCE))
- infoRec->PolylinesMask |= GCFunction;
- if(compositeFlags & RGB_EQUAL)
- infoRec->PolylinesMask |= GCForeground;
- }
-
-
- /**** Fill choosers ****/
-
- if(!infoRec->StippledFillChooser)
- infoRec->StippledFillChooser = XAAStippledFillChooser;
-
- if(!infoRec->OpaqueStippledFillChooser)
- infoRec->OpaqueStippledFillChooser = XAAOpaqueStippledFillChooser;
-
- if(!infoRec->TiledFillChooser)
- infoRec->TiledFillChooser = XAATiledFillChooser;
-
-
- /**** Setup the pixmap cache ****/
-
- if(infoRec->WriteBitmapToCache) {}
- else if(infoRec->WriteBitmap &&
- !(infoRec->WriteBitmapFlags & TRANSPARENCY_ONLY))
- infoRec->WriteBitmapToCache = XAAWriteBitmapToCache;
- else if(infoRec->Flags & LINEAR_FRAMEBUFFER)
- infoRec->WriteBitmapToCache = XAAWriteBitmapToCacheLinear;
- else
- infoRec->PixmapCacheFlags |= DO_NOT_BLIT_STIPPLES;
-
- if(infoRec->WritePixmapToCache) {}
- else if(infoRec->WritePixmap && !(infoRec->WritePixmapFlags & NO_GXCOPY))
- infoRec->WritePixmapToCache = XAAWritePixmapToCache;
- else if(infoRec->Flags & LINEAR_FRAMEBUFFER)
- infoRec->WritePixmapToCache = XAAWritePixmapToCacheLinear;
- else
- infoRec->Flags &= ~PIXMAP_CACHE;
-
- if (xf86ReturnOptValBool(options, XAAOPT_PIXMAP_CACHE, FALSE))
- infoRec->Flags &= ~PIXMAP_CACHE;
-
- if(infoRec->WriteMono8x8PatternToCache) {}
- else if(infoRec->PixmapCacheFlags & CACHE_MONO_8x8) {
- if(infoRec->WritePixmapToCache)
- infoRec->WriteMono8x8PatternToCache = XAAWriteMono8x8PatternToCache;
- else
- infoRec->PixmapCacheFlags &= ~CACHE_MONO_8x8;
- }
-
- if(infoRec->WriteColor8x8PatternToCache) {}
- else if(infoRec->PixmapCacheFlags & CACHE_COLOR_8x8) {
- if(infoRec->WritePixmapToCache && infoRec->WriteBitmapToCache)
- infoRec->WriteColor8x8PatternToCache = XAAWriteColor8x8PatternToCache;
- else
- infoRec->PixmapCacheFlags &= ~CACHE_COLOR_8x8;
- }
-
- if(infoRec->CachePixelGranularity < 0) {
- switch(pScrn->bitsPerPixel) {
- case 24:
- case 8: infoRec->CachePixelGranularity = 4; break;
- case 16: infoRec->CachePixelGranularity = 2; break;
- case 32: infoRec->CachePixelGranularity = 1; break;
- default: break;
- }
-
- if(BITMAP_SCANLINE_PAD == 64)
- infoRec->CachePixelGranularity *= 2;
- }
-
- xfree(options);
-
- if(!infoRec->CacheTile && infoRec->WritePixmapToCache)
- infoRec->CacheTile = XAACacheTile;
- if(!infoRec->CacheMonoStipple && infoRec->WritePixmapToCache)
- infoRec->CacheMonoStipple = XAACacheMonoStipple;
- if(!infoRec->CacheStipple && infoRec->WriteBitmapToCache)
- infoRec->CacheStipple = XAACacheStipple;
- if(!infoRec->CacheMono8x8Pattern && infoRec->WriteMono8x8PatternToCache)
- infoRec->CacheMono8x8Pattern = XAACacheMono8x8Pattern;
- if(!infoRec->CacheColor8x8Pattern && infoRec->WriteColor8x8PatternToCache)
- infoRec->CacheColor8x8Pattern = XAACacheColor8x8Pattern;
-
- if((infoRec->Flags & PIXMAP_CACHE) && !infoRec->InitPixmapCache) {
- infoRec->InitPixmapCache = XAAInitPixmapCache;
- infoRec->ClosePixmapCache = XAAClosePixmapCache;
- }
-
- return TRUE;
-}
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <string.h>
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include <X11/X.h>
+#include "scrnintstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xf86fbman.h"
+#include "servermd.h"
+
+/*
+ * XAA Config options
+ */
+
+typedef enum {
+ XAAOPT_SCREEN_TO_SCREEN_COPY,
+ XAAOPT_SOLID_FILL_RECT,
+ XAAOPT_SOLID_FILL_TRAP,
+ XAAOPT_SOLID_TWO_POINT_LINE,
+ XAAOPT_SOLID_BRESENHAM_LINE,
+ XAAOPT_SOLID_HORVERT_LINE,
+ XAAOPT_DASHED_TWO_POINT_LINE,
+ XAAOPT_DASHED_BRESENHAM_LINE,
+ XAAOPT_MONO_8x8_PATTERN_FILL_RECT,
+ XAAOPT_MONO_8x8_PATTERN_FILL_TRAP,
+ XAAOPT_COL_8x8_PATTERN_FILL_RECT,
+ XAAOPT_COL_8x8_PATTERN_FILL_TRAP,
+ XAAOPT_CPU_TO_SCREEN_COL_EXP_FILL,
+ XAAOPT_SCANLINE_CPU_TO_SCREEN_COL_EXP_FILL,
+ XAAOPT_SCREEN_TO_SCREEN_COL_EXP_FILL,
+ XAAOPT_IMAGE_WRITE_RECT,
+ XAAOPT_SCANLINE_IMAGE_WRITE_RECT,
+ XAAOPT_WRITE_BITMAP,
+ XAAOPT_WRITE_PIXMAP,
+ XAAOPT_PIXMAP_CACHE,
+ XAAOPT_OFFSCREEN_PIXMAPS,
+ XAAOPT_HAS_DUMB_INVERTED_OPTION_SENSE
+} XAAOpts;
+
+static const OptionInfoRec XAAOptions[] = {
+ {XAAOPT_SCREEN_TO_SCREEN_COPY, "XaaNoScreenToScreenCopy",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_SOLID_FILL_RECT, "XaaNoSolidFillRect",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_SOLID_FILL_TRAP, "XaaNoSolidFillTrap",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_SOLID_TWO_POINT_LINE, "XaaNoSolidTwoPointLine",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_SOLID_BRESENHAM_LINE, "XaaNoSolidBresenhamLine",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_SOLID_HORVERT_LINE, "XaaNoSolidHorVertLine",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_DASHED_TWO_POINT_LINE, "XaaNoDashedTwoPointLine",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_DASHED_BRESENHAM_LINE, "XaaNoDashedBresenhamLine",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_MONO_8x8_PATTERN_FILL_RECT, "XaaNoMono8x8PatternFillRect",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_MONO_8x8_PATTERN_FILL_TRAP, "XaaNoMono8x8PatternFillTrap",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_COL_8x8_PATTERN_FILL_RECT, "XaaNoColor8x8PatternFillRect",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_COL_8x8_PATTERN_FILL_TRAP, "XaaNoColor8x8PatternFillTrap",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_CPU_TO_SCREEN_COL_EXP_FILL, "XaaNoCPUToScreenColorExpandFill",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_SCANLINE_CPU_TO_SCREEN_COL_EXP_FILL,"XaaNoScanlineCPUToScreenColorExpandFill",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_SCREEN_TO_SCREEN_COL_EXP_FILL, "XaaNoScreenToScreenColorExpandFill",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_IMAGE_WRITE_RECT, "XaaNoImageWriteRect",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_SCANLINE_IMAGE_WRITE_RECT, "XaaNoScanlineImageWriteRect",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_WRITE_BITMAP, "XaaNoWriteBitmap",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_WRITE_PIXMAP, "XaaNoWritePixmap",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_PIXMAP_CACHE, "XaaNoPixmapCache",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_OFFSCREEN_PIXMAPS, "XaaNoOffscreenPixmaps",
+ OPTV_BOOLEAN, {0}, FALSE },
+ {XAAOPT_HAS_DUMB_INVERTED_OPTION_SENSE, "XaaOffscreenPixmaps",
+ OPTV_BOOLEAN, {0}, FALSE },
+ { -1, NULL,
+ OPTV_NONE, {0}, FALSE }
+};
+
+static XF86ModuleVersionInfo xaaVersRec =
+{
+ "xaa",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XORG_VERSION_CURRENT,
+ XAA_VERSION_MAJOR,
+ XAA_VERSION_MINOR,
+ XAA_VERSION_RELEASE,
+ ABI_CLASS_VIDEODRV, /* requires the video driver ABI */
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_NONE,
+ {0,0,0,0}
+};
+
+_X_EXPORT XF86ModuleData xaaModuleData = { &xaaVersRec, NULL, NULL };
+
+Bool
+XAAInitAccel(ScreenPtr pScreen, XAAInfoRecPtr infoRec)
+{
+ int index = pScreen->myNum;
+ ScrnInfoPtr pScrn = xf86Screens[index];
+ Bool HaveScreenToScreenCopy = FALSE;
+ Bool HaveColorExpansion = FALSE;
+ Bool HaveScanlineColorExpansion = FALSE;
+ Bool HaveSolidFillRect = FALSE;
+ Bool HaveMono8x8PatternFillRect = FALSE;
+ Bool HaveColor8x8PatternFillRect = FALSE;
+ Bool HaveSolidFillTrap = FALSE;
+ Bool HaveMono8x8PatternFillTrap = FALSE;
+ Bool HaveColor8x8PatternFillTrap = FALSE;
+ Bool HaveSolidTwoPointLine = FALSE;
+ Bool HaveSolidBresenhamLine = FALSE;
+ Bool HaveSolidHorVertLine = FALSE;
+ Bool HaveDashedTwoPointLine = FALSE;
+ Bool HaveDashedBresenhamLine = FALSE;
+ Bool HaveImageWriteRect = FALSE;
+ Bool HaveScanlineImageWriteRect = FALSE;
+ Bool HaveScreenToScreenColorExpandFill = FALSE;
+ OptionInfoPtr options;
+ int is_shared = 0;
+ int i;
+
+ options = xnfalloc(sizeof(XAAOptions));
+ (void)memcpy(options, XAAOptions, sizeof(XAAOptions));
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, options);
+
+ infoRec->pScrn = pScrn;
+ infoRec->NeedToSync = FALSE;
+
+ /* must have a Sync function */
+ if(!infoRec->Sync) return FALSE;
+ for(i = 0; i < pScrn->numEntities; i++) {
+ if(xf86IsEntityShared(pScrn->entityList[i])) is_shared = 1;
+ }
+
+ /* If this PCI entity has IS_SHARED_ACCEL set in entityProp
+ * then a RestoreAccelState function is required
+ */
+ if(!infoRec->RestoreAccelState && is_shared) return FALSE;
+
+ if(infoRec->RestoreAccelState) {
+ if(!XAAInitStateWrap(pScreen, infoRec)) return FALSE;
+ }
+
+ if (serverGeneration == 1)
+ xf86DrvMsg(index, X_INFO,
+ "Using XFree86 Acceleration Architecture (XAA)\n");
+
+
+ /************** Low Level *************/
+
+ if(!infoRec->SetClippingRectangle || !infoRec->DisableClipping) {
+ infoRec->ClippingFlags = 0;
+ infoRec->SetClippingRectangle = NULL;
+ infoRec->DisableClipping = NULL;
+ }
+
+ /**** CopyArea ****/
+
+ if(infoRec->SetupForScreenToScreenCopy &&
+ infoRec->SubsequentScreenToScreenCopy &&
+ !xf86ReturnOptValBool(options, XAAOPT_SCREEN_TO_SCREEN_COPY, FALSE)) {
+ HaveScreenToScreenCopy = TRUE;
+ } else {
+ infoRec->ScreenToScreenCopyFlags = 0;
+ infoRec->SetupForScreenToScreenCopy = NULL;
+ infoRec->SubsequentScreenToScreenCopy = NULL;
+ }
+
+ /**** Solid Filled Rects ****/
+
+ if(infoRec->SetupForSolidFill && infoRec->SubsequentSolidFillRect &&
+ !xf86ReturnOptValBool(options, XAAOPT_SOLID_FILL_RECT, FALSE)) {
+ HaveSolidFillRect = TRUE;
+ if(infoRec->SubsequentSolidFillTrap &&
+ !xf86ReturnOptValBool(options, XAAOPT_SOLID_FILL_TRAP, FALSE))
+ HaveSolidFillTrap = TRUE;
+ else
+ infoRec->SubsequentSolidFillTrap = NULL;
+ } else {
+ infoRec->SolidFillFlags = 0;
+ infoRec->SetupForSolidFill = NULL;
+ infoRec->SubsequentSolidFillRect = NULL;
+ infoRec->SubsequentSolidFillTrap = NULL;
+ }
+
+ /**** Solid lines ****/
+
+ if(infoRec->SetupForSolidLine) {
+ if(infoRec->SubsequentSolidTwoPointLine &&
+ !xf86ReturnOptValBool(options,
+ XAAOPT_SOLID_TWO_POINT_LINE, FALSE))
+ HaveSolidTwoPointLine = TRUE;
+ if(infoRec->SubsequentSolidBresenhamLine &&
+ !xf86ReturnOptValBool(options, XAAOPT_SOLID_BRESENHAM_LINE, FALSE)) {
+ HaveSolidBresenhamLine = TRUE;
+
+ if(infoRec->SolidBresenhamLineErrorTermBits)
+ infoRec->SolidBresenhamLineErrorTermBits =
+ ~((1 << infoRec->SolidBresenhamLineErrorTermBits) - 1);
+ }
+
+ if(infoRec->SubsequentSolidHorVertLine &&
+ !xf86ReturnOptValBool(options,
+ XAAOPT_SOLID_HORVERT_LINE, FALSE))
+ HaveSolidHorVertLine = TRUE;
+ else if(HaveSolidTwoPointLine) {
+ infoRec->SubsequentSolidHorVertLine =
+ XAASolidHorVertLineAsTwoPoint;
+ HaveSolidHorVertLine = TRUE;
+ } else if(HaveSolidBresenhamLine) {
+ infoRec->SubsequentSolidHorVertLine =
+ XAASolidHorVertLineAsBresenham;
+ HaveSolidHorVertLine = TRUE;
+ }
+ }
+
+ /* XXX Should this also check for XAAOPT_SOLID_HORVERT_LINE? */
+ if (!HaveSolidTwoPointLine &&
+ !HaveSolidBresenhamLine &&
+ !HaveSolidHorVertLine &&
+ HaveSolidFillRect) {
+ infoRec->SetupForSolidLine = infoRec->SetupForSolidFill;
+ infoRec->SubsequentSolidHorVertLine = XAASolidHorVertLineAsRects;
+ infoRec->SolidLineFlags = infoRec->SolidFillFlags;
+ HaveSolidHorVertLine = TRUE;
+ }
+
+ if (!HaveSolidTwoPointLine)
+ infoRec->SubsequentSolidTwoPointLine = NULL;
+ if (!HaveSolidBresenhamLine)
+ infoRec->SubsequentSolidBresenhamLine = NULL;
+ if (!HaveSolidHorVertLine)
+ infoRec->SubsequentSolidHorVertLine = NULL;
+
+ /* Disable all if nothing left over */
+ if (!HaveSolidTwoPointLine &&
+ !HaveSolidBresenhamLine &&
+ !HaveSolidHorVertLine) {
+ infoRec->SolidLineFlags = 0;
+ infoRec->SetupForSolidLine = NULL;
+ }
+
+ /**** 8x8 Mono Pattern Filled Rects ****/
+
+ if(infoRec->SetupForMono8x8PatternFill &&
+ infoRec->SubsequentMono8x8PatternFillRect &&
+ !xf86ReturnOptValBool(options,
+ XAAOPT_MONO_8x8_PATTERN_FILL_RECT,
+ FALSE)) {
+ HaveMono8x8PatternFillRect = TRUE;
+ if(infoRec->SubsequentMono8x8PatternFillTrap &&
+ !xf86ReturnOptValBool(options,
+ XAAOPT_MONO_8x8_PATTERN_FILL_TRAP,
+ FALSE))
+ HaveMono8x8PatternFillTrap = TRUE;
+
+ if(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_BITS) {
+ infoRec->CanDoMono8x8 = TRUE;
+ } else { /* others require caching */
+ int min_pitch;
+ infoRec->PixmapCacheFlags |= CACHE_MONO_8x8;
+
+ switch(pScrn->bitsPerPixel) {
+ case 32: min_pitch = 2; break;
+ case 24: min_pitch = 3; break;
+ case 16: min_pitch = 4; break;
+ default: min_pitch = 8; break;
+ }
+
+ if(min_pitch > infoRec->MonoPatternPitch)
+ infoRec->MonoPatternPitch = min_pitch;
+
+ if(infoRec->Mono8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN) {
+ if(!infoRec->CacheWidthMono8x8Pattern ||
+ !infoRec->CacheHeightMono8x8Pattern) {
+ infoRec->CacheWidthMono8x8Pattern =
+ infoRec->MonoPatternPitch;
+ infoRec->CacheHeightMono8x8Pattern = 1;
+ }
+ } else {
+ int numPerLine = 128/infoRec->MonoPatternPitch;
+
+ if(!infoRec->CacheWidthMono8x8Pattern ||
+ !infoRec->CacheHeightMono8x8Pattern) {
+ infoRec->CacheWidthMono8x8Pattern =
+ numPerLine * infoRec->MonoPatternPitch;
+ infoRec->CacheHeightMono8x8Pattern =
+ (64 + numPerLine - 1)/numPerLine;
+ }
+ }
+ }
+ } else {
+ infoRec->Mono8x8PatternFillFlags = 0;
+ infoRec->SetupForMono8x8PatternFill = NULL;
+ infoRec->SubsequentMono8x8PatternFillRect = NULL;
+ }
+
+ /**** Dashed lines ****/
+
+ if(infoRec->SetupForDashedLine && infoRec->DashPatternMaxLength) {
+ if(infoRec->SubsequentDashedTwoPointLine &&
+ !xf86ReturnOptValBool(options, XAAOPT_DASHED_TWO_POINT_LINE,
+ FALSE))
+ HaveDashedTwoPointLine = TRUE;
+ if(infoRec->SubsequentDashedBresenhamLine &&
+ !xf86ReturnOptValBool(options, XAAOPT_DASHED_BRESENHAM_LINE,
+ FALSE)) {
+ HaveDashedBresenhamLine = TRUE;
+
+ if(infoRec->DashedBresenhamLineErrorTermBits)
+ infoRec->DashedBresenhamLineErrorTermBits =
+ ~((1 << infoRec->DashedBresenhamLineErrorTermBits) - 1);
+ }
+ }
+
+ if (!HaveDashedTwoPointLine)
+ infoRec->SubsequentDashedTwoPointLine = NULL;
+ if (!HaveDashedBresenhamLine)
+ infoRec->SubsequentDashedBresenhamLine = NULL;
+
+ /* Disable all if nothing left over */
+ if (!HaveDashedTwoPointLine && !HaveDashedBresenhamLine) {
+ infoRec->DashedLineFlags = 0;
+ infoRec->SetupForDashedLine = NULL;
+ }
+
+ /**** 8x8 Color Pattern Filled Rects ****/
+
+ if(infoRec->SetupForColor8x8PatternFill &&
+ infoRec->SubsequentColor8x8PatternFillRect &&
+ !xf86ReturnOptValBool(options, XAAOPT_COL_8x8_PATTERN_FILL_RECT, FALSE)) {
+ HaveColor8x8PatternFillRect = TRUE;
+ if(infoRec->SubsequentColor8x8PatternFillTrap &&
+ !xf86ReturnOptValBool(options, XAAOPT_COL_8x8_PATTERN_FILL_TRAP,
+ FALSE))
+ HaveColor8x8PatternFillTrap = TRUE;
+ else
+ infoRec->SubsequentColor8x8PatternFillTrap = NULL;
+
+ infoRec->PixmapCacheFlags |= CACHE_COLOR_8x8;
+
+ if(infoRec->Color8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN) {
+ if(!infoRec->CacheWidthColor8x8Pattern ||
+ !infoRec->CacheHeightColor8x8Pattern) {
+ infoRec->CacheWidthColor8x8Pattern = 64;
+ infoRec->CacheHeightColor8x8Pattern = 1;
+ }
+ } else {
+ if(!infoRec->CacheWidthColor8x8Pattern ||
+ !infoRec->CacheHeightColor8x8Pattern) {
+ infoRec->CacheWidthColor8x8Pattern = 128;
+ infoRec->CacheHeightColor8x8Pattern = 8;
+ }
+ }
+ } else {
+ infoRec->Color8x8PatternFillFlags = 0;
+ infoRec->SetupForColor8x8PatternFill = NULL;
+ infoRec->SubsequentColor8x8PatternFillRect = NULL;
+ infoRec->SubsequentColor8x8PatternFillTrap = NULL;
+ }
+
+ /**** Color Expansion ****/
+
+ if(infoRec->SetupForCPUToScreenColorExpandFill &&
+ infoRec->ColorExpandBase &&
+ infoRec->SubsequentCPUToScreenColorExpandFill &&
+ !xf86ReturnOptValBool(options, XAAOPT_CPU_TO_SCREEN_COL_EXP_FILL,
+ FALSE)) {
+ int dwordsNeeded = pScrn->virtualX;
+
+ infoRec->ColorExpandRange >>= 2; /* convert to DWORDS */
+ HaveColorExpansion = TRUE;
+
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ LEFT_EDGE_CLIPPING_NEGATIVE_X)
+ dwordsNeeded += 31;
+ dwordsNeeded = (dwordsNeeded + 31) >> 5;
+ if(dwordsNeeded > infoRec->ColorExpandRange)
+ infoRec->CPUToScreenColorExpandFillFlags |= CPU_TRANSFER_BASE_FIXED;
+ } else {
+ infoRec->CPUToScreenColorExpandFillFlags = 0;
+ infoRec->SetupForCPUToScreenColorExpandFill = NULL;
+ infoRec->SubsequentCPUToScreenColorExpandFill = NULL;
+ }
+
+ /**** Scanline Color Expansion ****/
+
+ if(infoRec->SetupForScanlineCPUToScreenColorExpandFill &&
+ infoRec->SubsequentScanlineCPUToScreenColorExpandFill &&
+ infoRec->SubsequentColorExpandScanline &&
+ infoRec->ScanlineColorExpandBuffers &&
+ (infoRec->NumScanlineColorExpandBuffers > 0) &&
+ !xf86ReturnOptValBool(options,
+ XAAOPT_SCANLINE_CPU_TO_SCREEN_COL_EXP_FILL,
+ FALSE)) {
+ HaveScanlineColorExpansion = TRUE;
+ } else {
+ infoRec->ScanlineCPUToScreenColorExpandFillFlags = 0;
+ infoRec->SetupForScanlineCPUToScreenColorExpandFill = NULL;
+ infoRec->SubsequentScanlineCPUToScreenColorExpandFill = NULL;
+ infoRec->SubsequentColorExpandScanline = NULL;
+ }
+
+ /**** Screen to Screen Color Expansion ****/
+
+ if(infoRec->SetupForScreenToScreenColorExpandFill &&
+ infoRec->SubsequentScreenToScreenColorExpandFill &&
+ !xf86ReturnOptValBool(options, XAAOPT_SCREEN_TO_SCREEN_COL_EXP_FILL,
+ FALSE)) {
+ HaveScreenToScreenColorExpandFill = TRUE;
+ if (!infoRec->CacheColorExpandDensity)
+ infoRec->CacheColorExpandDensity = 1;
+ } else {
+ infoRec->ScreenToScreenColorExpandFillFlags = 0;
+ infoRec->SetupForScreenToScreenColorExpandFill = NULL;
+ infoRec->SubsequentScreenToScreenColorExpandFill = NULL;
+ }
+
+ /**** Image Writes ****/
+
+ if(infoRec->SetupForImageWrite && infoRec->ImageWriteBase &&
+ infoRec->SubsequentImageWriteRect &&
+ !xf86ReturnOptValBool(options, XAAOPT_IMAGE_WRITE_RECT, FALSE)) {
+
+ infoRec->ImageWriteRange >>= 2; /* convert to DWORDS */
+ if(infoRec->ImageWriteFlags & CPU_TRANSFER_BASE_FIXED)
+ infoRec->ImageWriteRange = 0;
+ HaveImageWriteRect = TRUE;
+ } else {
+ infoRec->ImageWriteFlags = 0;
+ infoRec->SetupForImageWrite = NULL;
+ infoRec->SubsequentImageWriteRect = NULL;
+ }
+
+ /**** Scanline Image Writes ****/
+
+ if(infoRec->SetupForScanlineImageWrite &&
+ infoRec->SubsequentScanlineImageWriteRect &&
+ infoRec->SubsequentImageWriteScanline &&
+ infoRec->ScanlineImageWriteBuffers &&
+ (infoRec->NumScanlineImageWriteBuffers > 0) &&
+ !xf86ReturnOptValBool(options, XAAOPT_SCANLINE_IMAGE_WRITE_RECT,
+ FALSE)) {
+ HaveScanlineImageWriteRect = TRUE;
+ } else {
+ infoRec->ScanlineImageWriteFlags = 0;
+ infoRec->SetupForScanlineImageWrite = NULL;
+ infoRec->SubsequentScanlineImageWriteRect = NULL;
+ infoRec->SubsequentImageWriteScanline = NULL;
+ }
+
+#ifndef __i386__
+ /* XAA makes some unaligned accesses when clipping is not available */
+# define CLIP_FLAGS (LEFT_EDGE_CLIPPING | LEFT_EDGE_CLIPPING_NEGATIVE_X)
+ if(HaveImageWriteRect &&
+ ((infoRec->ImageWriteFlags & CLIP_FLAGS) != CLIP_FLAGS))
+ {
+ HaveImageWriteRect = FALSE;
+ }
+ if(HaveScanlineImageWriteRect &&
+ ((infoRec->ScanlineImageWriteFlags & CLIP_FLAGS) != CLIP_FLAGS))
+ {
+ HaveScanlineImageWriteRect = FALSE;
+ }
+#endif
+
+ if (serverGeneration == 1) {
+ if(HaveScreenToScreenCopy)
+ xf86ErrorF("\tScreen to screen bit blits\n");
+ if(HaveSolidFillRect)
+ xf86ErrorF("\tSolid filled rectangles\n");
+ if(HaveSolidFillTrap)
+ xf86ErrorF("\tSolid filled trapezoids\n");
+ if(HaveMono8x8PatternFillRect)
+ xf86ErrorF("\t8x8 mono pattern filled rectangles\n");
+ if(HaveMono8x8PatternFillTrap)
+ xf86ErrorF("\t8x8 mono pattern filled trapezoids\n");
+ if(HaveColor8x8PatternFillRect)
+ xf86ErrorF("\t8x8 color pattern filled rectangles\n");
+ if(HaveColor8x8PatternFillTrap)
+ xf86ErrorF("\t8x8 color pattern filled trapezoids\n");
+
+ if(HaveColorExpansion)
+ xf86ErrorF("\tCPU to Screen color expansion\n");
+ else if(HaveScanlineColorExpansion)
+ xf86ErrorF("\tIndirect CPU to Screen color expansion\n");
+
+ if(HaveScreenToScreenColorExpandFill)
+ xf86ErrorF("\tScreen to Screen color expansion\n");
+
+ if(HaveSolidTwoPointLine || HaveSolidBresenhamLine)
+ xf86ErrorF("\tSolid Lines\n");
+ else if(HaveSolidHorVertLine)
+ xf86ErrorF("\tSolid Horizontal and Vertical Lines\n");
+
+ if(HaveDashedTwoPointLine || HaveDashedBresenhamLine)
+ xf86ErrorF("\tDashed Lines\n");
+
+ if(HaveImageWriteRect)
+ xf86ErrorF("\tImage Writes\n");
+ else if(HaveScanlineImageWriteRect)
+ xf86ErrorF("\tScanline Image Writes\n");
+
+ }
+
+#define XAAMSG(s) do { if (serverGeneration == 1) xf86ErrorF(s); } while (0)
+
+ if((infoRec->Flags & OFFSCREEN_PIXMAPS) && HaveScreenToScreenCopy &&
+ xf86ReturnOptValBool(options,
+ XAAOPT_HAS_DUMB_INVERTED_OPTION_SENSE,
+ FALSE))
+ {
+ XAAMSG("\tOffscreen Pixmaps\n");
+ } else {
+ infoRec->Flags &= ~OFFSCREEN_PIXMAPS;
+ }
+
+
+ /************** Mid Level *************/
+
+ /**** ScreenToScreenBitBlt ****/
+
+ if(infoRec->ScreenToScreenBitBlt) {
+ XAAMSG("\tDriver provided ScreenToScreenBitBlt replacement\n");
+ } else if(HaveScreenToScreenCopy) {
+ infoRec->ScreenToScreenBitBlt = XAAScreenToScreenBitBlt;
+ infoRec->ScreenToScreenBitBltFlags = infoRec->ScreenToScreenCopyFlags;
+ }
+
+ /**** FillSolidRects ****/
+
+ if(infoRec->FillSolidRects) {
+ XAAMSG("\tDriver provided FillSolidRects replacement\n");
+ } else if(HaveSolidFillRect) {
+ infoRec->FillSolidRects = XAAFillSolidRects;
+ infoRec->FillSolidRectsFlags = infoRec->SolidFillFlags;
+ }
+
+ /**** FillSolidSpans ****/
+
+ if(infoRec->FillSolidSpans) {
+ XAAMSG("\tDriver provided FillSolidSpans replacement\n");
+ } else if(HaveSolidFillRect) {
+ infoRec->FillSolidSpans = XAAFillSolidSpans;
+ infoRec->FillSolidSpansFlags = infoRec->SolidFillFlags;
+ }
+
+ /**** FillMono8x8PatternRects ****/
+
+ if(infoRec->FillMono8x8PatternRects) {
+ XAAMSG("\tDriver provided FillMono8x8PatternRects replacement\n");
+ } else if(HaveMono8x8PatternFillRect) {
+ infoRec->FillMono8x8PatternRects =
+ (infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_SCREEN_ORIGIN) ?
+ XAAFillMono8x8PatternRectsScreenOrigin :
+ XAAFillMono8x8PatternRects;
+
+ infoRec->FillMono8x8PatternRectsFlags =
+ infoRec->Mono8x8PatternFillFlags;
+ }
+
+ /**** FillMono8x8PatternSpans ****/
+
+ if(infoRec->FillMono8x8PatternSpans) {
+ XAAMSG("\tDriver provided FillMono8x8PatternSpans replacement\n");
+ } else if(HaveMono8x8PatternFillRect) {
+ infoRec->FillMono8x8PatternSpans =
+ (infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_SCREEN_ORIGIN) ?
+ XAAFillMono8x8PatternSpansScreenOrigin:
+ XAAFillMono8x8PatternSpans;
+
+ infoRec->FillMono8x8PatternSpansFlags =
+ infoRec->Mono8x8PatternFillFlags;
+ }
+
+ /**** FillColor8x8Rects ****/
+
+ if(infoRec->FillColor8x8PatternRects) {
+ XAAMSG("\tDriver provided FillColor8x8PatternRects replacement\n");
+ } else if(HaveColor8x8PatternFillRect) {
+ infoRec->FillColor8x8PatternRects =
+ (infoRec->Color8x8PatternFillFlags & HARDWARE_PATTERN_SCREEN_ORIGIN) ?
+ XAAFillColor8x8PatternRectsScreenOrigin :
+ XAAFillColor8x8PatternRects;
+
+ infoRec->FillColor8x8PatternRectsFlags =
+ infoRec->Color8x8PatternFillFlags;
+ }
+
+ /**** FillColor8x8Spans ****/
+
+ if(infoRec->FillColor8x8PatternSpans) {
+ XAAMSG("\tDriver provided FillColor8x8PatternSpans replacement\n");
+ } else if(HaveColor8x8PatternFillRect) {
+ infoRec->FillColor8x8PatternSpans =
+ (infoRec->Color8x8PatternFillFlags & HARDWARE_PATTERN_SCREEN_ORIGIN) ?
+ XAAFillColor8x8PatternSpansScreenOrigin:
+ XAAFillColor8x8PatternSpans;
+
+ infoRec->FillColor8x8PatternSpansFlags =
+ infoRec->Color8x8PatternFillFlags;
+ }
+
+ /**** FillCacheBltRects ****/
+
+ if(infoRec->FillCacheBltRects) {
+ XAAMSG("\tDriver provided FillCacheBltRects replacement\n");
+ } else if(HaveScreenToScreenCopy) {
+ infoRec->FillCacheBltRects = XAAFillCacheBltRects;
+ infoRec->FillCacheBltRectsFlags = infoRec->ScreenToScreenCopyFlags;
+ }
+
+ /**** FillCacheBltSpans ****/
+
+ if(infoRec->FillCacheBltSpans) {
+ XAAMSG("\tDriver provided FillCacheBltSpans replacement\n");
+ } else if(HaveScreenToScreenCopy) {
+ infoRec->FillCacheBltSpans = XAAFillCacheBltSpans;
+ infoRec->FillCacheBltSpansFlags = infoRec->ScreenToScreenCopyFlags;
+ }
+
+ /**** FillCacheExpandRects ****/
+
+ if(infoRec->FillCacheExpandRects) {
+ XAAMSG("\tDriver provided FillCacheExpandRects replacement\n");
+ } else if(HaveScreenToScreenColorExpandFill) {
+ infoRec->FillCacheExpandRects = XAAFillCacheExpandRects;
+ infoRec->FillCacheExpandRectsFlags =
+ infoRec->ScreenToScreenColorExpandFillFlags;
+ }
+
+ /**** FillCacheExpandSpans ****/
+
+ if(infoRec->FillCacheExpandSpans) {
+ XAAMSG("\tDriver provided FillCacheExpandSpans replacement\n");
+ } else if(HaveScreenToScreenColorExpandFill) {
+ infoRec->FillCacheExpandSpans = XAAFillCacheExpandSpans;
+ infoRec->FillCacheExpandSpansFlags =
+ infoRec->ScreenToScreenColorExpandFillFlags;
+ }
+
+ /**** FillColorExpandRects ****/
+
+ if(infoRec->FillColorExpandRects) {
+ XAAMSG("\tDriver provided FillColorExpandRects replacement\n");
+ } else if(HaveColorExpansion) {
+ if (infoRec->CPUToScreenColorExpandFillFlags & TRIPLE_BITS_24BPP) {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST) {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->FillColorExpandRects =
+ XAAFillColorExpandRects3MSBFirstFixedBase;
+ else
+ infoRec->FillColorExpandRects =
+ XAAFillColorExpandRects3MSBFirst;
+ } else {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->FillColorExpandRects =
+ XAAFillColorExpandRects3LSBFirstFixedBase;
+ else
+ infoRec->FillColorExpandRects =
+ XAAFillColorExpandRects3LSBFirst;
+ }
+ } else {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST) {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->FillColorExpandRects =
+ XAAFillColorExpandRectsMSBFirstFixedBase;
+ else
+ infoRec->FillColorExpandRects =
+ XAAFillColorExpandRectsMSBFirst;
+ } else {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->FillColorExpandRects =
+ XAAFillColorExpandRectsLSBFirstFixedBase;
+ else
+ infoRec->FillColorExpandRects =
+ XAAFillColorExpandRectsLSBFirst;
+ }
+ }
+ infoRec->FillColorExpandRectsFlags =
+ infoRec->CPUToScreenColorExpandFillFlags;
+ } else if(HaveScanlineColorExpansion) {
+ if (infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ TRIPLE_BITS_24BPP) {
+ if(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST)
+ infoRec->FillColorExpandRects =
+ XAAFillScanlineColorExpandRects3MSBFirst;
+ else
+ infoRec->FillColorExpandRects =
+ XAAFillScanlineColorExpandRects3LSBFirst;
+ } else {
+ if(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST)
+ infoRec->FillColorExpandRects =
+ XAAFillScanlineColorExpandRectsMSBFirst;
+ else
+ infoRec->FillColorExpandRects =
+ XAAFillScanlineColorExpandRectsLSBFirst;
+ }
+ infoRec->FillColorExpandRectsFlags =
+ infoRec->ScanlineCPUToScreenColorExpandFillFlags;
+ }
+
+ /**** FillColorExpandSpans ****/
+
+ if(infoRec->FillColorExpandSpans) {
+ XAAMSG("\tDriver provided FillColorExpandSpans replacement\n");
+ } else if(HaveColorExpansion) {
+ if (infoRec->CPUToScreenColorExpandFillFlags & TRIPLE_BITS_24BPP) {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST) {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->FillColorExpandSpans =
+ XAAFillColorExpandSpans3MSBFirstFixedBase;
+ else
+ infoRec->FillColorExpandSpans =
+ XAAFillColorExpandSpans3MSBFirst;
+ } else {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->FillColorExpandSpans =
+ XAAFillColorExpandSpans3LSBFirstFixedBase;
+ else
+ infoRec->FillColorExpandSpans =
+ XAAFillColorExpandSpans3LSBFirst;
+ }
+ } else {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST) {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->FillColorExpandSpans =
+ XAAFillColorExpandSpansMSBFirstFixedBase;
+ else
+ infoRec->FillColorExpandSpans =
+ XAAFillColorExpandSpansMSBFirst;
+ } else {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->FillColorExpandSpans =
+ XAAFillColorExpandSpansLSBFirstFixedBase;
+ else
+ infoRec->FillColorExpandSpans =
+ XAAFillColorExpandSpansLSBFirst;
+ }
+ }
+ infoRec->FillColorExpandSpansFlags =
+ infoRec->CPUToScreenColorExpandFillFlags;
+ } else if(HaveScanlineColorExpansion) {
+ if (infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ TRIPLE_BITS_24BPP) {
+ if(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST)
+ infoRec->FillColorExpandSpans =
+ XAAFillScanlineColorExpandSpans3MSBFirst;
+ else
+ infoRec->FillColorExpandSpans =
+ XAAFillScanlineColorExpandSpans3LSBFirst;
+ } else {
+ if(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST)
+ infoRec->FillColorExpandSpans =
+ XAAFillScanlineColorExpandSpansMSBFirst;
+ else
+ infoRec->FillColorExpandSpans =
+ XAAFillScanlineColorExpandSpansLSBFirst;
+ }
+ infoRec->FillColorExpandSpansFlags =
+ infoRec->ScanlineCPUToScreenColorExpandFillFlags;
+ }
+
+ /**** FillImageWriteRects ****/
+
+ if(infoRec->FillImageWriteRects) {
+ XAAMSG("\tDriver provided FillImageWriteRects replacement\n");
+ } else if(HaveImageWriteRect &&
+ (infoRec->ImageWriteFlags & LEFT_EDGE_CLIPPING_NEGATIVE_X) &&
+ (infoRec->ImageWriteFlags & LEFT_EDGE_CLIPPING)) {
+ infoRec->FillImageWriteRects = XAAFillImageWriteRects;
+ infoRec->FillImageWriteRectsFlags = infoRec->ImageWriteFlags;
+ }
+
+ /**** WriteBitmap ****/
+
+ if(infoRec->WriteBitmap &&
+ !xf86ReturnOptValBool(options, XAAOPT_WRITE_BITMAP, FALSE)) {
+ XAAMSG("\tDriver provided WriteBitmap replacement\n");
+ } else if(HaveColorExpansion) {
+ if (infoRec->CPUToScreenColorExpandFillFlags & TRIPLE_BITS_24BPP) {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST) {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->WriteBitmap =
+ XAAWriteBitmapColorExpand3MSBFirstFixedBase;
+ else
+ infoRec->WriteBitmap = XAAWriteBitmapColorExpand3MSBFirst;
+ } else {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->WriteBitmap =
+ XAAWriteBitmapColorExpand3LSBFirstFixedBase;
+ else
+ infoRec->WriteBitmap = XAAWriteBitmapColorExpand3LSBFirst;
+ }
+ } else {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST) {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->WriteBitmap =
+ XAAWriteBitmapColorExpandMSBFirstFixedBase;
+ else
+ infoRec->WriteBitmap = XAAWriteBitmapColorExpandMSBFirst;
+ } else {
+ if(infoRec->CPUToScreenColorExpandFillFlags &
+ CPU_TRANSFER_BASE_FIXED)
+ infoRec->WriteBitmap =
+ XAAWriteBitmapColorExpandLSBFirstFixedBase;
+ else
+ infoRec->WriteBitmap = XAAWriteBitmapColorExpandLSBFirst;
+ }
+ }
+ infoRec->WriteBitmapFlags = infoRec->CPUToScreenColorExpandFillFlags;
+ } else if(HaveScanlineColorExpansion) {
+ if (infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ TRIPLE_BITS_24BPP) {
+ if(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST)
+ infoRec->WriteBitmap =
+ XAAWriteBitmapScanlineColorExpand3MSBFirst;
+ else
+ infoRec->WriteBitmap =
+ XAAWriteBitmapScanlineColorExpand3LSBFirst;
+ } else {
+ if(infoRec->ScanlineCPUToScreenColorExpandFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST)
+ infoRec->WriteBitmap =
+ XAAWriteBitmapScanlineColorExpandMSBFirst;
+ else
+ infoRec->WriteBitmap =
+ XAAWriteBitmapScanlineColorExpandLSBFirst;
+ }
+ infoRec->WriteBitmapFlags =
+ infoRec->ScanlineCPUToScreenColorExpandFillFlags;
+ } else
+ infoRec->WriteBitmap = NULL;
+
+ /**** TE Glyphs ****/
+
+ if (infoRec->TEGlyphRenderer) {
+ XAAMSG("\tDriver provided TEGlyphRenderer replacement\n");
+ } else if (HaveColorExpansion) {
+ infoRec->TEGlyphRendererFlags =
+ infoRec->CPUToScreenColorExpandFillFlags;
+
+ if (infoRec->TEGlyphRendererFlags & TRIPLE_BITS_24BPP) {
+ if (infoRec->TEGlyphRendererFlags & BIT_ORDER_IN_BYTE_MSBFIRST) {
+ if (infoRec->TEGlyphRendererFlags & CPU_TRANSFER_BASE_FIXED)
+ infoRec->TEGlyphRenderer =
+ XAATEGlyphRenderer3MSBFirstFixedBase;
+ else
+ infoRec->TEGlyphRenderer = XAATEGlyphRenderer3MSBFirst;
+ } else {
+ if (infoRec->TEGlyphRendererFlags & CPU_TRANSFER_BASE_FIXED)
+ infoRec->TEGlyphRenderer =
+ XAATEGlyphRenderer3LSBFirstFixedBase;
+ else
+ infoRec->TEGlyphRenderer = XAATEGlyphRenderer3LSBFirst;
+ }
+
+ if (!HaveSolidFillRect &&
+ (infoRec->TEGlyphRendererFlags & RGB_EQUAL)) {
+ infoRec->TEGlyphRendererFlags &= ~RGB_EQUAL;
+ XAAMSG("WARNING: TEGlyphRenderer cannot support RGB_EQUAL"
+ " without solid fills\n");
+ }
+ } else {
+ if (infoRec->TEGlyphRendererFlags & BIT_ORDER_IN_BYTE_MSBFIRST) {
+ if (infoRec->TEGlyphRendererFlags & CPU_TRANSFER_BASE_FIXED)
+ infoRec->TEGlyphRenderer =
+ XAATEGlyphRendererMSBFirstFixedBase;
+ else
+ infoRec->TEGlyphRenderer = XAATEGlyphRendererMSBFirst;
+ } else {
+ if (infoRec->TEGlyphRendererFlags & CPU_TRANSFER_BASE_FIXED)
+ infoRec->TEGlyphRenderer =
+ XAATEGlyphRendererLSBFirstFixedBase;
+ else
+ infoRec->TEGlyphRenderer = XAATEGlyphRendererLSBFirst;
+ }
+ }
+
+ if (!HaveSolidFillRect &&
+ (infoRec->TEGlyphRendererFlags & TRANSPARENCY_ONLY)) {
+ infoRec->TEGlyphRendererFlags &= ~TRANSPARENCY_ONLY;
+ XAAMSG("WARNING: TEGlyphRenderer cannot support TRANPARENCY_ONLY"
+ " without solid fills\n");
+ }
+
+ } else if (HaveScanlineColorExpansion) {
+ infoRec->TEGlyphRendererFlags =
+ infoRec->ScanlineCPUToScreenColorExpandFillFlags;
+
+ if (infoRec->TEGlyphRendererFlags & TRIPLE_BITS_24BPP) {
+ if (infoRec->TEGlyphRendererFlags & BIT_ORDER_IN_BYTE_MSBFIRST)
+ infoRec->TEGlyphRenderer = XAATEGlyphRendererScanline3MSBFirst;
+ else
+ infoRec->TEGlyphRenderer = XAATEGlyphRendererScanline3LSBFirst;
+
+ if (!HaveSolidFillRect &&
+ (infoRec->TEGlyphRendererFlags & RGB_EQUAL)) {
+ infoRec->TEGlyphRendererFlags &= ~RGB_EQUAL;
+ XAAMSG("WARNING: TEGlyphRenderer cannot support RGB_EQUAL"
+ " without solid fills\n");
+ }
+ } else {
+ if (infoRec->TEGlyphRendererFlags & BIT_ORDER_IN_BYTE_MSBFIRST)
+ infoRec->TEGlyphRenderer = XAATEGlyphRendererScanlineMSBFirst;
+ else
+ infoRec->TEGlyphRenderer = XAATEGlyphRendererScanlineLSBFirst;
+ }
+
+ if (!HaveSolidFillRect &&
+ (infoRec->TEGlyphRendererFlags & TRANSPARENCY_ONLY)) {
+ infoRec->TEGlyphRendererFlags &= ~TRANSPARENCY_ONLY;
+ XAAMSG("WARNING: TEGlyphRenderer cannot support TRANPARENCY_ONLY"
+ " without solid fills\n");
+ }
+ }
+
+ /**** NonTE Glyphs ****/
+
+ if(infoRec->NonTEGlyphRenderer) {
+ XAAMSG("\tDriver provided NonTEGlyphRenderer replacement\n");
+ } else if(infoRec->WriteBitmap &&
+ !(infoRec->WriteBitmapFlags & NO_TRANSPARENCY)) {
+ infoRec->NonTEGlyphRenderer = XAANonTEGlyphRenderer;
+ infoRec->NonTEGlyphRendererFlags = infoRec->WriteBitmapFlags;
+ }
+
+ /**** WritePixmap ****/
+
+ if(infoRec->WritePixmap &&
+ !xf86ReturnOptValBool(options, XAAOPT_WRITE_PIXMAP, FALSE)) {
+ XAAMSG("\tDriver provided WritePixmap replacement\n");
+ } else if(HaveImageWriteRect) {
+ infoRec->WritePixmap = XAAWritePixmap;
+ infoRec->WritePixmapFlags =
+ infoRec->ImageWriteFlags | CONVERT_32BPP_TO_24BPP;
+ } else if(HaveScanlineImageWriteRect) {
+ infoRec->WritePixmap = XAAWritePixmapScanline;
+ infoRec->WritePixmapFlags = infoRec->ScanlineImageWriteFlags;
+ } else
+ infoRec->WritePixmap = NULL;
+
+ /**** ReadPixmap ****/
+
+ if(infoRec->ReadPixmap) {
+ XAAMSG("\tDriver provided ReadPixmap replacement\n");
+ }
+
+
+ /************** GC Level *************/
+
+ /**** CopyArea ****/
+
+ if(infoRec->CopyArea) {
+ XAAMSG("\tDriver provided GC level CopyArea replacement\n");
+ } else if(infoRec->ScreenToScreenBitBlt) {
+ infoRec->CopyArea = XAACopyArea;
+ infoRec->CopyAreaFlags = infoRec->ScreenToScreenBitBltFlags;
+
+ /* most GC level primitives use one mid-level primitive so
+ the GC level primitive gets the mid-level primitive flag
+ and we use that at GC validation time. But CopyArea uses
+ more than one mid-level primitive so we have to essentially
+ do a GC validation every time that primitive is used.
+ The CopyAreaFlags would only be used for filtering out the
+ common denominators. Here we assume that if you don't do
+ ScreenToScreenBitBlt you aren't going to do the others.
+ We also assume that ScreenToScreenBitBlt has the least
+ restrictions. */
+ }
+
+ if(infoRec->CopyPlane) {
+ XAAMSG("\tDriver provided GC level CopyPlane replacement\n");
+ } else if(infoRec->WriteBitmap &&
+ !(infoRec->WriteBitmapFlags & TRANSPARENCY_ONLY)) {
+ infoRec->CopyPlane = XAACopyPlaneColorExpansion;
+ infoRec->CopyPlaneFlags = infoRec->WriteBitmapFlags;
+ }
+
+ if(infoRec->PushPixelsSolid) {
+ XAAMSG("\tDriver provided GC level PushPixelsSolid replacement\n");
+ } else if(infoRec->WriteBitmap &&
+ !(infoRec->WriteBitmapFlags & NO_TRANSPARENCY)) {
+ infoRec->PushPixelsSolid = XAAPushPixelsSolidColorExpansion;
+ infoRec->PushPixelsFlags = infoRec->WriteBitmapFlags;
+ }
+
+ if(infoRec->FillSolidRects) {
+ if(!infoRec->PolyFillRectSolid) {
+ infoRec->PolyFillRectSolid = XAAPolyFillRect;
+ infoRec->PolyFillRectSolidFlags = infoRec->FillSolidRectsFlags;
+ }
+ }
+ if(infoRec->FillSolidSpans) {
+ if(!infoRec->FillSpansSolid) {
+ infoRec->FillSpansSolid = XAAFillSpans;
+ infoRec->FillSpansSolidFlags = infoRec->FillSolidSpansFlags;
+ }
+ }
+
+ if(infoRec->FillMono8x8PatternRects || infoRec->FillColor8x8PatternRects ||
+ infoRec->FillCacheBltRects || infoRec->FillColorExpandRects ||
+ infoRec->FillCacheExpandRects) {
+ if(!infoRec->PolyFillRectStippled) {
+
+ infoRec->PolyFillRectStippled = XAAPolyFillRect;
+ infoRec->PolyFillRectStippledFlags = 0;
+ }
+ }
+
+ if(infoRec->FillMono8x8PatternSpans || infoRec->FillColor8x8PatternSpans ||
+ infoRec->FillCacheBltSpans || infoRec->FillColorExpandSpans ||
+ infoRec->FillCacheExpandSpans) {
+ if(!infoRec->FillSpansStippled) {
+
+ infoRec->FillSpansStippled = XAAFillSpans;
+ infoRec->FillSpansStippledFlags = 0;
+ }
+ }
+
+ if(infoRec->FillMono8x8PatternRects || infoRec->FillColor8x8PatternRects ||
+ infoRec->FillCacheBltRects || infoRec->FillColorExpandRects ||
+ infoRec->FillCacheExpandRects) {
+ if(!infoRec->PolyFillRectOpaqueStippled) {
+
+ infoRec->PolyFillRectOpaqueStippled = XAAPolyFillRect;
+ infoRec->PolyFillRectOpaqueStippledFlags = 0;
+ }
+ }
+
+ if(infoRec->FillMono8x8PatternSpans || infoRec->FillColor8x8PatternSpans ||
+ infoRec->FillCacheBltSpans || infoRec->FillColorExpandSpans ||
+ infoRec->FillCacheExpandSpans) {
+ if(!infoRec->FillSpansOpaqueStippled) {
+
+ infoRec->FillSpansOpaqueStippled = XAAFillSpans;
+ infoRec->FillSpansOpaqueStippledFlags = 0;
+ }
+ }
+
+ if(infoRec->FillMono8x8PatternRects || infoRec->FillColor8x8PatternRects ||
+ infoRec->FillCacheBltRects || infoRec->FillImageWriteRects) {
+ if(!infoRec->PolyFillRectTiled) {
+
+ infoRec->PolyFillRectTiled = XAAPolyFillRect;
+ infoRec->PolyFillRectTiledFlags = 0;
+ }
+ }
+
+ if(infoRec->FillMono8x8PatternSpans || infoRec->FillColor8x8PatternSpans ||
+ infoRec->FillCacheBltSpans) {
+ if(!infoRec->FillSpansTiled) {
+
+ infoRec->FillSpansTiled = XAAFillSpans;
+ infoRec->FillSpansTiledFlags = 0;
+ }
+ }
+
+ if(infoRec->TEGlyphRenderer &&
+ !(infoRec->TEGlyphRendererFlags & NO_TRANSPARENCY)) {
+
+ if(!infoRec->PolyText8TE) {
+ infoRec->PolyText8TE = XAAPolyText8TEColorExpansion;
+ infoRec->PolyText8TEFlags = infoRec->TEGlyphRendererFlags;
+ }
+
+ if(!infoRec->PolyText16TE) {
+ infoRec->PolyText16TE = XAAPolyText16TEColorExpansion;
+ infoRec->PolyText16TEFlags = infoRec->TEGlyphRendererFlags;
+ }
+
+ if(!infoRec->PolyGlyphBltTE) {
+ infoRec->PolyGlyphBltTE = XAAPolyGlyphBltTEColorExpansion;
+ infoRec->PolyGlyphBltTEFlags = infoRec->TEGlyphRendererFlags;
+ }
+ }
+
+ if(infoRec->TEGlyphRenderer &&
+ !(infoRec->TEGlyphRendererFlags & TRANSPARENCY_ONLY)) {
+
+ if(!infoRec->ImageText8TE) {
+ infoRec->ImageText8TE = XAAImageText8TEColorExpansion;
+ infoRec->ImageText8TEFlags = infoRec->TEGlyphRendererFlags;
+ }
+
+ if(!infoRec->ImageText16TE) {
+ infoRec->ImageText16TE = XAAImageText16TEColorExpansion;
+ infoRec->ImageText16TEFlags = infoRec->TEGlyphRendererFlags;
+ }
+
+ if(!infoRec->ImageGlyphBltTE) {
+ infoRec->ImageGlyphBltTE = XAAImageGlyphBltTEColorExpansion;
+ infoRec->ImageGlyphBltTEFlags = infoRec->TEGlyphRendererFlags;
+ }
+ }
+
+ if(infoRec->NonTEGlyphRenderer) {
+ if(!infoRec->PolyText8NonTE) {
+ infoRec->PolyText8NonTE = XAAPolyText8NonTEColorExpansion;
+ infoRec->PolyText8NonTEFlags = infoRec->NonTEGlyphRendererFlags;
+ }
+
+ if(!infoRec->PolyText16NonTE) {
+ infoRec->PolyText16NonTE = XAAPolyText16NonTEColorExpansion;
+ infoRec->PolyText16NonTEFlags = infoRec->NonTEGlyphRendererFlags;
+ }
+ if(!infoRec->PolyGlyphBltNonTE) {
+ infoRec->PolyGlyphBltNonTE = XAAPolyGlyphBltNonTEColorExpansion;
+ infoRec->PolyGlyphBltNonTEFlags = infoRec->NonTEGlyphRendererFlags;
+ }
+ }
+
+ if(infoRec->NonTEGlyphRenderer && HaveSolidFillRect) {
+ if(!infoRec->ImageText8NonTE) {
+ infoRec->ImageText8NonTE = XAAImageText8NonTEColorExpansion;
+ infoRec->ImageText8NonTEFlags = infoRec->NonTEGlyphRendererFlags;
+ }
+
+ if(!infoRec->ImageText16NonTE) {
+ infoRec->ImageText16NonTE = XAAImageText16NonTEColorExpansion;
+ infoRec->ImageText16NonTEFlags = infoRec->NonTEGlyphRendererFlags;
+ }
+
+ if(!infoRec->ImageGlyphBltNonTE) {
+ infoRec->ImageGlyphBltNonTE = XAAImageGlyphBltNonTEColorExpansion;
+ infoRec->ImageGlyphBltNonTEFlags = infoRec->NonTEGlyphRendererFlags;
+ }
+ }
+
+ if(!infoRec->PolyRectangleThinSolid && HaveSolidHorVertLine) {
+ infoRec->PolyRectangleThinSolid = XAAPolyRectangleThinSolid;
+ infoRec->PolyRectangleThinSolidFlags = infoRec->SolidLineFlags;
+ }
+
+ if(!infoRec->FillPolygonSolid && HaveSolidFillRect) {
+ infoRec->FillPolygonSolid = XAAFillPolygonSolid;
+ infoRec->FillPolygonSolidFlags = infoRec->SolidFillFlags;
+ }
+
+ if(!infoRec->FillPolygonStippled && (HaveMono8x8PatternFillRect ||
+ HaveScreenToScreenColorExpandFill || HaveScreenToScreenCopy)) {
+ infoRec->FillPolygonStippled = XAAFillPolygonStippled;
+ infoRec->FillPolygonStippledFlags = infoRec->SolidFillFlags;
+ }
+
+ if(!infoRec->FillPolygonOpaqueStippled && (HaveMono8x8PatternFillRect ||
+ HaveScreenToScreenColorExpandFill || HaveScreenToScreenCopy)) {
+ infoRec->FillPolygonOpaqueStippled = XAAFillPolygonStippled;
+ infoRec->FillPolygonOpaqueStippledFlags = infoRec->SolidFillFlags;
+ }
+
+ if(!infoRec->FillPolygonTiled && (HaveMono8x8PatternFillRect ||
+ HaveScreenToScreenColorExpandFill || HaveScreenToScreenCopy)) {
+ infoRec->FillPolygonTiled = XAAFillPolygonTiled;
+ infoRec->FillPolygonTiledFlags = infoRec->SolidFillFlags;
+ }
+
+
+ if(!infoRec->PolyFillArcSolid && HaveSolidFillRect) {
+ infoRec->PolyFillArcSolid = XAAPolyFillArcSolid;
+ infoRec->PolyFillArcSolidFlags = infoRec->SolidFillFlags;
+ }
+
+ if(!infoRec->PolylinesWideSolid && HaveSolidFillRect) {
+ infoRec->PolylinesWideSolid = XAAPolylinesWideSolid;
+ infoRec->PolylinesWideSolidFlags =
+ infoRec->SolidFillFlags | GXCOPY_ONLY;
+ }
+
+ if(!infoRec->PutImage && (infoRec->WritePixmap ||
+ (infoRec->WriteBitmap &&
+ !(infoRec->WriteBitmapFlags & TRANSPARENCY_ONLY)))) {
+ infoRec->PutImage = XAAPutImage;
+
+ /* See comment for CopyArea above. But here we make fewer
+ assumptions. The driver can provide the PutImageFlags if
+ it wants too */
+ }
+
+ if(HaveSolidHorVertLine &&
+ (HaveSolidBresenhamLine || (HaveSolidTwoPointLine &&
+ (infoRec->ClippingFlags & HARDWARE_CLIP_SOLID_LINE)))){
+ if(!infoRec->PolylinesThinSolid) {
+ infoRec->PolylinesThinSolid = XAAPolyLines;
+ infoRec->PolylinesThinSolidFlags = infoRec->SolidLineFlags;
+ }
+ if(!infoRec->PolySegmentThinSolid) {
+ infoRec->PolySegmentThinSolid = XAAPolySegment;
+ infoRec->PolySegmentThinSolidFlags = infoRec->SolidLineFlags;
+ }
+ }
+
+ if(HaveDashedBresenhamLine || (HaveDashedTwoPointLine &&
+ (infoRec->ClippingFlags & HARDWARE_CLIP_DASHED_LINE))){
+ if(!infoRec->PolylinesThinDashed) {
+ infoRec->PolylinesThinDashed = XAAPolyLinesDashed;
+ infoRec->PolylinesThinDashedFlags = infoRec->DashedLineFlags;
+ }
+ if(!infoRec->PolySegmentThinDashed) {
+ infoRec->PolySegmentThinDashed = XAAPolySegmentDashed;
+ infoRec->PolySegmentThinDashedFlags = infoRec->DashedLineFlags;
+ }
+ }
+
+ if(infoRec->PolylinesThinDashed || infoRec->PolySegmentThinDashed) {
+ if(!infoRec->ComputeDash)
+ infoRec->ComputeDash = XAAComputeDash;
+ }
+
+ {
+ Bool haveTexture = infoRec->CPUToScreenTextureFormats &&
+ infoRec->CPUToScreenTextureDstFormats &&
+ infoRec->SetupForCPUToScreenTexture2 &&
+ infoRec->SubsequentCPUToScreenTexture;
+ Bool haveAlphaTexture = infoRec->CPUToScreenAlphaTextureFormats &&
+ infoRec->CPUToScreenAlphaTextureDstFormats &&
+ infoRec->SetupForCPUToScreenAlphaTexture2 &&
+ infoRec->SubsequentCPUToScreenAlphaTexture;
+
+ if(!infoRec->Composite && (haveTexture || haveAlphaTexture))
+ infoRec->Composite = XAADoComposite;
+
+ if(!infoRec->Glyphs && infoRec->WriteBitmap &&
+ !(infoRec->WriteBitmapFlags & NO_TRANSPARENCY))
+ {
+ infoRec->Glyphs = XAADoGlyphs;
+ }
+ }
+
+ /************ Validation Functions **************/
+
+ if(!infoRec->ValidateCopyArea && infoRec->CopyArea) {
+ infoRec->CopyAreaMask = GCWhenForced;
+ if((infoRec->CopyAreaFlags & GXCOPY_ONLY) ||
+ (infoRec->CopyAreaFlags & ROP_NEEDS_SOURCE))
+ infoRec->CopyAreaMask |= GCFunction;
+ if(infoRec->CopyAreaFlags & NO_PLANEMASK)
+ infoRec->CopyAreaMask |= GCPlaneMask;
+ infoRec->ValidateCopyArea = XAAValidateCopyArea;
+ }
+
+ if(!infoRec->ValidateCopyPlane && infoRec->CopyPlane) {
+ infoRec->CopyPlaneMask = GCWhenForced;
+ if((infoRec->CopyPlaneFlags & GXCOPY_ONLY) ||
+ (infoRec->CopyPlaneFlags & ROP_NEEDS_SOURCE))
+ infoRec->CopyPlaneMask |= GCFunction;
+ if(infoRec->CopyPlaneFlags & NO_PLANEMASK)
+ infoRec->CopyPlaneMask |= GCPlaneMask;
+ if(infoRec->CopyPlaneFlags & RGB_EQUAL)
+ infoRec->CopyPlaneMask |= GCForeground | GCBackground;
+ infoRec->ValidateCopyPlane = XAAValidateCopyPlane;
+ }
+
+ if(!infoRec->ValidatePutImage && infoRec->PutImage) {
+ infoRec->PutImageMask = GCWhenForced;
+ if((infoRec->PutImageFlags & GXCOPY_ONLY) ||
+ (infoRec->PutImageFlags & ROP_NEEDS_SOURCE))
+ infoRec->PutImageMask |= GCFunction;
+ if(infoRec->PutImageFlags & NO_PLANEMASK)
+ infoRec->PutImageMask |= GCPlaneMask;
+ if(infoRec->PutImageFlags & RGB_EQUAL)
+ infoRec->PutImageMask |= GCForeground | GCBackground;
+ infoRec->ValidatePutImage = XAAValidatePutImage;
+ }
+
+
+ if(!infoRec->ValidatePushPixels && infoRec->PushPixelsSolid) {
+ infoRec->PushPixelsMask = GCFillStyle;
+ if((infoRec->PushPixelsFlags & GXCOPY_ONLY) ||
+ (infoRec->PushPixelsFlags & ROP_NEEDS_SOURCE) ||
+ (infoRec->PushPixelsFlags & TRANSPARENCY_GXCOPY_ONLY))
+ infoRec->PushPixelsMask |= GCFunction;
+ if(infoRec->PushPixelsFlags & NO_PLANEMASK)
+ infoRec->PushPixelsMask |= GCPlaneMask;
+ if(infoRec->PushPixelsFlags & RGB_EQUAL)
+ infoRec->PushPixelsMask |= GCForeground;
+ infoRec->ValidatePushPixels = XAAValidatePushPixels;
+ }
+
+ /* By default XAA assumes the FillSpans, PolyFillRects, FillPolygon
+ and PolyFillArcs have the same restrictions. If you supply GC
+ level replacements for any of these and alter this relationship
+ you may need to supply replacement validation routines */
+
+ if(!infoRec->ValidateFillSpans &&
+ (infoRec->FillSpansSolid || infoRec->FillSpansStippled ||
+ infoRec->FillSpansOpaqueStippled || infoRec->FillSpansTiled)) {
+
+ int compositeFlags = infoRec->FillSpansSolidFlags |
+ infoRec->FillSpansStippledFlags |
+ infoRec->FillSpansOpaqueStippledFlags |
+ infoRec->FillSpansTiledFlags;
+
+ infoRec->FillSpansMask = GCFillStyle | GCTile | GCStipple;
+
+ if((compositeFlags & GXCOPY_ONLY) ||
+ (compositeFlags & ROP_NEEDS_SOURCE))
+ infoRec->FillSpansMask |= GCFunction;
+ if(compositeFlags & NO_PLANEMASK)
+ infoRec->FillSpansMask |= GCPlaneMask;
+ if(compositeFlags & RGB_EQUAL)
+ infoRec->FillSpansMask |= GCForeground;
+ infoRec->ValidateFillSpans = XAAValidateFillSpans;
+ }
+
+ /* By default XAA only provides Validations for the GlyphBlt
+ functions and not the text higher up. This is because the
+ Text8/16 and GlyphBlt are linked. If you break this linkage,
+ you may need to have the driver supply its own Validation
+ routines */
+
+ if(!infoRec->ValidatePolyGlyphBlt &&
+ (infoRec->PolyGlyphBltTE || infoRec->PolyGlyphBltNonTE)) {
+ int compositeFlags = infoRec->PolyGlyphBltTEFlags |
+ infoRec->PolyGlyphBltNonTEFlags;
+
+ infoRec->PolyGlyphBltMask = GCFillStyle | GCFont;
+ if((compositeFlags & GXCOPY_ONLY) ||
+ (compositeFlags & ROP_NEEDS_SOURCE) ||
+ (infoRec->PolyGlyphBltNonTEFlags & TRANSPARENCY_GXCOPY_ONLY))
+ infoRec->PolyGlyphBltMask |= GCFunction;
+ if(compositeFlags & NO_PLANEMASK)
+ infoRec->PolyGlyphBltMask |= GCPlaneMask;
+ if(compositeFlags & RGB_EQUAL)
+ infoRec->PolyGlyphBltMask |= GCForeground;
+ infoRec->ValidatePolyGlyphBlt = XAAValidatePolyGlyphBlt;
+ }
+
+ if(!infoRec->ValidateImageGlyphBlt &&
+ (infoRec->ImageGlyphBltTE || infoRec->ImageGlyphBltNonTE)) {
+ int compositeFlags = infoRec->ImageGlyphBltTEFlags |
+ infoRec->ImageGlyphBltNonTEFlags;
+
+ if(infoRec->ImageGlyphBltNonTE)
+ compositeFlags |= infoRec->SolidFillFlags;
+
+ infoRec->ImageGlyphBltMask = GCFont;
+ if(compositeFlags & NO_PLANEMASK)
+ infoRec->ImageGlyphBltMask |= GCPlaneMask;
+ if(compositeFlags & RGB_EQUAL)
+ infoRec->ImageGlyphBltMask |= GCForeground | GCBackground;
+ infoRec->ValidateImageGlyphBlt = XAAValidateImageGlyphBlt;
+ }
+
+ /* By default XAA only provides a Validation function for the
+ Polylines and does segments and polylines at the same time */
+
+ if(!infoRec->ValidatePolylines && infoRec->ValidateFillSpans) {
+ int compositeFlags = infoRec->PolyRectangleThinSolidFlags |
+ infoRec->PolylinesWideSolidFlags |
+ infoRec->PolylinesThinSolidFlags |
+ infoRec->PolySegmentThinSolidFlags |
+ infoRec->PolySegmentThinDashedFlags |
+ infoRec->PolylinesThinDashedFlags;
+
+ infoRec->ValidatePolylines = XAAValidatePolylines;
+ infoRec->PolylinesMask =
+ infoRec->FillSpansMask | GCLineStyle | GCLineWidth;
+
+ if(infoRec->PolySegmentThinDashed || infoRec->PolylinesThinDashed)
+ infoRec->PolylinesMask |= GCDashList;
+ if(compositeFlags & NO_PLANEMASK)
+ infoRec->PolylinesMask |= GCPlaneMask;
+ if((compositeFlags & GXCOPY_ONLY) ||
+ (compositeFlags & ROP_NEEDS_SOURCE))
+ infoRec->PolylinesMask |= GCFunction;
+ if(compositeFlags & RGB_EQUAL)
+ infoRec->PolylinesMask |= GCForeground;
+ }
+
+
+ /**** Fill choosers ****/
+
+ if(!infoRec->StippledFillChooser)
+ infoRec->StippledFillChooser = XAAStippledFillChooser;
+
+ if(!infoRec->OpaqueStippledFillChooser)
+ infoRec->OpaqueStippledFillChooser = XAAOpaqueStippledFillChooser;
+
+ if(!infoRec->TiledFillChooser)
+ infoRec->TiledFillChooser = XAATiledFillChooser;
+
+
+ /**** Setup the pixmap cache ****/
+
+ if(infoRec->WriteBitmapToCache) {}
+ else if(infoRec->WriteBitmap &&
+ !(infoRec->WriteBitmapFlags & TRANSPARENCY_ONLY))
+ infoRec->WriteBitmapToCache = XAAWriteBitmapToCache;
+ else if(infoRec->Flags & LINEAR_FRAMEBUFFER)
+ infoRec->WriteBitmapToCache = XAAWriteBitmapToCacheLinear;
+ else
+ infoRec->PixmapCacheFlags |= DO_NOT_BLIT_STIPPLES;
+
+ if(infoRec->WritePixmapToCache) {}
+ else if(infoRec->WritePixmap && !(infoRec->WritePixmapFlags & NO_GXCOPY))
+ infoRec->WritePixmapToCache = XAAWritePixmapToCache;
+ else if(infoRec->Flags & LINEAR_FRAMEBUFFER)
+ infoRec->WritePixmapToCache = XAAWritePixmapToCacheLinear;
+ else
+ infoRec->Flags &= ~PIXMAP_CACHE;
+
+ if (xf86ReturnOptValBool(options, XAAOPT_PIXMAP_CACHE, FALSE))
+ infoRec->Flags &= ~PIXMAP_CACHE;
+
+ if(infoRec->WriteMono8x8PatternToCache) {}
+ else if(infoRec->PixmapCacheFlags & CACHE_MONO_8x8) {
+ if(infoRec->WritePixmapToCache)
+ infoRec->WriteMono8x8PatternToCache = XAAWriteMono8x8PatternToCache;
+ else
+ infoRec->PixmapCacheFlags &= ~CACHE_MONO_8x8;
+ }
+
+ if(infoRec->WriteColor8x8PatternToCache) {}
+ else if(infoRec->PixmapCacheFlags & CACHE_COLOR_8x8) {
+ if(infoRec->WritePixmapToCache && infoRec->WriteBitmapToCache)
+ infoRec->WriteColor8x8PatternToCache = XAAWriteColor8x8PatternToCache;
+ else
+ infoRec->PixmapCacheFlags &= ~CACHE_COLOR_8x8;
+ }
+
+ if(infoRec->CachePixelGranularity < 0) {
+ switch(pScrn->bitsPerPixel) {
+ case 24:
+ case 8: infoRec->CachePixelGranularity = 4; break;
+ case 16: infoRec->CachePixelGranularity = 2; break;
+ case 32: infoRec->CachePixelGranularity = 1; break;
+ default: break;
+ }
+
+ if(BITMAP_SCANLINE_PAD == 64)
+ infoRec->CachePixelGranularity *= 2;
+ }
+
+ free(options);
+
+ if(!infoRec->CacheTile && infoRec->WritePixmapToCache)
+ infoRec->CacheTile = XAACacheTile;
+ if(!infoRec->CacheMonoStipple && infoRec->WritePixmapToCache)
+ infoRec->CacheMonoStipple = XAACacheMonoStipple;
+ if(!infoRec->CacheStipple && infoRec->WriteBitmapToCache)
+ infoRec->CacheStipple = XAACacheStipple;
+ if(!infoRec->CacheMono8x8Pattern && infoRec->WriteMono8x8PatternToCache)
+ infoRec->CacheMono8x8Pattern = XAACacheMono8x8Pattern;
+ if(!infoRec->CacheColor8x8Pattern && infoRec->WriteColor8x8PatternToCache)
+ infoRec->CacheColor8x8Pattern = XAACacheColor8x8Pattern;
+
+ if((infoRec->Flags & PIXMAP_CACHE) && !infoRec->InitPixmapCache) {
+ infoRec->InitPixmapCache = XAAInitPixmapCache;
+ infoRec->ClosePixmapCache = XAAClosePixmapCache;
+ }
+
+ return TRUE;
+}
diff --git a/xorg-server/hw/xfree86/xaa/xaaLineMisc.c b/xorg-server/hw/xfree86/xaa/xaaLineMisc.c
index 6cef4bcd5..3e5330fd3 100644
--- a/xorg-server/hw/xfree86/xaa/xaaLineMisc.c
+++ b/xorg-server/hw/xfree86/xaa/xaaLineMisc.c
@@ -1,151 +1,151 @@
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "misc.h"
-#include "xf86.h"
-#include "xf86_OSproc.h"
-
-#include <X11/X.h>
-#include "scrnintstr.h"
-#include "miline.h"
-#include "xf86str.h"
-#include "xaa.h"
-#include "xaalocal.h"
-
-
-void
-XAASolidHorVertLineAsRects(
- ScrnInfoPtr pScrn,
- int x, int y, int len, int dir
-){
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
-
- if(dir == DEGREES_0)
- (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, len, 1);
- else
- (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, 1, len);
-}
-
-
-void
-XAASolidHorVertLineAsTwoPoint(
- ScrnInfoPtr pScrn,
- int x, int y, int len, int dir
-){
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
-
- len--;
-
- if(dir == DEGREES_0)
- (*infoRec->SubsequentSolidTwoPointLine)(pScrn, x, y, x + len, y, 0);
- else
- (*infoRec->SubsequentSolidTwoPointLine)(pScrn, x, y, x, y + len, 0);
-}
-
-void
-XAASolidHorVertLineAsBresenham(
- ScrnInfoPtr pScrn,
- int x, int y, int len, int dir
-){
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
-
- if(dir == DEGREES_0)
- (*infoRec->SubsequentSolidBresenhamLine)(
- pScrn, x, y, len << 1, 0, -len, len, 0);
- else
- (*infoRec->SubsequentSolidBresenhamLine)(
- pScrn, x, y, len << 1, 0, -len, len, YMAJOR);
-}
-
-
-void
-XAAComputeDash(GCPtr pGC)
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
- XAAGCPtr pGCPriv = (XAAGCPtr)dixLookupPrivate(&pGC->devPrivates,
- XAAGetGCKey());
- Bool EvenDash = (pGC->numInDashList & 0x01) ? FALSE : TRUE;
- int PatternLength = 0;
- unsigned char* DashPtr = (unsigned char*)pGC->dash;
- CARD32 *ptr;
- int count = pGC->numInDashList;
- int shift, value, direction;
- Bool set;
-
- if(pGCPriv->DashPattern)
- xfree(pGCPriv->DashPattern);
-
- pGCPriv->DashPattern = NULL;
- pGCPriv->DashLength = 0;
-
- while(count--)
- PatternLength += *(DashPtr++);
-
- if(!EvenDash)
- PatternLength <<= 1;
-
- if(PatternLength > infoRec->DashPatternMaxLength)
- return;
-
- if((infoRec->DashedLineFlags & LINE_PATTERN_POWER_OF_2_ONLY) &&
- (PatternLength & (PatternLength - 1)))
- return;
-
- pGCPriv->DashPattern = xcalloc((PatternLength + 31) >> 5, 4);
- if(!pGCPriv->DashPattern) return;
- pGCPriv->DashLength = PatternLength;
-
- if(infoRec->DashedLineFlags & (LINE_PATTERN_LSBFIRST_MSBJUSTIFIED |
- LINE_PATTERN_LSBFIRST_LSBJUSTIFIED)) {
- direction = 1;
- set = TRUE;
- DashPtr = (unsigned char*)pGC->dash;
- } else {
- direction = -1;
- set = FALSE;
- DashPtr = (unsigned char*)pGC->dash + pGC->numInDashList - 1;
- }
-
- if(infoRec->DashedLineFlags & (LINE_PATTERN_LSBFIRST_MSBJUSTIFIED |
- LINE_PATTERN_MSBFIRST_MSBJUSTIFIED))
- shift = 32 - (PatternLength & 31);
- else
- shift = 0;
-
- ptr = (CARD32*)(pGCPriv->DashPattern);
-
-CONCATENATE:
-
- count = pGC->numInDashList;
-
- while(count--) {
- value = *DashPtr;
- DashPtr += direction;
- while(value) {
- if(value < (32 - shift)) {
- if(set) *ptr |= XAAShiftMasks[value] << shift;
- shift += value;
- break;
- } else {
- if(set) *ptr |= ~0L << shift;
- value -= (32 - shift);
- shift = 0;
- ptr++;
- }
- }
- if(set) set = FALSE;
- else set = TRUE;
- }
-
- if(!EvenDash) {
- EvenDash = TRUE;
- if(infoRec->DashedLineFlags & (LINE_PATTERN_LSBFIRST_MSBJUSTIFIED |
- LINE_PATTERN_LSBFIRST_LSBJUSTIFIED))
- DashPtr = (unsigned char*)pGC->dash;
- else
- DashPtr = (unsigned char*)pGC->dash + pGC->numInDashList;
- goto CONCATENATE;
- }
-}
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include <X11/X.h>
+#include "scrnintstr.h"
+#include "miline.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+
+
+void
+XAASolidHorVertLineAsRects(
+ ScrnInfoPtr pScrn,
+ int x, int y, int len, int dir
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ if(dir == DEGREES_0)
+ (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, len, 1);
+ else
+ (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, 1, len);
+}
+
+
+void
+XAASolidHorVertLineAsTwoPoint(
+ ScrnInfoPtr pScrn,
+ int x, int y, int len, int dir
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ len--;
+
+ if(dir == DEGREES_0)
+ (*infoRec->SubsequentSolidTwoPointLine)(pScrn, x, y, x + len, y, 0);
+ else
+ (*infoRec->SubsequentSolidTwoPointLine)(pScrn, x, y, x, y + len, 0);
+}
+
+void
+XAASolidHorVertLineAsBresenham(
+ ScrnInfoPtr pScrn,
+ int x, int y, int len, int dir
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ if(dir == DEGREES_0)
+ (*infoRec->SubsequentSolidBresenhamLine)(
+ pScrn, x, y, len << 1, 0, -len, len, 0);
+ else
+ (*infoRec->SubsequentSolidBresenhamLine)(
+ pScrn, x, y, len << 1, 0, -len, len, YMAJOR);
+}
+
+
+void
+XAAComputeDash(GCPtr pGC)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ XAAGCPtr pGCPriv = (XAAGCPtr)dixLookupPrivate(&pGC->devPrivates,
+ XAAGetGCKey());
+ Bool EvenDash = (pGC->numInDashList & 0x01) ? FALSE : TRUE;
+ int PatternLength = 0;
+ unsigned char* DashPtr = (unsigned char*)pGC->dash;
+ CARD32 *ptr;
+ int count = pGC->numInDashList;
+ int shift, value, direction;
+ Bool set;
+
+ if(pGCPriv->DashPattern)
+ free(pGCPriv->DashPattern);
+
+ pGCPriv->DashPattern = NULL;
+ pGCPriv->DashLength = 0;
+
+ while(count--)
+ PatternLength += *(DashPtr++);
+
+ if(!EvenDash)
+ PatternLength <<= 1;
+
+ if(PatternLength > infoRec->DashPatternMaxLength)
+ return;
+
+ if((infoRec->DashedLineFlags & LINE_PATTERN_POWER_OF_2_ONLY) &&
+ (PatternLength & (PatternLength - 1)))
+ return;
+
+ pGCPriv->DashPattern = calloc((PatternLength + 31) >> 5, 4);
+ if(!pGCPriv->DashPattern) return;
+ pGCPriv->DashLength = PatternLength;
+
+ if(infoRec->DashedLineFlags & (LINE_PATTERN_LSBFIRST_MSBJUSTIFIED |
+ LINE_PATTERN_LSBFIRST_LSBJUSTIFIED)) {
+ direction = 1;
+ set = TRUE;
+ DashPtr = (unsigned char*)pGC->dash;
+ } else {
+ direction = -1;
+ set = FALSE;
+ DashPtr = (unsigned char*)pGC->dash + pGC->numInDashList - 1;
+ }
+
+ if(infoRec->DashedLineFlags & (LINE_PATTERN_LSBFIRST_MSBJUSTIFIED |
+ LINE_PATTERN_MSBFIRST_MSBJUSTIFIED))
+ shift = 32 - (PatternLength & 31);
+ else
+ shift = 0;
+
+ ptr = (CARD32*)(pGCPriv->DashPattern);
+
+CONCATENATE:
+
+ count = pGC->numInDashList;
+
+ while(count--) {
+ value = *DashPtr;
+ DashPtr += direction;
+ while(value) {
+ if(value < (32 - shift)) {
+ if(set) *ptr |= XAAShiftMasks[value] << shift;
+ shift += value;
+ break;
+ } else {
+ if(set) *ptr |= ~0L << shift;
+ value -= (32 - shift);
+ shift = 0;
+ ptr++;
+ }
+ }
+ if(set) set = FALSE;
+ else set = TRUE;
+ }
+
+ if(!EvenDash) {
+ EvenDash = TRUE;
+ if(infoRec->DashedLineFlags & (LINE_PATTERN_LSBFIRST_MSBJUSTIFIED |
+ LINE_PATTERN_LSBFIRST_LSBJUSTIFIED))
+ DashPtr = (unsigned char*)pGC->dash;
+ else
+ DashPtr = (unsigned char*)pGC->dash + pGC->numInDashList;
+ goto CONCATENATE;
+ }
+}
diff --git a/xorg-server/hw/xfree86/xaa/xaaNonTEText.c b/xorg-server/hw/xfree86/xaa/xaaNonTEText.c
index d32c0bbc5..eb798a82b 100644
--- a/xorg-server/hw/xfree86/xaa/xaaNonTEText.c
+++ b/xorg-server/hw/xfree86/xaa/xaaNonTEText.c
@@ -1,591 +1,591 @@
-
-/********************************************************************
-
- In this file we have GC level replacements for PolyText8/16,
- ImageText8/16, ImageGlyphBlt and PolyGlyphBlt for NonTE (proportional)
- fonts. The idea is that everything in this file is device independent.
- The mentioned GCOps are merely wrappers for the
- PolyGlyphBltNonTEColorExpansion and ImageGlyphBltNonTEColorExpansion
- functions which calculate the boxes containing arbitrarily clipped
- text and passes them to the NonTEGlyphRenderer which will usually
- be a lower level XAA function which renders these clipped glyphs using
- the basic color expansion functions exported by the chipset driver.
- The NonTEGlyphRenderer itself may optionally be driver supplied to
- facilitate work-arounds/optimizations at a higher level than usual.
-
- Written by Mark Vojkovich (mvojkovi@ucsd.edu)
-
-********************************************************************/
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <string.h>
-
-#include "misc.h"
-#include "xf86.h"
-#include "xf86_OSproc.h"
-
-#include <X11/X.h>
-#include <X11/fonts/font.h>
-#include "scrnintstr.h"
-#include "dixfontstr.h"
-#include "xf86str.h"
-#include "xaa.h"
-#include "xaacexp.h"
-#include "xaalocal.h"
-#include "gcstruct.h"
-#include "pixmapstr.h"
-
-
-static void ImageGlyphBltNonTEColorExpansion(ScrnInfoPtr pScrn,
- int xInit, int yInit, FontPtr font,
- int fg, int bg, unsigned planemask,
- RegionPtr cclip, int nglyph,
- unsigned char* gBase, CharInfoPtr *ppci);
-static int PolyGlyphBltNonTEColorExpansion(ScrnInfoPtr pScrn,
- int xInit, int yInit, FontPtr font,
- int fg, int rop, unsigned planemask,
- RegionPtr cclip, int nglyph,
- unsigned char* gBase, CharInfoPtr *ppci);
-
-/********************************************************************
-
- GC level replacements for PolyText8/16 and ImageText8/16
- for NonTE fonts when using color expansion.
-
-********************************************************************/
-
-
-int
-XAAPolyText8NonTEColorExpansion(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x,
- int y,
- int count,
- char *chars )
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
- unsigned long n;
- int width = 0;
-
- (*pGC->font->get_glyphs)(pGC->font, (unsigned long)count,
- (unsigned char *)chars, Linear8Bit, &n, infoRec->CharInfo);
-
- if(n) {
- width = PolyGlyphBltNonTEColorExpansion( infoRec->pScrn,
- x + pDraw->x, y + pDraw->y, pGC->font,
- pGC->fgPixel, pGC->alu, pGC->planemask,
- pGC->pCompositeClip, n, FONTGLYPHS(pGC->font),
- infoRec->CharInfo);
- }
-
- return (x + width);
-}
-
-
-int
-XAAPolyText16NonTEColorExpansion(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x,
- int y,
- int count,
- unsigned short *chars )
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
- unsigned long n;
- int width = 0;
-
- (*pGC->font->get_glyphs)(
- pGC->font, (unsigned long)count, (unsigned char *)chars,
- (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
- &n, infoRec->CharInfo);
-
- if(n) {
- width = PolyGlyphBltNonTEColorExpansion( infoRec->pScrn,
- x + pDraw->x, y + pDraw->y, pGC->font,
- pGC->fgPixel, pGC->alu, pGC->planemask,
- pGC->pCompositeClip, n, FONTGLYPHS(pGC->font),
- infoRec->CharInfo);
- }
-
- return (x + width);
-}
-
-
-void
-XAAImageText8NonTEColorExpansion(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x,
- int y,
- int count,
- char *chars
-){
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
- unsigned long n;
-
- if(!REGION_NUM_RECTS(pGC->pCompositeClip))
- return;
-
- (*pGC->font->get_glyphs)(pGC->font, (unsigned long)count,
- (unsigned char *)chars, Linear8Bit, &n, infoRec->CharInfo);
-
- if(n) ImageGlyphBltNonTEColorExpansion(
- infoRec->pScrn, x + pDraw->x, y + pDraw->y,
- pGC->font, pGC->fgPixel, pGC->bgPixel, pGC->planemask,
- pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
-}
-
-
-void
-XAAImageText16NonTEColorExpansion(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x,
- int y,
- int count,
- unsigned short *chars
-){
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
- unsigned long n;
-
- if(!REGION_NUM_RECTS(pGC->pCompositeClip))
- return;
-
- (*pGC->font->get_glyphs)(
- pGC->font, (unsigned long)count, (unsigned char *)chars,
- (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
- &n, infoRec->CharInfo);
-
- if(n) ImageGlyphBltNonTEColorExpansion(
- infoRec->pScrn, x + pDraw->x, y + pDraw->y,
- pGC->font, pGC->fgPixel, pGC->bgPixel, pGC->planemask,
- pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
-}
-
-
-
-/********************************************************************
-
- GC level replacements for ImageGlyphBlt and PolyGlyphBlt for
- NonTE fonts when using color expansion.
-
-********************************************************************/
-
-
-void
-XAAImageGlyphBltNonTEColorExpansion(
- DrawablePtr pDraw,
- GCPtr pGC,
- int xInit, int yInit,
- unsigned int nglyph,
- CharInfoPtr *ppci, /* array of character info */
- pointer pglyphBase /* start of array of glyphs */
-){
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
-
- if(!REGION_NUM_RECTS(pGC->pCompositeClip))
- return;
-
- ImageGlyphBltNonTEColorExpansion(
- infoRec->pScrn, xInit + pDraw->x, yInit + pDraw->y,
- pGC->font, pGC->fgPixel, pGC->bgPixel, pGC->planemask,
- pGC->pCompositeClip, nglyph, (unsigned char*)pglyphBase, ppci);
-}
-
-void
-XAAPolyGlyphBltNonTEColorExpansion(
- DrawablePtr pDraw,
- GCPtr pGC,
- int xInit, int yInit,
- unsigned int nglyph,
- CharInfoPtr *ppci, /* array of character info */
- pointer pglyphBase /* start of array of glyphs */
-){
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
-
- if(!REGION_NUM_RECTS(pGC->pCompositeClip))
- return;
-
- PolyGlyphBltNonTEColorExpansion(
- infoRec->pScrn, xInit + pDraw->x, yInit + pDraw->y,
- pGC->font, pGC->fgPixel, pGC->alu, pGC->planemask,
- pGC->pCompositeClip, nglyph, (unsigned char*)pglyphBase, ppci);
-}
-
-
-
-
-/********************************************************************
-
- ImageGlyphBltNonTEColorExpansion -
- PolyGlyphBltNonTEColorExpansion -
-
- These guys compute the clipped pieces of text and send it to
- the lower-level function which will handle acceleration of
- arbitrarily clipped text.
-
-********************************************************************/
-
-
-
-static int
-CollectCharacterInfo(
- NonTEGlyphPtr glyphs,
- unsigned int nglyph,
- CharInfoPtr *ppci,
- FontPtr pfont
-){
- int i, w = 0;
-
- for(i = 0; i < nglyph; i++, ppci++, glyphs++) {
- glyphs->bits = (unsigned char*)((*ppci)->bits);
- glyphs->start = w + (*ppci)->metrics.leftSideBearing;
- glyphs->end = w + (*ppci)->metrics.rightSideBearing;
- glyphs->yoff = (*ppci)->metrics.ascent;
- glyphs->height = glyphs->yoff + (*ppci)->metrics.descent;
- glyphs->srcwidth = PADGLYPHWIDTHBYTES(glyphs->end - glyphs->start);
- w += (*ppci)->metrics.characterWidth;
- }
- return w;
-}
-
-
-static void
-PolyGlyphBltAsSingleBitmap (
- ScrnInfoPtr pScrn,
- int nglyph,
- FontPtr font,
- int xInit,
- int yInit,
- int nbox,
- BoxPtr pbox,
- int fg,
- int rop,
- unsigned planemask
-){
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
- CARD32 *block, *pntr, *bits;
- int pitch, topLine, botLine, top, bot, height;
- int Left, Right, Top, Bottom;
- int LeftEdge, RightEdge;
- int bitPitch, shift, size, i, skippix;
- NonTEGlyphPtr glyphs = infoRec->GlyphInfo;
- Bool extra;
-
- Left = xInit + infoRec->GlyphInfo[0].start;
- Right = xInit + infoRec->GlyphInfo[nglyph - 1].end;
- Top = yInit - FONTMAXBOUNDS(font,ascent);
- Bottom = yInit + FONTMAXBOUNDS(font,descent);
-
- /* get into the first band that may contain part of our string */
- while(nbox && (Top >= pbox->y2)) {
- pbox++; nbox--;
- }
-
- if(!nbox) return;
-
- pitch = (Right - Left + 31) >> 5;
- size = (pitch << 2) * (Bottom - Top);
- block = xcalloc(1, size);
-
- topLine = 10000; botLine = -10000;
-
- while(nglyph--) {
- top = -glyphs->yoff;
- bot = top + glyphs->height;
- if(top < topLine) topLine = top;
- if(bot > botLine) botLine = bot;
- skippix = glyphs->start - infoRec->GlyphInfo[0].start;
- bits = (CARD32*)glyphs->bits;
- bitPitch = glyphs->srcwidth >> 2;
- pntr = block + ((FONTMAXBOUNDS(font,ascent) + top) * pitch) +
- (skippix >> 5);
- shift = skippix & 31;
- extra = ((shift + glyphs->end - glyphs->start) > 32);
-
- for(i = top; i < bot; i++) {
- *pntr |= SHIFT_L(*bits, shift);
- if(extra)
- *(pntr + 1) |= SHIFT_R(*bits,32 - shift);
- pntr += pitch;
- bits += bitPitch;
- }
-
- glyphs++;
- }
-
- pntr = block + ((FONTMAXBOUNDS(font,ascent) + topLine) * pitch);
-
- Top = yInit + topLine;
- Bottom = yInit + botLine;
-
- while(nbox && (Top >= pbox->y2)) {
- pbox++; nbox--;
- }
-
- while(nbox && (Bottom > pbox->y1)) {
- LeftEdge = max(Left, pbox->x1);
- RightEdge = min(Right, pbox->x2);
-
- if(RightEdge > LeftEdge) {
- skippix = LeftEdge - Left;
- topLine = max(Top, pbox->y1);
- botLine = min(Bottom, pbox->y2);
- height = botLine - topLine;
-
- if(height > 0)
- (*infoRec->WriteBitmap)(pScrn, LeftEdge, topLine,
- RightEdge - LeftEdge, height,
- (unsigned char*)(pntr + ((topLine - Top) * pitch) +
- (skippix >> 5)),
- pitch << 2, skippix & 31, fg, -1, rop, planemask);
- }
-
- nbox--; pbox++;
- }
-
- xfree(block);
-}
-
-static void
-ImageGlyphBltNonTEColorExpansion(
- ScrnInfoPtr pScrn,
- int xInit, int yInit,
- FontPtr font,
- int fg, int bg,
- unsigned planemask,
- RegionPtr cclip,
- int nglyph,
- unsigned char* gBase,
- CharInfoPtr *ppci
-){
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
- int skippix, skipglyph, width, n, i;
- int Left, Right, Top, Bottom;
- int LeftEdge, RightEdge, ytop, ybot;
- int nbox = REGION_NUM_RECTS(cclip);
- BoxPtr pbox = REGION_RECTS(cclip);
- Bool AlreadySetup = FALSE;
-
- width = CollectCharacterInfo(infoRec->GlyphInfo, nglyph, ppci, font);
-
- /* find our backing rectangle dimensions */
- Left = xInit;
- Right = Left + width;
- Top = yInit - FONTASCENT(font);
- Bottom = yInit + FONTDESCENT(font);
-
- /* get into the first band that may contain part of our box */
- while(nbox && (Top >= pbox->y2)) {
- pbox++; nbox--;
- }
-
- while(nbox && (Bottom >= pbox->y1)) {
- /* handle backing rect first */
- LeftEdge = max(Left, pbox->x1);
- RightEdge = min(Right, pbox->x2);
- if(RightEdge > LeftEdge) {
- ytop = max(Top, pbox->y1);
- ybot = min(Bottom, pbox->y2);
-
- if(ybot > ytop) {
- if(!AlreadySetup) {
- (*infoRec->SetupForSolidFill)(pScrn, bg, GXcopy, planemask);
- AlreadySetup = TRUE;
- }
- (*infoRec->SubsequentSolidFillRect)(pScrn,
- LeftEdge, ytop, RightEdge - LeftEdge, ybot - ytop);
- }
- }
- nbox--; pbox++;
- }
-
- nbox = REGION_NUM_RECTS(cclip);
- pbox = REGION_RECTS(cclip);
-
- if(infoRec->WriteBitmap && (nglyph > 1) &&
- ((FONTMAXBOUNDS(font, rightSideBearing) -
- FONTMINBOUNDS(font, leftSideBearing)) <= 32))
- {
- PolyGlyphBltAsSingleBitmap(pScrn, nglyph, font,
- xInit, yInit, nbox, pbox,
- fg, GXcopy, planemask);
-
- return;
- }
-
- /* compute an approximate but covering bounding box */
- Left = xInit + infoRec->GlyphInfo[0].start;
- Right = xInit + infoRec->GlyphInfo[nglyph - 1].end;
- Top = yInit - FONTMAXBOUNDS(font,ascent);
- Bottom = yInit + FONTMAXBOUNDS(font,descent);
-
- /* get into the first band that may contain part of our box */
- while(nbox && (Top >= pbox->y2)) {
- pbox++; nbox--;
- }
-
- /* stop when the lower edge of the box is beyond our string */
- while(nbox && (Bottom >= pbox->y1)) {
- LeftEdge = max(Left, pbox->x1);
- RightEdge = min(Right, pbox->x2);
-
- if(RightEdge > LeftEdge) { /* we're possibly drawing something */
- ytop = max(Top, pbox->y1);
- ybot = min(Bottom, pbox->y2);
- if(ybot > ytop) {
- skippix = LeftEdge - xInit;
- skipglyph = 0;
- while(skippix >= infoRec->GlyphInfo[skipglyph].end)
- skipglyph++;
-
- skippix = RightEdge - xInit;
- n = 0; i = skipglyph;
- while((i < nglyph) && (skippix > infoRec->GlyphInfo[i].start)) {
- i++; n++;
- }
-
- if(n) (*infoRec->NonTEGlyphRenderer)(pScrn,
- xInit, yInit, n, infoRec->GlyphInfo + skipglyph,
- pbox, fg, GXcopy, planemask);
- }
- }
-
- nbox--; pbox++;
- }
-}
-
-
-static int
-PolyGlyphBltNonTEColorExpansion(
- ScrnInfoPtr pScrn,
- int xInit, int yInit,
- FontPtr font,
- int fg, int rop,
- unsigned planemask,
- RegionPtr cclip,
- int nglyph,
- unsigned char* gBase,
- CharInfoPtr *ppci
-){
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
- int skippix, skipglyph, width, n, i;
- int Left, Right, Top, Bottom;
- int LeftEdge, RightEdge;
- int nbox = REGION_NUM_RECTS(cclip);
- BoxPtr pbox = REGION_RECTS(cclip);
-
- width = CollectCharacterInfo(infoRec->GlyphInfo, nglyph, ppci, font);
-
- if(!nbox)
- return width;
-
- if((infoRec->WriteBitmap) && (rop == GXcopy) && (nglyph > 1) &&
- ((FONTMAXBOUNDS(font, rightSideBearing) -
- FONTMINBOUNDS(font, leftSideBearing)) <= 32)) {
-
- PolyGlyphBltAsSingleBitmap(pScrn, nglyph, font,
- xInit, yInit, nbox, pbox,
- fg, rop, planemask);
-
- return width;
- }
-
- /* compute an approximate but covering bounding box */
- Left = xInit + infoRec->GlyphInfo[0].start;
- Right = xInit + infoRec->GlyphInfo[nglyph - 1].end;
- Top = yInit - FONTMAXBOUNDS(font,ascent);
- Bottom = yInit + FONTMAXBOUNDS(font,descent);
-
- /* get into the first band that may contain part of our string */
- while(nbox && (Top >= pbox->y2)) {
- pbox++; nbox--;
- }
-
- /* stop when the lower edge of the box is beyond our string */
- while(nbox && (Bottom >= pbox->y1)) {
- LeftEdge = max(Left, pbox->x1);
- RightEdge = min(Right, pbox->x2);
-
- if(RightEdge > LeftEdge) { /* we're possibly drawing something */
-
- skippix = LeftEdge - xInit;
- skipglyph = 0;
- while(skippix >= infoRec->GlyphInfo[skipglyph].end)
- skipglyph++;
-
- skippix = RightEdge - xInit;
- n = 0; i = skipglyph;
- while((i < nglyph) && (skippix > infoRec->GlyphInfo[i].start)) {
- i++; n++;
- }
-
- if(n) (*infoRec->NonTEGlyphRenderer)(pScrn,
- xInit, yInit, n, infoRec->GlyphInfo + skipglyph,
- pbox, fg, rop, planemask);
- }
-
- nbox--; pbox++;
- }
- return width;
-}
-
-
-/* It is possible that the none of the glyphs passed to the
- NonTEGlyphRenderer will be drawn. This function being called
- indicates that part of the text string's bounding box is visible
- but not necessarily that any of the characters are visible */
-
-void XAANonTEGlyphRenderer(
- ScrnInfoPtr pScrn,
- int x, int y, int n,
- NonTEGlyphPtr glyphs,
- BoxPtr pbox,
- int fg, int rop,
- unsigned int planemask
-){
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
- int x1, x2, y1, y2, i, w, h, skipleft, skiptop;
- unsigned char *src;
-
- for(i = 0; i < n; i++, glyphs++) {
- x1 = x + glyphs->start;
- x2 = x + glyphs->end;
- y1 = y - glyphs->yoff;
- y2 = y1 + glyphs->height;
-
- if(y1 < pbox->y1) {
- skiptop = pbox->y1 - y1;
- y1 = pbox->y1;
- } else skiptop = 0;
- if(y2 > pbox->y2) y2 = pbox->y2;
- h = y2 - y1;
- if(h <= 0) continue;
-
- if(x1 < pbox->x1) {
- skipleft = pbox->x1 - x1;
- x1 = pbox->x1;
- } else skipleft = 0;
- if(x2 > pbox->x2) x2 = pbox->x2;
-
- w = x2 - x1;
-
- if(w > 0) {
- src = glyphs->bits + (skiptop * glyphs->srcwidth);
-
- if(skipleft) {
- src += (skipleft >> 5) << 2;
- skipleft &= 31;
- }
-
- (*infoRec->WriteBitmap)(pScrn, x1, y1, w, h, src,
- glyphs->srcwidth, skipleft, fg, -1, rop, planemask);
- }
- }
-
-}
+
+/********************************************************************
+
+ In this file we have GC level replacements for PolyText8/16,
+ ImageText8/16, ImageGlyphBlt and PolyGlyphBlt for NonTE (proportional)
+ fonts. The idea is that everything in this file is device independent.
+ The mentioned GCOps are merely wrappers for the
+ PolyGlyphBltNonTEColorExpansion and ImageGlyphBltNonTEColorExpansion
+ functions which calculate the boxes containing arbitrarily clipped
+ text and passes them to the NonTEGlyphRenderer which will usually
+ be a lower level XAA function which renders these clipped glyphs using
+ the basic color expansion functions exported by the chipset driver.
+ The NonTEGlyphRenderer itself may optionally be driver supplied to
+ facilitate work-arounds/optimizations at a higher level than usual.
+
+ Written by Mark Vojkovich (mvojkovi@ucsd.edu)
+
+********************************************************************/
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <string.h>
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include <X11/X.h>
+#include <X11/fonts/font.h>
+#include "scrnintstr.h"
+#include "dixfontstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaacexp.h"
+#include "xaalocal.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+
+
+static void ImageGlyphBltNonTEColorExpansion(ScrnInfoPtr pScrn,
+ int xInit, int yInit, FontPtr font,
+ int fg, int bg, unsigned planemask,
+ RegionPtr cclip, int nglyph,
+ unsigned char* gBase, CharInfoPtr *ppci);
+static int PolyGlyphBltNonTEColorExpansion(ScrnInfoPtr pScrn,
+ int xInit, int yInit, FontPtr font,
+ int fg, int rop, unsigned planemask,
+ RegionPtr cclip, int nglyph,
+ unsigned char* gBase, CharInfoPtr *ppci);
+
+/********************************************************************
+
+ GC level replacements for PolyText8/16 and ImageText8/16
+ for NonTE fonts when using color expansion.
+
+********************************************************************/
+
+
+int
+XAAPolyText8NonTEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ unsigned long n;
+ int width = 0;
+
+ (*pGC->font->get_glyphs)(pGC->font, (unsigned long)count,
+ (unsigned char *)chars, Linear8Bit, &n, infoRec->CharInfo);
+
+ if(n) {
+ width = PolyGlyphBltNonTEColorExpansion( infoRec->pScrn,
+ x + pDraw->x, y + pDraw->y, pGC->font,
+ pGC->fgPixel, pGC->alu, pGC->planemask,
+ pGC->pCompositeClip, n, FONTGLYPHS(pGC->font),
+ infoRec->CharInfo);
+ }
+
+ return (x + width);
+}
+
+
+int
+XAAPolyText16NonTEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ unsigned long n;
+ int width = 0;
+
+ (*pGC->font->get_glyphs)(
+ pGC->font, (unsigned long)count, (unsigned char *)chars,
+ (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
+ &n, infoRec->CharInfo);
+
+ if(n) {
+ width = PolyGlyphBltNonTEColorExpansion( infoRec->pScrn,
+ x + pDraw->x, y + pDraw->y, pGC->font,
+ pGC->fgPixel, pGC->alu, pGC->planemask,
+ pGC->pCompositeClip, n, FONTGLYPHS(pGC->font),
+ infoRec->CharInfo);
+ }
+
+ return (x + width);
+}
+
+
+void
+XAAImageText8NonTEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ char *chars
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ unsigned long n;
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ (*pGC->font->get_glyphs)(pGC->font, (unsigned long)count,
+ (unsigned char *)chars, Linear8Bit, &n, infoRec->CharInfo);
+
+ if(n) ImageGlyphBltNonTEColorExpansion(
+ infoRec->pScrn, x + pDraw->x, y + pDraw->y,
+ pGC->font, pGC->fgPixel, pGC->bgPixel, pGC->planemask,
+ pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
+}
+
+
+void
+XAAImageText16NonTEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x,
+ int y,
+ int count,
+ unsigned short *chars
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ unsigned long n;
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ (*pGC->font->get_glyphs)(
+ pGC->font, (unsigned long)count, (unsigned char *)chars,
+ (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
+ &n, infoRec->CharInfo);
+
+ if(n) ImageGlyphBltNonTEColorExpansion(
+ infoRec->pScrn, x + pDraw->x, y + pDraw->y,
+ pGC->font, pGC->fgPixel, pGC->bgPixel, pGC->planemask,
+ pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
+}
+
+
+
+/********************************************************************
+
+ GC level replacements for ImageGlyphBlt and PolyGlyphBlt for
+ NonTE fonts when using color expansion.
+
+********************************************************************/
+
+
+void
+XAAImageGlyphBltNonTEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci, /* array of character info */
+ pointer pglyphBase /* start of array of glyphs */
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ ImageGlyphBltNonTEColorExpansion(
+ infoRec->pScrn, xInit + pDraw->x, yInit + pDraw->y,
+ pGC->font, pGC->fgPixel, pGC->bgPixel, pGC->planemask,
+ pGC->pCompositeClip, nglyph, (unsigned char*)pglyphBase, ppci);
+}
+
+void
+XAAPolyGlyphBltNonTEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci, /* array of character info */
+ pointer pglyphBase /* start of array of glyphs */
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ PolyGlyphBltNonTEColorExpansion(
+ infoRec->pScrn, xInit + pDraw->x, yInit + pDraw->y,
+ pGC->font, pGC->fgPixel, pGC->alu, pGC->planemask,
+ pGC->pCompositeClip, nglyph, (unsigned char*)pglyphBase, ppci);
+}
+
+
+
+
+/********************************************************************
+
+ ImageGlyphBltNonTEColorExpansion -
+ PolyGlyphBltNonTEColorExpansion -
+
+ These guys compute the clipped pieces of text and send it to
+ the lower-level function which will handle acceleration of
+ arbitrarily clipped text.
+
+********************************************************************/
+
+
+
+static int
+CollectCharacterInfo(
+ NonTEGlyphPtr glyphs,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ FontPtr pfont
+){
+ int i, w = 0;
+
+ for(i = 0; i < nglyph; i++, ppci++, glyphs++) {
+ glyphs->bits = (unsigned char*)((*ppci)->bits);
+ glyphs->start = w + (*ppci)->metrics.leftSideBearing;
+ glyphs->end = w + (*ppci)->metrics.rightSideBearing;
+ glyphs->yoff = (*ppci)->metrics.ascent;
+ glyphs->height = glyphs->yoff + (*ppci)->metrics.descent;
+ glyphs->srcwidth = PADGLYPHWIDTHBYTES(glyphs->end - glyphs->start);
+ w += (*ppci)->metrics.characterWidth;
+ }
+ return w;
+}
+
+
+static void
+PolyGlyphBltAsSingleBitmap (
+ ScrnInfoPtr pScrn,
+ int nglyph,
+ FontPtr font,
+ int xInit,
+ int yInit,
+ int nbox,
+ BoxPtr pbox,
+ int fg,
+ int rop,
+ unsigned planemask
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ CARD32 *block, *pntr, *bits;
+ int pitch, topLine, botLine, top, bot, height;
+ int Left, Right, Top, Bottom;
+ int LeftEdge, RightEdge;
+ int bitPitch, shift, size, i, skippix;
+ NonTEGlyphPtr glyphs = infoRec->GlyphInfo;
+ Bool extra;
+
+ Left = xInit + infoRec->GlyphInfo[0].start;
+ Right = xInit + infoRec->GlyphInfo[nglyph - 1].end;
+ Top = yInit - FONTMAXBOUNDS(font,ascent);
+ Bottom = yInit + FONTMAXBOUNDS(font,descent);
+
+ /* get into the first band that may contain part of our string */
+ while(nbox && (Top >= pbox->y2)) {
+ pbox++; nbox--;
+ }
+
+ if(!nbox) return;
+
+ pitch = (Right - Left + 31) >> 5;
+ size = (pitch << 2) * (Bottom - Top);
+ block = calloc(1, size);
+
+ topLine = 10000; botLine = -10000;
+
+ while(nglyph--) {
+ top = -glyphs->yoff;
+ bot = top + glyphs->height;
+ if(top < topLine) topLine = top;
+ if(bot > botLine) botLine = bot;
+ skippix = glyphs->start - infoRec->GlyphInfo[0].start;
+ bits = (CARD32*)glyphs->bits;
+ bitPitch = glyphs->srcwidth >> 2;
+ pntr = block + ((FONTMAXBOUNDS(font,ascent) + top) * pitch) +
+ (skippix >> 5);
+ shift = skippix & 31;
+ extra = ((shift + glyphs->end - glyphs->start) > 32);
+
+ for(i = top; i < bot; i++) {
+ *pntr |= SHIFT_L(*bits, shift);
+ if(extra)
+ *(pntr + 1) |= SHIFT_R(*bits,32 - shift);
+ pntr += pitch;
+ bits += bitPitch;
+ }
+
+ glyphs++;
+ }
+
+ pntr = block + ((FONTMAXBOUNDS(font,ascent) + topLine) * pitch);
+
+ Top = yInit + topLine;
+ Bottom = yInit + botLine;
+
+ while(nbox && (Top >= pbox->y2)) {
+ pbox++; nbox--;
+ }
+
+ while(nbox && (Bottom > pbox->y1)) {
+ LeftEdge = max(Left, pbox->x1);
+ RightEdge = min(Right, pbox->x2);
+
+ if(RightEdge > LeftEdge) {
+ skippix = LeftEdge - Left;
+ topLine = max(Top, pbox->y1);
+ botLine = min(Bottom, pbox->y2);
+ height = botLine - topLine;
+
+ if(height > 0)
+ (*infoRec->WriteBitmap)(pScrn, LeftEdge, topLine,
+ RightEdge - LeftEdge, height,
+ (unsigned char*)(pntr + ((topLine - Top) * pitch) +
+ (skippix >> 5)),
+ pitch << 2, skippix & 31, fg, -1, rop, planemask);
+ }
+
+ nbox--; pbox++;
+ }
+
+ free(block);
+}
+
+static void
+ImageGlyphBltNonTEColorExpansion(
+ ScrnInfoPtr pScrn,
+ int xInit, int yInit,
+ FontPtr font,
+ int fg, int bg,
+ unsigned planemask,
+ RegionPtr cclip,
+ int nglyph,
+ unsigned char* gBase,
+ CharInfoPtr *ppci
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int skippix, skipglyph, width, n, i;
+ int Left, Right, Top, Bottom;
+ int LeftEdge, RightEdge, ytop, ybot;
+ int nbox = REGION_NUM_RECTS(cclip);
+ BoxPtr pbox = REGION_RECTS(cclip);
+ Bool AlreadySetup = FALSE;
+
+ width = CollectCharacterInfo(infoRec->GlyphInfo, nglyph, ppci, font);
+
+ /* find our backing rectangle dimensions */
+ Left = xInit;
+ Right = Left + width;
+ Top = yInit - FONTASCENT(font);
+ Bottom = yInit + FONTDESCENT(font);
+
+ /* get into the first band that may contain part of our box */
+ while(nbox && (Top >= pbox->y2)) {
+ pbox++; nbox--;
+ }
+
+ while(nbox && (Bottom >= pbox->y1)) {
+ /* handle backing rect first */
+ LeftEdge = max(Left, pbox->x1);
+ RightEdge = min(Right, pbox->x2);
+ if(RightEdge > LeftEdge) {
+ ytop = max(Top, pbox->y1);
+ ybot = min(Bottom, pbox->y2);
+
+ if(ybot > ytop) {
+ if(!AlreadySetup) {
+ (*infoRec->SetupForSolidFill)(pScrn, bg, GXcopy, planemask);
+ AlreadySetup = TRUE;
+ }
+ (*infoRec->SubsequentSolidFillRect)(pScrn,
+ LeftEdge, ytop, RightEdge - LeftEdge, ybot - ytop);
+ }
+ }
+ nbox--; pbox++;
+ }
+
+ nbox = REGION_NUM_RECTS(cclip);
+ pbox = REGION_RECTS(cclip);
+
+ if(infoRec->WriteBitmap && (nglyph > 1) &&
+ ((FONTMAXBOUNDS(font, rightSideBearing) -
+ FONTMINBOUNDS(font, leftSideBearing)) <= 32))
+ {
+ PolyGlyphBltAsSingleBitmap(pScrn, nglyph, font,
+ xInit, yInit, nbox, pbox,
+ fg, GXcopy, planemask);
+
+ return;
+ }
+
+ /* compute an approximate but covering bounding box */
+ Left = xInit + infoRec->GlyphInfo[0].start;
+ Right = xInit + infoRec->GlyphInfo[nglyph - 1].end;
+ Top = yInit - FONTMAXBOUNDS(font,ascent);
+ Bottom = yInit + FONTMAXBOUNDS(font,descent);
+
+ /* get into the first band that may contain part of our box */
+ while(nbox && (Top >= pbox->y2)) {
+ pbox++; nbox--;
+ }
+
+ /* stop when the lower edge of the box is beyond our string */
+ while(nbox && (Bottom >= pbox->y1)) {
+ LeftEdge = max(Left, pbox->x1);
+ RightEdge = min(Right, pbox->x2);
+
+ if(RightEdge > LeftEdge) { /* we're possibly drawing something */
+ ytop = max(Top, pbox->y1);
+ ybot = min(Bottom, pbox->y2);
+ if(ybot > ytop) {
+ skippix = LeftEdge - xInit;
+ skipglyph = 0;
+ while(skippix >= infoRec->GlyphInfo[skipglyph].end)
+ skipglyph++;
+
+ skippix = RightEdge - xInit;
+ n = 0; i = skipglyph;
+ while((i < nglyph) && (skippix > infoRec->GlyphInfo[i].start)) {
+ i++; n++;
+ }
+
+ if(n) (*infoRec->NonTEGlyphRenderer)(pScrn,
+ xInit, yInit, n, infoRec->GlyphInfo + skipglyph,
+ pbox, fg, GXcopy, planemask);
+ }
+ }
+
+ nbox--; pbox++;
+ }
+}
+
+
+static int
+PolyGlyphBltNonTEColorExpansion(
+ ScrnInfoPtr pScrn,
+ int xInit, int yInit,
+ FontPtr font,
+ int fg, int rop,
+ unsigned planemask,
+ RegionPtr cclip,
+ int nglyph,
+ unsigned char* gBase,
+ CharInfoPtr *ppci
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int skippix, skipglyph, width, n, i;
+ int Left, Right, Top, Bottom;
+ int LeftEdge, RightEdge;
+ int nbox = REGION_NUM_RECTS(cclip);
+ BoxPtr pbox = REGION_RECTS(cclip);
+
+ width = CollectCharacterInfo(infoRec->GlyphInfo, nglyph, ppci, font);
+
+ if(!nbox)
+ return width;
+
+ if((infoRec->WriteBitmap) && (rop == GXcopy) && (nglyph > 1) &&
+ ((FONTMAXBOUNDS(font, rightSideBearing) -
+ FONTMINBOUNDS(font, leftSideBearing)) <= 32)) {
+
+ PolyGlyphBltAsSingleBitmap(pScrn, nglyph, font,
+ xInit, yInit, nbox, pbox,
+ fg, rop, planemask);
+
+ return width;
+ }
+
+ /* compute an approximate but covering bounding box */
+ Left = xInit + infoRec->GlyphInfo[0].start;
+ Right = xInit + infoRec->GlyphInfo[nglyph - 1].end;
+ Top = yInit - FONTMAXBOUNDS(font,ascent);
+ Bottom = yInit + FONTMAXBOUNDS(font,descent);
+
+ /* get into the first band that may contain part of our string */
+ while(nbox && (Top >= pbox->y2)) {
+ pbox++; nbox--;
+ }
+
+ /* stop when the lower edge of the box is beyond our string */
+ while(nbox && (Bottom >= pbox->y1)) {
+ LeftEdge = max(Left, pbox->x1);
+ RightEdge = min(Right, pbox->x2);
+
+ if(RightEdge > LeftEdge) { /* we're possibly drawing something */
+
+ skippix = LeftEdge - xInit;
+ skipglyph = 0;
+ while(skippix >= infoRec->GlyphInfo[skipglyph].end)
+ skipglyph++;
+
+ skippix = RightEdge - xInit;
+ n = 0; i = skipglyph;
+ while((i < nglyph) && (skippix > infoRec->GlyphInfo[i].start)) {
+ i++; n++;
+ }
+
+ if(n) (*infoRec->NonTEGlyphRenderer)(pScrn,
+ xInit, yInit, n, infoRec->GlyphInfo + skipglyph,
+ pbox, fg, rop, planemask);
+ }
+
+ nbox--; pbox++;
+ }
+ return width;
+}
+
+
+/* It is possible that the none of the glyphs passed to the
+ NonTEGlyphRenderer will be drawn. This function being called
+ indicates that part of the text string's bounding box is visible
+ but not necessarily that any of the characters are visible */
+
+void XAANonTEGlyphRenderer(
+ ScrnInfoPtr pScrn,
+ int x, int y, int n,
+ NonTEGlyphPtr glyphs,
+ BoxPtr pbox,
+ int fg, int rop,
+ unsigned int planemask
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int x1, x2, y1, y2, i, w, h, skipleft, skiptop;
+ unsigned char *src;
+
+ for(i = 0; i < n; i++, glyphs++) {
+ x1 = x + glyphs->start;
+ x2 = x + glyphs->end;
+ y1 = y - glyphs->yoff;
+ y2 = y1 + glyphs->height;
+
+ if(y1 < pbox->y1) {
+ skiptop = pbox->y1 - y1;
+ y1 = pbox->y1;
+ } else skiptop = 0;
+ if(y2 > pbox->y2) y2 = pbox->y2;
+ h = y2 - y1;
+ if(h <= 0) continue;
+
+ if(x1 < pbox->x1) {
+ skipleft = pbox->x1 - x1;
+ x1 = pbox->x1;
+ } else skipleft = 0;
+ if(x2 > pbox->x2) x2 = pbox->x2;
+
+ w = x2 - x1;
+
+ if(w > 0) {
+ src = glyphs->bits + (skiptop * glyphs->srcwidth);
+
+ if(skipleft) {
+ src += (skipleft >> 5) << 2;
+ skipleft &= 31;
+ }
+
+ (*infoRec->WriteBitmap)(pScrn, x1, y1, w, h, src,
+ glyphs->srcwidth, skipleft, fg, -1, rop, planemask);
+ }
+ }
+
+}
diff --git a/xorg-server/hw/xfree86/xaa/xaaOffscreen.c b/xorg-server/hw/xfree86/xaa/xaaOffscreen.c
index 7c9d53270..41be2b491 100644
--- a/xorg-server/hw/xfree86/xaa/xaaOffscreen.c
+++ b/xorg-server/hw/xfree86/xaa/xaaOffscreen.c
@@ -1,162 +1,162 @@
-
-/*
- Copyright (c) 1999 - The XFree86 Project Inc.
-
- Written by Mark Vojkovich
-
-*/
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "misc.h"
-#include "xf86.h"
-#include "xf86_OSproc.h"
-
-#include <X11/X.h>
-#include "scrnintstr.h"
-#include "pixmapstr.h"
-#include "windowstr.h"
-#include "xf86str.h"
-#include "mi.h"
-#include "miline.h"
-#include "xaa.h"
-#include "xaalocal.h"
-#include "xaawrap.h"
-#include "xf86fbman.h"
-#include "servermd.h"
-
-void
-XAAMoveOutOffscreenPixmaps(ScreenPtr pScreen)
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
- PixmapLinkPtr pLink = infoRec->OffscreenPixmaps;
- XAAPixmapPtr pPriv;
-
- while(pLink) {
- pPriv = XAA_GET_PIXMAP_PRIVATE(pLink->pPix);
- pLink->area = pPriv->offscreenArea;
- XAAMoveOutOffscreenPixmap(pLink->pPix);
- pLink = pLink->next;
- }
-}
-
-
-
-void
-XAAMoveInOffscreenPixmaps(ScreenPtr pScreen)
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
- PixmapLinkPtr pLink = infoRec->OffscreenPixmaps;
- PixmapPtr pPix, pScreenPix, tmpPix;
- pointer data;
- XAAPixmapPtr pPriv;
- GCPtr pGC;
- FBAreaPtr area;
-
- pScreenPix = (*pScreen->GetScreenPixmap)(pScreen);
-
- while(pLink) {
- pPix = pLink->pPix;
- pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
- area = pLink->area;
-
- data = pPix->devPrivate.ptr;
- tmpPix = GetScratchPixmapHeader(pScreen,
- pPix->drawable.width, pPix->drawable.height,
- pPix->drawable.depth, pPix->drawable.bitsPerPixel,
- pPix->devKind, data);
-
- pPriv->freeData = FALSE;
-
- pPix->drawable.x = area->box.x1;
- pPix->drawable.y = area->box.y1;
- pPix->devKind = pScreenPix->devKind;
- pPix->devPrivate.ptr = pScreenPix->devPrivate.ptr;
- pPix->drawable.bitsPerPixel = infoRec->pScrn->bitsPerPixel;
- pPix->drawable.serialNumber = NEXT_SERIAL_NUMBER;
-
- if(!tmpPix) {
- pPriv->offscreenArea = area;
- xfree(data);
- pLink = pLink->next;
- continue;
- }
-
- pGC = GetScratchGC(pPix->drawable.depth, pScreen);
- ValidateGC((DrawablePtr)pPix, pGC);
-
- (*pGC->ops->CopyArea)((DrawablePtr)tmpPix, (DrawablePtr)pPix, pGC,
- 0, 0, pPix->drawable.width, pPix->drawable.height, 0, 0);
-
- xfree(data);
- tmpPix->devPrivate.ptr = NULL;
-
- FreeScratchGC(pGC);
- FreeScratchPixmapHeader(tmpPix);
-
- pPriv->offscreenArea = area;
- pLink->area = NULL;
- pLink = pLink->next;
- }
-}
-
-
-void
-XAARemoveAreaCallback(FBAreaPtr area)
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(area->pScreen);
- PixmapPtr pPix = (PixmapPtr)area->devPrivate.ptr;
- XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
-
- XAAMoveOutOffscreenPixmap(pPix);
-
- pPriv->flags &= ~OFFSCREEN;
-
- DELIST_OFFSCREEN_PIXMAP(pPix);
-}
-
-void
-XAAMoveOutOffscreenPixmap(PixmapPtr pPix)
-{
- ScreenPtr pScreen = pPix->drawable.pScreen;
- XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
- int width, height, devKind, bitsPerPixel;
- PixmapPtr tmpPix;
- unsigned char *data;
- GCPtr pGC;
-
- width = pPix->drawable.width;
- height = pPix->drawable.height;
- bitsPerPixel = pPix->drawable.bitsPerPixel;
-
- devKind = BitmapBytePad(width * bitsPerPixel);
- if(!(data = xalloc(devKind * height)))
- FatalError("Out of memory\n");
-
- tmpPix = GetScratchPixmapHeader(pScreen, width, height,
- pPix->drawable.depth, bitsPerPixel, devKind, data);
- if(!tmpPix) {
- xfree(data);
- FatalError("Out of memory\n");
- }
-
- pGC = GetScratchGC(pPix->drawable.depth, pScreen);
- ValidateGC((DrawablePtr)tmpPix, pGC);
-
- (*pGC->ops->CopyArea)((DrawablePtr)pPix, (DrawablePtr)tmpPix,
- pGC, 0, 0, width, height, 0, 0);
-
- FreeScratchGC(pGC);
- FreeScratchPixmapHeader(tmpPix);
-
- pPix->drawable.x = 0;
- pPix->drawable.y = 0;
- pPix->devKind = devKind;
- pPix->devPrivate.ptr = data;
- pPix->drawable.serialNumber = NEXT_SERIAL_NUMBER;
-
- pPriv->offscreenArea = NULL;
- pPriv->freeData = TRUE;
-}
+
+/*
+ Copyright (c) 1999 - The XFree86 Project Inc.
+
+ Written by Mark Vojkovich
+
+*/
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include <X11/X.h>
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "xf86str.h"
+#include "mi.h"
+#include "miline.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xaawrap.h"
+#include "xf86fbman.h"
+#include "servermd.h"
+
+void
+XAAMoveOutOffscreenPixmaps(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ PixmapLinkPtr pLink = infoRec->OffscreenPixmaps;
+ XAAPixmapPtr pPriv;
+
+ while(pLink) {
+ pPriv = XAA_GET_PIXMAP_PRIVATE(pLink->pPix);
+ pLink->area = pPriv->offscreenArea;
+ XAAMoveOutOffscreenPixmap(pLink->pPix);
+ pLink = pLink->next;
+ }
+}
+
+
+
+void
+XAAMoveInOffscreenPixmaps(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ PixmapLinkPtr pLink = infoRec->OffscreenPixmaps;
+ PixmapPtr pPix, pScreenPix, tmpPix;
+ pointer data;
+ XAAPixmapPtr pPriv;
+ GCPtr pGC;
+ FBAreaPtr area;
+
+ pScreenPix = (*pScreen->GetScreenPixmap)(pScreen);
+
+ while(pLink) {
+ pPix = pLink->pPix;
+ pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+ area = pLink->area;
+
+ data = pPix->devPrivate.ptr;
+ tmpPix = GetScratchPixmapHeader(pScreen,
+ pPix->drawable.width, pPix->drawable.height,
+ pPix->drawable.depth, pPix->drawable.bitsPerPixel,
+ pPix->devKind, data);
+
+ pPriv->freeData = FALSE;
+
+ pPix->drawable.x = area->box.x1;
+ pPix->drawable.y = area->box.y1;
+ pPix->devKind = pScreenPix->devKind;
+ pPix->devPrivate.ptr = pScreenPix->devPrivate.ptr;
+ pPix->drawable.bitsPerPixel = infoRec->pScrn->bitsPerPixel;
+ pPix->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+ if(!tmpPix) {
+ pPriv->offscreenArea = area;
+ free(data);
+ pLink = pLink->next;
+ continue;
+ }
+
+ pGC = GetScratchGC(pPix->drawable.depth, pScreen);
+ ValidateGC((DrawablePtr)pPix, pGC);
+
+ (*pGC->ops->CopyArea)((DrawablePtr)tmpPix, (DrawablePtr)pPix, pGC,
+ 0, 0, pPix->drawable.width, pPix->drawable.height, 0, 0);
+
+ free(data);
+ tmpPix->devPrivate.ptr = NULL;
+
+ FreeScratchGC(pGC);
+ FreeScratchPixmapHeader(tmpPix);
+
+ pPriv->offscreenArea = area;
+ pLink->area = NULL;
+ pLink = pLink->next;
+ }
+}
+
+
+void
+XAARemoveAreaCallback(FBAreaPtr area)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(area->pScreen);
+ PixmapPtr pPix = (PixmapPtr)area->devPrivate.ptr;
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+
+ XAAMoveOutOffscreenPixmap(pPix);
+
+ pPriv->flags &= ~OFFSCREEN;
+
+ DELIST_OFFSCREEN_PIXMAP(pPix);
+}
+
+void
+XAAMoveOutOffscreenPixmap(PixmapPtr pPix)
+{
+ ScreenPtr pScreen = pPix->drawable.pScreen;
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+ int width, height, devKind, bitsPerPixel;
+ PixmapPtr tmpPix;
+ unsigned char *data;
+ GCPtr pGC;
+
+ width = pPix->drawable.width;
+ height = pPix->drawable.height;
+ bitsPerPixel = pPix->drawable.bitsPerPixel;
+
+ devKind = BitmapBytePad(width * bitsPerPixel);
+ if(!(data = malloc(devKind * height)))
+ FatalError("Out of memory\n");
+
+ tmpPix = GetScratchPixmapHeader(pScreen, width, height,
+ pPix->drawable.depth, bitsPerPixel, devKind, data);
+ if(!tmpPix) {
+ free(data);
+ FatalError("Out of memory\n");
+ }
+
+ pGC = GetScratchGC(pPix->drawable.depth, pScreen);
+ ValidateGC((DrawablePtr)tmpPix, pGC);
+
+ (*pGC->ops->CopyArea)((DrawablePtr)pPix, (DrawablePtr)tmpPix,
+ pGC, 0, 0, width, height, 0, 0);
+
+ FreeScratchGC(pGC);
+ FreeScratchPixmapHeader(tmpPix);
+
+ pPix->drawable.x = 0;
+ pPix->drawable.y = 0;
+ pPix->devKind = devKind;
+ pPix->devPrivate.ptr = data;
+ pPix->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+
+ pPriv->offscreenArea = NULL;
+ pPriv->freeData = TRUE;
+}
diff --git a/xorg-server/hw/xfree86/xaa/xaaOverlay.c b/xorg-server/hw/xfree86/xaa/xaaOverlay.c
index 2956a3dbf..b7122a58f 100644
--- a/xorg-server/hw/xfree86/xaa/xaaOverlay.c
+++ b/xorg-server/hw/xfree86/xaa/xaaOverlay.c
@@ -1,129 +1,129 @@
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "misc.h"
-#include "xf86.h"
-#include "xf86_OSproc.h"
-
-#include <X11/X.h>
-#include "scrnintstr.h"
-#include "windowstr.h"
-#include "xf86str.h"
-#include "xaa.h"
-#include "xaalocal.h"
-#include "xaawrap.h"
-#include "gcstruct.h"
-#include "pixmapstr.h"
-#include "mioverlay.h"
-
-#ifdef PANORAMIX
-#include "panoramiX.h"
-#include "panoramiXsrv.h"
-#endif
-
-static void
-XAACopyWindow8_32(
- WindowPtr pWin,
- DDXPointRec ptOldOrg,
- RegionPtr prgnSrc
-){
- DDXPointPtr pptSrc, ppt;
- RegionRec rgnDst;
- BoxPtr pbox;
- int dx, dy, nbox;
- WindowPtr pwinRoot;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- XAAInfoRecPtr infoRec =
- GET_XAAINFORECPTR_FROM_DRAWABLE((&pWin->drawable));
- Bool doUnderlay = miOverlayCopyUnderlay(pScreen);
- RegionPtr borderClip = &pWin->borderClip;
- Bool freeReg = FALSE;
-
- if (!infoRec->pScrn->vtSema || !infoRec->ScreenToScreenBitBlt ||
- (infoRec->ScreenToScreenBitBltFlags & NO_PLANEMASK))
- {
- XAA_SCREEN_PROLOGUE (pScreen, CopyWindow);
- if(infoRec->pScrn->vtSema && infoRec->NeedToSync) {
- (*infoRec->Sync)(infoRec->pScrn);
- infoRec->NeedToSync = FALSE;
- }
- (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
- XAA_SCREEN_EPILOGUE (pScreen, CopyWindow, XAACopyWindow8_32);
- return;
- }
-
- pwinRoot = WindowTable[pScreen->myNum];
-
- if(doUnderlay)
- freeReg = miOverlayCollectUnderlayRegions(pWin, &borderClip);
-
- REGION_NULL(pScreen, &rgnDst);
-
- dx = ptOldOrg.x - pWin->drawable.x;
- dy = ptOldOrg.y - pWin->drawable.y;
- REGION_TRANSLATE(pScreen, prgnSrc, -dx, -dy);
- REGION_INTERSECT(pScreen, &rgnDst, borderClip, prgnSrc);
-
- pbox = REGION_RECTS(&rgnDst);
- nbox = REGION_NUM_RECTS(&rgnDst);
- if(!nbox ||
- !(pptSrc = (DDXPointPtr )xalloc(nbox * sizeof(DDXPointRec)))) {
- REGION_UNINIT(pScreen, &rgnDst);
- return;
- }
- ppt = pptSrc;
-
- while(nbox--) {
- ppt->x = pbox->x1 + dx;
- ppt->y = pbox->y1 + dy;
- ppt++; pbox++;
- }
-
- infoRec->ScratchGC.planemask = doUnderlay ? 0x00ffffff : 0xff000000;
- infoRec->ScratchGC.alu = GXcopy;
-
- XAADoBitBlt((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot,
- &(infoRec->ScratchGC), &rgnDst, pptSrc);
-
- xfree(pptSrc);
- REGION_UNINIT(pScreen, &rgnDst);
- if(freeReg)
- REGION_DESTROY(pScreen, borderClip);
-}
-
-static void
-XAASetColorKey8_32(
- ScreenPtr pScreen,
- int nbox,
- BoxPtr pbox
-){
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
- ScrnInfoPtr pScrn = infoRec->pScrn;
-
- /* I'm counting on writes being clipped away while switched away.
- If this isn't going to be true then I need to be wrapping instead. */
- if(!infoRec->pScrn->vtSema) return;
-
- (*infoRec->FillSolidRects)(pScrn, pScrn->colorKey << 24, GXcopy,
- 0xff000000, nbox, pbox);
-
- SET_SYNC_FLAG(infoRec);
-}
-
-void
-XAASetupOverlay8_32Planar(ScreenPtr pScreen)
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
- int i;
-
- pScreen->CopyWindow = XAACopyWindow8_32;
-
- if(!(infoRec->FillSolidRectsFlags & NO_PLANEMASK))
- miOverlaySetTransFunction(pScreen, XAASetColorKey8_32);
-
- infoRec->FullPlanemask = ~0;
- for(i = 0; i < 32; i++) /* haven't thought about this much */
- infoRec->FullPlanemasks[i] = ~0;
-}
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include <X11/X.h>
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xaawrap.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "mioverlay.h"
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+static void
+XAACopyWindow8_32(
+ WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc
+){
+ DDXPointPtr pptSrc, ppt;
+ RegionRec rgnDst;
+ BoxPtr pbox;
+ int dx, dy, nbox;
+ WindowPtr pwinRoot;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ XAAInfoRecPtr infoRec =
+ GET_XAAINFORECPTR_FROM_DRAWABLE((&pWin->drawable));
+ Bool doUnderlay = miOverlayCopyUnderlay(pScreen);
+ RegionPtr borderClip = &pWin->borderClip;
+ Bool freeReg = FALSE;
+
+ if (!infoRec->pScrn->vtSema || !infoRec->ScreenToScreenBitBlt ||
+ (infoRec->ScreenToScreenBitBltFlags & NO_PLANEMASK))
+ {
+ XAA_SCREEN_PROLOGUE (pScreen, CopyWindow);
+ if(infoRec->pScrn->vtSema && infoRec->NeedToSync) {
+ (*infoRec->Sync)(infoRec->pScrn);
+ infoRec->NeedToSync = FALSE;
+ }
+ (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
+ XAA_SCREEN_EPILOGUE (pScreen, CopyWindow, XAACopyWindow8_32);
+ return;
+ }
+
+ pwinRoot = WindowTable[pScreen->myNum];
+
+ if(doUnderlay)
+ freeReg = miOverlayCollectUnderlayRegions(pWin, &borderClip);
+
+ REGION_NULL(pScreen, &rgnDst);
+
+ dx = ptOldOrg.x - pWin->drawable.x;
+ dy = ptOldOrg.y - pWin->drawable.y;
+ REGION_TRANSLATE(pScreen, prgnSrc, -dx, -dy);
+ REGION_INTERSECT(pScreen, &rgnDst, borderClip, prgnSrc);
+
+ pbox = REGION_RECTS(&rgnDst);
+ nbox = REGION_NUM_RECTS(&rgnDst);
+ if(!nbox ||
+ !(pptSrc = (DDXPointPtr )malloc(nbox * sizeof(DDXPointRec)))) {
+ REGION_UNINIT(pScreen, &rgnDst);
+ return;
+ }
+ ppt = pptSrc;
+
+ while(nbox--) {
+ ppt->x = pbox->x1 + dx;
+ ppt->y = pbox->y1 + dy;
+ ppt++; pbox++;
+ }
+
+ infoRec->ScratchGC.planemask = doUnderlay ? 0x00ffffff : 0xff000000;
+ infoRec->ScratchGC.alu = GXcopy;
+
+ XAADoBitBlt((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot,
+ &(infoRec->ScratchGC), &rgnDst, pptSrc);
+
+ free(pptSrc);
+ REGION_UNINIT(pScreen, &rgnDst);
+ if(freeReg)
+ REGION_DESTROY(pScreen, borderClip);
+}
+
+static void
+XAASetColorKey8_32(
+ ScreenPtr pScreen,
+ int nbox,
+ BoxPtr pbox
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ ScrnInfoPtr pScrn = infoRec->pScrn;
+
+ /* I'm counting on writes being clipped away while switched away.
+ If this isn't going to be true then I need to be wrapping instead. */
+ if(!infoRec->pScrn->vtSema) return;
+
+ (*infoRec->FillSolidRects)(pScrn, pScrn->colorKey << 24, GXcopy,
+ 0xff000000, nbox, pbox);
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+void
+XAASetupOverlay8_32Planar(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ int i;
+
+ pScreen->CopyWindow = XAACopyWindow8_32;
+
+ if(!(infoRec->FillSolidRectsFlags & NO_PLANEMASK))
+ miOverlaySetTransFunction(pScreen, XAASetColorKey8_32);
+
+ infoRec->FullPlanemask = ~0;
+ for(i = 0; i < 32; i++) /* haven't thought about this much */
+ infoRec->FullPlanemasks[i] = ~0;
+}
diff --git a/xorg-server/hw/xfree86/xaa/xaaOverlayDF.c b/xorg-server/hw/xfree86/xaa/xaaOverlayDF.c
index 8db816e1e..4548935fd 100644
--- a/xorg-server/hw/xfree86/xaa/xaaOverlayDF.c
+++ b/xorg-server/hw/xfree86/xaa/xaaOverlayDF.c
@@ -1,1050 +1,1050 @@
-/*
- Copyright (c) 1999 - The XFree86 Project Inc.
-
- Written by Mark Vojkovich
-*/
-
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "misc.h"
-#include "xf86.h"
-#include "xf86_OSproc.h"
-
-#include <X11/X.h>
-#include "scrnintstr.h"
-#include "pixmapstr.h"
-#include "windowstr.h"
-#include "xf86str.h"
-#include "mi.h"
-#include "miline.h"
-#include "xaa.h"
-#include "xaalocal.h"
-#include "xaawrap.h"
-#include "servermd.h"
-
-/* Screen funcs */
-
-static void XAAOverCopyWindow(WindowPtr, DDXPointRec, RegionPtr);
-static void XAAOverWindowExposures(WindowPtr, RegionPtr, RegionPtr);
-
-static int XAAOverStippledFillChooser(GCPtr);
-static int XAAOverOpaqueStippledFillChooser(GCPtr);
-static int XAAOverTiledFillChooser(GCPtr);
-
-/* GC funcs */
-
-static RegionPtr XAAOverCopyArea(DrawablePtr, DrawablePtr, GC *,
- int, int, int, int, int, int);
-static RegionPtr XAAOverCopyPlane(DrawablePtr, DrawablePtr, GCPtr,
- int, int, int, int, int, int, unsigned long);
-static void XAAOverPushPixelsSolid(GCPtr, PixmapPtr, DrawablePtr, int,
- int, int, int);
-static void XAAOverPolyFillRectSolid(DrawablePtr, GCPtr, int, xRectangle*);
-static void XAAOverPolyFillRectStippled(DrawablePtr, GCPtr, int, xRectangle*);
-static void XAAOverPolyFillRectOpaqueStippled(DrawablePtr, GCPtr,
- int, xRectangle*);
-static void XAAOverPolyFillRectTiled(DrawablePtr, GCPtr, int, xRectangle*);
-static void XAAOverFillSpansSolid(DrawablePtr, GCPtr, int, DDXPointPtr,
- int*, int);
-static void XAAOverFillSpansStippled(DrawablePtr, GCPtr, int, DDXPointPtr,
- int*, int);
-static void XAAOverFillSpansOpaqueStippled(DrawablePtr, GCPtr, int,
- DDXPointPtr, int*, int);
-static void XAAOverFillSpansTiled(DrawablePtr, GCPtr, int, DDXPointPtr,
- int*, int);
-static int XAAOverPolyText8TE(DrawablePtr, GCPtr, int, int, int, char *);
-static int XAAOverPolyText16TE(DrawablePtr, GCPtr, int, int, int,
- unsigned short*);
-static void XAAOverImageText8TE(DrawablePtr, GCPtr, int, int, int, char*);
-static void XAAOverImageText16TE(DrawablePtr, GCPtr, int, int, int,
- unsigned short*);
-static void XAAOverImageGlyphBltTE(DrawablePtr, GCPtr, int, int,
- unsigned int, CharInfoPtr*, pointer);
-static void XAAOverPolyGlyphBltTE(DrawablePtr, GCPtr, int, int,
- unsigned int, CharInfoPtr*, pointer);
-static int XAAOverPolyText8NonTE(DrawablePtr, GCPtr, int, int, int, char*);
-static int XAAOverPolyText16NonTE(DrawablePtr, GCPtr, int, int, int,
- unsigned short*);
-static void XAAOverImageText8NonTE(DrawablePtr, GCPtr, int, int, int, char*);
-static void XAAOverImageText16NonTE(DrawablePtr, GCPtr, int, int, int,
- unsigned short*);
-static void XAAOverImageGlyphBltNonTE(DrawablePtr, GCPtr, int, int,
- unsigned int, CharInfoPtr *, pointer);
-static void XAAOverPolyGlyphBltNonTE(DrawablePtr, GCPtr, int, int,
- unsigned int, CharInfoPtr *, pointer);
-static void XAAOverPolyRectangleThinSolid(DrawablePtr, GCPtr, int, xRectangle*);
-static void XAAOverPolylinesWideSolid(DrawablePtr, GCPtr, int, int,
- DDXPointPtr);
-static void XAAOverPolylinesThinSolid(DrawablePtr, GCPtr, int, int,
- DDXPointPtr);
-static void XAAOverPolySegmentThinSolid(DrawablePtr, GCPtr, int, xSegment*);
-static void XAAOverPolylinesThinDashed(DrawablePtr, GCPtr, int, int,
- DDXPointPtr);
-static void XAAOverPolySegmentThinDashed(DrawablePtr, GCPtr, int, xSegment*);
-static void XAAOverFillPolygonSolid(DrawablePtr, GCPtr, int, int, int,
- DDXPointPtr);
-static void XAAOverFillPolygonStippled(DrawablePtr, GCPtr, int, int, int,
- DDXPointPtr);
-static void XAAOverFillPolygonOpaqueStippled(DrawablePtr, GCPtr, int, int, int,
- DDXPointPtr);
-static void XAAOverFillPolygonTiled(DrawablePtr, GCPtr, int, int, int,
- DDXPointPtr);
-static void XAAOverPolyFillArcSolid(DrawablePtr, GCPtr, int, xArc*);
-static void XAAOverPutImage(DrawablePtr, GCPtr, int, int, int, int, int,
- int, int, char*);
-
-
-typedef struct {
- ScrnInfoPtr pScrn;
- DepthChangeFuncPtr callback;
- int currentDepth;
-/* GC funcs */
- RegionPtr (*CopyArea)(DrawablePtr, DrawablePtr, GC *,
- int, int, int, int, int, int);
- RegionPtr (*CopyPlane)(DrawablePtr, DrawablePtr, GCPtr,
- int, int, int, int, int, int, unsigned long);
- void (*PushPixelsSolid)(GCPtr, PixmapPtr, DrawablePtr, int, int, int, int);
- void (*PolyFillRectSolid)(DrawablePtr, GCPtr, int, xRectangle*);
- void (*PolyFillRectStippled)(DrawablePtr, GCPtr, int, xRectangle*);
- void (*PolyFillRectOpaqueStippled)(DrawablePtr, GCPtr, int, xRectangle*);
- void (*PolyFillRectTiled)(DrawablePtr, GCPtr, int, xRectangle*);
- void (*FillSpansSolid)(DrawablePtr, GCPtr, int, DDXPointPtr, int*, int);
- void (*FillSpansStippled)(DrawablePtr, GCPtr, int, DDXPointPtr, int*, int);
- void (*FillSpansOpaqueStippled)(DrawablePtr,GCPtr,int,DDXPointPtr,int*,int);
- void (*FillSpansTiled)(DrawablePtr, GCPtr, int, DDXPointPtr, int*, int);
- int (*PolyText8TE)(DrawablePtr, GCPtr, int, int, int, char *);
- int (*PolyText16TE)(DrawablePtr, GCPtr, int, int, int, unsigned short*);
- void (*ImageText8TE)(DrawablePtr, GCPtr, int, int, int, char*);
- void (*ImageText16TE)(DrawablePtr, GCPtr, int, int, int, unsigned short*);
- void (*ImageGlyphBltTE)(DrawablePtr, GCPtr, int, int, unsigned int,
- CharInfoPtr*, pointer);
- void (*PolyGlyphBltTE)(DrawablePtr, GCPtr, int, int, unsigned int,
- CharInfoPtr*, pointer);
- int (*PolyText8NonTE)(DrawablePtr, GCPtr, int, int, int, char*);
- int (*PolyText16NonTE)(DrawablePtr, GCPtr, int, int, int, unsigned short*);
- void (*ImageText8NonTE)(DrawablePtr, GCPtr, int, int, int, char*);
- void (*ImageText16NonTE)(DrawablePtr, GCPtr, int, int, int, unsigned short*);
- void (*ImageGlyphBltNonTE)(DrawablePtr, GCPtr, int, int, unsigned int,
- CharInfoPtr *, pointer);
- void (*PolyGlyphBltNonTE)(DrawablePtr, GCPtr, int, int, unsigned int,
- CharInfoPtr *, pointer);
- void (*PolyRectangleThinSolid)(DrawablePtr, GCPtr, int, xRectangle*);
- void (*PolylinesWideSolid)(DrawablePtr, GCPtr, int, int, DDXPointPtr);
-
- void (*PolylinesThinSolid)(DrawablePtr, GCPtr, int, int, DDXPointPtr);
- void (*PolySegmentThinSolid)(DrawablePtr, GCPtr, int, xSegment*);
- void (*PolylinesThinDashed)(DrawablePtr, GCPtr, int, int, DDXPointPtr);
- void (*PolySegmentThinDashed)(DrawablePtr, GCPtr, int, xSegment*);
- void (*FillPolygonSolid)(DrawablePtr, GCPtr, int, int, int, DDXPointPtr);
- void (*FillPolygonStippled)(DrawablePtr, GCPtr, int, int, int, DDXPointPtr);
- void (*FillPolygonOpaqueStippled)(DrawablePtr, GCPtr, int, int, int,
- DDXPointPtr);
- void (*FillPolygonTiled)(DrawablePtr, GCPtr, int, int, int, DDXPointPtr);
- void (*PolyFillArcSolid)(DrawablePtr, GCPtr, int, xArc*);
- void (*PutImage)(DrawablePtr, GCPtr, int, int, int, int, int, int,
- int, char*);
- int (*StippledFillChooser)(GCPtr);
- int (*OpaqueStippledFillChooser)(GCPtr);
- int (*TiledFillChooser)(GCPtr);
-} XAAOverlayRec, *XAAOverlayPtr;
-
-static int XAAOverlayKeyIndex;
-static DevPrivateKey XAAOverlayKey = &XAAOverlayKeyIndex;
-
-#define GET_OVERLAY_PRIV(pScreen) \
- (XAAOverlayPtr)dixLookupPrivate(&(pScreen)->devPrivates, XAAOverlayKey)
-
-#define SWITCH_DEPTH(d) \
- if(pOverPriv->currentDepth != d) { \
- (*pOverPriv->callback)(pOverPriv->pScrn, d); \
- pOverPriv->currentDepth = d; \
- }
-
-
-Bool
-XAAInitDualFramebufferOverlay(
- ScreenPtr pScreen,
- DepthChangeFuncPtr callback
-){
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
- XAAOverlayPtr pOverPriv;
-
- if(!(pOverPriv = xalloc(sizeof(XAAOverlayRec))))
- return FALSE;
-
- dixSetPrivate(&pScreen->devPrivates, XAAOverlayKey, pOverPriv);
-
- pOverPriv->pScrn = pScrn;
- pOverPriv->callback = callback;
- pOverPriv->currentDepth = -1;
-
- /* Overwrite key screen functions. The XAA core will clean up */
-
- pScreen->CopyWindow = XAAOverCopyWindow;
- pScreen->WindowExposures = XAAOverWindowExposures;
-
- pOverPriv->StippledFillChooser = infoRec->StippledFillChooser;
- pOverPriv->OpaqueStippledFillChooser = infoRec->OpaqueStippledFillChooser;
- pOverPriv->TiledFillChooser = infoRec->TiledFillChooser;
-
- infoRec->StippledFillChooser = XAAOverStippledFillChooser;
- infoRec->OpaqueStippledFillChooser = XAAOverOpaqueStippledFillChooser;
- infoRec->TiledFillChooser = XAAOverTiledFillChooser;
-
- /* wrap all XAA GC rendering */
-
- pOverPriv->CopyArea = infoRec->CopyArea;
- pOverPriv->CopyPlane = infoRec->CopyPlane;
- pOverPriv->PushPixelsSolid = infoRec->PushPixelsSolid;
- pOverPriv->PolyFillRectSolid = infoRec->PolyFillRectSolid;
- pOverPriv->PolyFillRectStippled = infoRec->PolyFillRectStippled;
- pOverPriv->PolyFillRectOpaqueStippled = infoRec->PolyFillRectOpaqueStippled;
- pOverPriv->PolyFillRectTiled = infoRec->PolyFillRectTiled;
- pOverPriv->FillSpansSolid = infoRec->FillSpansSolid;
- pOverPriv->FillSpansStippled = infoRec->FillSpansStippled;
- pOverPriv->FillSpansOpaqueStippled = infoRec->FillSpansOpaqueStippled;
- pOverPriv->FillSpansTiled = infoRec->FillSpansTiled;
- pOverPriv->PolyText8TE = infoRec->PolyText8TE;
- pOverPriv->PolyText16TE = infoRec->PolyText16TE;
- pOverPriv->ImageText8TE = infoRec->ImageText8TE;
- pOverPriv->ImageText16TE = infoRec->ImageText16TE;
- pOverPriv->ImageGlyphBltTE = infoRec->ImageGlyphBltTE;
- pOverPriv->PolyGlyphBltTE = infoRec->PolyGlyphBltTE;
- pOverPriv->PolyText8NonTE = infoRec->PolyText8NonTE;
- pOverPriv->PolyText16NonTE = infoRec->PolyText16NonTE;
- pOverPriv->ImageText8NonTE = infoRec->ImageText8NonTE;
- pOverPriv->ImageText16NonTE = infoRec->ImageText16NonTE;
- pOverPriv->ImageGlyphBltNonTE = infoRec->ImageGlyphBltNonTE;
- pOverPriv->PolyGlyphBltNonTE = infoRec->PolyGlyphBltNonTE;
- pOverPriv->PolyRectangleThinSolid = infoRec->PolyRectangleThinSolid;
- pOverPriv->PolylinesWideSolid = infoRec->PolylinesWideSolid;
- pOverPriv->PolylinesThinSolid = infoRec->PolylinesThinSolid;
- pOverPriv->PolySegmentThinSolid = infoRec->PolySegmentThinSolid;
- pOverPriv->PolylinesThinDashed = infoRec->PolylinesThinDashed;
- pOverPriv->PolySegmentThinDashed = infoRec->PolySegmentThinDashed;
- pOverPriv->FillPolygonSolid = infoRec->FillPolygonSolid;
- pOverPriv->FillPolygonStippled = infoRec->FillPolygonStippled;
- pOverPriv->FillPolygonOpaqueStippled = infoRec->FillPolygonOpaqueStippled;
- pOverPriv->FillPolygonTiled = infoRec->FillPolygonTiled;
- pOverPriv->PolyFillArcSolid = infoRec->PolyFillArcSolid;
- pOverPriv->PutImage = infoRec->PutImage;
-
-
- if(infoRec->CopyArea)
- infoRec->CopyArea = XAAOverCopyArea;
- if(infoRec->CopyPlane)
- infoRec->CopyPlane = XAAOverCopyPlane;
- if(infoRec->PushPixelsSolid)
- infoRec->PushPixelsSolid = XAAOverPushPixelsSolid;
- if(infoRec->PolyFillRectSolid)
- infoRec->PolyFillRectSolid = XAAOverPolyFillRectSolid;
- if(infoRec->PolyFillRectStippled)
- infoRec->PolyFillRectStippled = XAAOverPolyFillRectStippled;
- if(infoRec->PolyFillRectOpaqueStippled)
- infoRec->PolyFillRectOpaqueStippled = XAAOverPolyFillRectOpaqueStippled;
- if(infoRec->PolyFillRectTiled)
- infoRec->PolyFillRectTiled = XAAOverPolyFillRectTiled;
- if(infoRec->FillSpansSolid)
- infoRec->FillSpansSolid = XAAOverFillSpansSolid;
- if(infoRec->FillSpansStippled)
- infoRec->FillSpansStippled = XAAOverFillSpansStippled;
- if(infoRec->FillSpansOpaqueStippled)
- infoRec->FillSpansOpaqueStippled = XAAOverFillSpansOpaqueStippled;
- if(infoRec->FillSpansTiled)
- infoRec->FillSpansTiled = XAAOverFillSpansTiled;
- if(infoRec->PolyText8TE)
- infoRec->PolyText8TE = XAAOverPolyText8TE;
- if(infoRec->PolyText16TE)
- infoRec->PolyText16TE = XAAOverPolyText16TE;
- if(infoRec->ImageText8TE)
- infoRec->ImageText8TE = XAAOverImageText8TE;
- if(infoRec->ImageText16TE)
- infoRec->ImageText16TE = XAAOverImageText16TE;
- if(infoRec->ImageGlyphBltTE)
- infoRec->ImageGlyphBltTE = XAAOverImageGlyphBltTE;
- if(infoRec->PolyGlyphBltTE)
- infoRec->PolyGlyphBltTE = XAAOverPolyGlyphBltTE;
- if(infoRec->PolyText8NonTE)
- infoRec->PolyText8NonTE = XAAOverPolyText8NonTE;
- if(infoRec->PolyText16NonTE)
- infoRec->PolyText16NonTE = XAAOverPolyText16NonTE;
- if(infoRec->ImageText8NonTE)
- infoRec->ImageText8NonTE = XAAOverImageText8NonTE;
- if(infoRec->ImageText16NonTE)
- infoRec->ImageText16NonTE = XAAOverImageText16NonTE;
- if(infoRec->ImageGlyphBltNonTE)
- infoRec->ImageGlyphBltNonTE = XAAOverImageGlyphBltNonTE;
- if(infoRec->PolyGlyphBltNonTE)
- infoRec->PolyGlyphBltNonTE = XAAOverPolyGlyphBltNonTE;
- if(infoRec->PolyRectangleThinSolid)
- infoRec->PolyRectangleThinSolid = XAAOverPolyRectangleThinSolid;
- if(infoRec->PolylinesWideSolid)
- infoRec->PolylinesWideSolid = XAAOverPolylinesWideSolid;
- if(infoRec->PolylinesThinSolid)
- infoRec->PolylinesThinSolid = XAAOverPolylinesThinSolid;
- if(infoRec->PolySegmentThinSolid)
- infoRec->PolySegmentThinSolid = XAAOverPolySegmentThinSolid;
- if(infoRec->PolylinesThinDashed)
- infoRec->PolylinesThinDashed = XAAOverPolylinesThinDashed;
- if(infoRec->PolySegmentThinDashed)
- infoRec->PolySegmentThinDashed = XAAOverPolySegmentThinDashed;
- if(infoRec->FillPolygonSolid)
- infoRec->FillPolygonSolid = XAAOverFillPolygonSolid;
- if(infoRec->FillPolygonStippled)
- infoRec->FillPolygonStippled = XAAOverFillPolygonStippled;
- if(infoRec->FillPolygonOpaqueStippled)
- infoRec->FillPolygonOpaqueStippled = XAAOverFillPolygonOpaqueStippled;
- if(infoRec->FillPolygonTiled)
- infoRec->FillPolygonTiled = XAAOverFillPolygonTiled;
- if(infoRec->PolyFillArcSolid)
- infoRec->PolyFillArcSolid = XAAOverPolyFillArcSolid;
- if(infoRec->PutImage)
- infoRec->PutImage = XAAOverPutImage;
-
- return TRUE;
-}
-
-/*********************** Screen functions ************************/
-
-void
-XAAOverCopyWindow(
- WindowPtr pWin,
- DDXPointRec ptOldOrg,
- RegionPtr prgnSrc
-){
- ScreenPtr pScreen = pWin->drawable.pScreen;
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pScreen);
- ScrnInfoPtr pScrn = infoRec->pScrn;
- DDXPointPtr ppt, pptSrc;
- RegionRec rgnDst;
- BoxPtr pbox;
- int i, nbox, dx, dy;
- WindowPtr pRoot = WindowTable[pScreen->myNum];
-
-
- if (!pScrn->vtSema || !infoRec->ScreenToScreenBitBlt) {
- XAA_SCREEN_PROLOGUE (pScreen, CopyWindow);
- if(pScrn->vtSema && infoRec->NeedToSync) {
- (*infoRec->Sync)(pScrn);
- infoRec->NeedToSync = FALSE;
- }
- (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
- XAA_SCREEN_EPILOGUE (pScreen, CopyWindow, XAAOverCopyWindow);
- return;
- }
-
- infoRec->ScratchGC.alu = GXcopy;
- infoRec->ScratchGC.planemask = ~0;
-
- REGION_NULL(pScreen, &rgnDst);
-
- dx = ptOldOrg.x - pWin->drawable.x;
- dy = ptOldOrg.y - pWin->drawable.y;
- REGION_TRANSLATE(pScreen, prgnSrc, -dx, -dy);
- REGION_INTERSECT(pScreen, &rgnDst, &pWin->borderClip, prgnSrc);
-
- nbox = REGION_NUM_RECTS(&rgnDst);
- if(nbox &&
- (pptSrc = (DDXPointPtr )xalloc(nbox * sizeof(DDXPointRec)))) {
-
- pbox = REGION_RECTS(&rgnDst);
- for (i = nbox, ppt = pptSrc; i--; ppt++, pbox++) {
- ppt->x = pbox->x1 + dx;
- ppt->y = pbox->y1 + dy;
- }
-
- SWITCH_DEPTH(8);
- XAADoBitBlt((DrawablePtr)pRoot, (DrawablePtr)pRoot,
- &(infoRec->ScratchGC), &rgnDst, pptSrc);
-
- if(pWin->drawable.bitsPerPixel != 8) {
- SWITCH_DEPTH(pScrn->depth);
- XAADoBitBlt((DrawablePtr)pRoot, (DrawablePtr)pRoot,
- &(infoRec->ScratchGC), &rgnDst, pptSrc);
- }
-
- xfree(pptSrc);
- }
-
- REGION_UNINIT(pScreen, &rgnDst);
-
- if(pWin->drawable.depth == 8) {
- REGION_NULL(pScreen, &rgnDst);
- miSegregateChildren(pWin, &rgnDst, pScrn->depth);
- if(REGION_NOTEMPTY(pScreen, &rgnDst)) {
- REGION_INTERSECT(pScreen, &rgnDst, &rgnDst, prgnSrc);
- nbox = REGION_NUM_RECTS(&rgnDst);
- if(nbox &&
- (pptSrc = (DDXPointPtr )xalloc(nbox * sizeof(DDXPointRec)))){
-
- pbox = REGION_RECTS(&rgnDst);
- for (i = nbox, ppt = pptSrc; i--; ppt++, pbox++) {
- ppt->x = pbox->x1 + dx;
- ppt->y = pbox->y1 + dy;
- }
-
- SWITCH_DEPTH(pScrn->depth);
- XAADoBitBlt((DrawablePtr)pRoot, (DrawablePtr)pRoot,
- &(infoRec->ScratchGC), &rgnDst, pptSrc);
- xfree(pptSrc);
- }
- }
- REGION_UNINIT(pScreen, &rgnDst);
- }
-}
-
-
-void
-XAAOverWindowExposures(
- WindowPtr pWin,
- RegionPtr pReg,
- RegionPtr pOtherReg
-){
- ScreenPtr pScreen = pWin->drawable.pScreen;
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
-
- if((pWin->drawable.bitsPerPixel != 8) && infoRec->pScrn->vtSema) {
- if(REGION_NUM_RECTS(pReg) && infoRec->FillSolidRects) {
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pScreen);
-
- SWITCH_DEPTH(8);
- (*infoRec->FillSolidRects)(infoRec->pScrn,
- infoRec->pScrn->colorKey, GXcopy, ~0,
- REGION_NUM_RECTS(pReg), REGION_RECTS(pReg));
- miWindowExposures(pWin, pReg, pOtherReg);
- return;
- } else if(infoRec->NeedToSync) {
- (*infoRec->Sync)(infoRec->pScrn);
- infoRec->NeedToSync = FALSE;
- }
- }
-
- XAA_SCREEN_PROLOGUE (pScreen, WindowExposures);
- (*pScreen->WindowExposures) (pWin, pReg, pOtherReg);
- XAA_SCREEN_EPILOGUE(pScreen, WindowExposures, XAAOverWindowExposures);
-}
-
-/********************* Choosers *************************/
-
-static int
-XAAOverStippledFillChooser(GCPtr pGC)
-{
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
- int ret;
-
- ret = (*pOverPriv->StippledFillChooser)(pGC);
-
- if((pGC->depth == 8) &&
- ((ret == DO_COLOR_8x8) || (ret == DO_CACHE_BLT))) {
- ret = 0;
- }
-
- return ret;
-}
-
-static int
-XAAOverOpaqueStippledFillChooser(GCPtr pGC)
-{
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
- int ret;
-
- ret = (*pOverPriv->OpaqueStippledFillChooser)(pGC);
-
- if((pGC->depth == 8) &&
- ((ret == DO_COLOR_8x8) || (ret == DO_CACHE_BLT))) {
- ret = 0;
- }
-
- return ret;
-}
-
-static int
-XAAOverTiledFillChooser(GCPtr pGC)
-{
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
- int ret;
-
- ret = (*pOverPriv->TiledFillChooser)(pGC);
-
- if((pGC->depth == 8) &&
- ((ret == DO_COLOR_8x8) || (ret == DO_CACHE_BLT))) {
- ret = 0;
- }
-
- return ret;
-}
-
-
-/**************************** GC Functions **************************/
-
-static RegionPtr
-XAAOverCopyArea(
- DrawablePtr pSrc,
- DrawablePtr pDst,
- GC *pGC,
- int srcx, int srcy,
- int width, int height,
- int dstx, int dsty
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- return (*pOverPriv->CopyArea)(pSrc, pDst,
- pGC, srcx, srcy, width, height, dstx, dsty);
-}
-
-static RegionPtr
-XAAOverCopyPlane(
- DrawablePtr pSrc,
- DrawablePtr pDst,
- GCPtr pGC,
- int srcx, int srcy,
- int width, int height,
- int dstx, int dsty,
- unsigned long bitPlane
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- return (*pOverPriv->CopyPlane)(pSrc, pDst,
- pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
-
-}
-
-static void
-XAAOverPushPixelsSolid(
- GCPtr pGC,
- PixmapPtr pBitMap,
- DrawablePtr pDraw,
- int dx, int dy,
- int xOrg, int yOrg
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- (*pOverPriv->PushPixelsSolid)(pGC, pBitMap, pDraw, dx, dy, xOrg, yOrg);
-}
-
-
-
-static void
-XAAOverPolyFillRectSolid(
- DrawablePtr pDraw,
- GCPtr pGC,
- int nrectFill,
- xRectangle *prectInit
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- (*pOverPriv->PolyFillRectSolid)(pDraw, pGC, nrectFill, prectInit);
-}
-
-static void
-XAAOverPolyFillRectStippled(
- DrawablePtr pDraw,
- GCPtr pGC,
- int nrectFill,
- xRectangle *prectInit
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- (*pOverPriv->PolyFillRectStippled)(pDraw, pGC, nrectFill, prectInit);
-}
-
-
-static void
-XAAOverPolyFillRectOpaqueStippled(
- DrawablePtr pDraw,
- GCPtr pGC,
- int nrectFill,
- xRectangle *prectInit
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- (*pOverPriv->PolyFillRectOpaqueStippled)(pDraw, pGC, nrectFill, prectInit);
-}
-
-static void
-XAAOverPolyFillRectTiled(
- DrawablePtr pDraw,
- GCPtr pGC,
- int nrectFill,
- xRectangle *prectInit
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- (*pOverPriv->PolyFillRectTiled)(pDraw, pGC, nrectFill, prectInit);
-}
-
-
-static void
-XAAOverFillSpansSolid(
- DrawablePtr pDraw,
- GCPtr pGC,
- int nInit,
- DDXPointPtr ppt,
- int *pwidth,
- int fSorted
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- (*pOverPriv->FillSpansSolid)(
- pDraw, pGC, nInit, ppt, pwidth, fSorted);
-}
-
-
-static void
-XAAOverFillSpansStippled(
- DrawablePtr pDraw,
- GCPtr pGC,
- int nInit,
- DDXPointPtr ppt,
- int *pwidth,
- int fSorted
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- (*pOverPriv->FillSpansStippled)(pDraw, pGC, nInit, ppt, pwidth, fSorted);
-}
-
-static void
-XAAOverFillSpansOpaqueStippled(
- DrawablePtr pDraw,
- GCPtr pGC,
- int nInit,
- DDXPointPtr ppt,
- int *pwidth,
- int fSorted
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- (*pOverPriv->FillSpansOpaqueStippled)(
- pDraw, pGC, nInit, ppt, pwidth, fSorted);
-}
-
-
-static void
-XAAOverFillSpansTiled(
- DrawablePtr pDraw,
- GCPtr pGC,
- int nInit,
- DDXPointPtr ppt,
- int *pwidth,
- int fSorted
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- (*pOverPriv->FillSpansTiled)(pDraw, pGC, nInit, ppt, pwidth, fSorted);
-}
-
-static int
-XAAOverPolyText8TE(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x, int y,
- int count,
- char *chars
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- return (*pOverPriv->PolyText8TE)(pDraw, pGC, x, y, count, chars);
-}
-
-
-static int
-XAAOverPolyText16TE(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x, int y,
- int count,
- unsigned short *chars
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- return (*pOverPriv->PolyText16TE)(pDraw, pGC, x, y, count, chars);
-}
-
-
-static void
-XAAOverImageText8TE(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x, int y,
- int count,
- char *chars
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- (*pOverPriv->ImageText8TE)(pDraw, pGC, x, y, count, chars);
-}
-
-
-static void
-XAAOverImageText16TE(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x, int y,
- int count,
- unsigned short *chars
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- (*pOverPriv->ImageText16TE)(pDraw, pGC, x, y, count, chars);
-}
-
-static void
-XAAOverImageGlyphBltTE(
- DrawablePtr pDraw,
- GCPtr pGC,
- int xInit, int yInit,
- unsigned int nglyph,
- CharInfoPtr *ppci,
- pointer pglyphBase
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- (*pOverPriv->ImageGlyphBltTE)(
- pDraw, pGC, xInit, yInit, nglyph, ppci, pglyphBase);
-}
-
-static void
-XAAOverPolyGlyphBltTE(
- DrawablePtr pDraw,
- GCPtr pGC,
- int xInit, int yInit,
- unsigned int nglyph,
- CharInfoPtr *ppci,
- pointer pglyphBase
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- (*pOverPriv->PolyGlyphBltTE)(
- pDraw, pGC, xInit, yInit, nglyph, ppci, pglyphBase);
-}
-
-static int
-XAAOverPolyText8NonTE(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x, int y,
- int count,
- char *chars
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- return (*pOverPriv->PolyText8NonTE)(pDraw, pGC, x, y, count, chars);
-}
-
-
-static int
-XAAOverPolyText16NonTE(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x, int y,
- int count,
- unsigned short *chars
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- return (*pOverPriv->PolyText16NonTE)(pDraw, pGC, x, y, count, chars);
-}
-
-static void
-XAAOverImageText8NonTE(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x, int y,
- int count,
- char *chars
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- (*pOverPriv->ImageText8NonTE)(pDraw, pGC, x, y, count, chars);
-}
-
-static void
-XAAOverImageText16NonTE(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x, int y,
- int count,
- unsigned short *chars
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- (*pOverPriv->ImageText16NonTE)(pDraw, pGC, x, y, count, chars);
-}
-
-
-static void
-XAAOverImageGlyphBltNonTE(
- DrawablePtr pDraw,
- GCPtr pGC,
- int xInit, int yInit,
- unsigned int nglyph,
- CharInfoPtr *ppci,
- pointer pglyphBase
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- (*pOverPriv->ImageGlyphBltNonTE)(
- pDraw, pGC, xInit, yInit, nglyph, ppci, pglyphBase);
-}
-
-static void
-XAAOverPolyGlyphBltNonTE(
- DrawablePtr pDraw,
- GCPtr pGC,
- int xInit, int yInit,
- unsigned int nglyph,
- CharInfoPtr *ppci,
- pointer pglyphBase
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- (*pOverPriv->PolyGlyphBltNonTE)(
- pDraw, pGC, xInit, yInit, nglyph, ppci, pglyphBase);
-}
-
-static void
-XAAOverPolyRectangleThinSolid(
- DrawablePtr pDraw,
- GCPtr pGC,
- int nRectsInit,
- xRectangle *pRectsInit
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- (*pOverPriv->PolyRectangleThinSolid)(pDraw, pGC, nRectsInit, pRectsInit);
-}
-
-
-
-static void
-XAAOverPolylinesWideSolid(
- DrawablePtr pDraw,
- GCPtr pGC,
- int mode,
- int npt,
- DDXPointPtr pPts
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- (*pOverPriv->PolylinesWideSolid)(pDraw, pGC, mode, npt, pPts);
-}
-
-
-static void
-XAAOverPolylinesThinSolid(
- DrawablePtr pDraw,
- GCPtr pGC,
- int mode,
- int npt,
- DDXPointPtr pPts
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- (*pOverPriv->PolylinesThinSolid)(pDraw, pGC, mode, npt, pPts);
-}
-
-static void
-XAAOverPolySegmentThinSolid(
- DrawablePtr pDraw,
- GCPtr pGC,
- int nseg,
- xSegment *pSeg
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- (*pOverPriv->PolySegmentThinSolid)(pDraw, pGC, nseg, pSeg);
-}
-
-static void
-XAAOverPolylinesThinDashed(
- DrawablePtr pDraw,
- GCPtr pGC,
- int mode,
- int npt,
- DDXPointPtr pPts
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- (*pOverPriv->PolylinesThinDashed)(pDraw, pGC, mode, npt, pPts);
-}
-
-static void
-XAAOverPolySegmentThinDashed(
- DrawablePtr pDraw,
- GCPtr pGC,
- int nseg,
- xSegment *pSeg
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- (*pOverPriv->PolySegmentThinDashed)(pDraw, pGC, nseg, pSeg);
-}
-
-
-static void
-XAAOverFillPolygonSolid(
- DrawablePtr pDraw,
- GCPtr pGC,
- int shape,
- int mode,
- int count,
- DDXPointPtr ptsIn
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- (*pOverPriv->FillPolygonSolid)(pDraw, pGC, shape, mode, count, ptsIn);
-}
-
-static void
-XAAOverFillPolygonStippled(
- DrawablePtr pDraw,
- GCPtr pGC,
- int shape,
- int mode,
- int count,
- DDXPointPtr ptsIn
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- (*pOverPriv->FillPolygonStippled)(pDraw, pGC, shape, mode, count, ptsIn);
-}
-
-
-static void
-XAAOverFillPolygonOpaqueStippled(
- DrawablePtr pDraw,
- GCPtr pGC,
- int shape,
- int mode,
- int count,
- DDXPointPtr ptsIn
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- (*pOverPriv->FillPolygonOpaqueStippled)(
- pDraw, pGC, shape, mode, count, ptsIn);
-}
-
-static void
-XAAOverFillPolygonTiled(
- DrawablePtr pDraw,
- GCPtr pGC,
- int shape,
- int mode,
- int count,
- DDXPointPtr ptsIn
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- (*pOverPriv->FillPolygonTiled)(pDraw, pGC, shape, mode, count, ptsIn);
-}
-
-
-static void
-XAAOverPolyFillArcSolid(
- DrawablePtr pDraw,
- GCPtr pGC,
- int narcs,
- xArc *parcs
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- (*pOverPriv->PolyFillArcSolid)(pDraw, pGC, narcs, parcs);
-}
-
-
-static void
-XAAOverPutImage(
- DrawablePtr pDraw,
- GCPtr pGC,
- int depth,
- int x,
- int y,
- int w,
- int h,
- int leftPad,
- int format,
- char *pImage
-){
- XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
-
- SWITCH_DEPTH(pGC->depth);
-
- (*pOverPriv->PutImage)(pDraw, pGC, depth, x, y, w, h,
- leftPad, format, pImage);
-}
-
+/*
+ Copyright (c) 1999 - The XFree86 Project Inc.
+
+ Written by Mark Vojkovich
+*/
+
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include <X11/X.h>
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "xf86str.h"
+#include "mi.h"
+#include "miline.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xaawrap.h"
+#include "servermd.h"
+
+/* Screen funcs */
+
+static void XAAOverCopyWindow(WindowPtr, DDXPointRec, RegionPtr);
+static void XAAOverWindowExposures(WindowPtr, RegionPtr, RegionPtr);
+
+static int XAAOverStippledFillChooser(GCPtr);
+static int XAAOverOpaqueStippledFillChooser(GCPtr);
+static int XAAOverTiledFillChooser(GCPtr);
+
+/* GC funcs */
+
+static RegionPtr XAAOverCopyArea(DrawablePtr, DrawablePtr, GC *,
+ int, int, int, int, int, int);
+static RegionPtr XAAOverCopyPlane(DrawablePtr, DrawablePtr, GCPtr,
+ int, int, int, int, int, int, unsigned long);
+static void XAAOverPushPixelsSolid(GCPtr, PixmapPtr, DrawablePtr, int,
+ int, int, int);
+static void XAAOverPolyFillRectSolid(DrawablePtr, GCPtr, int, xRectangle*);
+static void XAAOverPolyFillRectStippled(DrawablePtr, GCPtr, int, xRectangle*);
+static void XAAOverPolyFillRectOpaqueStippled(DrawablePtr, GCPtr,
+ int, xRectangle*);
+static void XAAOverPolyFillRectTiled(DrawablePtr, GCPtr, int, xRectangle*);
+static void XAAOverFillSpansSolid(DrawablePtr, GCPtr, int, DDXPointPtr,
+ int*, int);
+static void XAAOverFillSpansStippled(DrawablePtr, GCPtr, int, DDXPointPtr,
+ int*, int);
+static void XAAOverFillSpansOpaqueStippled(DrawablePtr, GCPtr, int,
+ DDXPointPtr, int*, int);
+static void XAAOverFillSpansTiled(DrawablePtr, GCPtr, int, DDXPointPtr,
+ int*, int);
+static int XAAOverPolyText8TE(DrawablePtr, GCPtr, int, int, int, char *);
+static int XAAOverPolyText16TE(DrawablePtr, GCPtr, int, int, int,
+ unsigned short*);
+static void XAAOverImageText8TE(DrawablePtr, GCPtr, int, int, int, char*);
+static void XAAOverImageText16TE(DrawablePtr, GCPtr, int, int, int,
+ unsigned short*);
+static void XAAOverImageGlyphBltTE(DrawablePtr, GCPtr, int, int,
+ unsigned int, CharInfoPtr*, pointer);
+static void XAAOverPolyGlyphBltTE(DrawablePtr, GCPtr, int, int,
+ unsigned int, CharInfoPtr*, pointer);
+static int XAAOverPolyText8NonTE(DrawablePtr, GCPtr, int, int, int, char*);
+static int XAAOverPolyText16NonTE(DrawablePtr, GCPtr, int, int, int,
+ unsigned short*);
+static void XAAOverImageText8NonTE(DrawablePtr, GCPtr, int, int, int, char*);
+static void XAAOverImageText16NonTE(DrawablePtr, GCPtr, int, int, int,
+ unsigned short*);
+static void XAAOverImageGlyphBltNonTE(DrawablePtr, GCPtr, int, int,
+ unsigned int, CharInfoPtr *, pointer);
+static void XAAOverPolyGlyphBltNonTE(DrawablePtr, GCPtr, int, int,
+ unsigned int, CharInfoPtr *, pointer);
+static void XAAOverPolyRectangleThinSolid(DrawablePtr, GCPtr, int, xRectangle*);
+static void XAAOverPolylinesWideSolid(DrawablePtr, GCPtr, int, int,
+ DDXPointPtr);
+static void XAAOverPolylinesThinSolid(DrawablePtr, GCPtr, int, int,
+ DDXPointPtr);
+static void XAAOverPolySegmentThinSolid(DrawablePtr, GCPtr, int, xSegment*);
+static void XAAOverPolylinesThinDashed(DrawablePtr, GCPtr, int, int,
+ DDXPointPtr);
+static void XAAOverPolySegmentThinDashed(DrawablePtr, GCPtr, int, xSegment*);
+static void XAAOverFillPolygonSolid(DrawablePtr, GCPtr, int, int, int,
+ DDXPointPtr);
+static void XAAOverFillPolygonStippled(DrawablePtr, GCPtr, int, int, int,
+ DDXPointPtr);
+static void XAAOverFillPolygonOpaqueStippled(DrawablePtr, GCPtr, int, int, int,
+ DDXPointPtr);
+static void XAAOverFillPolygonTiled(DrawablePtr, GCPtr, int, int, int,
+ DDXPointPtr);
+static void XAAOverPolyFillArcSolid(DrawablePtr, GCPtr, int, xArc*);
+static void XAAOverPutImage(DrawablePtr, GCPtr, int, int, int, int, int,
+ int, int, char*);
+
+
+typedef struct {
+ ScrnInfoPtr pScrn;
+ DepthChangeFuncPtr callback;
+ int currentDepth;
+/* GC funcs */
+ RegionPtr (*CopyArea)(DrawablePtr, DrawablePtr, GC *,
+ int, int, int, int, int, int);
+ RegionPtr (*CopyPlane)(DrawablePtr, DrawablePtr, GCPtr,
+ int, int, int, int, int, int, unsigned long);
+ void (*PushPixelsSolid)(GCPtr, PixmapPtr, DrawablePtr, int, int, int, int);
+ void (*PolyFillRectSolid)(DrawablePtr, GCPtr, int, xRectangle*);
+ void (*PolyFillRectStippled)(DrawablePtr, GCPtr, int, xRectangle*);
+ void (*PolyFillRectOpaqueStippled)(DrawablePtr, GCPtr, int, xRectangle*);
+ void (*PolyFillRectTiled)(DrawablePtr, GCPtr, int, xRectangle*);
+ void (*FillSpansSolid)(DrawablePtr, GCPtr, int, DDXPointPtr, int*, int);
+ void (*FillSpansStippled)(DrawablePtr, GCPtr, int, DDXPointPtr, int*, int);
+ void (*FillSpansOpaqueStippled)(DrawablePtr,GCPtr,int,DDXPointPtr,int*,int);
+ void (*FillSpansTiled)(DrawablePtr, GCPtr, int, DDXPointPtr, int*, int);
+ int (*PolyText8TE)(DrawablePtr, GCPtr, int, int, int, char *);
+ int (*PolyText16TE)(DrawablePtr, GCPtr, int, int, int, unsigned short*);
+ void (*ImageText8TE)(DrawablePtr, GCPtr, int, int, int, char*);
+ void (*ImageText16TE)(DrawablePtr, GCPtr, int, int, int, unsigned short*);
+ void (*ImageGlyphBltTE)(DrawablePtr, GCPtr, int, int, unsigned int,
+ CharInfoPtr*, pointer);
+ void (*PolyGlyphBltTE)(DrawablePtr, GCPtr, int, int, unsigned int,
+ CharInfoPtr*, pointer);
+ int (*PolyText8NonTE)(DrawablePtr, GCPtr, int, int, int, char*);
+ int (*PolyText16NonTE)(DrawablePtr, GCPtr, int, int, int, unsigned short*);
+ void (*ImageText8NonTE)(DrawablePtr, GCPtr, int, int, int, char*);
+ void (*ImageText16NonTE)(DrawablePtr, GCPtr, int, int, int, unsigned short*);
+ void (*ImageGlyphBltNonTE)(DrawablePtr, GCPtr, int, int, unsigned int,
+ CharInfoPtr *, pointer);
+ void (*PolyGlyphBltNonTE)(DrawablePtr, GCPtr, int, int, unsigned int,
+ CharInfoPtr *, pointer);
+ void (*PolyRectangleThinSolid)(DrawablePtr, GCPtr, int, xRectangle*);
+ void (*PolylinesWideSolid)(DrawablePtr, GCPtr, int, int, DDXPointPtr);
+
+ void (*PolylinesThinSolid)(DrawablePtr, GCPtr, int, int, DDXPointPtr);
+ void (*PolySegmentThinSolid)(DrawablePtr, GCPtr, int, xSegment*);
+ void (*PolylinesThinDashed)(DrawablePtr, GCPtr, int, int, DDXPointPtr);
+ void (*PolySegmentThinDashed)(DrawablePtr, GCPtr, int, xSegment*);
+ void (*FillPolygonSolid)(DrawablePtr, GCPtr, int, int, int, DDXPointPtr);
+ void (*FillPolygonStippled)(DrawablePtr, GCPtr, int, int, int, DDXPointPtr);
+ void (*FillPolygonOpaqueStippled)(DrawablePtr, GCPtr, int, int, int,
+ DDXPointPtr);
+ void (*FillPolygonTiled)(DrawablePtr, GCPtr, int, int, int, DDXPointPtr);
+ void (*PolyFillArcSolid)(DrawablePtr, GCPtr, int, xArc*);
+ void (*PutImage)(DrawablePtr, GCPtr, int, int, int, int, int, int,
+ int, char*);
+ int (*StippledFillChooser)(GCPtr);
+ int (*OpaqueStippledFillChooser)(GCPtr);
+ int (*TiledFillChooser)(GCPtr);
+} XAAOverlayRec, *XAAOverlayPtr;
+
+static int XAAOverlayKeyIndex;
+static DevPrivateKey XAAOverlayKey = &XAAOverlayKeyIndex;
+
+#define GET_OVERLAY_PRIV(pScreen) \
+ (XAAOverlayPtr)dixLookupPrivate(&(pScreen)->devPrivates, XAAOverlayKey)
+
+#define SWITCH_DEPTH(d) \
+ if(pOverPriv->currentDepth != d) { \
+ (*pOverPriv->callback)(pOverPriv->pScrn, d); \
+ pOverPriv->currentDepth = d; \
+ }
+
+
+Bool
+XAAInitDualFramebufferOverlay(
+ ScreenPtr pScreen,
+ DepthChangeFuncPtr callback
+){
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ XAAOverlayPtr pOverPriv;
+
+ if(!(pOverPriv = malloc(sizeof(XAAOverlayRec))))
+ return FALSE;
+
+ dixSetPrivate(&pScreen->devPrivates, XAAOverlayKey, pOverPriv);
+
+ pOverPriv->pScrn = pScrn;
+ pOverPriv->callback = callback;
+ pOverPriv->currentDepth = -1;
+
+ /* Overwrite key screen functions. The XAA core will clean up */
+
+ pScreen->CopyWindow = XAAOverCopyWindow;
+ pScreen->WindowExposures = XAAOverWindowExposures;
+
+ pOverPriv->StippledFillChooser = infoRec->StippledFillChooser;
+ pOverPriv->OpaqueStippledFillChooser = infoRec->OpaqueStippledFillChooser;
+ pOverPriv->TiledFillChooser = infoRec->TiledFillChooser;
+
+ infoRec->StippledFillChooser = XAAOverStippledFillChooser;
+ infoRec->OpaqueStippledFillChooser = XAAOverOpaqueStippledFillChooser;
+ infoRec->TiledFillChooser = XAAOverTiledFillChooser;
+
+ /* wrap all XAA GC rendering */
+
+ pOverPriv->CopyArea = infoRec->CopyArea;
+ pOverPriv->CopyPlane = infoRec->CopyPlane;
+ pOverPriv->PushPixelsSolid = infoRec->PushPixelsSolid;
+ pOverPriv->PolyFillRectSolid = infoRec->PolyFillRectSolid;
+ pOverPriv->PolyFillRectStippled = infoRec->PolyFillRectStippled;
+ pOverPriv->PolyFillRectOpaqueStippled = infoRec->PolyFillRectOpaqueStippled;
+ pOverPriv->PolyFillRectTiled = infoRec->PolyFillRectTiled;
+ pOverPriv->FillSpansSolid = infoRec->FillSpansSolid;
+ pOverPriv->FillSpansStippled = infoRec->FillSpansStippled;
+ pOverPriv->FillSpansOpaqueStippled = infoRec->FillSpansOpaqueStippled;
+ pOverPriv->FillSpansTiled = infoRec->FillSpansTiled;
+ pOverPriv->PolyText8TE = infoRec->PolyText8TE;
+ pOverPriv->PolyText16TE = infoRec->PolyText16TE;
+ pOverPriv->ImageText8TE = infoRec->ImageText8TE;
+ pOverPriv->ImageText16TE = infoRec->ImageText16TE;
+ pOverPriv->ImageGlyphBltTE = infoRec->ImageGlyphBltTE;
+ pOverPriv->PolyGlyphBltTE = infoRec->PolyGlyphBltTE;
+ pOverPriv->PolyText8NonTE = infoRec->PolyText8NonTE;
+ pOverPriv->PolyText16NonTE = infoRec->PolyText16NonTE;
+ pOverPriv->ImageText8NonTE = infoRec->ImageText8NonTE;
+ pOverPriv->ImageText16NonTE = infoRec->ImageText16NonTE;
+ pOverPriv->ImageGlyphBltNonTE = infoRec->ImageGlyphBltNonTE;
+ pOverPriv->PolyGlyphBltNonTE = infoRec->PolyGlyphBltNonTE;
+ pOverPriv->PolyRectangleThinSolid = infoRec->PolyRectangleThinSolid;
+ pOverPriv->PolylinesWideSolid = infoRec->PolylinesWideSolid;
+ pOverPriv->PolylinesThinSolid = infoRec->PolylinesThinSolid;
+ pOverPriv->PolySegmentThinSolid = infoRec->PolySegmentThinSolid;
+ pOverPriv->PolylinesThinDashed = infoRec->PolylinesThinDashed;
+ pOverPriv->PolySegmentThinDashed = infoRec->PolySegmentThinDashed;
+ pOverPriv->FillPolygonSolid = infoRec->FillPolygonSolid;
+ pOverPriv->FillPolygonStippled = infoRec->FillPolygonStippled;
+ pOverPriv->FillPolygonOpaqueStippled = infoRec->FillPolygonOpaqueStippled;
+ pOverPriv->FillPolygonTiled = infoRec->FillPolygonTiled;
+ pOverPriv->PolyFillArcSolid = infoRec->PolyFillArcSolid;
+ pOverPriv->PutImage = infoRec->PutImage;
+
+
+ if(infoRec->CopyArea)
+ infoRec->CopyArea = XAAOverCopyArea;
+ if(infoRec->CopyPlane)
+ infoRec->CopyPlane = XAAOverCopyPlane;
+ if(infoRec->PushPixelsSolid)
+ infoRec->PushPixelsSolid = XAAOverPushPixelsSolid;
+ if(infoRec->PolyFillRectSolid)
+ infoRec->PolyFillRectSolid = XAAOverPolyFillRectSolid;
+ if(infoRec->PolyFillRectStippled)
+ infoRec->PolyFillRectStippled = XAAOverPolyFillRectStippled;
+ if(infoRec->PolyFillRectOpaqueStippled)
+ infoRec->PolyFillRectOpaqueStippled = XAAOverPolyFillRectOpaqueStippled;
+ if(infoRec->PolyFillRectTiled)
+ infoRec->PolyFillRectTiled = XAAOverPolyFillRectTiled;
+ if(infoRec->FillSpansSolid)
+ infoRec->FillSpansSolid = XAAOverFillSpansSolid;
+ if(infoRec->FillSpansStippled)
+ infoRec->FillSpansStippled = XAAOverFillSpansStippled;
+ if(infoRec->FillSpansOpaqueStippled)
+ infoRec->FillSpansOpaqueStippled = XAAOverFillSpansOpaqueStippled;
+ if(infoRec->FillSpansTiled)
+ infoRec->FillSpansTiled = XAAOverFillSpansTiled;
+ if(infoRec->PolyText8TE)
+ infoRec->PolyText8TE = XAAOverPolyText8TE;
+ if(infoRec->PolyText16TE)
+ infoRec->PolyText16TE = XAAOverPolyText16TE;
+ if(infoRec->ImageText8TE)
+ infoRec->ImageText8TE = XAAOverImageText8TE;
+ if(infoRec->ImageText16TE)
+ infoRec->ImageText16TE = XAAOverImageText16TE;
+ if(infoRec->ImageGlyphBltTE)
+ infoRec->ImageGlyphBltTE = XAAOverImageGlyphBltTE;
+ if(infoRec->PolyGlyphBltTE)
+ infoRec->PolyGlyphBltTE = XAAOverPolyGlyphBltTE;
+ if(infoRec->PolyText8NonTE)
+ infoRec->PolyText8NonTE = XAAOverPolyText8NonTE;
+ if(infoRec->PolyText16NonTE)
+ infoRec->PolyText16NonTE = XAAOverPolyText16NonTE;
+ if(infoRec->ImageText8NonTE)
+ infoRec->ImageText8NonTE = XAAOverImageText8NonTE;
+ if(infoRec->ImageText16NonTE)
+ infoRec->ImageText16NonTE = XAAOverImageText16NonTE;
+ if(infoRec->ImageGlyphBltNonTE)
+ infoRec->ImageGlyphBltNonTE = XAAOverImageGlyphBltNonTE;
+ if(infoRec->PolyGlyphBltNonTE)
+ infoRec->PolyGlyphBltNonTE = XAAOverPolyGlyphBltNonTE;
+ if(infoRec->PolyRectangleThinSolid)
+ infoRec->PolyRectangleThinSolid = XAAOverPolyRectangleThinSolid;
+ if(infoRec->PolylinesWideSolid)
+ infoRec->PolylinesWideSolid = XAAOverPolylinesWideSolid;
+ if(infoRec->PolylinesThinSolid)
+ infoRec->PolylinesThinSolid = XAAOverPolylinesThinSolid;
+ if(infoRec->PolySegmentThinSolid)
+ infoRec->PolySegmentThinSolid = XAAOverPolySegmentThinSolid;
+ if(infoRec->PolylinesThinDashed)
+ infoRec->PolylinesThinDashed = XAAOverPolylinesThinDashed;
+ if(infoRec->PolySegmentThinDashed)
+ infoRec->PolySegmentThinDashed = XAAOverPolySegmentThinDashed;
+ if(infoRec->FillPolygonSolid)
+ infoRec->FillPolygonSolid = XAAOverFillPolygonSolid;
+ if(infoRec->FillPolygonStippled)
+ infoRec->FillPolygonStippled = XAAOverFillPolygonStippled;
+ if(infoRec->FillPolygonOpaqueStippled)
+ infoRec->FillPolygonOpaqueStippled = XAAOverFillPolygonOpaqueStippled;
+ if(infoRec->FillPolygonTiled)
+ infoRec->FillPolygonTiled = XAAOverFillPolygonTiled;
+ if(infoRec->PolyFillArcSolid)
+ infoRec->PolyFillArcSolid = XAAOverPolyFillArcSolid;
+ if(infoRec->PutImage)
+ infoRec->PutImage = XAAOverPutImage;
+
+ return TRUE;
+}
+
+/*********************** Screen functions ************************/
+
+void
+XAAOverCopyWindow(
+ WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc
+){
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pScreen);
+ ScrnInfoPtr pScrn = infoRec->pScrn;
+ DDXPointPtr ppt, pptSrc;
+ RegionRec rgnDst;
+ BoxPtr pbox;
+ int i, nbox, dx, dy;
+ WindowPtr pRoot = WindowTable[pScreen->myNum];
+
+
+ if (!pScrn->vtSema || !infoRec->ScreenToScreenBitBlt) {
+ XAA_SCREEN_PROLOGUE (pScreen, CopyWindow);
+ if(pScrn->vtSema && infoRec->NeedToSync) {
+ (*infoRec->Sync)(pScrn);
+ infoRec->NeedToSync = FALSE;
+ }
+ (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc);
+ XAA_SCREEN_EPILOGUE (pScreen, CopyWindow, XAAOverCopyWindow);
+ return;
+ }
+
+ infoRec->ScratchGC.alu = GXcopy;
+ infoRec->ScratchGC.planemask = ~0;
+
+ REGION_NULL(pScreen, &rgnDst);
+
+ dx = ptOldOrg.x - pWin->drawable.x;
+ dy = ptOldOrg.y - pWin->drawable.y;
+ REGION_TRANSLATE(pScreen, prgnSrc, -dx, -dy);
+ REGION_INTERSECT(pScreen, &rgnDst, &pWin->borderClip, prgnSrc);
+
+ nbox = REGION_NUM_RECTS(&rgnDst);
+ if(nbox &&
+ (pptSrc = (DDXPointPtr )malloc(nbox * sizeof(DDXPointRec)))) {
+
+ pbox = REGION_RECTS(&rgnDst);
+ for (i = nbox, ppt = pptSrc; i--; ppt++, pbox++) {
+ ppt->x = pbox->x1 + dx;
+ ppt->y = pbox->y1 + dy;
+ }
+
+ SWITCH_DEPTH(8);
+ XAADoBitBlt((DrawablePtr)pRoot, (DrawablePtr)pRoot,
+ &(infoRec->ScratchGC), &rgnDst, pptSrc);
+
+ if(pWin->drawable.bitsPerPixel != 8) {
+ SWITCH_DEPTH(pScrn->depth);
+ XAADoBitBlt((DrawablePtr)pRoot, (DrawablePtr)pRoot,
+ &(infoRec->ScratchGC), &rgnDst, pptSrc);
+ }
+
+ free(pptSrc);
+ }
+
+ REGION_UNINIT(pScreen, &rgnDst);
+
+ if(pWin->drawable.depth == 8) {
+ REGION_NULL(pScreen, &rgnDst);
+ miSegregateChildren(pWin, &rgnDst, pScrn->depth);
+ if(REGION_NOTEMPTY(pScreen, &rgnDst)) {
+ REGION_INTERSECT(pScreen, &rgnDst, &rgnDst, prgnSrc);
+ nbox = REGION_NUM_RECTS(&rgnDst);
+ if(nbox &&
+ (pptSrc = (DDXPointPtr )malloc(nbox * sizeof(DDXPointRec)))){
+
+ pbox = REGION_RECTS(&rgnDst);
+ for (i = nbox, ppt = pptSrc; i--; ppt++, pbox++) {
+ ppt->x = pbox->x1 + dx;
+ ppt->y = pbox->y1 + dy;
+ }
+
+ SWITCH_DEPTH(pScrn->depth);
+ XAADoBitBlt((DrawablePtr)pRoot, (DrawablePtr)pRoot,
+ &(infoRec->ScratchGC), &rgnDst, pptSrc);
+ free(pptSrc);
+ }
+ }
+ REGION_UNINIT(pScreen, &rgnDst);
+ }
+}
+
+
+void
+XAAOverWindowExposures(
+ WindowPtr pWin,
+ RegionPtr pReg,
+ RegionPtr pOtherReg
+){
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+
+ if((pWin->drawable.bitsPerPixel != 8) && infoRec->pScrn->vtSema) {
+ if(REGION_NUM_RECTS(pReg) && infoRec->FillSolidRects) {
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pScreen);
+
+ SWITCH_DEPTH(8);
+ (*infoRec->FillSolidRects)(infoRec->pScrn,
+ infoRec->pScrn->colorKey, GXcopy, ~0,
+ REGION_NUM_RECTS(pReg), REGION_RECTS(pReg));
+ miWindowExposures(pWin, pReg, pOtherReg);
+ return;
+ } else if(infoRec->NeedToSync) {
+ (*infoRec->Sync)(infoRec->pScrn);
+ infoRec->NeedToSync = FALSE;
+ }
+ }
+
+ XAA_SCREEN_PROLOGUE (pScreen, WindowExposures);
+ (*pScreen->WindowExposures) (pWin, pReg, pOtherReg);
+ XAA_SCREEN_EPILOGUE(pScreen, WindowExposures, XAAOverWindowExposures);
+}
+
+/********************* Choosers *************************/
+
+static int
+XAAOverStippledFillChooser(GCPtr pGC)
+{
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+ int ret;
+
+ ret = (*pOverPriv->StippledFillChooser)(pGC);
+
+ if((pGC->depth == 8) &&
+ ((ret == DO_COLOR_8x8) || (ret == DO_CACHE_BLT))) {
+ ret = 0;
+ }
+
+ return ret;
+}
+
+static int
+XAAOverOpaqueStippledFillChooser(GCPtr pGC)
+{
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+ int ret;
+
+ ret = (*pOverPriv->OpaqueStippledFillChooser)(pGC);
+
+ if((pGC->depth == 8) &&
+ ((ret == DO_COLOR_8x8) || (ret == DO_CACHE_BLT))) {
+ ret = 0;
+ }
+
+ return ret;
+}
+
+static int
+XAAOverTiledFillChooser(GCPtr pGC)
+{
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+ int ret;
+
+ ret = (*pOverPriv->TiledFillChooser)(pGC);
+
+ if((pGC->depth == 8) &&
+ ((ret == DO_COLOR_8x8) || (ret == DO_CACHE_BLT))) {
+ ret = 0;
+ }
+
+ return ret;
+}
+
+
+/**************************** GC Functions **************************/
+
+static RegionPtr
+XAAOverCopyArea(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ return (*pOverPriv->CopyArea)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty);
+}
+
+static RegionPtr
+XAAOverCopyPlane(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx, int srcy,
+ int width, int height,
+ int dstx, int dsty,
+ unsigned long bitPlane
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ return (*pOverPriv->CopyPlane)(pSrc, pDst,
+ pGC, srcx, srcy, width, height, dstx, dsty, bitPlane);
+
+}
+
+static void
+XAAOverPushPixelsSolid(
+ GCPtr pGC,
+ PixmapPtr pBitMap,
+ DrawablePtr pDraw,
+ int dx, int dy,
+ int xOrg, int yOrg
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PushPixelsSolid)(pGC, pBitMap, pDraw, dx, dy, xOrg, yOrg);
+}
+
+
+
+static void
+XAAOverPolyFillRectSolid(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolyFillRectSolid)(pDraw, pGC, nrectFill, prectInit);
+}
+
+static void
+XAAOverPolyFillRectStippled(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolyFillRectStippled)(pDraw, pGC, nrectFill, prectInit);
+}
+
+
+static void
+XAAOverPolyFillRectOpaqueStippled(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolyFillRectOpaqueStippled)(pDraw, pGC, nrectFill, prectInit);
+}
+
+static void
+XAAOverPolyFillRectTiled(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolyFillRectTiled)(pDraw, pGC, nrectFill, prectInit);
+}
+
+
+static void
+XAAOverFillSpansSolid(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nInit,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->FillSpansSolid)(
+ pDraw, pGC, nInit, ppt, pwidth, fSorted);
+}
+
+
+static void
+XAAOverFillSpansStippled(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nInit,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->FillSpansStippled)(pDraw, pGC, nInit, ppt, pwidth, fSorted);
+}
+
+static void
+XAAOverFillSpansOpaqueStippled(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nInit,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->FillSpansOpaqueStippled)(
+ pDraw, pGC, nInit, ppt, pwidth, fSorted);
+}
+
+
+static void
+XAAOverFillSpansTiled(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nInit,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->FillSpansTiled)(pDraw, pGC, nInit, ppt, pwidth, fSorted);
+}
+
+static int
+XAAOverPolyText8TE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ return (*pOverPriv->PolyText8TE)(pDraw, pGC, x, y, count, chars);
+}
+
+
+static int
+XAAOverPolyText16TE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ return (*pOverPriv->PolyText16TE)(pDraw, pGC, x, y, count, chars);
+}
+
+
+static void
+XAAOverImageText8TE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->ImageText8TE)(pDraw, pGC, x, y, count, chars);
+}
+
+
+static void
+XAAOverImageText16TE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->ImageText16TE)(pDraw, pGC, x, y, count, chars);
+}
+
+static void
+XAAOverImageGlyphBltTE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->ImageGlyphBltTE)(
+ pDraw, pGC, xInit, yInit, nglyph, ppci, pglyphBase);
+}
+
+static void
+XAAOverPolyGlyphBltTE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolyGlyphBltTE)(
+ pDraw, pGC, xInit, yInit, nglyph, ppci, pglyphBase);
+}
+
+static int
+XAAOverPolyText8NonTE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ return (*pOverPriv->PolyText8NonTE)(pDraw, pGC, x, y, count, chars);
+}
+
+
+static int
+XAAOverPolyText16NonTE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ return (*pOverPriv->PolyText16NonTE)(pDraw, pGC, x, y, count, chars);
+}
+
+static void
+XAAOverImageText8NonTE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->ImageText8NonTE)(pDraw, pGC, x, y, count, chars);
+}
+
+static void
+XAAOverImageText16NonTE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->ImageText16NonTE)(pDraw, pGC, x, y, count, chars);
+}
+
+
+static void
+XAAOverImageGlyphBltNonTE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->ImageGlyphBltNonTE)(
+ pDraw, pGC, xInit, yInit, nglyph, ppci, pglyphBase);
+}
+
+static void
+XAAOverPolyGlyphBltNonTE(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolyGlyphBltNonTE)(
+ pDraw, pGC, xInit, yInit, nglyph, ppci, pglyphBase);
+}
+
+static void
+XAAOverPolyRectangleThinSolid(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nRectsInit,
+ xRectangle *pRectsInit
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolyRectangleThinSolid)(pDraw, pGC, nRectsInit, pRectsInit);
+}
+
+
+
+static void
+XAAOverPolylinesWideSolid(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pPts
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolylinesWideSolid)(pDraw, pGC, mode, npt, pPts);
+}
+
+
+static void
+XAAOverPolylinesThinSolid(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pPts
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolylinesThinSolid)(pDraw, pGC, mode, npt, pPts);
+}
+
+static void
+XAAOverPolySegmentThinSolid(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolySegmentThinSolid)(pDraw, pGC, nseg, pSeg);
+}
+
+static void
+XAAOverPolylinesThinDashed(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pPts
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolylinesThinDashed)(pDraw, pGC, mode, npt, pPts);
+}
+
+static void
+XAAOverPolySegmentThinDashed(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolySegmentThinDashed)(pDraw, pGC, nseg, pSeg);
+}
+
+
+static void
+XAAOverFillPolygonSolid(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->FillPolygonSolid)(pDraw, pGC, shape, mode, count, ptsIn);
+}
+
+static void
+XAAOverFillPolygonStippled(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->FillPolygonStippled)(pDraw, pGC, shape, mode, count, ptsIn);
+}
+
+
+static void
+XAAOverFillPolygonOpaqueStippled(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->FillPolygonOpaqueStippled)(
+ pDraw, pGC, shape, mode, count, ptsIn);
+}
+
+static void
+XAAOverFillPolygonTiled(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->FillPolygonTiled)(pDraw, pGC, shape, mode, count, ptsIn);
+}
+
+
+static void
+XAAOverPolyFillArcSolid(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int narcs,
+ xArc *parcs
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PolyFillArcSolid)(pDraw, pGC, narcs, parcs);
+}
+
+
+static void
+XAAOverPutImage(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int depth,
+ int x,
+ int y,
+ int w,
+ int h,
+ int leftPad,
+ int format,
+ char *pImage
+){
+ XAAOverlayPtr pOverPriv = GET_OVERLAY_PRIV(pGC->pScreen);
+
+ SWITCH_DEPTH(pGC->depth);
+
+ (*pOverPriv->PutImage)(pDraw, pGC, depth, x, y, w, h,
+ leftPad, format, pImage);
+}
+
diff --git a/xorg-server/hw/xfree86/xaa/xaaPCache.c b/xorg-server/hw/xfree86/xaa/xaaPCache.c
index 7e3011bd5..62726d539 100644
--- a/xorg-server/hw/xfree86/xaa/xaaPCache.c
+++ b/xorg-server/hw/xfree86/xaa/xaaPCache.c
@@ -1,2380 +1,2380 @@
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <string.h>
-
-#include "misc.h"
-#include "xf86.h"
-#include "xf86_OSproc.h"
-
-#include <X11/X.h>
-#include "scrnintstr.h"
-#include "gc.h"
-#include "mi.h"
-#include "pixmapstr.h"
-#include "windowstr.h"
-#include "regionstr.h"
-#include "servermd.h"
-#include "xf86str.h"
-#include "xaa.h"
-#include "xaacexp.h"
-#include "xaalocal.h"
-#include "xaawrap.h"
-
-#define MAX_COLOR 32
-#define MAX_MONO 32
-#define MAX_8 32
-#define MAX_128 32
-#define MAX_256 32
-#define MAX_512 16
-
-static int CacheInitIndex = -1;
-#define CACHEINIT(p) ((p)->privates[CacheInitIndex].val)
-
-
-typedef struct _CacheLink {
- int x;
- int y;
- int w;
- int h;
- struct _CacheLink *next;
-} CacheLink, *CacheLinkPtr;
-
-
-static void
-TransferList(CacheLinkPtr list, XAACacheInfoPtr array, int num)
-{
- while(num--) {
- array->x = list->x;
- array->y = list->y;
- array->w = list->w;
- array->h = list->h;
- array->serialNumber = 0;
- array->fg = array->bg = -1;
- list = list->next;
- array++;
- }
-}
-
-
-
-static CacheLinkPtr
-Enlist(CacheLinkPtr link, int x, int y, int w, int h)
-{
- CacheLinkPtr newLink;
-
- newLink = xalloc(sizeof(CacheLink));
- newLink->next = link;
- newLink->x = x; newLink->y = y;
- newLink->w = w; newLink->h = h;
- return newLink;
-}
-
-
-
-static CacheLinkPtr
-Delist(CacheLinkPtr link) {
- CacheLinkPtr ret = NULL;
-
- if(link) {
- ret = link->next;
- xfree(link);
- }
- return ret;
-}
-
-
-
-static void
-FreeList(CacheLinkPtr link) {
- CacheLinkPtr tmp;
-
- while(link) {
- tmp = link;
- link = link->next;
- xfree(tmp);
- }
-}
-
-
-
-static CacheLinkPtr
-QuadLinks(CacheLinkPtr big, CacheLinkPtr little)
-{
- /* CAUTION: This doesn't free big */
- int w1, w2, h1, h2;
-
- while(big) {
- w1 = big->w >> 1;
- w2 = big->w - w1;
- h1 = big->h >> 1;
- h2 = big->h - h1;
-
- little = Enlist(little, big->x, big->y, w1, h1);
- little = Enlist(little, big->x + w1, big->y, w2, h1);
- little = Enlist(little, big->x, big->y + h1, w1, h2);
- little = Enlist(little, big->x + w1, big->y + h1, w2, h2);
-
- big = big->next;
- }
- return little;
-}
-
-
-static void
-SubdivideList(CacheLinkPtr *large, CacheLinkPtr *small)
-{
- CacheLinkPtr big = *large;
- CacheLinkPtr little = *small;
- int size = big->w >> 1;
-
- little = Enlist(little, big->x, big->y, size, size);
- little = Enlist(little, big->x + size, big->y, size, size);
- little = Enlist(little, big->x, big->y + size, size, size);
- little = Enlist(little, big->x + size, big->y + size, size, size);
- *small = little;
- big = Delist(big);
- *large = big;
-}
-
-static void
-FreePixmapCachePrivate(XAAPixmapCachePrivatePtr pPriv)
-{
- if(!pPriv) return;
-
- if(pPriv->Info512)
- xfree(pPriv->Info512);
- if(pPriv->Info256)
- xfree(pPriv->Info256);
- if(pPriv->Info128)
- xfree(pPriv->Info128);
- if(pPriv->InfoColor)
- xfree(pPriv->InfoColor);
- if(pPriv->InfoMono)
- xfree(pPriv->InfoMono);
- if(pPriv->InfoPartial)
- xfree(pPriv->InfoPartial);
-
- xfree(pPriv);
-}
-
-void
-XAAClosePixmapCache(ScreenPtr pScreen)
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
-
- if(infoRec->PixmapCachePrivate)
- FreePixmapCachePrivate(
- (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate);
-
- infoRec->PixmapCachePrivate = NULL;
-}
-
-
-
-static CacheLinkPtr
-ThinOutPartials(
- CacheLinkPtr ListPartial,
- int *num, int *maxw, int *maxh
-) {
-/* This guy's job is to get at least 4 big slots out of a list of fragments */
-
- CacheLinkPtr List64, List32, List16, List8, pCur, next, ListKeepers;
- int Num64, Num32, Num16, Num8, NumKeepers;
- int w, h;
-
- List64 = List32 = List16 = List8 = ListKeepers = NULL;
- Num64 = Num32 = Num16 = Num8 = NumKeepers = 0;
- w = h = 0;
-
- /* We sort partials by how large a square tile they can cache.
- If a partial can't store a 64x64, 32x32, 16x16 or 8x8 tile,
- we free it. */
-
- pCur = ListPartial;
- while(pCur) {
- next = pCur->next;
- if((pCur->w >= 64) && (pCur->h >= 64)) {
- pCur->next = List64; List64 = pCur;
- Num64++;
- } else
- if((pCur->w >= 32) && (pCur->h >= 32)) {
- pCur->next = List32; List32 = pCur;
- Num32++;
- } else
- if((pCur->w >= 16) && (pCur->h >= 16)) {
- pCur->next = List16; List16 = pCur;
- Num16++;
- } else
- if((pCur->w >= 8) && (pCur->h >= 8)) {
- pCur->next = List8; List8 = pCur;
- Num8++;
- } else {
- xfree(pCur);
- }
-
- pCur = next;
- }
-
- /* We save all the tiles from the largest bin that we can get
- at least 4 of. If there are too few of a bigger slot, we
- cut it in fourths to make smaller slots. */
-
- if(Num64 >= 4) {
- ListKeepers = List64; List64 = NULL;
- NumKeepers = Num64;
- goto GOT_EM;
- } else if(Num64) {
- List32 = QuadLinks(List64, List32);
- Num32 += Num64 * 4;
- Num64 = 0;
- }
-
- if(Num32 >= 4) {
- ListKeepers = List32; List32 = NULL;
- NumKeepers = Num32;
- goto GOT_EM;
- } else if(Num32) {
- List16 = QuadLinks(List32, List16);
- Num16 += Num32 * 4;
- Num32 = 0;
- }
-
- if(Num16 >= 4) {
- ListKeepers = List16; List16 = NULL;
- NumKeepers = Num16;
- goto GOT_EM;
- } else if(Num16) {
- List8 = QuadLinks(List16, List8);
- Num8 += Num16 * 4;
- Num16 = 0;
- }
-
- if(Num8 >= 4) {
- ListKeepers = List8; List8 = NULL;
- NumKeepers = Num8;
- goto GOT_EM;
- }
-
-GOT_EM:
-
- /* Free the ones we aren't using */
-
- if(List64) FreeList(List64);
- if(List32) FreeList(List32);
- if(List16) FreeList(List16);
- if(List8) FreeList(List8);
-
-
- /* Enlarge the slots if we can */
-
- if(ListKeepers) {
- CacheLinkPtr pLink = ListKeepers;
- w = h = 128;
-
- while(pLink) {
- if(pLink->w < w) w = pLink->w;
- if(pLink->h < h) h = pLink->h;
- pLink = pLink->next;
- }
- }
-
- *maxw = w;
- *maxh = h;
- *num = NumKeepers;
- return ListKeepers;
-}
-
-static void
-ConvertColorToMono(
- CacheLinkPtr *ColorList,
- int ColorW, int ColorH,
- CacheLinkPtr *MonoList,
- int MonoW, int MonoH
-){
- int x, y, w;
-
- x = (*ColorList)->x; y = (*ColorList)->y;
- *ColorList = Delist(*ColorList);
-
- while(ColorH) {
- ColorH -= MonoH;
- for(w = 0; w <= (ColorW - MonoW); w += MonoW)
- *MonoList = Enlist(*MonoList, x + w, y + ColorH, MonoW, MonoH);
- }
-}
-
-static void
-ConvertAllPartialsTo8x8(
- int *NumMono, int *NumColor,
- CacheLinkPtr ListPartial,
- CacheLinkPtr *ListMono,
- CacheLinkPtr *ListColor,
- XAAInfoRecPtr infoRec
-){
-/* This guy extracts as many 8x8 slots as it can out of fragments */
-
- int ColorH = infoRec->CacheHeightColor8x8Pattern;
- int ColorW = infoRec->CacheWidthColor8x8Pattern;
- int MonoH = infoRec->CacheHeightMono8x8Pattern;
- int MonoW = infoRec->CacheWidthMono8x8Pattern;
- int x, y, w, Height, Width;
- Bool DoColor = (infoRec->PixmapCacheFlags & CACHE_COLOR_8x8);
- Bool DoMono = (infoRec->PixmapCacheFlags & CACHE_MONO_8x8);
- CacheLinkPtr pLink = ListPartial;
- CacheLinkPtr MonoList = *ListMono, ColorList = *ListColor;
-
- if(DoColor && DoMono) {
- /* we assume color patterns take more space than color ones */
- if(MonoH > ColorH) ColorH = MonoH;
- if(MonoW > ColorW) ColorW = MonoW;
- }
-
- /* Break up the area into as many Color and Mono slots as we can */
-
- while(pLink) {
- Height = pLink->h;
- Width = pLink->w;
- x = pLink->x;
- y = pLink->y;
-
- if(DoColor) {
- while(Height >= ColorH) {
- Height -= ColorH;
- for(w = 0; w <= (Width - ColorW); w += ColorW) {
- ColorList = Enlist(
- ColorList, x + w, y + Height, ColorW, ColorH);
- (*NumColor)++;
- }
- }
- }
-
- if(DoMono && (Height >= MonoH)) {
- while(Height >= MonoH) {
- Height -= MonoH;
- for(w = 0; w <= (Width - MonoW); w += MonoW) {
- MonoList = Enlist(
- MonoList, x + w, y + Height, MonoW, MonoH);
- (*NumMono)++;
- }
- }
- }
-
- pLink = pLink->next;
- }
-
-
- *ListMono = MonoList;
- *ListColor = ColorList;
- FreeList(ListPartial);
-}
-
-
-static CacheLinkPtr
-ExtractOneThatFits(CacheLinkPtr *initList, int w, int h)
-{
- CacheLinkPtr list = *initList;
- CacheLinkPtr prev = NULL;
-
- while(list) {
- if((list->w >= w) && (list->h >= h))
- break;
- prev = list;
- list = list->next;
- }
-
- if(list) {
- if(prev)
- prev->next = list->next;
- else
- *initList = list->next;
-
- list->next = NULL;
- }
-
- return list;
-}
-
-
-static CacheLinkPtr
-ConvertSomePartialsTo8x8(
- int *NumMono, int *NumColor, int *NumPartial,
- CacheLinkPtr ListPartial,
- CacheLinkPtr *ListMono,
- CacheLinkPtr *ListColor,
- int *maxw, int *maxh,
- XAAInfoRecPtr infoRec
-){
-/* This guy tries to get 4 of each type of 8x8 slot requested out of
- a list of fragments all while trying to retain some big fragments
- for the cache blits */
-
- int ColorH = infoRec->CacheHeightColor8x8Pattern;
- int ColorW = infoRec->CacheWidthColor8x8Pattern;
- int MonoH = infoRec->CacheHeightMono8x8Pattern;
- int MonoW = infoRec->CacheWidthMono8x8Pattern;
- Bool DoColor = (infoRec->PixmapCacheFlags & CACHE_COLOR_8x8);
- Bool DoMono = (infoRec->PixmapCacheFlags & CACHE_MONO_8x8);
- CacheLinkPtr List64, List32, List16, List8, pCur, next, ListKeepers;
- CacheLinkPtr MonoList = *ListMono, ColorList = *ListColor;
- int Num64, Num32, Num16, Num8, NumKeepers;
- int w, h, Width, Height;
- int MonosPerColor = 1;
-
- if(DoColor && DoMono) {
- /* we assume color patterns take more space than color ones */
- if(MonoH > ColorH) ColorH = MonoH;
- if(MonoW > ColorW) ColorW = MonoW;
- MonosPerColor = (ColorH/MonoH) * (ColorW/MonoW);
- }
-
- List64 = List32 = List16 = List8 = ListKeepers = MonoList = ColorList = NULL;
- Num64 = Num32 = Num16 = Num8 = NumKeepers = 0;
- Width = Height = 0;
-
- /* We sort partials by how large a square tile they can cache.
- We make 8x8 patterns from the leftovers if we can. */
-
- pCur = ListPartial;
- while(pCur) {
- next = pCur->next;
- if((pCur->w >= 64) && (pCur->h >= 64)) {
- pCur->next = List64; List64 = pCur;
- Num64++;
- } else
- if((pCur->w >= 32) && (pCur->h >= 32)) {
- pCur->next = List32; List32 = pCur;
- Num32++;
- } else
- if((pCur->w >= 16) && (pCur->h >= 16)) {
- pCur->next = List16; List16 = pCur;
- Num16++;
- } else
- if((pCur->w >= 8) && (pCur->h >= 8)) {
- pCur->next = List8; List8 = pCur;
- Num8++;
- } else {
- h = pCur->h;
- if(DoColor && (pCur->w >= ColorW) && (h >= ColorH)) {
- while(h >= ColorH) {
- h -= ColorH;
- for(w = 0; w <= (pCur->w - ColorW); w += ColorW) {
- ColorList = Enlist( ColorList,
- pCur->x + w, pCur->y + h, ColorW, ColorH);
- (*NumColor)++;
- }
- }
- }
- if(DoMono && (pCur->w >= MonoW) && (h >= MonoH)) {
- while(h >= MonoH) {
- h -= MonoH;
- for(w = 0; w <= (pCur->w - MonoW); w += MonoW) {
- MonoList = Enlist( MonoList,
- pCur->x + w, pCur->y + h, MonoW, MonoH);
- (*NumMono)++;
- }
- }
- }
- xfree(pCur);
- }
-
- pCur = next;
- }
-
- /* Try to extract at least 4 of each type of 8x8 slot that we need */
-
- if(DoColor) {
- CacheLinkPtr theOne;
- while(*NumColor < 4) {
- theOne = NULL;
- if(Num8) {
- if((theOne = ExtractOneThatFits(&List8, ColorW, ColorH)))
- Num8--;
- }
- if(Num16 && !theOne) {
- if((theOne = ExtractOneThatFits(&List16, ColorW, ColorH)))
- Num16--;
- }
- if(Num32 && !theOne) {
- if((theOne = ExtractOneThatFits(&List32, ColorW, ColorH)))
- Num32--;
- }
- if(Num64 && !theOne) {
- if((theOne = ExtractOneThatFits(&List64, ColorW, ColorH)))
- Num64--;
- }
-
- if(!theOne) break;
-
-
- ConvertAllPartialsTo8x8(NumMono, NumColor, theOne,
- &MonoList, &ColorList, infoRec);
-
- if(DoMono) {
- while(*NumColor && (*NumMono < 4)) {
- ConvertColorToMono(&ColorList, ColorW, ColorH,
- &MonoList, MonoW, MonoH);
- (*NumColor)--; *NumMono += MonosPerColor;
- }
- }
- }
- }
-
- if(DoMono) {
- CacheLinkPtr theOne;
- while(*NumMono < 4) {
- theOne = NULL;
- if(Num8) {
- if((theOne = ExtractOneThatFits(&List8, MonoW, MonoH)))
- Num8--;
- }
- if(Num16 && !theOne) {
- if((theOne = ExtractOneThatFits(&List16, MonoW, MonoH)))
- Num16--;
- }
- if(Num32 && !theOne) {
- if((theOne = ExtractOneThatFits(&List32, MonoW, MonoH)))
- Num32--;
- }
- if(Num64 && !theOne) {
- if((theOne = ExtractOneThatFits(&List64, MonoW, MonoH)))
- Num64--;
- }
-
- if(!theOne) break;
-
- ConvertAllPartialsTo8x8(NumMono, NumColor, theOne,
- &MonoList, &ColorList, infoRec);
- }
- }
-
- /* We save all the tiles from the largest bin that we can get
- at least 4 of. If there are too few of a bigger slot, we
- cut it in fourths to make smaller slots. */
-
- if(Num64 >= 4) {
- ListKeepers = List64; List64 = NULL;
- NumKeepers = Num64;
- goto GOT_EM;
- } else if(Num64) {
- List32 = QuadLinks(List64, List32);
- Num32 += Num64 * 4;
- Num64 = 0;
- }
-
- if(Num32 >= 4) {
- ListKeepers = List32; List32 = NULL;
- NumKeepers = Num32;
- goto GOT_EM;
- } else if(Num32) {
- List16 = QuadLinks(List32, List16);
- Num16 += Num32 * 4;
- Num32 = 0;
- }
-
- if(Num16 >= 4) {
- ListKeepers = List16; List16 = NULL;
- NumKeepers = Num16;
- goto GOT_EM;
- } else if(Num16) {
- List8 = QuadLinks(List16, List8);
- Num8 += Num16 * 4;
- Num16 = 0;
- }
-
- if(Num8 >= 4) {
- ListKeepers = List8; List8 = NULL;
- NumKeepers = Num8;
- goto GOT_EM;
- }
-
-GOT_EM:
-
- /* Free the ones we aren't using */
-
- if(List64)
- ConvertAllPartialsTo8x8(NumMono, NumColor, List64,
- &MonoList, &ColorList, infoRec);
- if(List32)
- ConvertAllPartialsTo8x8(NumMono, NumColor, List32,
- &MonoList, &ColorList, infoRec);
- if(List16)
- ConvertAllPartialsTo8x8(NumMono, NumColor, List16,
- &MonoList, &ColorList, infoRec);
- if(List8)
- ConvertAllPartialsTo8x8(NumMono, NumColor, List8,
- &MonoList, &ColorList, infoRec);
-
-
- /* Enlarge the slots if we can */
-
- if(ListKeepers) {
- CacheLinkPtr pLink = ListKeepers;
- Width = Height = 128;
-
- while(pLink) {
- if(pLink->w < Width) Width = pLink->w;
- if(pLink->h < Height) Height = pLink->h;
- pLink = pLink->next;
- }
- }
-
- *ListMono = MonoList;
- *ListColor = ColorList;
- *maxw = Width;
- *maxh = Height;
- *NumPartial = NumKeepers;
- return ListKeepers;
-}
-
-
-void
-XAAInitPixmapCache(
- ScreenPtr pScreen,
- RegionPtr areas,
- pointer data
-) {
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- XAAInfoRecPtr infoRec = (XAAInfoRecPtr)data;
- XAAPixmapCachePrivatePtr pCachePriv;
- BoxPtr pBox = REGION_RECTS(areas);
- int nBox = REGION_NUM_RECTS(areas);
- int Num512, Num256, Num128, NumPartial, NumColor, NumMono;
- int Target512, Target256;
- CacheLinkPtr List512, List256, List128, ListPartial, ListColor, ListMono;
- int x, y, w, h, ntotal, granularity, width, height, i;
- int MaxPartialWidth, MaxPartialHeight;
-
- infoRec->MaxCacheableTileWidth = 0;
- infoRec->MaxCacheableTileHeight = 0;
- infoRec->MaxCacheableStippleHeight = 0;
- infoRec->MaxCacheableStippleWidth = 0;
- infoRec->UsingPixmapCache = FALSE;
-
-
- if(!nBox || !pBox || !(infoRec->Flags & PIXMAP_CACHE))
- return;
-
- /* Allocate a persistent per-screen init flag to control messages */
- if (CacheInitIndex < 0)
- CacheInitIndex = xf86AllocateScrnInfoPrivateIndex();
-
- /* free the old private data if it exists */
- if(infoRec->PixmapCachePrivate) {
- FreePixmapCachePrivate(
- (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate);
- infoRec->PixmapCachePrivate = NULL;
- }
-
- Num512 = Num256 = Num128 = NumPartial = NumMono = NumColor = 0;
- List512 = List256 = List128 = ListPartial = ListMono = ListColor = NULL;
- granularity = infoRec->CachePixelGranularity;
- if(granularity <= 1) granularity = 0;
-
- /* go through the boxes and break it into as many pieces as we can fit */
-
- while(nBox--) {
- x = pBox->x1;
- if(granularity) {
- int tmp = x % granularity;
- if(tmp) x += (granularity - tmp);
- }
- width = pBox->x2 - x;
- if(width <= 0) {pBox++; continue;}
-
- y = pBox->y1;
- height = pBox->y2 - y;
-
- for(h = 0; h <= (height - 512); h += 512) {
- for(w = 0; w <= (width - 512); w += 512) {
- List512 = Enlist(List512, x + w, y + h, 512, 512);
- Num512++;
- }
- for(; w <= (width - 256); w += 256) {
- List256 = Enlist(List256, x + w, y + h, 256, 256);
- List256 = Enlist(List256, x + w, y + h + 256, 256, 256);
- Num256 += 2;
- }
- for(; w <= (width - 128); w += 128) {
- List128 = Enlist(List128, x + w, y + h, 128, 128);
- List128 = Enlist(List128, x + w, y + h + 128, 128, 128);
- List128 = Enlist(List128, x + w, y + h + 256, 128, 128);
- List128 = Enlist(List128, x + w, y + h + 384, 128, 128);
- Num128 += 4;
- }
- if(w < width) {
- int d = width - w;
- ListPartial = Enlist(ListPartial, x + w, y + h, d, 128);
- ListPartial = Enlist(ListPartial, x + w, y + h + 128, d, 128);
- ListPartial = Enlist(ListPartial, x + w, y + h + 256, d, 128);
- ListPartial = Enlist(ListPartial, x + w, y + h + 384, d, 128);
- NumPartial += 4;
- }
- }
- for(; h <= (height - 256); h += 256) {
- for(w = 0; w <= (width - 256); w += 256) {
- List256 = Enlist(List256, x + w, y + h, 256, 256);
- Num256++;
- }
- for(; w <= (width - 128); w += 128) {
- List128 = Enlist(List128, x + w, y + h, 128, 128);
- List128 = Enlist(List128, x + w, y + h + 128, 128, 128);
- Num128 += 2;
- }
- if(w < width) {
- int d = width - w;
- ListPartial = Enlist(ListPartial, x + w, y + h, d, 128);
- ListPartial = Enlist(ListPartial, x + w, y + h + 128, d, 128);
- NumPartial += 2;
- }
- }
- for(; h <= (height - 128); h += 128) {
- for(w = 0; w <= (width - 128); w += 128) {
- List128 = Enlist(List128, x + w, y + h, 128, 128);
- Num128++;
- }
- if(w < width) {
- ListPartial = Enlist(
- ListPartial, x + w, y + h, width - w, 128);
- NumPartial++;
- }
- }
- if(h < height) {
- int d = height - h;
- for(w = 0; w <= (width - 128); w += 128) {
- ListPartial = Enlist(ListPartial, x + w, y + h, 128, d);
- NumPartial++;
- }
- if(w < width) {
- ListPartial = Enlist(ListPartial, x + w, y + h, width - w, d);
- NumPartial++;
- }
- }
- pBox++;
- }
-
-
-/*
- by this point we've carved the space into as many 512x512, 256x256
- and 128x128 blocks as we could fit. We will then break larger
- blocks into smaller ones if we need to. The rules are as follows:
-
- 512x512 -
- 1) Don't take up more than half the memory.
- 2) Don't bother if you can't get at least four.
- 3) Don't make more than MAX_512.
- 4) Don't have any of there are no 256x256s.
-
- 256x256 -
- 1) Don't take up more than a quarter of the memory enless there
- aren't any 512x512s. Then we can take up to half.
- 2) Don't bother if you can't get at least four.
- 3) Don't make more than MAX_256.
-
- 128x128 -
- 1) Don't make more than MAX_128.
-
- We don't bother with the partial blocks unless we can use them
- for 8x8 pattern fills or we are short on larger blocks.
-
-*/
-
- ntotal = Num128 + (Num256<<2) + (Num512<<4);
-
- Target512 = ntotal >> 5;
- if(Target512 < 4) Target512 = 0;
- if(!Target512) Target256 = ntotal >> 3;
- else Target256 = ntotal >> 4;
- if(Target256 < 4) Target256 = 0;
-
- if(Num512 && Num256 < 4) {
- while(Num512 && Num256 < Target256) {
- SubdivideList(&List512, &List256);
- Num256 += 4; Num512--;
- }
- }
-
- if(!Num512) { /* no room */
- } else if((Num512 < 4) || (!Target512)) {
- while(Num512) {
- SubdivideList(&List512, &List256);
- Num256 += 4; Num512--;
- }
- } else if((Num512 > MAX_512) || (Num512 > Target512)){
- while(Num512 > MAX_512) {
- SubdivideList(&List512, &List256);
- Num256 += 4; Num512--;
- }
- while(Num512 > Target512) {
- if(Num256 < MAX_256) {
- SubdivideList(&List512, &List256);
- Num256 += 4; Num512--;
- } else break;
- }
- }
-
- if(!Num256) { /* no room */
- } else if((Num256 < 4) || (!Target256)) {
- while(Num256) {
- SubdivideList(&List256, &List128);
- Num128 += 4; Num256--;
- }
- } else if((Num256 > MAX_256) || (Num256 > Target256)) {
- while(Num256 > MAX_256) {
- SubdivideList(&List256, &List128);
- Num128 += 4; Num256--;
- }
- while(Num256 > Target256) {
- if(Num128 < MAX_128) {
- SubdivideList(&List256, &List128);
- Num128 += 4; Num256--;
- } else break;
- }
- }
-
- if(Num128 && ((Num128 < 4) || (Num128 > MAX_128))) {
- CacheLinkPtr next;
- int max = (Num128 > MAX_128) ? MAX_128 : 0;
-
- /*
- * Note: next is set in this way to work around a code generation
- * bug in gcc 2.7.2.3.
- */
- next = List128->next;
- while(Num128 > max) {
- List128->next = ListPartial;
- ListPartial = List128;
- if((List128 = next))
- next = List128->next;
- NumPartial++; Num128--;
- }
- }
-
- MaxPartialHeight = MaxPartialWidth = 0;
-
- /* at this point we have as many 512x512 and 256x256 slots as we
- want but may have an excess of 128x128 slots. We still need
- to find out if we need 8x8 slots. We take these from the
- partials if we have them. Otherwise, we break some 128x128's */
-
- if(!(infoRec->PixmapCacheFlags & (CACHE_MONO_8x8 | CACHE_COLOR_8x8))) {
- if(NumPartial) {
- if(Num128) { /* don't bother with partials */
- FreeList(ListPartial);
- NumPartial = 0; ListPartial = NULL;
- } else {
- /* We have no big slots. Weed out the unusable partials */
- ListPartial = ThinOutPartials(ListPartial, &NumPartial,
- &MaxPartialWidth, &MaxPartialHeight);
- }
- }
- } else {
- int MonosPerColor = 1;
- int ColorH = infoRec->CacheHeightColor8x8Pattern;
- int ColorW = infoRec->CacheWidthColor8x8Pattern;
- int MonoH = infoRec->CacheHeightMono8x8Pattern;
- int MonoW = infoRec->CacheWidthMono8x8Pattern;
- Bool DoColor = (infoRec->PixmapCacheFlags & CACHE_COLOR_8x8);
- Bool DoMono = (infoRec->PixmapCacheFlags & CACHE_MONO_8x8);
-
- if(DoColor) infoRec->CanDoColor8x8 = FALSE;
- if(DoMono) infoRec->CanDoMono8x8 = FALSE;
-
- if(DoColor && DoMono) {
- /* we assume color patterns take more space than color ones */
- if(MonoH > ColorH) ColorH = MonoH;
- if(MonoW > ColorW) ColorW = MonoW;
- MonosPerColor = (ColorH/MonoH) * (ColorW/MonoW);
- }
-
- if(Num128) {
- if(NumPartial) { /* use all for 8x8 slots */
- ConvertAllPartialsTo8x8(&NumMono, &NumColor,
- ListPartial, &ListMono, &ListColor, infoRec);
- NumPartial = 0; ListPartial = NULL;
- }
-
- /* Get some 8x8 slots from the 128 slots */
- while((Num128 > 4) &&
- ((NumMono < MAX_MONO) && (NumColor < MAX_COLOR))) {
- CacheLinkPtr tmp = NULL;
-
- tmp = Enlist(tmp, List128->x, List128->y,
- List128->w, List128->h);
- List128 = Delist(List128);
- Num128--;
-
- ConvertAllPartialsTo8x8(&NumMono, &NumColor,
- tmp, &ListMono, &ListColor, infoRec);
- }
- } else if(NumPartial) {
- /* We have share partials between 8x8 slots and tiles. */
- ListPartial = ConvertSomePartialsTo8x8(&NumMono, &NumColor,
- &NumPartial, ListPartial, &ListMono, &ListColor,
- &MaxPartialWidth, &MaxPartialHeight, infoRec);
- }
-
-
- if(DoMono && DoColor) {
- if(NumColor && ((NumColor > MAX_COLOR) || (NumColor < 4))) {
- int max = (NumColor > MAX_COLOR) ? MAX_COLOR : 0;
-
- while(NumColor > max) {
- ConvertColorToMono(&ListColor, ColorW, ColorH,
- &ListMono, MonoW, MonoH);
- NumColor--; NumMono += MonosPerColor;
- }
- }
-
- /* favor Mono slots over Color ones */
- while((NumColor > 4) && (NumMono < MAX_MONO)) {
- ConvertColorToMono(&ListColor, ColorW, ColorH,
- &ListMono, MonoW, MonoH);
- NumColor--; NumMono += MonosPerColor;
- }
- }
-
- if(NumMono && ((NumMono > MAX_MONO) || (NumMono < 4))) {
- int max = (NumMono > MAX_MONO) ? MAX_MONO : 0;
-
- while(NumMono > max) {
- ListMono = Delist(ListMono);
- NumMono--;
- }
- }
- if(NumColor && ((NumColor > MAX_COLOR) || (NumColor < 4))) {
- int max = (NumColor > MAX_COLOR) ? MAX_COLOR : 0;
-
- while(NumColor > max) {
- ListColor = Delist(ListColor);
- NumColor--;
- }
- }
- }
-
-
- pCachePriv = xcalloc(1,sizeof(XAAPixmapCachePrivate));
- if(!pCachePriv) {
- if(Num512) FreeList(List512);
- if(Num256) FreeList(List256);
- if(Num128) FreeList(List128);
- if(NumPartial) FreeList(ListPartial);
- if(NumColor) FreeList(ListColor);
- if(NumMono) FreeList(ListMono);
- return;
- }
-
- infoRec->PixmapCachePrivate = (char*)pCachePriv;
-
- if(Num512) {
- pCachePriv->Info512 = xcalloc(Num512,sizeof(XAACacheInfoRec));
- if(!pCachePriv->Info512) Num512 = 0;
- if(Num512) TransferList(List512, pCachePriv->Info512, Num512);
- FreeList(List512);
- pCachePriv->Num512x512 = Num512;
- }
- if(Num256) {
- pCachePriv->Info256 = xcalloc(Num256, sizeof(XAACacheInfoRec));
- if(!pCachePriv->Info256) Num256 = 0;
- if(Num256) TransferList(List256, pCachePriv->Info256, Num256);
- FreeList(List256);
- pCachePriv->Num256x256 = Num256;
- }
- if(Num128) {
- pCachePriv->Info128 = xcalloc(Num128, sizeof(XAACacheInfoRec));
- if(!pCachePriv->Info128) Num128 = 0;
- if(Num128) TransferList(List128, pCachePriv->Info128, Num128);
- FreeList(List128);
- pCachePriv->Num128x128 = Num128;
- }
-
- if(NumPartial) {
- pCachePriv->InfoPartial = xcalloc(NumPartial, sizeof(XAACacheInfoRec));
- if(!pCachePriv->InfoPartial) NumPartial = 0;
- if(NumPartial)
- TransferList(ListPartial, pCachePriv->InfoPartial, NumPartial);
- FreeList(ListPartial);
- pCachePriv->NumPartial = NumPartial;
- }
-
- if(NumColor) {
- pCachePriv->InfoColor = xcalloc(NumColor, sizeof(XAACacheInfoRec));
- if(!pCachePriv->InfoColor) NumColor = 0;
- if(NumColor) TransferList(ListColor, pCachePriv->InfoColor, NumColor);
- FreeList(ListColor);
- pCachePriv->NumColor = NumColor;
- }
-
- if(NumMono) {
- pCachePriv->InfoMono = xcalloc(NumMono, sizeof(XAACacheInfoRec));
- if(!pCachePriv->InfoMono) NumMono = 0;
- if(NumMono) TransferList(ListMono, pCachePriv->InfoMono, NumMono);
- FreeList(ListMono);
- pCachePriv->NumMono = NumMono;
- }
-
-
- if(NumPartial) {
- infoRec->MaxCacheableTileWidth = MaxPartialWidth;
- infoRec->MaxCacheableTileHeight = MaxPartialHeight;
- }
- if(Num128)
- infoRec->MaxCacheableTileWidth = infoRec->MaxCacheableTileHeight = 128;
- if(Num256)
- infoRec->MaxCacheableTileWidth = infoRec->MaxCacheableTileHeight = 256;
- if(Num512)
- infoRec->MaxCacheableTileWidth = infoRec->MaxCacheableTileHeight = 512;
-
-
- infoRec->MaxCacheableStippleHeight = infoRec->MaxCacheableTileHeight;
- infoRec->MaxCacheableStippleWidth =
- infoRec->MaxCacheableTileWidth * pScrn->bitsPerPixel;
- if(infoRec->ScreenToScreenColorExpandFillFlags & TRIPLE_BITS_24BPP)
- infoRec->MaxCacheableStippleWidth /= 3;
-
- if(NumMono) {
- if(!(infoRec->Mono8x8PatternFillFlags &
- (HARDWARE_PATTERN_PROGRAMMED_ORIGIN |
- HARDWARE_PATTERN_PROGRAMMED_BITS))) {
- int numPerLine =
- infoRec->CacheWidthMono8x8Pattern/infoRec->MonoPatternPitch;
-
- for(i = 0; i < 64; i++) {
- pCachePriv->MonoOffsets[i].y = i/numPerLine;
- pCachePriv->MonoOffsets[i].x = (i % numPerLine) *
- infoRec->MonoPatternPitch;
- }
- }
- infoRec->CanDoMono8x8 = TRUE;
- }
- if(NumColor) {
- if(!(infoRec->Color8x8PatternFillFlags &
- HARDWARE_PATTERN_PROGRAMMED_ORIGIN)) {
-
- for(i = 0; i < 64; i++) {
- pCachePriv->ColorOffsets[i].y = i & 0x07;
- pCachePriv->ColorOffsets[i].x = i & ~0x07;
- }
- }
- infoRec->CanDoColor8x8 = TRUE;
- }
-
- if(!CACHEINIT(pScrn)) {
- xf86ErrorF("\tSetting up tile and stipple cache:\n");
- if(NumPartial)
- xf86ErrorF("\t\t%i %ix%i slots\n",
- NumPartial, MaxPartialWidth, MaxPartialHeight);
- if(Num128) xf86ErrorF("\t\t%i 128x128 slots\n", Num128);
- if(Num256) xf86ErrorF("\t\t%i 256x256 slots\n", Num256);
- if(Num512) xf86ErrorF("\t\t%i 512x512 slots\n", Num512);
- if(NumColor) xf86ErrorF("\t\t%i 8x8 color pattern slots\n", NumColor);
- if(NumMono) xf86ErrorF("\t\t%i 8x8 color expansion slots\n", NumMono);
- }
-
- if(!(NumPartial | Num128 | Num256 | Num512 | NumColor | NumMono)) {
- if(!CACHEINIT(pScrn))
- xf86ErrorF("\t\tNot enough video memory for pixmap cache\n");
- } else infoRec->UsingPixmapCache = TRUE;
-
- CACHEINIT(pScrn) = 1;
-}
-
-#if X_BYTE_ORDER == X_BIG_ENDIAN
-static CARD32 StippleMasks[4] = {
- 0x80808080,
- 0xC0C0C0C0,
- 0x00000000,
- 0xF0F0F0F0
-};
-#else
-static CARD32 StippleMasks[4] = {
- 0x01010101,
- 0x03030303,
- 0x00000000,
- 0x0F0F0F0F
-};
-#endif
-
-Bool
-XAACheckStippleReducibility(PixmapPtr pPixmap)
-{
- XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_DRAWABLE(&pPixmap->drawable);
- CARD32 *IntPtr = (CARD32*)pPixmap->devPrivate.ptr;
- int w = pPixmap->drawable.width;
- int h = pPixmap->drawable.height;
- int i;
- CARD32 bits[8];
- CARD32 mask = SHIFT_R(0xFFFFFFFF,24);
-
- pPriv->flags |= REDUCIBILITY_CHECKED | REDUCIBLE_TO_2_COLOR;
- pPriv->flags &= ~REDUCIBLE_TO_8x8;
-
- if((w > 32) || (h > 32) || (w & (w - 1)) || (h & (h - 1)))
- return FALSE;
-
- i = (h > 8) ? 8 : h;
-
- switch(w) {
- case 32:
- while(i--) {
- bits[i] = IntPtr[i] & mask;
- if( (bits[i] != SHIFT_R((IntPtr[i] & SHIFT_L(mask, 8)), 8)) ||
- (bits[i] != SHIFT_R((IntPtr[i] & SHIFT_L(mask,16)),16)) ||
- (bits[i] != SHIFT_R((IntPtr[i] & SHIFT_L(mask,24)),24)))
- return FALSE;
- }
- break;
- case 16:
- while(i--) {
- bits[i] = IntPtr[i] & mask;
- if(bits[i] != ((IntPtr[i] & SHIFT_R(SHIFT_L(mask,8),8))))
- return FALSE;
- }
- break;
- default:
- while(i--)
- bits[i] = IntPtr[i] & mask;
- break;
- }
-
- switch(h) {
- case 32:
- if( (IntPtr[8] != IntPtr[16]) || (IntPtr[9] != IntPtr[17]) ||
- (IntPtr[10] != IntPtr[18]) || (IntPtr[11] != IntPtr[19]) ||
- (IntPtr[12] != IntPtr[20]) || (IntPtr[13] != IntPtr[21]) ||
- (IntPtr[14] != IntPtr[22]) || (IntPtr[15] != IntPtr[23]) ||
- (IntPtr[16] != IntPtr[24]) || (IntPtr[17] != IntPtr[25]) ||
- (IntPtr[18] != IntPtr[26]) || (IntPtr[19] != IntPtr[27]) ||
- (IntPtr[20] != IntPtr[28]) || (IntPtr[21] != IntPtr[29]) ||
- (IntPtr[22] != IntPtr[30]) || (IntPtr[23] != IntPtr[31]))
- return FALSE;
- /* fall through */
- case 16:
- if( (IntPtr[0] != IntPtr[8]) || (IntPtr[1] != IntPtr[9]) ||
- (IntPtr[2] != IntPtr[10]) || (IntPtr[3] != IntPtr[11]) ||
- (IntPtr[4] != IntPtr[12]) || (IntPtr[5] != IntPtr[13]) ||
- (IntPtr[6] != IntPtr[14]) || (IntPtr[7] != IntPtr[15]))
- return FALSE;
- case 8: break;
- case 1: bits[1] = bits[0];
- case 2: bits[2] = bits[0]; bits[3] = bits[1];
- case 4: bits[4] = bits[0]; bits[5] = bits[1];
- bits[6] = bits[2]; bits[7] = bits[3];
- break;
- }
-
- pPriv->flags |= REDUCIBLE_TO_8x8;
-
- pPriv->pattern0 = bits[0] | SHIFT_L(bits[1],8) | SHIFT_L(bits[2],16) | SHIFT_L(bits[3],24);
- pPriv->pattern1 = bits[4] | SHIFT_L(bits[5],8) | SHIFT_L(bits[6],16) | SHIFT_L(bits[7],24);
-
- if(w < 8) {
- pPriv->pattern0 &= StippleMasks[w - 1];
- pPriv->pattern1 &= StippleMasks[w - 1];
-
- switch(w) {
- case 1: pPriv->pattern0 |= SHIFT_L(pPriv->pattern0,1);
- pPriv->pattern1 |= SHIFT_L(pPriv->pattern1,1);
- case 2: pPriv->pattern0 |= SHIFT_L(pPriv->pattern0,2);
- pPriv->pattern1 |= SHIFT_L(pPriv->pattern1,2);
- case 4: pPriv->pattern0 |= SHIFT_L(pPriv->pattern0,4);
- pPriv->pattern1 |= SHIFT_L(pPriv->pattern1,4);
- }
- }
-
- if(infoRec->Mono8x8PatternFillFlags & BIT_ORDER_IN_BYTE_MSBFIRST) {
- pPriv->pattern0 = SWAP_BITS_IN_BYTES(pPriv->pattern0);
- pPriv->pattern1 = SWAP_BITS_IN_BYTES(pPriv->pattern1);
- }
-
-
- return TRUE;
-}
-
-
-Bool
-XAACheckTileReducibility(PixmapPtr pPixmap, Bool checkMono)
-{
- XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
- CARD32 *IntPtr;
- int w = pPixmap->drawable.width;
- int h = pPixmap->drawable.height;
- int pitch = pPixmap->devKind >> 2;
- int dwords, i, j;
-
- pPriv->flags |= REDUCIBILITY_CHECKED;
- pPriv->flags &= ~(REDUCIBILITY_CHECKED | REDUCIBLE_TO_2_COLOR);
-
- if((w > 32) || (h > 32) || (w & (w - 1)) || (h & (h - 1)))
- return FALSE;
-
- dwords = ((w * pPixmap->drawable.bitsPerPixel) + 31) >> 5;
- i = (h > 8) ? 8 : h;
-
-
- if(w > 8) {
- IntPtr = (CARD32*)pPixmap->devPrivate.ptr;
- switch(pPixmap->drawable.bitsPerPixel) {
- case 8:
- while(i--) {
- for(j = 2; j < dwords; j++)
- if(IntPtr[j] != IntPtr[j & 0x01])
- return FALSE;
- IntPtr += pitch;
- }
- break;
- case 16:
- while(i--) {
- for(j = 4; j < dwords; j++)
- if(IntPtr[j] != IntPtr[j & 0x03])
- return FALSE;
- IntPtr += pitch;
- }
- break;
- case 24:
- while(i--) {
- for(j = 6; j < dwords; j++)
- if(IntPtr[j] != IntPtr[j % 6])
- return FALSE;
- IntPtr += pitch;
- }
- break;
- case 32:
- while(i--) {
- for(j = 8; j < dwords; j++)
- if(IntPtr[j] != IntPtr[j & 0x07])
- return FALSE;
- IntPtr += pitch;
- }
- break;
- default: return FALSE;
- }
-
- }
-
-
- if(h == 32) {
- CARD32 *IntPtr2, *IntPtr3, *IntPtr4;
- i = 8;
- IntPtr = (CARD32*)pPixmap->devPrivate.ptr;
- IntPtr2 = IntPtr + (pitch << 3);
- IntPtr3 = IntPtr2 + (pitch << 3);
- IntPtr4 = IntPtr3 + (pitch << 3);
- while(i--) {
- for(j = 0; j < dwords; j++)
- if((IntPtr[j] != IntPtr2[j]) || (IntPtr[j] != IntPtr3[j]) ||
- (IntPtr[j] != IntPtr4[j]))
- return FALSE;
- IntPtr += pitch;
- IntPtr2 += pitch;
- IntPtr3 += pitch;
- IntPtr4 += pitch;
- }
- } else if (h == 16) {
- CARD32 *IntPtr2;
- i = 8;
- IntPtr = (CARD32*)pPixmap->devPrivate.ptr;
- IntPtr2 = IntPtr + (pitch << 3);
- while(i--) {
- for(j = 0; j < dwords; j++)
- if(IntPtr[j] != IntPtr2[j])
- return FALSE;
- IntPtr += pitch;
- IntPtr2 += pitch;
- }
- }
-
- pPriv->flags |= REDUCIBLE_TO_8x8;
-
- if(checkMono) {
- XAAInfoRecPtr infoRec =
- GET_XAAINFORECPTR_FROM_DRAWABLE(&pPixmap->drawable);
- unsigned char bits[8];
- int fg, bg = -1, x, y;
-
- i = (h > 8) ? 8 : h;
- j = (w > 8) ? 8 : w;
-
- if(pPixmap->drawable.bitsPerPixel == 8) {
- unsigned char *srcp = pPixmap->devPrivate.ptr;
- fg = srcp[0];
- pitch = pPixmap->devKind;
- for(y = 0; y < i; y++) {
- bits[y] = 0;
- for(x = 0; x < j; x++) {
- if(srcp[x] != fg) {
- if(bg == -1) bg = srcp[x];
- else if(bg != srcp[x]) return TRUE;
- } else bits[y] |= 1 << x;
- }
- srcp += pitch;
- }
- } else if(pPixmap->drawable.bitsPerPixel == 16) {
- unsigned short *srcp = (unsigned short*)pPixmap->devPrivate.ptr;
- fg = srcp[0];
- pitch = pPixmap->devKind >> 1;
- for(y = 0; y < i; y++) {
- bits[y] = 0;
- for(x = 0; x < j; x++) {
- if(srcp[x] != fg) {
- if(bg == -1) bg = srcp[x];
- else if(bg != srcp[x]) return TRUE;
- } else bits[y] |= 1 << x;
- }
- srcp += pitch;
- }
- } else if(pPixmap->drawable.bitsPerPixel == 24) {
- CARD32 val;
- unsigned char *srcp = pPixmap->devPrivate.ptr;
- fg = *((CARD32*)srcp) & 0x00FFFFFF;
- pitch = pPixmap->devKind;
- j *= 3;
- for(y = 0; y < i; y++) {
- bits[y] = 0;
- for(x = 0; x < j; x+=3) {
- val = *((CARD32*)(srcp+x)) & 0x00FFFFFF;
- if(val != fg) {
- if(bg == -1) bg = val;
- else if(bg != val)
- return TRUE;
- } else bits[y] |= 1 << (x/3);
- }
- srcp += pitch;
- }
- } else if(pPixmap->drawable.bitsPerPixel == 32) {
- IntPtr = (CARD32*)pPixmap->devPrivate.ptr;
- fg = IntPtr[0];
- for(y = 0; y < i; y++) {
- bits[y] = 0;
- for(x = 0; x < j; x++) {
- if(IntPtr[x] != fg) {
- if(bg == -1) bg = IntPtr[x];
- else if(bg != IntPtr[x]) return TRUE;
- } else bits[y] |= 1 << x;
- }
- IntPtr += pitch;
- }
- } else return TRUE;
-
- pPriv->fg = fg;
- if(bg == -1) pPriv->bg = fg;
- else pPriv->bg = bg;
-
- if(h < 8) {
- switch(h) {
- case 1: bits[1] = bits[0];
- case 2: bits[2] = bits[0]; bits[3] = bits[1];
- case 4: bits[4] = bits[0]; bits[5] = bits[1];
- bits[6] = bits[2]; bits[7] = bits[3];
- break;
- }
- }
-
- pPriv->pattern0 =
- bits[0] | (bits[1]<<8) | (bits[2]<<16) | (bits[3]<<24);
- pPriv->pattern1 =
- bits[4] | (bits[5]<<8) | (bits[6]<<16) | (bits[7]<<24);
-
- if(w < 8) {
- switch(w) {
- case 1: pPriv->pattern0 |= (pPriv->pattern0 << 1);
- pPriv->pattern1 |= (pPriv->pattern1 << 1);
- case 2: pPriv->pattern0 |= (pPriv->pattern0 << 2);
- pPriv->pattern1 |= (pPriv->pattern1 << 2);
- case 4: pPriv->pattern0 |= (pPriv->pattern0 << 4);
- pPriv->pattern1 |= (pPriv->pattern1 << 4);
- }
- }
- pPriv->flags |= REDUCIBLE_TO_2_COLOR;
-
- if(infoRec->Mono8x8PatternFillFlags & BIT_ORDER_IN_BYTE_MSBFIRST) {
- pPriv->pattern0 = SWAP_BITS_IN_BYTES(pPriv->pattern0);
- pPriv->pattern1 = SWAP_BITS_IN_BYTES(pPriv->pattern1);
- }
-
- }
-
- return TRUE;
-}
-
-
-void XAATileCache(
- ScrnInfoPtr pScrn,
- XAACacheInfoPtr pCache,
- int w, int h
-) {
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
-
- (*infoRec->SetupForScreenToScreenCopy)(pScrn, 1, 1, GXcopy, ~0, -1);
-
- while((w << 1) <= pCache->w) {
- (*infoRec->SubsequentScreenToScreenCopy)(pScrn, pCache->x, pCache->y,
- pCache->x + w, pCache->y, w, h);
- w <<= 1;
- }
- if(w != pCache->w) {
- (*infoRec->SubsequentScreenToScreenCopy)(pScrn, pCache->x, pCache->y,
- pCache->x + w, pCache->y, pCache->w - w, h);
- w = pCache->w;
- }
-
- while((h << 1) <= pCache->h) {
- (*infoRec->SubsequentScreenToScreenCopy)(pScrn, pCache->x, pCache->y,
- pCache->x, pCache->y + h, w, h);
- h <<= 1;
- }
- if(h != pCache->h) {
- (*infoRec->SubsequentScreenToScreenCopy)(pScrn, pCache->x, pCache->y,
- pCache->x, pCache->y + h, w, pCache->h - h);
- }
- SET_SYNC_FLAG(infoRec);
-}
-
-XAACacheInfoPtr
-XAACacheTile(ScrnInfoPtr pScrn, PixmapPtr pPix)
-{
- int w = pPix->drawable.width;
- int h = pPix->drawable.height;
- int size = max(w, h);
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
- XAAPixmapCachePrivatePtr pCachePriv =
- (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
- XAACacheInfoPtr pCache, cacheRoot = NULL;
- int i, max = 0;
- int *current;
-
- if(size <= 128) {
- if(pCachePriv->Info128) {
- cacheRoot = pCachePriv->Info128;
- max = pCachePriv->Num128x128;
- current = &pCachePriv->Current128;
- } else {
- cacheRoot = pCachePriv->InfoPartial;
- max = pCachePriv->NumPartial;
- current = &pCachePriv->CurrentPartial;
- }
- } else if(size <= 256) {
- cacheRoot = pCachePriv->Info256;
- max = pCachePriv->Num256x256;
- current = &pCachePriv->Current256;
- } else if(size <= 512) {
- cacheRoot = pCachePriv->Info512;
- max = pCachePriv->Num512x512;
- current = &pCachePriv->Current512;
- } else { /* something's wrong */
- ErrorF("Something's wrong in XAACacheTile()\n");
- return pCachePriv->Info128;
- }
-
- pCache = cacheRoot;
-
- /* lets look for it */
- for(i = 0; i < max; i++, pCache++) {
- if(pCache->serialNumber == pPix->drawable.serialNumber) {
- pCache->trans_color = -1;
- return pCache;
- }
- }
-
- pCache = &cacheRoot[(*current)++];
- if(*current >= max) *current = 0;
-
- pCache->serialNumber = pPix->drawable.serialNumber;
- pCache->trans_color = pCache->bg = pCache->fg = -1;
- pCache->orig_w = w; pCache->orig_h = h;
- (*infoRec->WritePixmapToCache)(
- pScrn, pCache->x, pCache->y, w, h, pPix->devPrivate.ptr,
- pPix->devKind, pPix->drawable.bitsPerPixel, pPix->drawable.depth);
- if(!(infoRec->PixmapCacheFlags & DO_NOT_TILE_COLOR_DATA) &&
- ((w != pCache->w) || (h != pCache->h)))
- XAATileCache(pScrn, pCache, w, h);
-
- return pCache;
-}
-
-XAACacheInfoPtr
-XAACacheMonoStipple(ScrnInfoPtr pScrn, PixmapPtr pPix)
-{
- int w = pPix->drawable.width;
- int h = pPix->drawable.height;
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
- XAAPixmapCachePrivatePtr pCachePriv =
- (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
- XAACacheInfoPtr pCache, cacheRoot = NULL;
- int i, max = 0, funcNo, pad, dwords, bpp = pScrn->bitsPerPixel;
- int *current;
- StippleScanlineProcPtr StippleFunc;
- unsigned char *data, *srcPtr, *dstPtr;
-
- if((h <= 128) && (w <= 128 * bpp)) {
- if(pCachePriv->Info128) {
- cacheRoot = pCachePriv->Info128;
- max = pCachePriv->Num128x128;
- current = &pCachePriv->Current128;
- } else {
- cacheRoot = pCachePriv->InfoPartial;
- max = pCachePriv->NumPartial;
- current = &pCachePriv->CurrentPartial;
- }
- } else if((h <= 256) && (w <= 256 * bpp)){
- cacheRoot = pCachePriv->Info256;
- max = pCachePriv->Num256x256;
- current = &pCachePriv->Current256;
- } else if((h <= 512) && (w <= 526 * bpp)){
- cacheRoot = pCachePriv->Info512;
- max = pCachePriv->Num512x512;
- current = &pCachePriv->Current512;
- } else { /* something's wrong */
- ErrorF("Something's wrong in XAACacheMonoStipple()\n");
- return pCachePriv->Info128;
- }
-
- pCache = cacheRoot;
-
- /* lets look for it */
- for(i = 0; i < max; i++, pCache++) {
- if((pCache->serialNumber == pPix->drawable.serialNumber) &&
- (pCache->fg == -1) && (pCache->bg == -1)) {
- pCache->trans_color = -1;
- return pCache;
- }
- }
-
- pCache = &cacheRoot[(*current)++];
- if(*current >= max) *current = 0;
-
- pCache->serialNumber = pPix->drawable.serialNumber;
- pCache->trans_color = pCache->bg = pCache->fg = -1;
- pCache->orig_w = w; pCache->orig_h = h;
-
- if(w <= 32) {
- if(w & (w - 1)) funcNo = 1;
- else funcNo = 0;
- } else funcNo = 2;
-
- pad = BitmapBytePad(pCache->w * bpp);
- dwords = bytes_to_int32(pad);
- dstPtr = data = (unsigned char*)xalloc(pad * pCache->h);
- srcPtr = (unsigned char*)pPix->devPrivate.ptr;
-
- if(infoRec->ScreenToScreenColorExpandFillFlags & BIT_ORDER_IN_BYTE_MSBFIRST)
- StippleFunc = XAAStippleScanlineFuncMSBFirst[funcNo];
- else
- StippleFunc = XAAStippleScanlineFuncLSBFirst[funcNo];
-
- /* don't bother generating more than we'll ever use */
- max = ((pScrn->displayWidth + w - 1) + 31) >> 5;
- if(dwords > max)
- dwords = max;
-
- for(i = 0; i < h; i++) {
- (*StippleFunc)((CARD32*)dstPtr, (CARD32*)srcPtr, 0, w, dwords);
- srcPtr += pPix->devKind;
- dstPtr += pad;
- }
-
- while((h<<1) <= pCache->h) {
- memcpy(data + (pad * h), data, pad * h);
- h <<= 1;
- }
-
- if(h < pCache->h)
- memcpy(data + (pad * h), data, pad * (pCache->h - h));
-
- (*infoRec->WritePixmapToCache)(
- pScrn, pCache->x, pCache->y, pCache->w, pCache->h, data,
- pad, bpp, pScrn->depth);
-
- xfree(data);
-
- return pCache;
-}
-
-XAACacheInfoPtr
-XAACachePlanarMonoStipple(ScrnInfoPtr pScrn, PixmapPtr pPix)
-{
- int w = pPix->drawable.width;
- int h = pPix->drawable.height;
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
- XAAPixmapCachePrivatePtr pCachePriv =
- (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
- XAACacheInfoPtr pCache, cacheRoot = NULL;
- int i, max = 0;
- int *current;
-
- if((h <= 128) && (w <= 128)) {
- if(pCachePriv->Info128) {
- cacheRoot = pCachePriv->Info128;
- max = pCachePriv->Num128x128;
- current = &pCachePriv->Current128;
- } else {
- cacheRoot = pCachePriv->InfoPartial;
- max = pCachePriv->NumPartial;
- current = &pCachePriv->CurrentPartial;
- }
- } else if((h <= 256) && (w <= 256)){
- cacheRoot = pCachePriv->Info256;
- max = pCachePriv->Num256x256;
- current = &pCachePriv->Current256;
- } else if((h <= 512) && (w <= 526)){
- cacheRoot = pCachePriv->Info512;
- max = pCachePriv->Num512x512;
- current = &pCachePriv->Current512;
- } else { /* something's wrong */
- ErrorF("Something's wrong in XAACachePlanarMonoStipple()\n");
- return pCachePriv->Info128;
- }
-
- pCache = cacheRoot;
-
- /* lets look for it */
- for(i = 0; i < max; i++, pCache++) {
- if((pCache->serialNumber == pPix->drawable.serialNumber) &&
- (pCache->fg == -1) && (pCache->bg == -1)) {
- pCache->trans_color = -1;
- return pCache;
- }
- }
-
- pCache = &cacheRoot[(*current)++];
- if(*current >= max) *current = 0;
-
- pCache->serialNumber = pPix->drawable.serialNumber;
- pCache->trans_color = pCache->bg = pCache->fg = -1;
- pCache->orig_w = w; pCache->orig_h = h;
-
- /* Plane 0 holds the stipple. Plane 1 holds the inverted stipple */
- (*infoRec->WriteBitmapToCache)(pScrn, pCache->x, pCache->y,
- pPix->drawable.width, pPix->drawable.height, pPix->devPrivate.ptr,
- pPix->devKind, 1, 2);
- if(!(infoRec->PixmapCacheFlags & DO_NOT_TILE_MONO_DATA) &&
- ((w != pCache->w) || (h != pCache->h)))
- XAATileCache(pScrn, pCache, w, h);
-
- return pCache;
-}
-
-XAACachePlanarMonoStippleProc
-XAAGetCachePlanarMonoStipple(void)
-{
- return XAACachePlanarMonoStipple;
-}
-
-XAACacheInfoPtr
-XAACacheStipple(ScrnInfoPtr pScrn, PixmapPtr pPix, int fg, int bg)
-{
- int w = pPix->drawable.width;
- int h = pPix->drawable.height;
- int size = max(w, h);
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
- XAAPixmapCachePrivatePtr pCachePriv =
- (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
- XAACacheInfoPtr pCache, cacheRoot = NULL;
- int i, max = 0;
- int *current;
-
- if(size <= 128) {
- if(pCachePriv->Info128) {
- cacheRoot = pCachePriv->Info128;
- max = pCachePriv->Num128x128;
- current = &pCachePriv->Current128;
- } else {
- cacheRoot = pCachePriv->InfoPartial;
- max = pCachePriv->NumPartial;
- current = &pCachePriv->CurrentPartial;
- }
- } else if(size <= 256) {
- cacheRoot = pCachePriv->Info256;
- max = pCachePriv->Num256x256;
- current = &pCachePriv->Current256;
- } else if(size <= 512) {
- cacheRoot = pCachePriv->Info512;
- max = pCachePriv->Num512x512;
- current = &pCachePriv->Current512;
- } else { /* something's wrong */
- ErrorF("Something's wrong in XAACacheStipple()\n");
- return pCachePriv->Info128;
- }
-
- pCache = cacheRoot;
- /* lets look for it */
- if(bg == -1)
- for(i = 0; i < max; i++, pCache++) {
- if((pCache->serialNumber == pPix->drawable.serialNumber) &&
- (fg == pCache->fg) && (pCache->fg != pCache->bg)) {
- pCache->trans_color = pCache->bg;
- return pCache;
- }
- }
- else
- for(i = 0; i < max; i++, pCache++) {
- if((pCache->serialNumber == pPix->drawable.serialNumber) &&
- (fg == pCache->fg) && (bg == pCache->bg)) {
- pCache->trans_color = -1;
- return pCache;
- }
- }
-
- pCache = &cacheRoot[(*current)++];
- if(*current >= max) *current = 0;
-
- pCache->serialNumber = pPix->drawable.serialNumber;
- pCache->fg = fg;
- if(bg == -1)
- pCache->trans_color = bg = fg ^ 1;
- else
- pCache->trans_color = -1;
- pCache->bg = bg;
-
- pCache->orig_w = w; pCache->orig_h = h;
- (*infoRec->WriteBitmapToCache)(pScrn, pCache->x, pCache->y,
- pPix->drawable.width, pPix->drawable.height, pPix->devPrivate.ptr,
- pPix->devKind, fg, bg);
- if(!(infoRec->PixmapCacheFlags & DO_NOT_TILE_COLOR_DATA) &&
- ((w != pCache->w) || (h != pCache->h)))
- XAATileCache(pScrn, pCache, w, h);
-
- return pCache;
-}
-
-
-
-XAACacheInfoPtr
-XAACacheMono8x8Pattern(ScrnInfoPtr pScrn, int pat0, int pat1)
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
- XAAPixmapCachePrivatePtr pCachePriv =
- (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
- XAACacheInfoPtr pCache = pCachePriv->InfoMono;
- int i;
-
- for(i = 0; i < pCachePriv->NumMono; i++, pCache++) {
- if(pCache->serialNumber &&
- (pCache->pat0 == pat0) && (pCache->pat1 == pat1))
- return pCache;
- }
-
- /* OK, let's cache it */
- pCache = &pCachePriv->InfoMono[pCachePriv->CurrentMono++];
- if(pCachePriv->CurrentMono >= pCachePriv->NumMono)
- pCachePriv->CurrentMono = 0;
-
- pCache->serialNumber = 1; /* we don't care since we do lookups by pattern */
- pCache->pat0 = pat0;
- pCache->pat1 = pat1;
-
- (*infoRec->WriteMono8x8PatternToCache)(pScrn, pCache);
-
- return pCache;
-}
-
-
-
-XAACacheInfoPtr
-XAACacheColor8x8Pattern(ScrnInfoPtr pScrn, PixmapPtr pPix, int fg, int bg)
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
- XAAPixmapCachePrivatePtr pCachePriv =
- (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
- XAACacheInfoPtr pCache = pCachePriv->InfoColor;
- XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
- int i;
-
- if(!(pixPriv->flags & REDUCIBLE_TO_2_COLOR)) {
- for(i = 0; i < pCachePriv->NumColor; i++, pCache++) {
- if(pCache->serialNumber == pPix->drawable.serialNumber) {
- pCache->trans_color = -1;
- return pCache;
- }
- }
- pCache = &pCachePriv->InfoColor[pCachePriv->CurrentColor++];
- if(pCachePriv->CurrentColor >= pCachePriv->NumColor)
- pCachePriv->CurrentColor = 0;
-
- pCache->serialNumber = pPix->drawable.serialNumber;
- pCache->trans_color = pCache->fg = pCache->bg = -1;
- } else {
- int pat0 = pixPriv->pattern0;
- int pat1 = pixPriv->pattern1;
-
- if(fg == -1) { /* it's a tile */
- fg = pixPriv->fg; bg = pixPriv->bg;
- }
-
- if(bg == -1) { /* stipple */
- for(i = 0; i < pCachePriv->NumColor; i++, pCache++) {
- if(pCache->serialNumber &&
- (pCache->pat0 == pat0) && (pCache->pat1 == pat1) &&
- (pCache->fg == fg) && (pCache->bg != fg)) {
- pCache->trans_color = pCache->bg;
- return pCache;
- }
- }
- } else { /* opaque stipple */
- for(i = 0; i < pCachePriv->NumColor; i++, pCache++) {
- if(pCache->serialNumber &&
- (pCache->pat0 == pat0) && (pCache->pat1 == pat1) &&
- (pCache->fg == fg) && (pCache->bg == bg)) {
- pCache->trans_color = -1;
- return pCache;
- }
- }
- }
- pCache = &pCachePriv->InfoColor[pCachePriv->CurrentColor++];
- if(pCachePriv->CurrentColor >= pCachePriv->NumColor)
- pCachePriv->CurrentColor = 0;
-
- if(bg == -1)
- pCache->trans_color = bg = fg ^ 1;
- else
- pCache->trans_color = -1;
-
- pCache->pat0 = pat0; pCache->pat1 = pat1;
- pCache->fg = fg; pCache->bg = bg;
- pCache->serialNumber = 1;
- }
-
- (*infoRec->WriteColor8x8PatternToCache)(pScrn, pPix, pCache);
-
- return pCache;
-}
-
-
-void
-XAAWriteBitmapToCache(
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned char *src,
- int srcwidth,
- int fg, int bg
-) {
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
-
- (*infoRec->WriteBitmap)(pScrn, x, y, w, h, src, srcwidth,
- 0, fg, bg, GXcopy, ~0);
-}
-
-void
-XAAWriteBitmapToCacheLinear(
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned char *src,
- int srcwidth,
- int fg, int bg
-){
- ScreenPtr pScreen = pScrn->pScreen;
- PixmapPtr pScreenPix, pDstPix;
- XID gcvals[2];
- GCPtr pGC;
-
- pScreenPix = (*pScreen->GetScreenPixmap)(pScreen);
-
- pDstPix = GetScratchPixmapHeader(pScreen, pScreenPix->drawable.width,
- y + h, pScreenPix->drawable.depth,
- pScreenPix->drawable.bitsPerPixel,
- pScreenPix->devKind,
- pScreenPix->devPrivate.ptr);
-
- pGC = GetScratchGC(pScreenPix->drawable.depth, pScreen);
- gcvals[0] = fg;
- gcvals[1] = bg;
- DoChangeGC(pGC, GCForeground | GCBackground, gcvals, 0);
- ValidateGC((DrawablePtr)pDstPix, pGC);
-
- /* We've unwrapped already so these ops miss a sync */
- SYNC_CHECK(pScrn);
-
- (*pGC->ops->PutImage)((DrawablePtr)pDstPix, pGC, 1, x, y, w, h, 0,
- XYBitmap, (pointer)src);
-
- FreeScratchGC(pGC);
- FreeScratchPixmapHeader(pDstPix);
-}
-
-
-void
-XAAWritePixmapToCache(
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned char *src,
- int srcwidth,
- int bpp, int depth
-) {
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
-
- (*infoRec->WritePixmap)(pScrn, x, y, w, h, src, srcwidth,
- GXcopy, ~0, -1, bpp, depth);
-}
-
-
-
-void
-XAAWritePixmapToCacheLinear(
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned char *src,
- int srcwidth,
- int bpp, int depth
-){
- ScreenPtr pScreen = pScrn->pScreen;
- PixmapPtr pScreenPix, pDstPix;
- GCPtr pGC;
-
- pScreenPix = (*pScreen->GetScreenPixmap)(pScreen);
-
- pDstPix = GetScratchPixmapHeader(pScreen, x + w, y + h,
- depth, bpp, pScreenPix->devKind,
- pScreenPix->devPrivate.ptr);
-
- pGC = GetScratchGC(depth, pScreen);
- ValidateGC((DrawablePtr)pDstPix, pGC);
-
- /* We've unwrapped already so these ops miss a sync */
- SYNC_CHECK(pScrn);
-
- if(bpp == BitsPerPixel(depth))
- (*pGC->ops->PutImage)((DrawablePtr)pDstPix, pGC, depth, x, y, w,
- h, 0, ZPixmap, (pointer)src);
- else {
- PixmapPtr pSrcPix;
-
- pSrcPix = GetScratchPixmapHeader(pScreen, w, h, depth, bpp,
- srcwidth, (pointer)src);
-
- (*pGC->ops->CopyArea)((DrawablePtr)pSrcPix, (DrawablePtr)pDstPix,
- pGC, 0, 0, w, h, x, y);
-
- FreeScratchPixmapHeader(pSrcPix);
- }
-
- FreeScratchGC(pGC);
- FreeScratchPixmapHeader(pDstPix);
-}
-
-
-void
-XAAWriteMono8x8PatternToCache(
- ScrnInfoPtr pScrn,
- XAACacheInfoPtr pCache
-){
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
- XAAPixmapCachePrivatePtr pCachePriv =
- (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
- unsigned char *data;
- int pad, Bpp = (pScrn->bitsPerPixel >> 3);
-
- pCache->offsets = pCachePriv->MonoOffsets;
-
- pad = BitmapBytePad(pCache->w * pScrn->bitsPerPixel);
-
- data = (unsigned char*)xalloc(pad * pCache->h);
- if(!data) return;
-
- if(infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_PROGRAMMED_ORIGIN) {
- CARD32* ptr = (CARD32*)data;
- ptr[0] = pCache->pat0; ptr[1] = pCache->pat1;
- } else {
- CARD32 *ptr;
- DDXPointPtr pPoint = pCache->offsets;
- int patx, paty, i;
-
- for(i = 0; i < 64; i++, pPoint++) {
- patx = pCache->pat0; paty = pCache->pat1;
- XAARotateMonoPattern(&patx, &paty, i & 0x07, i >> 3,
- (infoRec->Mono8x8PatternFillFlags &
- BIT_ORDER_IN_BYTE_MSBFIRST));
- ptr = (CARD32*)(data + (pad * pPoint->y) + (Bpp * pPoint->x));
- ptr[0] = patx; ptr[1] = paty;
- }
- }
-
- (*infoRec->WritePixmapToCache)(pScrn, pCache->x, pCache->y,
- pCache->w, pCache->h, data, pad, pScrn->bitsPerPixel, pScrn->depth);
-
- xfree(data);
-}
-
-void
-XAAWriteColor8x8PatternToCache(
- ScrnInfoPtr pScrn,
- PixmapPtr pPix,
- XAACacheInfoPtr pCache
-){
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
- XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
- XAAPixmapCachePrivatePtr pCachePriv =
- (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
- int pad, i, w, h, nw, nh, Bpp;
- unsigned char *data, *srcPtr, *dstPtr;
-
- pCache->offsets = pCachePriv->ColorOffsets;
-
- if(pixPriv->flags & REDUCIBLE_TO_2_COLOR) {
- CARD32* ptr;
- pad = BitmapBytePad(pCache->w);
- data = (unsigned char*)xalloc(pad * pCache->h);
- if(!data) return;
-
- if(infoRec->Color8x8PatternFillFlags &
- HARDWARE_PATTERN_PROGRAMMED_ORIGIN) {
- ptr = (CARD32*)data;
- ptr[0] = pCache->pat0; ptr[1] = pCache->pat1;
- } else {
- int patx, paty;
-
- ptr = (CARD32*)data;
- ptr[0] = ptr[2] = pCache->pat0; ptr[1] = ptr[3] = pCache->pat1;
- for(i = 1; i < 8; i++) {
- patx = pCache->pat0; paty = pCache->pat1;
- XAARotateMonoPattern(&patx, &paty, i, 0,
- (infoRec->Mono8x8PatternFillFlags &
- BIT_ORDER_IN_BYTE_MSBFIRST));
- ptr = (CARD32*)(data + (pad * i));
- ptr[0] = ptr[2] = patx; ptr[1] = ptr[3] = paty;
- }
- }
-
- (*infoRec->WriteBitmapToCache)(pScrn, pCache->x, pCache->y,
- pCache->w, pCache->h, data, pad, pCache->fg, pCache->bg);
-
- xfree(data);
- return;
- }
-
- Bpp = pScrn->bitsPerPixel >> 3;
- h = min(8,pPix->drawable.height);
- w = min(8,pPix->drawable.width);
- pad = BitmapBytePad(pCache->w * pScrn->bitsPerPixel);
-
- data = (unsigned char*)xalloc(pad * pCache->h);
- if(!data) return;
-
- /* Write and expand horizontally. */
- for (i = h, dstPtr = data, srcPtr = pPix->devPrivate.ptr; i--;
- srcPtr += pPix->devKind, dstPtr += pScrn->bitsPerPixel) {
- nw = w;
- memcpy(dstPtr, srcPtr, w * Bpp);
- while (nw != 8) {
- memcpy(dstPtr + (nw * Bpp), dstPtr, nw * Bpp);
- nw <<= 1;
- }
- }
- nh = h;
- /* Expand vertically. */
- while (nh != 8) {
- memcpy(data + (nh*pScrn->bitsPerPixel), data, nh*pScrn->bitsPerPixel);
- nh <<= 1;
- }
-
- if(!(infoRec->Color8x8PatternFillFlags &
- HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
- int j;
- unsigned char *ptr = data + (128 * Bpp);
-
- memcpy(data + (64 * Bpp), data, 64 * Bpp);
- for(i = 1; i < 8; i++, ptr += (128 * Bpp)) {
- for(j = 0; j < 8; j++) {
- memcpy(ptr + (j * 8) * Bpp, data + (j * 8 + i) * Bpp,
- (8 - i) * Bpp);
- memcpy(ptr + (j * 8 + 8 - i) * Bpp, data + j * 8 * Bpp, i*Bpp);
- }
- memcpy(ptr + (64 * Bpp), ptr, 64 * Bpp);
- }
- }
-
- (*infoRec->WritePixmapToCache)(pScrn, pCache->x, pCache->y,
- pCache->w, pCache->h, data, pad, pScrn->bitsPerPixel, pScrn->depth);
-
- xfree(data);
-}
-
-
-
-int
-XAAStippledFillChooser(GCPtr pGC)
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
- PixmapPtr pPixmap = pGC->stipple;
- XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
-
- if(!(pPriv->flags & REDUCIBILITY_CHECKED) &&
- (infoRec->CanDoMono8x8 || infoRec->CanDoColor8x8)) {
- XAACheckStippleReducibility(pPixmap);
- }
-
-
- if(pPriv->flags & REDUCIBLE_TO_8x8) {
- if(infoRec->CanDoMono8x8 &&
- !(infoRec->FillMono8x8PatternSpansFlags & NO_TRANSPARENCY) &&
- ((pGC->alu == GXcopy) || !(infoRec->FillMono8x8PatternSpansFlags &
- TRANSPARENCY_GXCOPY_ONLY)) &&
- CHECK_ROP(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
- CHECK_ROPSRC(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
- CHECK_FG(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
- CHECK_PLANEMASK(pGC,infoRec->FillMono8x8PatternSpansFlags)) {
-
- return DO_MONO_8x8;
- }
-
- if(infoRec->CanDoColor8x8 &&
- !(infoRec->FillColor8x8PatternSpansFlags & NO_TRANSPARENCY) &&
- ((pGC->alu == GXcopy) || !(infoRec->FillColor8x8PatternSpansFlags &
- TRANSPARENCY_GXCOPY_ONLY)) &&
- CHECK_ROP(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
- CHECK_ROPSRC(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
- CHECK_PLANEMASK(pGC,infoRec->FillColor8x8PatternSpansFlags)) {
-
- return DO_COLOR_8x8;
- }
- }
-
- if(infoRec->UsingPixmapCache && infoRec->FillCacheExpandSpans &&
- (pPixmap->drawable.height <= infoRec->MaxCacheableStippleHeight) &&
- (pPixmap->drawable.width <= infoRec->MaxCacheableStippleWidth /
- infoRec->CacheColorExpandDensity) &&
- !(infoRec->FillCacheExpandSpansFlags & NO_TRANSPARENCY) &&
- ((pGC->alu == GXcopy) || !(infoRec->FillCacheExpandSpansFlags &
- TRANSPARENCY_GXCOPY_ONLY)) &&
- CHECK_ROP(pGC,infoRec->FillCacheExpandSpansFlags) &&
- CHECK_ROPSRC(pGC,infoRec->FillCacheExpandSpansFlags) &&
- CHECK_FG(pGC,infoRec->FillCacheExpandSpansFlags) &&
- CHECK_PLANEMASK(pGC,infoRec->FillCacheExpandSpansFlags)) {
-
- return DO_CACHE_EXPAND;
- }
-
-
- if(infoRec->UsingPixmapCache &&
- !(infoRec->PixmapCacheFlags & DO_NOT_BLIT_STIPPLES) &&
- infoRec->FillCacheBltSpans &&
- (pPixmap->drawable.height <= infoRec->MaxCacheableTileHeight) &&
- (pPixmap->drawable.width <= infoRec->MaxCacheableTileWidth) &&
- !(infoRec->FillCacheBltSpansFlags & NO_TRANSPARENCY) &&
- ((pGC->alu == GXcopy) || !(infoRec->FillCacheBltSpansFlags &
- TRANSPARENCY_GXCOPY_ONLY)) &&
- CHECK_ROP(pGC,infoRec->FillCacheBltSpansFlags) &&
- CHECK_ROPSRC(pGC,infoRec->FillCacheBltSpansFlags) &&
- CHECK_PLANEMASK(pGC,infoRec->FillCacheBltSpansFlags)) {
-
- return DO_CACHE_BLT;
- }
-
- if(infoRec->FillColorExpandSpans &&
- !(infoRec->FillColorExpandSpansFlags & NO_TRANSPARENCY) &&
- ((pGC->alu == GXcopy) || !(infoRec->FillColorExpandSpansFlags &
- TRANSPARENCY_GXCOPY_ONLY)) &&
- CHECK_ROP(pGC,infoRec->FillColorExpandSpansFlags) &&
- CHECK_ROPSRC(pGC,infoRec->FillColorExpandSpansFlags) &&
- CHECK_FG(pGC,infoRec->FillColorExpandSpansFlags) &&
- CHECK_PLANEMASK(pGC,infoRec->FillColorExpandSpansFlags)) {
-
- return DO_COLOR_EXPAND;
- }
-
- return 0;
-}
-
-
-int
-XAAOpaqueStippledFillChooser(GCPtr pGC)
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
- PixmapPtr pPixmap = pGC->stipple;
- XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
-
- if(XAA_DEPTH_BUG(pGC))
- return 0;
-
- if(!(pPriv->flags & REDUCIBILITY_CHECKED) &&
- (infoRec->CanDoMono8x8 || infoRec->CanDoColor8x8)) {
- XAACheckStippleReducibility(pPixmap);
- }
-
- if(pPriv->flags & REDUCIBLE_TO_8x8) {
- if(infoRec->CanDoMono8x8 &&
- !(infoRec->FillMono8x8PatternSpansFlags & TRANSPARENCY_ONLY) &&
- CHECK_ROP(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
- CHECK_ROPSRC(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
- CHECK_COLORS(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
- CHECK_PLANEMASK(pGC,infoRec->FillMono8x8PatternSpansFlags)) {
-
- return DO_MONO_8x8;
- }
-
- if(infoRec->CanDoColor8x8 &&
- CHECK_ROP(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
- CHECK_ROPSRC(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
- CHECK_PLANEMASK(pGC,infoRec->FillColor8x8PatternSpansFlags)) {
-
- return DO_COLOR_8x8;
- }
- }
-
- if(infoRec->UsingPixmapCache && infoRec->FillCacheExpandSpans &&
- (pPixmap->drawable.height <= infoRec->MaxCacheableStippleHeight) &&
- (pPixmap->drawable.width <= infoRec->MaxCacheableStippleWidth /
- infoRec->CacheColorExpandDensity) &&
- !(infoRec->FillCacheExpandSpansFlags & TRANSPARENCY_ONLY) &&
- CHECK_ROP(pGC,infoRec->FillCacheExpandSpansFlags) &&
- CHECK_ROPSRC(pGC,infoRec->FillCacheExpandSpansFlags) &&
- CHECK_COLORS(pGC,infoRec->FillCacheExpandSpansFlags) &&
- CHECK_PLANEMASK(pGC,infoRec->FillCacheExpandSpansFlags)) {
-
- return DO_CACHE_EXPAND;
- }
-
- if(infoRec->UsingPixmapCache &&
- !(infoRec->PixmapCacheFlags & DO_NOT_BLIT_STIPPLES) &&
- infoRec->FillCacheBltSpans &&
- (pPixmap->drawable.height <= infoRec->MaxCacheableTileHeight) &&
- (pPixmap->drawable.width <= infoRec->MaxCacheableTileWidth) &&
- CHECK_ROP(pGC,infoRec->FillCacheBltSpansFlags) &&
- CHECK_ROPSRC(pGC,infoRec->FillCacheBltSpansFlags) &&
- CHECK_PLANEMASK(pGC,infoRec->FillCacheBltSpansFlags)) {
-
- return DO_CACHE_BLT;
- }
-
- if(infoRec->FillColorExpandSpans &&
- !(infoRec->FillColorExpandSpansFlags & TRANSPARENCY_ONLY) &&
- CHECK_ROP(pGC,infoRec->FillColorExpandSpansFlags) &&
- CHECK_ROPSRC(pGC,infoRec->FillColorExpandSpansFlags) &&
- CHECK_COLORS(pGC,infoRec->FillColorExpandSpansFlags) &&
- CHECK_PLANEMASK(pGC,infoRec->FillColorExpandSpansFlags)) {
-
- return DO_COLOR_EXPAND;
- }
-
- return 0;
-}
-
-
-
-int
-XAATiledFillChooser(GCPtr pGC)
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
- PixmapPtr pPixmap = pGC->tile.pixmap;
- XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
-
- if(IS_OFFSCREEN_PIXMAP(pPixmap) && infoRec->FillCacheBltSpans &&
- CHECK_ROP(pGC,infoRec->FillCacheBltSpansFlags) &&
- CHECK_ROPSRC(pGC,infoRec->FillCacheBltSpansFlags) &&
- CHECK_PLANEMASK(pGC,infoRec->FillCacheBltSpansFlags)) {
-
- return DO_PIXMAP_COPY;
- }
-
- if(!(pPriv->flags & REDUCIBILITY_CHECKED) &&
- (infoRec->CanDoMono8x8 || infoRec->CanDoColor8x8)) {
- XAACheckTileReducibility(pPixmap,infoRec->CanDoMono8x8);
- }
-
- if(pPriv->flags & REDUCIBLE_TO_8x8) {
- if((pPriv->flags & REDUCIBLE_TO_2_COLOR) && infoRec->CanDoMono8x8 &&
- !(infoRec->FillMono8x8PatternSpansFlags & TRANSPARENCY_ONLY) &&
- CHECK_ROP(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
- CHECK_ROPSRC(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
- (!(infoRec->FillMono8x8PatternSpansFlags & RGB_EQUAL) ||
- (CHECK_RGB_EQUAL(pPriv->fg) && CHECK_RGB_EQUAL(pPriv->bg))) &&
- CHECK_PLANEMASK(pGC,infoRec->FillMono8x8PatternSpansFlags)) {
-
- return DO_MONO_8x8;
- }
-
- if(infoRec->CanDoColor8x8 &&
- CHECK_ROP(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
- CHECK_ROPSRC(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
- CHECK_PLANEMASK(pGC,infoRec->FillColor8x8PatternSpansFlags)) {
-
- return DO_COLOR_8x8;
- }
- }
-
- if(infoRec->UsingPixmapCache && infoRec->FillCacheBltSpans &&
- (pPixmap->drawable.height <= infoRec->MaxCacheableTileHeight) &&
- (pPixmap->drawable.width <= infoRec->MaxCacheableTileWidth) &&
- CHECK_ROP(pGC,infoRec->FillCacheBltSpansFlags) &&
- CHECK_ROPSRC(pGC,infoRec->FillCacheBltSpansFlags) &&
- CHECK_PLANEMASK(pGC,infoRec->FillCacheBltSpansFlags)) {
-
- return DO_CACHE_BLT;
- }
-
- if(infoRec->FillImageWriteRects &&
- CHECK_NO_GXCOPY(pGC,infoRec->FillImageWriteRectsFlags) &&
- CHECK_ROP(pGC,infoRec->FillImageWriteRectsFlags) &&
- CHECK_ROPSRC(pGC,infoRec->FillImageWriteRectsFlags) &&
- CHECK_PLANEMASK(pGC,infoRec->FillImageWriteRectsFlags)) {
-
- return DO_IMAGE_WRITE;
- }
-
- return 0;
-}
-
-
-static int RotateMasksX[8] = {
- 0xFFFFFFFF, 0x7F7F7F7F, 0x3F3F3F3F, 0x1F1F1F1F,
- 0x0F0F0F0F, 0x07070707, 0x03030303, 0x01010101
-};
-
-static int RotateMasksY[4] = {
- 0xFFFFFFFF, 0x00FFFFFF, 0x0000FFFF, 0x000000FF
-};
-
-void
-XAARotateMonoPattern(
- int *pat0, int *pat1,
- int xorg, int yorg,
- Bool msbfirst
-){
- int tmp, mask;
-
- if(xorg) {
- if(msbfirst) xorg = 8 - xorg;
- mask = RotateMasksX[xorg];
- *pat0 = ((*pat0 >> xorg) & mask) | ((*pat0 << (8 - xorg)) & ~mask);
- *pat1 = ((*pat1 >> xorg) & mask) | ((*pat1 << (8 - xorg)) & ~mask);
- }
- if(yorg >= 4) {
- tmp = *pat0; *pat0 = *pat1; *pat1 = tmp;
- yorg -= 4;
- }
- if(yorg) {
- mask = RotateMasksY[yorg];
- yorg <<= 3;
- tmp = *pat0;
- *pat0 = ((*pat0 >> yorg) & mask) | ((*pat1 << (32 - yorg)) & ~mask);
- *pat1 = ((*pat1 >> yorg) & mask) | ((tmp << (32 - yorg)) & ~mask);
- }
-}
-
-
-
-void
-XAAInvalidatePixmapCache(ScreenPtr pScreen)
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
- XAAPixmapCachePrivatePtr pCachePriv =
- (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
- int i;
-
- if(!pCachePriv) return;
-
- for(i = 0; i < pCachePriv->Num512x512; i++)
- (pCachePriv->Info512)[i].serialNumber = 0;
- for(i = 0; i < pCachePriv->Num256x256; i++)
- (pCachePriv->Info256)[i].serialNumber = 0;
- for(i = 0; i < pCachePriv->Num128x128; i++)
- (pCachePriv->Info128)[i].serialNumber = 0;
- for(i = 0; i < pCachePriv->NumPartial; i++)
- (pCachePriv->InfoPartial)[i].serialNumber = 0;
- for(i = 0; i < pCachePriv->NumMono; i++)
- (pCachePriv->InfoMono)[i].serialNumber = 0;
- for(i = 0; i < pCachePriv->NumColor; i++)
- (pCachePriv->InfoColor)[i].serialNumber = 0;
-}
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <string.h>
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include <X11/X.h>
+#include "scrnintstr.h"
+#include "gc.h"
+#include "mi.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "regionstr.h"
+#include "servermd.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaacexp.h"
+#include "xaalocal.h"
+#include "xaawrap.h"
+
+#define MAX_COLOR 32
+#define MAX_MONO 32
+#define MAX_8 32
+#define MAX_128 32
+#define MAX_256 32
+#define MAX_512 16
+
+static int CacheInitIndex = -1;
+#define CACHEINIT(p) ((p)->privates[CacheInitIndex].val)
+
+
+typedef struct _CacheLink {
+ int x;
+ int y;
+ int w;
+ int h;
+ struct _CacheLink *next;
+} CacheLink, *CacheLinkPtr;
+
+
+static void
+TransferList(CacheLinkPtr list, XAACacheInfoPtr array, int num)
+{
+ while(num--) {
+ array->x = list->x;
+ array->y = list->y;
+ array->w = list->w;
+ array->h = list->h;
+ array->serialNumber = 0;
+ array->fg = array->bg = -1;
+ list = list->next;
+ array++;
+ }
+}
+
+
+
+static CacheLinkPtr
+Enlist(CacheLinkPtr link, int x, int y, int w, int h)
+{
+ CacheLinkPtr newLink;
+
+ newLink = malloc(sizeof(CacheLink));
+ newLink->next = link;
+ newLink->x = x; newLink->y = y;
+ newLink->w = w; newLink->h = h;
+ return newLink;
+}
+
+
+
+static CacheLinkPtr
+Delist(CacheLinkPtr link) {
+ CacheLinkPtr ret = NULL;
+
+ if(link) {
+ ret = link->next;
+ free(link);
+ }
+ return ret;
+}
+
+
+
+static void
+FreeList(CacheLinkPtr link) {
+ CacheLinkPtr tmp;
+
+ while(link) {
+ tmp = link;
+ link = link->next;
+ free(tmp);
+ }
+}
+
+
+
+static CacheLinkPtr
+QuadLinks(CacheLinkPtr big, CacheLinkPtr little)
+{
+ /* CAUTION: This doesn't free big */
+ int w1, w2, h1, h2;
+
+ while(big) {
+ w1 = big->w >> 1;
+ w2 = big->w - w1;
+ h1 = big->h >> 1;
+ h2 = big->h - h1;
+
+ little = Enlist(little, big->x, big->y, w1, h1);
+ little = Enlist(little, big->x + w1, big->y, w2, h1);
+ little = Enlist(little, big->x, big->y + h1, w1, h2);
+ little = Enlist(little, big->x + w1, big->y + h1, w2, h2);
+
+ big = big->next;
+ }
+ return little;
+}
+
+
+static void
+SubdivideList(CacheLinkPtr *large, CacheLinkPtr *small)
+{
+ CacheLinkPtr big = *large;
+ CacheLinkPtr little = *small;
+ int size = big->w >> 1;
+
+ little = Enlist(little, big->x, big->y, size, size);
+ little = Enlist(little, big->x + size, big->y, size, size);
+ little = Enlist(little, big->x, big->y + size, size, size);
+ little = Enlist(little, big->x + size, big->y + size, size, size);
+ *small = little;
+ big = Delist(big);
+ *large = big;
+}
+
+static void
+FreePixmapCachePrivate(XAAPixmapCachePrivatePtr pPriv)
+{
+ if(!pPriv) return;
+
+ if(pPriv->Info512)
+ free(pPriv->Info512);
+ if(pPriv->Info256)
+ free(pPriv->Info256);
+ if(pPriv->Info128)
+ free(pPriv->Info128);
+ if(pPriv->InfoColor)
+ free(pPriv->InfoColor);
+ if(pPriv->InfoMono)
+ free(pPriv->InfoMono);
+ if(pPriv->InfoPartial)
+ free(pPriv->InfoPartial);
+
+ free(pPriv);
+}
+
+void
+XAAClosePixmapCache(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+
+ if(infoRec->PixmapCachePrivate)
+ FreePixmapCachePrivate(
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate);
+
+ infoRec->PixmapCachePrivate = NULL;
+}
+
+
+
+static CacheLinkPtr
+ThinOutPartials(
+ CacheLinkPtr ListPartial,
+ int *num, int *maxw, int *maxh
+) {
+/* This guy's job is to get at least 4 big slots out of a list of fragments */
+
+ CacheLinkPtr List64, List32, List16, List8, pCur, next, ListKeepers;
+ int Num64, Num32, Num16, Num8, NumKeepers;
+ int w, h;
+
+ List64 = List32 = List16 = List8 = ListKeepers = NULL;
+ Num64 = Num32 = Num16 = Num8 = NumKeepers = 0;
+ w = h = 0;
+
+ /* We sort partials by how large a square tile they can cache.
+ If a partial can't store a 64x64, 32x32, 16x16 or 8x8 tile,
+ we free it. */
+
+ pCur = ListPartial;
+ while(pCur) {
+ next = pCur->next;
+ if((pCur->w >= 64) && (pCur->h >= 64)) {
+ pCur->next = List64; List64 = pCur;
+ Num64++;
+ } else
+ if((pCur->w >= 32) && (pCur->h >= 32)) {
+ pCur->next = List32; List32 = pCur;
+ Num32++;
+ } else
+ if((pCur->w >= 16) && (pCur->h >= 16)) {
+ pCur->next = List16; List16 = pCur;
+ Num16++;
+ } else
+ if((pCur->w >= 8) && (pCur->h >= 8)) {
+ pCur->next = List8; List8 = pCur;
+ Num8++;
+ } else {
+ free(pCur);
+ }
+
+ pCur = next;
+ }
+
+ /* We save all the tiles from the largest bin that we can get
+ at least 4 of. If there are too few of a bigger slot, we
+ cut it in fourths to make smaller slots. */
+
+ if(Num64 >= 4) {
+ ListKeepers = List64; List64 = NULL;
+ NumKeepers = Num64;
+ goto GOT_EM;
+ } else if(Num64) {
+ List32 = QuadLinks(List64, List32);
+ Num32 += Num64 * 4;
+ Num64 = 0;
+ }
+
+ if(Num32 >= 4) {
+ ListKeepers = List32; List32 = NULL;
+ NumKeepers = Num32;
+ goto GOT_EM;
+ } else if(Num32) {
+ List16 = QuadLinks(List32, List16);
+ Num16 += Num32 * 4;
+ Num32 = 0;
+ }
+
+ if(Num16 >= 4) {
+ ListKeepers = List16; List16 = NULL;
+ NumKeepers = Num16;
+ goto GOT_EM;
+ } else if(Num16) {
+ List8 = QuadLinks(List16, List8);
+ Num8 += Num16 * 4;
+ Num16 = 0;
+ }
+
+ if(Num8 >= 4) {
+ ListKeepers = List8; List8 = NULL;
+ NumKeepers = Num8;
+ goto GOT_EM;
+ }
+
+GOT_EM:
+
+ /* Free the ones we aren't using */
+
+ if(List64) FreeList(List64);
+ if(List32) FreeList(List32);
+ if(List16) FreeList(List16);
+ if(List8) FreeList(List8);
+
+
+ /* Enlarge the slots if we can */
+
+ if(ListKeepers) {
+ CacheLinkPtr pLink = ListKeepers;
+ w = h = 128;
+
+ while(pLink) {
+ if(pLink->w < w) w = pLink->w;
+ if(pLink->h < h) h = pLink->h;
+ pLink = pLink->next;
+ }
+ }
+
+ *maxw = w;
+ *maxh = h;
+ *num = NumKeepers;
+ return ListKeepers;
+}
+
+static void
+ConvertColorToMono(
+ CacheLinkPtr *ColorList,
+ int ColorW, int ColorH,
+ CacheLinkPtr *MonoList,
+ int MonoW, int MonoH
+){
+ int x, y, w;
+
+ x = (*ColorList)->x; y = (*ColorList)->y;
+ *ColorList = Delist(*ColorList);
+
+ while(ColorH) {
+ ColorH -= MonoH;
+ for(w = 0; w <= (ColorW - MonoW); w += MonoW)
+ *MonoList = Enlist(*MonoList, x + w, y + ColorH, MonoW, MonoH);
+ }
+}
+
+static void
+ConvertAllPartialsTo8x8(
+ int *NumMono, int *NumColor,
+ CacheLinkPtr ListPartial,
+ CacheLinkPtr *ListMono,
+ CacheLinkPtr *ListColor,
+ XAAInfoRecPtr infoRec
+){
+/* This guy extracts as many 8x8 slots as it can out of fragments */
+
+ int ColorH = infoRec->CacheHeightColor8x8Pattern;
+ int ColorW = infoRec->CacheWidthColor8x8Pattern;
+ int MonoH = infoRec->CacheHeightMono8x8Pattern;
+ int MonoW = infoRec->CacheWidthMono8x8Pattern;
+ int x, y, w, Height, Width;
+ Bool DoColor = (infoRec->PixmapCacheFlags & CACHE_COLOR_8x8);
+ Bool DoMono = (infoRec->PixmapCacheFlags & CACHE_MONO_8x8);
+ CacheLinkPtr pLink = ListPartial;
+ CacheLinkPtr MonoList = *ListMono, ColorList = *ListColor;
+
+ if(DoColor && DoMono) {
+ /* we assume color patterns take more space than color ones */
+ if(MonoH > ColorH) ColorH = MonoH;
+ if(MonoW > ColorW) ColorW = MonoW;
+ }
+
+ /* Break up the area into as many Color and Mono slots as we can */
+
+ while(pLink) {
+ Height = pLink->h;
+ Width = pLink->w;
+ x = pLink->x;
+ y = pLink->y;
+
+ if(DoColor) {
+ while(Height >= ColorH) {
+ Height -= ColorH;
+ for(w = 0; w <= (Width - ColorW); w += ColorW) {
+ ColorList = Enlist(
+ ColorList, x + w, y + Height, ColorW, ColorH);
+ (*NumColor)++;
+ }
+ }
+ }
+
+ if(DoMono && (Height >= MonoH)) {
+ while(Height >= MonoH) {
+ Height -= MonoH;
+ for(w = 0; w <= (Width - MonoW); w += MonoW) {
+ MonoList = Enlist(
+ MonoList, x + w, y + Height, MonoW, MonoH);
+ (*NumMono)++;
+ }
+ }
+ }
+
+ pLink = pLink->next;
+ }
+
+
+ *ListMono = MonoList;
+ *ListColor = ColorList;
+ FreeList(ListPartial);
+}
+
+
+static CacheLinkPtr
+ExtractOneThatFits(CacheLinkPtr *initList, int w, int h)
+{
+ CacheLinkPtr list = *initList;
+ CacheLinkPtr prev = NULL;
+
+ while(list) {
+ if((list->w >= w) && (list->h >= h))
+ break;
+ prev = list;
+ list = list->next;
+ }
+
+ if(list) {
+ if(prev)
+ prev->next = list->next;
+ else
+ *initList = list->next;
+
+ list->next = NULL;
+ }
+
+ return list;
+}
+
+
+static CacheLinkPtr
+ConvertSomePartialsTo8x8(
+ int *NumMono, int *NumColor, int *NumPartial,
+ CacheLinkPtr ListPartial,
+ CacheLinkPtr *ListMono,
+ CacheLinkPtr *ListColor,
+ int *maxw, int *maxh,
+ XAAInfoRecPtr infoRec
+){
+/* This guy tries to get 4 of each type of 8x8 slot requested out of
+ a list of fragments all while trying to retain some big fragments
+ for the cache blits */
+
+ int ColorH = infoRec->CacheHeightColor8x8Pattern;
+ int ColorW = infoRec->CacheWidthColor8x8Pattern;
+ int MonoH = infoRec->CacheHeightMono8x8Pattern;
+ int MonoW = infoRec->CacheWidthMono8x8Pattern;
+ Bool DoColor = (infoRec->PixmapCacheFlags & CACHE_COLOR_8x8);
+ Bool DoMono = (infoRec->PixmapCacheFlags & CACHE_MONO_8x8);
+ CacheLinkPtr List64, List32, List16, List8, pCur, next, ListKeepers;
+ CacheLinkPtr MonoList = *ListMono, ColorList = *ListColor;
+ int Num64, Num32, Num16, Num8, NumKeepers;
+ int w, h, Width, Height;
+ int MonosPerColor = 1;
+
+ if(DoColor && DoMono) {
+ /* we assume color patterns take more space than color ones */
+ if(MonoH > ColorH) ColorH = MonoH;
+ if(MonoW > ColorW) ColorW = MonoW;
+ MonosPerColor = (ColorH/MonoH) * (ColorW/MonoW);
+ }
+
+ List64 = List32 = List16 = List8 = ListKeepers = MonoList = ColorList = NULL;
+ Num64 = Num32 = Num16 = Num8 = NumKeepers = 0;
+ Width = Height = 0;
+
+ /* We sort partials by how large a square tile they can cache.
+ We make 8x8 patterns from the leftovers if we can. */
+
+ pCur = ListPartial;
+ while(pCur) {
+ next = pCur->next;
+ if((pCur->w >= 64) && (pCur->h >= 64)) {
+ pCur->next = List64; List64 = pCur;
+ Num64++;
+ } else
+ if((pCur->w >= 32) && (pCur->h >= 32)) {
+ pCur->next = List32; List32 = pCur;
+ Num32++;
+ } else
+ if((pCur->w >= 16) && (pCur->h >= 16)) {
+ pCur->next = List16; List16 = pCur;
+ Num16++;
+ } else
+ if((pCur->w >= 8) && (pCur->h >= 8)) {
+ pCur->next = List8; List8 = pCur;
+ Num8++;
+ } else {
+ h = pCur->h;
+ if(DoColor && (pCur->w >= ColorW) && (h >= ColorH)) {
+ while(h >= ColorH) {
+ h -= ColorH;
+ for(w = 0; w <= (pCur->w - ColorW); w += ColorW) {
+ ColorList = Enlist( ColorList,
+ pCur->x + w, pCur->y + h, ColorW, ColorH);
+ (*NumColor)++;
+ }
+ }
+ }
+ if(DoMono && (pCur->w >= MonoW) && (h >= MonoH)) {
+ while(h >= MonoH) {
+ h -= MonoH;
+ for(w = 0; w <= (pCur->w - MonoW); w += MonoW) {
+ MonoList = Enlist( MonoList,
+ pCur->x + w, pCur->y + h, MonoW, MonoH);
+ (*NumMono)++;
+ }
+ }
+ }
+ free(pCur);
+ }
+
+ pCur = next;
+ }
+
+ /* Try to extract at least 4 of each type of 8x8 slot that we need */
+
+ if(DoColor) {
+ CacheLinkPtr theOne;
+ while(*NumColor < 4) {
+ theOne = NULL;
+ if(Num8) {
+ if((theOne = ExtractOneThatFits(&List8, ColorW, ColorH)))
+ Num8--;
+ }
+ if(Num16 && !theOne) {
+ if((theOne = ExtractOneThatFits(&List16, ColorW, ColorH)))
+ Num16--;
+ }
+ if(Num32 && !theOne) {
+ if((theOne = ExtractOneThatFits(&List32, ColorW, ColorH)))
+ Num32--;
+ }
+ if(Num64 && !theOne) {
+ if((theOne = ExtractOneThatFits(&List64, ColorW, ColorH)))
+ Num64--;
+ }
+
+ if(!theOne) break;
+
+
+ ConvertAllPartialsTo8x8(NumMono, NumColor, theOne,
+ &MonoList, &ColorList, infoRec);
+
+ if(DoMono) {
+ while(*NumColor && (*NumMono < 4)) {
+ ConvertColorToMono(&ColorList, ColorW, ColorH,
+ &MonoList, MonoW, MonoH);
+ (*NumColor)--; *NumMono += MonosPerColor;
+ }
+ }
+ }
+ }
+
+ if(DoMono) {
+ CacheLinkPtr theOne;
+ while(*NumMono < 4) {
+ theOne = NULL;
+ if(Num8) {
+ if((theOne = ExtractOneThatFits(&List8, MonoW, MonoH)))
+ Num8--;
+ }
+ if(Num16 && !theOne) {
+ if((theOne = ExtractOneThatFits(&List16, MonoW, MonoH)))
+ Num16--;
+ }
+ if(Num32 && !theOne) {
+ if((theOne = ExtractOneThatFits(&List32, MonoW, MonoH)))
+ Num32--;
+ }
+ if(Num64 && !theOne) {
+ if((theOne = ExtractOneThatFits(&List64, MonoW, MonoH)))
+ Num64--;
+ }
+
+ if(!theOne) break;
+
+ ConvertAllPartialsTo8x8(NumMono, NumColor, theOne,
+ &MonoList, &ColorList, infoRec);
+ }
+ }
+
+ /* We save all the tiles from the largest bin that we can get
+ at least 4 of. If there are too few of a bigger slot, we
+ cut it in fourths to make smaller slots. */
+
+ if(Num64 >= 4) {
+ ListKeepers = List64; List64 = NULL;
+ NumKeepers = Num64;
+ goto GOT_EM;
+ } else if(Num64) {
+ List32 = QuadLinks(List64, List32);
+ Num32 += Num64 * 4;
+ Num64 = 0;
+ }
+
+ if(Num32 >= 4) {
+ ListKeepers = List32; List32 = NULL;
+ NumKeepers = Num32;
+ goto GOT_EM;
+ } else if(Num32) {
+ List16 = QuadLinks(List32, List16);
+ Num16 += Num32 * 4;
+ Num32 = 0;
+ }
+
+ if(Num16 >= 4) {
+ ListKeepers = List16; List16 = NULL;
+ NumKeepers = Num16;
+ goto GOT_EM;
+ } else if(Num16) {
+ List8 = QuadLinks(List16, List8);
+ Num8 += Num16 * 4;
+ Num16 = 0;
+ }
+
+ if(Num8 >= 4) {
+ ListKeepers = List8; List8 = NULL;
+ NumKeepers = Num8;
+ goto GOT_EM;
+ }
+
+GOT_EM:
+
+ /* Free the ones we aren't using */
+
+ if(List64)
+ ConvertAllPartialsTo8x8(NumMono, NumColor, List64,
+ &MonoList, &ColorList, infoRec);
+ if(List32)
+ ConvertAllPartialsTo8x8(NumMono, NumColor, List32,
+ &MonoList, &ColorList, infoRec);
+ if(List16)
+ ConvertAllPartialsTo8x8(NumMono, NumColor, List16,
+ &MonoList, &ColorList, infoRec);
+ if(List8)
+ ConvertAllPartialsTo8x8(NumMono, NumColor, List8,
+ &MonoList, &ColorList, infoRec);
+
+
+ /* Enlarge the slots if we can */
+
+ if(ListKeepers) {
+ CacheLinkPtr pLink = ListKeepers;
+ Width = Height = 128;
+
+ while(pLink) {
+ if(pLink->w < Width) Width = pLink->w;
+ if(pLink->h < Height) Height = pLink->h;
+ pLink = pLink->next;
+ }
+ }
+
+ *ListMono = MonoList;
+ *ListColor = ColorList;
+ *maxw = Width;
+ *maxh = Height;
+ *NumPartial = NumKeepers;
+ return ListKeepers;
+}
+
+
+void
+XAAInitPixmapCache(
+ ScreenPtr pScreen,
+ RegionPtr areas,
+ pointer data
+) {
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XAAInfoRecPtr infoRec = (XAAInfoRecPtr)data;
+ XAAPixmapCachePrivatePtr pCachePriv;
+ BoxPtr pBox = REGION_RECTS(areas);
+ int nBox = REGION_NUM_RECTS(areas);
+ int Num512, Num256, Num128, NumPartial, NumColor, NumMono;
+ int Target512, Target256;
+ CacheLinkPtr List512, List256, List128, ListPartial, ListColor, ListMono;
+ int x, y, w, h, ntotal, granularity, width, height, i;
+ int MaxPartialWidth, MaxPartialHeight;
+
+ infoRec->MaxCacheableTileWidth = 0;
+ infoRec->MaxCacheableTileHeight = 0;
+ infoRec->MaxCacheableStippleHeight = 0;
+ infoRec->MaxCacheableStippleWidth = 0;
+ infoRec->UsingPixmapCache = FALSE;
+
+
+ if(!nBox || !pBox || !(infoRec->Flags & PIXMAP_CACHE))
+ return;
+
+ /* Allocate a persistent per-screen init flag to control messages */
+ if (CacheInitIndex < 0)
+ CacheInitIndex = xf86AllocateScrnInfoPrivateIndex();
+
+ /* free the old private data if it exists */
+ if(infoRec->PixmapCachePrivate) {
+ FreePixmapCachePrivate(
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate);
+ infoRec->PixmapCachePrivate = NULL;
+ }
+
+ Num512 = Num256 = Num128 = NumPartial = NumMono = NumColor = 0;
+ List512 = List256 = List128 = ListPartial = ListMono = ListColor = NULL;
+ granularity = infoRec->CachePixelGranularity;
+ if(granularity <= 1) granularity = 0;
+
+ /* go through the boxes and break it into as many pieces as we can fit */
+
+ while(nBox--) {
+ x = pBox->x1;
+ if(granularity) {
+ int tmp = x % granularity;
+ if(tmp) x += (granularity - tmp);
+ }
+ width = pBox->x2 - x;
+ if(width <= 0) {pBox++; continue;}
+
+ y = pBox->y1;
+ height = pBox->y2 - y;
+
+ for(h = 0; h <= (height - 512); h += 512) {
+ for(w = 0; w <= (width - 512); w += 512) {
+ List512 = Enlist(List512, x + w, y + h, 512, 512);
+ Num512++;
+ }
+ for(; w <= (width - 256); w += 256) {
+ List256 = Enlist(List256, x + w, y + h, 256, 256);
+ List256 = Enlist(List256, x + w, y + h + 256, 256, 256);
+ Num256 += 2;
+ }
+ for(; w <= (width - 128); w += 128) {
+ List128 = Enlist(List128, x + w, y + h, 128, 128);
+ List128 = Enlist(List128, x + w, y + h + 128, 128, 128);
+ List128 = Enlist(List128, x + w, y + h + 256, 128, 128);
+ List128 = Enlist(List128, x + w, y + h + 384, 128, 128);
+ Num128 += 4;
+ }
+ if(w < width) {
+ int d = width - w;
+ ListPartial = Enlist(ListPartial, x + w, y + h, d, 128);
+ ListPartial = Enlist(ListPartial, x + w, y + h + 128, d, 128);
+ ListPartial = Enlist(ListPartial, x + w, y + h + 256, d, 128);
+ ListPartial = Enlist(ListPartial, x + w, y + h + 384, d, 128);
+ NumPartial += 4;
+ }
+ }
+ for(; h <= (height - 256); h += 256) {
+ for(w = 0; w <= (width - 256); w += 256) {
+ List256 = Enlist(List256, x + w, y + h, 256, 256);
+ Num256++;
+ }
+ for(; w <= (width - 128); w += 128) {
+ List128 = Enlist(List128, x + w, y + h, 128, 128);
+ List128 = Enlist(List128, x + w, y + h + 128, 128, 128);
+ Num128 += 2;
+ }
+ if(w < width) {
+ int d = width - w;
+ ListPartial = Enlist(ListPartial, x + w, y + h, d, 128);
+ ListPartial = Enlist(ListPartial, x + w, y + h + 128, d, 128);
+ NumPartial += 2;
+ }
+ }
+ for(; h <= (height - 128); h += 128) {
+ for(w = 0; w <= (width - 128); w += 128) {
+ List128 = Enlist(List128, x + w, y + h, 128, 128);
+ Num128++;
+ }
+ if(w < width) {
+ ListPartial = Enlist(
+ ListPartial, x + w, y + h, width - w, 128);
+ NumPartial++;
+ }
+ }
+ if(h < height) {
+ int d = height - h;
+ for(w = 0; w <= (width - 128); w += 128) {
+ ListPartial = Enlist(ListPartial, x + w, y + h, 128, d);
+ NumPartial++;
+ }
+ if(w < width) {
+ ListPartial = Enlist(ListPartial, x + w, y + h, width - w, d);
+ NumPartial++;
+ }
+ }
+ pBox++;
+ }
+
+
+/*
+ by this point we've carved the space into as many 512x512, 256x256
+ and 128x128 blocks as we could fit. We will then break larger
+ blocks into smaller ones if we need to. The rules are as follows:
+
+ 512x512 -
+ 1) Don't take up more than half the memory.
+ 2) Don't bother if you can't get at least four.
+ 3) Don't make more than MAX_512.
+ 4) Don't have any of there are no 256x256s.
+
+ 256x256 -
+ 1) Don't take up more than a quarter of the memory enless there
+ aren't any 512x512s. Then we can take up to half.
+ 2) Don't bother if you can't get at least four.
+ 3) Don't make more than MAX_256.
+
+ 128x128 -
+ 1) Don't make more than MAX_128.
+
+ We don't bother with the partial blocks unless we can use them
+ for 8x8 pattern fills or we are short on larger blocks.
+
+*/
+
+ ntotal = Num128 + (Num256<<2) + (Num512<<4);
+
+ Target512 = ntotal >> 5;
+ if(Target512 < 4) Target512 = 0;
+ if(!Target512) Target256 = ntotal >> 3;
+ else Target256 = ntotal >> 4;
+ if(Target256 < 4) Target256 = 0;
+
+ if(Num512 && Num256 < 4) {
+ while(Num512 && Num256 < Target256) {
+ SubdivideList(&List512, &List256);
+ Num256 += 4; Num512--;
+ }
+ }
+
+ if(!Num512) { /* no room */
+ } else if((Num512 < 4) || (!Target512)) {
+ while(Num512) {
+ SubdivideList(&List512, &List256);
+ Num256 += 4; Num512--;
+ }
+ } else if((Num512 > MAX_512) || (Num512 > Target512)){
+ while(Num512 > MAX_512) {
+ SubdivideList(&List512, &List256);
+ Num256 += 4; Num512--;
+ }
+ while(Num512 > Target512) {
+ if(Num256 < MAX_256) {
+ SubdivideList(&List512, &List256);
+ Num256 += 4; Num512--;
+ } else break;
+ }
+ }
+
+ if(!Num256) { /* no room */
+ } else if((Num256 < 4) || (!Target256)) {
+ while(Num256) {
+ SubdivideList(&List256, &List128);
+ Num128 += 4; Num256--;
+ }
+ } else if((Num256 > MAX_256) || (Num256 > Target256)) {
+ while(Num256 > MAX_256) {
+ SubdivideList(&List256, &List128);
+ Num128 += 4; Num256--;
+ }
+ while(Num256 > Target256) {
+ if(Num128 < MAX_128) {
+ SubdivideList(&List256, &List128);
+ Num128 += 4; Num256--;
+ } else break;
+ }
+ }
+
+ if(Num128 && ((Num128 < 4) || (Num128 > MAX_128))) {
+ CacheLinkPtr next;
+ int max = (Num128 > MAX_128) ? MAX_128 : 0;
+
+ /*
+ * Note: next is set in this way to work around a code generation
+ * bug in gcc 2.7.2.3.
+ */
+ next = List128->next;
+ while(Num128 > max) {
+ List128->next = ListPartial;
+ ListPartial = List128;
+ if((List128 = next))
+ next = List128->next;
+ NumPartial++; Num128--;
+ }
+ }
+
+ MaxPartialHeight = MaxPartialWidth = 0;
+
+ /* at this point we have as many 512x512 and 256x256 slots as we
+ want but may have an excess of 128x128 slots. We still need
+ to find out if we need 8x8 slots. We take these from the
+ partials if we have them. Otherwise, we break some 128x128's */
+
+ if(!(infoRec->PixmapCacheFlags & (CACHE_MONO_8x8 | CACHE_COLOR_8x8))) {
+ if(NumPartial) {
+ if(Num128) { /* don't bother with partials */
+ FreeList(ListPartial);
+ NumPartial = 0; ListPartial = NULL;
+ } else {
+ /* We have no big slots. Weed out the unusable partials */
+ ListPartial = ThinOutPartials(ListPartial, &NumPartial,
+ &MaxPartialWidth, &MaxPartialHeight);
+ }
+ }
+ } else {
+ int MonosPerColor = 1;
+ int ColorH = infoRec->CacheHeightColor8x8Pattern;
+ int ColorW = infoRec->CacheWidthColor8x8Pattern;
+ int MonoH = infoRec->CacheHeightMono8x8Pattern;
+ int MonoW = infoRec->CacheWidthMono8x8Pattern;
+ Bool DoColor = (infoRec->PixmapCacheFlags & CACHE_COLOR_8x8);
+ Bool DoMono = (infoRec->PixmapCacheFlags & CACHE_MONO_8x8);
+
+ if(DoColor) infoRec->CanDoColor8x8 = FALSE;
+ if(DoMono) infoRec->CanDoMono8x8 = FALSE;
+
+ if(DoColor && DoMono) {
+ /* we assume color patterns take more space than color ones */
+ if(MonoH > ColorH) ColorH = MonoH;
+ if(MonoW > ColorW) ColorW = MonoW;
+ MonosPerColor = (ColorH/MonoH) * (ColorW/MonoW);
+ }
+
+ if(Num128) {
+ if(NumPartial) { /* use all for 8x8 slots */
+ ConvertAllPartialsTo8x8(&NumMono, &NumColor,
+ ListPartial, &ListMono, &ListColor, infoRec);
+ NumPartial = 0; ListPartial = NULL;
+ }
+
+ /* Get some 8x8 slots from the 128 slots */
+ while((Num128 > 4) &&
+ ((NumMono < MAX_MONO) && (NumColor < MAX_COLOR))) {
+ CacheLinkPtr tmp = NULL;
+
+ tmp = Enlist(tmp, List128->x, List128->y,
+ List128->w, List128->h);
+ List128 = Delist(List128);
+ Num128--;
+
+ ConvertAllPartialsTo8x8(&NumMono, &NumColor,
+ tmp, &ListMono, &ListColor, infoRec);
+ }
+ } else if(NumPartial) {
+ /* We have share partials between 8x8 slots and tiles. */
+ ListPartial = ConvertSomePartialsTo8x8(&NumMono, &NumColor,
+ &NumPartial, ListPartial, &ListMono, &ListColor,
+ &MaxPartialWidth, &MaxPartialHeight, infoRec);
+ }
+
+
+ if(DoMono && DoColor) {
+ if(NumColor && ((NumColor > MAX_COLOR) || (NumColor < 4))) {
+ int max = (NumColor > MAX_COLOR) ? MAX_COLOR : 0;
+
+ while(NumColor > max) {
+ ConvertColorToMono(&ListColor, ColorW, ColorH,
+ &ListMono, MonoW, MonoH);
+ NumColor--; NumMono += MonosPerColor;
+ }
+ }
+
+ /* favor Mono slots over Color ones */
+ while((NumColor > 4) && (NumMono < MAX_MONO)) {
+ ConvertColorToMono(&ListColor, ColorW, ColorH,
+ &ListMono, MonoW, MonoH);
+ NumColor--; NumMono += MonosPerColor;
+ }
+ }
+
+ if(NumMono && ((NumMono > MAX_MONO) || (NumMono < 4))) {
+ int max = (NumMono > MAX_MONO) ? MAX_MONO : 0;
+
+ while(NumMono > max) {
+ ListMono = Delist(ListMono);
+ NumMono--;
+ }
+ }
+ if(NumColor && ((NumColor > MAX_COLOR) || (NumColor < 4))) {
+ int max = (NumColor > MAX_COLOR) ? MAX_COLOR : 0;
+
+ while(NumColor > max) {
+ ListColor = Delist(ListColor);
+ NumColor--;
+ }
+ }
+ }
+
+
+ pCachePriv = calloc(1,sizeof(XAAPixmapCachePrivate));
+ if(!pCachePriv) {
+ if(Num512) FreeList(List512);
+ if(Num256) FreeList(List256);
+ if(Num128) FreeList(List128);
+ if(NumPartial) FreeList(ListPartial);
+ if(NumColor) FreeList(ListColor);
+ if(NumMono) FreeList(ListMono);
+ return;
+ }
+
+ infoRec->PixmapCachePrivate = (char*)pCachePriv;
+
+ if(Num512) {
+ pCachePriv->Info512 = calloc(Num512,sizeof(XAACacheInfoRec));
+ if(!pCachePriv->Info512) Num512 = 0;
+ if(Num512) TransferList(List512, pCachePriv->Info512, Num512);
+ FreeList(List512);
+ pCachePriv->Num512x512 = Num512;
+ }
+ if(Num256) {
+ pCachePriv->Info256 = calloc(Num256, sizeof(XAACacheInfoRec));
+ if(!pCachePriv->Info256) Num256 = 0;
+ if(Num256) TransferList(List256, pCachePriv->Info256, Num256);
+ FreeList(List256);
+ pCachePriv->Num256x256 = Num256;
+ }
+ if(Num128) {
+ pCachePriv->Info128 = calloc(Num128, sizeof(XAACacheInfoRec));
+ if(!pCachePriv->Info128) Num128 = 0;
+ if(Num128) TransferList(List128, pCachePriv->Info128, Num128);
+ FreeList(List128);
+ pCachePriv->Num128x128 = Num128;
+ }
+
+ if(NumPartial) {
+ pCachePriv->InfoPartial = calloc(NumPartial, sizeof(XAACacheInfoRec));
+ if(!pCachePriv->InfoPartial) NumPartial = 0;
+ if(NumPartial)
+ TransferList(ListPartial, pCachePriv->InfoPartial, NumPartial);
+ FreeList(ListPartial);
+ pCachePriv->NumPartial = NumPartial;
+ }
+
+ if(NumColor) {
+ pCachePriv->InfoColor = calloc(NumColor, sizeof(XAACacheInfoRec));
+ if(!pCachePriv->InfoColor) NumColor = 0;
+ if(NumColor) TransferList(ListColor, pCachePriv->InfoColor, NumColor);
+ FreeList(ListColor);
+ pCachePriv->NumColor = NumColor;
+ }
+
+ if(NumMono) {
+ pCachePriv->InfoMono = calloc(NumMono, sizeof(XAACacheInfoRec));
+ if(!pCachePriv->InfoMono) NumMono = 0;
+ if(NumMono) TransferList(ListMono, pCachePriv->InfoMono, NumMono);
+ FreeList(ListMono);
+ pCachePriv->NumMono = NumMono;
+ }
+
+
+ if(NumPartial) {
+ infoRec->MaxCacheableTileWidth = MaxPartialWidth;
+ infoRec->MaxCacheableTileHeight = MaxPartialHeight;
+ }
+ if(Num128)
+ infoRec->MaxCacheableTileWidth = infoRec->MaxCacheableTileHeight = 128;
+ if(Num256)
+ infoRec->MaxCacheableTileWidth = infoRec->MaxCacheableTileHeight = 256;
+ if(Num512)
+ infoRec->MaxCacheableTileWidth = infoRec->MaxCacheableTileHeight = 512;
+
+
+ infoRec->MaxCacheableStippleHeight = infoRec->MaxCacheableTileHeight;
+ infoRec->MaxCacheableStippleWidth =
+ infoRec->MaxCacheableTileWidth * pScrn->bitsPerPixel;
+ if(infoRec->ScreenToScreenColorExpandFillFlags & TRIPLE_BITS_24BPP)
+ infoRec->MaxCacheableStippleWidth /= 3;
+
+ if(NumMono) {
+ if(!(infoRec->Mono8x8PatternFillFlags &
+ (HARDWARE_PATTERN_PROGRAMMED_ORIGIN |
+ HARDWARE_PATTERN_PROGRAMMED_BITS))) {
+ int numPerLine =
+ infoRec->CacheWidthMono8x8Pattern/infoRec->MonoPatternPitch;
+
+ for(i = 0; i < 64; i++) {
+ pCachePriv->MonoOffsets[i].y = i/numPerLine;
+ pCachePriv->MonoOffsets[i].x = (i % numPerLine) *
+ infoRec->MonoPatternPitch;
+ }
+ }
+ infoRec->CanDoMono8x8 = TRUE;
+ }
+ if(NumColor) {
+ if(!(infoRec->Color8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)) {
+
+ for(i = 0; i < 64; i++) {
+ pCachePriv->ColorOffsets[i].y = i & 0x07;
+ pCachePriv->ColorOffsets[i].x = i & ~0x07;
+ }
+ }
+ infoRec->CanDoColor8x8 = TRUE;
+ }
+
+ if(!CACHEINIT(pScrn)) {
+ xf86ErrorF("\tSetting up tile and stipple cache:\n");
+ if(NumPartial)
+ xf86ErrorF("\t\t%i %ix%i slots\n",
+ NumPartial, MaxPartialWidth, MaxPartialHeight);
+ if(Num128) xf86ErrorF("\t\t%i 128x128 slots\n", Num128);
+ if(Num256) xf86ErrorF("\t\t%i 256x256 slots\n", Num256);
+ if(Num512) xf86ErrorF("\t\t%i 512x512 slots\n", Num512);
+ if(NumColor) xf86ErrorF("\t\t%i 8x8 color pattern slots\n", NumColor);
+ if(NumMono) xf86ErrorF("\t\t%i 8x8 color expansion slots\n", NumMono);
+ }
+
+ if(!(NumPartial | Num128 | Num256 | Num512 | NumColor | NumMono)) {
+ if(!CACHEINIT(pScrn))
+ xf86ErrorF("\t\tNot enough video memory for pixmap cache\n");
+ } else infoRec->UsingPixmapCache = TRUE;
+
+ CACHEINIT(pScrn) = 1;
+}
+
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+static CARD32 StippleMasks[4] = {
+ 0x80808080,
+ 0xC0C0C0C0,
+ 0x00000000,
+ 0xF0F0F0F0
+};
+#else
+static CARD32 StippleMasks[4] = {
+ 0x01010101,
+ 0x03030303,
+ 0x00000000,
+ 0x0F0F0F0F
+};
+#endif
+
+Bool
+XAACheckStippleReducibility(PixmapPtr pPixmap)
+{
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_DRAWABLE(&pPixmap->drawable);
+ CARD32 *IntPtr = (CARD32*)pPixmap->devPrivate.ptr;
+ int w = pPixmap->drawable.width;
+ int h = pPixmap->drawable.height;
+ int i;
+ CARD32 bits[8];
+ CARD32 mask = SHIFT_R(0xFFFFFFFF,24);
+
+ pPriv->flags |= REDUCIBILITY_CHECKED | REDUCIBLE_TO_2_COLOR;
+ pPriv->flags &= ~REDUCIBLE_TO_8x8;
+
+ if((w > 32) || (h > 32) || (w & (w - 1)) || (h & (h - 1)))
+ return FALSE;
+
+ i = (h > 8) ? 8 : h;
+
+ switch(w) {
+ case 32:
+ while(i--) {
+ bits[i] = IntPtr[i] & mask;
+ if( (bits[i] != SHIFT_R((IntPtr[i] & SHIFT_L(mask, 8)), 8)) ||
+ (bits[i] != SHIFT_R((IntPtr[i] & SHIFT_L(mask,16)),16)) ||
+ (bits[i] != SHIFT_R((IntPtr[i] & SHIFT_L(mask,24)),24)))
+ return FALSE;
+ }
+ break;
+ case 16:
+ while(i--) {
+ bits[i] = IntPtr[i] & mask;
+ if(bits[i] != ((IntPtr[i] & SHIFT_R(SHIFT_L(mask,8),8))))
+ return FALSE;
+ }
+ break;
+ default:
+ while(i--)
+ bits[i] = IntPtr[i] & mask;
+ break;
+ }
+
+ switch(h) {
+ case 32:
+ if( (IntPtr[8] != IntPtr[16]) || (IntPtr[9] != IntPtr[17]) ||
+ (IntPtr[10] != IntPtr[18]) || (IntPtr[11] != IntPtr[19]) ||
+ (IntPtr[12] != IntPtr[20]) || (IntPtr[13] != IntPtr[21]) ||
+ (IntPtr[14] != IntPtr[22]) || (IntPtr[15] != IntPtr[23]) ||
+ (IntPtr[16] != IntPtr[24]) || (IntPtr[17] != IntPtr[25]) ||
+ (IntPtr[18] != IntPtr[26]) || (IntPtr[19] != IntPtr[27]) ||
+ (IntPtr[20] != IntPtr[28]) || (IntPtr[21] != IntPtr[29]) ||
+ (IntPtr[22] != IntPtr[30]) || (IntPtr[23] != IntPtr[31]))
+ return FALSE;
+ /* fall through */
+ case 16:
+ if( (IntPtr[0] != IntPtr[8]) || (IntPtr[1] != IntPtr[9]) ||
+ (IntPtr[2] != IntPtr[10]) || (IntPtr[3] != IntPtr[11]) ||
+ (IntPtr[4] != IntPtr[12]) || (IntPtr[5] != IntPtr[13]) ||
+ (IntPtr[6] != IntPtr[14]) || (IntPtr[7] != IntPtr[15]))
+ return FALSE;
+ case 8: break;
+ case 1: bits[1] = bits[0];
+ case 2: bits[2] = bits[0]; bits[3] = bits[1];
+ case 4: bits[4] = bits[0]; bits[5] = bits[1];
+ bits[6] = bits[2]; bits[7] = bits[3];
+ break;
+ }
+
+ pPriv->flags |= REDUCIBLE_TO_8x8;
+
+ pPriv->pattern0 = bits[0] | SHIFT_L(bits[1],8) | SHIFT_L(bits[2],16) | SHIFT_L(bits[3],24);
+ pPriv->pattern1 = bits[4] | SHIFT_L(bits[5],8) | SHIFT_L(bits[6],16) | SHIFT_L(bits[7],24);
+
+ if(w < 8) {
+ pPriv->pattern0 &= StippleMasks[w - 1];
+ pPriv->pattern1 &= StippleMasks[w - 1];
+
+ switch(w) {
+ case 1: pPriv->pattern0 |= SHIFT_L(pPriv->pattern0,1);
+ pPriv->pattern1 |= SHIFT_L(pPriv->pattern1,1);
+ case 2: pPriv->pattern0 |= SHIFT_L(pPriv->pattern0,2);
+ pPriv->pattern1 |= SHIFT_L(pPriv->pattern1,2);
+ case 4: pPriv->pattern0 |= SHIFT_L(pPriv->pattern0,4);
+ pPriv->pattern1 |= SHIFT_L(pPriv->pattern1,4);
+ }
+ }
+
+ if(infoRec->Mono8x8PatternFillFlags & BIT_ORDER_IN_BYTE_MSBFIRST) {
+ pPriv->pattern0 = SWAP_BITS_IN_BYTES(pPriv->pattern0);
+ pPriv->pattern1 = SWAP_BITS_IN_BYTES(pPriv->pattern1);
+ }
+
+
+ return TRUE;
+}
+
+
+Bool
+XAACheckTileReducibility(PixmapPtr pPixmap, Bool checkMono)
+{
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
+ CARD32 *IntPtr;
+ int w = pPixmap->drawable.width;
+ int h = pPixmap->drawable.height;
+ int pitch = pPixmap->devKind >> 2;
+ int dwords, i, j;
+
+ pPriv->flags |= REDUCIBILITY_CHECKED;
+ pPriv->flags &= ~(REDUCIBILITY_CHECKED | REDUCIBLE_TO_2_COLOR);
+
+ if((w > 32) || (h > 32) || (w & (w - 1)) || (h & (h - 1)))
+ return FALSE;
+
+ dwords = ((w * pPixmap->drawable.bitsPerPixel) + 31) >> 5;
+ i = (h > 8) ? 8 : h;
+
+
+ if(w > 8) {
+ IntPtr = (CARD32*)pPixmap->devPrivate.ptr;
+ switch(pPixmap->drawable.bitsPerPixel) {
+ case 8:
+ while(i--) {
+ for(j = 2; j < dwords; j++)
+ if(IntPtr[j] != IntPtr[j & 0x01])
+ return FALSE;
+ IntPtr += pitch;
+ }
+ break;
+ case 16:
+ while(i--) {
+ for(j = 4; j < dwords; j++)
+ if(IntPtr[j] != IntPtr[j & 0x03])
+ return FALSE;
+ IntPtr += pitch;
+ }
+ break;
+ case 24:
+ while(i--) {
+ for(j = 6; j < dwords; j++)
+ if(IntPtr[j] != IntPtr[j % 6])
+ return FALSE;
+ IntPtr += pitch;
+ }
+ break;
+ case 32:
+ while(i--) {
+ for(j = 8; j < dwords; j++)
+ if(IntPtr[j] != IntPtr[j & 0x07])
+ return FALSE;
+ IntPtr += pitch;
+ }
+ break;
+ default: return FALSE;
+ }
+
+ }
+
+
+ if(h == 32) {
+ CARD32 *IntPtr2, *IntPtr3, *IntPtr4;
+ i = 8;
+ IntPtr = (CARD32*)pPixmap->devPrivate.ptr;
+ IntPtr2 = IntPtr + (pitch << 3);
+ IntPtr3 = IntPtr2 + (pitch << 3);
+ IntPtr4 = IntPtr3 + (pitch << 3);
+ while(i--) {
+ for(j = 0; j < dwords; j++)
+ if((IntPtr[j] != IntPtr2[j]) || (IntPtr[j] != IntPtr3[j]) ||
+ (IntPtr[j] != IntPtr4[j]))
+ return FALSE;
+ IntPtr += pitch;
+ IntPtr2 += pitch;
+ IntPtr3 += pitch;
+ IntPtr4 += pitch;
+ }
+ } else if (h == 16) {
+ CARD32 *IntPtr2;
+ i = 8;
+ IntPtr = (CARD32*)pPixmap->devPrivate.ptr;
+ IntPtr2 = IntPtr + (pitch << 3);
+ while(i--) {
+ for(j = 0; j < dwords; j++)
+ if(IntPtr[j] != IntPtr2[j])
+ return FALSE;
+ IntPtr += pitch;
+ IntPtr2 += pitch;
+ }
+ }
+
+ pPriv->flags |= REDUCIBLE_TO_8x8;
+
+ if(checkMono) {
+ XAAInfoRecPtr infoRec =
+ GET_XAAINFORECPTR_FROM_DRAWABLE(&pPixmap->drawable);
+ unsigned char bits[8];
+ int fg, bg = -1, x, y;
+
+ i = (h > 8) ? 8 : h;
+ j = (w > 8) ? 8 : w;
+
+ if(pPixmap->drawable.bitsPerPixel == 8) {
+ unsigned char *srcp = pPixmap->devPrivate.ptr;
+ fg = srcp[0];
+ pitch = pPixmap->devKind;
+ for(y = 0; y < i; y++) {
+ bits[y] = 0;
+ for(x = 0; x < j; x++) {
+ if(srcp[x] != fg) {
+ if(bg == -1) bg = srcp[x];
+ else if(bg != srcp[x]) return TRUE;
+ } else bits[y] |= 1 << x;
+ }
+ srcp += pitch;
+ }
+ } else if(pPixmap->drawable.bitsPerPixel == 16) {
+ unsigned short *srcp = (unsigned short*)pPixmap->devPrivate.ptr;
+ fg = srcp[0];
+ pitch = pPixmap->devKind >> 1;
+ for(y = 0; y < i; y++) {
+ bits[y] = 0;
+ for(x = 0; x < j; x++) {
+ if(srcp[x] != fg) {
+ if(bg == -1) bg = srcp[x];
+ else if(bg != srcp[x]) return TRUE;
+ } else bits[y] |= 1 << x;
+ }
+ srcp += pitch;
+ }
+ } else if(pPixmap->drawable.bitsPerPixel == 24) {
+ CARD32 val;
+ unsigned char *srcp = pPixmap->devPrivate.ptr;
+ fg = *((CARD32*)srcp) & 0x00FFFFFF;
+ pitch = pPixmap->devKind;
+ j *= 3;
+ for(y = 0; y < i; y++) {
+ bits[y] = 0;
+ for(x = 0; x < j; x+=3) {
+ val = *((CARD32*)(srcp+x)) & 0x00FFFFFF;
+ if(val != fg) {
+ if(bg == -1) bg = val;
+ else if(bg != val)
+ return TRUE;
+ } else bits[y] |= 1 << (x/3);
+ }
+ srcp += pitch;
+ }
+ } else if(pPixmap->drawable.bitsPerPixel == 32) {
+ IntPtr = (CARD32*)pPixmap->devPrivate.ptr;
+ fg = IntPtr[0];
+ for(y = 0; y < i; y++) {
+ bits[y] = 0;
+ for(x = 0; x < j; x++) {
+ if(IntPtr[x] != fg) {
+ if(bg == -1) bg = IntPtr[x];
+ else if(bg != IntPtr[x]) return TRUE;
+ } else bits[y] |= 1 << x;
+ }
+ IntPtr += pitch;
+ }
+ } else return TRUE;
+
+ pPriv->fg = fg;
+ if(bg == -1) pPriv->bg = fg;
+ else pPriv->bg = bg;
+
+ if(h < 8) {
+ switch(h) {
+ case 1: bits[1] = bits[0];
+ case 2: bits[2] = bits[0]; bits[3] = bits[1];
+ case 4: bits[4] = bits[0]; bits[5] = bits[1];
+ bits[6] = bits[2]; bits[7] = bits[3];
+ break;
+ }
+ }
+
+ pPriv->pattern0 =
+ bits[0] | (bits[1]<<8) | (bits[2]<<16) | (bits[3]<<24);
+ pPriv->pattern1 =
+ bits[4] | (bits[5]<<8) | (bits[6]<<16) | (bits[7]<<24);
+
+ if(w < 8) {
+ switch(w) {
+ case 1: pPriv->pattern0 |= (pPriv->pattern0 << 1);
+ pPriv->pattern1 |= (pPriv->pattern1 << 1);
+ case 2: pPriv->pattern0 |= (pPriv->pattern0 << 2);
+ pPriv->pattern1 |= (pPriv->pattern1 << 2);
+ case 4: pPriv->pattern0 |= (pPriv->pattern0 << 4);
+ pPriv->pattern1 |= (pPriv->pattern1 << 4);
+ }
+ }
+ pPriv->flags |= REDUCIBLE_TO_2_COLOR;
+
+ if(infoRec->Mono8x8PatternFillFlags & BIT_ORDER_IN_BYTE_MSBFIRST) {
+ pPriv->pattern0 = SWAP_BITS_IN_BYTES(pPriv->pattern0);
+ pPriv->pattern1 = SWAP_BITS_IN_BYTES(pPriv->pattern1);
+ }
+
+ }
+
+ return TRUE;
+}
+
+
+void XAATileCache(
+ ScrnInfoPtr pScrn,
+ XAACacheInfoPtr pCache,
+ int w, int h
+) {
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ (*infoRec->SetupForScreenToScreenCopy)(pScrn, 1, 1, GXcopy, ~0, -1);
+
+ while((w << 1) <= pCache->w) {
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn, pCache->x, pCache->y,
+ pCache->x + w, pCache->y, w, h);
+ w <<= 1;
+ }
+ if(w != pCache->w) {
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn, pCache->x, pCache->y,
+ pCache->x + w, pCache->y, pCache->w - w, h);
+ w = pCache->w;
+ }
+
+ while((h << 1) <= pCache->h) {
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn, pCache->x, pCache->y,
+ pCache->x, pCache->y + h, w, h);
+ h <<= 1;
+ }
+ if(h != pCache->h) {
+ (*infoRec->SubsequentScreenToScreenCopy)(pScrn, pCache->x, pCache->y,
+ pCache->x, pCache->y + h, w, pCache->h - h);
+ }
+ SET_SYNC_FLAG(infoRec);
+}
+
+XAACacheInfoPtr
+XAACacheTile(ScrnInfoPtr pScrn, PixmapPtr pPix)
+{
+ int w = pPix->drawable.width;
+ int h = pPix->drawable.height;
+ int size = max(w, h);
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
+ XAACacheInfoPtr pCache, cacheRoot = NULL;
+ int i, max = 0;
+ int *current;
+
+ if(size <= 128) {
+ if(pCachePriv->Info128) {
+ cacheRoot = pCachePriv->Info128;
+ max = pCachePriv->Num128x128;
+ current = &pCachePriv->Current128;
+ } else {
+ cacheRoot = pCachePriv->InfoPartial;
+ max = pCachePriv->NumPartial;
+ current = &pCachePriv->CurrentPartial;
+ }
+ } else if(size <= 256) {
+ cacheRoot = pCachePriv->Info256;
+ max = pCachePriv->Num256x256;
+ current = &pCachePriv->Current256;
+ } else if(size <= 512) {
+ cacheRoot = pCachePriv->Info512;
+ max = pCachePriv->Num512x512;
+ current = &pCachePriv->Current512;
+ } else { /* something's wrong */
+ ErrorF("Something's wrong in XAACacheTile()\n");
+ return pCachePriv->Info128;
+ }
+
+ pCache = cacheRoot;
+
+ /* lets look for it */
+ for(i = 0; i < max; i++, pCache++) {
+ if(pCache->serialNumber == pPix->drawable.serialNumber) {
+ pCache->trans_color = -1;
+ return pCache;
+ }
+ }
+
+ pCache = &cacheRoot[(*current)++];
+ if(*current >= max) *current = 0;
+
+ pCache->serialNumber = pPix->drawable.serialNumber;
+ pCache->trans_color = pCache->bg = pCache->fg = -1;
+ pCache->orig_w = w; pCache->orig_h = h;
+ (*infoRec->WritePixmapToCache)(
+ pScrn, pCache->x, pCache->y, w, h, pPix->devPrivate.ptr,
+ pPix->devKind, pPix->drawable.bitsPerPixel, pPix->drawable.depth);
+ if(!(infoRec->PixmapCacheFlags & DO_NOT_TILE_COLOR_DATA) &&
+ ((w != pCache->w) || (h != pCache->h)))
+ XAATileCache(pScrn, pCache, w, h);
+
+ return pCache;
+}
+
+XAACacheInfoPtr
+XAACacheMonoStipple(ScrnInfoPtr pScrn, PixmapPtr pPix)
+{
+ int w = pPix->drawable.width;
+ int h = pPix->drawable.height;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
+ XAACacheInfoPtr pCache, cacheRoot = NULL;
+ int i, max = 0, funcNo, pad, dwords, bpp = pScrn->bitsPerPixel;
+ int *current;
+ StippleScanlineProcPtr StippleFunc;
+ unsigned char *data, *srcPtr, *dstPtr;
+
+ if((h <= 128) && (w <= 128 * bpp)) {
+ if(pCachePriv->Info128) {
+ cacheRoot = pCachePriv->Info128;
+ max = pCachePriv->Num128x128;
+ current = &pCachePriv->Current128;
+ } else {
+ cacheRoot = pCachePriv->InfoPartial;
+ max = pCachePriv->NumPartial;
+ current = &pCachePriv->CurrentPartial;
+ }
+ } else if((h <= 256) && (w <= 256 * bpp)){
+ cacheRoot = pCachePriv->Info256;
+ max = pCachePriv->Num256x256;
+ current = &pCachePriv->Current256;
+ } else if((h <= 512) && (w <= 526 * bpp)){
+ cacheRoot = pCachePriv->Info512;
+ max = pCachePriv->Num512x512;
+ current = &pCachePriv->Current512;
+ } else { /* something's wrong */
+ ErrorF("Something's wrong in XAACacheMonoStipple()\n");
+ return pCachePriv->Info128;
+ }
+
+ pCache = cacheRoot;
+
+ /* lets look for it */
+ for(i = 0; i < max; i++, pCache++) {
+ if((pCache->serialNumber == pPix->drawable.serialNumber) &&
+ (pCache->fg == -1) && (pCache->bg == -1)) {
+ pCache->trans_color = -1;
+ return pCache;
+ }
+ }
+
+ pCache = &cacheRoot[(*current)++];
+ if(*current >= max) *current = 0;
+
+ pCache->serialNumber = pPix->drawable.serialNumber;
+ pCache->trans_color = pCache->bg = pCache->fg = -1;
+ pCache->orig_w = w; pCache->orig_h = h;
+
+ if(w <= 32) {
+ if(w & (w - 1)) funcNo = 1;
+ else funcNo = 0;
+ } else funcNo = 2;
+
+ pad = BitmapBytePad(pCache->w * bpp);
+ dwords = bytes_to_int32(pad);
+ dstPtr = data = (unsigned char*)malloc(pad * pCache->h);
+ srcPtr = (unsigned char*)pPix->devPrivate.ptr;
+
+ if(infoRec->ScreenToScreenColorExpandFillFlags & BIT_ORDER_IN_BYTE_MSBFIRST)
+ StippleFunc = XAAStippleScanlineFuncMSBFirst[funcNo];
+ else
+ StippleFunc = XAAStippleScanlineFuncLSBFirst[funcNo];
+
+ /* don't bother generating more than we'll ever use */
+ max = ((pScrn->displayWidth + w - 1) + 31) >> 5;
+ if(dwords > max)
+ dwords = max;
+
+ for(i = 0; i < h; i++) {
+ (*StippleFunc)((CARD32*)dstPtr, (CARD32*)srcPtr, 0, w, dwords);
+ srcPtr += pPix->devKind;
+ dstPtr += pad;
+ }
+
+ while((h<<1) <= pCache->h) {
+ memcpy(data + (pad * h), data, pad * h);
+ h <<= 1;
+ }
+
+ if(h < pCache->h)
+ memcpy(data + (pad * h), data, pad * (pCache->h - h));
+
+ (*infoRec->WritePixmapToCache)(
+ pScrn, pCache->x, pCache->y, pCache->w, pCache->h, data,
+ pad, bpp, pScrn->depth);
+
+ free(data);
+
+ return pCache;
+}
+
+XAACacheInfoPtr
+XAACachePlanarMonoStipple(ScrnInfoPtr pScrn, PixmapPtr pPix)
+{
+ int w = pPix->drawable.width;
+ int h = pPix->drawable.height;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
+ XAACacheInfoPtr pCache, cacheRoot = NULL;
+ int i, max = 0;
+ int *current;
+
+ if((h <= 128) && (w <= 128)) {
+ if(pCachePriv->Info128) {
+ cacheRoot = pCachePriv->Info128;
+ max = pCachePriv->Num128x128;
+ current = &pCachePriv->Current128;
+ } else {
+ cacheRoot = pCachePriv->InfoPartial;
+ max = pCachePriv->NumPartial;
+ current = &pCachePriv->CurrentPartial;
+ }
+ } else if((h <= 256) && (w <= 256)){
+ cacheRoot = pCachePriv->Info256;
+ max = pCachePriv->Num256x256;
+ current = &pCachePriv->Current256;
+ } else if((h <= 512) && (w <= 526)){
+ cacheRoot = pCachePriv->Info512;
+ max = pCachePriv->Num512x512;
+ current = &pCachePriv->Current512;
+ } else { /* something's wrong */
+ ErrorF("Something's wrong in XAACachePlanarMonoStipple()\n");
+ return pCachePriv->Info128;
+ }
+
+ pCache = cacheRoot;
+
+ /* lets look for it */
+ for(i = 0; i < max; i++, pCache++) {
+ if((pCache->serialNumber == pPix->drawable.serialNumber) &&
+ (pCache->fg == -1) && (pCache->bg == -1)) {
+ pCache->trans_color = -1;
+ return pCache;
+ }
+ }
+
+ pCache = &cacheRoot[(*current)++];
+ if(*current >= max) *current = 0;
+
+ pCache->serialNumber = pPix->drawable.serialNumber;
+ pCache->trans_color = pCache->bg = pCache->fg = -1;
+ pCache->orig_w = w; pCache->orig_h = h;
+
+ /* Plane 0 holds the stipple. Plane 1 holds the inverted stipple */
+ (*infoRec->WriteBitmapToCache)(pScrn, pCache->x, pCache->y,
+ pPix->drawable.width, pPix->drawable.height, pPix->devPrivate.ptr,
+ pPix->devKind, 1, 2);
+ if(!(infoRec->PixmapCacheFlags & DO_NOT_TILE_MONO_DATA) &&
+ ((w != pCache->w) || (h != pCache->h)))
+ XAATileCache(pScrn, pCache, w, h);
+
+ return pCache;
+}
+
+XAACachePlanarMonoStippleProc
+XAAGetCachePlanarMonoStipple(void)
+{
+ return XAACachePlanarMonoStipple;
+}
+
+XAACacheInfoPtr
+XAACacheStipple(ScrnInfoPtr pScrn, PixmapPtr pPix, int fg, int bg)
+{
+ int w = pPix->drawable.width;
+ int h = pPix->drawable.height;
+ int size = max(w, h);
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
+ XAACacheInfoPtr pCache, cacheRoot = NULL;
+ int i, max = 0;
+ int *current;
+
+ if(size <= 128) {
+ if(pCachePriv->Info128) {
+ cacheRoot = pCachePriv->Info128;
+ max = pCachePriv->Num128x128;
+ current = &pCachePriv->Current128;
+ } else {
+ cacheRoot = pCachePriv->InfoPartial;
+ max = pCachePriv->NumPartial;
+ current = &pCachePriv->CurrentPartial;
+ }
+ } else if(size <= 256) {
+ cacheRoot = pCachePriv->Info256;
+ max = pCachePriv->Num256x256;
+ current = &pCachePriv->Current256;
+ } else if(size <= 512) {
+ cacheRoot = pCachePriv->Info512;
+ max = pCachePriv->Num512x512;
+ current = &pCachePriv->Current512;
+ } else { /* something's wrong */
+ ErrorF("Something's wrong in XAACacheStipple()\n");
+ return pCachePriv->Info128;
+ }
+
+ pCache = cacheRoot;
+ /* lets look for it */
+ if(bg == -1)
+ for(i = 0; i < max; i++, pCache++) {
+ if((pCache->serialNumber == pPix->drawable.serialNumber) &&
+ (fg == pCache->fg) && (pCache->fg != pCache->bg)) {
+ pCache->trans_color = pCache->bg;
+ return pCache;
+ }
+ }
+ else
+ for(i = 0; i < max; i++, pCache++) {
+ if((pCache->serialNumber == pPix->drawable.serialNumber) &&
+ (fg == pCache->fg) && (bg == pCache->bg)) {
+ pCache->trans_color = -1;
+ return pCache;
+ }
+ }
+
+ pCache = &cacheRoot[(*current)++];
+ if(*current >= max) *current = 0;
+
+ pCache->serialNumber = pPix->drawable.serialNumber;
+ pCache->fg = fg;
+ if(bg == -1)
+ pCache->trans_color = bg = fg ^ 1;
+ else
+ pCache->trans_color = -1;
+ pCache->bg = bg;
+
+ pCache->orig_w = w; pCache->orig_h = h;
+ (*infoRec->WriteBitmapToCache)(pScrn, pCache->x, pCache->y,
+ pPix->drawable.width, pPix->drawable.height, pPix->devPrivate.ptr,
+ pPix->devKind, fg, bg);
+ if(!(infoRec->PixmapCacheFlags & DO_NOT_TILE_COLOR_DATA) &&
+ ((w != pCache->w) || (h != pCache->h)))
+ XAATileCache(pScrn, pCache, w, h);
+
+ return pCache;
+}
+
+
+
+XAACacheInfoPtr
+XAACacheMono8x8Pattern(ScrnInfoPtr pScrn, int pat0, int pat1)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
+ XAACacheInfoPtr pCache = pCachePriv->InfoMono;
+ int i;
+
+ for(i = 0; i < pCachePriv->NumMono; i++, pCache++) {
+ if(pCache->serialNumber &&
+ (pCache->pat0 == pat0) && (pCache->pat1 == pat1))
+ return pCache;
+ }
+
+ /* OK, let's cache it */
+ pCache = &pCachePriv->InfoMono[pCachePriv->CurrentMono++];
+ if(pCachePriv->CurrentMono >= pCachePriv->NumMono)
+ pCachePriv->CurrentMono = 0;
+
+ pCache->serialNumber = 1; /* we don't care since we do lookups by pattern */
+ pCache->pat0 = pat0;
+ pCache->pat1 = pat1;
+
+ (*infoRec->WriteMono8x8PatternToCache)(pScrn, pCache);
+
+ return pCache;
+}
+
+
+
+XAACacheInfoPtr
+XAACacheColor8x8Pattern(ScrnInfoPtr pScrn, PixmapPtr pPix, int fg, int bg)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
+ XAACacheInfoPtr pCache = pCachePriv->InfoColor;
+ XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+ int i;
+
+ if(!(pixPriv->flags & REDUCIBLE_TO_2_COLOR)) {
+ for(i = 0; i < pCachePriv->NumColor; i++, pCache++) {
+ if(pCache->serialNumber == pPix->drawable.serialNumber) {
+ pCache->trans_color = -1;
+ return pCache;
+ }
+ }
+ pCache = &pCachePriv->InfoColor[pCachePriv->CurrentColor++];
+ if(pCachePriv->CurrentColor >= pCachePriv->NumColor)
+ pCachePriv->CurrentColor = 0;
+
+ pCache->serialNumber = pPix->drawable.serialNumber;
+ pCache->trans_color = pCache->fg = pCache->bg = -1;
+ } else {
+ int pat0 = pixPriv->pattern0;
+ int pat1 = pixPriv->pattern1;
+
+ if(fg == -1) { /* it's a tile */
+ fg = pixPriv->fg; bg = pixPriv->bg;
+ }
+
+ if(bg == -1) { /* stipple */
+ for(i = 0; i < pCachePriv->NumColor; i++, pCache++) {
+ if(pCache->serialNumber &&
+ (pCache->pat0 == pat0) && (pCache->pat1 == pat1) &&
+ (pCache->fg == fg) && (pCache->bg != fg)) {
+ pCache->trans_color = pCache->bg;
+ return pCache;
+ }
+ }
+ } else { /* opaque stipple */
+ for(i = 0; i < pCachePriv->NumColor; i++, pCache++) {
+ if(pCache->serialNumber &&
+ (pCache->pat0 == pat0) && (pCache->pat1 == pat1) &&
+ (pCache->fg == fg) && (pCache->bg == bg)) {
+ pCache->trans_color = -1;
+ return pCache;
+ }
+ }
+ }
+ pCache = &pCachePriv->InfoColor[pCachePriv->CurrentColor++];
+ if(pCachePriv->CurrentColor >= pCachePriv->NumColor)
+ pCachePriv->CurrentColor = 0;
+
+ if(bg == -1)
+ pCache->trans_color = bg = fg ^ 1;
+ else
+ pCache->trans_color = -1;
+
+ pCache->pat0 = pat0; pCache->pat1 = pat1;
+ pCache->fg = fg; pCache->bg = bg;
+ pCache->serialNumber = 1;
+ }
+
+ (*infoRec->WriteColor8x8PatternToCache)(pScrn, pPix, pCache);
+
+ return pCache;
+}
+
+
+void
+XAAWriteBitmapToCache(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int fg, int bg
+) {
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ (*infoRec->WriteBitmap)(pScrn, x, y, w, h, src, srcwidth,
+ 0, fg, bg, GXcopy, ~0);
+}
+
+void
+XAAWriteBitmapToCacheLinear(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int fg, int bg
+){
+ ScreenPtr pScreen = pScrn->pScreen;
+ PixmapPtr pScreenPix, pDstPix;
+ ChangeGCVal gcvals[2];
+ GCPtr pGC;
+
+ pScreenPix = (*pScreen->GetScreenPixmap)(pScreen);
+
+ pDstPix = GetScratchPixmapHeader(pScreen, pScreenPix->drawable.width,
+ y + h, pScreenPix->drawable.depth,
+ pScreenPix->drawable.bitsPerPixel,
+ pScreenPix->devKind,
+ pScreenPix->devPrivate.ptr);
+
+ pGC = GetScratchGC(pScreenPix->drawable.depth, pScreen);
+ gcvals[0].val = fg;
+ gcvals[1].val = bg;
+ ChangeGC(NullClient, pGC, GCForeground | GCBackground, gcvals);
+ ValidateGC((DrawablePtr)pDstPix, pGC);
+
+ /* We've unwrapped already so these ops miss a sync */
+ SYNC_CHECK(pScrn);
+
+ (*pGC->ops->PutImage)((DrawablePtr)pDstPix, pGC, 1, x, y, w, h, 0,
+ XYBitmap, (pointer)src);
+
+ FreeScratchGC(pGC);
+ FreeScratchPixmapHeader(pDstPix);
+}
+
+
+void
+XAAWritePixmapToCache(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int bpp, int depth
+) {
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+
+ (*infoRec->WritePixmap)(pScrn, x, y, w, h, src, srcwidth,
+ GXcopy, ~0, -1, bpp, depth);
+}
+
+
+
+void
+XAAWritePixmapToCacheLinear(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int bpp, int depth
+){
+ ScreenPtr pScreen = pScrn->pScreen;
+ PixmapPtr pScreenPix, pDstPix;
+ GCPtr pGC;
+
+ pScreenPix = (*pScreen->GetScreenPixmap)(pScreen);
+
+ pDstPix = GetScratchPixmapHeader(pScreen, x + w, y + h,
+ depth, bpp, pScreenPix->devKind,
+ pScreenPix->devPrivate.ptr);
+
+ pGC = GetScratchGC(depth, pScreen);
+ ValidateGC((DrawablePtr)pDstPix, pGC);
+
+ /* We've unwrapped already so these ops miss a sync */
+ SYNC_CHECK(pScrn);
+
+ if(bpp == BitsPerPixel(depth))
+ (*pGC->ops->PutImage)((DrawablePtr)pDstPix, pGC, depth, x, y, w,
+ h, 0, ZPixmap, (pointer)src);
+ else {
+ PixmapPtr pSrcPix;
+
+ pSrcPix = GetScratchPixmapHeader(pScreen, w, h, depth, bpp,
+ srcwidth, (pointer)src);
+
+ (*pGC->ops->CopyArea)((DrawablePtr)pSrcPix, (DrawablePtr)pDstPix,
+ pGC, 0, 0, w, h, x, y);
+
+ FreeScratchPixmapHeader(pSrcPix);
+ }
+
+ FreeScratchGC(pGC);
+ FreeScratchPixmapHeader(pDstPix);
+}
+
+
+void
+XAAWriteMono8x8PatternToCache(
+ ScrnInfoPtr pScrn,
+ XAACacheInfoPtr pCache
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
+ unsigned char *data;
+ int pad, Bpp = (pScrn->bitsPerPixel >> 3);
+
+ pCache->offsets = pCachePriv->MonoOffsets;
+
+ pad = BitmapBytePad(pCache->w * pScrn->bitsPerPixel);
+
+ data = (unsigned char*)malloc(pad * pCache->h);
+ if(!data) return;
+
+ if(infoRec->Mono8x8PatternFillFlags & HARDWARE_PATTERN_PROGRAMMED_ORIGIN) {
+ CARD32* ptr = (CARD32*)data;
+ ptr[0] = pCache->pat0; ptr[1] = pCache->pat1;
+ } else {
+ CARD32 *ptr;
+ DDXPointPtr pPoint = pCache->offsets;
+ int patx, paty, i;
+
+ for(i = 0; i < 64; i++, pPoint++) {
+ patx = pCache->pat0; paty = pCache->pat1;
+ XAARotateMonoPattern(&patx, &paty, i & 0x07, i >> 3,
+ (infoRec->Mono8x8PatternFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST));
+ ptr = (CARD32*)(data + (pad * pPoint->y) + (Bpp * pPoint->x));
+ ptr[0] = patx; ptr[1] = paty;
+ }
+ }
+
+ (*infoRec->WritePixmapToCache)(pScrn, pCache->x, pCache->y,
+ pCache->w, pCache->h, data, pad, pScrn->bitsPerPixel, pScrn->depth);
+
+ free(data);
+}
+
+void
+XAAWriteColor8x8PatternToCache(
+ ScrnInfoPtr pScrn,
+ PixmapPtr pPix,
+ XAACacheInfoPtr pCache
+){
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(pPix);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
+ int pad, i, w, h, nw, nh, Bpp;
+ unsigned char *data, *srcPtr, *dstPtr;
+
+ pCache->offsets = pCachePriv->ColorOffsets;
+
+ if(pixPriv->flags & REDUCIBLE_TO_2_COLOR) {
+ CARD32* ptr;
+ pad = BitmapBytePad(pCache->w);
+ data = (unsigned char*)malloc(pad * pCache->h);
+ if(!data) return;
+
+ if(infoRec->Color8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN) {
+ ptr = (CARD32*)data;
+ ptr[0] = pCache->pat0; ptr[1] = pCache->pat1;
+ } else {
+ int patx, paty;
+
+ ptr = (CARD32*)data;
+ ptr[0] = ptr[2] = pCache->pat0; ptr[1] = ptr[3] = pCache->pat1;
+ for(i = 1; i < 8; i++) {
+ patx = pCache->pat0; paty = pCache->pat1;
+ XAARotateMonoPattern(&patx, &paty, i, 0,
+ (infoRec->Mono8x8PatternFillFlags &
+ BIT_ORDER_IN_BYTE_MSBFIRST));
+ ptr = (CARD32*)(data + (pad * i));
+ ptr[0] = ptr[2] = patx; ptr[1] = ptr[3] = paty;
+ }
+ }
+
+ (*infoRec->WriteBitmapToCache)(pScrn, pCache->x, pCache->y,
+ pCache->w, pCache->h, data, pad, pCache->fg, pCache->bg);
+
+ free(data);
+ return;
+ }
+
+ Bpp = pScrn->bitsPerPixel >> 3;
+ h = min(8,pPix->drawable.height);
+ w = min(8,pPix->drawable.width);
+ pad = BitmapBytePad(pCache->w * pScrn->bitsPerPixel);
+
+ data = (unsigned char*)malloc(pad * pCache->h);
+ if(!data) return;
+
+ /* Write and expand horizontally. */
+ for (i = h, dstPtr = data, srcPtr = pPix->devPrivate.ptr; i--;
+ srcPtr += pPix->devKind, dstPtr += pScrn->bitsPerPixel) {
+ nw = w;
+ memcpy(dstPtr, srcPtr, w * Bpp);
+ while (nw != 8) {
+ memcpy(dstPtr + (nw * Bpp), dstPtr, nw * Bpp);
+ nw <<= 1;
+ }
+ }
+ nh = h;
+ /* Expand vertically. */
+ while (nh != 8) {
+ memcpy(data + (nh*pScrn->bitsPerPixel), data, nh*pScrn->bitsPerPixel);
+ nh <<= 1;
+ }
+
+ if(!(infoRec->Color8x8PatternFillFlags &
+ HARDWARE_PATTERN_PROGRAMMED_ORIGIN)){
+ int j;
+ unsigned char *ptr = data + (128 * Bpp);
+
+ memcpy(data + (64 * Bpp), data, 64 * Bpp);
+ for(i = 1; i < 8; i++, ptr += (128 * Bpp)) {
+ for(j = 0; j < 8; j++) {
+ memcpy(ptr + (j * 8) * Bpp, data + (j * 8 + i) * Bpp,
+ (8 - i) * Bpp);
+ memcpy(ptr + (j * 8 + 8 - i) * Bpp, data + j * 8 * Bpp, i*Bpp);
+ }
+ memcpy(ptr + (64 * Bpp), ptr, 64 * Bpp);
+ }
+ }
+
+ (*infoRec->WritePixmapToCache)(pScrn, pCache->x, pCache->y,
+ pCache->w, pCache->h, data, pad, pScrn->bitsPerPixel, pScrn->depth);
+
+ free(data);
+}
+
+
+
+int
+XAAStippledFillChooser(GCPtr pGC)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ PixmapPtr pPixmap = pGC->stipple;
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
+
+ if(!(pPriv->flags & REDUCIBILITY_CHECKED) &&
+ (infoRec->CanDoMono8x8 || infoRec->CanDoColor8x8)) {
+ XAACheckStippleReducibility(pPixmap);
+ }
+
+
+ if(pPriv->flags & REDUCIBLE_TO_8x8) {
+ if(infoRec->CanDoMono8x8 &&
+ !(infoRec->FillMono8x8PatternSpansFlags & NO_TRANSPARENCY) &&
+ ((pGC->alu == GXcopy) || !(infoRec->FillMono8x8PatternSpansFlags &
+ TRANSPARENCY_GXCOPY_ONLY)) &&
+ CHECK_ROP(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
+ CHECK_FG(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillMono8x8PatternSpansFlags)) {
+
+ return DO_MONO_8x8;
+ }
+
+ if(infoRec->CanDoColor8x8 &&
+ !(infoRec->FillColor8x8PatternSpansFlags & NO_TRANSPARENCY) &&
+ ((pGC->alu == GXcopy) || !(infoRec->FillColor8x8PatternSpansFlags &
+ TRANSPARENCY_GXCOPY_ONLY)) &&
+ CHECK_ROP(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillColor8x8PatternSpansFlags)) {
+
+ return DO_COLOR_8x8;
+ }
+ }
+
+ if(infoRec->UsingPixmapCache && infoRec->FillCacheExpandSpans &&
+ (pPixmap->drawable.height <= infoRec->MaxCacheableStippleHeight) &&
+ (pPixmap->drawable.width <= infoRec->MaxCacheableStippleWidth /
+ infoRec->CacheColorExpandDensity) &&
+ !(infoRec->FillCacheExpandSpansFlags & NO_TRANSPARENCY) &&
+ ((pGC->alu == GXcopy) || !(infoRec->FillCacheExpandSpansFlags &
+ TRANSPARENCY_GXCOPY_ONLY)) &&
+ CHECK_ROP(pGC,infoRec->FillCacheExpandSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillCacheExpandSpansFlags) &&
+ CHECK_FG(pGC,infoRec->FillCacheExpandSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillCacheExpandSpansFlags)) {
+
+ return DO_CACHE_EXPAND;
+ }
+
+
+ if(infoRec->UsingPixmapCache &&
+ !(infoRec->PixmapCacheFlags & DO_NOT_BLIT_STIPPLES) &&
+ infoRec->FillCacheBltSpans &&
+ (pPixmap->drawable.height <= infoRec->MaxCacheableTileHeight) &&
+ (pPixmap->drawable.width <= infoRec->MaxCacheableTileWidth) &&
+ !(infoRec->FillCacheBltSpansFlags & NO_TRANSPARENCY) &&
+ ((pGC->alu == GXcopy) || !(infoRec->FillCacheBltSpansFlags &
+ TRANSPARENCY_GXCOPY_ONLY)) &&
+ CHECK_ROP(pGC,infoRec->FillCacheBltSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillCacheBltSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillCacheBltSpansFlags)) {
+
+ return DO_CACHE_BLT;
+ }
+
+ if(infoRec->FillColorExpandSpans &&
+ !(infoRec->FillColorExpandSpansFlags & NO_TRANSPARENCY) &&
+ ((pGC->alu == GXcopy) || !(infoRec->FillColorExpandSpansFlags &
+ TRANSPARENCY_GXCOPY_ONLY)) &&
+ CHECK_ROP(pGC,infoRec->FillColorExpandSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillColorExpandSpansFlags) &&
+ CHECK_FG(pGC,infoRec->FillColorExpandSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillColorExpandSpansFlags)) {
+
+ return DO_COLOR_EXPAND;
+ }
+
+ return 0;
+}
+
+
+int
+XAAOpaqueStippledFillChooser(GCPtr pGC)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ PixmapPtr pPixmap = pGC->stipple;
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
+
+ if(XAA_DEPTH_BUG(pGC))
+ return 0;
+
+ if(!(pPriv->flags & REDUCIBILITY_CHECKED) &&
+ (infoRec->CanDoMono8x8 || infoRec->CanDoColor8x8)) {
+ XAACheckStippleReducibility(pPixmap);
+ }
+
+ if(pPriv->flags & REDUCIBLE_TO_8x8) {
+ if(infoRec->CanDoMono8x8 &&
+ !(infoRec->FillMono8x8PatternSpansFlags & TRANSPARENCY_ONLY) &&
+ CHECK_ROP(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
+ CHECK_COLORS(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillMono8x8PatternSpansFlags)) {
+
+ return DO_MONO_8x8;
+ }
+
+ if(infoRec->CanDoColor8x8 &&
+ CHECK_ROP(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillColor8x8PatternSpansFlags)) {
+
+ return DO_COLOR_8x8;
+ }
+ }
+
+ if(infoRec->UsingPixmapCache && infoRec->FillCacheExpandSpans &&
+ (pPixmap->drawable.height <= infoRec->MaxCacheableStippleHeight) &&
+ (pPixmap->drawable.width <= infoRec->MaxCacheableStippleWidth /
+ infoRec->CacheColorExpandDensity) &&
+ !(infoRec->FillCacheExpandSpansFlags & TRANSPARENCY_ONLY) &&
+ CHECK_ROP(pGC,infoRec->FillCacheExpandSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillCacheExpandSpansFlags) &&
+ CHECK_COLORS(pGC,infoRec->FillCacheExpandSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillCacheExpandSpansFlags)) {
+
+ return DO_CACHE_EXPAND;
+ }
+
+ if(infoRec->UsingPixmapCache &&
+ !(infoRec->PixmapCacheFlags & DO_NOT_BLIT_STIPPLES) &&
+ infoRec->FillCacheBltSpans &&
+ (pPixmap->drawable.height <= infoRec->MaxCacheableTileHeight) &&
+ (pPixmap->drawable.width <= infoRec->MaxCacheableTileWidth) &&
+ CHECK_ROP(pGC,infoRec->FillCacheBltSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillCacheBltSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillCacheBltSpansFlags)) {
+
+ return DO_CACHE_BLT;
+ }
+
+ if(infoRec->FillColorExpandSpans &&
+ !(infoRec->FillColorExpandSpansFlags & TRANSPARENCY_ONLY) &&
+ CHECK_ROP(pGC,infoRec->FillColorExpandSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillColorExpandSpansFlags) &&
+ CHECK_COLORS(pGC,infoRec->FillColorExpandSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillColorExpandSpansFlags)) {
+
+ return DO_COLOR_EXPAND;
+ }
+
+ return 0;
+}
+
+
+
+int
+XAATiledFillChooser(GCPtr pGC)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ PixmapPtr pPixmap = pGC->tile.pixmap;
+ XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPixmap);
+
+ if(IS_OFFSCREEN_PIXMAP(pPixmap) && infoRec->FillCacheBltSpans &&
+ CHECK_ROP(pGC,infoRec->FillCacheBltSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillCacheBltSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillCacheBltSpansFlags)) {
+
+ return DO_PIXMAP_COPY;
+ }
+
+ if(!(pPriv->flags & REDUCIBILITY_CHECKED) &&
+ (infoRec->CanDoMono8x8 || infoRec->CanDoColor8x8)) {
+ XAACheckTileReducibility(pPixmap,infoRec->CanDoMono8x8);
+ }
+
+ if(pPriv->flags & REDUCIBLE_TO_8x8) {
+ if((pPriv->flags & REDUCIBLE_TO_2_COLOR) && infoRec->CanDoMono8x8 &&
+ !(infoRec->FillMono8x8PatternSpansFlags & TRANSPARENCY_ONLY) &&
+ CHECK_ROP(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillMono8x8PatternSpansFlags) &&
+ (!(infoRec->FillMono8x8PatternSpansFlags & RGB_EQUAL) ||
+ (CHECK_RGB_EQUAL(pPriv->fg) && CHECK_RGB_EQUAL(pPriv->bg))) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillMono8x8PatternSpansFlags)) {
+
+ return DO_MONO_8x8;
+ }
+
+ if(infoRec->CanDoColor8x8 &&
+ CHECK_ROP(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillColor8x8PatternSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillColor8x8PatternSpansFlags)) {
+
+ return DO_COLOR_8x8;
+ }
+ }
+
+ if(infoRec->UsingPixmapCache && infoRec->FillCacheBltSpans &&
+ (pPixmap->drawable.height <= infoRec->MaxCacheableTileHeight) &&
+ (pPixmap->drawable.width <= infoRec->MaxCacheableTileWidth) &&
+ CHECK_ROP(pGC,infoRec->FillCacheBltSpansFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillCacheBltSpansFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillCacheBltSpansFlags)) {
+
+ return DO_CACHE_BLT;
+ }
+
+ if(infoRec->FillImageWriteRects &&
+ CHECK_NO_GXCOPY(pGC,infoRec->FillImageWriteRectsFlags) &&
+ CHECK_ROP(pGC,infoRec->FillImageWriteRectsFlags) &&
+ CHECK_ROPSRC(pGC,infoRec->FillImageWriteRectsFlags) &&
+ CHECK_PLANEMASK(pGC,infoRec->FillImageWriteRectsFlags)) {
+
+ return DO_IMAGE_WRITE;
+ }
+
+ return 0;
+}
+
+
+static int RotateMasksX[8] = {
+ 0xFFFFFFFF, 0x7F7F7F7F, 0x3F3F3F3F, 0x1F1F1F1F,
+ 0x0F0F0F0F, 0x07070707, 0x03030303, 0x01010101
+};
+
+static int RotateMasksY[4] = {
+ 0xFFFFFFFF, 0x00FFFFFF, 0x0000FFFF, 0x000000FF
+};
+
+void
+XAARotateMonoPattern(
+ int *pat0, int *pat1,
+ int xorg, int yorg,
+ Bool msbfirst
+){
+ int tmp, mask;
+
+ if(xorg) {
+ if(msbfirst) xorg = 8 - xorg;
+ mask = RotateMasksX[xorg];
+ *pat0 = ((*pat0 >> xorg) & mask) | ((*pat0 << (8 - xorg)) & ~mask);
+ *pat1 = ((*pat1 >> xorg) & mask) | ((*pat1 << (8 - xorg)) & ~mask);
+ }
+ if(yorg >= 4) {
+ tmp = *pat0; *pat0 = *pat1; *pat1 = tmp;
+ yorg -= 4;
+ }
+ if(yorg) {
+ mask = RotateMasksY[yorg];
+ yorg <<= 3;
+ tmp = *pat0;
+ *pat0 = ((*pat0 >> yorg) & mask) | ((*pat1 << (32 - yorg)) & ~mask);
+ *pat1 = ((*pat1 >> yorg) & mask) | ((tmp << (32 - yorg)) & ~mask);
+ }
+}
+
+
+
+void
+XAAInvalidatePixmapCache(ScreenPtr pScreen)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ XAAPixmapCachePrivatePtr pCachePriv =
+ (XAAPixmapCachePrivatePtr)infoRec->PixmapCachePrivate;
+ int i;
+
+ if(!pCachePriv) return;
+
+ for(i = 0; i < pCachePriv->Num512x512; i++)
+ (pCachePriv->Info512)[i].serialNumber = 0;
+ for(i = 0; i < pCachePriv->Num256x256; i++)
+ (pCachePriv->Info256)[i].serialNumber = 0;
+ for(i = 0; i < pCachePriv->Num128x128; i++)
+ (pCachePriv->Info128)[i].serialNumber = 0;
+ for(i = 0; i < pCachePriv->NumPartial; i++)
+ (pCachePriv->InfoPartial)[i].serialNumber = 0;
+ for(i = 0; i < pCachePriv->NumMono; i++)
+ (pCachePriv->InfoMono)[i].serialNumber = 0;
+ for(i = 0; i < pCachePriv->NumColor; i++)
+ (pCachePriv->InfoColor)[i].serialNumber = 0;
+}
diff --git a/xorg-server/hw/xfree86/xaa/xaaPict.c b/xorg-server/hw/xfree86/xaa/xaaPict.c
index e059d3d65..b66291458 100644
--- a/xorg-server/hw/xfree86/xaa/xaaPict.c
+++ b/xorg-server/hw/xfree86/xaa/xaaPict.c
@@ -1,655 +1,655 @@
-/*
- *
- * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of Keith Packard not be used in
- * advertising or publicity pertaining to distribution of the software without
- * specific, written prior permission. Keith Packard makes no
- * representations about the suitability of this software for any purpose. It
- * is provided "as is" without express or implied warranty.
- *
- * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
- * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
- * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
- * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <string.h>
-
-#include "misc.h"
-#include "xf86.h"
-#include "xf86_OSproc.h"
-
-#include <X11/X.h>
-#include "scrnintstr.h"
-#include "pixmapstr.h"
-#include "windowstr.h"
-#include "xf86str.h"
-#include "mi.h"
-#include "picturestr.h"
-#include "glyphstr.h"
-#include "picture.h"
-#include "mipict.h"
-#include "xaa.h"
-#include "xaalocal.h"
-#include "xaawrap.h"
-#include "xaacexp.h"
-#include "xf86fbman.h"
-#include "servermd.h"
-
-Bool
-XAAGetPixelFromRGBA (
- CARD32 *pixel,
- CARD16 red,
- CARD16 green,
- CARD16 blue,
- CARD16 alpha,
- CARD32 format
-){
- int rbits, bbits, gbits, abits;
- int rshift, bshift, gshift, ashift;
-
- *pixel = 0;
-
- if(!PICT_FORMAT_COLOR(format))
- return FALSE;
-
- rbits = PICT_FORMAT_R(format);
- gbits = PICT_FORMAT_G(format);
- bbits = PICT_FORMAT_B(format);
- abits = PICT_FORMAT_A(format);
-
- if(PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
- bshift = 0;
- gshift = bbits;
- rshift = gshift + gbits;
- ashift = rshift + rbits;
- } else if(PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) {
- rshift = 0;
- gshift = rbits;
- bshift = gshift + gbits;
- ashift = bshift + bbits;
- } else if(PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) {
- bshift = PICT_FORMAT_BPP(format) - bbits;
- gshift = bshift - gbits;
- rshift = gshift - rbits;
- ashift = 0;
- } else
- return FALSE;
-
- *pixel |= ( blue >> (16 - bbits)) << bshift;
- *pixel |= ( red >> (16 - rbits)) << rshift;
- *pixel |= (green >> (16 - gbits)) << gshift;
- *pixel |= (alpha >> (16 - abits)) << ashift;
-
- return TRUE;
-}
-
-
-Bool
-XAAGetRGBAFromPixel(
- CARD32 pixel,
- CARD16 *red,
- CARD16 *green,
- CARD16 *blue,
- CARD16 *alpha,
- CARD32 format
-){
- int rbits, bbits, gbits, abits;
- int rshift, bshift, gshift, ashift;
-
- if(!PICT_FORMAT_COLOR(format))
- return FALSE;
-
- rbits = PICT_FORMAT_R(format);
- gbits = PICT_FORMAT_G(format);
- bbits = PICT_FORMAT_B(format);
- abits = PICT_FORMAT_A(format);
-
- if(PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
- bshift = 0;
- gshift = bbits;
- rshift = gshift + gbits;
- ashift = rshift + rbits;
- } else if(PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) {
- rshift = 0;
- gshift = rbits;
- bshift = gshift + gbits;
- ashift = bshift + bbits;
- } else if(PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) {
- bshift = PICT_FORMAT_BPP(format) - bbits;
- gshift = bshift - gbits;
- rshift = gshift - rbits;
- ashift = 0;
- } else
- return FALSE;
-
- *red = ((pixel >> rshift ) & ((1 << rbits) - 1)) << (16 - rbits);
- while(rbits < 16) {
- *red |= *red >> rbits;
- rbits <<= 1;
- }
-
- *green = ((pixel >> gshift ) & ((1 << gbits) - 1)) << (16 - gbits);
- while(gbits < 16) {
- *green |= *green >> gbits;
- gbits <<= 1;
- }
-
- *blue = ((pixel >> bshift ) & ((1 << bbits) - 1)) << (16 - bbits);
- while(bbits < 16) {
- *blue |= *blue >> bbits;
- bbits <<= 1;
- }
-
- if(abits) {
- *alpha = ((pixel >> ashift ) & ((1 << abits) - 1)) << (16 - abits);
- while(abits < 16) {
- *alpha |= *alpha >> abits;
- abits <<= 1;
- }
- } else *alpha = 0xffff;
-
- return TRUE;
-}
-
-/* 8:8:8 + PICT_a8 -> 8:8:8:8 texture */
-
-void
-XAA_888_plus_PICT_a8_to_8888 (
- CARD32 color,
- CARD8 *alphaPtr, /* in bytes */
- int alphaPitch,
- CARD32 *dstPtr,
- int dstPitch, /* in dwords */
- int width,
- int height
-){
- int x;
-
- color &= 0x00ffffff;
-
- while(height--) {
- for(x = 0; x < width; x++)
- dstPtr[x] = color | (alphaPtr[x] << 24);
- dstPtr += dstPitch;
- alphaPtr += alphaPitch;
- }
-}
-
-#define DRAWABLE_IS_ON_CARD(pDraw) \
- (pDraw->type == DRAWABLE_WINDOW || \
- (pDraw->type == DRAWABLE_PIXMAP && IS_OFFSCREEN_PIXMAP(pDraw)))
-
-Bool
-XAADoComposite (
- CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst,
- INT16 yDst,
- CARD16 width,
- CARD16 height
-){
- ScreenPtr pScreen = pDst->pDrawable->pScreen;
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
- RegionRec region;
- CARD32 *formats, *dstformats;
- int flags = 0;
- BoxPtr pbox;
- int nbox, w, h;
-
- if(!REGION_NUM_RECTS(pDst->pCompositeClip))
- return TRUE;
-
- if(!infoRec->pScrn->vtSema || !DRAWABLE_IS_ON_CARD(pDst->pDrawable))
- return FALSE;
-
- if(DRAWABLE_IS_ON_CARD(pSrc->pDrawable))
- return FALSE;
-
- if (pSrc->transform || (pMask && pMask->transform))
- return FALSE;
-
- if (pDst->alphaMap || pSrc->alphaMap || (pMask && pMask->alphaMap))
- return FALSE;
-
- if ((pSrc->repeat && pSrc->repeatType != RepeatNormal) ||
- (pMask && pMask->repeat && pMask->repeatType != RepeatNormal))
- {
- return FALSE;
- }
-
- xDst += pDst->pDrawable->x;
- yDst += pDst->pDrawable->y;
- xSrc += pSrc->pDrawable->x;
- ySrc += pSrc->pDrawable->y;
-
- if(pMask) {
- if(pMask->componentAlpha)
- return FALSE;
-
- /* for now we only do it if there is a 1x1 (solid) source */
-
- if((pSrc->pDrawable->width == 1) && (pSrc->pDrawable->height == 1)) {
- CARD16 red, green, blue, alpha;
- CARD32 pixel =
- *((CARD32*)(((PixmapPtr)(pSrc->pDrawable))->devPrivate.ptr));
-
- if(!XAAGetRGBAFromPixel(pixel,&red,&green,&blue,&alpha,pSrc->format))
- return FALSE;
-
- xMask += pMask->pDrawable->x;
- yMask += pMask->pDrawable->y;
-
- /* pull out color expandable operations here */
- if((pMask->format == PICT_a1) && (alpha == 0xffff) &&
- (op == PictOpOver) && infoRec->WriteBitmap && !pMask->repeat &&
- !(infoRec->WriteBitmapFlags & NO_TRANSPARENCY) &&
- (!(infoRec->WriteBitmapFlags & RGB_EQUAL) ||
- ((red == green) && (green == blue))))
- {
- PixmapPtr pPix = (PixmapPtr)(pMask->pDrawable);
- int skipleft;
-
- if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
- xSrc, ySrc, xMask, yMask, xDst, yDst,
- width, height))
- return TRUE;
-
- nbox = REGION_NUM_RECTS(&region);
- pbox = REGION_RECTS(&region);
-
- if(!nbox)
- return TRUE;
-
- XAAGetPixelFromRGBA(&pixel, red, green, blue, 0, pDst->format);
-
- xMask -= xDst;
- yMask -= yDst;
-
- while(nbox--) {
- skipleft = pbox->x1 + xMask;
-
- (*infoRec->WriteBitmap)(infoRec->pScrn,
- pbox->x1, pbox->y1,
- pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
- (unsigned char*)(pPix->devPrivate.ptr) +
- (pPix->devKind * (pbox->y1 + yMask)) +
- ((skipleft >> 3) & ~3), pPix->devKind,
- skipleft & 31, pixel, -1, GXcopy, ~0);
- pbox++;
- }
-
- /* WriteBitmap sets the Sync flag */
- REGION_UNINIT(pScreen, &region);
- return TRUE;
- }
-
- formats = infoRec->CPUToScreenAlphaTextureFormats;
- dstformats = infoRec->CPUToScreenAlphaTextureDstFormats;
- if(!formats || !dstformats)
- return FALSE;
-
- w = pMask->pDrawable->width;
- h = pMask->pDrawable->height;
-
- if(pMask->repeat) {
- if((infoRec->CPUToScreenAlphaTextureFlags & XAA_RENDER_NO_TILE) ||
- ((infoRec->CPUToScreenAlphaTextureFlags &
- XAA_RENDER_POWER_OF_2_TILE_ONLY) &&
- ((h & (h - 1)) || (w & (w - 1)))))
- {
- return FALSE;
- }
- flags |= XAA_RENDER_REPEAT;
- }
-
- if((alpha != 0xffff) &&
- (infoRec->CPUToScreenAlphaTextureFlags & XAA_RENDER_NO_SRC_ALPHA))
- return FALSE;
-
- while(*formats != pMask->format) {
- if(!(*formats)) return FALSE;
- formats++;
- }
- while(*dstformats != pDst->format) {
- if(!(*dstformats))
- return FALSE;
- dstformats++;
- }
-
- if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
- xSrc, ySrc, xMask, yMask, xDst, yDst,
- width, height))
- return TRUE;
-
- nbox = REGION_NUM_RECTS(&region);
- pbox = REGION_RECTS(&region);
-
- if(!nbox) {
- REGION_UNINIT(pScreen, &region);
- return TRUE;
- }
-
- if(!(infoRec->SetupForCPUToScreenAlphaTexture2)(infoRec->pScrn,
- op, red, green, blue, alpha, pMask->format,
- pDst->format,
- ((PixmapPtr)(pMask->pDrawable))->devPrivate.ptr,
- ((PixmapPtr)(pMask->pDrawable))->devKind,
- w, h, flags))
- {
- REGION_UNINIT(pScreen, &region);
- return FALSE;
- }
-
- xMask -= xDst;
- yMask -= yDst;
-
- while(nbox--) {
- (*infoRec->SubsequentCPUToScreenAlphaTexture)(infoRec->pScrn,
- pbox->x1, pbox->y1,
- pbox->x1 + xMask, pbox->y1 + yMask,
- pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
- pbox++;
- }
-
- SET_SYNC_FLAG(infoRec);
- REGION_UNINIT(pScreen, &region);
- return TRUE;
- }
- } else {
- formats = infoRec->CPUToScreenTextureFormats;
- dstformats = infoRec->CPUToScreenTextureDstFormats;
- if(!formats || !dstformats)
- return FALSE;
-
- w = pSrc->pDrawable->width;
- h = pSrc->pDrawable->height;
-
- if(pSrc->repeat) {
- if((infoRec->CPUToScreenTextureFlags & XAA_RENDER_NO_TILE) ||
- ((infoRec->CPUToScreenTextureFlags &
- XAA_RENDER_POWER_OF_2_TILE_ONLY) &&
- ((h & (h - 1)) || (w & (w - 1)))))
- {
- return FALSE;
- }
- flags |= XAA_RENDER_REPEAT;
- }
-
- while(*formats != pSrc->format) {
- if(!(*formats)) return FALSE;
- formats++;
- }
- while(*dstformats != pDst->format) {
- if(!(*dstformats))
- return FALSE;
- dstformats++;
- }
-
- if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
- xSrc, ySrc, xMask, yMask, xDst, yDst,
- width, height))
- return TRUE;
-
- nbox = REGION_NUM_RECTS(&region);
- pbox = REGION_RECTS(&region);
-
- if(!nbox) {
- REGION_UNINIT(pScreen, &region);
- return TRUE;
- }
-
- if(!(infoRec->SetupForCPUToScreenTexture2)(infoRec->pScrn,
- op, pSrc->format, pDst->format,
- ((PixmapPtr)(pSrc->pDrawable))->devPrivate.ptr,
- ((PixmapPtr)(pSrc->pDrawable))->devKind,
- w, h, flags))
- {
- REGION_UNINIT(pScreen, &region);
- return FALSE;
- }
-
-
- xSrc -= xDst;
- ySrc -= yDst;
-
- while(nbox--) {
- (*infoRec->SubsequentCPUToScreenTexture)(infoRec->pScrn,
- pbox->x1, pbox->y1,
- pbox->x1 + xSrc, pbox->y1 + ySrc,
- pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
- pbox++;
- }
-
- SET_SYNC_FLAG(infoRec);
- REGION_UNINIT(pScreen, &region);
- return TRUE;
- }
-
-
- return FALSE;
-}
-
-static void
-XAACompositeSrcCopy (PicturePtr pSrc,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xDst,
- INT16 yDst,
- CARD16 width,
- CARD16 height)
-{
- ScreenPtr pScreen = pDst->pDrawable->pScreen;
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
- int i, nbox;
- int xoff, yoff;
- BoxPtr pbox;
- DDXPointPtr pptSrc;
- RegionRec region;
-
- xDst += pDst->pDrawable->x;
- yDst += pDst->pDrawable->y;
- xSrc += pSrc->pDrawable->x;
- ySrc += pSrc->pDrawable->y;
-
- if (!miComputeCompositeRegion (&region, pSrc, NULL, pDst,
- xSrc, ySrc, 0, 0, xDst, yDst,
- width, height))
- return;
-
- nbox = REGION_NUM_RECTS(&region);
- pbox = REGION_RECTS(&region);
-
- if(!nbox) {
- REGION_UNINIT(pScreen, &region);
- return;
- }
- pptSrc = xalloc(sizeof(DDXPointRec) * nbox);
- if (!pptSrc) {
- REGION_UNINIT(pScreen, &region);
- return;
- }
- xoff = xSrc - xDst;
- yoff = ySrc - yDst;
- for (i = 0; i < nbox; i++) {
- pptSrc[i].x = pbox[i].x1 + xoff;
- pptSrc[i].y = pbox[i].y1 + yoff;
- }
-
- infoRec->ScratchGC.planemask = ~0L;
- infoRec->ScratchGC.alu = GXcopy;
-
- XAADoBitBlt(pSrc->pDrawable, pDst->pDrawable, &infoRec->ScratchGC, &region,
- pptSrc);
-
- xfree(pptSrc);
- REGION_UNINIT(pScreen, &region);
- return;
-}
-
-void
-XAAComposite (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst,
- INT16 yDst,
- CARD16 width,
- CARD16 height)
-{
- ScreenPtr pScreen = pDst->pDrawable->pScreen;
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
- XAA_RENDER_PROLOGUE(pScreen, Composite);
-
- if(!pMask && infoRec->pScrn->vtSema &&
- infoRec->ScreenToScreenBitBlt &&
- pSrc->pDrawable &&
- DRAWABLE_IS_ON_CARD(pSrc->pDrawable) &&
- DRAWABLE_IS_ON_CARD(pDst->pDrawable) &&
- !pSrc->transform &&
- (!pSrc->repeat || (xSrc >= 0 && ySrc >= 0 &&
- xSrc+width<=pSrc->pDrawable->width &&
- ySrc+height<=pSrc->pDrawable->height)) &&
- ((op == PictOpSrc &&
- ((pSrc->format==pDst->format) ||
- (pSrc->format==PICT_a8r8g8b8 && pDst->format==PICT_x8r8g8b8) ||
- (pSrc->format==PICT_a8b8g8r8 && pDst->format==PICT_x8b8g8r8))) ||
- (op == PictOpOver && !pSrc->alphaMap && !pDst->alphaMap &&
- pSrc->format==pDst->format &&
- (pSrc->format==PICT_x8r8g8b8 || pSrc->format==PICT_x8b8g8r8))))
- {
- XAACompositeSrcCopy(pSrc, pDst, xSrc, ySrc, xDst, yDst, width, height);
- } else if(!pSrc->pDrawable || (pMask && !pMask->pDrawable) ||
- !infoRec->Composite ||
- !(*infoRec->Composite)(op, pSrc, pMask, pDst,
- xSrc, ySrc, xMask, yMask, xDst, yDst,
- width, height))
- {
- if(infoRec->pScrn->vtSema &&
- ((pSrc->pDrawable &&
- (pSrc->pDrawable->type == DRAWABLE_WINDOW || IS_OFFSCREEN_PIXMAP(pSrc->pDrawable))) ||
- pDst->pDrawable->type == DRAWABLE_WINDOW || IS_OFFSCREEN_PIXMAP(pDst->pDrawable))) {
- SYNC_CHECK(pDst->pDrawable);
- }
- (*GetPictureScreen(pScreen)->Composite) (op,
- pSrc,
- pMask,
- pDst,
- xSrc,
- ySrc,
- xMask,
- yMask,
- xDst,
- yDst,
- width,
- height);
- }
-
- if(pDst->pDrawable->type == DRAWABLE_PIXMAP)
- (XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pDst->pDrawable)))->flags |= DIRTY;
-
- XAA_RENDER_EPILOGUE(pScreen, Composite, XAAComposite);
-}
-
-Bool
-XAADoGlyphs (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc,
- int nlist,
- GlyphListPtr list,
- GlyphPtr *glyphs)
-{
- ScreenPtr pScreen = pDst->pDrawable->pScreen;
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
-
- if(!REGION_NUM_RECTS(pDst->pCompositeClip))
- return TRUE;
-
- if(!infoRec->pScrn->vtSema ||
- ((pDst->pDrawable->type != DRAWABLE_WINDOW) &&
- !IS_OFFSCREEN_PIXMAP(pDst->pDrawable)))
- return FALSE;
-
- if((pSrc->pDrawable->type != DRAWABLE_PIXMAP) ||
- IS_OFFSCREEN_PIXMAP(pSrc->pDrawable))
- return FALSE;
-
- /*
- * If it looks like we have a chance of being able to draw these
- * glyphs with an accelerated Composite, do that now to avoid
- * unneeded and costly syncs.
- */
- if(maskFormat) {
- if(!infoRec->CPUToScreenAlphaTextureFormats)
- return FALSE;
- } else {
- if(!infoRec->CPUToScreenTextureFormats)
- return FALSE;
- }
-
- miGlyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
-
- return TRUE;
-}
-
-
-void
-XAAGlyphs (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc,
- int nlist,
- GlyphListPtr list,
- GlyphPtr *glyphs)
-{
- ScreenPtr pScreen = pDst->pDrawable->pScreen;
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
- XAA_RENDER_PROLOGUE(pScreen, Glyphs);
-
- if(!pSrc->pDrawable || !infoRec->Glyphs ||
- !(*infoRec->Glyphs)(op, pSrc, pDst, maskFormat,
- xSrc, ySrc, nlist, list, glyphs))
- {
- if(infoRec->pScrn->vtSema &&
- ((pSrc->pDrawable &&
- (pSrc->pDrawable->type == DRAWABLE_WINDOW || IS_OFFSCREEN_PIXMAP(pSrc->pDrawable))) ||
- pDst->pDrawable->type == DRAWABLE_WINDOW || IS_OFFSCREEN_PIXMAP(pDst->pDrawable))) {
- SYNC_CHECK(pDst->pDrawable);
- }
- (*GetPictureScreen(pScreen)->Glyphs) (op, pSrc, pDst, maskFormat,
- xSrc, ySrc, nlist, list, glyphs);
- }
-
- if(pDst->pDrawable->type == DRAWABLE_PIXMAP)
- (XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pDst->pDrawable)))->flags |= DIRTY;
-
- XAA_RENDER_EPILOGUE(pScreen, Glyphs, XAAGlyphs);
-}
+/*
+ *
+ * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <string.h>
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include <X11/X.h>
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "xf86str.h"
+#include "mi.h"
+#include "picturestr.h"
+#include "glyphstr.h"
+#include "picture.h"
+#include "mipict.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xaawrap.h"
+#include "xaacexp.h"
+#include "xf86fbman.h"
+#include "servermd.h"
+
+Bool
+XAAGetPixelFromRGBA (
+ CARD32 *pixel,
+ CARD16 red,
+ CARD16 green,
+ CARD16 blue,
+ CARD16 alpha,
+ CARD32 format
+){
+ int rbits, bbits, gbits, abits;
+ int rshift, bshift, gshift, ashift;
+
+ *pixel = 0;
+
+ if(!PICT_FORMAT_COLOR(format))
+ return FALSE;
+
+ rbits = PICT_FORMAT_R(format);
+ gbits = PICT_FORMAT_G(format);
+ bbits = PICT_FORMAT_B(format);
+ abits = PICT_FORMAT_A(format);
+
+ if(PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
+ bshift = 0;
+ gshift = bbits;
+ rshift = gshift + gbits;
+ ashift = rshift + rbits;
+ } else if(PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) {
+ rshift = 0;
+ gshift = rbits;
+ bshift = gshift + gbits;
+ ashift = bshift + bbits;
+ } else if(PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) {
+ bshift = PICT_FORMAT_BPP(format) - bbits;
+ gshift = bshift - gbits;
+ rshift = gshift - rbits;
+ ashift = 0;
+ } else
+ return FALSE;
+
+ *pixel |= ( blue >> (16 - bbits)) << bshift;
+ *pixel |= ( red >> (16 - rbits)) << rshift;
+ *pixel |= (green >> (16 - gbits)) << gshift;
+ *pixel |= (alpha >> (16 - abits)) << ashift;
+
+ return TRUE;
+}
+
+
+Bool
+XAAGetRGBAFromPixel(
+ CARD32 pixel,
+ CARD16 *red,
+ CARD16 *green,
+ CARD16 *blue,
+ CARD16 *alpha,
+ CARD32 format
+){
+ int rbits, bbits, gbits, abits;
+ int rshift, bshift, gshift, ashift;
+
+ if(!PICT_FORMAT_COLOR(format))
+ return FALSE;
+
+ rbits = PICT_FORMAT_R(format);
+ gbits = PICT_FORMAT_G(format);
+ bbits = PICT_FORMAT_B(format);
+ abits = PICT_FORMAT_A(format);
+
+ if(PICT_FORMAT_TYPE(format) == PICT_TYPE_ARGB) {
+ bshift = 0;
+ gshift = bbits;
+ rshift = gshift + gbits;
+ ashift = rshift + rbits;
+ } else if(PICT_FORMAT_TYPE(format) == PICT_TYPE_ABGR) {
+ rshift = 0;
+ gshift = rbits;
+ bshift = gshift + gbits;
+ ashift = bshift + bbits;
+ } else if(PICT_FORMAT_TYPE(format) == PICT_TYPE_BGRA) {
+ bshift = PICT_FORMAT_BPP(format) - bbits;
+ gshift = bshift - gbits;
+ rshift = gshift - rbits;
+ ashift = 0;
+ } else
+ return FALSE;
+
+ *red = ((pixel >> rshift ) & ((1 << rbits) - 1)) << (16 - rbits);
+ while(rbits < 16) {
+ *red |= *red >> rbits;
+ rbits <<= 1;
+ }
+
+ *green = ((pixel >> gshift ) & ((1 << gbits) - 1)) << (16 - gbits);
+ while(gbits < 16) {
+ *green |= *green >> gbits;
+ gbits <<= 1;
+ }
+
+ *blue = ((pixel >> bshift ) & ((1 << bbits) - 1)) << (16 - bbits);
+ while(bbits < 16) {
+ *blue |= *blue >> bbits;
+ bbits <<= 1;
+ }
+
+ if(abits) {
+ *alpha = ((pixel >> ashift ) & ((1 << abits) - 1)) << (16 - abits);
+ while(abits < 16) {
+ *alpha |= *alpha >> abits;
+ abits <<= 1;
+ }
+ } else *alpha = 0xffff;
+
+ return TRUE;
+}
+
+/* 8:8:8 + PICT_a8 -> 8:8:8:8 texture */
+
+void
+XAA_888_plus_PICT_a8_to_8888 (
+ CARD32 color,
+ CARD8 *alphaPtr, /* in bytes */
+ int alphaPitch,
+ CARD32 *dstPtr,
+ int dstPitch, /* in dwords */
+ int width,
+ int height
+){
+ int x;
+
+ color &= 0x00ffffff;
+
+ while(height--) {
+ for(x = 0; x < width; x++)
+ dstPtr[x] = color | (alphaPtr[x] << 24);
+ dstPtr += dstPitch;
+ alphaPtr += alphaPitch;
+ }
+}
+
+#define DRAWABLE_IS_ON_CARD(pDraw) \
+ (pDraw->type == DRAWABLE_WINDOW || \
+ (pDraw->type == DRAWABLE_PIXMAP && IS_OFFSCREEN_PIXMAP(pDraw)))
+
+Bool
+XAADoComposite (
+ CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height
+){
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ RegionRec region;
+ CARD32 *formats, *dstformats;
+ int flags = 0;
+ BoxPtr pbox;
+ int nbox, w, h;
+
+ if(!REGION_NUM_RECTS(pDst->pCompositeClip))
+ return TRUE;
+
+ if(!infoRec->pScrn->vtSema || !DRAWABLE_IS_ON_CARD(pDst->pDrawable))
+ return FALSE;
+
+ if(DRAWABLE_IS_ON_CARD(pSrc->pDrawable))
+ return FALSE;
+
+ if (pSrc->transform || (pMask && pMask->transform))
+ return FALSE;
+
+ if (pDst->alphaMap || pSrc->alphaMap || (pMask && pMask->alphaMap))
+ return FALSE;
+
+ if ((pSrc->repeat && pSrc->repeatType != RepeatNormal) ||
+ (pMask && pMask->repeat && pMask->repeatType != RepeatNormal))
+ {
+ return FALSE;
+ }
+
+ xDst += pDst->pDrawable->x;
+ yDst += pDst->pDrawable->y;
+ xSrc += pSrc->pDrawable->x;
+ ySrc += pSrc->pDrawable->y;
+
+ if(pMask) {
+ if(pMask->componentAlpha)
+ return FALSE;
+
+ /* for now we only do it if there is a 1x1 (solid) source */
+
+ if((pSrc->pDrawable->width == 1) && (pSrc->pDrawable->height == 1)) {
+ CARD16 red, green, blue, alpha;
+ CARD32 pixel =
+ *((CARD32*)(((PixmapPtr)(pSrc->pDrawable))->devPrivate.ptr));
+
+ if(!XAAGetRGBAFromPixel(pixel,&red,&green,&blue,&alpha,pSrc->format))
+ return FALSE;
+
+ xMask += pMask->pDrawable->x;
+ yMask += pMask->pDrawable->y;
+
+ /* pull out color expandable operations here */
+ if((pMask->format == PICT_a1) && (alpha == 0xffff) &&
+ (op == PictOpOver) && infoRec->WriteBitmap && !pMask->repeat &&
+ !(infoRec->WriteBitmapFlags & NO_TRANSPARENCY) &&
+ (!(infoRec->WriteBitmapFlags & RGB_EQUAL) ||
+ ((red == green) && (green == blue))))
+ {
+ PixmapPtr pPix = (PixmapPtr)(pMask->pDrawable);
+ int skipleft;
+
+ if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
+ xSrc, ySrc, xMask, yMask, xDst, yDst,
+ width, height))
+ return TRUE;
+
+ nbox = REGION_NUM_RECTS(&region);
+ pbox = REGION_RECTS(&region);
+
+ if(!nbox)
+ return TRUE;
+
+ XAAGetPixelFromRGBA(&pixel, red, green, blue, 0, pDst->format);
+
+ xMask -= xDst;
+ yMask -= yDst;
+
+ while(nbox--) {
+ skipleft = pbox->x1 + xMask;
+
+ (*infoRec->WriteBitmap)(infoRec->pScrn,
+ pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
+ (unsigned char*)(pPix->devPrivate.ptr) +
+ (pPix->devKind * (pbox->y1 + yMask)) +
+ ((skipleft >> 3) & ~3), pPix->devKind,
+ skipleft & 31, pixel, -1, GXcopy, ~0);
+ pbox++;
+ }
+
+ /* WriteBitmap sets the Sync flag */
+ REGION_UNINIT(pScreen, &region);
+ return TRUE;
+ }
+
+ formats = infoRec->CPUToScreenAlphaTextureFormats;
+ dstformats = infoRec->CPUToScreenAlphaTextureDstFormats;
+ if(!formats || !dstformats)
+ return FALSE;
+
+ w = pMask->pDrawable->width;
+ h = pMask->pDrawable->height;
+
+ if(pMask->repeat) {
+ if((infoRec->CPUToScreenAlphaTextureFlags & XAA_RENDER_NO_TILE) ||
+ ((infoRec->CPUToScreenAlphaTextureFlags &
+ XAA_RENDER_POWER_OF_2_TILE_ONLY) &&
+ ((h & (h - 1)) || (w & (w - 1)))))
+ {
+ return FALSE;
+ }
+ flags |= XAA_RENDER_REPEAT;
+ }
+
+ if((alpha != 0xffff) &&
+ (infoRec->CPUToScreenAlphaTextureFlags & XAA_RENDER_NO_SRC_ALPHA))
+ return FALSE;
+
+ while(*formats != pMask->format) {
+ if(!(*formats)) return FALSE;
+ formats++;
+ }
+ while(*dstformats != pDst->format) {
+ if(!(*dstformats))
+ return FALSE;
+ dstformats++;
+ }
+
+ if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
+ xSrc, ySrc, xMask, yMask, xDst, yDst,
+ width, height))
+ return TRUE;
+
+ nbox = REGION_NUM_RECTS(&region);
+ pbox = REGION_RECTS(&region);
+
+ if(!nbox) {
+ REGION_UNINIT(pScreen, &region);
+ return TRUE;
+ }
+
+ if(!(infoRec->SetupForCPUToScreenAlphaTexture2)(infoRec->pScrn,
+ op, red, green, blue, alpha, pMask->format,
+ pDst->format,
+ ((PixmapPtr)(pMask->pDrawable))->devPrivate.ptr,
+ ((PixmapPtr)(pMask->pDrawable))->devKind,
+ w, h, flags))
+ {
+ REGION_UNINIT(pScreen, &region);
+ return FALSE;
+ }
+
+ xMask -= xDst;
+ yMask -= yDst;
+
+ while(nbox--) {
+ (*infoRec->SubsequentCPUToScreenAlphaTexture)(infoRec->pScrn,
+ pbox->x1, pbox->y1,
+ pbox->x1 + xMask, pbox->y1 + yMask,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+ pbox++;
+ }
+
+ SET_SYNC_FLAG(infoRec);
+ REGION_UNINIT(pScreen, &region);
+ return TRUE;
+ }
+ } else {
+ formats = infoRec->CPUToScreenTextureFormats;
+ dstformats = infoRec->CPUToScreenTextureDstFormats;
+ if(!formats || !dstformats)
+ return FALSE;
+
+ w = pSrc->pDrawable->width;
+ h = pSrc->pDrawable->height;
+
+ if(pSrc->repeat) {
+ if((infoRec->CPUToScreenTextureFlags & XAA_RENDER_NO_TILE) ||
+ ((infoRec->CPUToScreenTextureFlags &
+ XAA_RENDER_POWER_OF_2_TILE_ONLY) &&
+ ((h & (h - 1)) || (w & (w - 1)))))
+ {
+ return FALSE;
+ }
+ flags |= XAA_RENDER_REPEAT;
+ }
+
+ while(*formats != pSrc->format) {
+ if(!(*formats)) return FALSE;
+ formats++;
+ }
+ while(*dstformats != pDst->format) {
+ if(!(*dstformats))
+ return FALSE;
+ dstformats++;
+ }
+
+ if (!miComputeCompositeRegion (&region, pSrc, pMask, pDst,
+ xSrc, ySrc, xMask, yMask, xDst, yDst,
+ width, height))
+ return TRUE;
+
+ nbox = REGION_NUM_RECTS(&region);
+ pbox = REGION_RECTS(&region);
+
+ if(!nbox) {
+ REGION_UNINIT(pScreen, &region);
+ return TRUE;
+ }
+
+ if(!(infoRec->SetupForCPUToScreenTexture2)(infoRec->pScrn,
+ op, pSrc->format, pDst->format,
+ ((PixmapPtr)(pSrc->pDrawable))->devPrivate.ptr,
+ ((PixmapPtr)(pSrc->pDrawable))->devKind,
+ w, h, flags))
+ {
+ REGION_UNINIT(pScreen, &region);
+ return FALSE;
+ }
+
+
+ xSrc -= xDst;
+ ySrc -= yDst;
+
+ while(nbox--) {
+ (*infoRec->SubsequentCPUToScreenTexture)(infoRec->pScrn,
+ pbox->x1, pbox->y1,
+ pbox->x1 + xSrc, pbox->y1 + ySrc,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+ pbox++;
+ }
+
+ SET_SYNC_FLAG(infoRec);
+ REGION_UNINIT(pScreen, &region);
+ return TRUE;
+ }
+
+
+ return FALSE;
+}
+
+static void
+XAACompositeSrcCopy (PicturePtr pSrc,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ int i, nbox;
+ int xoff, yoff;
+ BoxPtr pbox;
+ DDXPointPtr pptSrc;
+ RegionRec region;
+
+ xDst += pDst->pDrawable->x;
+ yDst += pDst->pDrawable->y;
+ xSrc += pSrc->pDrawable->x;
+ ySrc += pSrc->pDrawable->y;
+
+ if (!miComputeCompositeRegion (&region, pSrc, NULL, pDst,
+ xSrc, ySrc, 0, 0, xDst, yDst,
+ width, height))
+ return;
+
+ nbox = REGION_NUM_RECTS(&region);
+ pbox = REGION_RECTS(&region);
+
+ if(!nbox) {
+ REGION_UNINIT(pScreen, &region);
+ return;
+ }
+ pptSrc = malloc(sizeof(DDXPointRec) * nbox);
+ if (!pptSrc) {
+ REGION_UNINIT(pScreen, &region);
+ return;
+ }
+ xoff = xSrc - xDst;
+ yoff = ySrc - yDst;
+ for (i = 0; i < nbox; i++) {
+ pptSrc[i].x = pbox[i].x1 + xoff;
+ pptSrc[i].y = pbox[i].y1 + yoff;
+ }
+
+ infoRec->ScratchGC.planemask = ~0L;
+ infoRec->ScratchGC.alu = GXcopy;
+
+ XAADoBitBlt(pSrc->pDrawable, pDst->pDrawable, &infoRec->ScratchGC, &region,
+ pptSrc);
+
+ free(pptSrc);
+ REGION_UNINIT(pScreen, &region);
+ return;
+}
+
+void
+XAAComposite (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ XAA_RENDER_PROLOGUE(pScreen, Composite);
+
+ if(!pMask && infoRec->pScrn->vtSema &&
+ infoRec->ScreenToScreenBitBlt &&
+ pSrc->pDrawable &&
+ DRAWABLE_IS_ON_CARD(pSrc->pDrawable) &&
+ DRAWABLE_IS_ON_CARD(pDst->pDrawable) &&
+ !pSrc->transform &&
+ (!pSrc->repeat || (xSrc >= 0 && ySrc >= 0 &&
+ xSrc+width<=pSrc->pDrawable->width &&
+ ySrc+height<=pSrc->pDrawable->height)) &&
+ ((op == PictOpSrc &&
+ ((pSrc->format==pDst->format) ||
+ (pSrc->format==PICT_a8r8g8b8 && pDst->format==PICT_x8r8g8b8) ||
+ (pSrc->format==PICT_a8b8g8r8 && pDst->format==PICT_x8b8g8r8))) ||
+ (op == PictOpOver && !pSrc->alphaMap && !pDst->alphaMap &&
+ pSrc->format==pDst->format &&
+ (pSrc->format==PICT_x8r8g8b8 || pSrc->format==PICT_x8b8g8r8))))
+ {
+ XAACompositeSrcCopy(pSrc, pDst, xSrc, ySrc, xDst, yDst, width, height);
+ } else if(!pSrc->pDrawable || (pMask && !pMask->pDrawable) ||
+ !infoRec->Composite ||
+ !(*infoRec->Composite)(op, pSrc, pMask, pDst,
+ xSrc, ySrc, xMask, yMask, xDst, yDst,
+ width, height))
+ {
+ if(infoRec->pScrn->vtSema &&
+ ((pSrc->pDrawable &&
+ (pSrc->pDrawable->type == DRAWABLE_WINDOW || IS_OFFSCREEN_PIXMAP(pSrc->pDrawable))) ||
+ pDst->pDrawable->type == DRAWABLE_WINDOW || IS_OFFSCREEN_PIXMAP(pDst->pDrawable))) {
+ SYNC_CHECK(pDst->pDrawable);
+ }
+ (*GetPictureScreen(pScreen)->Composite) (op,
+ pSrc,
+ pMask,
+ pDst,
+ xSrc,
+ ySrc,
+ xMask,
+ yMask,
+ xDst,
+ yDst,
+ width,
+ height);
+ }
+
+ if(pDst->pDrawable->type == DRAWABLE_PIXMAP)
+ (XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pDst->pDrawable)))->flags |= DIRTY;
+
+ XAA_RENDER_EPILOGUE(pScreen, Composite, XAAComposite);
+}
+
+Bool
+XAADoGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+
+ if(!REGION_NUM_RECTS(pDst->pCompositeClip))
+ return TRUE;
+
+ if(!infoRec->pScrn->vtSema ||
+ ((pDst->pDrawable->type != DRAWABLE_WINDOW) &&
+ !IS_OFFSCREEN_PIXMAP(pDst->pDrawable)))
+ return FALSE;
+
+ if((pSrc->pDrawable->type != DRAWABLE_PIXMAP) ||
+ IS_OFFSCREEN_PIXMAP(pSrc->pDrawable))
+ return FALSE;
+
+ /*
+ * If it looks like we have a chance of being able to draw these
+ * glyphs with an accelerated Composite, do that now to avoid
+ * unneeded and costly syncs.
+ */
+ if(maskFormat) {
+ if(!infoRec->CPUToScreenAlphaTextureFormats)
+ return FALSE;
+ } else {
+ if(!infoRec->CPUToScreenTextureFormats)
+ return FALSE;
+ }
+
+ miGlyphs(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs);
+
+ return TRUE;
+}
+
+
+void
+XAAGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen);
+ XAA_RENDER_PROLOGUE(pScreen, Glyphs);
+
+ if(!pSrc->pDrawable || !infoRec->Glyphs ||
+ !(*infoRec->Glyphs)(op, pSrc, pDst, maskFormat,
+ xSrc, ySrc, nlist, list, glyphs))
+ {
+ if(infoRec->pScrn->vtSema &&
+ ((pSrc->pDrawable &&
+ (pSrc->pDrawable->type == DRAWABLE_WINDOW || IS_OFFSCREEN_PIXMAP(pSrc->pDrawable))) ||
+ pDst->pDrawable->type == DRAWABLE_WINDOW || IS_OFFSCREEN_PIXMAP(pDst->pDrawable))) {
+ SYNC_CHECK(pDst->pDrawable);
+ }
+ (*GetPictureScreen(pScreen)->Glyphs) (op, pSrc, pDst, maskFormat,
+ xSrc, ySrc, nlist, list, glyphs);
+ }
+
+ if(pDst->pDrawable->type == DRAWABLE_PIXMAP)
+ (XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pDst->pDrawable)))->flags |= DIRTY;
+
+ XAA_RENDER_EPILOGUE(pScreen, Glyphs, XAAGlyphs);
+}
diff --git a/xorg-server/hw/xfree86/xaa/xaaStateChange.c b/xorg-server/hw/xfree86/xaa/xaaStateChange.c
index f33261453..9c98a32f2 100644
--- a/xorg-server/hw/xfree86/xaa/xaaStateChange.c
+++ b/xorg-server/hw/xfree86/xaa/xaaStateChange.c
@@ -1,1626 +1,1626 @@
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "misc.h"
-#include "xf86.h"
-#include "xf86_OSproc.h"
-
-#include <X11/X.h>
-#include "scrnintstr.h"
-#include "pixmapstr.h"
-#include "windowstr.h"
-#include "xf86str.h"
-#include "mi.h"
-#include "miline.h"
-#include "xaa.h"
-#include "xaalocal.h"
-#include "xaawrap.h"
-#include "servermd.h"
-
-#define XAA_STATE_WRAP(func) do {\
-if(infoRec->func) { \
- pStatePriv->func = infoRec->func;\
- infoRec->func = XAAStateWrap##func;\
-}} while(0)
-
-/* Wrap all XAA functions and allocate our private structure.
- */
-
-typedef struct _XAAStateWrapRec {
- ScrnInfoPtr pScrn;
- void (*RestoreAccelState)(ScrnInfoPtr pScrn);
- void (*Sync)(ScrnInfoPtr pScrn);
- void (*SetupForScreenToScreenCopy)(ScrnInfoPtr pScrn, int xdir, int ydir,
- int rop, unsigned int planemask,
- int trans_color);
- void (*SetupForSolidFill)(ScrnInfoPtr pScrn, int color, int rop,
- unsigned int planemask);
- void (*SetupForSolidLine)(ScrnInfoPtr pScrn,int color,int rop,
- unsigned int planemask);
- void (*SetupForDashedLine)(ScrnInfoPtr pScrn, int fg, int bg, int rop,
- unsigned int planemask, int length,
- unsigned char *pattern);
- void (*SetClippingRectangle) (ScrnInfoPtr pScrn, int left, int top,
- int right, int bottom);
- void (*DisableClipping)(ScrnInfoPtr pScrn);
- void (*SetupForMono8x8PatternFill)(ScrnInfoPtr pScrn, int patx, int paty,
- int fg, int bg, int rop,
- unsigned int planemask);
- void (*SetupForColor8x8PatternFill)(ScrnInfoPtr pScrn, int patx, int paty,
- int rop, unsigned int planemask,
- int transparency_color);
- void (*SetupForCPUToScreenColorExpandFill)(ScrnInfoPtr pScrn, int fg,
- int bg, int rop,
- unsigned int planemask);
- void (*SetupForScanlineCPUToScreenColorExpandFill)(ScrnInfoPtr pScrn,
- int fg, int bg, int rop,
- unsigned int planemask);
- void (*SetupForScreenToScreenColorExpandFill) (ScrnInfoPtr pScrn,
- int fg, int bg, int rop,
- unsigned int planemask);
- void (*SetupForImageWrite)(ScrnInfoPtr pScrn, int rop,
- unsigned int planemask, int transparency_color,
- int bpp, int depth);
- void (*SetupForScanlineImageWrite)(ScrnInfoPtr pScrn, int rop,
- unsigned int planemask,
- int transparency_color,
- int bpp, int depth);
- void (*SetupForImageRead) (ScrnInfoPtr pScrn, int bpp, int depth);
- void (*ScreenToScreenBitBlt)(ScrnInfoPtr pScrn, int nbox,
- DDXPointPtr pptSrc, BoxPtr pbox, int xdir,
- int ydir, int alu, unsigned int planmask);
- void (*WriteBitmap) (ScrnInfoPtr pScrn, int x, int y, int w, int h,
- unsigned char *src, int srcwidth, int skipleft,
- int fg, int bg, int rop, unsigned int planemask);
- void (*FillSolidRects)(ScrnInfoPtr pScrn, int fg, int rop,
- unsigned int planemask, int nBox, BoxPtr pBox);
- void (*FillMono8x8PatternRects)(ScrnInfoPtr pScrn, int fg, int bg, int rop,
- unsigned int planemask, int nBox,
- BoxPtr pBox, int pat0, int pat1,
- int xorg, int yorg);
- void (*FillColor8x8PatternRects)(ScrnInfoPtr pScrn, int rop,
- unsigned int planemask, int nBox,
- BoxPtr pBox, int xorg, int yorg,
- XAACacheInfoPtr pCache);
- void (*FillCacheBltRects)(ScrnInfoPtr pScrn, int rop,
- unsigned int planemask, int nBox, BoxPtr pBox,
- int xorg, int yorg, XAACacheInfoPtr pCache);
- void (*FillColorExpandRects)(ScrnInfoPtr pScrn, int fg, int bg, int rop,
- unsigned int planemask, int nBox,
- BoxPtr pBox, int xorg, int yorg,
- PixmapPtr pPix);
- void (*FillCacheExpandRects)(ScrnInfoPtr pScrn, int fg, int bg, int rop,
- unsigned int planemask, int nBox, BoxPtr pBox,
- int xorg, int yorg, PixmapPtr pPix);
- void (*FillImageWriteRects)(ScrnInfoPtr pScrn, int rop,
- unsigned int planemask, int nBox, BoxPtr pBox,
- int xorg, int yorg, PixmapPtr pPix);
- void (*FillSolidSpans)(ScrnInfoPtr pScrn, int fg, int rop,
- unsigned int planemask, int n, DDXPointPtr points,
- int *widths, int fSorted);
- void (*FillMono8x8PatternSpans)(ScrnInfoPtr pScrn, int fg, int bg, int rop,
- unsigned int planemask, int n,
- DDXPointPtr points, int *widths,
- int fSorted, int pat0, int pat1,
- int xorg, int yorg);
- void (*FillColor8x8PatternSpans)(ScrnInfoPtr pScrn, int rop,
- unsigned int planemask, int n,
- DDXPointPtr points, int *widths,
- int fSorted, XAACacheInfoPtr pCache,
- int xorg, int yorg);
- void (*FillCacheBltSpans)(ScrnInfoPtr pScrn, int rop,
- unsigned int planemask, int n, DDXPointPtr points,
- int *widths, int fSorted, XAACacheInfoPtr pCache,
- int xorg, int yorg);
- void (*FillColorExpandSpans)(ScrnInfoPtr pScrn, int fg, int bg, int rop,
- unsigned int planemask, int n,
- DDXPointPtr points, int *widths, int fSorted,
- int xorg, int yorg, PixmapPtr pPix);
- void (*FillCacheExpandSpans)(ScrnInfoPtr pScrn, int fg, int bg, int rop,
- unsigned int planemask, int n, DDXPointPtr ppt,
- int *pwidth, int fSorted, int xorg, int yorg,
- PixmapPtr pPix);
- void (*TEGlyphRenderer)(ScrnInfoPtr pScrn, int x, int y, int w, int h,
- int skipleft, int startline, unsigned int **glyphs,
- int glyphWidth, int fg, int bg, int rop,
- unsigned planemask);
- void (*NonTEGlyphRenderer)(ScrnInfoPtr pScrn, int x, int y, int n,
- NonTEGlyphPtr glyphs, BoxPtr pbox,
- int fg, int rop, unsigned int planemask);
- void (*WritePixmap) (ScrnInfoPtr pScrn, int x, int y, int w, int h,
- unsigned char *src, int srcwidth, int rop,
- unsigned int planemask, int transparency_color,
- int bpp, int depth);
- void (*ReadPixmap) (ScrnInfoPtr pScrn, int x, int y, int w, int h,
- unsigned char *dst, int dstwidth, int bpp, int depth);
- RegionPtr (*CopyArea)(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
- GC *pGC, int srcx, int srcy, int width, int height,
- int dstx, int dsty);
- RegionPtr (*CopyPlane)(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
- int srcx, int srcy, int width, int height, int dstx,
- int dsty, unsigned long bitPlane);
- void (*PushPixelsSolid) (GCPtr pGC, PixmapPtr pBitMap,
- DrawablePtr pDrawable, int dx, int dy, int xOrg,
- int yOrg);
- void (*PolyFillRectSolid)(DrawablePtr pDraw, GCPtr pGC, int nrectFill,
- xRectangle *prectInit);
- void (*PolyFillRectStippled)(DrawablePtr pDraw, GCPtr pGC, int nrectFill,
- xRectangle *prectInit);
- void (*PolyFillRectOpaqueStippled)(DrawablePtr pDraw, GCPtr pGC,
- int nrectFill, xRectangle *prectInit);
- void (*PolyFillRectTiled)(DrawablePtr pDraw, GCPtr pGC, int nrectFill,
- xRectangle *prectInit);
- void (*FillSpansSolid)(DrawablePtr pDraw, GCPtr pGC, int nInit,
- DDXPointPtr ppt, int *pwidth, int fSorted);
- void (*FillSpansStippled)(DrawablePtr pDraw, GCPtr pGC, int nInit,
- DDXPointPtr ppt, int *pwidth, int fSorted);
- void (*FillSpansOpaqueStippled)(DrawablePtr pDraw, GCPtr pGC, int nInit,
- DDXPointPtr ppt, int *pwidth, int fSorted);
- void (*FillSpansTiled)(DrawablePtr pDraw, GCPtr pGC, int nInit,
- DDXPointPtr ppt, int *pwidth, int fSorted);
- int (*PolyText8TE) (DrawablePtr pDraw, GCPtr pGC, int x, int y, int count,
- char *chars);
- int (*PolyText16TE) (DrawablePtr pDraw, GCPtr pGC, int x, int y, int count,
- unsigned short *chars);
- void (*ImageText8TE) (DrawablePtr pDraw, GCPtr pGC, int x, int y, int count,
- char *chars);
- void (*ImageText16TE) (DrawablePtr pDraw, GCPtr pGC, int x, int y,
- int count, unsigned short *chars);
- void (*ImageGlyphBltTE) (DrawablePtr pDrawable, GCPtr pGC, int xInit,
- int yInit, unsigned int nglyph, CharInfoPtr *ppci,
- pointer pglyphBase);
- void (*PolyGlyphBltTE) (DrawablePtr pDrawable, GCPtr pGC, int xInit,
- int yInit, unsigned int nglyph, CharInfoPtr *ppci,
- pointer pglyphBase);
- int (*PolyText8NonTE) (DrawablePtr pDraw, GCPtr pGC, int x, int y,
- int count, char *chars);
- int (*PolyText16NonTE) (DrawablePtr pDraw, GCPtr pGC, int x, int y,
- int count, unsigned short *chars);
- void (*ImageText8NonTE) (DrawablePtr pDraw, GCPtr pGC, int x, int y,
- int count, char *chars);
- void (*ImageText16NonTE) (DrawablePtr pDraw, GCPtr pGC, int x, int y,
- int count, unsigned short *chars);
- void (*ImageGlyphBltNonTE) (DrawablePtr pDrawable, GCPtr pGC, int xInit,
- int yInit, unsigned int nglyph,
- CharInfoPtr *ppci, pointer pglyphBase);
- void (*PolyGlyphBltNonTE) (DrawablePtr pDrawable, GCPtr pGC, int xInit,
- int yInit, unsigned int nglyph,
- CharInfoPtr *ppci, pointer pglyphBase);
- void (*PolyRectangleThinSolid)(DrawablePtr pDrawable,GCPtr pGC,
- int nRectsInit, xRectangle *pRectsInit);
- void (*PolylinesWideSolid)(DrawablePtr pDrawable, GCPtr pGC, int mode,
- int npt, DDXPointPtr pPts);
- void (*PolylinesThinSolid)(DrawablePtr pDrawable, GCPtr pGC, int mode,
- int npt, DDXPointPtr pPts);
- void (*PolySegmentThinSolid)(DrawablePtr pDrawable, GCPtr pGC, int nseg,
- xSegment *pSeg);
- void (*PolylinesThinDashed)(DrawablePtr pDrawable, GCPtr pGC, int mode,
- int npt, DDXPointPtr pPts);
- void (*PolySegmentThinDashed)(DrawablePtr pDrawable, GCPtr pGC, int nseg,
- xSegment *pSeg);
- void (*FillPolygonSolid)(DrawablePtr pDrawable, GCPtr pGC, int shape,
- int mode, int count, DDXPointPtr ptsIn);
- void (*FillPolygonStippled)(DrawablePtr pDrawable, GCPtr pGC, int shape,
- int mode, int count, DDXPointPtr ptsIn);
- void (*FillPolygonOpaqueStippled)(DrawablePtr pDrawable, GCPtr pGC,
- int shape, int mode, int count,
- DDXPointPtr ptsIn);
- void (*FillPolygonTiled)(DrawablePtr pDrawable, GCPtr pGC, int shape,
- int mode, int count, DDXPointPtr ptsIn);
- void (*PolyFillArcSolid)(DrawablePtr pDraw, GCPtr pGC, int narcs,
- xArc *parcs);
- void (*PutImage)(DrawablePtr pDraw, GCPtr pGC, int depth, int x, int y,
- int w, int h, int leftPad, int format, char *pImage);
- ValidateGCProcPtr ValidateFillSpans;
- ValidateGCProcPtr ValidateSetSpans;
- ValidateGCProcPtr ValidatePutImage;
- ValidateGCProcPtr ValidateCopyArea;
- ValidateGCProcPtr ValidateCopyPlane;
- ValidateGCProcPtr ValidatePolyPoint;
- ValidateGCProcPtr ValidatePolylines;
- ValidateGCProcPtr ValidatePolySegment;
- ValidateGCProcPtr ValidatePolyRectangle;
- ValidateGCProcPtr ValidatePolyArc;
- ValidateGCProcPtr ValidateFillPolygon;
- ValidateGCProcPtr ValidatePolyFillRect;
- ValidateGCProcPtr ValidatePolyFillArc;
- ValidateGCProcPtr ValidatePolyText8;
- ValidateGCProcPtr ValidatePolyText16;
- ValidateGCProcPtr ValidateImageText8;
- ValidateGCProcPtr ValidateImageText16;
- ValidateGCProcPtr ValidatePolyGlyphBlt;
- ValidateGCProcPtr ValidateImageGlyphBlt;
- ValidateGCProcPtr ValidatePushPixels;
- void (*ComputeDash)(GCPtr pGC);
- void (*InitPixmapCache)(ScreenPtr pScreen, RegionPtr areas, pointer data);
- void (*ClosePixmapCache)(ScreenPtr pScreen);
- int (*StippledFillChooser)(GCPtr pGC);
- int (*OpaqueStippledFillChooser)(GCPtr pGC);
- int (*TiledFillChooser)(GCPtr pGC);
- XAACacheInfoPtr (*CacheTile)(ScrnInfoPtr Scrn, PixmapPtr pPix);
- XAACacheInfoPtr (*CacheStipple)(ScrnInfoPtr Scrn, PixmapPtr pPix, int fg,
- int bg);
- XAACacheInfoPtr (*CacheMonoStipple)(ScrnInfoPtr Scrn, PixmapPtr pPix);
- XAACacheInfoPtr (*CacheMono8x8Pattern)(ScrnInfoPtr Scrn, int pat0,
- int pat1);
- XAACacheInfoPtr (*CacheColor8x8Pattern)(ScrnInfoPtr Scrn, PixmapPtr pPix,
- int fg, int bg);
- void (*WriteBitmapToCache) (ScrnInfoPtr pScrn, int x, int y, int w, int h,
- unsigned char *src, int srcwidth, int fg,
- int bg);
- void (*WritePixmapToCache) (ScrnInfoPtr pScrn, int x, int y, int w, int h,
- unsigned char *src, int srcwidth, int bpp,
- int depth);
- void (*WriteMono8x8PatternToCache)(ScrnInfoPtr pScrn,
- XAACacheInfoPtr pCache);
- void (*WriteColor8x8PatternToCache)(ScrnInfoPtr pScrn, PixmapPtr pPix,
- XAACacheInfoPtr pCache);
- GetImageProcPtr GetImage;
- GetSpansProcPtr GetSpans;
- CopyWindowProcPtr CopyWindow;
- Bool (*SetupForCPUToScreenAlphaTexture2)(ScrnInfoPtr pScrn, int op,
- CARD16 red, CARD16 green,
- CARD16 blue, CARD16 alpha,
- CARD32 maskFormat, CARD32 dstFormat,
- CARD8 *alphaPtr, int alphaPitch,
- int width, int height, int flags);
- Bool (*SetupForCPUToScreenTexture2)(ScrnInfoPtr pScrn, int op,
- CARD32 srcFormat, CARD32 dstFormat,
- CARD8 *texPtr, int texPitch,
- int width, int height, int flags);
-} XAAStateWrapRec, *XAAStateWrapPtr;
-
-static int XAAStateKeyIndex;
-static DevPrivateKey XAAStateKey = &XAAStateKeyIndex;
-
-/* Wrap functions start here */
-#define GET_STATEPRIV_GC(pGC) XAAStateWrapPtr pStatePriv =\
-(XAAStateWrapPtr)dixLookupPrivate(&(pGC)->pScreen->devPrivates, XAAStateKey)
-
-#define GET_STATEPRIV_SCREEN(pScreen) XAAStateWrapPtr pStatePriv =\
-(XAAStateWrapPtr)dixLookupPrivate(&(pScreen)->devPrivates, XAAStateKey)
-
-#define GET_STATEPRIV_PSCRN(pScrn) XAAStateWrapPtr pStatePriv =\
-(XAAStateWrapPtr)dixLookupPrivate(&(pScrn)->pScreen->devPrivates, XAAStateKey)
-
-#define STATE_CHECK_SP(pStatePriv) {\
- ScrnInfoPtr pScrn = pStatePriv->pScrn;\
- int i = 0;\
- int need_change = 0;\
- while(i < pScrn->numEntities) {\
- if(xf86IsEntityShared(pScrn->entityList[i]) &&\
- xf86GetLastScrnFlag(pScrn->entityList[i]) != pScrn->scrnIndex) {\
- need_change = 1;\
- xf86SetLastScrnFlag(pScrn->entityList[i],\
- pScrn->scrnIndex);\
- }\
- i++;\
- }\
- if(need_change == 1) (*pStatePriv->RestoreAccelState)(pScrn);\
-}
-
-#define STATE_CHECK_PSCRN(pScrn) {\
- int i = 0;\
- int need_change = 0;\
- while(i < pScrn->numEntities) {\
- if(xf86IsEntityShared(pScrn->entityList[i]) &&\
- xf86GetLastScrnFlag(pScrn->entityList[i]) != pScrn->scrnIndex) {\
- need_change = 1;\
- xf86SetLastScrnFlag(pScrn->entityList[i],\
- pScrn->scrnIndex);\
- }\
- i++;\
- }\
- if(need_change == 1) (*pStatePriv->RestoreAccelState)(pScrn);\
-}
-
-static void XAAStateWrapSync(ScrnInfoPtr pScrn)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->Sync)(pScrn);
-}
-
-static void XAAStateWrapSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir,
- int rop, unsigned int planemask,
- int trans_color)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->SetupForScreenToScreenCopy)(pScrn, xdir, ydir, rop, planemask,
- trans_color);
-}
-
-static void XAAStateWrapSetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
- unsigned int planemask)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->SetupForSolidFill)(pScrn, color, rop, planemask);
-}
-
-static void XAAStateWrapSetupForSolidLine(ScrnInfoPtr pScrn,int color,int rop,
- unsigned int planemask)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->SetupForSolidLine)(pScrn, color, rop, planemask);
-}
-
-static void XAAStateWrapSetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop,
- unsigned int planemask, int length,
- unsigned char *pattern)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->SetupForDashedLine)(pScrn, fg, bg, rop, planemask, length, pattern);
-}
-
-static void XAAStateWrapSetClippingRectangle(ScrnInfoPtr pScrn, int left, int top,
- int right, int bottom)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->SetClippingRectangle)(pScrn, left, top, right, bottom);
-}
-
-static void XAAStateWrapDisableClipping(ScrnInfoPtr pScrn)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->DisableClipping)(pScrn);
-}
-
-static void XAAStateWrapSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty,
- int fg, int bg, int rop,
- unsigned int planemask)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->SetupForMono8x8PatternFill)(pScrn, patx, paty, fg, bg, rop, planemask);
-}
-
-static void XAAStateWrapSetupForColor8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty,
- int rop, unsigned int planemask,
- int transparency_color)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->SetupForColor8x8PatternFill)(pScrn, patx, paty, rop, planemask,
- transparency_color);
-}
-
-static void XAAStateWrapSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg,
- int bg, int rop,
- unsigned int planemask)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->SetupForCPUToScreenColorExpandFill)(pScrn, fg, bg, rop, planemask);
-}
-
-static void XAAStateWrapSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
- int fg, int bg,
- int rop,
- unsigned int planemask)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->SetupForScanlineCPUToScreenColorExpandFill)(pScrn, fg, bg, rop,
- planemask);
-}
-
-static void XAAStateWrapSetupForScreenToScreenColorExpandFill(ScrnInfoPtr pScrn,
- int fg, int bg, int rop,
- unsigned int planemask)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->SetupForScreenToScreenColorExpandFill)(pScrn, fg, bg, rop, planemask);
-}
-
-static void XAAStateWrapSetupForImageWrite(ScrnInfoPtr pScrn, int rop,
- unsigned int planemask, int transparency_color,
- int bpp, int depth)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->SetupForImageWrite)(pScrn, rop, planemask, transparency_color, bpp,
- depth);
-}
-
-static void XAAStateWrapSetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop,
- unsigned int planemask,
- int transparency_color,
- int bpp, int depth)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->SetupForScanlineImageWrite)(pScrn, rop, planemask, transparency_color,
- bpp, depth);
-}
-
-static void XAAStateWrapSetupForImageRead(ScrnInfoPtr pScrn, int bpp, int depth)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->SetupForImageRead)(pScrn, bpp, depth);
-}
-
-static void XAAStateWrapScreenToScreenBitBlt(ScrnInfoPtr pScrn, int nbox,
- DDXPointPtr pptSrc, BoxPtr pbox, int xdir,
- int ydir, int alu, unsigned int planmask)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->ScreenToScreenBitBlt)(pScrn, nbox,
- pptSrc, pbox, xdir,
- ydir, alu, planmask);
-}
-
-static void XAAStateWrapWriteBitmap(ScrnInfoPtr pScrn, int x, int y, int w, int h,
- unsigned char *src, int srcwidth, int skipleft,
- int fg, int bg, int rop, unsigned int planemask)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->WriteBitmap)(pScrn, x, y, w, h,
- src, srcwidth, skipleft,
- fg, bg, rop, planemask);
-}
-
-static void XAAStateWrapFillSolidRects(ScrnInfoPtr pScrn, int fg, int rop,
- unsigned int planemask, int nBox, BoxPtr pBox)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->FillSolidRects)(pScrn, fg, rop,
- planemask, nBox, pBox);
-}
-
-static void XAAStateWrapFillMono8x8PatternRects(ScrnInfoPtr pScrn, int fg, int bg,
- int rop, unsigned int planemask, int nBox,
- BoxPtr pBox, int pat0, int pat1,
- int xorg, int yorg)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->FillMono8x8PatternRects)(pScrn, fg, bg,
- rop, planemask, nBox,
- pBox, pat0, pat1,
- xorg, yorg);
-}
-
-static void XAAStateWrapFillColor8x8PatternRects(ScrnInfoPtr pScrn, int rop,
- unsigned int planemask, int nBox,
- BoxPtr pBox, int xorg, int yorg,
- XAACacheInfoPtr pCache)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->FillColor8x8PatternRects)(pScrn, rop,
- planemask, nBox,
- pBox, xorg, yorg,
- pCache);
-}
-
-static void XAAStateWrapFillCacheBltRects(ScrnInfoPtr pScrn, int rop,
- unsigned int planemask, int nBox, BoxPtr pBox,
- int xorg, int yorg, XAACacheInfoPtr pCache)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->FillCacheBltRects)(pScrn, rop,
- planemask, nBox, pBox,
- xorg, yorg, pCache);
-}
-
-static void XAAStateWrapFillColorExpandRects(ScrnInfoPtr pScrn, int fg, int bg, int rop,
- unsigned int planemask, int nBox,
- BoxPtr pBox, int xorg, int yorg,
- PixmapPtr pPix)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->FillColorExpandRects)(pScrn, fg, bg, rop,
- planemask, nBox,
- pBox, xorg, yorg,
- pPix);
-}
-
-static void XAAStateWrapFillCacheExpandRects(ScrnInfoPtr pScrn, int fg, int bg, int rop,
- unsigned int planemask, int nBox,
- BoxPtr pBox, int xorg, int yorg,
- PixmapPtr pPix)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->FillCacheExpandRects)(pScrn, fg, bg, rop,
- planemask, nBox,
- pBox, xorg, yorg,
- pPix);
-}
-
-static void XAAStateWrapFillImageWriteRects(ScrnInfoPtr pScrn, int rop,
- unsigned int planemask, int nBox, BoxPtr pBox,
- int xorg, int yorg, PixmapPtr pPix)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->FillImageWriteRects)(pScrn, rop,
- planemask, nBox, pBox,
- xorg, yorg, pPix);
-}
-
-static void XAAStateWrapFillSolidSpans(ScrnInfoPtr pScrn, int fg, int rop,
- unsigned int planemask, int n, DDXPointPtr points,
- int *widths, int fSorted)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->FillSolidSpans)(pScrn, fg, rop,
- planemask, n, points,
- widths, fSorted);
-}
-
-static void XAAStateWrapFillMono8x8PatternSpans(ScrnInfoPtr pScrn, int fg, int bg,
- int rop, unsigned int planemask, int n,
- DDXPointPtr points, int *widths,
- int fSorted, int pat0, int pat1,
- int xorg, int yorg)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->FillMono8x8PatternSpans)(pScrn, fg, bg,
- rop, planemask, n,
- points, widths,
- fSorted, pat0, pat1,
- xorg, yorg);
-}
-
-static void XAAStateWrapFillColor8x8PatternSpans(ScrnInfoPtr pScrn, int rop,
- unsigned int planemask, int n,
- DDXPointPtr points, int *widths,
- int fSorted, XAACacheInfoPtr pCache,
- int xorg, int yorg)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->FillColor8x8PatternSpans)(pScrn, rop,
- planemask, n,
- points, widths,
- fSorted, pCache,
- xorg, yorg);
-}
-
-static void XAAStateWrapFillCacheBltSpans(ScrnInfoPtr pScrn, int rop,
- unsigned int planemask, int n,
- DDXPointPtr points, int *widths,
- int fSorted, XAACacheInfoPtr pCache,
- int xorg, int yorg)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->FillCacheBltSpans)(pScrn, rop,
- planemask, n,
- points, widths,
- fSorted, pCache,
- xorg, yorg);
-}
-
-static void XAAStateWrapFillColorExpandSpans(ScrnInfoPtr pScrn, int fg, int bg, int rop,
- unsigned int planemask, int n,
- DDXPointPtr points, int *widths, int fSorted,
- int xorg, int yorg, PixmapPtr pPix)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->FillColorExpandSpans)(pScrn, fg, bg, rop,
- planemask, n,
- points, widths, fSorted,
- xorg, yorg, pPix);
-}
-
-static void XAAStateWrapFillCacheExpandSpans(ScrnInfoPtr pScrn, int fg, int bg, int rop,
- unsigned int planemask, int n,
- DDXPointPtr ppt, int *pwidth, int fSorted,
- int xorg, int yorg, PixmapPtr pPix)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->FillCacheExpandSpans)(pScrn, fg, bg, rop,
- planemask, n,
- ppt, pwidth, fSorted,
- xorg, yorg, pPix);
-}
-
-static void XAAStateWrapTEGlyphRenderer(ScrnInfoPtr pScrn, int x, int y, int w, int h,
- int skipleft, int startline,
- unsigned int **glyphs,
- int glyphWidth, int fg, int bg, int rop,
- unsigned planemask)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->TEGlyphRenderer)(pScrn, x, y, w, h,
- skipleft, startline,
- glyphs,
- glyphWidth, fg, bg, rop,
- planemask);
-}
-
-static void XAAStateWrapNonTEGlyphRenderer(ScrnInfoPtr pScrn, int x, int y, int n,
- NonTEGlyphPtr glyphs, BoxPtr pbox,
- int fg, int rop, unsigned int planemask)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->NonTEGlyphRenderer)(pScrn, x, y, n,
- glyphs, pbox,
- fg, rop, planemask);
-}
-
-static void XAAStateWrapWritePixmap(ScrnInfoPtr pScrn, int x, int y, int w, int h,
- unsigned char *src, int srcwidth, int rop,
- unsigned int planemask, int transparency_color,
- int bpp, int depth)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->WritePixmap)(pScrn, x, y, w, h,
- src, srcwidth, rop,
- planemask, transparency_color,
- bpp, depth);
-}
-
-static void XAAStateWrapReadPixmap(ScrnInfoPtr pScrn, int x, int y, int w, int h,
- unsigned char *dst, int dstwidth, int bpp, int depth)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->ReadPixmap)(pScrn, x, y, w, h,
- dst, dstwidth, bpp, depth);
-}
-
-static RegionPtr XAAStateWrapCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
- GC *pGC, int srcx, int srcy, int width, int height,
- int dstx, int dsty)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- return (*pStatePriv->CopyArea)(pSrcDrawable, pDstDrawable,
- pGC, srcx, srcy, width, height,
- dstx, dsty);
-}
-
-static RegionPtr XAAStateWrapCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
- int srcx, int srcy, int width, int height,
- int dstx, int dsty, unsigned long bitPlane)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- return (*pStatePriv->CopyPlane)(pSrc, pDst, pGC,
- srcx, srcy, width, height,
- dstx, dsty, bitPlane);
-}
-
-static void XAAStateWrapPushPixelsSolid(GCPtr pGC, PixmapPtr pBitMap,
- DrawablePtr pDrawable, int dx, int dy, int xOrg,
- int yOrg)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->PushPixelsSolid)(pGC, pBitMap,
- pDrawable, dx, dy, xOrg,
- yOrg);
-}
-
-static void XAAStateWrapPolyFillRectSolid(DrawablePtr pDraw, GCPtr pGC, int nrectFill,
- xRectangle *prectInit)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->PolyFillRectSolid)(pDraw, pGC, nrectFill,
- prectInit);
-}
-
-static void XAAStateWrapPolyFillRectStippled(DrawablePtr pDraw, GCPtr pGC, int nrectFill,
- xRectangle *prectInit)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->PolyFillRectStippled)(pDraw, pGC, nrectFill,
- prectInit);
-}
-
-static void XAAStateWrapPolyFillRectOpaqueStippled(DrawablePtr pDraw, GCPtr pGC,
- int nrectFill, xRectangle *prectInit)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->PolyFillRectOpaqueStippled)(pDraw, pGC,
- nrectFill, prectInit);
-}
-
-static void XAAStateWrapPolyFillRectTiled(DrawablePtr pDraw, GCPtr pGC, int nrectFill,
- xRectangle *prectInit)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->PolyFillRectTiled)(pDraw, pGC, nrectFill,
- prectInit);
-}
-
-static void XAAStateWrapFillSpansSolid(DrawablePtr pDraw, GCPtr pGC, int nInit,
- DDXPointPtr ppt, int *pwidth, int fSorted)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->FillSpansSolid)(pDraw, pGC, nInit,
- ppt, pwidth, fSorted);
-}
-
-static void XAAStateWrapFillSpansStippled(DrawablePtr pDraw, GCPtr pGC, int nInit,
- DDXPointPtr ppt, int *pwidth, int fSorted)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->FillSpansStippled)(pDraw, pGC, nInit,
- ppt, pwidth, fSorted);
-}
-
-static void XAAStateWrapFillSpansOpaqueStippled(DrawablePtr pDraw, GCPtr pGC, int nInit,
- DDXPointPtr ppt, int *pwidth, int fSorted)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->FillSpansOpaqueStippled)(pDraw, pGC, nInit,
- ppt, pwidth, fSorted);
-}
-
-static void XAAStateWrapFillSpansTiled(DrawablePtr pDraw, GCPtr pGC, int nInit,
- DDXPointPtr ppt, int *pwidth, int fSorted)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->FillSpansTiled)(pDraw, pGC, nInit,
- ppt, pwidth, fSorted);
-}
-
-static int XAAStateWrapPolyText8TE(DrawablePtr pDraw, GCPtr pGC, int x, int y, int count,
- char *chars)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- return (*pStatePriv->PolyText8TE)(pDraw, pGC, x, y, count,
- chars);
-}
-
-static int XAAStateWrapPolyText16TE(DrawablePtr pDraw, GCPtr pGC, int x, int y, int count,
- unsigned short *chars)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- return (*pStatePriv->PolyText16TE)(pDraw, pGC, x, y, count,
- chars);
-}
-
-static void XAAStateWrapImageText8TE(DrawablePtr pDraw, GCPtr pGC, int x, int y,
- int count, char *chars)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->ImageText8TE)(pDraw, pGC, x, y,
- count, chars);
-}
-
-static void XAAStateWrapImageText16TE(DrawablePtr pDraw, GCPtr pGC, int x, int y,
- int count, unsigned short *chars)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->ImageText16TE)(pDraw, pGC, x, y,
- count, chars);
-}
-
-static void XAAStateWrapImageGlyphBltTE(DrawablePtr pDrawable, GCPtr pGC, int xInit,
- int yInit, unsigned int nglyph, CharInfoPtr *ppci,
- pointer pglyphBase)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->ImageGlyphBltTE)(pDrawable, pGC, xInit,
- yInit, nglyph, ppci,
- pglyphBase);
-}
-
-static void XAAStateWrapPolyGlyphBltTE(DrawablePtr pDrawable, GCPtr pGC, int xInit,
- int yInit, unsigned int nglyph, CharInfoPtr *ppci,
- pointer pglyphBase)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->PolyGlyphBltTE)(pDrawable, pGC, xInit,
- yInit, nglyph, ppci,
- pglyphBase);
-}
-
-static int XAAStateWrapPolyText8NonTE(DrawablePtr pDraw, GCPtr pGC, int x, int y,
- int count, char *chars)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- return (*pStatePriv->PolyText8NonTE)(pDraw, pGC, x, y,
- count, chars);
-}
-
-static int XAAStateWrapPolyText16NonTE(DrawablePtr pDraw, GCPtr pGC, int x, int y,
- int count, unsigned short *chars)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- return (*pStatePriv->PolyText16NonTE)(pDraw, pGC, x, y,
- count, chars);
-}
-
-static void XAAStateWrapImageText8NonTE(DrawablePtr pDraw, GCPtr pGC, int x, int y,
- int count, char *chars)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->ImageText8NonTE)(pDraw, pGC, x, y,
- count, chars);
-}
-
-static void XAAStateWrapImageText16NonTE(DrawablePtr pDraw, GCPtr pGC, int x, int y,
- int count, unsigned short *chars)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->ImageText16NonTE)(pDraw, pGC, x, y,
- count, chars);
-}
-
-static void XAAStateWrapImageGlyphBltNonTE(DrawablePtr pDrawable, GCPtr pGC, int xInit,
- int yInit, unsigned int nglyph,
- CharInfoPtr *ppci, pointer pglyphBase)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->ImageGlyphBltNonTE)(pDrawable, pGC, xInit,
- yInit, nglyph,
- ppci, pglyphBase);
-}
-
-static void XAAStateWrapPolyGlyphBltNonTE(DrawablePtr pDrawable, GCPtr pGC, int xInit,
- int yInit, unsigned int nglyph,
- CharInfoPtr *ppci, pointer pglyphBase)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->PolyGlyphBltNonTE)(pDrawable, pGC, xInit,
- yInit, nglyph,
- ppci, pglyphBase);
-}
-
-static void XAAStateWrapPolyRectangleThinSolid(DrawablePtr pDrawable,GCPtr pGC,
- int nRectsInit, xRectangle *pRectsInit)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->PolyRectangleThinSolid)(pDrawable, pGC,
- nRectsInit, pRectsInit);
-}
-
-static void XAAStateWrapPolylinesWideSolid(DrawablePtr pDrawable, GCPtr pGC, int mode,
- int npt, DDXPointPtr pPts)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->PolylinesWideSolid)(pDrawable, pGC, mode,
- npt, pPts);
-}
-
-static void XAAStateWrapPolylinesThinSolid(DrawablePtr pDrawable, GCPtr pGC, int mode,
- int npt, DDXPointPtr pPts)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->PolylinesThinSolid)(pDrawable, pGC, mode,
- npt, pPts);
-}
-
-static void XAAStateWrapPolySegmentThinSolid(DrawablePtr pDrawable, GCPtr pGC, int nseg,
- xSegment *pSeg)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->PolySegmentThinSolid)(pDrawable, pGC, nseg,
- pSeg);
-}
-
-static void XAAStateWrapPolylinesThinDashed(DrawablePtr pDrawable, GCPtr pGC, int mode,
- int npt, DDXPointPtr pPts)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->PolylinesThinDashed)(pDrawable, pGC, mode,
- npt, pPts);
-}
-
-static void XAAStateWrapPolySegmentThinDashed(DrawablePtr pDrawable, GCPtr pGC, int nseg,
- xSegment *pSeg)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->PolySegmentThinDashed)(pDrawable, pGC, nseg,
- pSeg);
-}
-
-static void XAAStateWrapFillPolygonSolid(DrawablePtr pDrawable, GCPtr pGC, int shape,
- int mode, int count, DDXPointPtr ptsIn)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->FillPolygonSolid)(pDrawable, pGC, shape,
- mode, count, ptsIn);
-}
-
-static void XAAStateWrapFillPolygonStippled(DrawablePtr pDrawable, GCPtr pGC, int shape,
- int mode, int count, DDXPointPtr ptsIn)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->FillPolygonStippled)(pDrawable, pGC, shape,
- mode, count, ptsIn);
-}
-
-static void XAAStateWrapFillPolygonOpaqueStippled(DrawablePtr pDrawable, GCPtr pGC,
- int shape, int mode, int count,
- DDXPointPtr ptsIn)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->FillPolygonOpaqueStippled)(pDrawable, pGC,
- shape, mode, count,
- ptsIn);
-}
-
-static void XAAStateWrapFillPolygonTiled(DrawablePtr pDrawable, GCPtr pGC, int shape,
- int mode, int count, DDXPointPtr ptsIn)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->FillPolygonTiled)(pDrawable, pGC, shape,
- mode, count, ptsIn);
-}
-
-static void XAAStateWrapPolyFillArcSolid(DrawablePtr pDraw, GCPtr pGC, int narcs,
- xArc *parcs)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->PolyFillArcSolid)(pDraw, pGC, narcs,
- parcs);
-}
-
-static void XAAStateWrapPutImage(DrawablePtr pDraw, GCPtr pGC, int depth, int x, int y,
- int w, int h, int leftPad, int format, char *pImage)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->PutImage)(pDraw, pGC, depth, x, y,
- w, h, leftPad, format, pImage);
-}
-
-static void XAAStateWrapValidateFillSpans(GCPtr pGC, unsigned long changes,
- DrawablePtr pDraw)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->ValidateFillSpans)(pGC, changes,
- pDraw);
-}
-
-static void XAAStateWrapValidateSetSpans(GCPtr pGC, unsigned long changes,
- DrawablePtr pDraw)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->ValidateSetSpans)(pGC, changes,
- pDraw);
-}
-
-static void XAAStateWrapValidatePutImage(GCPtr pGC, unsigned long changes,
- DrawablePtr pDraw)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->ValidatePutImage)(pGC, changes,
- pDraw);
-}
-
-static void XAAStateWrapValidateCopyArea(GCPtr pGC, unsigned long changes,
- DrawablePtr pDraw)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->ValidateCopyArea)(pGC, changes,
- pDraw);
-}
-
-static void XAAStateWrapValidateCopyPlane(GCPtr pGC, unsigned long changes,
- DrawablePtr pDraw)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->ValidateCopyPlane)(pGC, changes,
- pDraw);
-}
-
-static void XAAStateWrapValidatePolyPoint(GCPtr pGC, unsigned long changes,
- DrawablePtr pDraw)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->ValidatePolyPoint)(pGC, changes,
- pDraw);
-}
-
-static void XAAStateWrapValidatePolylines(GCPtr pGC, unsigned long changes,
- DrawablePtr pDraw)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->ValidatePolylines)(pGC, changes,
- pDraw);
-}
-
-static void XAAStateWrapValidatePolySegment(GCPtr pGC, unsigned long changes,
- DrawablePtr pDraw)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->ValidatePolySegment)(pGC, changes,
- pDraw);
-}
-
-static void XAAStateWrapValidatePolyRectangle(GCPtr pGC, unsigned long changes,
- DrawablePtr pDraw)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->ValidatePolyRectangle)(pGC, changes,
- pDraw);
-}
-
-static void XAAStateWrapValidatePolyArc(GCPtr pGC, unsigned long changes,
- DrawablePtr pDraw)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->ValidatePolyArc)(pGC, changes,
- pDraw);
-}
-
-static void XAAStateWrapValidateFillPolygon(GCPtr pGC, unsigned long changes,
- DrawablePtr pDraw)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->ValidateFillPolygon)(pGC, changes,
- pDraw);
-}
-
-static void XAAStateWrapValidatePolyFillRect(GCPtr pGC, unsigned long changes,
- DrawablePtr pDraw)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->ValidatePolyFillRect)(pGC, changes,
- pDraw);
-}
-
-static void XAAStateWrapValidatePolyFillArc(GCPtr pGC, unsigned long changes,
- DrawablePtr pDraw)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->ValidatePolyFillArc)(pGC, changes,
- pDraw);
-}
-
-static void XAAStateWrapValidatePolyText8(GCPtr pGC, unsigned long changes,
- DrawablePtr pDraw)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->ValidatePolyText8)(pGC, changes,
- pDraw);
-}
-
-static void XAAStateWrapValidatePolyText16(GCPtr pGC, unsigned long changes,
- DrawablePtr pDraw)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->ValidatePolyText16)(pGC, changes,
- pDraw);
-}
-
-static void XAAStateWrapValidateImageText8(GCPtr pGC, unsigned long changes,
- DrawablePtr pDraw)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->ValidateImageText8)(pGC, changes,
- pDraw);
-}
-
-static void XAAStateWrapValidateImageText16(GCPtr pGC, unsigned long changes,
- DrawablePtr pDraw)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->ValidateImageText16)(pGC, changes,
- pDraw);
-}
-
-static void XAAStateWrapValidatePolyGlyphBlt(GCPtr pGC, unsigned long changes,
- DrawablePtr pDraw)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->ValidatePolyGlyphBlt)(pGC, changes,
- pDraw);
-}
-
-static void XAAStateWrapValidateImageGlyphBlt(GCPtr pGC, unsigned long changes,
- DrawablePtr pDraw)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
- (*pStatePriv->ValidateImageGlyphBlt)(pGC, changes,
- pDraw);
-}
-
-static void XAAStateWrapValidatePushPixels(GCPtr pGC, unsigned long changes,
- DrawablePtr pDraw)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->ValidatePushPixels)(pGC, changes,
- pDraw);
-}
-
-static void XAAStateWrapComputeDash(GCPtr pGC)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->ComputeDash)(pGC);
-}
-
-static void XAAStateWrapInitPixmapCache(ScreenPtr pScreen, RegionPtr areas,
- pointer data)
-{
- GET_STATEPRIV_SCREEN(pScreen);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->InitPixmapCache)(pScreen, areas,
- data);
-}
-
-static void XAAStateWrapClosePixmapCache(ScreenPtr pScreen)
-{
- GET_STATEPRIV_SCREEN(pScreen);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->ClosePixmapCache)(pScreen);
-}
-
-static int XAAStateWrapStippledFillChooser(GCPtr pGC)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- return (*pStatePriv->StippledFillChooser)(pGC);
-}
-
-static int XAAStateWrapOpaqueStippledFillChooser(GCPtr pGC)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- return (*pStatePriv->OpaqueStippledFillChooser)(pGC);
-}
-
-static int XAAStateWrapTiledFillChooser(GCPtr pGC)
-{
- GET_STATEPRIV_GC(pGC);
- STATE_CHECK_SP(pStatePriv);
-
- return (*pStatePriv->TiledFillChooser)(pGC);
-}
-
-static XAACacheInfoPtr XAAStateWrapCacheTile(ScrnInfoPtr pScrn, PixmapPtr pPix)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- return (*pStatePriv->CacheTile)(pScrn, pPix);
-}
-
-static XAACacheInfoPtr XAAStateWrapCacheStipple(ScrnInfoPtr pScrn, PixmapPtr pPix, int fg,
- int bg)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- return (*pStatePriv->CacheStipple)(pScrn, pPix, fg,
- bg);
-}
-
-static XAACacheInfoPtr XAAStateWrapCacheMonoStipple(ScrnInfoPtr pScrn, PixmapPtr pPix)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- return (*pStatePriv->CacheMonoStipple)(pScrn, pPix);
-}
-
-static XAACacheInfoPtr XAAStateWrapCacheMono8x8Pattern(ScrnInfoPtr pScrn, int pat0,
- int pat1)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- return (*pStatePriv->CacheMono8x8Pattern)(pScrn, pat0,
- pat1);
-}
-
-static XAACacheInfoPtr XAAStateWrapCacheColor8x8Pattern(ScrnInfoPtr pScrn, PixmapPtr pPix,
- int fg, int bg)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- return (*pStatePriv->CacheColor8x8Pattern)(pScrn, pPix,
- fg, bg);
-}
-
-static void XAAStateWrapWriteBitmapToCache(ScrnInfoPtr pScrn, int x, int y, int w, int h,
- unsigned char *src, int srcwidth, int fg,
- int bg)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->WriteBitmapToCache)(pScrn, x, y, w, h,
- src, srcwidth, fg,
- bg);
-}
-
-static void XAAStateWrapWritePixmapToCache(ScrnInfoPtr pScrn, int x, int y, int w, int h,
- unsigned char *src, int srcwidth, int bpp,
- int depth)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->WritePixmapToCache)(pScrn, x, y, w, h,
- src, srcwidth, bpp,
- depth);
-}
-
-static void XAAStateWrapWriteMono8x8PatternToCache(ScrnInfoPtr pScrn,
- XAACacheInfoPtr pCache)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->WriteMono8x8PatternToCache)(pScrn,
- pCache);
-}
-
-static void XAAStateWrapWriteColor8x8PatternToCache(ScrnInfoPtr pScrn, PixmapPtr pPix,
- XAACacheInfoPtr pCache)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- (*pStatePriv->WriteColor8x8PatternToCache)(pScrn, pPix,
- pCache);
-}
-
-static void XAAStateWrapGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
- unsigned int format,unsigned long planeMask,
- char *pdstLine)
-{
- GET_STATEPRIV_SCREEN(pDrawable->pScreen);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->GetImage)(pDrawable, sx, sy, w, h,
- format, planeMask,
- pdstLine);
-}
-
-static void XAAStateWrapGetSpans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt,
- int *pwidth, int nspans, char *pdstStart)
-{
- GET_STATEPRIV_SCREEN(pDrawable->pScreen);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->GetSpans)(pDrawable, wMax, ppt,
- pwidth, nspans, pdstStart);
-}
-
-static void XAAStateWrapCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg,
- RegionPtr prgnSrc)
-{
- GET_STATEPRIV_SCREEN(pWindow->drawable.pScreen);
- STATE_CHECK_SP(pStatePriv);
-
- (*pStatePriv->CopyWindow)(pWindow, ptOldOrg,
- prgnSrc);
-}
-
-static Bool XAAStateWrapSetupForCPUToScreenAlphaTexture2(ScrnInfoPtr pScrn,
- int op, CARD16 red,
- CARD16 green,
- CARD16 blue,
- CARD16 alpha,
- CARD32 srcFormat,
- CARD32 dstFormat,
- CARD8 *alphaPtr,
- int alphaPitch,
- int width, int height,
- int flags)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- return (*pStatePriv->SetupForCPUToScreenAlphaTexture2)(pScrn, op, red, green,
- blue, alpha, srcFormat,
- dstFormat, alphaPtr,
- alphaPitch, width,
- height, flags);
-}
-
-static Bool XAAStateWrapSetupForCPUToScreenTexture2(ScrnInfoPtr pScrn, int op,
- CARD32 srcFormat,
- CARD32 dstFormat,
- CARD8 *texPtr, int texPitch,
- int width, int height,
- int flags)
-{
- GET_STATEPRIV_PSCRN(pScrn);
- STATE_CHECK_PSCRN(pScrn);
-
- return (*pStatePriv->SetupForCPUToScreenTexture2)(pScrn, op, srcFormat,
- dstFormat, texPtr, texPitch,
- width, height, flags);
-}
-
-/* Setup Function */
-Bool
-XAAInitStateWrap(ScreenPtr pScreen, XAAInfoRecPtr infoRec)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- XAAStateWrapPtr pStatePriv;
- int i = 0;
-
- if(!(pStatePriv = xalloc(sizeof(XAAStateWrapRec)))) return FALSE;
- dixSetPrivate(&pScreen->devPrivates, XAAStateKey, pStatePriv);
- pStatePriv->RestoreAccelState = infoRec->RestoreAccelState;
- pStatePriv->pScrn = pScrn;
-
- /* Initialize the last screen to -1 so whenever an accel function
- * is called the proper state is setup
- */
- while(i < pScrn->numEntities) {
- xf86SetLastScrnFlag(pScrn->entityList[i], -1);
- i++;
- }
-/* Do the wrapping */
- XAA_STATE_WRAP(Sync);
- XAA_STATE_WRAP(SetupForScreenToScreenCopy);
- XAA_STATE_WRAP(SetupForSolidFill);
- XAA_STATE_WRAP(SetupForSolidLine);
- XAA_STATE_WRAP(SetupForDashedLine);
- XAA_STATE_WRAP(SetClippingRectangle);
- XAA_STATE_WRAP(DisableClipping);
- XAA_STATE_WRAP(SetupForMono8x8PatternFill);
- XAA_STATE_WRAP(SetupForColor8x8PatternFill);
- XAA_STATE_WRAP(SetupForCPUToScreenColorExpandFill);
- XAA_STATE_WRAP(SetupForScanlineCPUToScreenColorExpandFill);
- XAA_STATE_WRAP(SetupForScreenToScreenColorExpandFill);
- XAA_STATE_WRAP(SetupForImageWrite);
- XAA_STATE_WRAP(SetupForScanlineImageWrite);
- XAA_STATE_WRAP(SetupForImageRead);
- XAA_STATE_WRAP(ScreenToScreenBitBlt);
- XAA_STATE_WRAP(WriteBitmap);
- XAA_STATE_WRAP(FillSolidRects);
- XAA_STATE_WRAP(FillMono8x8PatternRects);
- XAA_STATE_WRAP(FillColor8x8PatternRects);
- XAA_STATE_WRAP(FillCacheBltRects);
- XAA_STATE_WRAP(FillColorExpandRects);
- XAA_STATE_WRAP(FillCacheExpandRects);
- XAA_STATE_WRAP(FillImageWriteRects);
- XAA_STATE_WRAP(FillSolidSpans);
- XAA_STATE_WRAP(FillMono8x8PatternSpans);
- XAA_STATE_WRAP(FillColor8x8PatternSpans);
- XAA_STATE_WRAP(FillCacheBltSpans);
- XAA_STATE_WRAP(FillColorExpandSpans);
- XAA_STATE_WRAP(FillCacheExpandSpans);
- XAA_STATE_WRAP(TEGlyphRenderer);
- XAA_STATE_WRAP(NonTEGlyphRenderer);
- XAA_STATE_WRAP(WritePixmap);
- XAA_STATE_WRAP(ReadPixmap);
- XAA_STATE_WRAP(CopyArea);
- XAA_STATE_WRAP(CopyPlane);
- XAA_STATE_WRAP(PushPixelsSolid);
- XAA_STATE_WRAP(PolyFillRectSolid);
- XAA_STATE_WRAP(PolyFillRectStippled);
- XAA_STATE_WRAP(PolyFillRectOpaqueStippled);
- XAA_STATE_WRAP(PolyFillRectTiled);
- XAA_STATE_WRAP(FillSpansSolid);
- XAA_STATE_WRAP(FillSpansStippled);
- XAA_STATE_WRAP(FillSpansOpaqueStippled);
- XAA_STATE_WRAP(FillSpansTiled);
- XAA_STATE_WRAP(PolyText8TE);
- XAA_STATE_WRAP(PolyText16TE);
- XAA_STATE_WRAP(ImageText8TE);
- XAA_STATE_WRAP(ImageText16TE);
- XAA_STATE_WRAP(ImageGlyphBltTE);
- XAA_STATE_WRAP(PolyGlyphBltTE);
- XAA_STATE_WRAP(PolyText8NonTE);
- XAA_STATE_WRAP(PolyText16NonTE);
- XAA_STATE_WRAP(ImageText8NonTE);
- XAA_STATE_WRAP(ImageText16NonTE);
- XAA_STATE_WRAP(ImageGlyphBltNonTE);
- XAA_STATE_WRAP(PolyGlyphBltNonTE);
- XAA_STATE_WRAP(PolyRectangleThinSolid);
- XAA_STATE_WRAP(PolylinesWideSolid);
- XAA_STATE_WRAP(PolylinesThinSolid);
- XAA_STATE_WRAP(PolySegmentThinSolid);
- XAA_STATE_WRAP(PolylinesThinDashed);
- XAA_STATE_WRAP(PolySegmentThinDashed);
- XAA_STATE_WRAP(FillPolygonSolid);
- XAA_STATE_WRAP(FillPolygonStippled);
- XAA_STATE_WRAP(FillPolygonOpaqueStippled);
- XAA_STATE_WRAP(FillPolygonTiled);
- XAA_STATE_WRAP(PolyFillArcSolid);
- XAA_STATE_WRAP(PutImage);
- XAA_STATE_WRAP(ValidateFillSpans);
- XAA_STATE_WRAP(ValidateSetSpans);
- XAA_STATE_WRAP(ValidatePutImage);
- XAA_STATE_WRAP(ValidateCopyArea);
- XAA_STATE_WRAP(ValidateCopyPlane);
- XAA_STATE_WRAP(ValidatePolyPoint);
- XAA_STATE_WRAP(ValidatePolylines);
- XAA_STATE_WRAP(ValidatePolySegment);
- XAA_STATE_WRAP(ValidatePolyRectangle);
- XAA_STATE_WRAP(ValidatePolyArc);
- XAA_STATE_WRAP(ValidateFillPolygon);
- XAA_STATE_WRAP(ValidatePolyFillRect);
- XAA_STATE_WRAP(ValidatePolyFillArc);
- XAA_STATE_WRAP(ValidatePolyText8);
- XAA_STATE_WRAP(ValidatePolyText16);
- XAA_STATE_WRAP(ValidateImageText8);
- XAA_STATE_WRAP(ValidateImageText16);
- XAA_STATE_WRAP(ValidatePolyGlyphBlt);
- XAA_STATE_WRAP(ValidateImageGlyphBlt);
- XAA_STATE_WRAP(ValidatePushPixels);
- XAA_STATE_WRAP(ComputeDash);
- XAA_STATE_WRAP(InitPixmapCache);
- XAA_STATE_WRAP(ClosePixmapCache);
- XAA_STATE_WRAP(StippledFillChooser);
- XAA_STATE_WRAP(OpaqueStippledFillChooser);
- XAA_STATE_WRAP(TiledFillChooser);
- XAA_STATE_WRAP(CacheTile);
- XAA_STATE_WRAP(CacheStipple);
- XAA_STATE_WRAP(CacheMonoStipple);
- XAA_STATE_WRAP(CacheMono8x8Pattern);
- XAA_STATE_WRAP(CacheColor8x8Pattern);
- XAA_STATE_WRAP(WriteBitmapToCache);
- XAA_STATE_WRAP(WritePixmapToCache);
- XAA_STATE_WRAP(WriteMono8x8PatternToCache);
- XAA_STATE_WRAP(WriteColor8x8PatternToCache);
- XAA_STATE_WRAP(GetImage);
- XAA_STATE_WRAP(GetSpans);
- XAA_STATE_WRAP(CopyWindow);
- XAA_STATE_WRAP(SetupForCPUToScreenAlphaTexture2);
- XAA_STATE_WRAP(SetupForCPUToScreenTexture2);
- return TRUE;
-}
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include <X11/X.h>
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "xf86str.h"
+#include "mi.h"
+#include "miline.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xaawrap.h"
+#include "servermd.h"
+
+#define XAA_STATE_WRAP(func) do {\
+if(infoRec->func) { \
+ pStatePriv->func = infoRec->func;\
+ infoRec->func = XAAStateWrap##func;\
+}} while(0)
+
+/* Wrap all XAA functions and allocate our private structure.
+ */
+
+typedef struct _XAAStateWrapRec {
+ ScrnInfoPtr pScrn;
+ void (*RestoreAccelState)(ScrnInfoPtr pScrn);
+ void (*Sync)(ScrnInfoPtr pScrn);
+ void (*SetupForScreenToScreenCopy)(ScrnInfoPtr pScrn, int xdir, int ydir,
+ int rop, unsigned int planemask,
+ int trans_color);
+ void (*SetupForSolidFill)(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask);
+ void (*SetupForSolidLine)(ScrnInfoPtr pScrn,int color,int rop,
+ unsigned int planemask);
+ void (*SetupForDashedLine)(ScrnInfoPtr pScrn, int fg, int bg, int rop,
+ unsigned int planemask, int length,
+ unsigned char *pattern);
+ void (*SetClippingRectangle) (ScrnInfoPtr pScrn, int left, int top,
+ int right, int bottom);
+ void (*DisableClipping)(ScrnInfoPtr pScrn);
+ void (*SetupForMono8x8PatternFill)(ScrnInfoPtr pScrn, int patx, int paty,
+ int fg, int bg, int rop,
+ unsigned int planemask);
+ void (*SetupForColor8x8PatternFill)(ScrnInfoPtr pScrn, int patx, int paty,
+ int rop, unsigned int planemask,
+ int transparency_color);
+ void (*SetupForCPUToScreenColorExpandFill)(ScrnInfoPtr pScrn, int fg,
+ int bg, int rop,
+ unsigned int planemask);
+ void (*SetupForScanlineCPUToScreenColorExpandFill)(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask);
+ void (*SetupForScreenToScreenColorExpandFill) (ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask);
+ void (*SetupForImageWrite)(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask, int transparency_color,
+ int bpp, int depth);
+ void (*SetupForScanlineImageWrite)(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask,
+ int transparency_color,
+ int bpp, int depth);
+ void (*SetupForImageRead) (ScrnInfoPtr pScrn, int bpp, int depth);
+ void (*ScreenToScreenBitBlt)(ScrnInfoPtr pScrn, int nbox,
+ DDXPointPtr pptSrc, BoxPtr pbox, int xdir,
+ int ydir, int alu, unsigned int planmask);
+ void (*WriteBitmap) (ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *src, int srcwidth, int skipleft,
+ int fg, int bg, int rop, unsigned int planemask);
+ void (*FillSolidRects)(ScrnInfoPtr pScrn, int fg, int rop,
+ unsigned int planemask, int nBox, BoxPtr pBox);
+ void (*FillMono8x8PatternRects)(ScrnInfoPtr pScrn, int fg, int bg, int rop,
+ unsigned int planemask, int nBox,
+ BoxPtr pBox, int pat0, int pat1,
+ int xorg, int yorg);
+ void (*FillColor8x8PatternRects)(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask, int nBox,
+ BoxPtr pBox, int xorg, int yorg,
+ XAACacheInfoPtr pCache);
+ void (*FillCacheBltRects)(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask, int nBox, BoxPtr pBox,
+ int xorg, int yorg, XAACacheInfoPtr pCache);
+ void (*FillColorExpandRects)(ScrnInfoPtr pScrn, int fg, int bg, int rop,
+ unsigned int planemask, int nBox,
+ BoxPtr pBox, int xorg, int yorg,
+ PixmapPtr pPix);
+ void (*FillCacheExpandRects)(ScrnInfoPtr pScrn, int fg, int bg, int rop,
+ unsigned int planemask, int nBox, BoxPtr pBox,
+ int xorg, int yorg, PixmapPtr pPix);
+ void (*FillImageWriteRects)(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask, int nBox, BoxPtr pBox,
+ int xorg, int yorg, PixmapPtr pPix);
+ void (*FillSolidSpans)(ScrnInfoPtr pScrn, int fg, int rop,
+ unsigned int planemask, int n, DDXPointPtr points,
+ int *widths, int fSorted);
+ void (*FillMono8x8PatternSpans)(ScrnInfoPtr pScrn, int fg, int bg, int rop,
+ unsigned int planemask, int n,
+ DDXPointPtr points, int *widths,
+ int fSorted, int pat0, int pat1,
+ int xorg, int yorg);
+ void (*FillColor8x8PatternSpans)(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask, int n,
+ DDXPointPtr points, int *widths,
+ int fSorted, XAACacheInfoPtr pCache,
+ int xorg, int yorg);
+ void (*FillCacheBltSpans)(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask, int n, DDXPointPtr points,
+ int *widths, int fSorted, XAACacheInfoPtr pCache,
+ int xorg, int yorg);
+ void (*FillColorExpandSpans)(ScrnInfoPtr pScrn, int fg, int bg, int rop,
+ unsigned int planemask, int n,
+ DDXPointPtr points, int *widths, int fSorted,
+ int xorg, int yorg, PixmapPtr pPix);
+ void (*FillCacheExpandSpans)(ScrnInfoPtr pScrn, int fg, int bg, int rop,
+ unsigned int planemask, int n, DDXPointPtr ppt,
+ int *pwidth, int fSorted, int xorg, int yorg,
+ PixmapPtr pPix);
+ void (*TEGlyphRenderer)(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ int skipleft, int startline, unsigned int **glyphs,
+ int glyphWidth, int fg, int bg, int rop,
+ unsigned planemask);
+ void (*NonTEGlyphRenderer)(ScrnInfoPtr pScrn, int x, int y, int n,
+ NonTEGlyphPtr glyphs, BoxPtr pbox,
+ int fg, int rop, unsigned int planemask);
+ void (*WritePixmap) (ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *src, int srcwidth, int rop,
+ unsigned int planemask, int transparency_color,
+ int bpp, int depth);
+ void (*ReadPixmap) (ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *dst, int dstwidth, int bpp, int depth);
+ RegionPtr (*CopyArea)(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
+ GC *pGC, int srcx, int srcy, int width, int height,
+ int dstx, int dsty);
+ RegionPtr (*CopyPlane)(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int width, int height, int dstx,
+ int dsty, unsigned long bitPlane);
+ void (*PushPixelsSolid) (GCPtr pGC, PixmapPtr pBitMap,
+ DrawablePtr pDrawable, int dx, int dy, int xOrg,
+ int yOrg);
+ void (*PolyFillRectSolid)(DrawablePtr pDraw, GCPtr pGC, int nrectFill,
+ xRectangle *prectInit);
+ void (*PolyFillRectStippled)(DrawablePtr pDraw, GCPtr pGC, int nrectFill,
+ xRectangle *prectInit);
+ void (*PolyFillRectOpaqueStippled)(DrawablePtr pDraw, GCPtr pGC,
+ int nrectFill, xRectangle *prectInit);
+ void (*PolyFillRectTiled)(DrawablePtr pDraw, GCPtr pGC, int nrectFill,
+ xRectangle *prectInit);
+ void (*FillSpansSolid)(DrawablePtr pDraw, GCPtr pGC, int nInit,
+ DDXPointPtr ppt, int *pwidth, int fSorted);
+ void (*FillSpansStippled)(DrawablePtr pDraw, GCPtr pGC, int nInit,
+ DDXPointPtr ppt, int *pwidth, int fSorted);
+ void (*FillSpansOpaqueStippled)(DrawablePtr pDraw, GCPtr pGC, int nInit,
+ DDXPointPtr ppt, int *pwidth, int fSorted);
+ void (*FillSpansTiled)(DrawablePtr pDraw, GCPtr pGC, int nInit,
+ DDXPointPtr ppt, int *pwidth, int fSorted);
+ int (*PolyText8TE) (DrawablePtr pDraw, GCPtr pGC, int x, int y, int count,
+ char *chars);
+ int (*PolyText16TE) (DrawablePtr pDraw, GCPtr pGC, int x, int y, int count,
+ unsigned short *chars);
+ void (*ImageText8TE) (DrawablePtr pDraw, GCPtr pGC, int x, int y, int count,
+ char *chars);
+ void (*ImageText16TE) (DrawablePtr pDraw, GCPtr pGC, int x, int y,
+ int count, unsigned short *chars);
+ void (*ImageGlyphBltTE) (DrawablePtr pDrawable, GCPtr pGC, int xInit,
+ int yInit, unsigned int nglyph, CharInfoPtr *ppci,
+ pointer pglyphBase);
+ void (*PolyGlyphBltTE) (DrawablePtr pDrawable, GCPtr pGC, int xInit,
+ int yInit, unsigned int nglyph, CharInfoPtr *ppci,
+ pointer pglyphBase);
+ int (*PolyText8NonTE) (DrawablePtr pDraw, GCPtr pGC, int x, int y,
+ int count, char *chars);
+ int (*PolyText16NonTE) (DrawablePtr pDraw, GCPtr pGC, int x, int y,
+ int count, unsigned short *chars);
+ void (*ImageText8NonTE) (DrawablePtr pDraw, GCPtr pGC, int x, int y,
+ int count, char *chars);
+ void (*ImageText16NonTE) (DrawablePtr pDraw, GCPtr pGC, int x, int y,
+ int count, unsigned short *chars);
+ void (*ImageGlyphBltNonTE) (DrawablePtr pDrawable, GCPtr pGC, int xInit,
+ int yInit, unsigned int nglyph,
+ CharInfoPtr *ppci, pointer pglyphBase);
+ void (*PolyGlyphBltNonTE) (DrawablePtr pDrawable, GCPtr pGC, int xInit,
+ int yInit, unsigned int nglyph,
+ CharInfoPtr *ppci, pointer pglyphBase);
+ void (*PolyRectangleThinSolid)(DrawablePtr pDrawable,GCPtr pGC,
+ int nRectsInit, xRectangle *pRectsInit);
+ void (*PolylinesWideSolid)(DrawablePtr pDrawable, GCPtr pGC, int mode,
+ int npt, DDXPointPtr pPts);
+ void (*PolylinesThinSolid)(DrawablePtr pDrawable, GCPtr pGC, int mode,
+ int npt, DDXPointPtr pPts);
+ void (*PolySegmentThinSolid)(DrawablePtr pDrawable, GCPtr pGC, int nseg,
+ xSegment *pSeg);
+ void (*PolylinesThinDashed)(DrawablePtr pDrawable, GCPtr pGC, int mode,
+ int npt, DDXPointPtr pPts);
+ void (*PolySegmentThinDashed)(DrawablePtr pDrawable, GCPtr pGC, int nseg,
+ xSegment *pSeg);
+ void (*FillPolygonSolid)(DrawablePtr pDrawable, GCPtr pGC, int shape,
+ int mode, int count, DDXPointPtr ptsIn);
+ void (*FillPolygonStippled)(DrawablePtr pDrawable, GCPtr pGC, int shape,
+ int mode, int count, DDXPointPtr ptsIn);
+ void (*FillPolygonOpaqueStippled)(DrawablePtr pDrawable, GCPtr pGC,
+ int shape, int mode, int count,
+ DDXPointPtr ptsIn);
+ void (*FillPolygonTiled)(DrawablePtr pDrawable, GCPtr pGC, int shape,
+ int mode, int count, DDXPointPtr ptsIn);
+ void (*PolyFillArcSolid)(DrawablePtr pDraw, GCPtr pGC, int narcs,
+ xArc *parcs);
+ void (*PutImage)(DrawablePtr pDraw, GCPtr pGC, int depth, int x, int y,
+ int w, int h, int leftPad, int format, char *pImage);
+ ValidateGCProcPtr ValidateFillSpans;
+ ValidateGCProcPtr ValidateSetSpans;
+ ValidateGCProcPtr ValidatePutImage;
+ ValidateGCProcPtr ValidateCopyArea;
+ ValidateGCProcPtr ValidateCopyPlane;
+ ValidateGCProcPtr ValidatePolyPoint;
+ ValidateGCProcPtr ValidatePolylines;
+ ValidateGCProcPtr ValidatePolySegment;
+ ValidateGCProcPtr ValidatePolyRectangle;
+ ValidateGCProcPtr ValidatePolyArc;
+ ValidateGCProcPtr ValidateFillPolygon;
+ ValidateGCProcPtr ValidatePolyFillRect;
+ ValidateGCProcPtr ValidatePolyFillArc;
+ ValidateGCProcPtr ValidatePolyText8;
+ ValidateGCProcPtr ValidatePolyText16;
+ ValidateGCProcPtr ValidateImageText8;
+ ValidateGCProcPtr ValidateImageText16;
+ ValidateGCProcPtr ValidatePolyGlyphBlt;
+ ValidateGCProcPtr ValidateImageGlyphBlt;
+ ValidateGCProcPtr ValidatePushPixels;
+ void (*ComputeDash)(GCPtr pGC);
+ void (*InitPixmapCache)(ScreenPtr pScreen, RegionPtr areas, pointer data);
+ void (*ClosePixmapCache)(ScreenPtr pScreen);
+ int (*StippledFillChooser)(GCPtr pGC);
+ int (*OpaqueStippledFillChooser)(GCPtr pGC);
+ int (*TiledFillChooser)(GCPtr pGC);
+ XAACacheInfoPtr (*CacheTile)(ScrnInfoPtr Scrn, PixmapPtr pPix);
+ XAACacheInfoPtr (*CacheStipple)(ScrnInfoPtr Scrn, PixmapPtr pPix, int fg,
+ int bg);
+ XAACacheInfoPtr (*CacheMonoStipple)(ScrnInfoPtr Scrn, PixmapPtr pPix);
+ XAACacheInfoPtr (*CacheMono8x8Pattern)(ScrnInfoPtr Scrn, int pat0,
+ int pat1);
+ XAACacheInfoPtr (*CacheColor8x8Pattern)(ScrnInfoPtr Scrn, PixmapPtr pPix,
+ int fg, int bg);
+ void (*WriteBitmapToCache) (ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *src, int srcwidth, int fg,
+ int bg);
+ void (*WritePixmapToCache) (ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *src, int srcwidth, int bpp,
+ int depth);
+ void (*WriteMono8x8PatternToCache)(ScrnInfoPtr pScrn,
+ XAACacheInfoPtr pCache);
+ void (*WriteColor8x8PatternToCache)(ScrnInfoPtr pScrn, PixmapPtr pPix,
+ XAACacheInfoPtr pCache);
+ GetImageProcPtr GetImage;
+ GetSpansProcPtr GetSpans;
+ CopyWindowProcPtr CopyWindow;
+ Bool (*SetupForCPUToScreenAlphaTexture2)(ScrnInfoPtr pScrn, int op,
+ CARD16 red, CARD16 green,
+ CARD16 blue, CARD16 alpha,
+ CARD32 maskFormat, CARD32 dstFormat,
+ CARD8 *alphaPtr, int alphaPitch,
+ int width, int height, int flags);
+ Bool (*SetupForCPUToScreenTexture2)(ScrnInfoPtr pScrn, int op,
+ CARD32 srcFormat, CARD32 dstFormat,
+ CARD8 *texPtr, int texPitch,
+ int width, int height, int flags);
+} XAAStateWrapRec, *XAAStateWrapPtr;
+
+static int XAAStateKeyIndex;
+static DevPrivateKey XAAStateKey = &XAAStateKeyIndex;
+
+/* Wrap functions start here */
+#define GET_STATEPRIV_GC(pGC) XAAStateWrapPtr pStatePriv =\
+(XAAStateWrapPtr)dixLookupPrivate(&(pGC)->pScreen->devPrivates, XAAStateKey)
+
+#define GET_STATEPRIV_SCREEN(pScreen) XAAStateWrapPtr pStatePriv =\
+(XAAStateWrapPtr)dixLookupPrivate(&(pScreen)->devPrivates, XAAStateKey)
+
+#define GET_STATEPRIV_PSCRN(pScrn) XAAStateWrapPtr pStatePriv =\
+(XAAStateWrapPtr)dixLookupPrivate(&(pScrn)->pScreen->devPrivates, XAAStateKey)
+
+#define STATE_CHECK_SP(pStatePriv) {\
+ ScrnInfoPtr pScrn = pStatePriv->pScrn;\
+ int i = 0;\
+ int need_change = 0;\
+ while(i < pScrn->numEntities) {\
+ if(xf86IsEntityShared(pScrn->entityList[i]) &&\
+ xf86GetLastScrnFlag(pScrn->entityList[i]) != pScrn->scrnIndex) {\
+ need_change = 1;\
+ xf86SetLastScrnFlag(pScrn->entityList[i],\
+ pScrn->scrnIndex);\
+ }\
+ i++;\
+ }\
+ if(need_change == 1) (*pStatePriv->RestoreAccelState)(pScrn);\
+}
+
+#define STATE_CHECK_PSCRN(pScrn) {\
+ int i = 0;\
+ int need_change = 0;\
+ while(i < pScrn->numEntities) {\
+ if(xf86IsEntityShared(pScrn->entityList[i]) &&\
+ xf86GetLastScrnFlag(pScrn->entityList[i]) != pScrn->scrnIndex) {\
+ need_change = 1;\
+ xf86SetLastScrnFlag(pScrn->entityList[i],\
+ pScrn->scrnIndex);\
+ }\
+ i++;\
+ }\
+ if(need_change == 1) (*pStatePriv->RestoreAccelState)(pScrn);\
+}
+
+static void XAAStateWrapSync(ScrnInfoPtr pScrn)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->Sync)(pScrn);
+}
+
+static void XAAStateWrapSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, int xdir, int ydir,
+ int rop, unsigned int planemask,
+ int trans_color)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->SetupForScreenToScreenCopy)(pScrn, xdir, ydir, rop, planemask,
+ trans_color);
+}
+
+static void XAAStateWrapSetupForSolidFill(ScrnInfoPtr pScrn, int color, int rop,
+ unsigned int planemask)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->SetupForSolidFill)(pScrn, color, rop, planemask);
+}
+
+static void XAAStateWrapSetupForSolidLine(ScrnInfoPtr pScrn,int color,int rop,
+ unsigned int planemask)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->SetupForSolidLine)(pScrn, color, rop, planemask);
+}
+
+static void XAAStateWrapSetupForDashedLine(ScrnInfoPtr pScrn, int fg, int bg, int rop,
+ unsigned int planemask, int length,
+ unsigned char *pattern)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->SetupForDashedLine)(pScrn, fg, bg, rop, planemask, length, pattern);
+}
+
+static void XAAStateWrapSetClippingRectangle(ScrnInfoPtr pScrn, int left, int top,
+ int right, int bottom)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->SetClippingRectangle)(pScrn, left, top, right, bottom);
+}
+
+static void XAAStateWrapDisableClipping(ScrnInfoPtr pScrn)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->DisableClipping)(pScrn);
+}
+
+static void XAAStateWrapSetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->SetupForMono8x8PatternFill)(pScrn, patx, paty, fg, bg, rop, planemask);
+}
+
+static void XAAStateWrapSetupForColor8x8PatternFill(ScrnInfoPtr pScrn, int patx, int paty,
+ int rop, unsigned int planemask,
+ int transparency_color)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->SetupForColor8x8PatternFill)(pScrn, patx, paty, rop, planemask,
+ transparency_color);
+}
+
+static void XAAStateWrapSetupForCPUToScreenColorExpandFill(ScrnInfoPtr pScrn, int fg,
+ int bg, int rop,
+ unsigned int planemask)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->SetupForCPUToScreenColorExpandFill)(pScrn, fg, bg, rop, planemask);
+}
+
+static void XAAStateWrapSetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->SetupForScanlineCPUToScreenColorExpandFill)(pScrn, fg, bg, rop,
+ planemask);
+}
+
+static void XAAStateWrapSetupForScreenToScreenColorExpandFill(ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->SetupForScreenToScreenColorExpandFill)(pScrn, fg, bg, rop, planemask);
+}
+
+static void XAAStateWrapSetupForImageWrite(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask, int transparency_color,
+ int bpp, int depth)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->SetupForImageWrite)(pScrn, rop, planemask, transparency_color, bpp,
+ depth);
+}
+
+static void XAAStateWrapSetupForScanlineImageWrite(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask,
+ int transparency_color,
+ int bpp, int depth)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->SetupForScanlineImageWrite)(pScrn, rop, planemask, transparency_color,
+ bpp, depth);
+}
+
+static void XAAStateWrapSetupForImageRead(ScrnInfoPtr pScrn, int bpp, int depth)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->SetupForImageRead)(pScrn, bpp, depth);
+}
+
+static void XAAStateWrapScreenToScreenBitBlt(ScrnInfoPtr pScrn, int nbox,
+ DDXPointPtr pptSrc, BoxPtr pbox, int xdir,
+ int ydir, int alu, unsigned int planmask)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->ScreenToScreenBitBlt)(pScrn, nbox,
+ pptSrc, pbox, xdir,
+ ydir, alu, planmask);
+}
+
+static void XAAStateWrapWriteBitmap(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *src, int srcwidth, int skipleft,
+ int fg, int bg, int rop, unsigned int planemask)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->WriteBitmap)(pScrn, x, y, w, h,
+ src, srcwidth, skipleft,
+ fg, bg, rop, planemask);
+}
+
+static void XAAStateWrapFillSolidRects(ScrnInfoPtr pScrn, int fg, int rop,
+ unsigned int planemask, int nBox, BoxPtr pBox)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->FillSolidRects)(pScrn, fg, rop,
+ planemask, nBox, pBox);
+}
+
+static void XAAStateWrapFillMono8x8PatternRects(ScrnInfoPtr pScrn, int fg, int bg,
+ int rop, unsigned int planemask, int nBox,
+ BoxPtr pBox, int pat0, int pat1,
+ int xorg, int yorg)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->FillMono8x8PatternRects)(pScrn, fg, bg,
+ rop, planemask, nBox,
+ pBox, pat0, pat1,
+ xorg, yorg);
+}
+
+static void XAAStateWrapFillColor8x8PatternRects(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask, int nBox,
+ BoxPtr pBox, int xorg, int yorg,
+ XAACacheInfoPtr pCache)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->FillColor8x8PatternRects)(pScrn, rop,
+ planemask, nBox,
+ pBox, xorg, yorg,
+ pCache);
+}
+
+static void XAAStateWrapFillCacheBltRects(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask, int nBox, BoxPtr pBox,
+ int xorg, int yorg, XAACacheInfoPtr pCache)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->FillCacheBltRects)(pScrn, rop,
+ planemask, nBox, pBox,
+ xorg, yorg, pCache);
+}
+
+static void XAAStateWrapFillColorExpandRects(ScrnInfoPtr pScrn, int fg, int bg, int rop,
+ unsigned int planemask, int nBox,
+ BoxPtr pBox, int xorg, int yorg,
+ PixmapPtr pPix)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->FillColorExpandRects)(pScrn, fg, bg, rop,
+ planemask, nBox,
+ pBox, xorg, yorg,
+ pPix);
+}
+
+static void XAAStateWrapFillCacheExpandRects(ScrnInfoPtr pScrn, int fg, int bg, int rop,
+ unsigned int planemask, int nBox,
+ BoxPtr pBox, int xorg, int yorg,
+ PixmapPtr pPix)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->FillCacheExpandRects)(pScrn, fg, bg, rop,
+ planemask, nBox,
+ pBox, xorg, yorg,
+ pPix);
+}
+
+static void XAAStateWrapFillImageWriteRects(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask, int nBox, BoxPtr pBox,
+ int xorg, int yorg, PixmapPtr pPix)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->FillImageWriteRects)(pScrn, rop,
+ planemask, nBox, pBox,
+ xorg, yorg, pPix);
+}
+
+static void XAAStateWrapFillSolidSpans(ScrnInfoPtr pScrn, int fg, int rop,
+ unsigned int planemask, int n, DDXPointPtr points,
+ int *widths, int fSorted)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->FillSolidSpans)(pScrn, fg, rop,
+ planemask, n, points,
+ widths, fSorted);
+}
+
+static void XAAStateWrapFillMono8x8PatternSpans(ScrnInfoPtr pScrn, int fg, int bg,
+ int rop, unsigned int planemask, int n,
+ DDXPointPtr points, int *widths,
+ int fSorted, int pat0, int pat1,
+ int xorg, int yorg)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->FillMono8x8PatternSpans)(pScrn, fg, bg,
+ rop, planemask, n,
+ points, widths,
+ fSorted, pat0, pat1,
+ xorg, yorg);
+}
+
+static void XAAStateWrapFillColor8x8PatternSpans(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask, int n,
+ DDXPointPtr points, int *widths,
+ int fSorted, XAACacheInfoPtr pCache,
+ int xorg, int yorg)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->FillColor8x8PatternSpans)(pScrn, rop,
+ planemask, n,
+ points, widths,
+ fSorted, pCache,
+ xorg, yorg);
+}
+
+static void XAAStateWrapFillCacheBltSpans(ScrnInfoPtr pScrn, int rop,
+ unsigned int planemask, int n,
+ DDXPointPtr points, int *widths,
+ int fSorted, XAACacheInfoPtr pCache,
+ int xorg, int yorg)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->FillCacheBltSpans)(pScrn, rop,
+ planemask, n,
+ points, widths,
+ fSorted, pCache,
+ xorg, yorg);
+}
+
+static void XAAStateWrapFillColorExpandSpans(ScrnInfoPtr pScrn, int fg, int bg, int rop,
+ unsigned int planemask, int n,
+ DDXPointPtr points, int *widths, int fSorted,
+ int xorg, int yorg, PixmapPtr pPix)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->FillColorExpandSpans)(pScrn, fg, bg, rop,
+ planemask, n,
+ points, widths, fSorted,
+ xorg, yorg, pPix);
+}
+
+static void XAAStateWrapFillCacheExpandSpans(ScrnInfoPtr pScrn, int fg, int bg, int rop,
+ unsigned int planemask, int n,
+ DDXPointPtr ppt, int *pwidth, int fSorted,
+ int xorg, int yorg, PixmapPtr pPix)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->FillCacheExpandSpans)(pScrn, fg, bg, rop,
+ planemask, n,
+ ppt, pwidth, fSorted,
+ xorg, yorg, pPix);
+}
+
+static void XAAStateWrapTEGlyphRenderer(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ int skipleft, int startline,
+ unsigned int **glyphs,
+ int glyphWidth, int fg, int bg, int rop,
+ unsigned planemask)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->TEGlyphRenderer)(pScrn, x, y, w, h,
+ skipleft, startline,
+ glyphs,
+ glyphWidth, fg, bg, rop,
+ planemask);
+}
+
+static void XAAStateWrapNonTEGlyphRenderer(ScrnInfoPtr pScrn, int x, int y, int n,
+ NonTEGlyphPtr glyphs, BoxPtr pbox,
+ int fg, int rop, unsigned int planemask)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->NonTEGlyphRenderer)(pScrn, x, y, n,
+ glyphs, pbox,
+ fg, rop, planemask);
+}
+
+static void XAAStateWrapWritePixmap(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *src, int srcwidth, int rop,
+ unsigned int planemask, int transparency_color,
+ int bpp, int depth)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->WritePixmap)(pScrn, x, y, w, h,
+ src, srcwidth, rop,
+ planemask, transparency_color,
+ bpp, depth);
+}
+
+static void XAAStateWrapReadPixmap(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *dst, int dstwidth, int bpp, int depth)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->ReadPixmap)(pScrn, x, y, w, h,
+ dst, dstwidth, bpp, depth);
+}
+
+static RegionPtr XAAStateWrapCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
+ GC *pGC, int srcx, int srcy, int width, int height,
+ int dstx, int dsty)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ return (*pStatePriv->CopyArea)(pSrcDrawable, pDstDrawable,
+ pGC, srcx, srcy, width, height,
+ dstx, dsty);
+}
+
+static RegionPtr XAAStateWrapCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int width, int height,
+ int dstx, int dsty, unsigned long bitPlane)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ return (*pStatePriv->CopyPlane)(pSrc, pDst, pGC,
+ srcx, srcy, width, height,
+ dstx, dsty, bitPlane);
+}
+
+static void XAAStateWrapPushPixelsSolid(GCPtr pGC, PixmapPtr pBitMap,
+ DrawablePtr pDrawable, int dx, int dy, int xOrg,
+ int yOrg)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->PushPixelsSolid)(pGC, pBitMap,
+ pDrawable, dx, dy, xOrg,
+ yOrg);
+}
+
+static void XAAStateWrapPolyFillRectSolid(DrawablePtr pDraw, GCPtr pGC, int nrectFill,
+ xRectangle *prectInit)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->PolyFillRectSolid)(pDraw, pGC, nrectFill,
+ prectInit);
+}
+
+static void XAAStateWrapPolyFillRectStippled(DrawablePtr pDraw, GCPtr pGC, int nrectFill,
+ xRectangle *prectInit)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->PolyFillRectStippled)(pDraw, pGC, nrectFill,
+ prectInit);
+}
+
+static void XAAStateWrapPolyFillRectOpaqueStippled(DrawablePtr pDraw, GCPtr pGC,
+ int nrectFill, xRectangle *prectInit)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->PolyFillRectOpaqueStippled)(pDraw, pGC,
+ nrectFill, prectInit);
+}
+
+static void XAAStateWrapPolyFillRectTiled(DrawablePtr pDraw, GCPtr pGC, int nrectFill,
+ xRectangle *prectInit)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->PolyFillRectTiled)(pDraw, pGC, nrectFill,
+ prectInit);
+}
+
+static void XAAStateWrapFillSpansSolid(DrawablePtr pDraw, GCPtr pGC, int nInit,
+ DDXPointPtr ppt, int *pwidth, int fSorted)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->FillSpansSolid)(pDraw, pGC, nInit,
+ ppt, pwidth, fSorted);
+}
+
+static void XAAStateWrapFillSpansStippled(DrawablePtr pDraw, GCPtr pGC, int nInit,
+ DDXPointPtr ppt, int *pwidth, int fSorted)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->FillSpansStippled)(pDraw, pGC, nInit,
+ ppt, pwidth, fSorted);
+}
+
+static void XAAStateWrapFillSpansOpaqueStippled(DrawablePtr pDraw, GCPtr pGC, int nInit,
+ DDXPointPtr ppt, int *pwidth, int fSorted)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->FillSpansOpaqueStippled)(pDraw, pGC, nInit,
+ ppt, pwidth, fSorted);
+}
+
+static void XAAStateWrapFillSpansTiled(DrawablePtr pDraw, GCPtr pGC, int nInit,
+ DDXPointPtr ppt, int *pwidth, int fSorted)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->FillSpansTiled)(pDraw, pGC, nInit,
+ ppt, pwidth, fSorted);
+}
+
+static int XAAStateWrapPolyText8TE(DrawablePtr pDraw, GCPtr pGC, int x, int y, int count,
+ char *chars)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ return (*pStatePriv->PolyText8TE)(pDraw, pGC, x, y, count,
+ chars);
+}
+
+static int XAAStateWrapPolyText16TE(DrawablePtr pDraw, GCPtr pGC, int x, int y, int count,
+ unsigned short *chars)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ return (*pStatePriv->PolyText16TE)(pDraw, pGC, x, y, count,
+ chars);
+}
+
+static void XAAStateWrapImageText8TE(DrawablePtr pDraw, GCPtr pGC, int x, int y,
+ int count, char *chars)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ImageText8TE)(pDraw, pGC, x, y,
+ count, chars);
+}
+
+static void XAAStateWrapImageText16TE(DrawablePtr pDraw, GCPtr pGC, int x, int y,
+ int count, unsigned short *chars)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ImageText16TE)(pDraw, pGC, x, y,
+ count, chars);
+}
+
+static void XAAStateWrapImageGlyphBltTE(DrawablePtr pDrawable, GCPtr pGC, int xInit,
+ int yInit, unsigned int nglyph, CharInfoPtr *ppci,
+ pointer pglyphBase)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ImageGlyphBltTE)(pDrawable, pGC, xInit,
+ yInit, nglyph, ppci,
+ pglyphBase);
+}
+
+static void XAAStateWrapPolyGlyphBltTE(DrawablePtr pDrawable, GCPtr pGC, int xInit,
+ int yInit, unsigned int nglyph, CharInfoPtr *ppci,
+ pointer pglyphBase)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->PolyGlyphBltTE)(pDrawable, pGC, xInit,
+ yInit, nglyph, ppci,
+ pglyphBase);
+}
+
+static int XAAStateWrapPolyText8NonTE(DrawablePtr pDraw, GCPtr pGC, int x, int y,
+ int count, char *chars)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ return (*pStatePriv->PolyText8NonTE)(pDraw, pGC, x, y,
+ count, chars);
+}
+
+static int XAAStateWrapPolyText16NonTE(DrawablePtr pDraw, GCPtr pGC, int x, int y,
+ int count, unsigned short *chars)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ return (*pStatePriv->PolyText16NonTE)(pDraw, pGC, x, y,
+ count, chars);
+}
+
+static void XAAStateWrapImageText8NonTE(DrawablePtr pDraw, GCPtr pGC, int x, int y,
+ int count, char *chars)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ImageText8NonTE)(pDraw, pGC, x, y,
+ count, chars);
+}
+
+static void XAAStateWrapImageText16NonTE(DrawablePtr pDraw, GCPtr pGC, int x, int y,
+ int count, unsigned short *chars)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ImageText16NonTE)(pDraw, pGC, x, y,
+ count, chars);
+}
+
+static void XAAStateWrapImageGlyphBltNonTE(DrawablePtr pDrawable, GCPtr pGC, int xInit,
+ int yInit, unsigned int nglyph,
+ CharInfoPtr *ppci, pointer pglyphBase)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ImageGlyphBltNonTE)(pDrawable, pGC, xInit,
+ yInit, nglyph,
+ ppci, pglyphBase);
+}
+
+static void XAAStateWrapPolyGlyphBltNonTE(DrawablePtr pDrawable, GCPtr pGC, int xInit,
+ int yInit, unsigned int nglyph,
+ CharInfoPtr *ppci, pointer pglyphBase)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->PolyGlyphBltNonTE)(pDrawable, pGC, xInit,
+ yInit, nglyph,
+ ppci, pglyphBase);
+}
+
+static void XAAStateWrapPolyRectangleThinSolid(DrawablePtr pDrawable,GCPtr pGC,
+ int nRectsInit, xRectangle *pRectsInit)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->PolyRectangleThinSolid)(pDrawable, pGC,
+ nRectsInit, pRectsInit);
+}
+
+static void XAAStateWrapPolylinesWideSolid(DrawablePtr pDrawable, GCPtr pGC, int mode,
+ int npt, DDXPointPtr pPts)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->PolylinesWideSolid)(pDrawable, pGC, mode,
+ npt, pPts);
+}
+
+static void XAAStateWrapPolylinesThinSolid(DrawablePtr pDrawable, GCPtr pGC, int mode,
+ int npt, DDXPointPtr pPts)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->PolylinesThinSolid)(pDrawable, pGC, mode,
+ npt, pPts);
+}
+
+static void XAAStateWrapPolySegmentThinSolid(DrawablePtr pDrawable, GCPtr pGC, int nseg,
+ xSegment *pSeg)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->PolySegmentThinSolid)(pDrawable, pGC, nseg,
+ pSeg);
+}
+
+static void XAAStateWrapPolylinesThinDashed(DrawablePtr pDrawable, GCPtr pGC, int mode,
+ int npt, DDXPointPtr pPts)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->PolylinesThinDashed)(pDrawable, pGC, mode,
+ npt, pPts);
+}
+
+static void XAAStateWrapPolySegmentThinDashed(DrawablePtr pDrawable, GCPtr pGC, int nseg,
+ xSegment *pSeg)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->PolySegmentThinDashed)(pDrawable, pGC, nseg,
+ pSeg);
+}
+
+static void XAAStateWrapFillPolygonSolid(DrawablePtr pDrawable, GCPtr pGC, int shape,
+ int mode, int count, DDXPointPtr ptsIn)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->FillPolygonSolid)(pDrawable, pGC, shape,
+ mode, count, ptsIn);
+}
+
+static void XAAStateWrapFillPolygonStippled(DrawablePtr pDrawable, GCPtr pGC, int shape,
+ int mode, int count, DDXPointPtr ptsIn)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->FillPolygonStippled)(pDrawable, pGC, shape,
+ mode, count, ptsIn);
+}
+
+static void XAAStateWrapFillPolygonOpaqueStippled(DrawablePtr pDrawable, GCPtr pGC,
+ int shape, int mode, int count,
+ DDXPointPtr ptsIn)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->FillPolygonOpaqueStippled)(pDrawable, pGC,
+ shape, mode, count,
+ ptsIn);
+}
+
+static void XAAStateWrapFillPolygonTiled(DrawablePtr pDrawable, GCPtr pGC, int shape,
+ int mode, int count, DDXPointPtr ptsIn)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->FillPolygonTiled)(pDrawable, pGC, shape,
+ mode, count, ptsIn);
+}
+
+static void XAAStateWrapPolyFillArcSolid(DrawablePtr pDraw, GCPtr pGC, int narcs,
+ xArc *parcs)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->PolyFillArcSolid)(pDraw, pGC, narcs,
+ parcs);
+}
+
+static void XAAStateWrapPutImage(DrawablePtr pDraw, GCPtr pGC, int depth, int x, int y,
+ int w, int h, int leftPad, int format, char *pImage)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->PutImage)(pDraw, pGC, depth, x, y,
+ w, h, leftPad, format, pImage);
+}
+
+static void XAAStateWrapValidateFillSpans(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidateFillSpans)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidateSetSpans(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidateSetSpans)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidatePutImage(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidatePutImage)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidateCopyArea(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidateCopyArea)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidateCopyPlane(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidateCopyPlane)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidatePolyPoint(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidatePolyPoint)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidatePolylines(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidatePolylines)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidatePolySegment(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidatePolySegment)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidatePolyRectangle(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidatePolyRectangle)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidatePolyArc(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidatePolyArc)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidateFillPolygon(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidateFillPolygon)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidatePolyFillRect(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidatePolyFillRect)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidatePolyFillArc(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidatePolyFillArc)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidatePolyText8(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidatePolyText8)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidatePolyText16(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidatePolyText16)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidateImageText8(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidateImageText8)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidateImageText16(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidateImageText16)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidatePolyGlyphBlt(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidatePolyGlyphBlt)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidateImageGlyphBlt(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+ (*pStatePriv->ValidateImageGlyphBlt)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapValidatePushPixels(GCPtr pGC, unsigned long changes,
+ DrawablePtr pDraw)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ValidatePushPixels)(pGC, changes,
+ pDraw);
+}
+
+static void XAAStateWrapComputeDash(GCPtr pGC)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ComputeDash)(pGC);
+}
+
+static void XAAStateWrapInitPixmapCache(ScreenPtr pScreen, RegionPtr areas,
+ pointer data)
+{
+ GET_STATEPRIV_SCREEN(pScreen);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->InitPixmapCache)(pScreen, areas,
+ data);
+}
+
+static void XAAStateWrapClosePixmapCache(ScreenPtr pScreen)
+{
+ GET_STATEPRIV_SCREEN(pScreen);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->ClosePixmapCache)(pScreen);
+}
+
+static int XAAStateWrapStippledFillChooser(GCPtr pGC)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ return (*pStatePriv->StippledFillChooser)(pGC);
+}
+
+static int XAAStateWrapOpaqueStippledFillChooser(GCPtr pGC)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ return (*pStatePriv->OpaqueStippledFillChooser)(pGC);
+}
+
+static int XAAStateWrapTiledFillChooser(GCPtr pGC)
+{
+ GET_STATEPRIV_GC(pGC);
+ STATE_CHECK_SP(pStatePriv);
+
+ return (*pStatePriv->TiledFillChooser)(pGC);
+}
+
+static XAACacheInfoPtr XAAStateWrapCacheTile(ScrnInfoPtr pScrn, PixmapPtr pPix)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ return (*pStatePriv->CacheTile)(pScrn, pPix);
+}
+
+static XAACacheInfoPtr XAAStateWrapCacheStipple(ScrnInfoPtr pScrn, PixmapPtr pPix, int fg,
+ int bg)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ return (*pStatePriv->CacheStipple)(pScrn, pPix, fg,
+ bg);
+}
+
+static XAACacheInfoPtr XAAStateWrapCacheMonoStipple(ScrnInfoPtr pScrn, PixmapPtr pPix)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ return (*pStatePriv->CacheMonoStipple)(pScrn, pPix);
+}
+
+static XAACacheInfoPtr XAAStateWrapCacheMono8x8Pattern(ScrnInfoPtr pScrn, int pat0,
+ int pat1)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ return (*pStatePriv->CacheMono8x8Pattern)(pScrn, pat0,
+ pat1);
+}
+
+static XAACacheInfoPtr XAAStateWrapCacheColor8x8Pattern(ScrnInfoPtr pScrn, PixmapPtr pPix,
+ int fg, int bg)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ return (*pStatePriv->CacheColor8x8Pattern)(pScrn, pPix,
+ fg, bg);
+}
+
+static void XAAStateWrapWriteBitmapToCache(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *src, int srcwidth, int fg,
+ int bg)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->WriteBitmapToCache)(pScrn, x, y, w, h,
+ src, srcwidth, fg,
+ bg);
+}
+
+static void XAAStateWrapWritePixmapToCache(ScrnInfoPtr pScrn, int x, int y, int w, int h,
+ unsigned char *src, int srcwidth, int bpp,
+ int depth)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->WritePixmapToCache)(pScrn, x, y, w, h,
+ src, srcwidth, bpp,
+ depth);
+}
+
+static void XAAStateWrapWriteMono8x8PatternToCache(ScrnInfoPtr pScrn,
+ XAACacheInfoPtr pCache)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->WriteMono8x8PatternToCache)(pScrn,
+ pCache);
+}
+
+static void XAAStateWrapWriteColor8x8PatternToCache(ScrnInfoPtr pScrn, PixmapPtr pPix,
+ XAACacheInfoPtr pCache)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ (*pStatePriv->WriteColor8x8PatternToCache)(pScrn, pPix,
+ pCache);
+}
+
+static void XAAStateWrapGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
+ unsigned int format,unsigned long planeMask,
+ char *pdstLine)
+{
+ GET_STATEPRIV_SCREEN(pDrawable->pScreen);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->GetImage)(pDrawable, sx, sy, w, h,
+ format, planeMask,
+ pdstLine);
+}
+
+static void XAAStateWrapGetSpans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt,
+ int *pwidth, int nspans, char *pdstStart)
+{
+ GET_STATEPRIV_SCREEN(pDrawable->pScreen);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->GetSpans)(pDrawable, wMax, ppt,
+ pwidth, nspans, pdstStart);
+}
+
+static void XAAStateWrapCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc)
+{
+ GET_STATEPRIV_SCREEN(pWindow->drawable.pScreen);
+ STATE_CHECK_SP(pStatePriv);
+
+ (*pStatePriv->CopyWindow)(pWindow, ptOldOrg,
+ prgnSrc);
+}
+
+static Bool XAAStateWrapSetupForCPUToScreenAlphaTexture2(ScrnInfoPtr pScrn,
+ int op, CARD16 red,
+ CARD16 green,
+ CARD16 blue,
+ CARD16 alpha,
+ CARD32 srcFormat,
+ CARD32 dstFormat,
+ CARD8 *alphaPtr,
+ int alphaPitch,
+ int width, int height,
+ int flags)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ return (*pStatePriv->SetupForCPUToScreenAlphaTexture2)(pScrn, op, red, green,
+ blue, alpha, srcFormat,
+ dstFormat, alphaPtr,
+ alphaPitch, width,
+ height, flags);
+}
+
+static Bool XAAStateWrapSetupForCPUToScreenTexture2(ScrnInfoPtr pScrn, int op,
+ CARD32 srcFormat,
+ CARD32 dstFormat,
+ CARD8 *texPtr, int texPitch,
+ int width, int height,
+ int flags)
+{
+ GET_STATEPRIV_PSCRN(pScrn);
+ STATE_CHECK_PSCRN(pScrn);
+
+ return (*pStatePriv->SetupForCPUToScreenTexture2)(pScrn, op, srcFormat,
+ dstFormat, texPtr, texPitch,
+ width, height, flags);
+}
+
+/* Setup Function */
+Bool
+XAAInitStateWrap(ScreenPtr pScreen, XAAInfoRecPtr infoRec)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ XAAStateWrapPtr pStatePriv;
+ int i = 0;
+
+ if(!(pStatePriv = malloc(sizeof(XAAStateWrapRec)))) return FALSE;
+ dixSetPrivate(&pScreen->devPrivates, XAAStateKey, pStatePriv);
+ pStatePriv->RestoreAccelState = infoRec->RestoreAccelState;
+ pStatePriv->pScrn = pScrn;
+
+ /* Initialize the last screen to -1 so whenever an accel function
+ * is called the proper state is setup
+ */
+ while(i < pScrn->numEntities) {
+ xf86SetLastScrnFlag(pScrn->entityList[i], -1);
+ i++;
+ }
+/* Do the wrapping */
+ XAA_STATE_WRAP(Sync);
+ XAA_STATE_WRAP(SetupForScreenToScreenCopy);
+ XAA_STATE_WRAP(SetupForSolidFill);
+ XAA_STATE_WRAP(SetupForSolidLine);
+ XAA_STATE_WRAP(SetupForDashedLine);
+ XAA_STATE_WRAP(SetClippingRectangle);
+ XAA_STATE_WRAP(DisableClipping);
+ XAA_STATE_WRAP(SetupForMono8x8PatternFill);
+ XAA_STATE_WRAP(SetupForColor8x8PatternFill);
+ XAA_STATE_WRAP(SetupForCPUToScreenColorExpandFill);
+ XAA_STATE_WRAP(SetupForScanlineCPUToScreenColorExpandFill);
+ XAA_STATE_WRAP(SetupForScreenToScreenColorExpandFill);
+ XAA_STATE_WRAP(SetupForImageWrite);
+ XAA_STATE_WRAP(SetupForScanlineImageWrite);
+ XAA_STATE_WRAP(SetupForImageRead);
+ XAA_STATE_WRAP(ScreenToScreenBitBlt);
+ XAA_STATE_WRAP(WriteBitmap);
+ XAA_STATE_WRAP(FillSolidRects);
+ XAA_STATE_WRAP(FillMono8x8PatternRects);
+ XAA_STATE_WRAP(FillColor8x8PatternRects);
+ XAA_STATE_WRAP(FillCacheBltRects);
+ XAA_STATE_WRAP(FillColorExpandRects);
+ XAA_STATE_WRAP(FillCacheExpandRects);
+ XAA_STATE_WRAP(FillImageWriteRects);
+ XAA_STATE_WRAP(FillSolidSpans);
+ XAA_STATE_WRAP(FillMono8x8PatternSpans);
+ XAA_STATE_WRAP(FillColor8x8PatternSpans);
+ XAA_STATE_WRAP(FillCacheBltSpans);
+ XAA_STATE_WRAP(FillColorExpandSpans);
+ XAA_STATE_WRAP(FillCacheExpandSpans);
+ XAA_STATE_WRAP(TEGlyphRenderer);
+ XAA_STATE_WRAP(NonTEGlyphRenderer);
+ XAA_STATE_WRAP(WritePixmap);
+ XAA_STATE_WRAP(ReadPixmap);
+ XAA_STATE_WRAP(CopyArea);
+ XAA_STATE_WRAP(CopyPlane);
+ XAA_STATE_WRAP(PushPixelsSolid);
+ XAA_STATE_WRAP(PolyFillRectSolid);
+ XAA_STATE_WRAP(PolyFillRectStippled);
+ XAA_STATE_WRAP(PolyFillRectOpaqueStippled);
+ XAA_STATE_WRAP(PolyFillRectTiled);
+ XAA_STATE_WRAP(FillSpansSolid);
+ XAA_STATE_WRAP(FillSpansStippled);
+ XAA_STATE_WRAP(FillSpansOpaqueStippled);
+ XAA_STATE_WRAP(FillSpansTiled);
+ XAA_STATE_WRAP(PolyText8TE);
+ XAA_STATE_WRAP(PolyText16TE);
+ XAA_STATE_WRAP(ImageText8TE);
+ XAA_STATE_WRAP(ImageText16TE);
+ XAA_STATE_WRAP(ImageGlyphBltTE);
+ XAA_STATE_WRAP(PolyGlyphBltTE);
+ XAA_STATE_WRAP(PolyText8NonTE);
+ XAA_STATE_WRAP(PolyText16NonTE);
+ XAA_STATE_WRAP(ImageText8NonTE);
+ XAA_STATE_WRAP(ImageText16NonTE);
+ XAA_STATE_WRAP(ImageGlyphBltNonTE);
+ XAA_STATE_WRAP(PolyGlyphBltNonTE);
+ XAA_STATE_WRAP(PolyRectangleThinSolid);
+ XAA_STATE_WRAP(PolylinesWideSolid);
+ XAA_STATE_WRAP(PolylinesThinSolid);
+ XAA_STATE_WRAP(PolySegmentThinSolid);
+ XAA_STATE_WRAP(PolylinesThinDashed);
+ XAA_STATE_WRAP(PolySegmentThinDashed);
+ XAA_STATE_WRAP(FillPolygonSolid);
+ XAA_STATE_WRAP(FillPolygonStippled);
+ XAA_STATE_WRAP(FillPolygonOpaqueStippled);
+ XAA_STATE_WRAP(FillPolygonTiled);
+ XAA_STATE_WRAP(PolyFillArcSolid);
+ XAA_STATE_WRAP(PutImage);
+ XAA_STATE_WRAP(ValidateFillSpans);
+ XAA_STATE_WRAP(ValidateSetSpans);
+ XAA_STATE_WRAP(ValidatePutImage);
+ XAA_STATE_WRAP(ValidateCopyArea);
+ XAA_STATE_WRAP(ValidateCopyPlane);
+ XAA_STATE_WRAP(ValidatePolyPoint);
+ XAA_STATE_WRAP(ValidatePolylines);
+ XAA_STATE_WRAP(ValidatePolySegment);
+ XAA_STATE_WRAP(ValidatePolyRectangle);
+ XAA_STATE_WRAP(ValidatePolyArc);
+ XAA_STATE_WRAP(ValidateFillPolygon);
+ XAA_STATE_WRAP(ValidatePolyFillRect);
+ XAA_STATE_WRAP(ValidatePolyFillArc);
+ XAA_STATE_WRAP(ValidatePolyText8);
+ XAA_STATE_WRAP(ValidatePolyText16);
+ XAA_STATE_WRAP(ValidateImageText8);
+ XAA_STATE_WRAP(ValidateImageText16);
+ XAA_STATE_WRAP(ValidatePolyGlyphBlt);
+ XAA_STATE_WRAP(ValidateImageGlyphBlt);
+ XAA_STATE_WRAP(ValidatePushPixels);
+ XAA_STATE_WRAP(ComputeDash);
+ XAA_STATE_WRAP(InitPixmapCache);
+ XAA_STATE_WRAP(ClosePixmapCache);
+ XAA_STATE_WRAP(StippledFillChooser);
+ XAA_STATE_WRAP(OpaqueStippledFillChooser);
+ XAA_STATE_WRAP(TiledFillChooser);
+ XAA_STATE_WRAP(CacheTile);
+ XAA_STATE_WRAP(CacheStipple);
+ XAA_STATE_WRAP(CacheMonoStipple);
+ XAA_STATE_WRAP(CacheMono8x8Pattern);
+ XAA_STATE_WRAP(CacheColor8x8Pattern);
+ XAA_STATE_WRAP(WriteBitmapToCache);
+ XAA_STATE_WRAP(WritePixmapToCache);
+ XAA_STATE_WRAP(WriteMono8x8PatternToCache);
+ XAA_STATE_WRAP(WriteColor8x8PatternToCache);
+ XAA_STATE_WRAP(GetImage);
+ XAA_STATE_WRAP(GetSpans);
+ XAA_STATE_WRAP(CopyWindow);
+ XAA_STATE_WRAP(SetupForCPUToScreenAlphaTexture2);
+ XAA_STATE_WRAP(SetupForCPUToScreenTexture2);
+ return TRUE;
+}
diff --git a/xorg-server/hw/xfree86/xaa/xaaTEGlyph.c b/xorg-server/hw/xfree86/xaa/xaaTEGlyph.c
index 41e638e5c..049bb2cb3 100644
--- a/xorg-server/hw/xfree86/xaa/xaaTEGlyph.c
+++ b/xorg-server/hw/xfree86/xaa/xaaTEGlyph.c
@@ -1,1077 +1,1077 @@
-
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "xaa.h"
-#include "xaalocal.h"
-#include "xaacexp.h"
-#include "xf86.h"
-
-/* scanline function for TRIPLE_BITS_24BPP */
-static CARD32 *DrawTextScanline3(CARD32 *base, CARD32 *mem, int width);
-
-/* Loop unrolled functions for common font widths */
-static CARD32 *DrawTETextScanlineGeneric(CARD32 *base, unsigned int **glyphp,
- int line, int width, int glyphwidth);
-static CARD32 *DrawTETextScanlineWidth7(CARD32 *base, unsigned int **glyphp,
- int line, int width, int glyphwidth);
-static CARD32 *DrawTETextScanlineWidth10(CARD32 *base, unsigned int **glyphp,
- int line, int width, int glyphwidth);
-static CARD32 *DrawTETextScanlineWidth12(CARD32 *base, unsigned int **glyphp,
- int line, int width, int glyphwidth);
-static CARD32 *DrawTETextScanlineWidth14(CARD32 *base, unsigned int **glyphp,
- int line, int width, int glyphwidth);
-static CARD32 *DrawTETextScanlineWidth16(CARD32 *base, unsigned int **glyphp,
- int line, int width, int glyphwidth);
-static CARD32 *DrawTETextScanlineWidth18(CARD32 *base, unsigned int **glyphp,
- int line, int width, int glyphwidth);
-static CARD32 *DrawTETextScanlineWidth24(CARD32 *base, unsigned int **glyphp,
- int line, int width, int glyphwidth);
-
-
-#ifdef USEASSEMBLER
-# ifdef FIXEDBASE
-# ifdef MSBFIRST
-CARD32 *DrawTETextScanlineWidth6PMSBFirstFixedBase(CARD32 *base,
- unsigned int **glyphp, int line, int width, int glyphwidth);
-CARD32 *DrawTETextScanlineWidth8PMSBFirstFixedBase(CARD32 *base,
- unsigned int **glyphp, int line, int width, int glyphwidth);
-CARD32 *DrawTETextScanlineWidth9PMSBFirstFixedBase(CARD32 *base,
- unsigned int **glyphp, int line, int width, int glyphwidth);
-# else
-CARD32 *DrawTETextScanlineWidth6PLSBFirstFixedBase(CARD32 *base,
- unsigned int **glyphp, int line, int width, int glyphwidth);
-CARD32 *DrawTETextScanlineWidth8PLSBFirstFixedBase(CARD32 *base,
- unsigned int **glyphp, int line, int width, int glyphwidth);
-CARD32 *DrawTETextScanlineWidth9PLSBFirstFixedBase(CARD32 *base,
- unsigned int **glyphp, int line, int width, int glyphwidth);
-# endif
-# else
-# ifdef MSBFIRST
-CARD32 *DrawTETextScanlineWidth6PMSBFirst(CARD32 *base, unsigned int **glyphp,
- int line, int width, int glyphwidth);
-CARD32 *DrawTETextScanlineWidth8PMSBFirst(CARD32 *base, unsigned int **glyphp,
- int line, int width, int glyphwidth);
-CARD32 *DrawTETextScanlineWidth9PMSBFirst(CARD32 *base, unsigned int **glyphp,
- int line, int width, int glyphwidth);
-# else
-CARD32 *DrawTETextScanlineWidth6PLSBFirst(CARD32 *base, unsigned int **glyphp,
- int line, int width, int glyphwidth);
-CARD32 *DrawTETextScanlineWidth8PLSBFirst(CARD32 *base, unsigned int **glyphp,
- int line, int width, int glyphwidth);
-CARD32 *DrawTETextScanlineWidth9PLSBFirst(CARD32 *base, unsigned int **glyphp,
- int line, int width, int glyphwidth);
-# endif
-# endif
-#else
-static CARD32 *DrawTETextScanlineWidth6(CARD32 *base, unsigned int **glyphp,
- int line, int width, int glyphwidth);
-static CARD32 *DrawTETextScanlineWidth8(CARD32 *base, unsigned int **glyphp,
- int line, int width, int glyphwidth);
-static CARD32 *DrawTETextScanlineWidth9(CARD32 *base, unsigned int **glyphp,
- int line, int width, int glyphwidth);
-#endif
-
-#define glyph_scanline_func EXPNAME(XAAGlyphScanlineFunc)
-#define glyph_get_scanline_func EXPNAME(XAAGetGlyphScanlineFunc)
-
-
-GlyphScanlineFuncPtr glyph_scanline_func[32] = {
- DrawTETextScanlineGeneric, DrawTETextScanlineGeneric,
- DrawTETextScanlineGeneric, DrawTETextScanlineGeneric,
- DrawTETextScanlineGeneric,
-#ifdef USEASSEMBLER
-# ifdef FIXEDBASE
-# ifdef MSBFIRST
- DrawTETextScanlineWidth6PMSBFirstFixedBase,
- DrawTETextScanlineWidth7,
- DrawTETextScanlineWidth8PMSBFirstFixedBase,
- DrawTETextScanlineWidth9PMSBFirstFixedBase,
-# else
- DrawTETextScanlineWidth6PLSBFirstFixedBase,
- DrawTETextScanlineWidth7,
- DrawTETextScanlineWidth8PLSBFirstFixedBase,
- DrawTETextScanlineWidth9PLSBFirstFixedBase,
-# endif
-# else
-# ifdef MSBFIRST
- DrawTETextScanlineWidth6PMSBFirst,
- DrawTETextScanlineWidth7,
- DrawTETextScanlineWidth8PMSBFirst,
- DrawTETextScanlineWidth9PMSBFirst,
-# else
- DrawTETextScanlineWidth6PLSBFirst,
- DrawTETextScanlineWidth7,
- DrawTETextScanlineWidth8PLSBFirst,
- DrawTETextScanlineWidth9PLSBFirst,
-# endif
-# endif
-#else
- DrawTETextScanlineWidth6, DrawTETextScanlineWidth7,
- DrawTETextScanlineWidth8, DrawTETextScanlineWidth9,
-#endif
- DrawTETextScanlineWidth10,
- DrawTETextScanlineGeneric, DrawTETextScanlineWidth12,
- DrawTETextScanlineGeneric, DrawTETextScanlineWidth14,
- DrawTETextScanlineGeneric, DrawTETextScanlineWidth16,
- DrawTETextScanlineGeneric, DrawTETextScanlineWidth18,
- DrawTETextScanlineGeneric, DrawTETextScanlineGeneric,
- DrawTETextScanlineGeneric, DrawTETextScanlineGeneric,
- DrawTETextScanlineGeneric, DrawTETextScanlineWidth24,
- DrawTETextScanlineGeneric, DrawTETextScanlineGeneric,
- DrawTETextScanlineGeneric, DrawTETextScanlineGeneric,
- DrawTETextScanlineGeneric, DrawTETextScanlineGeneric,
- DrawTETextScanlineGeneric, DrawTETextScanlineGeneric
-};
-
-GlyphScanlineFuncPtr *glyph_get_scanline_func(void) {
- return glyph_scanline_func;
-}
-
-
-/********************************************************************
-
- Here we have TEGlyphRenders for a bunch of different color
- expansion types. The driver may provide its own renderer, but
- this is the default one which renders using lower-level primitives
- exported by the chipset driver.
-
-********************************************************************/
-
-/* This gets built for MSBFIRST or LSBFIRST with FIXEDBASE or not.
- A total of 4 versions */
-
-void
-EXPNAME(XAATEGlyphRenderer)(
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h, int skipleft, int startline,
- unsigned int **glyphs, int glyphWidth,
- int fg, int bg, int rop, unsigned planemask
-)
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
- CARD32* base;
- GlyphScanlineFuncPtr GlyphFunc = glyph_scanline_func[glyphWidth - 1];
- int dwords = 0;
-
- if((bg != -1) && (infoRec->TEGlyphRendererFlags & TRANSPARENCY_ONLY)) {
- (*infoRec->SetupForSolidFill)(pScrn, bg, rop, planemask);
- (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
- bg = -1;
- }
-
- (*infoRec->SetupForCPUToScreenColorExpandFill)(
- pScrn, fg, bg, rop, planemask);
-
- if(skipleft &&
- (!(infoRec->TEGlyphRendererFlags & LEFT_EDGE_CLIPPING) ||
- (!(infoRec->TEGlyphRendererFlags & LEFT_EDGE_CLIPPING_NEGATIVE_X) &&
- (skipleft > x)))) {
- /* draw the first character only */
-
- int count = h, line = startline;
- int width = glyphWidth - skipleft;
-
- if(width > w) width = w;
-
- (*infoRec->SubsequentCPUToScreenColorExpandFill)(
- pScrn, x, y, width, h, 0);
-
- base = (CARD32*)infoRec->ColorExpandBase;
-
- while(count--) {
- register CARD32 tmp = SHIFT_R(glyphs[0][line++],skipleft);
- WRITE_BITS(tmp);
- }
-
- w -= width;
- if((infoRec->TEGlyphRendererFlags & CPU_TRANSFER_PAD_QWORD) &&
- ((((width + 31) >> 5) * h) & 1)) {
- base = (CARD32*)infoRec->ColorExpandBase;
- base[0] = 0x00000000;
- }
- if(!w) goto THE_END;
- glyphs++;
- x += width;
- skipleft = 0; /* nicely aligned again */
- }
-
- w += skipleft;
- x -= skipleft;
- dwords = ((w + 31) >> 5) * h;
-
- (*infoRec->SubsequentCPUToScreenColorExpandFill)(
- pScrn, x, y, w, h, skipleft);
-
- base = (CARD32*)infoRec->ColorExpandBase;
-
-#ifndef FIXEDBASE
- if((((w + 31) >> 5) * h) <= infoRec->ColorExpandRange)
- while(h--) {
- base = (*GlyphFunc)(base, glyphs, startline++, w, glyphWidth);
- }
- else
-#endif
- while(h--) {
- (*GlyphFunc)(base, glyphs, startline++, w, glyphWidth);
- }
-
- if((infoRec->TEGlyphRendererFlags & CPU_TRANSFER_PAD_QWORD) &&
- (dwords & 1)) {
- base = (CARD32*)infoRec->ColorExpandBase;
- base[0] = 0x00000000;
- }
-
-THE_END:
-
- if(infoRec->TEGlyphRendererFlags & SYNC_AFTER_COLOR_EXPAND)
- (*infoRec->Sync)(pScrn);
- else SET_SYNC_FLAG(infoRec);
-}
-
-/********************************************************************
-
- This is the GlyphRenderer for TRIPLE_BITS_24BPP. It renders to a buffer
- with the non FIXEDBASE LSB_FIRST code before tripling, and possibly
- reversing the bits and sending them to the screen
-
-********************************************************************/
-
-void
-EXPNAME(XAATEGlyphRenderer3)(
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h, int skipleft, int startline,
- unsigned int **glyphs, int glyphWidth,
- int fg, int bg, int rop, unsigned planemask
-)
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
- CARD32 *base, *mem;
- GlyphScanlineFuncPtr GlyphFunc = XAAGlyphScanlineFuncLSBFirst[glyphWidth - 1];
- int dwords = 0;
-
- if((bg != -1) &&
- ((infoRec->TEGlyphRendererFlags & TRANSPARENCY_ONLY) ||
- ((infoRec->TEGlyphRendererFlags & RGB_EQUAL) &&
- (!CHECK_RGB_EQUAL(bg))))) {
- (*infoRec->SetupForSolidFill)(pScrn, bg, rop, planemask);
- (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
- bg = -1;
- }
-
- (*infoRec->SetupForCPUToScreenColorExpandFill)(
- pScrn, fg, bg, rop, planemask);
-
- if(skipleft) {
- /* draw the first character only */
-
- int count = h, line = startline;
- int width = glyphWidth - skipleft;
- CARD32 bits;
-
- if(width > w) width = w;
- (*infoRec->SubsequentCPUToScreenColorExpandFill)(
- pScrn, x, y, width, h, 0);
-
- base = (CARD32*)infoRec->ColorExpandBase;
-
- while(count--) {
- bits = SHIFT_R(glyphs[0][line++],skipleft);
- if (width >= 22) {
- WRITE_BITS3(bits);
- } else if (width >= 11) {
- WRITE_BITS2(bits);
- } else {
- WRITE_BITS1(bits);
- }
- }
-
- w -= width;
- if((infoRec->TEGlyphRendererFlags & CPU_TRANSFER_PAD_QWORD) &&
- ((((3 * width + 31) >> 5) * h) & 1)) {
- base = (CARD32*)infoRec->ColorExpandBase;
- base[0] = 0x00000000;
- }
- if(!w) goto THE_END;
- glyphs++;
- x += width;
- skipleft = 0; /* nicely aligned again */
- }
-
- dwords = ((3 * w + 31) >> 5) * h;
- mem = (CARD32*)xalloc(((w + 31) >> 3) * sizeof(char));
- if (!mem) return;
-
- (*infoRec->SubsequentCPUToScreenColorExpandFill)(pScrn, x, y, w, h, 0);
-
- base = (CARD32*)infoRec->ColorExpandBase;
-
-# ifndef FIXEDBASE
- if((((3 * w + 31) >> 5) * h) <= infoRec->ColorExpandRange)
- while(h--) {
- (*GlyphFunc)(mem, glyphs, startline++, w, glyphWidth);
- base = DrawTextScanline3(base, mem, w);
- }
- else
-# endif
- while(h--) {
- (*GlyphFunc)(mem, glyphs, startline++, w, glyphWidth);
- DrawTextScanline3(base, mem, w);
- }
-
- xfree(mem);
-
- if((infoRec->TEGlyphRendererFlags & CPU_TRANSFER_PAD_QWORD) &&
- (dwords & 1)) {
- base = (CARD32*)infoRec->ColorExpandBase;
- base[0] = 0x00000000;
- }
-
-THE_END:
-
- if(infoRec->TEGlyphRendererFlags & SYNC_AFTER_COLOR_EXPAND)
- (*infoRec->Sync)(pScrn);
- else SET_SYNC_FLAG(infoRec);
-}
-
-
-#ifndef FIXEDBASE
-/* Scanline version of above gets built for LSBFIRST and MSBFIRST */
-
-void
-EXPNAME(XAATEGlyphRendererScanline)(
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h, int skipleft, int startline,
- unsigned int **glyphs, int glyphWidth,
- int fg, int bg, int rop, unsigned planemask
-)
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
- int bufferNo;
- CARD32* base;
- GlyphScanlineFuncPtr GlyphFunc = glyph_scanline_func[glyphWidth - 1];
-
- if((bg != -1) && (infoRec->TEGlyphRendererFlags & TRANSPARENCY_ONLY)) {
- (*infoRec->SetupForSolidFill)(pScrn, bg, rop, planemask);
- (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
- bg = -1;
- }
-
- (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(
- pScrn, fg, bg, rop, planemask);
-
- if(skipleft &&
- (!(infoRec->TEGlyphRendererFlags & LEFT_EDGE_CLIPPING) ||
- (!(infoRec->TEGlyphRendererFlags & LEFT_EDGE_CLIPPING_NEGATIVE_X) &&
- (skipleft > x)))) {
- /* draw the first character only */
-
- int count = h, line = startline;
- int width = glyphWidth - skipleft;
-
- if(width > w) width = w;
-
- (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
- pScrn, x, y, width, h, 0);
-
- bufferNo = 0;
-
- while(count--) {
- register CARD32 tmp = SHIFT_R(glyphs[0][line++],skipleft);
- base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo];
- WRITE_BITS(tmp);
- (*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++);
- if(bufferNo >= infoRec->NumScanlineColorExpandBuffers)
- bufferNo = 0;
- }
-
- w -= width;
- if(!w) goto THE_END;
- glyphs++;
- x += width;
- skipleft = 0; /* nicely aligned again */
- }
-
- w += skipleft;
- x -= skipleft;
-
- (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
- pScrn, x, y, w, h, skipleft);
-
- bufferNo = 0;
-
- while(h--) {
- base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo];
- (*GlyphFunc)(base, glyphs, startline++, w, glyphWidth);
- (*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++);
- if(bufferNo >= infoRec->NumScanlineColorExpandBuffers)
- bufferNo = 0;
- }
-
-THE_END:
-
- SET_SYNC_FLAG(infoRec);
-}
-
-void
-EXPNAME(XAATEGlyphRendererScanline3)(
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h, int skipleft, int startline,
- unsigned int **glyphs, int glyphWidth,
- int fg, int bg, int rop, unsigned planemask
-)
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
- int bufferNo;
- CARD32 *base, *mem;
- GlyphScanlineFuncPtr GlyphFunc = XAAGlyphScanlineFuncLSBFirst[glyphWidth - 1];
-
- if((bg != -1) &&
- ((infoRec->TEGlyphRendererFlags & TRANSPARENCY_ONLY) ||
- ((infoRec->TEGlyphRendererFlags & RGB_EQUAL) &&
- (!CHECK_RGB_EQUAL(bg))))) {
- (*infoRec->SetupForSolidFill)(pScrn, bg, rop, planemask);
- (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
- bg = -1;
- }
-
- (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(
- pScrn, fg, bg, rop, planemask);
-
- if(skipleft) {
- /* draw the first character only */
-
- int count = h, line = startline;
- int width = glyphWidth - skipleft;
- CARD32 bits;
-
- if(width > w) width = w;
-
- (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
- pScrn, x, y, width, h, 0);
-
- bufferNo = 0;
-
- while(count--) {
- base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo];
- bits = SHIFT_R(glyphs[0][line++],skipleft);
- if (width >= 22) {
- WRITE_BITS3(bits);
- } else if (width >= 11) {
- WRITE_BITS2(bits);
- } else {
- WRITE_BITS1(bits);
- }
- (*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++);
- if(bufferNo >= infoRec->NumScanlineColorExpandBuffers)
- bufferNo = 0;
- }
-
- w -= width;
- if(!w) goto THE_END;
- glyphs++;
- x += width;
- skipleft = 0; /* nicely aligned again */
- }
-
- w += skipleft;
- x -= skipleft;
- mem = (CARD32*)xalloc(((w + 31) >> 3) * sizeof(char));
- if (!mem) return;
-
- (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
- pScrn, x, y, w, h, skipleft);
-
- bufferNo = 0;
-
- while(h--) {
- base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo];
- (*GlyphFunc)(mem, glyphs, startline++, w, glyphWidth);
- DrawTextScanline3(base, mem, w);
- (*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++);
- if(bufferNo >= infoRec->NumScanlineColorExpandBuffers)
- bufferNo = 0;
- }
-
- xfree(mem);
-
-THE_END:
-
- SET_SYNC_FLAG(infoRec);
-}
-
-#endif
-
-
-
-/********************************************************************
-
- TRIPLE_BITS_24BPP scanline rendering code.
-
-********************************************************************/
-
-
-
-static CARD32*
-DrawTextScanline3(
- CARD32 *base,
- CARD32 *mem,
- int width )
-{
-
- while(width > 32) {
- WRITE_BITS3(*mem);
- mem++;
- width -= 32;
- }
- if(width) {
- if (width >= 22) {
- WRITE_BITS3(*mem);
- } else if (width >= 11) {
- WRITE_BITS2(*mem);
- } else {
- WRITE_BITS1(*mem);
- }
- }
-
- return base;
-}
-
-
-/********************************************************************
-
- Generic TE scanline rendering code.
-
-********************************************************************/
-
-
-
-static CARD32*
-DrawTETextScanlineGeneric(
- CARD32 *base,
- unsigned int **glyphp,
- int line, int width, int glyphwidth )
-{
- CARD32 bits = (*glyphp)[line];
- int shift = glyphwidth;
-
- while(width > 32) {
- while(shift < 32) {
- glyphp++;
- bits |= SHIFT_L((*glyphp)[line], shift);
- shift += glyphwidth;
- }
- WRITE_BITS(bits);
- shift &= 31;
- if(shift)
- bits = SHIFT_R((*glyphp)[line],(glyphwidth - shift));
- else bits = 0;
- width -= 32;
- }
-
- if(width) {
- width -= shift;
- while(width > 0) {
- glyphp++;
- bits |= SHIFT_L((*glyphp)[line],shift);
- shift += glyphwidth;
- width -= glyphwidth;
- }
- WRITE_BITS(bits);
- }
-
- return base;
-}
-
-
-/********************************************************************
-
- Loop unrolled TE font scanline rendering code
-
-********************************************************************/
-
-
-#ifndef USEASSEMBLER
-static CARD32*
-DrawTETextScanlineWidth6(
- CARD32 *base,
- unsigned int **glyphp,
- int line, int width, int glyphwidth )
-{
- while (1) {
- unsigned int bits;
- bits = glyphp[0][line];
- bits |= SHIFT_L(glyphp[1][line],6);
- bits |= SHIFT_L(glyphp[2][line],12);
- bits |= SHIFT_L(glyphp[3][line],18);
- bits |= SHIFT_L(glyphp[4][line],24);
- bits |= SHIFT_L(glyphp[5][line],30);
- WRITE_IN_BITORDER(base, 0, bits);
- CHECKRETURN(1);
- bits = SHIFT_R(glyphp[5][line],2);
- bits |= SHIFT_L(glyphp[6][line],4);
- bits |= SHIFT_L(glyphp[7][line],10);
- bits |= SHIFT_L(glyphp[8][line],16);
- bits |= SHIFT_L(glyphp[9][line],22);
- bits |= SHIFT_L(glyphp[10][line],28);
- WRITE_IN_BITORDER(base, 1, bits);
- CHECKRETURN(2);
- bits = SHIFT_R(glyphp[10][line],4);
- bits |= SHIFT_L(glyphp[11][line],2);
- bits |= SHIFT_L(glyphp[12][line],8);
- bits |= SHIFT_L(glyphp[13][line],14);
- bits |= SHIFT_L(glyphp[14][line],20);
- bits |= SHIFT_L(glyphp[15][line],26);
- WRITE_IN_BITORDER(base, 2, bits);
- CHECKRETURN(3);
-#ifndef FIXEDBASE
- base += 3;
-#endif
- width -= 96;
- glyphp += 16;
- }
- return base;
-}
-#endif
-
-static CARD32*
-DrawTETextScanlineWidth7(
- CARD32 *base,
- unsigned int **glyphp,
- int line, int width, int glyphwidth )
-{
- while (1) {
- unsigned int bits;
- bits = glyphp[0][line];
- bits |= SHIFT_L(glyphp[1][line],7);
- bits |= SHIFT_L(glyphp[2][line],14);
- bits |= SHIFT_L(glyphp[3][line],21);
- bits |= SHIFT_L(glyphp[4][line],28);
- WRITE_IN_BITORDER(base, 0, bits);
- CHECKRETURN(1);
- bits = SHIFT_R(glyphp[4][line],4);
- bits |= SHIFT_L(glyphp[5][line],3);
- bits |= SHIFT_L(glyphp[6][line],10);
- bits |= SHIFT_L(glyphp[7][line],17);
- bits |= SHIFT_L(glyphp[8][line],24);
- bits |= SHIFT_L(glyphp[9][line],31);
- WRITE_IN_BITORDER(base, 1, bits);
- CHECKRETURN(2);
- bits = SHIFT_R(glyphp[9][line],1);
- bits |= SHIFT_L(glyphp[10][line],6);
- bits |= SHIFT_L(glyphp[11][line],13);
- bits |= SHIFT_L(glyphp[12][line],20);
- bits |= SHIFT_L(glyphp[13][line],27);
- WRITE_IN_BITORDER(base, 2, bits);
- CHECKRETURN(3);
- bits = SHIFT_R(glyphp[13][line],5);
- bits |= SHIFT_L(glyphp[14][line],2);
- bits |= SHIFT_L(glyphp[15][line],9);
- bits |= SHIFT_L(glyphp[16][line],16);
- bits |= SHIFT_L(glyphp[17][line],23);
- bits |= SHIFT_L(glyphp[18][line],30);
- WRITE_IN_BITORDER(base, 3, bits);
- CHECKRETURN(4);
- bits = SHIFT_R(glyphp[18][line],2);
- bits |= SHIFT_L(glyphp[19][line],5);
- bits |= SHIFT_L(glyphp[20][line],12);
- bits |= SHIFT_L(glyphp[21][line],19);
- bits |= SHIFT_L(glyphp[22][line],26);
- WRITE_IN_BITORDER(base, 4, bits);
- CHECKRETURN(5);
- bits = SHIFT_R(glyphp[22][line],6);
- bits |= SHIFT_L(glyphp[23][line],1);
- bits |= SHIFT_L(glyphp[24][line],8);
- bits |= SHIFT_L(glyphp[25][line],15);
- bits |= SHIFT_L(glyphp[26][line],22);
- bits |= SHIFT_L(glyphp[27][line],29);
- WRITE_IN_BITORDER(base, 5, bits);
- CHECKRETURN(6);
- bits = SHIFT_R(glyphp[27][line],3);
- bits |= SHIFT_L(glyphp[28][line],4);
- bits |= SHIFT_L(glyphp[29][line],11);
- bits |= SHIFT_L(glyphp[30][line],18);
- bits |= SHIFT_L(glyphp[31][line],25);
- WRITE_IN_BITORDER(base, 6, bits);
- CHECKRETURN(7);
-#ifndef FIXEDBASE
- base += 7;
-#endif
- width -= 224;
- glyphp += 32;
- }
- return base;
-}
-
-
-#ifndef USEASSEMBLER
-static CARD32*
-DrawTETextScanlineWidth8(
- CARD32 *base,
- unsigned int **glyphp,
- int line, int width, int glyphwidth )
-{
- while (1) {
- unsigned int bits;
- bits = glyphp[0][line];
- bits |= SHIFT_L(glyphp[1][line],8);
- bits |= SHIFT_L(glyphp[2][line],16);
- bits |= SHIFT_L(glyphp[3][line],24);
- WRITE_IN_BITORDER(base, 0, bits);
- CHECKRETURN(1);
- bits = glyphp[4][line];
- bits |= SHIFT_L(glyphp[5][line],8);
- bits |= SHIFT_L(glyphp[6][line],16);
- bits |= SHIFT_L(glyphp[7][line],24);
- WRITE_IN_BITORDER(base, 1, bits);
- CHECKRETURN(2);
-#ifndef FIXEDBASE
- base += 2;
-#endif
- width -= 64;
- glyphp += 8;
- }
- return base;
-}
-#endif
-
-#ifndef USEASSEMBLER
-static CARD32*
-DrawTETextScanlineWidth9(
- CARD32 *base,
- unsigned int **glyphp,
- int line, int width, int glyphwidth )
-{
- while (1) {
- unsigned int bits;
- bits = glyphp[0][line];
- bits |= SHIFT_L(glyphp[1][line],9);
- bits |= SHIFT_L(glyphp[2][line],18);
- bits |= SHIFT_L(glyphp[3][line],27);
- WRITE_IN_BITORDER(base, 0, bits);
- CHECKRETURN(1);
- bits = SHIFT_R(glyphp[3][line],5);
- bits |= SHIFT_L(glyphp[4][line],4);
- bits |= SHIFT_L(glyphp[5][line],13);
- bits |= SHIFT_L(glyphp[6][line],22);
- bits |= SHIFT_L(glyphp[7][line],31);
- WRITE_IN_BITORDER(base, 1, bits);
- CHECKRETURN(2);
- bits = SHIFT_R(glyphp[7][line],1);
- bits |= SHIFT_L(glyphp[8][line],8);
- bits |= SHIFT_L(glyphp[9][line],17);
- bits |= SHIFT_L(glyphp[10][line],26);
- WRITE_IN_BITORDER(base, 2, bits);
- CHECKRETURN(3);
- bits = SHIFT_R(glyphp[10][line],6);
- bits |= SHIFT_L(glyphp[11][line],3);
- bits |= SHIFT_L(glyphp[12][line],12);
- bits |= SHIFT_L(glyphp[13][line],21);
- bits |= SHIFT_L(glyphp[14][line],30);
- WRITE_IN_BITORDER(base, 3, bits);
- CHECKRETURN(4);
- bits = SHIFT_R(glyphp[14][line],2);
- bits |= SHIFT_L(glyphp[15][line],7);
- bits |= SHIFT_L(glyphp[16][line],16);
- bits |= SHIFT_L(glyphp[17][line],25);
- WRITE_IN_BITORDER(base, 4, bits);
- CHECKRETURN(5);
- bits = SHIFT_R(glyphp[17][line],7);
- bits |= SHIFT_L(glyphp[18][line],2);
- bits |= SHIFT_L(glyphp[19][line],11);
- bits |= SHIFT_L(glyphp[20][line],20);
- bits |= SHIFT_L(glyphp[21][line],29);
- WRITE_IN_BITORDER(base, 5, bits);
- CHECKRETURN(6);
- bits = SHIFT_R(glyphp[21][line],3);
- bits |= SHIFT_L(glyphp[22][line],6);
- bits |= SHIFT_L(glyphp[23][line],15);
- bits |= SHIFT_L(glyphp[24][line],24);
- WRITE_IN_BITORDER(base, 6, bits);
- CHECKRETURN(7);
- bits = SHIFT_R(glyphp[24][line],8);
- bits |= SHIFT_L(glyphp[25][line],1);
- bits |= SHIFT_L(glyphp[26][line],10);
- bits |= SHIFT_L(glyphp[27][line],19);
- bits |= SHIFT_L(glyphp[28][line],28);
- WRITE_IN_BITORDER(base, 7, bits);
- CHECKRETURN(8);
- bits = SHIFT_R(glyphp[28][line],4);
- bits |= SHIFT_L(glyphp[29][line],5);
- bits |= SHIFT_L(glyphp[30][line],14);
- bits |= SHIFT_L(glyphp[31][line],23);
- WRITE_IN_BITORDER(base, 8, bits);
- CHECKRETURN(9);
-#ifndef FIXEDBASE
- base += 9;
-#endif
- width -= 288;
- glyphp += 32;
- }
- return base;
-}
-#endif
-
-static CARD32*
-DrawTETextScanlineWidth10(
- CARD32 *base,
- unsigned int **glyphp,
- int line, int width, int glyphwidth )
-{
- while (1) {
- unsigned int bits;
- bits = glyphp[0][line];
- bits |= SHIFT_L(glyphp[1][line],10);
- bits |= SHIFT_L(glyphp[2][line],20);
- bits |= SHIFT_L(glyphp[3][line],30);
- WRITE_IN_BITORDER(base, 0, bits);
- CHECKRETURN(1);
- bits = SHIFT_R(glyphp[3][line],2);
- bits |= SHIFT_L(glyphp[4][line],8);
- bits |= SHIFT_L(glyphp[5][line],18);
- bits |= SHIFT_L(glyphp[6][line],28);
- WRITE_IN_BITORDER(base, 1, bits);
- CHECKRETURN(2);
- bits = SHIFT_R(glyphp[6][line],4);
- bits |= SHIFT_L(glyphp[7][line],6);
- bits |= SHIFT_L(glyphp[8][line],16);
- bits |= SHIFT_L(glyphp[9][line],26);
- WRITE_IN_BITORDER(base, 2, bits);
- CHECKRETURN(3);
- bits = SHIFT_R(glyphp[9][line],6);
- bits |= SHIFT_L(glyphp[10][line],4);
- bits |= SHIFT_L(glyphp[11][line],14);
- bits |= SHIFT_L(glyphp[12][line],24);
- WRITE_IN_BITORDER(base, 3, bits);
- CHECKRETURN(4);
- bits = SHIFT_R(glyphp[12][line],8);
- bits |= SHIFT_L(glyphp[13][line],2);
- bits |= SHIFT_L(glyphp[14][line],12);
- bits |= SHIFT_L(glyphp[15][line],22);
- WRITE_IN_BITORDER(base, 4, bits);
- CHECKRETURN(5);
-#ifndef FIXEDBASE
- base += 5;
-#endif
- width -= 160;
- glyphp += 16;
- }
- return base;
-}
-
-static CARD32*
-DrawTETextScanlineWidth12(
- CARD32 *base,
- unsigned int **glyphp,
- int line, int width, int glyphwidth )
-{
- while (1) {
- unsigned int bits;
- bits = glyphp[0][line];
- bits |= SHIFT_L(glyphp[1][line],12);
- bits |= SHIFT_L(glyphp[2][line],24);
- WRITE_IN_BITORDER(base, 0, bits);
- CHECKRETURN(1);
- bits = SHIFT_R(glyphp[2][line],8);
- bits |= SHIFT_L(glyphp[3][line],4);
- bits |= SHIFT_L(glyphp[4][line],16);
- bits |= SHIFT_L(glyphp[5][line],28);
- WRITE_IN_BITORDER(base, 1, bits);
- CHECKRETURN(2);
- bits = SHIFT_R(glyphp[5][line],4);
- bits |= SHIFT_L(glyphp[6][line],8);
- bits |= SHIFT_L(glyphp[7][line],20);
- WRITE_IN_BITORDER(base, 2, bits);
- CHECKRETURN(3);
-#ifndef FIXEDBASE
- base += 3;
-#endif
- width -= 96;
- glyphp += 8;
- }
- return base;
-}
-
-
-
-static CARD32*
-DrawTETextScanlineWidth14(
- CARD32 *base,
- unsigned int **glyphp,
- int line, int width, int glyphwidth )
-{
- while (1) {
- unsigned int bits;
- bits = glyphp[0][line];
- bits |= SHIFT_L(glyphp[1][line],14);
- bits |= SHIFT_L(glyphp[2][line],28);
- WRITE_IN_BITORDER(base, 0, bits);
- CHECKRETURN(1);
- bits = SHIFT_R(glyphp[2][line],4);
- bits |= SHIFT_L(glyphp[3][line],10);
- bits |= SHIFT_L(glyphp[4][line],24);
- WRITE_IN_BITORDER(base, 1, bits);
- CHECKRETURN(2);
- bits = SHIFT_R(glyphp[4][line],8);
- bits |= SHIFT_L(glyphp[5][line],6);
- bits |= SHIFT_L(glyphp[6][line],20);
- WRITE_IN_BITORDER(base, 2, bits);
- CHECKRETURN(3);
- bits = SHIFT_R(glyphp[6][line],12);
- bits |= SHIFT_L(glyphp[7][line],2);
- bits |= SHIFT_L(glyphp[8][line],16);
- bits |= SHIFT_L(glyphp[9][line],30);
- WRITE_IN_BITORDER(base, 3, bits);
- CHECKRETURN(4);
- bits = SHIFT_R(glyphp[9][line],2);
- bits |= SHIFT_L(glyphp[10][line],12);
- bits |= SHIFT_L(glyphp[11][line],26);
- WRITE_IN_BITORDER(base, 4, bits);
- CHECKRETURN(5);
- bits = SHIFT_R(glyphp[11][line],6);
- bits |= SHIFT_L(glyphp[12][line],8);
- bits |= SHIFT_L(glyphp[13][line],22);
- WRITE_IN_BITORDER(base, 5, bits);
- CHECKRETURN(6);
- bits = SHIFT_R(glyphp[13][line],10);
- bits |= SHIFT_L(glyphp[14][line],4);
- bits |= SHIFT_L(glyphp[15][line],18);
- WRITE_IN_BITORDER(base, 6, bits);
- CHECKRETURN(7);
-#ifndef FIXEDBASE
- base += 7;
-#endif
- width -= 224;
- glyphp += 16;
- }
- return base;
-}
-
-
-static CARD32*
-DrawTETextScanlineWidth16(
- CARD32 *base,
- unsigned int **glyphp,
- int line, int width, int glyphwidth )
-{
- while (1) {
- unsigned int bits;
- bits = glyphp[0][line];
- bits |= SHIFT_L(glyphp[1][line],16);
- WRITE_IN_BITORDER(base, 0, bits);
- CHECKRETURN(1);
- bits = glyphp[2][line];
- bits |= SHIFT_L(glyphp[3][line],16);
- WRITE_IN_BITORDER(base, 1, bits);
- CHECKRETURN(2);
- bits = glyphp[4][line];
- bits |= SHIFT_L(glyphp[5][line],16);
- WRITE_IN_BITORDER(base, 2, bits);
- CHECKRETURN(3);
- bits = glyphp[6][line];
- bits |= SHIFT_L(glyphp[7][line],16);
- WRITE_IN_BITORDER(base, 3, bits);
- CHECKRETURN(4);
-#ifndef FIXEDBASE
- base += 4;
-#endif
- width -= 128;
- glyphp += 8;
- }
- return base;
-}
-
-
-
-static CARD32*
-DrawTETextScanlineWidth18(
- CARD32 *base,
- unsigned int **glyphp,
- int line, int width, int glyphwidth )
-{
- while (1) {
- unsigned int bits;
- bits = glyphp[0][line];
- bits |= SHIFT_L(glyphp[1][line],18);
- WRITE_IN_BITORDER(base, 0, bits);
- CHECKRETURN(1);
- bits = SHIFT_R(glyphp[1][line],14);
- bits |= SHIFT_L(glyphp[2][line],4);
- bits |= SHIFT_L(glyphp[3][line],22);
- WRITE_IN_BITORDER(base, 1, bits);
- CHECKRETURN(2);
- bits = SHIFT_R(glyphp[3][line],10);
- bits |= SHIFT_L(glyphp[4][line],8);
- bits |= SHIFT_L(glyphp[5][line],26);
- WRITE_IN_BITORDER(base, 2, bits);
- CHECKRETURN(3);
- bits = SHIFT_R(glyphp[5][line],6);
- bits |= SHIFT_L(glyphp[6][line],12);
- bits |= SHIFT_L(glyphp[7][line],30);
- WRITE_IN_BITORDER(base, 3, bits);
- CHECKRETURN(4);
- bits = SHIFT_R(glyphp[7][line],2);
- bits |= SHIFT_L(glyphp[8][line],16);
- WRITE_IN_BITORDER(base, 4, bits);
- CHECKRETURN(5);
- bits = SHIFT_R(glyphp[8][line],16);
- bits |= SHIFT_L(glyphp[9][line],2);
- bits |= SHIFT_L(glyphp[10][line],20);
- WRITE_IN_BITORDER(base, 5, bits);
- CHECKRETURN(6);
- bits = SHIFT_R(glyphp[10][line],12);
- bits |= SHIFT_L(glyphp[11][line],6);
- bits |= SHIFT_L(glyphp[12][line],24);
- WRITE_IN_BITORDER(base, 6, bits);
- CHECKRETURN(7);
- bits = SHIFT_R(glyphp[12][line],8);
- bits |= SHIFT_L(glyphp[13][line],10);
- bits |= SHIFT_L(glyphp[14][line],28);
- WRITE_IN_BITORDER(base, 7, bits);
- CHECKRETURN(8);
- bits = SHIFT_R(glyphp[14][line],4);
- bits |= SHIFT_L(glyphp[15][line],14);
- WRITE_IN_BITORDER(base, 8, bits);
- CHECKRETURN(9);
-#ifndef FIXEDBASE
- base += 9;
-#endif
- width -= 288;
- glyphp += 16;
- }
- return base;
-}
-
-
-static CARD32*
-DrawTETextScanlineWidth24(
- CARD32 *base,
- unsigned int **glyphp,
- int line, int width, int glyphwidth )
-{
- while (1) {
- unsigned int bits;
- bits = glyphp[0][line];
- bits |= SHIFT_L(glyphp[1][line],24);
- WRITE_IN_BITORDER(base, 0, bits);
- CHECKRETURN(1);
- bits = SHIFT_R(glyphp[1][line],8);
- bits |= SHIFT_L(glyphp[2][line],16);
- WRITE_IN_BITORDER(base, 1, bits);
- CHECKRETURN(2);
- bits = SHIFT_R(glyphp[2][line],16);
- bits |= SHIFT_L(glyphp[3][line],8);
- WRITE_IN_BITORDER(base, 2, bits);
- CHECKRETURN(3);
-#ifndef FIXEDBASE
- base += 3;
-#endif
- width -= 96;
- glyphp += 4;
- }
- return base;
-}
-
-
+
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xaacexp.h"
+#include "xf86.h"
+
+/* scanline function for TRIPLE_BITS_24BPP */
+static CARD32 *DrawTextScanline3(CARD32 *base, CARD32 *mem, int width);
+
+/* Loop unrolled functions for common font widths */
+static CARD32 *DrawTETextScanlineGeneric(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+static CARD32 *DrawTETextScanlineWidth7(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+static CARD32 *DrawTETextScanlineWidth10(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+static CARD32 *DrawTETextScanlineWidth12(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+static CARD32 *DrawTETextScanlineWidth14(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+static CARD32 *DrawTETextScanlineWidth16(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+static CARD32 *DrawTETextScanlineWidth18(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+static CARD32 *DrawTETextScanlineWidth24(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+
+
+#ifdef USEASSEMBLER
+# ifdef FIXEDBASE
+# ifdef MSBFIRST
+CARD32 *DrawTETextScanlineWidth6PMSBFirstFixedBase(CARD32 *base,
+ unsigned int **glyphp, int line, int width, int glyphwidth);
+CARD32 *DrawTETextScanlineWidth8PMSBFirstFixedBase(CARD32 *base,
+ unsigned int **glyphp, int line, int width, int glyphwidth);
+CARD32 *DrawTETextScanlineWidth9PMSBFirstFixedBase(CARD32 *base,
+ unsigned int **glyphp, int line, int width, int glyphwidth);
+# else
+CARD32 *DrawTETextScanlineWidth6PLSBFirstFixedBase(CARD32 *base,
+ unsigned int **glyphp, int line, int width, int glyphwidth);
+CARD32 *DrawTETextScanlineWidth8PLSBFirstFixedBase(CARD32 *base,
+ unsigned int **glyphp, int line, int width, int glyphwidth);
+CARD32 *DrawTETextScanlineWidth9PLSBFirstFixedBase(CARD32 *base,
+ unsigned int **glyphp, int line, int width, int glyphwidth);
+# endif
+# else
+# ifdef MSBFIRST
+CARD32 *DrawTETextScanlineWidth6PMSBFirst(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+CARD32 *DrawTETextScanlineWidth8PMSBFirst(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+CARD32 *DrawTETextScanlineWidth9PMSBFirst(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+# else
+CARD32 *DrawTETextScanlineWidth6PLSBFirst(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+CARD32 *DrawTETextScanlineWidth8PLSBFirst(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+CARD32 *DrawTETextScanlineWidth9PLSBFirst(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+# endif
+# endif
+#else
+static CARD32 *DrawTETextScanlineWidth6(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+static CARD32 *DrawTETextScanlineWidth8(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+static CARD32 *DrawTETextScanlineWidth9(CARD32 *base, unsigned int **glyphp,
+ int line, int width, int glyphwidth);
+#endif
+
+#define glyph_scanline_func EXPNAME(XAAGlyphScanlineFunc)
+#define glyph_get_scanline_func EXPNAME(XAAGetGlyphScanlineFunc)
+
+
+GlyphScanlineFuncPtr glyph_scanline_func[32] = {
+ DrawTETextScanlineGeneric, DrawTETextScanlineGeneric,
+ DrawTETextScanlineGeneric, DrawTETextScanlineGeneric,
+ DrawTETextScanlineGeneric,
+#ifdef USEASSEMBLER
+# ifdef FIXEDBASE
+# ifdef MSBFIRST
+ DrawTETextScanlineWidth6PMSBFirstFixedBase,
+ DrawTETextScanlineWidth7,
+ DrawTETextScanlineWidth8PMSBFirstFixedBase,
+ DrawTETextScanlineWidth9PMSBFirstFixedBase,
+# else
+ DrawTETextScanlineWidth6PLSBFirstFixedBase,
+ DrawTETextScanlineWidth7,
+ DrawTETextScanlineWidth8PLSBFirstFixedBase,
+ DrawTETextScanlineWidth9PLSBFirstFixedBase,
+# endif
+# else
+# ifdef MSBFIRST
+ DrawTETextScanlineWidth6PMSBFirst,
+ DrawTETextScanlineWidth7,
+ DrawTETextScanlineWidth8PMSBFirst,
+ DrawTETextScanlineWidth9PMSBFirst,
+# else
+ DrawTETextScanlineWidth6PLSBFirst,
+ DrawTETextScanlineWidth7,
+ DrawTETextScanlineWidth8PLSBFirst,
+ DrawTETextScanlineWidth9PLSBFirst,
+# endif
+# endif
+#else
+ DrawTETextScanlineWidth6, DrawTETextScanlineWidth7,
+ DrawTETextScanlineWidth8, DrawTETextScanlineWidth9,
+#endif
+ DrawTETextScanlineWidth10,
+ DrawTETextScanlineGeneric, DrawTETextScanlineWidth12,
+ DrawTETextScanlineGeneric, DrawTETextScanlineWidth14,
+ DrawTETextScanlineGeneric, DrawTETextScanlineWidth16,
+ DrawTETextScanlineGeneric, DrawTETextScanlineWidth18,
+ DrawTETextScanlineGeneric, DrawTETextScanlineGeneric,
+ DrawTETextScanlineGeneric, DrawTETextScanlineGeneric,
+ DrawTETextScanlineGeneric, DrawTETextScanlineWidth24,
+ DrawTETextScanlineGeneric, DrawTETextScanlineGeneric,
+ DrawTETextScanlineGeneric, DrawTETextScanlineGeneric,
+ DrawTETextScanlineGeneric, DrawTETextScanlineGeneric,
+ DrawTETextScanlineGeneric, DrawTETextScanlineGeneric
+};
+
+GlyphScanlineFuncPtr *glyph_get_scanline_func(void) {
+ return glyph_scanline_func;
+}
+
+
+/********************************************************************
+
+ Here we have TEGlyphRenders for a bunch of different color
+ expansion types. The driver may provide its own renderer, but
+ this is the default one which renders using lower-level primitives
+ exported by the chipset driver.
+
+********************************************************************/
+
+/* This gets built for MSBFIRST or LSBFIRST with FIXEDBASE or not.
+ A total of 4 versions */
+
+void
+EXPNAME(XAATEGlyphRenderer)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ CARD32* base;
+ GlyphScanlineFuncPtr GlyphFunc = glyph_scanline_func[glyphWidth - 1];
+ int dwords = 0;
+
+ if((bg != -1) && (infoRec->TEGlyphRendererFlags & TRANSPARENCY_ONLY)) {
+ (*infoRec->SetupForSolidFill)(pScrn, bg, rop, planemask);
+ (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
+ bg = -1;
+ }
+
+ (*infoRec->SetupForCPUToScreenColorExpandFill)(
+ pScrn, fg, bg, rop, planemask);
+
+ if(skipleft &&
+ (!(infoRec->TEGlyphRendererFlags & LEFT_EDGE_CLIPPING) ||
+ (!(infoRec->TEGlyphRendererFlags & LEFT_EDGE_CLIPPING_NEGATIVE_X) &&
+ (skipleft > x)))) {
+ /* draw the first character only */
+
+ int count = h, line = startline;
+ int width = glyphWidth - skipleft;
+
+ if(width > w) width = w;
+
+ (*infoRec->SubsequentCPUToScreenColorExpandFill)(
+ pScrn, x, y, width, h, 0);
+
+ base = (CARD32*)infoRec->ColorExpandBase;
+
+ while(count--) {
+ register CARD32 tmp = SHIFT_R(glyphs[0][line++],skipleft);
+ WRITE_BITS(tmp);
+ }
+
+ w -= width;
+ if((infoRec->TEGlyphRendererFlags & CPU_TRANSFER_PAD_QWORD) &&
+ ((((width + 31) >> 5) * h) & 1)) {
+ base = (CARD32*)infoRec->ColorExpandBase;
+ base[0] = 0x00000000;
+ }
+ if(!w) goto THE_END;
+ glyphs++;
+ x += width;
+ skipleft = 0; /* nicely aligned again */
+ }
+
+ w += skipleft;
+ x -= skipleft;
+ dwords = ((w + 31) >> 5) * h;
+
+ (*infoRec->SubsequentCPUToScreenColorExpandFill)(
+ pScrn, x, y, w, h, skipleft);
+
+ base = (CARD32*)infoRec->ColorExpandBase;
+
+#ifndef FIXEDBASE
+ if((((w + 31) >> 5) * h) <= infoRec->ColorExpandRange)
+ while(h--) {
+ base = (*GlyphFunc)(base, glyphs, startline++, w, glyphWidth);
+ }
+ else
+#endif
+ while(h--) {
+ (*GlyphFunc)(base, glyphs, startline++, w, glyphWidth);
+ }
+
+ if((infoRec->TEGlyphRendererFlags & CPU_TRANSFER_PAD_QWORD) &&
+ (dwords & 1)) {
+ base = (CARD32*)infoRec->ColorExpandBase;
+ base[0] = 0x00000000;
+ }
+
+THE_END:
+
+ if(infoRec->TEGlyphRendererFlags & SYNC_AFTER_COLOR_EXPAND)
+ (*infoRec->Sync)(pScrn);
+ else SET_SYNC_FLAG(infoRec);
+}
+
+/********************************************************************
+
+ This is the GlyphRenderer for TRIPLE_BITS_24BPP. It renders to a buffer
+ with the non FIXEDBASE LSB_FIRST code before tripling, and possibly
+ reversing the bits and sending them to the screen
+
+********************************************************************/
+
+void
+EXPNAME(XAATEGlyphRenderer3)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ CARD32 *base, *mem;
+ GlyphScanlineFuncPtr GlyphFunc = XAAGlyphScanlineFuncLSBFirst[glyphWidth - 1];
+ int dwords = 0;
+
+ if((bg != -1) &&
+ ((infoRec->TEGlyphRendererFlags & TRANSPARENCY_ONLY) ||
+ ((infoRec->TEGlyphRendererFlags & RGB_EQUAL) &&
+ (!CHECK_RGB_EQUAL(bg))))) {
+ (*infoRec->SetupForSolidFill)(pScrn, bg, rop, planemask);
+ (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
+ bg = -1;
+ }
+
+ (*infoRec->SetupForCPUToScreenColorExpandFill)(
+ pScrn, fg, bg, rop, planemask);
+
+ if(skipleft) {
+ /* draw the first character only */
+
+ int count = h, line = startline;
+ int width = glyphWidth - skipleft;
+ CARD32 bits;
+
+ if(width > w) width = w;
+ (*infoRec->SubsequentCPUToScreenColorExpandFill)(
+ pScrn, x, y, width, h, 0);
+
+ base = (CARD32*)infoRec->ColorExpandBase;
+
+ while(count--) {
+ bits = SHIFT_R(glyphs[0][line++],skipleft);
+ if (width >= 22) {
+ WRITE_BITS3(bits);
+ } else if (width >= 11) {
+ WRITE_BITS2(bits);
+ } else {
+ WRITE_BITS1(bits);
+ }
+ }
+
+ w -= width;
+ if((infoRec->TEGlyphRendererFlags & CPU_TRANSFER_PAD_QWORD) &&
+ ((((3 * width + 31) >> 5) * h) & 1)) {
+ base = (CARD32*)infoRec->ColorExpandBase;
+ base[0] = 0x00000000;
+ }
+ if(!w) goto THE_END;
+ glyphs++;
+ x += width;
+ skipleft = 0; /* nicely aligned again */
+ }
+
+ dwords = ((3 * w + 31) >> 5) * h;
+ mem = (CARD32*)malloc(((w + 31) >> 3) * sizeof(char));
+ if (!mem) return;
+
+ (*infoRec->SubsequentCPUToScreenColorExpandFill)(pScrn, x, y, w, h, 0);
+
+ base = (CARD32*)infoRec->ColorExpandBase;
+
+# ifndef FIXEDBASE
+ if((((3 * w + 31) >> 5) * h) <= infoRec->ColorExpandRange)
+ while(h--) {
+ (*GlyphFunc)(mem, glyphs, startline++, w, glyphWidth);
+ base = DrawTextScanline3(base, mem, w);
+ }
+ else
+# endif
+ while(h--) {
+ (*GlyphFunc)(mem, glyphs, startline++, w, glyphWidth);
+ DrawTextScanline3(base, mem, w);
+ }
+
+ free(mem);
+
+ if((infoRec->TEGlyphRendererFlags & CPU_TRANSFER_PAD_QWORD) &&
+ (dwords & 1)) {
+ base = (CARD32*)infoRec->ColorExpandBase;
+ base[0] = 0x00000000;
+ }
+
+THE_END:
+
+ if(infoRec->TEGlyphRendererFlags & SYNC_AFTER_COLOR_EXPAND)
+ (*infoRec->Sync)(pScrn);
+ else SET_SYNC_FLAG(infoRec);
+}
+
+
+#ifndef FIXEDBASE
+/* Scanline version of above gets built for LSBFIRST and MSBFIRST */
+
+void
+EXPNAME(XAATEGlyphRendererScanline)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int bufferNo;
+ CARD32* base;
+ GlyphScanlineFuncPtr GlyphFunc = glyph_scanline_func[glyphWidth - 1];
+
+ if((bg != -1) && (infoRec->TEGlyphRendererFlags & TRANSPARENCY_ONLY)) {
+ (*infoRec->SetupForSolidFill)(pScrn, bg, rop, planemask);
+ (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
+ bg = -1;
+ }
+
+ (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(
+ pScrn, fg, bg, rop, planemask);
+
+ if(skipleft &&
+ (!(infoRec->TEGlyphRendererFlags & LEFT_EDGE_CLIPPING) ||
+ (!(infoRec->TEGlyphRendererFlags & LEFT_EDGE_CLIPPING_NEGATIVE_X) &&
+ (skipleft > x)))) {
+ /* draw the first character only */
+
+ int count = h, line = startline;
+ int width = glyphWidth - skipleft;
+
+ if(width > w) width = w;
+
+ (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
+ pScrn, x, y, width, h, 0);
+
+ bufferNo = 0;
+
+ while(count--) {
+ register CARD32 tmp = SHIFT_R(glyphs[0][line++],skipleft);
+ base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo];
+ WRITE_BITS(tmp);
+ (*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++);
+ if(bufferNo >= infoRec->NumScanlineColorExpandBuffers)
+ bufferNo = 0;
+ }
+
+ w -= width;
+ if(!w) goto THE_END;
+ glyphs++;
+ x += width;
+ skipleft = 0; /* nicely aligned again */
+ }
+
+ w += skipleft;
+ x -= skipleft;
+
+ (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
+ pScrn, x, y, w, h, skipleft);
+
+ bufferNo = 0;
+
+ while(h--) {
+ base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo];
+ (*GlyphFunc)(base, glyphs, startline++, w, glyphWidth);
+ (*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++);
+ if(bufferNo >= infoRec->NumScanlineColorExpandBuffers)
+ bufferNo = 0;
+ }
+
+THE_END:
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+void
+EXPNAME(XAATEGlyphRendererScanline3)(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+)
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int bufferNo;
+ CARD32 *base, *mem;
+ GlyphScanlineFuncPtr GlyphFunc = XAAGlyphScanlineFuncLSBFirst[glyphWidth - 1];
+
+ if((bg != -1) &&
+ ((infoRec->TEGlyphRendererFlags & TRANSPARENCY_ONLY) ||
+ ((infoRec->TEGlyphRendererFlags & RGB_EQUAL) &&
+ (!CHECK_RGB_EQUAL(bg))))) {
+ (*infoRec->SetupForSolidFill)(pScrn, bg, rop, planemask);
+ (*infoRec->SubsequentSolidFillRect)(pScrn, x, y, w, h);
+ bg = -1;
+ }
+
+ (*infoRec->SetupForScanlineCPUToScreenColorExpandFill)(
+ pScrn, fg, bg, rop, planemask);
+
+ if(skipleft) {
+ /* draw the first character only */
+
+ int count = h, line = startline;
+ int width = glyphWidth - skipleft;
+ CARD32 bits;
+
+ if(width > w) width = w;
+
+ (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
+ pScrn, x, y, width, h, 0);
+
+ bufferNo = 0;
+
+ while(count--) {
+ base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo];
+ bits = SHIFT_R(glyphs[0][line++],skipleft);
+ if (width >= 22) {
+ WRITE_BITS3(bits);
+ } else if (width >= 11) {
+ WRITE_BITS2(bits);
+ } else {
+ WRITE_BITS1(bits);
+ }
+ (*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++);
+ if(bufferNo >= infoRec->NumScanlineColorExpandBuffers)
+ bufferNo = 0;
+ }
+
+ w -= width;
+ if(!w) goto THE_END;
+ glyphs++;
+ x += width;
+ skipleft = 0; /* nicely aligned again */
+ }
+
+ w += skipleft;
+ x -= skipleft;
+ mem = (CARD32*)malloc(((w + 31) >> 3) * sizeof(char));
+ if (!mem) return;
+
+ (*infoRec->SubsequentScanlineCPUToScreenColorExpandFill)(
+ pScrn, x, y, w, h, skipleft);
+
+ bufferNo = 0;
+
+ while(h--) {
+ base = (CARD32*)infoRec->ScanlineColorExpandBuffers[bufferNo];
+ (*GlyphFunc)(mem, glyphs, startline++, w, glyphWidth);
+ DrawTextScanline3(base, mem, w);
+ (*infoRec->SubsequentColorExpandScanline)(pScrn, bufferNo++);
+ if(bufferNo >= infoRec->NumScanlineColorExpandBuffers)
+ bufferNo = 0;
+ }
+
+ free(mem);
+
+THE_END:
+
+ SET_SYNC_FLAG(infoRec);
+}
+
+#endif
+
+
+
+/********************************************************************
+
+ TRIPLE_BITS_24BPP scanline rendering code.
+
+********************************************************************/
+
+
+
+static CARD32*
+DrawTextScanline3(
+ CARD32 *base,
+ CARD32 *mem,
+ int width )
+{
+
+ while(width > 32) {
+ WRITE_BITS3(*mem);
+ mem++;
+ width -= 32;
+ }
+ if(width) {
+ if (width >= 22) {
+ WRITE_BITS3(*mem);
+ } else if (width >= 11) {
+ WRITE_BITS2(*mem);
+ } else {
+ WRITE_BITS1(*mem);
+ }
+ }
+
+ return base;
+}
+
+
+/********************************************************************
+
+ Generic TE scanline rendering code.
+
+********************************************************************/
+
+
+
+static CARD32*
+DrawTETextScanlineGeneric(
+ CARD32 *base,
+ unsigned int **glyphp,
+ int line, int width, int glyphwidth )
+{
+ CARD32 bits = (*glyphp)[line];
+ int shift = glyphwidth;
+
+ while(width > 32) {
+ while(shift < 32) {
+ glyphp++;
+ bits |= SHIFT_L((*glyphp)[line], shift);
+ shift += glyphwidth;
+ }
+ WRITE_BITS(bits);
+ shift &= 31;
+ if(shift)
+ bits = SHIFT_R((*glyphp)[line],(glyphwidth - shift));
+ else bits = 0;
+ width -= 32;
+ }
+
+ if(width) {
+ width -= shift;
+ while(width > 0) {
+ glyphp++;
+ bits |= SHIFT_L((*glyphp)[line],shift);
+ shift += glyphwidth;
+ width -= glyphwidth;
+ }
+ WRITE_BITS(bits);
+ }
+
+ return base;
+}
+
+
+/********************************************************************
+
+ Loop unrolled TE font scanline rendering code
+
+********************************************************************/
+
+
+#ifndef USEASSEMBLER
+static CARD32*
+DrawTETextScanlineWidth6(
+ CARD32 *base,
+ unsigned int **glyphp,
+ int line, int width, int glyphwidth )
+{
+ while (1) {
+ unsigned int bits;
+ bits = glyphp[0][line];
+ bits |= SHIFT_L(glyphp[1][line],6);
+ bits |= SHIFT_L(glyphp[2][line],12);
+ bits |= SHIFT_L(glyphp[3][line],18);
+ bits |= SHIFT_L(glyphp[4][line],24);
+ bits |= SHIFT_L(glyphp[5][line],30);
+ WRITE_IN_BITORDER(base, 0, bits);
+ CHECKRETURN(1);
+ bits = SHIFT_R(glyphp[5][line],2);
+ bits |= SHIFT_L(glyphp[6][line],4);
+ bits |= SHIFT_L(glyphp[7][line],10);
+ bits |= SHIFT_L(glyphp[8][line],16);
+ bits |= SHIFT_L(glyphp[9][line],22);
+ bits |= SHIFT_L(glyphp[10][line],28);
+ WRITE_IN_BITORDER(base, 1, bits);
+ CHECKRETURN(2);
+ bits = SHIFT_R(glyphp[10][line],4);
+ bits |= SHIFT_L(glyphp[11][line],2);
+ bits |= SHIFT_L(glyphp[12][line],8);
+ bits |= SHIFT_L(glyphp[13][line],14);
+ bits |= SHIFT_L(glyphp[14][line],20);
+ bits |= SHIFT_L(glyphp[15][line],26);
+ WRITE_IN_BITORDER(base, 2, bits);
+ CHECKRETURN(3);
+#ifndef FIXEDBASE
+ base += 3;
+#endif
+ width -= 96;
+ glyphp += 16;
+ }
+ return base;
+}
+#endif
+
+static CARD32*
+DrawTETextScanlineWidth7(
+ CARD32 *base,
+ unsigned int **glyphp,
+ int line, int width, int glyphwidth )
+{
+ while (1) {
+ unsigned int bits;
+ bits = glyphp[0][line];
+ bits |= SHIFT_L(glyphp[1][line],7);
+ bits |= SHIFT_L(glyphp[2][line],14);
+ bits |= SHIFT_L(glyphp[3][line],21);
+ bits |= SHIFT_L(glyphp[4][line],28);
+ WRITE_IN_BITORDER(base, 0, bits);
+ CHECKRETURN(1);
+ bits = SHIFT_R(glyphp[4][line],4);
+ bits |= SHIFT_L(glyphp[5][line],3);
+ bits |= SHIFT_L(glyphp[6][line],10);
+ bits |= SHIFT_L(glyphp[7][line],17);
+ bits |= SHIFT_L(glyphp[8][line],24);
+ bits |= SHIFT_L(glyphp[9][line],31);
+ WRITE_IN_BITORDER(base, 1, bits);
+ CHECKRETURN(2);
+ bits = SHIFT_R(glyphp[9][line],1);
+ bits |= SHIFT_L(glyphp[10][line],6);
+ bits |= SHIFT_L(glyphp[11][line],13);
+ bits |= SHIFT_L(glyphp[12][line],20);
+ bits |= SHIFT_L(glyphp[13][line],27);
+ WRITE_IN_BITORDER(base, 2, bits);
+ CHECKRETURN(3);
+ bits = SHIFT_R(glyphp[13][line],5);
+ bits |= SHIFT_L(glyphp[14][line],2);
+ bits |= SHIFT_L(glyphp[15][line],9);
+ bits |= SHIFT_L(glyphp[16][line],16);
+ bits |= SHIFT_L(glyphp[17][line],23);
+ bits |= SHIFT_L(glyphp[18][line],30);
+ WRITE_IN_BITORDER(base, 3, bits);
+ CHECKRETURN(4);
+ bits = SHIFT_R(glyphp[18][line],2);
+ bits |= SHIFT_L(glyphp[19][line],5);
+ bits |= SHIFT_L(glyphp[20][line],12);
+ bits |= SHIFT_L(glyphp[21][line],19);
+ bits |= SHIFT_L(glyphp[22][line],26);
+ WRITE_IN_BITORDER(base, 4, bits);
+ CHECKRETURN(5);
+ bits = SHIFT_R(glyphp[22][line],6);
+ bits |= SHIFT_L(glyphp[23][line],1);
+ bits |= SHIFT_L(glyphp[24][line],8);
+ bits |= SHIFT_L(glyphp[25][line],15);
+ bits |= SHIFT_L(glyphp[26][line],22);
+ bits |= SHIFT_L(glyphp[27][line],29);
+ WRITE_IN_BITORDER(base, 5, bits);
+ CHECKRETURN(6);
+ bits = SHIFT_R(glyphp[27][line],3);
+ bits |= SHIFT_L(glyphp[28][line],4);
+ bits |= SHIFT_L(glyphp[29][line],11);
+ bits |= SHIFT_L(glyphp[30][line],18);
+ bits |= SHIFT_L(glyphp[31][line],25);
+ WRITE_IN_BITORDER(base, 6, bits);
+ CHECKRETURN(7);
+#ifndef FIXEDBASE
+ base += 7;
+#endif
+ width -= 224;
+ glyphp += 32;
+ }
+ return base;
+}
+
+
+#ifndef USEASSEMBLER
+static CARD32*
+DrawTETextScanlineWidth8(
+ CARD32 *base,
+ unsigned int **glyphp,
+ int line, int width, int glyphwidth )
+{
+ while (1) {
+ unsigned int bits;
+ bits = glyphp[0][line];
+ bits |= SHIFT_L(glyphp[1][line],8);
+ bits |= SHIFT_L(glyphp[2][line],16);
+ bits |= SHIFT_L(glyphp[3][line],24);
+ WRITE_IN_BITORDER(base, 0, bits);
+ CHECKRETURN(1);
+ bits = glyphp[4][line];
+ bits |= SHIFT_L(glyphp[5][line],8);
+ bits |= SHIFT_L(glyphp[6][line],16);
+ bits |= SHIFT_L(glyphp[7][line],24);
+ WRITE_IN_BITORDER(base, 1, bits);
+ CHECKRETURN(2);
+#ifndef FIXEDBASE
+ base += 2;
+#endif
+ width -= 64;
+ glyphp += 8;
+ }
+ return base;
+}
+#endif
+
+#ifndef USEASSEMBLER
+static CARD32*
+DrawTETextScanlineWidth9(
+ CARD32 *base,
+ unsigned int **glyphp,
+ int line, int width, int glyphwidth )
+{
+ while (1) {
+ unsigned int bits;
+ bits = glyphp[0][line];
+ bits |= SHIFT_L(glyphp[1][line],9);
+ bits |= SHIFT_L(glyphp[2][line],18);
+ bits |= SHIFT_L(glyphp[3][line],27);
+ WRITE_IN_BITORDER(base, 0, bits);
+ CHECKRETURN(1);
+ bits = SHIFT_R(glyphp[3][line],5);
+ bits |= SHIFT_L(glyphp[4][line],4);
+ bits |= SHIFT_L(glyphp[5][line],13);
+ bits |= SHIFT_L(glyphp[6][line],22);
+ bits |= SHIFT_L(glyphp[7][line],31);
+ WRITE_IN_BITORDER(base, 1, bits);
+ CHECKRETURN(2);
+ bits = SHIFT_R(glyphp[7][line],1);
+ bits |= SHIFT_L(glyphp[8][line],8);
+ bits |= SHIFT_L(glyphp[9][line],17);
+ bits |= SHIFT_L(glyphp[10][line],26);
+ WRITE_IN_BITORDER(base, 2, bits);
+ CHECKRETURN(3);
+ bits = SHIFT_R(glyphp[10][line],6);
+ bits |= SHIFT_L(glyphp[11][line],3);
+ bits |= SHIFT_L(glyphp[12][line],12);
+ bits |= SHIFT_L(glyphp[13][line],21);
+ bits |= SHIFT_L(glyphp[14][line],30);
+ WRITE_IN_BITORDER(base, 3, bits);
+ CHECKRETURN(4);
+ bits = SHIFT_R(glyphp[14][line],2);
+ bits |= SHIFT_L(glyphp[15][line],7);
+ bits |= SHIFT_L(glyphp[16][line],16);
+ bits |= SHIFT_L(glyphp[17][line],25);
+ WRITE_IN_BITORDER(base, 4, bits);
+ CHECKRETURN(5);
+ bits = SHIFT_R(glyphp[17][line],7);
+ bits |= SHIFT_L(glyphp[18][line],2);
+ bits |= SHIFT_L(glyphp[19][line],11);
+ bits |= SHIFT_L(glyphp[20][line],20);
+ bits |= SHIFT_L(glyphp[21][line],29);
+ WRITE_IN_BITORDER(base, 5, bits);
+ CHECKRETURN(6);
+ bits = SHIFT_R(glyphp[21][line],3);
+ bits |= SHIFT_L(glyphp[22][line],6);
+ bits |= SHIFT_L(glyphp[23][line],15);
+ bits |= SHIFT_L(glyphp[24][line],24);
+ WRITE_IN_BITORDER(base, 6, bits);
+ CHECKRETURN(7);
+ bits = SHIFT_R(glyphp[24][line],8);
+ bits |= SHIFT_L(glyphp[25][line],1);
+ bits |= SHIFT_L(glyphp[26][line],10);
+ bits |= SHIFT_L(glyphp[27][line],19);
+ bits |= SHIFT_L(glyphp[28][line],28);
+ WRITE_IN_BITORDER(base, 7, bits);
+ CHECKRETURN(8);
+ bits = SHIFT_R(glyphp[28][line],4);
+ bits |= SHIFT_L(glyphp[29][line],5);
+ bits |= SHIFT_L(glyphp[30][line],14);
+ bits |= SHIFT_L(glyphp[31][line],23);
+ WRITE_IN_BITORDER(base, 8, bits);
+ CHECKRETURN(9);
+#ifndef FIXEDBASE
+ base += 9;
+#endif
+ width -= 288;
+ glyphp += 32;
+ }
+ return base;
+}
+#endif
+
+static CARD32*
+DrawTETextScanlineWidth10(
+ CARD32 *base,
+ unsigned int **glyphp,
+ int line, int width, int glyphwidth )
+{
+ while (1) {
+ unsigned int bits;
+ bits = glyphp[0][line];
+ bits |= SHIFT_L(glyphp[1][line],10);
+ bits |= SHIFT_L(glyphp[2][line],20);
+ bits |= SHIFT_L(glyphp[3][line],30);
+ WRITE_IN_BITORDER(base, 0, bits);
+ CHECKRETURN(1);
+ bits = SHIFT_R(glyphp[3][line],2);
+ bits |= SHIFT_L(glyphp[4][line],8);
+ bits |= SHIFT_L(glyphp[5][line],18);
+ bits |= SHIFT_L(glyphp[6][line],28);
+ WRITE_IN_BITORDER(base, 1, bits);
+ CHECKRETURN(2);
+ bits = SHIFT_R(glyphp[6][line],4);
+ bits |= SHIFT_L(glyphp[7][line],6);
+ bits |= SHIFT_L(glyphp[8][line],16);
+ bits |= SHIFT_L(glyphp[9][line],26);
+ WRITE_IN_BITORDER(base, 2, bits);
+ CHECKRETURN(3);
+ bits = SHIFT_R(glyphp[9][line],6);
+ bits |= SHIFT_L(glyphp[10][line],4);
+ bits |= SHIFT_L(glyphp[11][line],14);
+ bits |= SHIFT_L(glyphp[12][line],24);
+ WRITE_IN_BITORDER(base, 3, bits);
+ CHECKRETURN(4);
+ bits = SHIFT_R(glyphp[12][line],8);
+ bits |= SHIFT_L(glyphp[13][line],2);
+ bits |= SHIFT_L(glyphp[14][line],12);
+ bits |= SHIFT_L(glyphp[15][line],22);
+ WRITE_IN_BITORDER(base, 4, bits);
+ CHECKRETURN(5);
+#ifndef FIXEDBASE
+ base += 5;
+#endif
+ width -= 160;
+ glyphp += 16;
+ }
+ return base;
+}
+
+static CARD32*
+DrawTETextScanlineWidth12(
+ CARD32 *base,
+ unsigned int **glyphp,
+ int line, int width, int glyphwidth )
+{
+ while (1) {
+ unsigned int bits;
+ bits = glyphp[0][line];
+ bits |= SHIFT_L(glyphp[1][line],12);
+ bits |= SHIFT_L(glyphp[2][line],24);
+ WRITE_IN_BITORDER(base, 0, bits);
+ CHECKRETURN(1);
+ bits = SHIFT_R(glyphp[2][line],8);
+ bits |= SHIFT_L(glyphp[3][line],4);
+ bits |= SHIFT_L(glyphp[4][line],16);
+ bits |= SHIFT_L(glyphp[5][line],28);
+ WRITE_IN_BITORDER(base, 1, bits);
+ CHECKRETURN(2);
+ bits = SHIFT_R(glyphp[5][line],4);
+ bits |= SHIFT_L(glyphp[6][line],8);
+ bits |= SHIFT_L(glyphp[7][line],20);
+ WRITE_IN_BITORDER(base, 2, bits);
+ CHECKRETURN(3);
+#ifndef FIXEDBASE
+ base += 3;
+#endif
+ width -= 96;
+ glyphp += 8;
+ }
+ return base;
+}
+
+
+
+static CARD32*
+DrawTETextScanlineWidth14(
+ CARD32 *base,
+ unsigned int **glyphp,
+ int line, int width, int glyphwidth )
+{
+ while (1) {
+ unsigned int bits;
+ bits = glyphp[0][line];
+ bits |= SHIFT_L(glyphp[1][line],14);
+ bits |= SHIFT_L(glyphp[2][line],28);
+ WRITE_IN_BITORDER(base, 0, bits);
+ CHECKRETURN(1);
+ bits = SHIFT_R(glyphp[2][line],4);
+ bits |= SHIFT_L(glyphp[3][line],10);
+ bits |= SHIFT_L(glyphp[4][line],24);
+ WRITE_IN_BITORDER(base, 1, bits);
+ CHECKRETURN(2);
+ bits = SHIFT_R(glyphp[4][line],8);
+ bits |= SHIFT_L(glyphp[5][line],6);
+ bits |= SHIFT_L(glyphp[6][line],20);
+ WRITE_IN_BITORDER(base, 2, bits);
+ CHECKRETURN(3);
+ bits = SHIFT_R(glyphp[6][line],12);
+ bits |= SHIFT_L(glyphp[7][line],2);
+ bits |= SHIFT_L(glyphp[8][line],16);
+ bits |= SHIFT_L(glyphp[9][line],30);
+ WRITE_IN_BITORDER(base, 3, bits);
+ CHECKRETURN(4);
+ bits = SHIFT_R(glyphp[9][line],2);
+ bits |= SHIFT_L(glyphp[10][line],12);
+ bits |= SHIFT_L(glyphp[11][line],26);
+ WRITE_IN_BITORDER(base, 4, bits);
+ CHECKRETURN(5);
+ bits = SHIFT_R(glyphp[11][line],6);
+ bits |= SHIFT_L(glyphp[12][line],8);
+ bits |= SHIFT_L(glyphp[13][line],22);
+ WRITE_IN_BITORDER(base, 5, bits);
+ CHECKRETURN(6);
+ bits = SHIFT_R(glyphp[13][line],10);
+ bits |= SHIFT_L(glyphp[14][line],4);
+ bits |= SHIFT_L(glyphp[15][line],18);
+ WRITE_IN_BITORDER(base, 6, bits);
+ CHECKRETURN(7);
+#ifndef FIXEDBASE
+ base += 7;
+#endif
+ width -= 224;
+ glyphp += 16;
+ }
+ return base;
+}
+
+
+static CARD32*
+DrawTETextScanlineWidth16(
+ CARD32 *base,
+ unsigned int **glyphp,
+ int line, int width, int glyphwidth )
+{
+ while (1) {
+ unsigned int bits;
+ bits = glyphp[0][line];
+ bits |= SHIFT_L(glyphp[1][line],16);
+ WRITE_IN_BITORDER(base, 0, bits);
+ CHECKRETURN(1);
+ bits = glyphp[2][line];
+ bits |= SHIFT_L(glyphp[3][line],16);
+ WRITE_IN_BITORDER(base, 1, bits);
+ CHECKRETURN(2);
+ bits = glyphp[4][line];
+ bits |= SHIFT_L(glyphp[5][line],16);
+ WRITE_IN_BITORDER(base, 2, bits);
+ CHECKRETURN(3);
+ bits = glyphp[6][line];
+ bits |= SHIFT_L(glyphp[7][line],16);
+ WRITE_IN_BITORDER(base, 3, bits);
+ CHECKRETURN(4);
+#ifndef FIXEDBASE
+ base += 4;
+#endif
+ width -= 128;
+ glyphp += 8;
+ }
+ return base;
+}
+
+
+
+static CARD32*
+DrawTETextScanlineWidth18(
+ CARD32 *base,
+ unsigned int **glyphp,
+ int line, int width, int glyphwidth )
+{
+ while (1) {
+ unsigned int bits;
+ bits = glyphp[0][line];
+ bits |= SHIFT_L(glyphp[1][line],18);
+ WRITE_IN_BITORDER(base, 0, bits);
+ CHECKRETURN(1);
+ bits = SHIFT_R(glyphp[1][line],14);
+ bits |= SHIFT_L(glyphp[2][line],4);
+ bits |= SHIFT_L(glyphp[3][line],22);
+ WRITE_IN_BITORDER(base, 1, bits);
+ CHECKRETURN(2);
+ bits = SHIFT_R(glyphp[3][line],10);
+ bits |= SHIFT_L(glyphp[4][line],8);
+ bits |= SHIFT_L(glyphp[5][line],26);
+ WRITE_IN_BITORDER(base, 2, bits);
+ CHECKRETURN(3);
+ bits = SHIFT_R(glyphp[5][line],6);
+ bits |= SHIFT_L(glyphp[6][line],12);
+ bits |= SHIFT_L(glyphp[7][line],30);
+ WRITE_IN_BITORDER(base, 3, bits);
+ CHECKRETURN(4);
+ bits = SHIFT_R(glyphp[7][line],2);
+ bits |= SHIFT_L(glyphp[8][line],16);
+ WRITE_IN_BITORDER(base, 4, bits);
+ CHECKRETURN(5);
+ bits = SHIFT_R(glyphp[8][line],16);
+ bits |= SHIFT_L(glyphp[9][line],2);
+ bits |= SHIFT_L(glyphp[10][line],20);
+ WRITE_IN_BITORDER(base, 5, bits);
+ CHECKRETURN(6);
+ bits = SHIFT_R(glyphp[10][line],12);
+ bits |= SHIFT_L(glyphp[11][line],6);
+ bits |= SHIFT_L(glyphp[12][line],24);
+ WRITE_IN_BITORDER(base, 6, bits);
+ CHECKRETURN(7);
+ bits = SHIFT_R(glyphp[12][line],8);
+ bits |= SHIFT_L(glyphp[13][line],10);
+ bits |= SHIFT_L(glyphp[14][line],28);
+ WRITE_IN_BITORDER(base, 7, bits);
+ CHECKRETURN(8);
+ bits = SHIFT_R(glyphp[14][line],4);
+ bits |= SHIFT_L(glyphp[15][line],14);
+ WRITE_IN_BITORDER(base, 8, bits);
+ CHECKRETURN(9);
+#ifndef FIXEDBASE
+ base += 9;
+#endif
+ width -= 288;
+ glyphp += 16;
+ }
+ return base;
+}
+
+
+static CARD32*
+DrawTETextScanlineWidth24(
+ CARD32 *base,
+ unsigned int **glyphp,
+ int line, int width, int glyphwidth )
+{
+ while (1) {
+ unsigned int bits;
+ bits = glyphp[0][line];
+ bits |= SHIFT_L(glyphp[1][line],24);
+ WRITE_IN_BITORDER(base, 0, bits);
+ CHECKRETURN(1);
+ bits = SHIFT_R(glyphp[1][line],8);
+ bits |= SHIFT_L(glyphp[2][line],16);
+ WRITE_IN_BITORDER(base, 1, bits);
+ CHECKRETURN(2);
+ bits = SHIFT_R(glyphp[2][line],16);
+ bits |= SHIFT_L(glyphp[3][line],8);
+ WRITE_IN_BITORDER(base, 2, bits);
+ CHECKRETURN(3);
+#ifndef FIXEDBASE
+ base += 3;
+#endif
+ width -= 96;
+ glyphp += 4;
+ }
+ return base;
+}
+
+
diff --git a/xorg-server/hw/xfree86/xaa/xaaTEText.c b/xorg-server/hw/xfree86/xaa/xaaTEText.c
index fc445726f..1e28d3103 100644
--- a/xorg-server/hw/xfree86/xaa/xaaTEText.c
+++ b/xorg-server/hw/xfree86/xaa/xaaTEText.c
@@ -1,312 +1,312 @@
-
-/********************************************************************
-
- In this file we have GC level replacements for PolyText8/16,
- ImageText8/16, ImageGlyphBlt and PolyGlyphBlt for TE (fixed) fonts.
- The idea is that everything in this file is device independent.
- The mentioned GCOps are merely wrappers for XAAGlyphBltTEColorExpansion
- which calculates the boxes containing arbitrarily clipped text
- and passes them to the TEGlyphRenderer which will usually be a lower
- level XAA function which renders these clipped glyphs using
- the basic color expansion functions exported by the chipset driver.
- The TEGlyphRenderer itself may optionally be driver supplied to
- facilitate work-arounds/optimizations at a higher level than usual.
-
- v1.0 - Mark Vojkovich (mvojkovi@ucsd.edu)
-
-
-********************************************************************/
-
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include "misc.h"
-#include "xf86.h"
-#include "xf86_OSproc.h"
-
-#include <X11/X.h>
-#include <X11/fonts/font.h>
-#include "scrnintstr.h"
-#include "dixfontstr.h"
-#include "xf86str.h"
-#include "xaa.h"
-#include "xaalocal.h"
-#include "gcstruct.h"
-#include "pixmapstr.h"
-
-
-static void XAAGlyphBltTEColorExpansion(ScrnInfoPtr pScrn, int xInit,
- int yInit, FontPtr font, int fg, int bg, int rop,
- unsigned int planemask, RegionPtr cclip, int nglyph,
- unsigned char* gBase, CharInfoPtr *ppci);
-
-
-/********************************************************************
-
- GC level replacements for PolyText8/16 and ImageText8/16
- for TE fonts when using color expansion.
-
-********************************************************************/
-
-
-int
-XAAPolyText8TEColorExpansion(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x, int y,
- int count,
- char *chars )
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
- unsigned long n;
-
- (*pGC->font->get_glyphs)(pGC->font, (unsigned long)count,
- (unsigned char *)chars, Linear8Bit, &n, infoRec->CharInfo);
-
- /* we have divorced XAAGlyphBltTEColorExpansion from the drawable */
- if(n) XAAGlyphBltTEColorExpansion(
- infoRec->pScrn, x + pDraw->x, y + pDraw->y,
- pGC->font, pGC->fgPixel, -1, pGC->alu, pGC->planemask,
- pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
-
- return (x + (n * FONTMAXBOUNDS(pGC->font, characterWidth)));
-}
-
-
-int
-XAAPolyText16TEColorExpansion(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x, int y,
- int count,
- unsigned short *chars )
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
- unsigned long n;
-
- (*pGC->font->get_glyphs)(
- pGC->font, (unsigned long)count, (unsigned char *)chars,
- (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
- &n, infoRec->CharInfo);
-
- if(n) XAAGlyphBltTEColorExpansion(
- infoRec->pScrn, x + pDraw->x, y + pDraw->y,
- pGC->font, pGC->fgPixel, -1, pGC->alu, pGC->planemask,
- pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
-
- return (x + (n * FONTMAXBOUNDS(pGC->font, characterWidth)));
-}
-
-
-void
-XAAImageText8TEColorExpansion(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x, int y,
- int count,
- char *chars )
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
- unsigned long n;
-
- if(!REGION_NUM_RECTS(pGC->pCompositeClip))
- return;
-
- (*pGC->font->get_glyphs)(pGC->font, (unsigned long)count,
- (unsigned char *)chars, Linear8Bit, &n, infoRec->CharInfo);
-
- if(n) XAAGlyphBltTEColorExpansion(
- infoRec->pScrn, x + pDraw->x, y + pDraw->y,
- pGC->font, pGC->fgPixel, pGC->bgPixel, GXcopy, pGC->planemask,
- pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
-}
-
-
-void
-XAAImageText16TEColorExpansion(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x, int y,
- int count,
- unsigned short *chars )
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
- unsigned long n;
-
- if(!REGION_NUM_RECTS(pGC->pCompositeClip))
- return;
-
- (*pGC->font->get_glyphs)(
- pGC->font, (unsigned long)count, (unsigned char *)chars,
- (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
- &n, infoRec->CharInfo);
-
- if(n) XAAGlyphBltTEColorExpansion(
- infoRec->pScrn, x + pDraw->x, y + pDraw->y,
- pGC->font, pGC->fgPixel, pGC->bgPixel, GXcopy, pGC->planemask,
- pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
-}
-
-
-
-/********************************************************************
-
- GC level replacements for ImageGlyphBlt and PolyGlyphBlt for
- TE fonts when using color expansion.
-
-********************************************************************/
-
-
-void
-XAAImageGlyphBltTEColorExpansion(
- DrawablePtr pDrawable,
- GCPtr pGC,
- int xInit, int yInit,
- unsigned int nglyph,
- CharInfoPtr *ppci,
- pointer pglyphBase )
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
-
- if(!REGION_NUM_RECTS(pGC->pCompositeClip))
- return;
-
- XAAGlyphBltTEColorExpansion(
- infoRec->pScrn, xInit + pDrawable->x, yInit + pDrawable->y,
- pGC->font, pGC->fgPixel, pGC->bgPixel, GXcopy, pGC->planemask,
- pGC->pCompositeClip, nglyph, (unsigned char*)pglyphBase, ppci);
-}
-
-void
-XAAPolyGlyphBltTEColorExpansion(
- DrawablePtr pDrawable,
- GCPtr pGC,
- int xInit, int yInit,
- unsigned int nglyph,
- CharInfoPtr *ppci,
- pointer pglyphBase )
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
-
- if(!REGION_NUM_RECTS(pGC->pCompositeClip))
- return;
-
- XAAGlyphBltTEColorExpansion(
- infoRec->pScrn, xInit + pDrawable->x, yInit + pDrawable->y,
- pGC->font, pGC->fgPixel, -1, pGC->alu, pGC->planemask,
- pGC->pCompositeClip, nglyph, (unsigned char*)pglyphBase, ppci);
-}
-
-
-
-
-/********************************************************************
-
- XAAGlyphBltTEColorExpansion -
-
- This guy computes the clipped pieces of text and sends it to
- the lower-level function which will handle acceleration of
- arbitrarily clipped text.
-
-********************************************************************/
-
-
-static void
-XAAGlyphBltTEColorExpansion(
- ScrnInfoPtr pScrn,
- int xInit, int yInit,
- FontPtr font,
- int fg, int bg,
- int rop,
- unsigned int planemask,
- RegionPtr cclip,
- int nglyph,
- unsigned char* gBase,
- CharInfoPtr *ppci )
-{
- XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
- int skippix, skipglyphs;
- int Left, Right, Top, Bottom;
- int LeftEdge, RightEdge, ytop, ybot;
- int nbox = REGION_NUM_RECTS(cclip);
- BoxPtr pbox = REGION_RECTS(cclip);
- unsigned int **glyphs = NULL;
- int glyphWidth = FONTMAXBOUNDS(font, characterWidth);
-
- /* find the size of the box */
- Left = xInit;
- Right = Left + (glyphWidth * nglyph);
- Top = yInit - FONTASCENT(font);
- Bottom = yInit + FONTDESCENT(font);
-
- /* get into the first band that may contain part of our string */
- while(nbox && (Top >= pbox->y2)) {
- pbox++; nbox--;
- }
-
- /* stop when the lower edge of the box is beyond our string */
- while(nbox && (Bottom > pbox->y1)) {
- LeftEdge = max(Left, pbox->x1);
- RightEdge = min(Right, pbox->x2);
-
- if(RightEdge > LeftEdge) { /* we have something to draw */
- unsigned int *fallbackBits = NULL;
- ytop = max(Top, pbox->y1);
- ybot = min(Bottom, pbox->y2);
-
- if((skippix = LeftEdge - Left)) {
- skipglyphs = skippix/glyphWidth;
- skippix %= glyphWidth;
- } else skipglyphs = 0;
-
- if(!glyphs) {
- int count;
- glyphs = (unsigned int**)(infoRec->PreAllocMem);
-
- for(count = 0; count < nglyph; count++) {
- glyphs[count] = (unsigned int*)
- FONTGLYPHBITS(gBase,*ppci++);
- if (!glyphs[count]) {
- /* Glyphs with NULL bits do exist in the wild.
- Replace with blank bits in that case */
-
- if (!fallbackBits) {
- int fontHeight = Bottom - Top + 1;
- fallbackBits = xcalloc (glyphWidth * fontHeight, 1);
- if (!fallbackBits)
- return;
- }
- glyphs[count] = fallbackBits;
- }
- }
-
- /* our new unrolled TE code only writes DWORDS at a time
- so it can read up to 6 characters past the last one
- we're displaying */
- glyphs[count + 0] = glyphs[0];
- glyphs[count + 1] = glyphs[0];
- glyphs[count + 2] = glyphs[0];
- glyphs[count + 3] = glyphs[0];
- glyphs[count + 4] = glyphs[0];
- glyphs[count + 5] = glyphs[0];
- }
-
- /* x, y, w, h, skipleft, skiptop, glyphp, glyphWidth, fg, bg, rop, pm */
-
- (*infoRec->TEGlyphRenderer)( pScrn,
- LeftEdge, ytop, RightEdge - LeftEdge, ybot - ytop,
- skippix, ytop - Top, glyphs + skipglyphs, glyphWidth,
- fg, bg, rop, planemask);
-
- if (fallbackBits)
- xfree (fallbackBits);
- }
-
- nbox--; pbox++;
- }
-}
-
-
-
-
+
+/********************************************************************
+
+ In this file we have GC level replacements for PolyText8/16,
+ ImageText8/16, ImageGlyphBlt and PolyGlyphBlt for TE (fixed) fonts.
+ The idea is that everything in this file is device independent.
+ The mentioned GCOps are merely wrappers for XAAGlyphBltTEColorExpansion
+ which calculates the boxes containing arbitrarily clipped text
+ and passes them to the TEGlyphRenderer which will usually be a lower
+ level XAA function which renders these clipped glyphs using
+ the basic color expansion functions exported by the chipset driver.
+ The TEGlyphRenderer itself may optionally be driver supplied to
+ facilitate work-arounds/optimizations at a higher level than usual.
+
+ v1.0 - Mark Vojkovich (mvojkovi@ucsd.edu)
+
+
+********************************************************************/
+
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include "misc.h"
+#include "xf86.h"
+#include "xf86_OSproc.h"
+
+#include <X11/X.h>
+#include <X11/fonts/font.h>
+#include "scrnintstr.h"
+#include "dixfontstr.h"
+#include "xf86str.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+
+
+static void XAAGlyphBltTEColorExpansion(ScrnInfoPtr pScrn, int xInit,
+ int yInit, FontPtr font, int fg, int bg, int rop,
+ unsigned int planemask, RegionPtr cclip, int nglyph,
+ unsigned char* gBase, CharInfoPtr *ppci);
+
+
+/********************************************************************
+
+ GC level replacements for PolyText8/16 and ImageText8/16
+ for TE fonts when using color expansion.
+
+********************************************************************/
+
+
+int
+XAAPolyText8TEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ unsigned long n;
+
+ (*pGC->font->get_glyphs)(pGC->font, (unsigned long)count,
+ (unsigned char *)chars, Linear8Bit, &n, infoRec->CharInfo);
+
+ /* we have divorced XAAGlyphBltTEColorExpansion from the drawable */
+ if(n) XAAGlyphBltTEColorExpansion(
+ infoRec->pScrn, x + pDraw->x, y + pDraw->y,
+ pGC->font, pGC->fgPixel, -1, pGC->alu, pGC->planemask,
+ pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
+
+ return (x + (n * FONTMAXBOUNDS(pGC->font, characterWidth)));
+}
+
+
+int
+XAAPolyText16TEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ unsigned long n;
+
+ (*pGC->font->get_glyphs)(
+ pGC->font, (unsigned long)count, (unsigned char *)chars,
+ (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
+ &n, infoRec->CharInfo);
+
+ if(n) XAAGlyphBltTEColorExpansion(
+ infoRec->pScrn, x + pDraw->x, y + pDraw->y,
+ pGC->font, pGC->fgPixel, -1, pGC->alu, pGC->planemask,
+ pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
+
+ return (x + (n * FONTMAXBOUNDS(pGC->font, characterWidth)));
+}
+
+
+void
+XAAImageText8TEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ unsigned long n;
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ (*pGC->font->get_glyphs)(pGC->font, (unsigned long)count,
+ (unsigned char *)chars, Linear8Bit, &n, infoRec->CharInfo);
+
+ if(n) XAAGlyphBltTEColorExpansion(
+ infoRec->pScrn, x + pDraw->x, y + pDraw->y,
+ pGC->font, pGC->fgPixel, pGC->bgPixel, GXcopy, pGC->planemask,
+ pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
+}
+
+
+void
+XAAImageText16TEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+ unsigned long n;
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ (*pGC->font->get_glyphs)(
+ pGC->font, (unsigned long)count, (unsigned char *)chars,
+ (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit,
+ &n, infoRec->CharInfo);
+
+ if(n) XAAGlyphBltTEColorExpansion(
+ infoRec->pScrn, x + pDraw->x, y + pDraw->y,
+ pGC->font, pGC->fgPixel, pGC->bgPixel, GXcopy, pGC->planemask,
+ pGC->pCompositeClip, n, FONTGLYPHS(pGC->font), infoRec->CharInfo);
+}
+
+
+
+/********************************************************************
+
+ GC level replacements for ImageGlyphBlt and PolyGlyphBlt for
+ TE fonts when using color expansion.
+
+********************************************************************/
+
+
+void
+XAAImageGlyphBltTEColorExpansion(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ XAAGlyphBltTEColorExpansion(
+ infoRec->pScrn, xInit + pDrawable->x, yInit + pDrawable->y,
+ pGC->font, pGC->fgPixel, pGC->bgPixel, GXcopy, pGC->planemask,
+ pGC->pCompositeClip, nglyph, (unsigned char*)pglyphBase, ppci);
+}
+
+void
+XAAPolyGlyphBltTEColorExpansion(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC);
+
+ if(!REGION_NUM_RECTS(pGC->pCompositeClip))
+ return;
+
+ XAAGlyphBltTEColorExpansion(
+ infoRec->pScrn, xInit + pDrawable->x, yInit + pDrawable->y,
+ pGC->font, pGC->fgPixel, -1, pGC->alu, pGC->planemask,
+ pGC->pCompositeClip, nglyph, (unsigned char*)pglyphBase, ppci);
+}
+
+
+
+
+/********************************************************************
+
+ XAAGlyphBltTEColorExpansion -
+
+ This guy computes the clipped pieces of text and sends it to
+ the lower-level function which will handle acceleration of
+ arbitrarily clipped text.
+
+********************************************************************/
+
+
+static void
+XAAGlyphBltTEColorExpansion(
+ ScrnInfoPtr pScrn,
+ int xInit, int yInit,
+ FontPtr font,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask,
+ RegionPtr cclip,
+ int nglyph,
+ unsigned char* gBase,
+ CharInfoPtr *ppci )
+{
+ XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn);
+ int skippix, skipglyphs;
+ int Left, Right, Top, Bottom;
+ int LeftEdge, RightEdge, ytop, ybot;
+ int nbox = REGION_NUM_RECTS(cclip);
+ BoxPtr pbox = REGION_RECTS(cclip);
+ unsigned int **glyphs = NULL;
+ int glyphWidth = FONTMAXBOUNDS(font, characterWidth);
+
+ /* find the size of the box */
+ Left = xInit;
+ Right = Left + (glyphWidth * nglyph);
+ Top = yInit - FONTASCENT(font);
+ Bottom = yInit + FONTDESCENT(font);
+
+ /* get into the first band that may contain part of our string */
+ while(nbox && (Top >= pbox->y2)) {
+ pbox++; nbox--;
+ }
+
+ /* stop when the lower edge of the box is beyond our string */
+ while(nbox && (Bottom > pbox->y1)) {
+ LeftEdge = max(Left, pbox->x1);
+ RightEdge = min(Right, pbox->x2);
+
+ if(RightEdge > LeftEdge) { /* we have something to draw */
+ unsigned int *fallbackBits = NULL;
+ ytop = max(Top, pbox->y1);
+ ybot = min(Bottom, pbox->y2);
+
+ if((skippix = LeftEdge - Left)) {
+ skipglyphs = skippix/glyphWidth;
+ skippix %= glyphWidth;
+ } else skipglyphs = 0;
+
+ if(!glyphs) {
+ int count;
+ glyphs = (unsigned int**)(infoRec->PreAllocMem);
+
+ for(count = 0; count < nglyph; count++) {
+ glyphs[count] = (unsigned int*)
+ FONTGLYPHBITS(gBase,*ppci++);
+ if (!glyphs[count]) {
+ /* Glyphs with NULL bits do exist in the wild.
+ Replace with blank bits in that case */
+
+ if (!fallbackBits) {
+ int fontHeight = Bottom - Top + 1;
+ fallbackBits = calloc(glyphWidth * fontHeight, 1);
+ if (!fallbackBits)
+ return;
+ }
+ glyphs[count] = fallbackBits;
+ }
+ }
+
+ /* our new unrolled TE code only writes DWORDS at a time
+ so it can read up to 6 characters past the last one
+ we're displaying */
+ glyphs[count + 0] = glyphs[0];
+ glyphs[count + 1] = glyphs[0];
+ glyphs[count + 2] = glyphs[0];
+ glyphs[count + 3] = glyphs[0];
+ glyphs[count + 4] = glyphs[0];
+ glyphs[count + 5] = glyphs[0];
+ }
+
+ /* x, y, w, h, skipleft, skiptop, glyphp, glyphWidth, fg, bg, rop, pm */
+
+ (*infoRec->TEGlyphRenderer)( pScrn,
+ LeftEdge, ytop, RightEdge - LeftEdge, ybot - ytop,
+ skippix, ytop - Top, glyphs + skipglyphs, glyphWidth,
+ fg, bg, rop, planemask);
+
+ if (fallbackBits)
+ free(fallbackBits);
+ }
+
+ nbox--; pbox++;
+ }
+}
+
+
+
+
diff --git a/xorg-server/hw/xfree86/xaa/xaaWrapper.c b/xorg-server/hw/xfree86/xaa/xaaWrapper.c
index d6409887c..f709d0b35 100644
--- a/xorg-server/hw/xfree86/xaa/xaaWrapper.c
+++ b/xorg-server/hw/xfree86/xaa/xaaWrapper.c
@@ -1,474 +1,474 @@
-#ifdef HAVE_XORG_CONFIG_H
-#include <xorg-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "scrnintstr.h"
-#include "gcstruct.h"
-#include "glyphstr.h"
-#include "window.h"
-#include "windowstr.h"
-#include "picture.h"
-#include "picturestr.h"
-#include "colormapst.h"
-#include "xaa.h"
-#include "xaalocal.h"
-#include "xaaWrapper.h"
-
-void XAASync(ScreenPtr pScreen);
-
-/* #include "render.h" */
-
-#if 1
-#define COND(pDraw) \
- ((pDraw)->depth \
- != (xaaWrapperGetScrPriv(((DrawablePtr)(pDraw))->pScreen))->depth)
-#else
-#define COND(pDraw) 1
-#endif
-
-static Bool xaaWrapperCreateGC(GCPtr pGC);
-static void xaaWrapperValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDraw);
-static void xaaWrapperDestroyGC(GCPtr pGC);
-static void xaaWrapperChangeGC (GCPtr pGC, unsigned long mask);
-static void xaaWrapperCopyGC (GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
-static void xaaWrapperChangeClip (GCPtr pGC, int type, pointer pvalue, int nrects);
-
-static void xaaWrapperCopyClip(GCPtr pgcDst, GCPtr pgcSrc);
-static void xaaWrapperDestroyClip(GCPtr pGC);
-
-
-static void
-xaaWrapperComposite (CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
- INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask,
- INT16 xDst, INT16 yDst, CARD16 width, CARD16 height);
-static void
-xaaWrapperGlyphs (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
- PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlist,
- GlyphListPtr list, GlyphPtr *glyphs);
-
-
-typedef struct {
- CloseScreenProcPtr CloseScreen;
- CreateScreenResourcesProcPtr CreateScreenResources;
- CreateWindowProcPtr CreateWindow;
- CopyWindowProcPtr CopyWindow;
- WindowExposuresProcPtr WindowExposures;
- CreateGCProcPtr CreateGC;
- CreateColormapProcPtr CreateColormap;
- DestroyColormapProcPtr DestroyColormap;
- InstallColormapProcPtr InstallColormap;
- UninstallColormapProcPtr UninstallColormap;
- ListInstalledColormapsProcPtr ListInstalledColormaps;
- StoreColorsProcPtr StoreColors;
- CompositeProcPtr Composite;
- GlyphsProcPtr Glyphs;
-
- CloseScreenProcPtr wrapCloseScreen;
- CreateScreenResourcesProcPtr wrapCreateScreenResources;
- CreateWindowProcPtr wrapCreateWindow;
- CopyWindowProcPtr wrapCopyWindow;
- WindowExposuresProcPtr wrapWindowExposures;
- CreateGCProcPtr wrapCreateGC;
- CreateColormapProcPtr wrapCreateColormap;
- DestroyColormapProcPtr wrapDestroyColormap;
- InstallColormapProcPtr wrapInstallColormap;
- UninstallColormapProcPtr wrapUninstallColormap;
- ListInstalledColormapsProcPtr wrapListInstalledColormaps;
- StoreColorsProcPtr wrapStoreColors;
- CompositeProcPtr wrapComposite;
- GlyphsProcPtr wrapGlyphs;
- int depth;
-} xaaWrapperScrPrivRec, *xaaWrapperScrPrivPtr;
-
-#define xaaWrapperGetScrPriv(s) ((xaaWrapperScrPrivPtr) \
- dixLookupPrivate(&(s)->devPrivates, xaaWrapperScrPrivateKey))
-#define xaaWrapperScrPriv(s) xaaWrapperScrPrivPtr pScrPriv = xaaWrapperGetScrPriv(s)
-
-#define wrap(priv,real,mem,func) {\
- priv->mem = real->mem; \
- real->mem = func; \
-}
-
-#define unwrap(priv,real,mem) {\
- real->mem = priv->mem; \
-}
-
-#define cond_wrap(priv,cond,real,mem,wrapmem,func) {\
- if (COND(cond)) \
- priv->wrapmem = real->mem; \
- else \
- priv->mem = real->mem; \
- real->mem = func; \
-}
-
-#define cond_unwrap(priv,cond,real,mem,wrapmem) {\
- if (COND(cond)) \
- real->mem = priv->wrapmem; \
- else \
- real->mem = priv->mem; \
-}
-
-#define get(priv,real,func,wrap) \
- priv->wrap = real->func;
-
-typedef struct _xaaWrapperGCPriv {
- GCOps *ops;
- Bool wrap;
- GCFuncs *funcs;
- GCOps *wrapops;
-} xaaWrapperGCPrivRec, *xaaWrapperGCPrivPtr;
-
-#define xaaWrapperGetGCPriv(pGC) ((xaaWrapperGCPrivPtr) \
- dixLookupPrivate(&(pGC)->devPrivates, xaaWrapperGCPrivateKey))
-#define xaaWrapperGCPriv(pGC) xaaWrapperGCPrivPtr pGCPriv = xaaWrapperGetGCPriv(pGC)
-
-
-static int xaaWrapperScrPrivateKeyIndex;
-static DevPrivateKey xaaWrapperScrPrivateKey = &xaaWrapperScrPrivateKeyIndex;
-static int xaaWrapperGCPrivateKeyIndex;
-static DevPrivateKey xaaWrapperGCPrivateKey = &xaaWrapperGCPrivateKeyIndex;
-
-static Bool
-xaaWrapperCreateScreenResources(ScreenPtr pScreen)
-{
- xaaWrapperScrPriv(pScreen);
- Bool ret;
-
- unwrap (pScrPriv,pScreen, CreateScreenResources);
- ret = pScreen->CreateScreenResources(pScreen);
- wrap(pScrPriv,pScreen,CreateScreenResources,xaaWrapperCreateScreenResources);
- return ret;
-}
-
-static Bool
-xaaWrapperCloseScreen (int iScreen, ScreenPtr pScreen)
-{
- xaaWrapperScrPriv(pScreen);
- Bool ret;
-
- unwrap (pScrPriv,pScreen, CloseScreen);
- ret = pScreen->CloseScreen(iScreen,pScreen);
- return TRUE;
-}
-
-static Bool
-xaaWrapperCreateWindow(WindowPtr pWin)
-{
- xaaWrapperScrPriv(pWin->drawable.pScreen);
- Bool ret;
-
- cond_unwrap(pScrPriv, &pWin->drawable, pWin->drawable.pScreen,
- CreateWindow, wrapCreateWindow);
- ret = pWin->drawable.pScreen->CreateWindow(pWin);
- cond_wrap(pScrPriv, &pWin->drawable, pWin->drawable.pScreen, CreateWindow,
- wrapCreateWindow, xaaWrapperCreateWindow);
-
- return ret;
-}
-
-static void
-xaaWrapperCopyWindow(WindowPtr pWin,
- DDXPointRec ptOldOrg,
- RegionPtr prgnSrc)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- xaaWrapperScrPriv(pScreen);
-
- unwrap (pScrPriv, pScreen, CopyWindow);
-#if 0
- if (COND(&pWin->drawable))
- pWin->drawable.pScreen->CopyWindow = pScrPriv->wrapCopyWindow;
-#endif
- pScreen->CopyWindow(pWin, ptOldOrg, prgnSrc);
- wrap(pScrPriv, pScreen, CopyWindow, xaaWrapperCopyWindow);
-}
-
-static void
-xaaWrapperWindowExposures (WindowPtr pWin,
- RegionPtr prgn,
- RegionPtr other_exposed)
-{
- xaaWrapperScrPriv(pWin->drawable.pScreen);
-
- cond_unwrap(pScrPriv, &pWin->drawable, pWin->drawable.pScreen,
- WindowExposures, wrapWindowExposures);
- pWin->drawable.pScreen->WindowExposures(pWin, prgn, other_exposed);
- cond_wrap(pScrPriv, &pWin->drawable, pWin->drawable.pScreen,
- WindowExposures, wrapWindowExposures, xaaWrapperWindowExposures);
-}
-
-static Bool
-xaaWrapperCreateColormap(ColormapPtr pmap)
-{
- xaaWrapperScrPriv(pmap->pScreen);
- Bool ret;
- unwrap(pScrPriv,pmap->pScreen, CreateColormap);
- ret = pmap->pScreen->CreateColormap(pmap);
- wrap(pScrPriv,pmap->pScreen,CreateColormap,xaaWrapperCreateColormap);
-
- return ret;
-}
-
-static void
-xaaWrapperDestroyColormap(ColormapPtr pmap)
-{
- xaaWrapperScrPriv(pmap->pScreen);
- unwrap(pScrPriv,pmap->pScreen, DestroyColormap);
- pmap->pScreen->DestroyColormap(pmap);
- wrap(pScrPriv,pmap->pScreen,DestroyColormap,xaaWrapperDestroyColormap);
-}
-
-static void
-xaaWrapperStoreColors(ColormapPtr pmap, int nColors, xColorItem *pColors)
-{
- xaaWrapperScrPriv(pmap->pScreen);
- unwrap(pScrPriv,pmap->pScreen, StoreColors);
- pmap->pScreen->StoreColors(pmap,nColors,pColors);
- wrap(pScrPriv,pmap->pScreen,StoreColors,xaaWrapperStoreColors);
-}
-
-static void
-xaaWrapperInstallColormap(ColormapPtr pmap)
-{
- xaaWrapperScrPriv(pmap->pScreen);
-
- unwrap(pScrPriv,pmap->pScreen, InstallColormap);
- pmap->pScreen->InstallColormap(pmap);
- wrap(pScrPriv,pmap->pScreen,InstallColormap,xaaWrapperInstallColormap);
-}
-
-static void
-xaaWrapperUninstallColormap(ColormapPtr pmap)
-{
- xaaWrapperScrPriv(pmap->pScreen);
-
- unwrap(pScrPriv,pmap->pScreen, UninstallColormap);
- pmap->pScreen->UninstallColormap(pmap);
- wrap(pScrPriv,pmap->pScreen,UninstallColormap,xaaWrapperUninstallColormap);
-}
-
-static int
-xaaWrapperListInstalledColormaps(ScreenPtr pScreen, Colormap *pCmapIds)
-{
- int n;
- xaaWrapperScrPriv(pScreen);
-
- unwrap(pScrPriv,pScreen, ListInstalledColormaps);
- n = pScreen->ListInstalledColormaps(pScreen, pCmapIds);
- wrap (pScrPriv,pScreen,ListInstalledColormaps,xaaWrapperListInstalledColormaps);
- return n;
-}
-
-Bool
-xaaSetupWrapper(ScreenPtr pScreen, XAAInfoRecPtr infoPtr, int depth, SyncFunc *func)
-{
- Bool ret;
- xaaWrapperScrPrivPtr pScrPriv;
- PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
-
- if (!dixRequestPrivate(xaaWrapperGCPrivateKey, sizeof(xaaWrapperGCPrivRec)))
- return FALSE;
-
- pScrPriv = (xaaWrapperScrPrivPtr) xalloc (sizeof (xaaWrapperScrPrivRec));
- if (!pScrPriv)
- return FALSE;
-
- get (pScrPriv, pScreen, CloseScreen, wrapCloseScreen);
- get (pScrPriv, pScreen, CreateScreenResources, wrapCreateScreenResources);
- get (pScrPriv, pScreen, CreateWindow, wrapCreateWindow);
- get (pScrPriv, pScreen, CopyWindow, wrapCopyWindow);
- get (pScrPriv, pScreen, WindowExposures, wrapWindowExposures);
- get (pScrPriv, pScreen, CreateGC, wrapCreateGC);
- get (pScrPriv, pScreen, CreateColormap, wrapCreateColormap);
- get (pScrPriv, pScreen, DestroyColormap, wrapDestroyColormap);
- get (pScrPriv, pScreen, InstallColormap, wrapInstallColormap);
- get (pScrPriv, pScreen, UninstallColormap, wrapUninstallColormap);
- get (pScrPriv, pScreen, ListInstalledColormaps, wrapListInstalledColormaps);
- get (pScrPriv, pScreen, StoreColors, wrapStoreColors);
- if (ps) {
- get (pScrPriv, ps, Glyphs, wrapGlyphs);
- get (pScrPriv, ps, Composite, wrapComposite);
- }
- if (!(ret = XAAInit(pScreen,infoPtr)))
- return FALSE;
-
- wrap (pScrPriv, pScreen, CloseScreen, xaaWrapperCloseScreen);
- wrap (pScrPriv, pScreen, CreateScreenResources,
- xaaWrapperCreateScreenResources);
- wrap (pScrPriv, pScreen, CreateWindow, xaaWrapperCreateWindow);
- wrap (pScrPriv, pScreen, CopyWindow, xaaWrapperCopyWindow);
- wrap (pScrPriv, pScreen, WindowExposures, xaaWrapperWindowExposures);
- wrap (pScrPriv, pScreen, CreateGC, xaaWrapperCreateGC);
- wrap (pScrPriv, pScreen, CreateColormap, xaaWrapperCreateColormap);
- wrap (pScrPriv, pScreen, DestroyColormap, xaaWrapperDestroyColormap);
- wrap (pScrPriv, pScreen, InstallColormap, xaaWrapperInstallColormap);
- wrap (pScrPriv, pScreen, UninstallColormap, xaaWrapperUninstallColormap);
- wrap (pScrPriv, pScreen, ListInstalledColormaps,
- xaaWrapperListInstalledColormaps);
- wrap (pScrPriv, pScreen, StoreColors, xaaWrapperStoreColors);
-
- if (ps) {
- wrap (pScrPriv, ps, Glyphs, xaaWrapperGlyphs);
- wrap (pScrPriv, ps, Composite, xaaWrapperComposite);
- }
- pScrPriv->depth = depth;
- dixSetPrivate(&pScreen->devPrivates, xaaWrapperScrPrivateKey, pScrPriv);
-
- *func = XAASync;
-
- return ret;
-}
-
-GCFuncs xaaWrapperGCFuncs = {
- xaaWrapperValidateGC, xaaWrapperChangeGC, xaaWrapperCopyGC,
- xaaWrapperDestroyGC, xaaWrapperChangeClip, xaaWrapperDestroyClip,
- xaaWrapperCopyClip
-};
-
-#define XAAWRAPPER_GC_FUNC_PROLOGUE(pGC) \
- xaaWrapperGCPriv(pGC); \
- unwrap(pGCPriv, pGC, funcs); \
- if (pGCPriv->wrap) unwrap(pGCPriv, pGC, ops)
-
-#define XAAWRAPPER_GC_FUNC_EPILOGUE(pGC) \
- wrap(pGCPriv, pGC, funcs, &xaaWrapperGCFuncs); \
- if (pGCPriv->wrap) wrap(pGCPriv, pGC, ops, pGCPriv->wrapops)
-
-static Bool
-xaaWrapperCreateGC(GCPtr pGC)
-{
- ScreenPtr pScreen = pGC->pScreen;
- xaaWrapperScrPriv(pScreen);
- xaaWrapperGCPriv(pGC);
- Bool ret;
-
- unwrap (pScrPriv, pScreen, CreateGC);
- if((ret = (*pScreen->CreateGC) (pGC))) {
- pGCPriv->wrap = FALSE;
- pGCPriv->funcs = pGC->funcs;
- pGCPriv->wrapops = pGC->ops;
- pGC->funcs = &xaaWrapperGCFuncs;
- }
- wrap (pScrPriv, pScreen, CreateGC, xaaWrapperCreateGC);
-
- return ret;
-}
-
-static void
-xaaWrapperValidateGC(
- GCPtr pGC,
- unsigned long changes,
- DrawablePtr pDraw
-){
- XAAWRAPPER_GC_FUNC_PROLOGUE (pGC);
- (*pGC->funcs->ValidateGC)(pGC, changes, pDraw);
-
- if(COND(pDraw))
- pGCPriv->wrap = TRUE;
-
- XAAWRAPPER_GC_FUNC_EPILOGUE (pGC);
-}
-
-static void
-xaaWrapperDestroyGC(GCPtr pGC)
-{
- XAAWRAPPER_GC_FUNC_PROLOGUE (pGC);
- (*pGC->funcs->DestroyGC)(pGC);
- XAAWRAPPER_GC_FUNC_EPILOGUE (pGC);
-}
-
-static void
-xaaWrapperChangeGC (
- GCPtr pGC,
- unsigned long mask
-){
- XAAWRAPPER_GC_FUNC_PROLOGUE (pGC);
- (*pGC->funcs->ChangeGC) (pGC, mask);
- XAAWRAPPER_GC_FUNC_EPILOGUE (pGC);
-}
-
-static void
-xaaWrapperCopyGC (
- GCPtr pGCSrc,
- unsigned long mask,
- GCPtr pGCDst
-){
- XAAWRAPPER_GC_FUNC_PROLOGUE (pGCDst);
- (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
- XAAWRAPPER_GC_FUNC_EPILOGUE (pGCDst);
-}
-
-static void
-xaaWrapperChangeClip (
- GCPtr pGC,
- int type,
- pointer pvalue,
- int nrects
-){
- XAAWRAPPER_GC_FUNC_PROLOGUE (pGC);
- (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
- XAAWRAPPER_GC_FUNC_EPILOGUE (pGC);
-}
-
-static void
-xaaWrapperCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
-{
- XAAWRAPPER_GC_FUNC_PROLOGUE (pgcDst);
- (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
- XAAWRAPPER_GC_FUNC_EPILOGUE (pgcDst);
-}
-
-static void
-xaaWrapperDestroyClip(GCPtr pGC)
-{
- XAAWRAPPER_GC_FUNC_PROLOGUE (pGC);
- (* pGC->funcs->DestroyClip)(pGC);
- XAAWRAPPER_GC_FUNC_EPILOGUE (pGC);
-}
-
-static void
-xaaWrapperComposite (CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
- INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask,
- INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
-{
- ScreenPtr pScreen = pDst->pDrawable->pScreen;
- PictureScreenPtr ps = GetPictureScreen(pScreen);
- xaaWrapperScrPriv(pScreen);
-
- unwrap (pScrPriv, ps, Composite);
- (*ps->Composite) (op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
- xDst, yDst, width, height);
- wrap (pScrPriv, ps, Composite, xaaWrapperComposite);
-}
-
-
-static void
-xaaWrapperGlyphs (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
- PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlist,
- GlyphListPtr list, GlyphPtr *glyphs)
-{
- ScreenPtr pScreen = pDst->pDrawable->pScreen;
- PictureScreenPtr ps = GetPictureScreen(pScreen);
- xaaWrapperScrPriv(pScreen);
-
- unwrap (pScrPriv, ps, Glyphs);
- (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc,
- nlist, list, glyphs);
- wrap (pScrPriv, ps, Glyphs, xaaWrapperGlyphs);
-
-}
-
-void
-XAASync(ScreenPtr pScreen)
-{
- XAAScreenPtr pScreenPriv = (XAAScreenPtr)
- dixLookupPrivate(&pScreen->devPrivates, XAAGetScreenKey());
- XAAInfoRecPtr infoRec = pScreenPriv->AccelInfoRec;
-
- if(infoRec->NeedToSync) {
- (*infoRec->Sync)(infoRec->pScrn);
- infoRec->NeedToSync = FALSE;
- }
-}
+#ifdef HAVE_XORG_CONFIG_H
+#include <xorg-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "glyphstr.h"
+#include "window.h"
+#include "windowstr.h"
+#include "picture.h"
+#include "picturestr.h"
+#include "colormapst.h"
+#include "xaa.h"
+#include "xaalocal.h"
+#include "xaaWrapper.h"
+
+void XAASync(ScreenPtr pScreen);
+
+/* #include "render.h" */
+
+#if 1
+#define COND(pDraw) \
+ ((pDraw)->depth \
+ != (xaaWrapperGetScrPriv(((DrawablePtr)(pDraw))->pScreen))->depth)
+#else
+#define COND(pDraw) 1
+#endif
+
+static Bool xaaWrapperCreateGC(GCPtr pGC);
+static void xaaWrapperValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDraw);
+static void xaaWrapperDestroyGC(GCPtr pGC);
+static void xaaWrapperChangeGC (GCPtr pGC, unsigned long mask);
+static void xaaWrapperCopyGC (GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst);
+static void xaaWrapperChangeClip (GCPtr pGC, int type, pointer pvalue, int nrects);
+
+static void xaaWrapperCopyClip(GCPtr pgcDst, GCPtr pgcSrc);
+static void xaaWrapperDestroyClip(GCPtr pGC);
+
+
+static void
+xaaWrapperComposite (CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
+ INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask,
+ INT16 xDst, INT16 yDst, CARD16 width, CARD16 height);
+static void
+xaaWrapperGlyphs (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+ PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlist,
+ GlyphListPtr list, GlyphPtr *glyphs);
+
+
+typedef struct {
+ CloseScreenProcPtr CloseScreen;
+ CreateScreenResourcesProcPtr CreateScreenResources;
+ CreateWindowProcPtr CreateWindow;
+ CopyWindowProcPtr CopyWindow;
+ WindowExposuresProcPtr WindowExposures;
+ CreateGCProcPtr CreateGC;
+ CreateColormapProcPtr CreateColormap;
+ DestroyColormapProcPtr DestroyColormap;
+ InstallColormapProcPtr InstallColormap;
+ UninstallColormapProcPtr UninstallColormap;
+ ListInstalledColormapsProcPtr ListInstalledColormaps;
+ StoreColorsProcPtr StoreColors;
+ CompositeProcPtr Composite;
+ GlyphsProcPtr Glyphs;
+
+ CloseScreenProcPtr wrapCloseScreen;
+ CreateScreenResourcesProcPtr wrapCreateScreenResources;
+ CreateWindowProcPtr wrapCreateWindow;
+ CopyWindowProcPtr wrapCopyWindow;
+ WindowExposuresProcPtr wrapWindowExposures;
+ CreateGCProcPtr wrapCreateGC;
+ CreateColormapProcPtr wrapCreateColormap;
+ DestroyColormapProcPtr wrapDestroyColormap;
+ InstallColormapProcPtr wrapInstallColormap;
+ UninstallColormapProcPtr wrapUninstallColormap;
+ ListInstalledColormapsProcPtr wrapListInstalledColormaps;
+ StoreColorsProcPtr wrapStoreColors;
+ CompositeProcPtr wrapComposite;
+ GlyphsProcPtr wrapGlyphs;
+ int depth;
+} xaaWrapperScrPrivRec, *xaaWrapperScrPrivPtr;
+
+#define xaaWrapperGetScrPriv(s) ((xaaWrapperScrPrivPtr) \
+ dixLookupPrivate(&(s)->devPrivates, xaaWrapperScrPrivateKey))
+#define xaaWrapperScrPriv(s) xaaWrapperScrPrivPtr pScrPriv = xaaWrapperGetScrPriv(s)
+
+#define wrap(priv,real,mem,func) {\
+ priv->mem = real->mem; \
+ real->mem = func; \
+}
+
+#define unwrap(priv,real,mem) {\
+ real->mem = priv->mem; \
+}
+
+#define cond_wrap(priv,cond,real,mem,wrapmem,func) {\
+ if (COND(cond)) \
+ priv->wrapmem = real->mem; \
+ else \
+ priv->mem = real->mem; \
+ real->mem = func; \
+}
+
+#define cond_unwrap(priv,cond,real,mem,wrapmem) {\
+ if (COND(cond)) \
+ real->mem = priv->wrapmem; \
+ else \
+ real->mem = priv->mem; \
+}
+
+#define get(priv,real,func,wrap) \
+ priv->wrap = real->func;
+
+typedef struct _xaaWrapperGCPriv {
+ GCOps *ops;
+ Bool wrap;
+ GCFuncs *funcs;
+ GCOps *wrapops;
+} xaaWrapperGCPrivRec, *xaaWrapperGCPrivPtr;
+
+#define xaaWrapperGetGCPriv(pGC) ((xaaWrapperGCPrivPtr) \
+ dixLookupPrivate(&(pGC)->devPrivates, xaaWrapperGCPrivateKey))
+#define xaaWrapperGCPriv(pGC) xaaWrapperGCPrivPtr pGCPriv = xaaWrapperGetGCPriv(pGC)
+
+
+static int xaaWrapperScrPrivateKeyIndex;
+static DevPrivateKey xaaWrapperScrPrivateKey = &xaaWrapperScrPrivateKeyIndex;
+static int xaaWrapperGCPrivateKeyIndex;
+static DevPrivateKey xaaWrapperGCPrivateKey = &xaaWrapperGCPrivateKeyIndex;
+
+static Bool
+xaaWrapperCreateScreenResources(ScreenPtr pScreen)
+{
+ xaaWrapperScrPriv(pScreen);
+ Bool ret;
+
+ unwrap (pScrPriv,pScreen, CreateScreenResources);
+ ret = pScreen->CreateScreenResources(pScreen);
+ wrap(pScrPriv,pScreen,CreateScreenResources,xaaWrapperCreateScreenResources);
+ return ret;
+}
+
+static Bool
+xaaWrapperCloseScreen (int iScreen, ScreenPtr pScreen)
+{
+ xaaWrapperScrPriv(pScreen);
+ Bool ret;
+
+ unwrap (pScrPriv,pScreen, CloseScreen);
+ ret = pScreen->CloseScreen(iScreen,pScreen);
+ return TRUE;
+}
+
+static Bool
+xaaWrapperCreateWindow(WindowPtr pWin)
+{
+ xaaWrapperScrPriv(pWin->drawable.pScreen);
+ Bool ret;
+
+ cond_unwrap(pScrPriv, &pWin->drawable, pWin->drawable.pScreen,
+ CreateWindow, wrapCreateWindow);
+ ret = pWin->drawable.pScreen->CreateWindow(pWin);
+ cond_wrap(pScrPriv, &pWin->drawable, pWin->drawable.pScreen, CreateWindow,
+ wrapCreateWindow, xaaWrapperCreateWindow);
+
+ return ret;
+}
+
+static void
+xaaWrapperCopyWindow(WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ xaaWrapperScrPriv(pScreen);
+
+ unwrap (pScrPriv, pScreen, CopyWindow);
+#if 0
+ if (COND(&pWin->drawable))
+ pWin->drawable.pScreen->CopyWindow = pScrPriv->wrapCopyWindow;
+#endif
+ pScreen->CopyWindow(pWin, ptOldOrg, prgnSrc);
+ wrap(pScrPriv, pScreen, CopyWindow, xaaWrapperCopyWindow);
+}
+
+static void
+xaaWrapperWindowExposures (WindowPtr pWin,
+ RegionPtr prgn,
+ RegionPtr other_exposed)
+{
+ xaaWrapperScrPriv(pWin->drawable.pScreen);
+
+ cond_unwrap(pScrPriv, &pWin->drawable, pWin->drawable.pScreen,
+ WindowExposures, wrapWindowExposures);
+ pWin->drawable.pScreen->WindowExposures(pWin, prgn, other_exposed);
+ cond_wrap(pScrPriv, &pWin->drawable, pWin->drawable.pScreen,
+ WindowExposures, wrapWindowExposures, xaaWrapperWindowExposures);
+}
+
+static Bool
+xaaWrapperCreateColormap(ColormapPtr pmap)
+{
+ xaaWrapperScrPriv(pmap->pScreen);
+ Bool ret;
+ unwrap(pScrPriv,pmap->pScreen, CreateColormap);
+ ret = pmap->pScreen->CreateColormap(pmap);
+ wrap(pScrPriv,pmap->pScreen,CreateColormap,xaaWrapperCreateColormap);
+
+ return ret;
+}
+
+static void
+xaaWrapperDestroyColormap(ColormapPtr pmap)
+{
+ xaaWrapperScrPriv(pmap->pScreen);
+ unwrap(pScrPriv,pmap->pScreen, DestroyColormap);
+ pmap->pScreen->DestroyColormap(pmap);
+ wrap(pScrPriv,pmap->pScreen,DestroyColormap,xaaWrapperDestroyColormap);
+}
+
+static void
+xaaWrapperStoreColors(ColormapPtr pmap, int nColors, xColorItem *pColors)
+{
+ xaaWrapperScrPriv(pmap->pScreen);
+ unwrap(pScrPriv,pmap->pScreen, StoreColors);
+ pmap->pScreen->StoreColors(pmap,nColors,pColors);
+ wrap(pScrPriv,pmap->pScreen,StoreColors,xaaWrapperStoreColors);
+}
+
+static void
+xaaWrapperInstallColormap(ColormapPtr pmap)
+{
+ xaaWrapperScrPriv(pmap->pScreen);
+
+ unwrap(pScrPriv,pmap->pScreen, InstallColormap);
+ pmap->pScreen->InstallColormap(pmap);
+ wrap(pScrPriv,pmap->pScreen,InstallColormap,xaaWrapperInstallColormap);
+}
+
+static void
+xaaWrapperUninstallColormap(ColormapPtr pmap)
+{
+ xaaWrapperScrPriv(pmap->pScreen);
+
+ unwrap(pScrPriv,pmap->pScreen, UninstallColormap);
+ pmap->pScreen->UninstallColormap(pmap);
+ wrap(pScrPriv,pmap->pScreen,UninstallColormap,xaaWrapperUninstallColormap);
+}
+
+static int
+xaaWrapperListInstalledColormaps(ScreenPtr pScreen, Colormap *pCmapIds)
+{
+ int n;
+ xaaWrapperScrPriv(pScreen);
+
+ unwrap(pScrPriv,pScreen, ListInstalledColormaps);
+ n = pScreen->ListInstalledColormaps(pScreen, pCmapIds);
+ wrap (pScrPriv,pScreen,ListInstalledColormaps,xaaWrapperListInstalledColormaps);
+ return n;
+}
+
+Bool
+xaaSetupWrapper(ScreenPtr pScreen, XAAInfoRecPtr infoPtr, int depth, SyncFunc *func)
+{
+ Bool ret;
+ xaaWrapperScrPrivPtr pScrPriv;
+ PictureScreenPtr ps = GetPictureScreenIfSet(pScreen);
+
+ if (!dixRequestPrivate(xaaWrapperGCPrivateKey, sizeof(xaaWrapperGCPrivRec)))
+ return FALSE;
+
+ pScrPriv = (xaaWrapperScrPrivPtr) malloc(sizeof (xaaWrapperScrPrivRec));
+ if (!pScrPriv)
+ return FALSE;
+
+ get (pScrPriv, pScreen, CloseScreen, wrapCloseScreen);
+ get (pScrPriv, pScreen, CreateScreenResources, wrapCreateScreenResources);
+ get (pScrPriv, pScreen, CreateWindow, wrapCreateWindow);
+ get (pScrPriv, pScreen, CopyWindow, wrapCopyWindow);
+ get (pScrPriv, pScreen, WindowExposures, wrapWindowExposures);
+ get (pScrPriv, pScreen, CreateGC, wrapCreateGC);
+ get (pScrPriv, pScreen, CreateColormap, wrapCreateColormap);
+ get (pScrPriv, pScreen, DestroyColormap, wrapDestroyColormap);
+ get (pScrPriv, pScreen, InstallColormap, wrapInstallColormap);
+ get (pScrPriv, pScreen, UninstallColormap, wrapUninstallColormap);
+ get (pScrPriv, pScreen, ListInstalledColormaps, wrapListInstalledColormaps);
+ get (pScrPriv, pScreen, StoreColors, wrapStoreColors);
+ if (ps) {
+ get (pScrPriv, ps, Glyphs, wrapGlyphs);
+ get (pScrPriv, ps, Composite, wrapComposite);
+ }
+ if (!(ret = XAAInit(pScreen,infoPtr)))
+ return FALSE;
+
+ wrap (pScrPriv, pScreen, CloseScreen, xaaWrapperCloseScreen);
+ wrap (pScrPriv, pScreen, CreateScreenResources,
+ xaaWrapperCreateScreenResources);
+ wrap (pScrPriv, pScreen, CreateWindow, xaaWrapperCreateWindow);
+ wrap (pScrPriv, pScreen, CopyWindow, xaaWrapperCopyWindow);
+ wrap (pScrPriv, pScreen, WindowExposures, xaaWrapperWindowExposures);
+ wrap (pScrPriv, pScreen, CreateGC, xaaWrapperCreateGC);
+ wrap (pScrPriv, pScreen, CreateColormap, xaaWrapperCreateColormap);
+ wrap (pScrPriv, pScreen, DestroyColormap, xaaWrapperDestroyColormap);
+ wrap (pScrPriv, pScreen, InstallColormap, xaaWrapperInstallColormap);
+ wrap (pScrPriv, pScreen, UninstallColormap, xaaWrapperUninstallColormap);
+ wrap (pScrPriv, pScreen, ListInstalledColormaps,
+ xaaWrapperListInstalledColormaps);
+ wrap (pScrPriv, pScreen, StoreColors, xaaWrapperStoreColors);
+
+ if (ps) {
+ wrap (pScrPriv, ps, Glyphs, xaaWrapperGlyphs);
+ wrap (pScrPriv, ps, Composite, xaaWrapperComposite);
+ }
+ pScrPriv->depth = depth;
+ dixSetPrivate(&pScreen->devPrivates, xaaWrapperScrPrivateKey, pScrPriv);
+
+ *func = XAASync;
+
+ return ret;
+}
+
+GCFuncs xaaWrapperGCFuncs = {
+ xaaWrapperValidateGC, xaaWrapperChangeGC, xaaWrapperCopyGC,
+ xaaWrapperDestroyGC, xaaWrapperChangeClip, xaaWrapperDestroyClip,
+ xaaWrapperCopyClip
+};
+
+#define XAAWRAPPER_GC_FUNC_PROLOGUE(pGC) \
+ xaaWrapperGCPriv(pGC); \
+ unwrap(pGCPriv, pGC, funcs); \
+ if (pGCPriv->wrap) unwrap(pGCPriv, pGC, ops)
+
+#define XAAWRAPPER_GC_FUNC_EPILOGUE(pGC) \
+ wrap(pGCPriv, pGC, funcs, &xaaWrapperGCFuncs); \
+ if (pGCPriv->wrap) wrap(pGCPriv, pGC, ops, pGCPriv->wrapops)
+
+static Bool
+xaaWrapperCreateGC(GCPtr pGC)
+{
+ ScreenPtr pScreen = pGC->pScreen;
+ xaaWrapperScrPriv(pScreen);
+ xaaWrapperGCPriv(pGC);
+ Bool ret;
+
+ unwrap (pScrPriv, pScreen, CreateGC);
+ if((ret = (*pScreen->CreateGC) (pGC))) {
+ pGCPriv->wrap = FALSE;
+ pGCPriv->funcs = pGC->funcs;
+ pGCPriv->wrapops = pGC->ops;
+ pGC->funcs = &xaaWrapperGCFuncs;
+ }
+ wrap (pScrPriv, pScreen, CreateGC, xaaWrapperCreateGC);
+
+ return ret;
+}
+
+static void
+xaaWrapperValidateGC(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+){
+ XAAWRAPPER_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->ValidateGC)(pGC, changes, pDraw);
+
+ if(COND(pDraw))
+ pGCPriv->wrap = TRUE;
+
+ XAAWRAPPER_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+xaaWrapperDestroyGC(GCPtr pGC)
+{
+ XAAWRAPPER_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->DestroyGC)(pGC);
+ XAAWRAPPER_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+xaaWrapperChangeGC (
+ GCPtr pGC,
+ unsigned long mask
+){
+ XAAWRAPPER_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->ChangeGC) (pGC, mask);
+ XAAWRAPPER_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+xaaWrapperCopyGC (
+ GCPtr pGCSrc,
+ unsigned long mask,
+ GCPtr pGCDst
+){
+ XAAWRAPPER_GC_FUNC_PROLOGUE (pGCDst);
+ (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst);
+ XAAWRAPPER_GC_FUNC_EPILOGUE (pGCDst);
+}
+
+static void
+xaaWrapperChangeClip (
+ GCPtr pGC,
+ int type,
+ pointer pvalue,
+ int nrects
+){
+ XAAWRAPPER_GC_FUNC_PROLOGUE (pGC);
+ (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects);
+ XAAWRAPPER_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+xaaWrapperCopyClip(GCPtr pgcDst, GCPtr pgcSrc)
+{
+ XAAWRAPPER_GC_FUNC_PROLOGUE (pgcDst);
+ (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
+ XAAWRAPPER_GC_FUNC_EPILOGUE (pgcDst);
+}
+
+static void
+xaaWrapperDestroyClip(GCPtr pGC)
+{
+ XAAWRAPPER_GC_FUNC_PROLOGUE (pGC);
+ (* pGC->funcs->DestroyClip)(pGC);
+ XAAWRAPPER_GC_FUNC_EPILOGUE (pGC);
+}
+
+static void
+xaaWrapperComposite (CARD8 op, PicturePtr pSrc, PicturePtr pMask, PicturePtr pDst,
+ INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask,
+ INT16 xDst, INT16 yDst, CARD16 width, CARD16 height)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ xaaWrapperScrPriv(pScreen);
+
+ unwrap (pScrPriv, ps, Composite);
+ (*ps->Composite) (op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask,
+ xDst, yDst, width, height);
+ wrap (pScrPriv, ps, Composite, xaaWrapperComposite);
+}
+
+
+static void
+xaaWrapperGlyphs (CARD8 op, PicturePtr pSrc, PicturePtr pDst,
+ PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlist,
+ GlyphListPtr list, GlyphPtr *glyphs)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+ xaaWrapperScrPriv(pScreen);
+
+ unwrap (pScrPriv, ps, Glyphs);
+ (*ps->Glyphs) (op, pSrc, pDst, maskFormat, xSrc, ySrc,
+ nlist, list, glyphs);
+ wrap (pScrPriv, ps, Glyphs, xaaWrapperGlyphs);
+
+}
+
+void
+XAASync(ScreenPtr pScreen)
+{
+ XAAScreenPtr pScreenPriv = (XAAScreenPtr)
+ dixLookupPrivate(&pScreen->devPrivates, XAAGetScreenKey());
+ XAAInfoRecPtr infoRec = pScreenPriv->AccelInfoRec;
+
+ if(infoRec->NeedToSync) {
+ (*infoRec->Sync)(infoRec->pScrn);
+ infoRec->NeedToSync = FALSE;
+ }
+}
diff --git a/xorg-server/hw/xfree86/xaa/xaalocal.h b/xorg-server/hw/xfree86/xaa/xaalocal.h
index 129c1d6c4..6c492c013 100644
--- a/xorg-server/hw/xfree86/xaa/xaalocal.h
+++ b/xorg-server/hw/xfree86/xaa/xaalocal.h
@@ -1,1755 +1,1755 @@
-
-#ifndef _XAALOCAL_H
-#define _XAALOCAL_H
-
-/* This file is very unorganized ! */
-
-
-#include "gcstruct.h"
-#include "regionstr.h"
-#include "xf86fbman.h"
-#include "xaa.h"
-#include "mi.h"
-#include "picturestr.h"
-
-#define GCWhenForced (GCArcMode << 1)
-
-#define DO_COLOR_8x8 0x00000001
-#define DO_MONO_8x8 0x00000002
-#define DO_CACHE_BLT 0x00000003
-#define DO_COLOR_EXPAND 0x00000004
-#define DO_CACHE_EXPAND 0x00000005
-#define DO_IMAGE_WRITE 0x00000006
-#define DO_PIXMAP_COPY 0x00000007
-#define DO_SOLID 0x00000008
-
-
-typedef CARD32 * (*GlyphScanlineFuncPtr)(
- CARD32 *base, unsigned int **glyphp, int line, int nglyph, int width
-);
-
-typedef CARD32 *(*StippleScanlineProcPtr)(CARD32*, CARD32*, int, int, int);
-
-typedef void (*RectFuncPtr) (ScrnInfoPtr, int, int, int, int, int, int,
- XAACacheInfoPtr);
-typedef void (*TrapFuncPtr) (ScrnInfoPtr, int, int, int, int, int, int,
- int, int, int, int, int, int,
- XAACacheInfoPtr);
-
-
-
-typedef struct _XAAScreen {
- CreateGCProcPtr CreateGC;
- CloseScreenProcPtr CloseScreen;
- GetImageProcPtr GetImage;
- GetSpansProcPtr GetSpans;
- CopyWindowProcPtr CopyWindow;
- WindowExposuresProcPtr WindowExposures;
- CreatePixmapProcPtr CreatePixmap;
- DestroyPixmapProcPtr DestroyPixmap;
- ChangeWindowAttributesProcPtr ChangeWindowAttributes;
- XAAInfoRecPtr AccelInfoRec;
- Bool (*EnterVT)(int, int);
- void (*LeaveVT)(int, int);
- int (*SetDGAMode)(int, int, DGADevicePtr);
- void (*EnableDisableFBAccess)(int, Bool);
- CompositeProcPtr Composite;
- GlyphsProcPtr Glyphs;
-} XAAScreenRec, *XAAScreenPtr;
-
-#define OPS_ARE_PIXMAP 0x00000001
-#define OPS_ARE_ACCEL 0x00000002
-
-typedef struct _XAAGC {
- GCOps *wrapOps;
- GCFuncs *wrapFuncs;
- GCOps *XAAOps;
- int DashLength;
- unsigned char* DashPattern;
- unsigned long changes;
- unsigned long flags;
-} XAAGCRec, *XAAGCPtr;
-
-#define REDUCIBILITY_CHECKED 0x00000001
-#define REDUCIBLE_TO_8x8 0x00000002
-#define REDUCIBLE_TO_2_COLOR 0x00000004
-#define DIRTY 0x00010000
-#define OFFSCREEN 0x00020000
-#define DGA_PIXMAP 0x00040000
-#define SHARED_PIXMAP 0x00080000
-#define LOCKED_PIXMAP 0x00100000
-
-#define REDUCIBILITY_MASK \
- (REDUCIBILITY_CHECKED | REDUCIBLE_TO_8x8 | REDUCIBLE_TO_2_COLOR)
-
-typedef struct _XAAPixmap {
- unsigned long flags;
- CARD32 pattern0;
- CARD32 pattern1;
- int fg;
- int bg;
- FBAreaPtr offscreenArea;
- Bool freeData;
-} XAAPixmapRec, *XAAPixmapPtr;
-
-
-extern _X_EXPORT Bool
-XAACreateGC(
- GCPtr pGC
-);
-
-extern _X_EXPORT Bool
-XAAInitAccel(
- ScreenPtr pScreen,
- XAAInfoRecPtr infoRec
-);
-
-extern _X_EXPORT RegionPtr
-XAABitBlt(
- DrawablePtr pSrcDrawable,
- DrawablePtr pDstDrawable,
- GC *pGC,
- int srcx,
- int srcy,
- int width,
- int height,
- int dstx,
- int dsty,
- void (*doBitBlt)(DrawablePtr, DrawablePtr, GCPtr, RegionPtr, DDXPointPtr),
- unsigned long bitPlane
-);
-
-extern _X_EXPORT void
-XAAScreenToScreenBitBlt(
- ScrnInfoPtr pScrn,
- int nbox,
- DDXPointPtr pptSrc,
- BoxPtr pbox,
- int xdir,
- int ydir,
- int alu,
- unsigned int planemask
-);
-
-extern _X_EXPORT void
-XAADoBitBlt(
- DrawablePtr pSrc,
- DrawablePtr pDst,
- GC *pGC,
- RegionPtr prgnDst,
- DDXPointPtr pptSrc
-);
-
-extern _X_EXPORT void
-XAADoImageWrite(
- DrawablePtr pSrc,
- DrawablePtr pDst,
- GC *pGC,
- RegionPtr prgnDst,
- DDXPointPtr pptSrc
-);
-
-extern _X_EXPORT void
-XAADoImageRead(
- DrawablePtr pSrc,
- DrawablePtr pDst,
- GC *pGC,
- RegionPtr prgnDst,
- DDXPointPtr pptSrc
-);
-
-extern _X_EXPORT void
-XAACopyWindow(
- WindowPtr pWin,
- DDXPointRec ptOldOrg,
- RegionPtr prgnSrc
-);
-
-
-extern _X_EXPORT RegionPtr
-XAACopyArea(
- DrawablePtr pSrcDrawable,
- DrawablePtr pDstDrawable,
- GC *pGC,
- int srcx,
- int srcy,
- int width,
- int height,
- int dstx,
- int dsty
-);
-
-extern _X_EXPORT void
-XAAValidateCopyArea(
- GCPtr pGC,
- unsigned long changes,
- DrawablePtr pDraw
-);
-
-extern _X_EXPORT void
-XAAValidatePutImage(
- GCPtr pGC,
- unsigned long changes,
- DrawablePtr pDraw
-);
-
-extern _X_EXPORT void
-XAAValidateCopyPlane(
- GCPtr pGC,
- unsigned long changes,
- DrawablePtr pDraw
-);
-
-extern _X_EXPORT void
-XAAValidatePushPixels(
- GCPtr pGC,
- unsigned long changes,
- DrawablePtr pDraw
-);
-
-extern _X_EXPORT void
-XAAValidateFillSpans(
- GCPtr pGC,
- unsigned long changes,
- DrawablePtr pDraw
-);
-
-extern _X_EXPORT void
-XAAValidatePolyGlyphBlt(
- GCPtr pGC,
- unsigned long changes,
- DrawablePtr pDraw
-);
-
-extern _X_EXPORT void
-XAAValidateImageGlyphBlt(
- GCPtr pGC,
- unsigned long changes,
- DrawablePtr pDraw
-);
-
-extern _X_EXPORT void
-XAAValidatePolylines(
- GCPtr pGC,
- unsigned long changes,
- DrawablePtr pDraw
-);
-
-
-extern _X_EXPORT RegionPtr
-XAACopyPlaneColorExpansion(
- DrawablePtr pSrc,
- DrawablePtr pDst,
- GCPtr pGC,
- int srcx,
- int srcy,
- int width,
- int height,
- int dstx,
- int dsty,
- unsigned long bitPlane
-);
-
-
-extern _X_EXPORT void
-XAAPushPixelsSolidColorExpansion(
- GCPtr pGC,
- PixmapPtr pBitMap,
- DrawablePtr pDrawable,
- int dx,
- int dy,
- int xOrg,
- int yOrg
-);
-
-extern _X_EXPORT void
-XAAWriteBitmapColorExpandMSBFirstFixedBase (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned char *src,
- int srcwidth,
- int skipleft,
- int fg, int bg,
- int rop,
- unsigned int planemask
-);
-
-extern _X_EXPORT void
-XAAWriteBitmapColorExpand3MSBFirstFixedBase (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned char *src,
- int srcwidth,
- int skipleft,
- int fg, int bg,
- int rop,
- unsigned int planemask
-);
-
-extern _X_EXPORT void
-XAAWriteBitmapColorExpandMSBFirst (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned char *src,
- int srcwidth,
- int skipleft,
- int fg, int bg,
- int rop,
- unsigned int planemask
-);
-
-extern _X_EXPORT void
-XAAWriteBitmapColorExpand3MSBFirst (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned char *src,
- int srcwidth,
- int skipleft,
- int fg, int bg,
- int rop,
- unsigned int planemask
-);
-
-extern _X_EXPORT void
-XAAWriteBitmapColorExpandLSBFirstFixedBase (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned char *src,
- int srcwidth,
- int skipleft,
- int fg, int bg,
- int rop,
- unsigned int planemask
-);
-
-extern _X_EXPORT void
-XAAWriteBitmapColorExpand3LSBFirstFixedBase (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned char *src,
- int srcwidth,
- int skipleft,
- int fg, int bg,
- int rop,
- unsigned int planemask
-);
-
-extern _X_EXPORT void
-XAAWriteBitmapColorExpandLSBFirst (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned char *src,
- int srcwidth,
- int skipleft,
- int fg, int bg,
- int rop,
- unsigned int planemask
-);
-
-extern _X_EXPORT void
-XAAWriteBitmapColorExpand3LSBFirst (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned char *src,
- int srcwidth,
- int skipleft,
- int fg, int bg,
- int rop,
- unsigned int planemask
-);
-
-
-extern _X_EXPORT void
-XAAWriteBitmapScanlineColorExpandMSBFirst (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned char *src,
- int srcwidth,
- int skipleft,
- int fg, int bg,
- int rop,
- unsigned int planemask
-);
-
-extern _X_EXPORT void
-XAAWriteBitmapScanlineColorExpand3MSBFirst (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned char *src,
- int srcwidth,
- int skipleft,
- int fg, int bg,
- int rop,
- unsigned int planemask
-);
-
-extern _X_EXPORT void
-XAAWriteBitmapScanlineColorExpandMSBFirstFixedBase (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned char *src,
- int srcwidth,
- int skipleft,
- int fg, int bg,
- int rop,
- unsigned int planemask
-);
-
-extern _X_EXPORT void
-XAAWriteBitmapScanlineColorExpand3MSBFirstFixedBase (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned char *src,
- int srcwidth,
- int skipleft,
- int fg, int bg,
- int rop,
- unsigned int planemask
-);
-
-extern _X_EXPORT void
-XAAWriteBitmapScanlineColorExpandLSBFirst (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned char *src,
- int srcwidth,
- int skipleft,
- int fg, int bg,
- int rop,
- unsigned int planemask
-);
-
-extern _X_EXPORT void
-XAAWriteBitmapScanlineColorExpand3LSBFirst (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned char *src,
- int srcwidth,
- int skipleft,
- int fg, int bg,
- int rop,
- unsigned int planemask
-);
-
-extern _X_EXPORT void
-XAAWriteBitmapScanlineColorExpandLSBFirstFixedBase (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned char *src,
- int srcwidth,
- int skipleft,
- int fg, int bg,
- int rop,
- unsigned int planemask
-);
-
-extern _X_EXPORT void
-XAAWriteBitmapScanlineColorExpand3LSBFirstFixedBase (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned char *src,
- int srcwidth,
- int skipleft,
- int fg, int bg,
- int rop,
- unsigned int planemask
-);
-
-extern _X_EXPORT void
-XAAWritePixmap (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned char *src,
- int srcwidth,
- int rop,
- unsigned int planemask,
- int transparency_color,
- int bpp, int depth
-);
-
-extern _X_EXPORT void
-XAAWritePixmapScanline (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned char *src,
- int srcwidth,
- int rop,
- unsigned int planemask,
- int transparency_color,
- int bpp, int depth
-);
-
-typedef void (*ClipAndRenderRectsFunc)(GCPtr, int, BoxPtr, int, int);
-
-
-extern _X_EXPORT void
-XAAClipAndRenderRects(
- GCPtr pGC,
- ClipAndRenderRectsFunc func,
- int nrectFill,
- xRectangle *prectInit,
- int xorg, int yorg
-);
-
-
-typedef void (*ClipAndRenderSpansFunc)(GCPtr, int, DDXPointPtr, int*,
- int, int, int);
-
-extern _X_EXPORT void
-XAAClipAndRenderSpans(
- GCPtr pGC,
- DDXPointPtr ppt,
- int *pwidth,
- int nspans,
- int fSorted,
- ClipAndRenderSpansFunc func,
- int xorg,
- int yorg
-);
-
-
-extern _X_EXPORT void
-XAAFillSolidRects(
- ScrnInfoPtr pScrn,
- int fg, int rop,
- unsigned int planemask,
- int nBox,
- BoxPtr pBox
-);
-
-extern _X_EXPORT void
-XAAFillMono8x8PatternRects(
- ScrnInfoPtr pScrn,
- int fg, int bg, int rop,
- unsigned int planemask,
- int nBox,
- BoxPtr pBox,
- int pat0, int pat1,
- int xorg, int yorg
-);
-
-extern _X_EXPORT void
-XAAFillMono8x8PatternRectsScreenOrigin(
- ScrnInfoPtr pScrn,
- int fg, int bg, int rop,
- unsigned int planemask,
- int nBox,
- BoxPtr pBox,
- int pat0, int pat1,
- int xorg, int yorg
-);
-
-
-extern _X_EXPORT void
-XAAFillColor8x8PatternRectsScreenOrigin(
- ScrnInfoPtr pScrn,
- int rop,
- unsigned int planemask,
- int nBox,
- BoxPtr pBox,
- int xorigin, int yorigin,
- XAACacheInfoPtr pCache
-);
-
-extern _X_EXPORT void
-XAAFillColor8x8PatternRects(
- ScrnInfoPtr pScrn,
- int rop,
- unsigned int planemask,
- int nBox,
- BoxPtr pBox,
- int xorigin, int yorigin,
- XAACacheInfoPtr pCache
-);
-
-extern _X_EXPORT void
-XAAFillCacheBltRects(
- ScrnInfoPtr pScrn,
- int rop,
- unsigned int planemask,
- int nBox,
- BoxPtr pBox,
- int xorg, int yorg,
- XAACacheInfoPtr pCache
-);
-
-extern _X_EXPORT void
-XAAFillCacheExpandRects(
- ScrnInfoPtr pScrn,
- int fg, int bg, int rop,
- unsigned int planemask,
- int nBox,
- BoxPtr pBox,
- int xorg, int yorg,
- PixmapPtr pPix
-);
-
-extern _X_EXPORT void
-XAAFillImageWriteRects(
- ScrnInfoPtr pScrn,
- int rop,
- unsigned int planemask,
- int nBox,
- BoxPtr pBox,
- int xorg, int yorg,
- PixmapPtr pPix
-);
-
-extern _X_EXPORT void
-XAAPolyFillRect(
- DrawablePtr pDraw,
- GCPtr pGC,
- int nrectFill,
- xRectangle *prectInit
-);
-
-
-extern _X_EXPORT void
-XAATEGlyphRendererMSBFirstFixedBase (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h, int skipleft, int startline,
- unsigned int **glyphs, int glyphWidth,
- int fg, int bg, int rop, unsigned planemask
-);
-
-extern _X_EXPORT void
-XAATEGlyphRenderer3MSBFirstFixedBase (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h, int skipleft, int startline,
- unsigned int **glyphs, int glyphWidth,
- int fg, int bg, int rop, unsigned planemask
-);
-
-extern _X_EXPORT void
-XAATEGlyphRendererMSBFirst (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h, int skipleft, int startline,
- unsigned int **glyphs, int glyphWidth,
- int fg, int bg, int rop, unsigned planemask
-);
-
-extern _X_EXPORT void
-XAATEGlyphRenderer3MSBFirst (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h, int skipleft, int startline,
- unsigned int **glyphs, int glyphWidth,
- int fg, int bg, int rop, unsigned planemask
-);
-
-extern _X_EXPORT void
-XAATEGlyphRendererLSBFirstFixedBase (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h, int skipleft, int startline,
- unsigned int **glyphs, int glyphWidth,
- int fg, int bg, int rop, unsigned planemask
-);
-
-
-extern _X_EXPORT void
-XAATEGlyphRenderer3LSBFirstFixedBase (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h, int skipleft, int startline,
- unsigned int **glyphs, int glyphWidth,
- int fg, int bg, int rop, unsigned planemask
-);
-
-extern _X_EXPORT void
-XAATEGlyphRendererLSBFirst (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h, int skipleft, int startline,
- unsigned int **glyphs, int glyphWidth,
- int fg, int bg, int rop, unsigned planemask
-);
-
-extern _X_EXPORT void
-XAATEGlyphRenderer3LSBFirst (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h, int skipleft, int startline,
- unsigned int **glyphs, int glyphWidth,
- int fg, int bg, int rop, unsigned planemask
-);
-
-
-extern _X_EXPORT void
-XAATEGlyphRendererScanlineMSBFirst (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h, int skipleft, int startline,
- unsigned int **glyphs, int glyphWidth,
- int fg, int bg, int rop, unsigned planemask
-);
-
-extern _X_EXPORT void
-XAATEGlyphRendererScanline3MSBFirst (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h, int skipleft, int startline,
- unsigned int **glyphs, int glyphWidth,
- int fg, int bg, int rop, unsigned planemask
-);
-
-extern _X_EXPORT void
-XAATEGlyphRendererScanlineLSBFirst (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h, int skipleft, int startline,
- unsigned int **glyphs, int glyphWidth,
- int fg, int bg, int rop, unsigned planemask
-);
-
-extern _X_EXPORT void
-XAATEGlyphRendererScanline3LSBFirst (
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h, int skipleft, int startline,
- unsigned int **glyphs, int glyphWidth,
- int fg, int bg, int rop, unsigned planemask
-);
-
-
-extern _X_EXPORT CARD32 *(*XAAGlyphScanlineFuncMSBFirstFixedBase[32])(
- CARD32 *base, unsigned int **glyphp, int line, int nglyph, int width
-);
-
-extern _X_EXPORT CARD32 *(*XAAGlyphScanlineFuncMSBFirst[32])(
- CARD32 *base, unsigned int **glyphp, int line, int nglyph, int width
-);
-
-extern _X_EXPORT CARD32 *(*XAAGlyphScanlineFuncLSBFirstFixedBase[32])(
- CARD32 *base, unsigned int **glyphp, int line, int nglyph, int width
-);
-
-extern _X_EXPORT CARD32 *(*XAAGlyphScanlineFuncLSBFirst[32])(
- CARD32 *base, unsigned int **glyphp, int line, int nglyph, int width
-);
-
-extern _X_EXPORT GlyphScanlineFuncPtr *XAAGetGlyphScanlineFuncMSBFirstFixedBase(void);
-extern _X_EXPORT GlyphScanlineFuncPtr *XAAGetGlyphScanlineFuncMSBFirst(void);
-extern _X_EXPORT GlyphScanlineFuncPtr *XAAGetGlyphScanlineFuncLSBFirstFixedBase(void);
-extern _X_EXPORT GlyphScanlineFuncPtr *XAAGetGlyphScanlineFuncLSBFirst(void);
-
-extern _X_EXPORT void
-XAAFillColorExpandRectsLSBFirst(
- ScrnInfoPtr pScrn,
- int fg, int bg, int rop,
- unsigned int planemask,
- int nBox,
- BoxPtr pBox,
- int xorg, int yorg,
- PixmapPtr pPix
-);
-
-extern _X_EXPORT void
-XAAFillColorExpandRects3LSBFirst(
- ScrnInfoPtr pScrn,
- int fg, int bg, int rop,
- unsigned int planemask,
- int nBox,
- BoxPtr pBox,
- int xorg, int yorg,
- PixmapPtr pPix
-);
-
-extern _X_EXPORT void
-XAAFillColorExpandRectsLSBFirstFixedBase(
- ScrnInfoPtr pScrn,
- int fg, int bg, int rop,
- unsigned int planemask,
- int nBox,
- BoxPtr pBox,
- int xorg, int yorg,
- PixmapPtr pPix
-);
-
-extern _X_EXPORT void
-XAAFillColorExpandRects3LSBFirstFixedBase(
- ScrnInfoPtr pScrn,
- int fg, int bg, int rop,
- unsigned int planemask,
- int nBox,
- BoxPtr pBox,
- int xorg, int yorg,
- PixmapPtr pPix
-);
-
-extern _X_EXPORT void
-XAAFillColorExpandRectsMSBFirst(
- ScrnInfoPtr pScrn,
- int fg, int bg, int rop,
- unsigned int planemask,
- int nBox,
- BoxPtr pBox,
- int xorg, int yorg,
- PixmapPtr pPix
-);
-
-extern _X_EXPORT void
-XAAFillColorExpandRects3MSBFirst(
- ScrnInfoPtr pScrn,
- int fg, int bg, int rop,
- unsigned int planemask,
- int nBox,
- BoxPtr pBox,
- int xorg, int yorg,
- PixmapPtr pPix
-);
-
-extern _X_EXPORT void
-XAAFillColorExpandRectsMSBFirstFixedBase(
- ScrnInfoPtr pScrn,
- int fg, int bg, int rop,
- unsigned int planemask,
- int nBox,
- BoxPtr pBox,
- int xorg, int yorg,
- PixmapPtr pPix
-);
-
-extern _X_EXPORT void
-XAAFillColorExpandRects3MSBFirstFixedBase(
- ScrnInfoPtr pScrn,
- int fg, int bg, int rop,
- unsigned int planemask,
- int nBox,
- BoxPtr pBox,
- int xorg, int yorg,
- PixmapPtr pPix
-);
-
-extern _X_EXPORT void
-XAAFillScanlineColorExpandRectsLSBFirst(
- ScrnInfoPtr pScrn,
- int fg, int bg, int rop,
- unsigned int planemask,
- int nBox,
- BoxPtr pBox,
- int xorg, int yorg,
- PixmapPtr pPix
-);
-
-extern _X_EXPORT void
-XAAFillScanlineColorExpandRects3LSBFirst(
- ScrnInfoPtr pScrn,
- int fg, int bg, int rop,
- unsigned int planemask,
- int nBox,
- BoxPtr pBox,
- int xorg, int yorg,
- PixmapPtr pPix
-);
-
-extern _X_EXPORT void
-XAAFillScanlineColorExpandRectsMSBFirst(
- ScrnInfoPtr pScrn,
- int fg, int bg, int rop,
- unsigned int planemask,
- int nBox,
- BoxPtr pBox,
- int xorg, int yorg,
- PixmapPtr pPix
-);
-
-extern _X_EXPORT void
-XAAFillScanlineColorExpandRects3MSBFirst(
- ScrnInfoPtr pScrn,
- int fg, int bg, int rop,
- unsigned int planemask,
- int nBox,
- BoxPtr pBox,
- int xorg, int yorg,
- PixmapPtr pPix
-);
-
-extern _X_EXPORT void
-XAAFillColorExpandSpansLSBFirst(
- ScrnInfoPtr pScrn,
- int fg, int bg, int rop,
- unsigned int planemask,
- int n,
- DDXPointPtr ppt,
- int *pwidth,
- int fSorted,
- int xorg, int yorg,
- PixmapPtr pPix
-);
-
-extern _X_EXPORT void
-XAAFillColorExpandSpans3LSBFirst(
- ScrnInfoPtr pScrn,
- int fg, int bg, int rop,
- unsigned int planemask,
- int n,
- DDXPointPtr ppt,
- int *pwidth,
- int fSorted,
- int xorg, int yorg,
- PixmapPtr pPix
-);
-
-extern _X_EXPORT void
-XAAFillColorExpandSpansLSBFirstFixedBase(
- ScrnInfoPtr pScrn,
- int fg, int bg, int rop,
- unsigned int planemask,
- int n,
- DDXPointPtr ppt,
- int *pwidth,
- int fSorted,
- int xorg, int yorg,
- PixmapPtr pPix
-);
-
-extern _X_EXPORT void
-XAAFillColorExpandSpans3LSBFirstFixedBase(
- ScrnInfoPtr pScrn,
- int fg, int bg, int rop,
- unsigned int planemask,
- int n,
- DDXPointPtr ppt,
- int *pwidth,
- int fSorted,
- int xorg, int yorg,
- PixmapPtr pPix
-);
-
-extern _X_EXPORT void
-XAAFillColorExpandSpansMSBFirst(
- ScrnInfoPtr pScrn,
- int fg, int bg, int rop,
- unsigned int planemask,
- int n,
- DDXPointPtr ppt,
- int *pwidth,
- int fSorted,
- int xorg, int yorg,
- PixmapPtr pPix
-);
-
-extern _X_EXPORT void
-XAAFillColorExpandSpans3MSBFirst(
- ScrnInfoPtr pScrn,
- int fg, int bg, int rop,
- unsigned int planemask,
- int n,
- DDXPointPtr ppt,
- int *pwidth,
- int fSorted,
- int xorg, int yorg,
- PixmapPtr pPix
-);
-
-extern _X_EXPORT void
-XAAFillColorExpandSpansMSBFirstFixedBase(
- ScrnInfoPtr pScrn,
- int fg, int bg, int rop,
- unsigned int planemask,
- int n,
- DDXPointPtr ppt,
- int *pwidth,
- int fSorted,
- int xorg, int yorg,
- PixmapPtr pPix
-);
-
-extern _X_EXPORT void
-XAAFillColorExpandSpans3MSBFirstFixedBase(
- ScrnInfoPtr pScrn,
- int fg, int bg, int rop,
- unsigned int planemask,
- int n,
- DDXPointPtr ppt,
- int *pwidth,
- int fSorted,
- int xorg, int yorg,
- PixmapPtr pPix
-);
-
-extern _X_EXPORT void
-XAAFillScanlineColorExpandSpansLSBFirst(
- ScrnInfoPtr pScrn,
- int fg, int bg, int rop,
- unsigned int planemask,
- int n,
- DDXPointPtr ppt,
- int *pwidth,
- int fSorted,
- int xorg, int yorg,
- PixmapPtr pPix
-);
-
-extern _X_EXPORT void
-XAAFillScanlineColorExpandSpans3LSBFirst(
- ScrnInfoPtr pScrn,
- int fg, int bg, int rop,
- unsigned int planemask,
- int n,
- DDXPointPtr ppt,
- int *pwidth,
- int fSorted,
- int xorg, int yorg,
- PixmapPtr pPix
-);
-
-extern _X_EXPORT void
-XAAPutImage(
- DrawablePtr pDraw,
- GCPtr pGC,
- int depth,
- int x,
- int y,
- int w,
- int h,
- int leftPad,
- int format,
- char *pImage
-);
-
-extern _X_EXPORT void
-XAAFillScanlineColorExpandSpansMSBFirst(
- ScrnInfoPtr pScrn,
- int fg, int bg, int rop,
- unsigned int planemask,
- int n,
- DDXPointPtr ppt,
- int *pwidth,
- int fSorted,
- int xorg, int yorg,
- PixmapPtr pPix
-);
-
-extern _X_EXPORT void
-XAAFillScanlineColorExpandSpans3MSBFirst(
- ScrnInfoPtr pScrn,
- int fg, int bg, int rop,
- unsigned int planemask,
- int n,
- DDXPointPtr ppt,
- int *pwidth,
- int fSorted,
- int xorg, int yorg,
- PixmapPtr pPix
-);
-
-
-extern _X_EXPORT CARD32 *(*XAAStippleScanlineFuncMSBFirstFixedBase[6])(
- CARD32* base, CARD32* src, int offset, int width, int dwords
-);
-
-extern _X_EXPORT CARD32 *(*XAAStippleScanlineFuncMSBFirst[6])(
- CARD32* base, CARD32* src, int offset, int width, int dwords
-);
-
-extern _X_EXPORT CARD32 *(*XAAStippleScanlineFuncLSBFirstFixedBase[6])(
- CARD32* base, CARD32* src, int offset, int width, int dwords
-);
-
-extern _X_EXPORT CARD32 *(*XAAStippleScanlineFuncLSBFirst[6])(
- CARD32* base, CARD32* src, int offset, int width, int dwords
-);
-
-extern _X_EXPORT StippleScanlineProcPtr *XAAGetStippleScanlineFuncMSBFirstFixedBase(void);
-extern _X_EXPORT StippleScanlineProcPtr *XAAGetStippleScanlineFuncMSBFirst(void);
-extern _X_EXPORT StippleScanlineProcPtr *XAAGetStippleScanlineFuncLSBFirstFixedBase(void);
-extern _X_EXPORT StippleScanlineProcPtr *XAAGetStippleScanlineFuncLSBFirst(void);
-extern _X_EXPORT StippleScanlineProcPtr *XAAGetStippleScanlineFunc3MSBFirstFixedBase(void);
-extern _X_EXPORT StippleScanlineProcPtr *XAAGetStippleScanlineFunc3MSBFirst(void);
-extern _X_EXPORT StippleScanlineProcPtr *XAAGetStippleScanlineFunc3LSBFirstFixedBase(void);
-extern _X_EXPORT StippleScanlineProcPtr *XAAGetStippleScanlineFunc3LSBFirst(void);
-
-extern _X_EXPORT int
-XAAPolyText8TEColorExpansion(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x, int y,
- int count,
- char *chars
-);
-
-extern _X_EXPORT int
-XAAPolyText16TEColorExpansion(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x, int y,
- int count,
- unsigned short *chars
-);
-
-extern _X_EXPORT void
-XAAImageText8TEColorExpansion(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x, int y,
- int count,
- char *chars
-);
-
-extern _X_EXPORT void
-XAAImageText16TEColorExpansion(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x, int y,
- int count,
- unsigned short *chars
-);
-
-extern _X_EXPORT void
-XAAImageGlyphBltTEColorExpansion(
- DrawablePtr pDrawable,
- GCPtr pGC,
- int xInit, int yInit,
- unsigned int nglyph,
- CharInfoPtr *ppci,
- pointer pglyphBase
-);
-
-extern _X_EXPORT void
-XAAPolyGlyphBltTEColorExpansion(
- DrawablePtr pDrawable,
- GCPtr pGC,
- int xInit, int yInit,
- unsigned int nglyph,
- CharInfoPtr *ppci,
- pointer pglyphBase
-);
-
-
-extern _X_EXPORT int
-XAAPolyText8NonTEColorExpansion(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x, int y,
- int count,
- char *chars
-);
-
-extern _X_EXPORT int
-XAAPolyText16NonTEColorExpansion(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x, int y,
- int count,
- unsigned short *chars
-);
-
-extern _X_EXPORT void
-XAAImageText8NonTEColorExpansion(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x, int y,
- int count,
- char *chars
-);
-
-extern _X_EXPORT void
-XAAImageText16NonTEColorExpansion(
- DrawablePtr pDraw,
- GCPtr pGC,
- int x, int y,
- int count,
- unsigned short *chars
-);
-
-extern _X_EXPORT void
-XAAImageGlyphBltNonTEColorExpansion(
- DrawablePtr pDrawable,
- GCPtr pGC,
- int xInit, int yInit,
- unsigned int nglyph,
- CharInfoPtr *ppci,
- pointer pglyphBase
-);
-
-extern _X_EXPORT void
-XAAPolyGlyphBltNonTEColorExpansion(
- DrawablePtr pDrawable,
- GCPtr pGC,
- int xInit, int yInit,
- unsigned int nglyph,
- CharInfoPtr *ppci,
- pointer pglyphBase
-);
-
-
-extern _X_EXPORT void XAANonTEGlyphRenderer(
- ScrnInfoPtr pScrn,
- int x, int y, int n,
- NonTEGlyphPtr glyphs,
- BoxPtr pbox,
- int fg, int rop,
- unsigned int planemask
-);
-
-extern _X_EXPORT void
-XAAFillSolidSpans(
- ScrnInfoPtr pScrn,
- int fg, int rop,
- unsigned int planemask,
- int n,
- DDXPointPtr ppt,
- int *pwidth, int fSorted
-);
-
-extern _X_EXPORT void
-XAAFillMono8x8PatternSpans(
- ScrnInfoPtr pScrn,
- int fg, int bg, int rop,
- unsigned int planemask,
- int n,
- DDXPointPtr ppt,
- int *pwidth, int fSorted,
- int patx, int paty,
- int xorg, int yorg
-);
-
-extern _X_EXPORT void
-XAAFillMono8x8PatternSpansScreenOrigin(
- ScrnInfoPtr pScrn,
- int fg, int bg, int rop,
- unsigned int planemask,
- int n,
- DDXPointPtr ppt,
- int *pwidth, int fSorted,
- int patx, int paty,
- int xorg, int yorg
-);
-
-extern _X_EXPORT void
-XAAFillColor8x8PatternSpansScreenOrigin(
- ScrnInfoPtr pScrn,
- int rop,
- unsigned int planemask,
- int n,
- DDXPointPtr ppt,
- int *pwidth, int fSorted,
- XAACacheInfoPtr,
- int xorigin, int yorigin
-);
-
-extern _X_EXPORT void
-XAAFillColor8x8PatternSpans(
- ScrnInfoPtr pScrn,
- int rop,
- unsigned int planemask,
- int n,
- DDXPointPtr ppt,
- int *pwidth, int fSorted,
- XAACacheInfoPtr,
- int xorigin, int yorigin
-);
-
-extern _X_EXPORT void
-XAAFillCacheBltSpans(
- ScrnInfoPtr pScrn,
- int rop,
- unsigned int planemask,
- int n,
- DDXPointPtr points,
- int *widths,
- int fSorted,
- XAACacheInfoPtr pCache,
- int xorg, int yorg
-);
-
-extern _X_EXPORT void
-XAAFillCacheExpandSpans(
- ScrnInfoPtr pScrn,
- int fg, int bg, int rop,
- unsigned int planemask,
- int n,
- DDXPointPtr ppt,
- int *pwidth,
- int fSorted,
- int xorg, int yorg,
- PixmapPtr pPix
-);
-
-extern _X_EXPORT void
-XAAFillSpans(
- DrawablePtr pDrawable,
- GC *pGC,
- int nInit,
- DDXPointPtr pptInit,
- int *pwidth,
- int fSorted
-);
-
-
-extern _X_EXPORT void
-XAAInitPixmapCache(
- ScreenPtr pScreen,
- RegionPtr areas,
- pointer data
-);
-
-extern _X_EXPORT void
-XAAWriteBitmapToCache(
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned char *src,
- int srcwidth,
- int fg, int bg
-);
-
-extern _X_EXPORT void
-XAAWriteBitmapToCacheLinear(
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned char *src,
- int srcwidth,
- int fg, int bg
-);
-
-extern _X_EXPORT void
-XAAWritePixmapToCache(
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned char *src,
- int srcwidth,
- int bpp, int depth
-);
-
-extern _X_EXPORT void
-XAAWritePixmapToCacheLinear(
- ScrnInfoPtr pScrn,
- int x, int y, int w, int h,
- unsigned char *src,
- int srcwidth,
- int bpp, int depth
-);
-
-extern _X_EXPORT void
-XAASolidHorVertLineAsRects(
- ScrnInfoPtr pScrn,
- int x, int y, int len, int dir
-);
-
-extern _X_EXPORT void
-XAASolidHorVertLineAsTwoPoint(
- ScrnInfoPtr pScrn,
- int x, int y, int len, int dir
-);
-
-extern _X_EXPORT void
-XAASolidHorVertLineAsBresenham(
- ScrnInfoPtr pScrn,
- int x, int y, int len, int dir
-);
-
-
-extern _X_EXPORT void
-XAAPolyRectangleThinSolid(
- DrawablePtr pDrawable,
- GCPtr pGC,
- int nRectsInit,
- xRectangle *pRectsInit
-);
-
-
-extern _X_EXPORT void
-XAAPolylinesWideSolid (
- DrawablePtr pDrawable,
- GCPtr pGC,
- int mode,
- int npt,
- DDXPointPtr pPts
-);
-
-extern _X_EXPORT void
-XAAFillPolygonSolid(
- DrawablePtr pDrawable,
- GCPtr pGC,
- int shape,
- int mode,
- int count,
- DDXPointPtr ptsIn
-);
-
-extern _X_EXPORT void
-XAAFillPolygonStippled(
- DrawablePtr pDrawable,
- GCPtr pGC,
- int shape,
- int mode,
- int count,
- DDXPointPtr ptsIn
-);
-
-
-extern _X_EXPORT void
-XAAFillPolygonTiled(
- DrawablePtr pDrawable,
- GCPtr pGC,
- int shape,
- int mode,
- int count,
- DDXPointPtr ptsIn
-);
-
-
-extern _X_EXPORT int
-XAAIsEasyPolygon(
- DDXPointPtr ptsIn,
- int count,
- BoxPtr extents,
- int origin,
- DDXPointPtr *topPoint,
- int *topY, int *bottomY,
- int shape
-);
-
-extern _X_EXPORT void
-XAAFillPolygonHelper(
- ScrnInfoPtr pScrn,
- DDXPointPtr ptsIn,
- int count,
- DDXPointPtr topPoint,
- int y,
- int maxy,
- int origin,
- RectFuncPtr RectFunc,
- TrapFuncPtr TrapFunc,
- int xorg,
- int yorg,
- XAACacheInfoPtr pCache
-);
-
-extern _X_EXPORT void
-XAAPolySegment(
- DrawablePtr pDrawable,
- GCPtr pGC,
- int nseg,
- xSegment *pSeg
-);
-
-extern _X_EXPORT void
-XAAPolyLines(
- DrawablePtr pDrawable,
- GCPtr pGC,
- int mode,
- int npt,
- DDXPointPtr pptInit
-);
-
-extern _X_EXPORT void
-XAAPolySegmentDashed(
- DrawablePtr pDrawable,
- GCPtr pGC,
- int nseg,
- xSegment *pSeg
-);
-
-extern _X_EXPORT void
-XAAPolyLinesDashed(
- DrawablePtr pDrawable,
- GCPtr pGC,
- int mode,
- int npt,
- DDXPointPtr pptInit
-);
-
-
-extern _X_EXPORT void
-XAAWriteMono8x8PatternToCache(ScrnInfoPtr pScrn, XAACacheInfoPtr pCache);
-
-extern _X_EXPORT void
-XAAWriteColor8x8PatternToCache(
- ScrnInfoPtr pScrn,
- PixmapPtr pPix,
- XAACacheInfoPtr pCache
-);
-
-extern _X_EXPORT void
-XAARotateMonoPattern(
- int *pat0, int *pat1,
- int xoffset, int yoffset,
- Bool msbfirst
-);
-
-extern _X_EXPORT void XAAComputeDash(GCPtr pGC);
-
-extern _X_EXPORT void XAAMoveDWORDS_FixedBase(
- register CARD32* dest,
- register CARD32* src,
- register int dwords
-);
-
-extern _X_EXPORT void XAAMoveDWORDS_FixedSrc(
- register CARD32* dest,
- register CARD32* src,
- register int dwords
-);
-
-extern _X_EXPORT void XAAMoveDWORDS(
- register CARD32* dest,
- register CARD32* src,
- register int dwords
-);
-
-extern _X_EXPORT int
-XAAGetRectClipBoxes(
- GCPtr pGC,
- BoxPtr pboxClippedBase,
- int nrectFill,
- xRectangle *prectInit
-);
-
-extern _X_EXPORT void
-XAASetupOverlay8_32Planar(ScreenPtr);
-
-extern _X_EXPORT void
-XAAPolyFillArcSolid(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc *parcs);
-
-extern _X_EXPORT XAACacheInfoPtr
-XAACacheTile(ScrnInfoPtr Scrn, PixmapPtr pPix);
-
-extern _X_EXPORT XAACacheInfoPtr
-XAACacheMonoStipple(ScrnInfoPtr Scrn, PixmapPtr pPix);
-
-extern _X_EXPORT XAACacheInfoPtr
-XAACachePlanarMonoStipple(ScrnInfoPtr Scrn, PixmapPtr pPix);
-
-typedef XAACacheInfoPtr (*XAACachePlanarMonoStippleProc)(ScrnInfoPtr, PixmapPtr);
-extern _X_EXPORT XAACachePlanarMonoStippleProc XAAGetCachePlanarMonoStipple(void);
-
-extern _X_EXPORT XAACacheInfoPtr
-XAACacheStipple(ScrnInfoPtr Scrn, PixmapPtr pPix, int fg, int bg);
-
-extern _X_EXPORT XAACacheInfoPtr
-XAACacheMono8x8Pattern(ScrnInfoPtr Scrn, int pat0, int pat1);
-
-extern _X_EXPORT XAACacheInfoPtr
-XAACacheColor8x8Pattern(ScrnInfoPtr Scrn, PixmapPtr pPix, int fg, int bg);
-
-extern _X_EXPORT void
-XAATileCache(ScrnInfoPtr pScrn, XAACacheInfoPtr pCache, int w, int h);
-
-extern _X_EXPORT void XAAClosePixmapCache(ScreenPtr pScreen);
-void XAAInvalidatePixmapCache(ScreenPtr pScreen);
-
-extern _X_EXPORT Bool XAACheckStippleReducibility(PixmapPtr pPixmap);
-extern _X_EXPORT Bool XAACheckTileReducibility(PixmapPtr pPixmap, Bool checkMono);
-
-extern _X_EXPORT int XAAStippledFillChooser(GCPtr pGC);
-extern _X_EXPORT int XAAOpaqueStippledFillChooser(GCPtr pGC);
-extern _X_EXPORT int XAATiledFillChooser(GCPtr pGC);
-
-extern _X_EXPORT void XAAMoveInOffscreenPixmaps(ScreenPtr pScreen);
-extern _X_EXPORT void XAAMoveOutOffscreenPixmaps(ScreenPtr pScreen);
-extern _X_EXPORT void XAARemoveAreaCallback(FBAreaPtr area);
-extern _X_EXPORT void XAAMoveOutOffscreenPixmap(PixmapPtr pPix);
-extern _X_EXPORT Bool XAAInitStateWrap(ScreenPtr pScreen, XAAInfoRecPtr infoRec);
-
-extern _X_EXPORT void
-XAAComposite (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst,
- INT16 yDst,
- CARD16 width,
- CARD16 height);
-
-
-extern _X_EXPORT Bool
-XAADoComposite (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pMask,
- PicturePtr pDst,
- INT16 xSrc,
- INT16 ySrc,
- INT16 xMask,
- INT16 yMask,
- INT16 xDst,
- INT16 yDst,
- CARD16 width,
- CARD16 height);
-
-
-extern _X_EXPORT void
-XAAGlyphs (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc,
- int nlist,
- GlyphListPtr list,
- GlyphPtr *glyphs);
-
-extern _X_EXPORT Bool
-XAADoGlyphs (CARD8 op,
- PicturePtr pSrc,
- PicturePtr pDst,
- PictFormatPtr maskFormat,
- INT16 xSrc,
- INT16 ySrc,
- int nlist,
- GlyphListPtr list,
- GlyphPtr *glyphs);
-
-
-
-/* helpers */
-extern _X_EXPORT void
-XAA_888_plus_PICT_a8_to_8888 (
- CARD32 color,
- CARD8 *alphaPtr, /* in bytes */
- int alphaPitch,
- CARD32 *dstPtr,
- int dstPitch, /* in dwords */
- int width,
- int height
-);
-
-extern _X_EXPORT Bool
-XAAGetRGBAFromPixel(
- CARD32 pixel,
- CARD16 *red,
- CARD16 *green,
- CARD16 *blue,
- CARD16 *alpha,
- CARD32 format
-);
-
-
-extern _X_EXPORT Bool
-XAAGetPixelFromRGBA (
- CARD32 *pixel,
- CARD16 red,
- CARD16 green,
- CARD16 blue,
- CARD16 alpha,
- CARD32 format
-);
-
-/* XXX should be static */
-extern _X_EXPORT GCOps XAAFallbackOps;
-extern _X_EXPORT GCOps *XAAGetFallbackOps(void);
-extern _X_EXPORT GCFuncs XAAGCFuncs;
-extern _X_EXPORT DevPrivateKey XAAGetScreenKey(void);
-extern _X_EXPORT DevPrivateKey XAAGetGCKey(void);
-extern _X_EXPORT DevPrivateKey XAAGetPixmapKey(void);
-
-extern _X_EXPORT unsigned int XAAShiftMasks[32];
-
-extern _X_EXPORT unsigned int byte_expand3[256], byte_reversed_expand3[256];
-
-extern _X_EXPORT CARD32 XAAReverseBitOrder(CARD32 data);
-
-#define GET_XAASCREENPTR_FROM_SCREEN(pScreen)\
- dixLookupPrivate(&(pScreen)->devPrivates, XAAGetScreenKey())
-
-#define GET_XAASCREENPTR_FROM_GC(pGC)\
- dixLookupPrivate(&(pGC)->pScreen->devPrivates, XAAGetScreenKey())
-
-#define GET_XAASCREENPTR_FROM_DRAWABLE(pDraw)\
- dixLookupPrivate(&(pDraw)->pScreen->devPrivates, XAAGetScreenKey())
-
-#define GET_XAAINFORECPTR_FROM_SCREEN(pScreen)\
-((XAAScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates, XAAGetScreenKey()))->AccelInfoRec
-
-#define GET_XAAINFORECPTR_FROM_GC(pGC)\
-((XAAScreenPtr)dixLookupPrivate(&(pGC)->pScreen->devPrivates, XAAGetScreenKey()))->AccelInfoRec
-
-#define GET_XAAINFORECPTR_FROM_DRAWABLE(pDraw)\
-((XAAScreenPtr)dixLookupPrivate(&(pDraw)->pScreen->devPrivates, XAAGetScreenKey()))->AccelInfoRec
-
-#define GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn)\
-((XAAScreenPtr)dixLookupPrivate(&(pScrn)->pScreen->devPrivates, XAAGetScreenKey()))->AccelInfoRec
-
-#define XAA_GET_PIXMAP_PRIVATE(pix)\
- (XAAPixmapPtr)dixLookupPrivate(&(pix)->devPrivates, XAAGetPixmapKey())
-
-#define CHECK_RGB_EQUAL(c) (!((((c) >> 8) ^ (c)) & 0xffff))
-
-#define CHECK_FG(pGC, flags) \
- (!(flags & RGB_EQUAL) || CHECK_RGB_EQUAL(pGC->fgPixel))
-
-#define CHECK_BG(pGC, flags) \
- (!(flags & RGB_EQUAL) || CHECK_RGB_EQUAL(pGC->bgPixel))
-
-#define CHECK_ROP(pGC, flags) \
- (!(flags & GXCOPY_ONLY) || (pGC->alu == GXcopy))
-
-#define CHECK_ROPSRC(pGC, flags) \
- (!(flags & ROP_NEEDS_SOURCE) || ((pGC->alu != GXclear) && \
- (pGC->alu != GXnoop) && (pGC->alu != GXinvert) && \
- (pGC->alu != GXset)))
-
-#define CHECK_PLANEMASK(pGC, flags) \
- (!(flags & NO_PLANEMASK) || \
- ((pGC->planemask & infoRec->FullPlanemasks[pGC->depth - 1]) == \
- infoRec->FullPlanemasks[pGC->depth - 1]))
-
-#define CHECK_COLORS(pGC, flags) \
- (!(flags & RGB_EQUAL) || \
- (CHECK_RGB_EQUAL(pGC->fgPixel) && CHECK_RGB_EQUAL(pGC->bgPixel)))
-
-#define CHECK_NO_GXCOPY(pGC, flags) \
- ((pGC->alu != GXcopy) || !(flags & NO_GXCOPY) || \
- ((pGC->planemask & infoRec->FullPlanemask) != infoRec->FullPlanemask))
-
-#define IS_OFFSCREEN_PIXMAP(pPix)\
- ((XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pPix)))->offscreenArea)
-
-#define PIXMAP_IS_SHARED(pPix)\
- ((XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pPix)))->flags & SHARED_PIXMAP)
-
-#define OFFSCREEN_PIXMAP_LOCKED(pPix)\
- ((XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pPix)))->flags & LOCKED_PIXMAP)
-
-#define XAA_DEPTH_BUG(pGC) \
- ((pGC->depth == 32) && (pGC->bgPixel == 0xffffffff))
-
-#define DELIST_OFFSCREEN_PIXMAP(pPix) { \
- PixmapLinkPtr _pLink, _prev; \
- _pLink = infoRec->OffscreenPixmaps; \
- _prev = NULL; \
- while(_pLink) { \
- if(_pLink->pPix == pPix) { \
- if(_prev) _prev->next = _pLink->next; \
- else infoRec->OffscreenPixmaps = _pLink->next; \
- xfree(_pLink); \
- break; \
- } \
- _prev = _pLink; \
- _pLink = _pLink->next; \
- }}
-
-
-#define SWAP_BITS_IN_BYTES(v) \
- (((0x01010101 & (v)) << 7) | ((0x02020202 & (v)) << 5) | \
- ((0x04040404 & (v)) << 3) | ((0x08080808 & (v)) << 1) | \
- ((0x10101010 & (v)) >> 1) | ((0x20202020 & (v)) >> 3) | \
- ((0x40404040 & (v)) >> 5) | ((0x80808080 & (v)) >> 7))
-
-/*
- * Moved XAAPixmapCachePrivate here from xaaPCache.c, since driver
- * replacements for CacheMonoStipple need access to it
- */
-
-typedef struct {
- int Num512x512;
- int Current512;
- XAACacheInfoPtr Info512;
- int Num256x256;
- int Current256;
- XAACacheInfoPtr Info256;
- int Num128x128;
- int Current128;
- XAACacheInfoPtr Info128;
- int NumMono;
- int CurrentMono;
- XAACacheInfoPtr InfoMono;
- int NumColor;
- int CurrentColor;
- XAACacheInfoPtr InfoColor;
- int NumPartial;
- int CurrentPartial;
- XAACacheInfoPtr InfoPartial;
- DDXPointRec MonoOffsets[64];
- DDXPointRec ColorOffsets[64];
-} XAAPixmapCachePrivate, *XAAPixmapCachePrivatePtr;
-
-
-#endif /* _XAALOCAL_H */
+
+#ifndef _XAALOCAL_H
+#define _XAALOCAL_H
+
+/* This file is very unorganized ! */
+
+
+#include "gcstruct.h"
+#include "regionstr.h"
+#include "xf86fbman.h"
+#include "xaa.h"
+#include "mi.h"
+#include "picturestr.h"
+
+#define GCWhenForced (GCArcMode << 1)
+
+#define DO_COLOR_8x8 0x00000001
+#define DO_MONO_8x8 0x00000002
+#define DO_CACHE_BLT 0x00000003
+#define DO_COLOR_EXPAND 0x00000004
+#define DO_CACHE_EXPAND 0x00000005
+#define DO_IMAGE_WRITE 0x00000006
+#define DO_PIXMAP_COPY 0x00000007
+#define DO_SOLID 0x00000008
+
+
+typedef CARD32 * (*GlyphScanlineFuncPtr)(
+ CARD32 *base, unsigned int **glyphp, int line, int nglyph, int width
+);
+
+typedef CARD32 *(*StippleScanlineProcPtr)(CARD32*, CARD32*, int, int, int);
+
+typedef void (*RectFuncPtr) (ScrnInfoPtr, int, int, int, int, int, int,
+ XAACacheInfoPtr);
+typedef void (*TrapFuncPtr) (ScrnInfoPtr, int, int, int, int, int, int,
+ int, int, int, int, int, int,
+ XAACacheInfoPtr);
+
+
+
+typedef struct _XAAScreen {
+ CreateGCProcPtr CreateGC;
+ CloseScreenProcPtr CloseScreen;
+ GetImageProcPtr GetImage;
+ GetSpansProcPtr GetSpans;
+ CopyWindowProcPtr CopyWindow;
+ WindowExposuresProcPtr WindowExposures;
+ CreatePixmapProcPtr CreatePixmap;
+ DestroyPixmapProcPtr DestroyPixmap;
+ ChangeWindowAttributesProcPtr ChangeWindowAttributes;
+ XAAInfoRecPtr AccelInfoRec;
+ Bool (*EnterVT)(int, int);
+ void (*LeaveVT)(int, int);
+ int (*SetDGAMode)(int, int, DGADevicePtr);
+ void (*EnableDisableFBAccess)(int, Bool);
+ CompositeProcPtr Composite;
+ GlyphsProcPtr Glyphs;
+} XAAScreenRec, *XAAScreenPtr;
+
+#define OPS_ARE_PIXMAP 0x00000001
+#define OPS_ARE_ACCEL 0x00000002
+
+typedef struct _XAAGC {
+ GCOps *wrapOps;
+ GCFuncs *wrapFuncs;
+ GCOps *XAAOps;
+ int DashLength;
+ unsigned char* DashPattern;
+ unsigned long changes;
+ unsigned long flags;
+} XAAGCRec, *XAAGCPtr;
+
+#define REDUCIBILITY_CHECKED 0x00000001
+#define REDUCIBLE_TO_8x8 0x00000002
+#define REDUCIBLE_TO_2_COLOR 0x00000004
+#define DIRTY 0x00010000
+#define OFFSCREEN 0x00020000
+#define DGA_PIXMAP 0x00040000
+#define SHARED_PIXMAP 0x00080000
+#define LOCKED_PIXMAP 0x00100000
+
+#define REDUCIBILITY_MASK \
+ (REDUCIBILITY_CHECKED | REDUCIBLE_TO_8x8 | REDUCIBLE_TO_2_COLOR)
+
+typedef struct _XAAPixmap {
+ unsigned long flags;
+ CARD32 pattern0;
+ CARD32 pattern1;
+ int fg;
+ int bg;
+ FBAreaPtr offscreenArea;
+ Bool freeData;
+} XAAPixmapRec, *XAAPixmapPtr;
+
+
+extern _X_EXPORT Bool
+XAACreateGC(
+ GCPtr pGC
+);
+
+extern _X_EXPORT Bool
+XAAInitAccel(
+ ScreenPtr pScreen,
+ XAAInfoRecPtr infoRec
+);
+
+extern _X_EXPORT RegionPtr
+XAABitBlt(
+ DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GC *pGC,
+ int srcx,
+ int srcy,
+ int width,
+ int height,
+ int dstx,
+ int dsty,
+ void (*doBitBlt)(DrawablePtr, DrawablePtr, GCPtr, RegionPtr, DDXPointPtr),
+ unsigned long bitPlane
+);
+
+extern _X_EXPORT void
+XAAScreenToScreenBitBlt(
+ ScrnInfoPtr pScrn,
+ int nbox,
+ DDXPointPtr pptSrc,
+ BoxPtr pbox,
+ int xdir,
+ int ydir,
+ int alu,
+ unsigned int planemask
+);
+
+extern _X_EXPORT void
+XAADoBitBlt(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc
+);
+
+extern _X_EXPORT void
+XAADoImageWrite(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc
+);
+
+extern _X_EXPORT void
+XAADoImageRead(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GC *pGC,
+ RegionPtr prgnDst,
+ DDXPointPtr pptSrc
+);
+
+extern _X_EXPORT void
+XAACopyWindow(
+ WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc
+);
+
+
+extern _X_EXPORT RegionPtr
+XAACopyArea(
+ DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GC *pGC,
+ int srcx,
+ int srcy,
+ int width,
+ int height,
+ int dstx,
+ int dsty
+);
+
+extern _X_EXPORT void
+XAAValidateCopyArea(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+);
+
+extern _X_EXPORT void
+XAAValidatePutImage(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+);
+
+extern _X_EXPORT void
+XAAValidateCopyPlane(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+);
+
+extern _X_EXPORT void
+XAAValidatePushPixels(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+);
+
+extern _X_EXPORT void
+XAAValidateFillSpans(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+);
+
+extern _X_EXPORT void
+XAAValidatePolyGlyphBlt(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+);
+
+extern _X_EXPORT void
+XAAValidateImageGlyphBlt(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+);
+
+extern _X_EXPORT void
+XAAValidatePolylines(
+ GCPtr pGC,
+ unsigned long changes,
+ DrawablePtr pDraw
+);
+
+
+extern _X_EXPORT RegionPtr
+XAACopyPlaneColorExpansion(
+ DrawablePtr pSrc,
+ DrawablePtr pDst,
+ GCPtr pGC,
+ int srcx,
+ int srcy,
+ int width,
+ int height,
+ int dstx,
+ int dsty,
+ unsigned long bitPlane
+);
+
+
+extern _X_EXPORT void
+XAAPushPixelsSolidColorExpansion(
+ GCPtr pGC,
+ PixmapPtr pBitMap,
+ DrawablePtr pDrawable,
+ int dx,
+ int dy,
+ int xOrg,
+ int yOrg
+);
+
+extern _X_EXPORT void
+XAAWriteBitmapColorExpandMSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+extern _X_EXPORT void
+XAAWriteBitmapColorExpand3MSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+extern _X_EXPORT void
+XAAWriteBitmapColorExpandMSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+extern _X_EXPORT void
+XAAWriteBitmapColorExpand3MSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+extern _X_EXPORT void
+XAAWriteBitmapColorExpandLSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+extern _X_EXPORT void
+XAAWriteBitmapColorExpand3LSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+extern _X_EXPORT void
+XAAWriteBitmapColorExpandLSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+extern _X_EXPORT void
+XAAWriteBitmapColorExpand3LSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+
+extern _X_EXPORT void
+XAAWriteBitmapScanlineColorExpandMSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+extern _X_EXPORT void
+XAAWriteBitmapScanlineColorExpand3MSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+extern _X_EXPORT void
+XAAWriteBitmapScanlineColorExpandMSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+extern _X_EXPORT void
+XAAWriteBitmapScanlineColorExpand3MSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+extern _X_EXPORT void
+XAAWriteBitmapScanlineColorExpandLSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+extern _X_EXPORT void
+XAAWriteBitmapScanlineColorExpand3LSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+extern _X_EXPORT void
+XAAWriteBitmapScanlineColorExpandLSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+extern _X_EXPORT void
+XAAWriteBitmapScanlineColorExpand3LSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int skipleft,
+ int fg, int bg,
+ int rop,
+ unsigned int planemask
+);
+
+extern _X_EXPORT void
+XAAWritePixmap (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int rop,
+ unsigned int planemask,
+ int transparency_color,
+ int bpp, int depth
+);
+
+extern _X_EXPORT void
+XAAWritePixmapScanline (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int rop,
+ unsigned int planemask,
+ int transparency_color,
+ int bpp, int depth
+);
+
+typedef void (*ClipAndRenderRectsFunc)(GCPtr, int, BoxPtr, int, int);
+
+
+extern _X_EXPORT void
+XAAClipAndRenderRects(
+ GCPtr pGC,
+ ClipAndRenderRectsFunc func,
+ int nrectFill,
+ xRectangle *prectInit,
+ int xorg, int yorg
+);
+
+
+typedef void (*ClipAndRenderSpansFunc)(GCPtr, int, DDXPointPtr, int*,
+ int, int, int);
+
+extern _X_EXPORT void
+XAAClipAndRenderSpans(
+ GCPtr pGC,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ int fSorted,
+ ClipAndRenderSpansFunc func,
+ int xorg,
+ int yorg
+);
+
+
+extern _X_EXPORT void
+XAAFillSolidRects(
+ ScrnInfoPtr pScrn,
+ int fg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox
+);
+
+extern _X_EXPORT void
+XAAFillMono8x8PatternRects(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int pat0, int pat1,
+ int xorg, int yorg
+);
+
+extern _X_EXPORT void
+XAAFillMono8x8PatternRectsScreenOrigin(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int pat0, int pat1,
+ int xorg, int yorg
+);
+
+
+extern _X_EXPORT void
+XAAFillColor8x8PatternRectsScreenOrigin(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorigin, int yorigin,
+ XAACacheInfoPtr pCache
+);
+
+extern _X_EXPORT void
+XAAFillColor8x8PatternRects(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorigin, int yorigin,
+ XAACacheInfoPtr pCache
+);
+
+extern _X_EXPORT void
+XAAFillCacheBltRects(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ XAACacheInfoPtr pCache
+);
+
+extern _X_EXPORT void
+XAAFillCacheExpandRects(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+extern _X_EXPORT void
+XAAFillImageWriteRects(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+extern _X_EXPORT void
+XAAPolyFillRect(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int nrectFill,
+ xRectangle *prectInit
+);
+
+
+extern _X_EXPORT void
+XAATEGlyphRendererMSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+extern _X_EXPORT void
+XAATEGlyphRenderer3MSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+extern _X_EXPORT void
+XAATEGlyphRendererMSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+extern _X_EXPORT void
+XAATEGlyphRenderer3MSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+extern _X_EXPORT void
+XAATEGlyphRendererLSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+
+extern _X_EXPORT void
+XAATEGlyphRenderer3LSBFirstFixedBase (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+extern _X_EXPORT void
+XAATEGlyphRendererLSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+extern _X_EXPORT void
+XAATEGlyphRenderer3LSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+
+extern _X_EXPORT void
+XAATEGlyphRendererScanlineMSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+extern _X_EXPORT void
+XAATEGlyphRendererScanline3MSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+extern _X_EXPORT void
+XAATEGlyphRendererScanlineLSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+extern _X_EXPORT void
+XAATEGlyphRendererScanline3LSBFirst (
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h, int skipleft, int startline,
+ unsigned int **glyphs, int glyphWidth,
+ int fg, int bg, int rop, unsigned planemask
+);
+
+
+extern _X_EXPORT CARD32 *(*XAAGlyphScanlineFuncMSBFirstFixedBase[32])(
+ CARD32 *base, unsigned int **glyphp, int line, int nglyph, int width
+);
+
+extern _X_EXPORT CARD32 *(*XAAGlyphScanlineFuncMSBFirst[32])(
+ CARD32 *base, unsigned int **glyphp, int line, int nglyph, int width
+);
+
+extern _X_EXPORT CARD32 *(*XAAGlyphScanlineFuncLSBFirstFixedBase[32])(
+ CARD32 *base, unsigned int **glyphp, int line, int nglyph, int width
+);
+
+extern _X_EXPORT CARD32 *(*XAAGlyphScanlineFuncLSBFirst[32])(
+ CARD32 *base, unsigned int **glyphp, int line, int nglyph, int width
+);
+
+extern _X_EXPORT GlyphScanlineFuncPtr *XAAGetGlyphScanlineFuncMSBFirstFixedBase(void);
+extern _X_EXPORT GlyphScanlineFuncPtr *XAAGetGlyphScanlineFuncMSBFirst(void);
+extern _X_EXPORT GlyphScanlineFuncPtr *XAAGetGlyphScanlineFuncLSBFirstFixedBase(void);
+extern _X_EXPORT GlyphScanlineFuncPtr *XAAGetGlyphScanlineFuncLSBFirst(void);
+
+extern _X_EXPORT void
+XAAFillColorExpandRectsLSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+extern _X_EXPORT void
+XAAFillColorExpandRects3LSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+extern _X_EXPORT void
+XAAFillColorExpandRectsLSBFirstFixedBase(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+extern _X_EXPORT void
+XAAFillColorExpandRects3LSBFirstFixedBase(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+extern _X_EXPORT void
+XAAFillColorExpandRectsMSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+extern _X_EXPORT void
+XAAFillColorExpandRects3MSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+extern _X_EXPORT void
+XAAFillColorExpandRectsMSBFirstFixedBase(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+extern _X_EXPORT void
+XAAFillColorExpandRects3MSBFirstFixedBase(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+extern _X_EXPORT void
+XAAFillScanlineColorExpandRectsLSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+extern _X_EXPORT void
+XAAFillScanlineColorExpandRects3LSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+extern _X_EXPORT void
+XAAFillScanlineColorExpandRectsMSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+extern _X_EXPORT void
+XAAFillScanlineColorExpandRects3MSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int nBox,
+ BoxPtr pBox,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+extern _X_EXPORT void
+XAAFillColorExpandSpansLSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+extern _X_EXPORT void
+XAAFillColorExpandSpans3LSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+extern _X_EXPORT void
+XAAFillColorExpandSpansLSBFirstFixedBase(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+extern _X_EXPORT void
+XAAFillColorExpandSpans3LSBFirstFixedBase(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+extern _X_EXPORT void
+XAAFillColorExpandSpansMSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+extern _X_EXPORT void
+XAAFillColorExpandSpans3MSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+extern _X_EXPORT void
+XAAFillColorExpandSpansMSBFirstFixedBase(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+extern _X_EXPORT void
+XAAFillColorExpandSpans3MSBFirstFixedBase(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+extern _X_EXPORT void
+XAAFillScanlineColorExpandSpansLSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+extern _X_EXPORT void
+XAAFillScanlineColorExpandSpans3LSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+extern _X_EXPORT void
+XAAPutImage(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int depth,
+ int x,
+ int y,
+ int w,
+ int h,
+ int leftPad,
+ int format,
+ char *pImage
+);
+
+extern _X_EXPORT void
+XAAFillScanlineColorExpandSpansMSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+extern _X_EXPORT void
+XAAFillScanlineColorExpandSpans3MSBFirst(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+
+extern _X_EXPORT CARD32 *(*XAAStippleScanlineFuncMSBFirstFixedBase[6])(
+ CARD32* base, CARD32* src, int offset, int width, int dwords
+);
+
+extern _X_EXPORT CARD32 *(*XAAStippleScanlineFuncMSBFirst[6])(
+ CARD32* base, CARD32* src, int offset, int width, int dwords
+);
+
+extern _X_EXPORT CARD32 *(*XAAStippleScanlineFuncLSBFirstFixedBase[6])(
+ CARD32* base, CARD32* src, int offset, int width, int dwords
+);
+
+extern _X_EXPORT CARD32 *(*XAAStippleScanlineFuncLSBFirst[6])(
+ CARD32* base, CARD32* src, int offset, int width, int dwords
+);
+
+extern _X_EXPORT StippleScanlineProcPtr *XAAGetStippleScanlineFuncMSBFirstFixedBase(void);
+extern _X_EXPORT StippleScanlineProcPtr *XAAGetStippleScanlineFuncMSBFirst(void);
+extern _X_EXPORT StippleScanlineProcPtr *XAAGetStippleScanlineFuncLSBFirstFixedBase(void);
+extern _X_EXPORT StippleScanlineProcPtr *XAAGetStippleScanlineFuncLSBFirst(void);
+extern _X_EXPORT StippleScanlineProcPtr *XAAGetStippleScanlineFunc3MSBFirstFixedBase(void);
+extern _X_EXPORT StippleScanlineProcPtr *XAAGetStippleScanlineFunc3MSBFirst(void);
+extern _X_EXPORT StippleScanlineProcPtr *XAAGetStippleScanlineFunc3LSBFirstFixedBase(void);
+extern _X_EXPORT StippleScanlineProcPtr *XAAGetStippleScanlineFunc3LSBFirst(void);
+
+extern _X_EXPORT int
+XAAPolyText8TEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars
+);
+
+extern _X_EXPORT int
+XAAPolyText16TEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars
+);
+
+extern _X_EXPORT void
+XAAImageText8TEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars
+);
+
+extern _X_EXPORT void
+XAAImageText16TEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars
+);
+
+extern _X_EXPORT void
+XAAImageGlyphBltTEColorExpansion(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+);
+
+extern _X_EXPORT void
+XAAPolyGlyphBltTEColorExpansion(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+);
+
+
+extern _X_EXPORT int
+XAAPolyText8NonTEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars
+);
+
+extern _X_EXPORT int
+XAAPolyText16NonTEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars
+);
+
+extern _X_EXPORT void
+XAAImageText8NonTEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ char *chars
+);
+
+extern _X_EXPORT void
+XAAImageText16NonTEColorExpansion(
+ DrawablePtr pDraw,
+ GCPtr pGC,
+ int x, int y,
+ int count,
+ unsigned short *chars
+);
+
+extern _X_EXPORT void
+XAAImageGlyphBltNonTEColorExpansion(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+);
+
+extern _X_EXPORT void
+XAAPolyGlyphBltNonTEColorExpansion(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int xInit, int yInit,
+ unsigned int nglyph,
+ CharInfoPtr *ppci,
+ pointer pglyphBase
+);
+
+
+extern _X_EXPORT void XAANonTEGlyphRenderer(
+ ScrnInfoPtr pScrn,
+ int x, int y, int n,
+ NonTEGlyphPtr glyphs,
+ BoxPtr pbox,
+ int fg, int rop,
+ unsigned int planemask
+);
+
+extern _X_EXPORT void
+XAAFillSolidSpans(
+ ScrnInfoPtr pScrn,
+ int fg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth, int fSorted
+);
+
+extern _X_EXPORT void
+XAAFillMono8x8PatternSpans(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth, int fSorted,
+ int patx, int paty,
+ int xorg, int yorg
+);
+
+extern _X_EXPORT void
+XAAFillMono8x8PatternSpansScreenOrigin(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth, int fSorted,
+ int patx, int paty,
+ int xorg, int yorg
+);
+
+extern _X_EXPORT void
+XAAFillColor8x8PatternSpansScreenOrigin(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth, int fSorted,
+ XAACacheInfoPtr,
+ int xorigin, int yorigin
+);
+
+extern _X_EXPORT void
+XAAFillColor8x8PatternSpans(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth, int fSorted,
+ XAACacheInfoPtr,
+ int xorigin, int yorigin
+);
+
+extern _X_EXPORT void
+XAAFillCacheBltSpans(
+ ScrnInfoPtr pScrn,
+ int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr points,
+ int *widths,
+ int fSorted,
+ XAACacheInfoPtr pCache,
+ int xorg, int yorg
+);
+
+extern _X_EXPORT void
+XAAFillCacheExpandSpans(
+ ScrnInfoPtr pScrn,
+ int fg, int bg, int rop,
+ unsigned int planemask,
+ int n,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int fSorted,
+ int xorg, int yorg,
+ PixmapPtr pPix
+);
+
+extern _X_EXPORT void
+XAAFillSpans(
+ DrawablePtr pDrawable,
+ GC *pGC,
+ int nInit,
+ DDXPointPtr pptInit,
+ int *pwidth,
+ int fSorted
+);
+
+
+extern _X_EXPORT void
+XAAInitPixmapCache(
+ ScreenPtr pScreen,
+ RegionPtr areas,
+ pointer data
+);
+
+extern _X_EXPORT void
+XAAWriteBitmapToCache(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int fg, int bg
+);
+
+extern _X_EXPORT void
+XAAWriteBitmapToCacheLinear(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int fg, int bg
+);
+
+extern _X_EXPORT void
+XAAWritePixmapToCache(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int bpp, int depth
+);
+
+extern _X_EXPORT void
+XAAWritePixmapToCacheLinear(
+ ScrnInfoPtr pScrn,
+ int x, int y, int w, int h,
+ unsigned char *src,
+ int srcwidth,
+ int bpp, int depth
+);
+
+extern _X_EXPORT void
+XAASolidHorVertLineAsRects(
+ ScrnInfoPtr pScrn,
+ int x, int y, int len, int dir
+);
+
+extern _X_EXPORT void
+XAASolidHorVertLineAsTwoPoint(
+ ScrnInfoPtr pScrn,
+ int x, int y, int len, int dir
+);
+
+extern _X_EXPORT void
+XAASolidHorVertLineAsBresenham(
+ ScrnInfoPtr pScrn,
+ int x, int y, int len, int dir
+);
+
+
+extern _X_EXPORT void
+XAAPolyRectangleThinSolid(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nRectsInit,
+ xRectangle *pRectsInit
+);
+
+
+extern _X_EXPORT void
+XAAPolylinesWideSolid (
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pPts
+);
+
+extern _X_EXPORT void
+XAAFillPolygonSolid(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+);
+
+extern _X_EXPORT void
+XAAFillPolygonStippled(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+);
+
+
+extern _X_EXPORT void
+XAAFillPolygonTiled(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int shape,
+ int mode,
+ int count,
+ DDXPointPtr ptsIn
+);
+
+
+extern _X_EXPORT int
+XAAIsEasyPolygon(
+ DDXPointPtr ptsIn,
+ int count,
+ BoxPtr extents,
+ int origin,
+ DDXPointPtr *topPoint,
+ int *topY, int *bottomY,
+ int shape
+);
+
+extern _X_EXPORT void
+XAAFillPolygonHelper(
+ ScrnInfoPtr pScrn,
+ DDXPointPtr ptsIn,
+ int count,
+ DDXPointPtr topPoint,
+ int y,
+ int maxy,
+ int origin,
+ RectFuncPtr RectFunc,
+ TrapFuncPtr TrapFunc,
+ int xorg,
+ int yorg,
+ XAACacheInfoPtr pCache
+);
+
+extern _X_EXPORT void
+XAAPolySegment(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+);
+
+extern _X_EXPORT void
+XAAPolyLines(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pptInit
+);
+
+extern _X_EXPORT void
+XAAPolySegmentDashed(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nseg,
+ xSegment *pSeg
+);
+
+extern _X_EXPORT void
+XAAPolyLinesDashed(
+ DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr pptInit
+);
+
+
+extern _X_EXPORT void
+XAAWriteMono8x8PatternToCache(ScrnInfoPtr pScrn, XAACacheInfoPtr pCache);
+
+extern _X_EXPORT void
+XAAWriteColor8x8PatternToCache(
+ ScrnInfoPtr pScrn,
+ PixmapPtr pPix,
+ XAACacheInfoPtr pCache
+);
+
+extern _X_EXPORT void
+XAARotateMonoPattern(
+ int *pat0, int *pat1,
+ int xoffset, int yoffset,
+ Bool msbfirst
+);
+
+extern _X_EXPORT void XAAComputeDash(GCPtr pGC);
+
+extern _X_EXPORT void XAAMoveDWORDS_FixedBase(
+ register CARD32* dest,
+ register CARD32* src,
+ register int dwords
+);
+
+extern _X_EXPORT void XAAMoveDWORDS_FixedSrc(
+ register CARD32* dest,
+ register CARD32* src,
+ register int dwords
+);
+
+extern _X_EXPORT void XAAMoveDWORDS(
+ register CARD32* dest,
+ register CARD32* src,
+ register int dwords
+);
+
+extern _X_EXPORT int
+XAAGetRectClipBoxes(
+ GCPtr pGC,
+ BoxPtr pboxClippedBase,
+ int nrectFill,
+ xRectangle *prectInit
+);
+
+extern _X_EXPORT void
+XAASetupOverlay8_32Planar(ScreenPtr);
+
+extern _X_EXPORT void
+XAAPolyFillArcSolid(DrawablePtr pDraw, GCPtr pGC, int narcs, xArc *parcs);
+
+extern _X_EXPORT XAACacheInfoPtr
+XAACacheTile(ScrnInfoPtr Scrn, PixmapPtr pPix);
+
+extern _X_EXPORT XAACacheInfoPtr
+XAACacheMonoStipple(ScrnInfoPtr Scrn, PixmapPtr pPix);
+
+extern _X_EXPORT XAACacheInfoPtr
+XAACachePlanarMonoStipple(ScrnInfoPtr Scrn, PixmapPtr pPix);
+
+typedef XAACacheInfoPtr (*XAACachePlanarMonoStippleProc)(ScrnInfoPtr, PixmapPtr);
+extern _X_EXPORT XAACachePlanarMonoStippleProc XAAGetCachePlanarMonoStipple(void);
+
+extern _X_EXPORT XAACacheInfoPtr
+XAACacheStipple(ScrnInfoPtr Scrn, PixmapPtr pPix, int fg, int bg);
+
+extern _X_EXPORT XAACacheInfoPtr
+XAACacheMono8x8Pattern(ScrnInfoPtr Scrn, int pat0, int pat1);
+
+extern _X_EXPORT XAACacheInfoPtr
+XAACacheColor8x8Pattern(ScrnInfoPtr Scrn, PixmapPtr pPix, int fg, int bg);
+
+extern _X_EXPORT void
+XAATileCache(ScrnInfoPtr pScrn, XAACacheInfoPtr pCache, int w, int h);
+
+extern _X_EXPORT void XAAClosePixmapCache(ScreenPtr pScreen);
+void XAAInvalidatePixmapCache(ScreenPtr pScreen);
+
+extern _X_EXPORT Bool XAACheckStippleReducibility(PixmapPtr pPixmap);
+extern _X_EXPORT Bool XAACheckTileReducibility(PixmapPtr pPixmap, Bool checkMono);
+
+extern _X_EXPORT int XAAStippledFillChooser(GCPtr pGC);
+extern _X_EXPORT int XAAOpaqueStippledFillChooser(GCPtr pGC);
+extern _X_EXPORT int XAATiledFillChooser(GCPtr pGC);
+
+extern _X_EXPORT void XAAMoveInOffscreenPixmaps(ScreenPtr pScreen);
+extern _X_EXPORT void XAAMoveOutOffscreenPixmaps(ScreenPtr pScreen);
+extern _X_EXPORT void XAARemoveAreaCallback(FBAreaPtr area);
+extern _X_EXPORT void XAAMoveOutOffscreenPixmap(PixmapPtr pPix);
+extern _X_EXPORT Bool XAAInitStateWrap(ScreenPtr pScreen, XAAInfoRecPtr infoRec);
+
+extern _X_EXPORT void
+XAAComposite (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+
+extern _X_EXPORT Bool
+XAADoComposite (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height);
+
+
+extern _X_EXPORT void
+XAAGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs);
+
+extern _X_EXPORT Bool
+XAADoGlyphs (CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pDst,
+ PictFormatPtr maskFormat,
+ INT16 xSrc,
+ INT16 ySrc,
+ int nlist,
+ GlyphListPtr list,
+ GlyphPtr *glyphs);
+
+
+
+/* helpers */
+extern _X_EXPORT void
+XAA_888_plus_PICT_a8_to_8888 (
+ CARD32 color,
+ CARD8 *alphaPtr, /* in bytes */
+ int alphaPitch,
+ CARD32 *dstPtr,
+ int dstPitch, /* in dwords */
+ int width,
+ int height
+);
+
+extern _X_EXPORT Bool
+XAAGetRGBAFromPixel(
+ CARD32 pixel,
+ CARD16 *red,
+ CARD16 *green,
+ CARD16 *blue,
+ CARD16 *alpha,
+ CARD32 format
+);
+
+
+extern _X_EXPORT Bool
+XAAGetPixelFromRGBA (
+ CARD32 *pixel,
+ CARD16 red,
+ CARD16 green,
+ CARD16 blue,
+ CARD16 alpha,
+ CARD32 format
+);
+
+/* XXX should be static */
+extern _X_EXPORT GCOps XAAFallbackOps;
+extern _X_EXPORT GCOps *XAAGetFallbackOps(void);
+extern _X_EXPORT GCFuncs XAAGCFuncs;
+extern _X_EXPORT DevPrivateKey XAAGetScreenKey(void);
+extern _X_EXPORT DevPrivateKey XAAGetGCKey(void);
+extern _X_EXPORT DevPrivateKey XAAGetPixmapKey(void);
+
+extern _X_EXPORT unsigned int XAAShiftMasks[32];
+
+extern _X_EXPORT unsigned int byte_expand3[256], byte_reversed_expand3[256];
+
+extern _X_EXPORT CARD32 XAAReverseBitOrder(CARD32 data);
+
+#define GET_XAASCREENPTR_FROM_SCREEN(pScreen)\
+ dixLookupPrivate(&(pScreen)->devPrivates, XAAGetScreenKey())
+
+#define GET_XAASCREENPTR_FROM_GC(pGC)\
+ dixLookupPrivate(&(pGC)->pScreen->devPrivates, XAAGetScreenKey())
+
+#define GET_XAASCREENPTR_FROM_DRAWABLE(pDraw)\
+ dixLookupPrivate(&(pDraw)->pScreen->devPrivates, XAAGetScreenKey())
+
+#define GET_XAAINFORECPTR_FROM_SCREEN(pScreen)\
+((XAAScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates, XAAGetScreenKey()))->AccelInfoRec
+
+#define GET_XAAINFORECPTR_FROM_GC(pGC)\
+((XAAScreenPtr)dixLookupPrivate(&(pGC)->pScreen->devPrivates, XAAGetScreenKey()))->AccelInfoRec
+
+#define GET_XAAINFORECPTR_FROM_DRAWABLE(pDraw)\
+((XAAScreenPtr)dixLookupPrivate(&(pDraw)->pScreen->devPrivates, XAAGetScreenKey()))->AccelInfoRec
+
+#define GET_XAAINFORECPTR_FROM_SCRNINFOPTR(pScrn)\
+((XAAScreenPtr)dixLookupPrivate(&(pScrn)->pScreen->devPrivates, XAAGetScreenKey()))->AccelInfoRec
+
+#define XAA_GET_PIXMAP_PRIVATE(pix)\
+ (XAAPixmapPtr)dixLookupPrivate(&(pix)->devPrivates, XAAGetPixmapKey())
+
+#define CHECK_RGB_EQUAL(c) (!((((c) >> 8) ^ (c)) & 0xffff))
+
+#define CHECK_FG(pGC, flags) \
+ (!(flags & RGB_EQUAL) || CHECK_RGB_EQUAL(pGC->fgPixel))
+
+#define CHECK_BG(pGC, flags) \
+ (!(flags & RGB_EQUAL) || CHECK_RGB_EQUAL(pGC->bgPixel))
+
+#define CHECK_ROP(pGC, flags) \
+ (!(flags & GXCOPY_ONLY) || (pGC->alu == GXcopy))
+
+#define CHECK_ROPSRC(pGC, flags) \
+ (!(flags & ROP_NEEDS_SOURCE) || ((pGC->alu != GXclear) && \
+ (pGC->alu != GXnoop) && (pGC->alu != GXinvert) && \
+ (pGC->alu != GXset)))
+
+#define CHECK_PLANEMASK(pGC, flags) \
+ (!(flags & NO_PLANEMASK) || \
+ ((pGC->planemask & infoRec->FullPlanemasks[pGC->depth - 1]) == \
+ infoRec->FullPlanemasks[pGC->depth - 1]))
+
+#define CHECK_COLORS(pGC, flags) \
+ (!(flags & RGB_EQUAL) || \
+ (CHECK_RGB_EQUAL(pGC->fgPixel) && CHECK_RGB_EQUAL(pGC->bgPixel)))
+
+#define CHECK_NO_GXCOPY(pGC, flags) \
+ ((pGC->alu != GXcopy) || !(flags & NO_GXCOPY) || \
+ ((pGC->planemask & infoRec->FullPlanemask) != infoRec->FullPlanemask))
+
+#define IS_OFFSCREEN_PIXMAP(pPix)\
+ ((XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pPix)))->offscreenArea)
+
+#define PIXMAP_IS_SHARED(pPix)\
+ ((XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pPix)))->flags & SHARED_PIXMAP)
+
+#define OFFSCREEN_PIXMAP_LOCKED(pPix)\
+ ((XAA_GET_PIXMAP_PRIVATE((PixmapPtr)(pPix)))->flags & LOCKED_PIXMAP)
+
+#define XAA_DEPTH_BUG(pGC) \
+ ((pGC->depth == 32) && (pGC->bgPixel == 0xffffffff))
+
+#define DELIST_OFFSCREEN_PIXMAP(pPix) { \
+ PixmapLinkPtr _pLink, _prev; \
+ _pLink = infoRec->OffscreenPixmaps; \
+ _prev = NULL; \
+ while(_pLink) { \
+ if(_pLink->pPix == pPix) { \
+ if(_prev) _prev->next = _pLink->next; \
+ else infoRec->OffscreenPixmaps = _pLink->next; \
+ free(_pLink); \
+ break; \
+ } \
+ _prev = _pLink; \
+ _pLink = _pLink->next; \
+ }}
+
+
+#define SWAP_BITS_IN_BYTES(v) \
+ (((0x01010101 & (v)) << 7) | ((0x02020202 & (v)) << 5) | \
+ ((0x04040404 & (v)) << 3) | ((0x08080808 & (v)) << 1) | \
+ ((0x10101010 & (v)) >> 1) | ((0x20202020 & (v)) >> 3) | \
+ ((0x40404040 & (v)) >> 5) | ((0x80808080 & (v)) >> 7))
+
+/*
+ * Moved XAAPixmapCachePrivate here from xaaPCache.c, since driver
+ * replacements for CacheMonoStipple need access to it
+ */
+
+typedef struct {
+ int Num512x512;
+ int Current512;
+ XAACacheInfoPtr Info512;
+ int Num256x256;
+ int Current256;
+ XAACacheInfoPtr Info256;
+ int Num128x128;
+ int Current128;
+ XAACacheInfoPtr Info128;
+ int NumMono;
+ int CurrentMono;
+ XAACacheInfoPtr InfoMono;
+ int NumColor;
+ int CurrentColor;
+ XAACacheInfoPtr InfoColor;
+ int NumPartial;
+ int CurrentPartial;
+ XAACacheInfoPtr InfoPartial;
+ DDXPointRec MonoOffsets[64];
+ DDXPointRec ColorOffsets[64];
+} XAAPixmapCachePrivate, *XAAPixmapCachePrivatePtr;
+
+
+#endif /* _XAALOCAL_H */
diff --git a/xorg-server/hw/xnest/Color.c b/xorg-server/hw/xnest/Color.c
index 2e6de15e4..985b5ad95 100644
--- a/xorg-server/hw/xnest/Color.c
+++ b/xorg-server/hw/xnest/Color.c
@@ -1,495 +1,495 @@
-/*
-
-Copyright 1993 by Davor Matic
-
-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. Davor Matic makes no representations about
-the suitability of this software for any purpose. It is provided "as
-is" without express or implied warranty.
-
-*/
-
-#ifdef HAVE_XNEST_CONFIG_H
-#include <xnest-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "scrnintstr.h"
-#include "window.h"
-#include "windowstr.h"
-#include "colormapst.h"
-#include "resource.h"
-
-#include "Xnest.h"
-
-
-#include "Display.h"
-#include "Screen.h"
-#include "Color.h"
-#include "Visual.h"
-#include "XNWindow.h"
-#include "Args.h"
-
-static int cmapScrPrivateKeyIndex;
-static DevPrivateKey cmapScrPrivateKey = &cmapScrPrivateKeyIndex;
-
-#define GetInstalledColormap(s) ((ColormapPtr) dixLookupPrivate(&(s)->devPrivates, cmapScrPrivateKey))
-#define SetInstalledColormap(s,c) (dixSetPrivate(&(s)->devPrivates, cmapScrPrivateKey, c))
-
-Bool
-xnestCreateColormap(ColormapPtr pCmap)
-{
- VisualPtr pVisual;
- XColor *colors;
- int i, ncolors;
- Pixel red, green, blue;
- Pixel redInc, greenInc, blueInc;
-
- pVisual = pCmap->pVisual;
- ncolors = pVisual->ColormapEntries;
-
- pCmap->devPriv = (pointer)xalloc(sizeof(xnestPrivColormap));
-
- xnestColormapPriv(pCmap)->colormap =
- XCreateColormap(xnestDisplay,
- xnestDefaultWindows[pCmap->pScreen->myNum],
- xnestVisual(pVisual),
- (pVisual->class & DynamicClass) ?
- AllocAll : AllocNone);
-
-
- switch (pVisual->class) {
- case StaticGray: /* read only */
- colors = (XColor *)xalloc(ncolors * sizeof(XColor));
- for (i = 0; i < ncolors; i++)
- colors[i].pixel = i;
- XQueryColors(xnestDisplay, xnestColormap(pCmap), colors, ncolors);
- for (i = 0; i < ncolors; i++) {
- pCmap->red[i].co.local.red = colors[i].red;
- pCmap->red[i].co.local.green = colors[i].red;
- pCmap->red[i].co.local.blue = colors[i].red;
- }
- xfree(colors);
- break;
-
- case StaticColor: /* read only */
- colors = (XColor *)xalloc(ncolors * sizeof(XColor));
- for (i = 0; i < ncolors; i++)
- colors[i].pixel = i;
- XQueryColors(xnestDisplay, xnestColormap(pCmap), colors, ncolors);
- for (i = 0; i < ncolors; i++) {
- pCmap->red[i].co.local.red = colors[i].red;
- pCmap->red[i].co.local.green = colors[i].green;
- pCmap->red[i].co.local.blue = colors[i].blue;
- }
- xfree(colors);
- break;
-
- case TrueColor: /* read only */
- colors = (XColor *)xalloc(ncolors * sizeof(XColor));
- red = green = blue = 0L;
- redInc = lowbit(pVisual->redMask);
- greenInc = lowbit(pVisual->greenMask);
- blueInc = lowbit(pVisual->blueMask);
- for (i = 0; i < ncolors; i++) {
- colors[i].pixel = red | green | blue;
- red += redInc;
- if (red > pVisual->redMask) red = 0L;
- green += greenInc;
- if (green > pVisual->greenMask) green = 0L;
- blue += blueInc;
- if (blue > pVisual->blueMask) blue = 0L;
- }
- XQueryColors(xnestDisplay, xnestColormap(pCmap), colors, ncolors);
- for (i = 0; i < ncolors; i++) {
- pCmap->red[i].co.local.red = colors[i].red;
- pCmap->green[i].co.local.green = colors[i].green;
- pCmap->blue[i].co.local.blue = colors[i].blue;
- }
- xfree(colors);
- break;
-
- case GrayScale: /* read and write */
- break;
-
- case PseudoColor: /* read and write */
- break;
-
- case DirectColor: /* read and write */
- break;
- }
-
- return True;
-}
-
-void
-xnestDestroyColormap(ColormapPtr pCmap)
-{
- XFreeColormap(xnestDisplay, xnestColormap(pCmap));
- xfree(pCmap->devPriv);
-}
-
-#define SEARCH_PREDICATE \
- (xnestWindow(pWin) != None && wColormap(pWin) == icws->cmapIDs[i])
-
-static int
-xnestCountInstalledColormapWindows(WindowPtr pWin, pointer ptr)
-{
- xnestInstalledColormapWindows *icws = (xnestInstalledColormapWindows *)ptr;
- int i;
-
- for (i = 0; i < icws->numCmapIDs; i++)
- if (SEARCH_PREDICATE) {
- icws->numWindows++;
- return WT_DONTWALKCHILDREN;
- }
-
- return WT_WALKCHILDREN;
-}
-
-static int
-xnestGetInstalledColormapWindows(WindowPtr pWin, pointer ptr)
-{
- xnestInstalledColormapWindows *icws = (xnestInstalledColormapWindows *)ptr;
- int i;
-
- for (i = 0; i < icws->numCmapIDs; i++)
- if (SEARCH_PREDICATE) {
- icws->windows[icws->index++] = xnestWindow(pWin);
- return WT_DONTWALKCHILDREN;
- }
-
- return WT_WALKCHILDREN;
-}
-
-static Window *xnestOldInstalledColormapWindows = NULL;
-static int xnestNumOldInstalledColormapWindows = 0;
-
-static Bool
-xnestSameInstalledColormapWindows(Window *windows, int numWindows)
-{
- if (xnestNumOldInstalledColormapWindows != numWindows)
- return False;
-
- if (xnestOldInstalledColormapWindows == windows)
- return True;
-
- if (xnestOldInstalledColormapWindows == NULL || windows == NULL)
- return False;
-
- if (memcmp(xnestOldInstalledColormapWindows, windows,
- numWindows * sizeof(Window)))
- return False;
-
- return True;
-}
-
-void
-xnestSetInstalledColormapWindows(ScreenPtr pScreen)
-{
- xnestInstalledColormapWindows icws;
- int numWindows;
-
- icws.cmapIDs = (Colormap *)xalloc(pScreen->maxInstalledCmaps *
- sizeof(Colormap));
- icws.numCmapIDs = xnestListInstalledColormaps(pScreen, icws.cmapIDs);
- icws.numWindows = 0;
- WalkTree(pScreen, xnestCountInstalledColormapWindows, (pointer)&icws);
- if (icws.numWindows) {
- icws.windows = (Window *)xalloc((icws.numWindows + 1) * sizeof(Window));
- icws.index = 0;
- WalkTree(pScreen, xnestGetInstalledColormapWindows, (pointer)&icws);
- icws.windows[icws.numWindows] = xnestDefaultWindows[pScreen->myNum];
- numWindows = icws.numWindows + 1;
- }
- else {
- icws.windows = NULL;
- numWindows = 0;
- }
-
- xfree(icws.cmapIDs);
-
- if (!xnestSameInstalledColormapWindows(icws.windows, icws.numWindows)) {
- if (xnestOldInstalledColormapWindows)
- xfree(xnestOldInstalledColormapWindows);
-
-#ifdef _XSERVER64
- {
- int i;
- Window64 *windows = (Window64 *)xalloc(numWindows * sizeof(Window64));
-
- for(i = 0; i < numWindows; ++i)
- windows[i] = icws.windows[i];
- XSetWMColormapWindows(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
- windows, numWindows);
- xfree(windows);
- }
-#else
- XSetWMColormapWindows(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
- icws.windows, numWindows);
-#endif
-
- xnestOldInstalledColormapWindows = icws.windows;
- xnestNumOldInstalledColormapWindows = icws.numWindows;
-
-#ifdef DUMB_WINDOW_MANAGERS
- /*
- This code is for dumb window managers.
- This will only work with default local visual colormaps.
- */
- if (icws.numWindows)
- {
- WindowPtr pWin;
- Visual *visual;
- ColormapPtr pCmap;
-
- pWin = xnestWindowPtr(icws.windows[0]);
- visual = xnestVisualFromID(pScreen, wVisual(pWin));
-
- if (visual == xnestDefaultVisual(pScreen))
- dixLookupResourceByType((pointer *)&pCmap, wColormap(pWin),
- RT_COLORMAP, serverClient, DixUseAccess);
- else
- dixLookupResourceByType((pointer *)&pCmap, pScreen->defColormap,
- RT_COLORMAP, serverClient, DixUseAccess);
-
- XSetWindowColormap(xnestDisplay,
- xnestDefaultWindows[pScreen->myNum],
- xnestColormap(pCmap));
- }
-#endif /* DUMB_WINDOW_MANAGERS */
- }
- else
- if (icws.windows) xfree(icws.windows);
-}
-
-void
-xnestSetScreenSaverColormapWindow(ScreenPtr pScreen)
-{
- if (xnestOldInstalledColormapWindows)
- xfree(xnestOldInstalledColormapWindows);
-
-#ifdef _XSERVER64
- {
- Window64 window;
-
- window = xnestScreenSaverWindows[pScreen->myNum];
- XSetWMColormapWindows(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
- &window, 1);
- xnestScreenSaverWindows[pScreen->myNum] = window;
- }
-#else
- XSetWMColormapWindows(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
- &xnestScreenSaverWindows[pScreen->myNum], 1);
-#endif /* _XSERVER64 */
-
- xnestOldInstalledColormapWindows = NULL;
- xnestNumOldInstalledColormapWindows = 0;
-
- xnestDirectUninstallColormaps(pScreen);
-}
-
-void
-xnestDirectInstallColormaps(ScreenPtr pScreen)
-{
- int i, n;
- Colormap pCmapIDs[MAXCMAPS];
-
- if (!xnestDoDirectColormaps) return;
-
- n = (*pScreen->ListInstalledColormaps)(pScreen, pCmapIDs);
-
- for (i = 0; i < n; i++) {
- ColormapPtr pCmap;
-
- dixLookupResourceByType((pointer *)&pCmap, pCmapIDs[i], RT_COLORMAP,
- serverClient, DixInstallAccess);
- if (pCmap)
- XInstallColormap(xnestDisplay, xnestColormap(pCmap));
- }
-}
-
-void
-xnestDirectUninstallColormaps(ScreenPtr pScreen)
-{
- int i, n;
- Colormap pCmapIDs[MAXCMAPS];
-
- if (!xnestDoDirectColormaps) return;
-
- n = (*pScreen->ListInstalledColormaps)(pScreen, pCmapIDs);
-
- for (i = 0; i < n; i++) {
- ColormapPtr pCmap;
-
- dixLookupResourceByType((pointer *)&pCmap, pCmapIDs[i], RT_COLORMAP,
- serverClient, DixUninstallAccess);
- if (pCmap)
- XUninstallColormap(xnestDisplay, xnestColormap(pCmap));
- }
-}
-
-void
-xnestInstallColormap(ColormapPtr pCmap)
-{
- ColormapPtr pOldCmap = GetInstalledColormap(pCmap->pScreen);
-
- if(pCmap != pOldCmap)
- {
- xnestDirectUninstallColormaps(pCmap->pScreen);
-
- /* Uninstall pInstalledMap. Notify all interested parties. */
- if(pOldCmap != (ColormapPtr)None)
- WalkTree(pCmap->pScreen, TellLostMap, (pointer)&pOldCmap->mid);
-
- SetInstalledColormap(pCmap->pScreen, pCmap);
- WalkTree(pCmap->pScreen, TellGainedMap, (pointer)&pCmap->mid);
-
- xnestSetInstalledColormapWindows(pCmap->pScreen);
- xnestDirectInstallColormaps(pCmap->pScreen);
- }
-}
-
-void
-xnestUninstallColormap(ColormapPtr pCmap)
-{
- ColormapPtr pCurCmap = GetInstalledColormap(pCmap->pScreen);
-
- if(pCmap == pCurCmap)
- {
- if (pCmap->mid != pCmap->pScreen->defColormap)
- {
- dixLookupResourceByType((pointer *)&pCurCmap,
- pCmap->pScreen->defColormap,
- RT_COLORMAP,
- serverClient, DixInstallAccess);
- (*pCmap->pScreen->InstallColormap)(pCurCmap);
- }
- }
-}
-
-static Bool xnestInstalledDefaultColormap = False;
-
-int
-xnestListInstalledColormaps(ScreenPtr pScreen, Colormap *pCmapIDs)
-{
- if (xnestInstalledDefaultColormap) {
- *pCmapIDs = GetInstalledColormap(pScreen)->mid;
- return 1;
- }
- else
- return 0;
-}
-
-void
-xnestStoreColors(ColormapPtr pCmap, int nColors, xColorItem *pColors)
-{
- if (pCmap->pVisual->class & DynamicClass)
-#ifdef _XSERVER64
- {
- int i;
- XColor *pColors64 = (XColor *)xalloc(nColors * sizeof(XColor) );
-
- for(i = 0; i < nColors; ++i)
- {
- pColors64[i].pixel = pColors[i].pixel;
- pColors64[i].red = pColors[i].red;
- pColors64[i].green = pColors[i].green;
- pColors64[i].blue = pColors[i].blue;
- pColors64[i].flags = pColors[i].flags;
- }
- XStoreColors(xnestDisplay, xnestColormap(pCmap), pColors64, nColors);
- xfree(pColors64);
- }
-#else
- XStoreColors(xnestDisplay, xnestColormap(pCmap),
- (XColor *)pColors, nColors);
-#endif
-}
-
-void
-xnestResolveColor(unsigned short *pRed, unsigned short *pGreen,
- unsigned short *pBlue, VisualPtr pVisual)
-{
- int shift;
- unsigned int lim;
-
- shift = 16 - pVisual->bitsPerRGBValue;
- lim = (1 << pVisual->bitsPerRGBValue) - 1;
-
- if ((pVisual->class == PseudoColor) || (pVisual->class == DirectColor))
- {
- /* rescale to rgb bits */
- *pRed = ((*pRed >> shift) * 65535) / lim;
- *pGreen = ((*pGreen >> shift) * 65535) / lim;
- *pBlue = ((*pBlue >> shift) * 65535) / lim;
- }
- else if (pVisual->class == GrayScale)
- {
- /* rescale to gray then rgb bits */
- *pRed = (30L * *pRed + 59L * *pGreen + 11L * *pBlue) / 100;
- *pBlue = *pGreen = *pRed = ((*pRed >> shift) * 65535) / lim;
- }
- else if (pVisual->class == StaticGray)
- {
- unsigned int limg;
-
- limg = pVisual->ColormapEntries - 1;
- /* rescale to gray then [0..limg] then [0..65535] then rgb bits */
- *pRed = (30L * *pRed + 59L * *pGreen + 11L * *pBlue) / 100;
- *pRed = ((((*pRed * (limg + 1))) >> 16) * 65535) / limg;
- *pBlue = *pGreen = *pRed = ((*pRed >> shift) * 65535) / lim;
- }
- else
- {
- unsigned limr, limg, limb;
-
- limr = pVisual->redMask >> pVisual->offsetRed;
- limg = pVisual->greenMask >> pVisual->offsetGreen;
- limb = pVisual->blueMask >> pVisual->offsetBlue;
- /* rescale to [0..limN] then [0..65535] then rgb bits */
- *pRed = ((((((*pRed * (limr + 1)) >> 16) *
- 65535) / limr) >> shift) * 65535) / lim;
- *pGreen = ((((((*pGreen * (limg + 1)) >> 16) *
- 65535) / limg) >> shift) * 65535) / lim;
- *pBlue = ((((((*pBlue * (limb + 1)) >> 16) *
- 65535) / limb) >> shift) * 65535) / lim;
- }
-}
-
-Bool
-xnestCreateDefaultColormap(ScreenPtr pScreen)
-{
- VisualPtr pVisual;
- ColormapPtr pCmap;
- unsigned short zero = 0, ones = 0xFFFF;
- Pixel wp, bp;
-
- for (pVisual = pScreen->visuals;
- pVisual->vid != pScreen->rootVisual;
- pVisual++);
-
- if (CreateColormap(pScreen->defColormap, pScreen, pVisual, &pCmap,
- (pVisual->class & DynamicClass) ? AllocNone : AllocAll, 0)
- != Success)
- return False;
-
- wp = pScreen->whitePixel;
- bp = pScreen->blackPixel;
- if ((AllocColor(pCmap, &ones, &ones, &ones, &wp, 0) !=
- Success) ||
- (AllocColor(pCmap, &zero, &zero, &zero, &bp, 0) !=
- Success))
- return FALSE;
- pScreen->whitePixel = wp;
- pScreen->blackPixel = bp;
- (*pScreen->InstallColormap)(pCmap);
-
- xnestInstalledDefaultColormap = True;
-
- return True;
-}
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifdef HAVE_XNEST_CONFIG_H
+#include <xnest-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "scrnintstr.h"
+#include "window.h"
+#include "windowstr.h"
+#include "colormapst.h"
+#include "resource.h"
+
+#include "Xnest.h"
+
+
+#include "Display.h"
+#include "Screen.h"
+#include "Color.h"
+#include "Visual.h"
+#include "XNWindow.h"
+#include "Args.h"
+
+static int cmapScrPrivateKeyIndex;
+static DevPrivateKey cmapScrPrivateKey = &cmapScrPrivateKeyIndex;
+
+#define GetInstalledColormap(s) ((ColormapPtr) dixLookupPrivate(&(s)->devPrivates, cmapScrPrivateKey))
+#define SetInstalledColormap(s,c) (dixSetPrivate(&(s)->devPrivates, cmapScrPrivateKey, c))
+
+Bool
+xnestCreateColormap(ColormapPtr pCmap)
+{
+ VisualPtr pVisual;
+ XColor *colors;
+ int i, ncolors;
+ Pixel red, green, blue;
+ Pixel redInc, greenInc, blueInc;
+
+ pVisual = pCmap->pVisual;
+ ncolors = pVisual->ColormapEntries;
+
+ pCmap->devPriv = (pointer)malloc(sizeof(xnestPrivColormap));
+
+ xnestColormapPriv(pCmap)->colormap =
+ XCreateColormap(xnestDisplay,
+ xnestDefaultWindows[pCmap->pScreen->myNum],
+ xnestVisual(pVisual),
+ (pVisual->class & DynamicClass) ?
+ AllocAll : AllocNone);
+
+
+ switch (pVisual->class) {
+ case StaticGray: /* read only */
+ colors = (XColor *)malloc(ncolors * sizeof(XColor));
+ for (i = 0; i < ncolors; i++)
+ colors[i].pixel = i;
+ XQueryColors(xnestDisplay, xnestColormap(pCmap), colors, ncolors);
+ for (i = 0; i < ncolors; i++) {
+ pCmap->red[i].co.local.red = colors[i].red;
+ pCmap->red[i].co.local.green = colors[i].red;
+ pCmap->red[i].co.local.blue = colors[i].red;
+ }
+ free(colors);
+ break;
+
+ case StaticColor: /* read only */
+ colors = (XColor *)malloc(ncolors * sizeof(XColor));
+ for (i = 0; i < ncolors; i++)
+ colors[i].pixel = i;
+ XQueryColors(xnestDisplay, xnestColormap(pCmap), colors, ncolors);
+ for (i = 0; i < ncolors; i++) {
+ pCmap->red[i].co.local.red = colors[i].red;
+ pCmap->red[i].co.local.green = colors[i].green;
+ pCmap->red[i].co.local.blue = colors[i].blue;
+ }
+ free(colors);
+ break;
+
+ case TrueColor: /* read only */
+ colors = (XColor *)malloc(ncolors * sizeof(XColor));
+ red = green = blue = 0L;
+ redInc = lowbit(pVisual->redMask);
+ greenInc = lowbit(pVisual->greenMask);
+ blueInc = lowbit(pVisual->blueMask);
+ for (i = 0; i < ncolors; i++) {
+ colors[i].pixel = red | green | blue;
+ red += redInc;
+ if (red > pVisual->redMask) red = 0L;
+ green += greenInc;
+ if (green > pVisual->greenMask) green = 0L;
+ blue += blueInc;
+ if (blue > pVisual->blueMask) blue = 0L;
+ }
+ XQueryColors(xnestDisplay, xnestColormap(pCmap), colors, ncolors);
+ for (i = 0; i < ncolors; i++) {
+ pCmap->red[i].co.local.red = colors[i].red;
+ pCmap->green[i].co.local.green = colors[i].green;
+ pCmap->blue[i].co.local.blue = colors[i].blue;
+ }
+ free(colors);
+ break;
+
+ case GrayScale: /* read and write */
+ break;
+
+ case PseudoColor: /* read and write */
+ break;
+
+ case DirectColor: /* read and write */
+ break;
+ }
+
+ return True;
+}
+
+void
+xnestDestroyColormap(ColormapPtr pCmap)
+{
+ XFreeColormap(xnestDisplay, xnestColormap(pCmap));
+ free(pCmap->devPriv);
+}
+
+#define SEARCH_PREDICATE \
+ (xnestWindow(pWin) != None && wColormap(pWin) == icws->cmapIDs[i])
+
+static int
+xnestCountInstalledColormapWindows(WindowPtr pWin, pointer ptr)
+{
+ xnestInstalledColormapWindows *icws = (xnestInstalledColormapWindows *)ptr;
+ int i;
+
+ for (i = 0; i < icws->numCmapIDs; i++)
+ if (SEARCH_PREDICATE) {
+ icws->numWindows++;
+ return WT_DONTWALKCHILDREN;
+ }
+
+ return WT_WALKCHILDREN;
+}
+
+static int
+xnestGetInstalledColormapWindows(WindowPtr pWin, pointer ptr)
+{
+ xnestInstalledColormapWindows *icws = (xnestInstalledColormapWindows *)ptr;
+ int i;
+
+ for (i = 0; i < icws->numCmapIDs; i++)
+ if (SEARCH_PREDICATE) {
+ icws->windows[icws->index++] = xnestWindow(pWin);
+ return WT_DONTWALKCHILDREN;
+ }
+
+ return WT_WALKCHILDREN;
+}
+
+static Window *xnestOldInstalledColormapWindows = NULL;
+static int xnestNumOldInstalledColormapWindows = 0;
+
+static Bool
+xnestSameInstalledColormapWindows(Window *windows, int numWindows)
+{
+ if (xnestNumOldInstalledColormapWindows != numWindows)
+ return False;
+
+ if (xnestOldInstalledColormapWindows == windows)
+ return True;
+
+ if (xnestOldInstalledColormapWindows == NULL || windows == NULL)
+ return False;
+
+ if (memcmp(xnestOldInstalledColormapWindows, windows,
+ numWindows * sizeof(Window)))
+ return False;
+
+ return True;
+}
+
+void
+xnestSetInstalledColormapWindows(ScreenPtr pScreen)
+{
+ xnestInstalledColormapWindows icws;
+ int numWindows;
+
+ icws.cmapIDs = (Colormap *)malloc(pScreen->maxInstalledCmaps *
+ sizeof(Colormap));
+ icws.numCmapIDs = xnestListInstalledColormaps(pScreen, icws.cmapIDs);
+ icws.numWindows = 0;
+ WalkTree(pScreen, xnestCountInstalledColormapWindows, (pointer)&icws);
+ if (icws.numWindows) {
+ icws.windows = (Window *)malloc((icws.numWindows + 1) * sizeof(Window));
+ icws.index = 0;
+ WalkTree(pScreen, xnestGetInstalledColormapWindows, (pointer)&icws);
+ icws.windows[icws.numWindows] = xnestDefaultWindows[pScreen->myNum];
+ numWindows = icws.numWindows + 1;
+ }
+ else {
+ icws.windows = NULL;
+ numWindows = 0;
+ }
+
+ free(icws.cmapIDs);
+
+ if (!xnestSameInstalledColormapWindows(icws.windows, icws.numWindows)) {
+ if (xnestOldInstalledColormapWindows)
+ free(xnestOldInstalledColormapWindows);
+
+#ifdef _XSERVER64
+ {
+ int i;
+ Window64 *windows = (Window64 *)malloc(numWindows * sizeof(Window64));
+
+ for(i = 0; i < numWindows; ++i)
+ windows[i] = icws.windows[i];
+ XSetWMColormapWindows(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
+ windows, numWindows);
+ free(windows);
+ }
+#else
+ XSetWMColormapWindows(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
+ icws.windows, numWindows);
+#endif
+
+ xnestOldInstalledColormapWindows = icws.windows;
+ xnestNumOldInstalledColormapWindows = icws.numWindows;
+
+#ifdef DUMB_WINDOW_MANAGERS
+ /*
+ This code is for dumb window managers.
+ This will only work with default local visual colormaps.
+ */
+ if (icws.numWindows)
+ {
+ WindowPtr pWin;
+ Visual *visual;
+ ColormapPtr pCmap;
+
+ pWin = xnestWindowPtr(icws.windows[0]);
+ visual = xnestVisualFromID(pScreen, wVisual(pWin));
+
+ if (visual == xnestDefaultVisual(pScreen))
+ dixLookupResourceByType((pointer *)&pCmap, wColormap(pWin),
+ RT_COLORMAP, serverClient, DixUseAccess);
+ else
+ dixLookupResourceByType((pointer *)&pCmap, pScreen->defColormap,
+ RT_COLORMAP, serverClient, DixUseAccess);
+
+ XSetWindowColormap(xnestDisplay,
+ xnestDefaultWindows[pScreen->myNum],
+ xnestColormap(pCmap));
+ }
+#endif /* DUMB_WINDOW_MANAGERS */
+ }
+ else
+ if (icws.windows) free(icws.windows);
+}
+
+void
+xnestSetScreenSaverColormapWindow(ScreenPtr pScreen)
+{
+ if (xnestOldInstalledColormapWindows)
+ free(xnestOldInstalledColormapWindows);
+
+#ifdef _XSERVER64
+ {
+ Window64 window;
+
+ window = xnestScreenSaverWindows[pScreen->myNum];
+ XSetWMColormapWindows(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
+ &window, 1);
+ xnestScreenSaverWindows[pScreen->myNum] = window;
+ }
+#else
+ XSetWMColormapWindows(xnestDisplay, xnestDefaultWindows[pScreen->myNum],
+ &xnestScreenSaverWindows[pScreen->myNum], 1);
+#endif /* _XSERVER64 */
+
+ xnestOldInstalledColormapWindows = NULL;
+ xnestNumOldInstalledColormapWindows = 0;
+
+ xnestDirectUninstallColormaps(pScreen);
+}
+
+void
+xnestDirectInstallColormaps(ScreenPtr pScreen)
+{
+ int i, n;
+ Colormap pCmapIDs[MAXCMAPS];
+
+ if (!xnestDoDirectColormaps) return;
+
+ n = (*pScreen->ListInstalledColormaps)(pScreen, pCmapIDs);
+
+ for (i = 0; i < n; i++) {
+ ColormapPtr pCmap;
+
+ dixLookupResourceByType((pointer *)&pCmap, pCmapIDs[i], RT_COLORMAP,
+ serverClient, DixInstallAccess);
+ if (pCmap)
+ XInstallColormap(xnestDisplay, xnestColormap(pCmap));
+ }
+}
+
+void
+xnestDirectUninstallColormaps(ScreenPtr pScreen)
+{
+ int i, n;
+ Colormap pCmapIDs[MAXCMAPS];
+
+ if (!xnestDoDirectColormaps) return;
+
+ n = (*pScreen->ListInstalledColormaps)(pScreen, pCmapIDs);
+
+ for (i = 0; i < n; i++) {
+ ColormapPtr pCmap;
+
+ dixLookupResourceByType((pointer *)&pCmap, pCmapIDs[i], RT_COLORMAP,
+ serverClient, DixUninstallAccess);
+ if (pCmap)
+ XUninstallColormap(xnestDisplay, xnestColormap(pCmap));
+ }
+}
+
+void
+xnestInstallColormap(ColormapPtr pCmap)
+{
+ ColormapPtr pOldCmap = GetInstalledColormap(pCmap->pScreen);
+
+ if(pCmap != pOldCmap)
+ {
+ xnestDirectUninstallColormaps(pCmap->pScreen);
+
+ /* Uninstall pInstalledMap. Notify all interested parties. */
+ if(pOldCmap != (ColormapPtr)None)
+ WalkTree(pCmap->pScreen, TellLostMap, (pointer)&pOldCmap->mid);
+
+ SetInstalledColormap(pCmap->pScreen, pCmap);
+ WalkTree(pCmap->pScreen, TellGainedMap, (pointer)&pCmap->mid);
+
+ xnestSetInstalledColormapWindows(pCmap->pScreen);
+ xnestDirectInstallColormaps(pCmap->pScreen);
+ }
+}
+
+void
+xnestUninstallColormap(ColormapPtr pCmap)
+{
+ ColormapPtr pCurCmap = GetInstalledColormap(pCmap->pScreen);
+
+ if(pCmap == pCurCmap)
+ {
+ if (pCmap->mid != pCmap->pScreen->defColormap)
+ {
+ dixLookupResourceByType((pointer *)&pCurCmap,
+ pCmap->pScreen->defColormap,
+ RT_COLORMAP,
+ serverClient, DixInstallAccess);
+ (*pCmap->pScreen->InstallColormap)(pCurCmap);
+ }
+ }
+}
+
+static Bool xnestInstalledDefaultColormap = False;
+
+int
+xnestListInstalledColormaps(ScreenPtr pScreen, Colormap *pCmapIDs)
+{
+ if (xnestInstalledDefaultColormap) {
+ *pCmapIDs = GetInstalledColormap(pScreen)->mid;
+ return 1;
+ }
+ else
+ return 0;
+}
+
+void
+xnestStoreColors(ColormapPtr pCmap, int nColors, xColorItem *pColors)
+{
+ if (pCmap->pVisual->class & DynamicClass)
+#ifdef _XSERVER64
+ {
+ int i;
+ XColor *pColors64 = (XColor *)malloc(nColors * sizeof(XColor) );
+
+ for(i = 0; i < nColors; ++i)
+ {
+ pColors64[i].pixel = pColors[i].pixel;
+ pColors64[i].red = pColors[i].red;
+ pColors64[i].green = pColors[i].green;
+ pColors64[i].blue = pColors[i].blue;
+ pColors64[i].flags = pColors[i].flags;
+ }
+ XStoreColors(xnestDisplay, xnestColormap(pCmap), pColors64, nColors);
+ free(pColors64);
+ }
+#else
+ XStoreColors(xnestDisplay, xnestColormap(pCmap),
+ (XColor *)pColors, nColors);
+#endif
+}
+
+void
+xnestResolveColor(unsigned short *pRed, unsigned short *pGreen,
+ unsigned short *pBlue, VisualPtr pVisual)
+{
+ int shift;
+ unsigned int lim;
+
+ shift = 16 - pVisual->bitsPerRGBValue;
+ lim = (1 << pVisual->bitsPerRGBValue) - 1;
+
+ if ((pVisual->class == PseudoColor) || (pVisual->class == DirectColor))
+ {
+ /* rescale to rgb bits */
+ *pRed = ((*pRed >> shift) * 65535) / lim;
+ *pGreen = ((*pGreen >> shift) * 65535) / lim;
+ *pBlue = ((*pBlue >> shift) * 65535) / lim;
+ }
+ else if (pVisual->class == GrayScale)
+ {
+ /* rescale to gray then rgb bits */
+ *pRed = (30L * *pRed + 59L * *pGreen + 11L * *pBlue) / 100;
+ *pBlue = *pGreen = *pRed = ((*pRed >> shift) * 65535) / lim;
+ }
+ else if (pVisual->class == StaticGray)
+ {
+ unsigned int limg;
+
+ limg = pVisual->ColormapEntries - 1;
+ /* rescale to gray then [0..limg] then [0..65535] then rgb bits */
+ *pRed = (30L * *pRed + 59L * *pGreen + 11L * *pBlue) / 100;
+ *pRed = ((((*pRed * (limg + 1))) >> 16) * 65535) / limg;
+ *pBlue = *pGreen = *pRed = ((*pRed >> shift) * 65535) / lim;
+ }
+ else
+ {
+ unsigned limr, limg, limb;
+
+ limr = pVisual->redMask >> pVisual->offsetRed;
+ limg = pVisual->greenMask >> pVisual->offsetGreen;
+ limb = pVisual->blueMask >> pVisual->offsetBlue;
+ /* rescale to [0..limN] then [0..65535] then rgb bits */
+ *pRed = ((((((*pRed * (limr + 1)) >> 16) *
+ 65535) / limr) >> shift) * 65535) / lim;
+ *pGreen = ((((((*pGreen * (limg + 1)) >> 16) *
+ 65535) / limg) >> shift) * 65535) / lim;
+ *pBlue = ((((((*pBlue * (limb + 1)) >> 16) *
+ 65535) / limb) >> shift) * 65535) / lim;
+ }
+}
+
+Bool
+xnestCreateDefaultColormap(ScreenPtr pScreen)
+{
+ VisualPtr pVisual;
+ ColormapPtr pCmap;
+ unsigned short zero = 0, ones = 0xFFFF;
+ Pixel wp, bp;
+
+ for (pVisual = pScreen->visuals;
+ pVisual->vid != pScreen->rootVisual;
+ pVisual++);
+
+ if (CreateColormap(pScreen->defColormap, pScreen, pVisual, &pCmap,
+ (pVisual->class & DynamicClass) ? AllocNone : AllocAll, 0)
+ != Success)
+ return False;
+
+ wp = pScreen->whitePixel;
+ bp = pScreen->blackPixel;
+ if ((AllocColor(pCmap, &ones, &ones, &ones, &wp, 0) !=
+ Success) ||
+ (AllocColor(pCmap, &zero, &zero, &zero, &bp, 0) !=
+ Success))
+ return FALSE;
+ pScreen->whitePixel = wp;
+ pScreen->blackPixel = bp;
+ (*pScreen->InstallColormap)(pCmap);
+
+ xnestInstalledDefaultColormap = True;
+
+ return True;
+}
diff --git a/xorg-server/hw/xnest/Cursor.c b/xorg-server/hw/xnest/Cursor.c
index 12f47e725..290074d4e 100644
--- a/xorg-server/hw/xnest/Cursor.c
+++ b/xorg-server/hw/xnest/Cursor.c
@@ -1,183 +1,183 @@
-/*
-
-Copyright 1993 by Davor Matic
-
-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. Davor Matic makes no representations about
-the suitability of this software for any purpose. It is provided "as
-is" without express or implied warranty.
-
-*/
-
-#ifdef HAVE_XNEST_CONFIG_H
-#include <xnest-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "screenint.h"
-#include "input.h"
-#include "misc.h"
-#include "cursor.h"
-#include "cursorstr.h"
-#include "scrnintstr.h"
-#include "servermd.h"
-#include "mipointrst.h"
-
-#include "Xnest.h"
-
-#include "Display.h"
-#include "Screen.h"
-#include "XNCursor.h"
-#include "Visual.h"
-#include "Keyboard.h"
-#include "Args.h"
-
-xnestCursorFuncRec xnestCursorFuncs = {NULL};
-
-Bool
-xnestRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
-{
- XImage *ximage;
- Pixmap source, mask;
- XColor fg_color, bg_color;
- unsigned long valuemask;
- XGCValues values;
-
- valuemask = GCFunction |
- GCPlaneMask |
- GCForeground |
- GCBackground |
- GCClipMask;
-
- values.function = GXcopy;
- values.plane_mask = AllPlanes;
- values.foreground = 1L;
- values.background = 0L;
- values.clip_mask = None;
-
- XChangeGC(xnestDisplay, xnestBitmapGC, valuemask, &values);
-
- source = XCreatePixmap(xnestDisplay,
- xnestDefaultWindows[pScreen->myNum],
- pCursor->bits->width,
- pCursor->bits->height,
- 1);
-
- mask = XCreatePixmap(xnestDisplay,
- xnestDefaultWindows[pScreen->myNum],
- pCursor->bits->width,
- pCursor->bits->height,
- 1);
-
- ximage = XCreateImage(xnestDisplay,
- xnestDefaultVisual(pScreen),
- 1, XYBitmap, 0,
- (char *)pCursor->bits->source,
- pCursor->bits->width,
- pCursor->bits->height,
- BitmapPad(xnestDisplay), 0);
-
- XPutImage(xnestDisplay, source, xnestBitmapGC, ximage,
- 0, 0, 0, 0, pCursor->bits->width, pCursor->bits->height);
-
- XFree(ximage);
-
- ximage = XCreateImage(xnestDisplay,
- xnestDefaultVisual(pScreen),
- 1, XYBitmap, 0,
- (char *)pCursor->bits->mask,
- pCursor->bits->width,
- pCursor->bits->height,
- BitmapPad(xnestDisplay), 0);
-
- XPutImage(xnestDisplay, mask, xnestBitmapGC, ximage,
- 0, 0, 0, 0, pCursor->bits->width, pCursor->bits->height);
-
- XFree(ximage);
-
- fg_color.red = pCursor->foreRed;
- fg_color.green = pCursor->foreGreen;
- fg_color.blue = pCursor->foreBlue;
-
- bg_color.red = pCursor->backRed;
- bg_color.green = pCursor->backGreen;
- bg_color.blue = pCursor->backBlue;
-
- xnestSetCursorPriv(pCursor, pScreen, xalloc(sizeof(xnestPrivCursor)));
- xnestCursor(pCursor, pScreen) =
- XCreatePixmapCursor(xnestDisplay, source, mask, &fg_color, &bg_color,
- pCursor->bits->xhot, pCursor->bits->yhot);
-
- XFreePixmap(xnestDisplay, source);
- XFreePixmap(xnestDisplay, mask);
-
- return True;
-}
-
-Bool
-xnestUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
-{
- XFreeCursor(xnestDisplay, xnestCursor(pCursor, pScreen));
- xfree(xnestGetCursorPriv(pCursor, pScreen));
- return True;
-}
-
-void
-xnestRecolorCursor(ScreenPtr pScreen, CursorPtr pCursor, Bool displayed)
-{
- XColor fg_color, bg_color;
-
- fg_color.red = pCursor->foreRed;
- fg_color.green = pCursor->foreGreen;
- fg_color.blue = pCursor->foreBlue;
-
- bg_color.red = pCursor->backRed;
- bg_color.green = pCursor->backGreen;
- bg_color.blue = pCursor->backBlue;
-
- XRecolorCursor(xnestDisplay,
- xnestCursor(pCursor, pScreen),
- &fg_color, &bg_color);
-}
-
-void xnestSetCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
-{
- if (pCursor)
- {
- XDefineCursor(xnestDisplay,
- xnestDefaultWindows[pScreen->myNum],
- xnestCursor(pCursor, pScreen));
- }
-}
-
-void
-xnestMoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
-{
-}
-
-Bool
-xnestDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
-{
- xnestCursorFuncPtr pScreenPriv;
-
- pScreenPriv = (xnestCursorFuncPtr)
- dixLookupPrivate(&pScreen->devPrivates, xnestCursorScreenKey);
-
- pScreenPriv->spriteFuncs->DeviceCursorInitialize(pDev, pScreen);
- return TRUE;
-}
-
-void
-xnestDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
-{
- xnestCursorFuncPtr pScreenPriv;
-
- pScreenPriv = (xnestCursorFuncPtr)
- dixLookupPrivate(&pScreen->devPrivates, xnestCursorScreenKey);
-
- pScreenPriv->spriteFuncs->DeviceCursorCleanup(pDev, pScreen);
-}
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifdef HAVE_XNEST_CONFIG_H
+#include <xnest-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "screenint.h"
+#include "input.h"
+#include "misc.h"
+#include "cursor.h"
+#include "cursorstr.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+#include "mipointrst.h"
+
+#include "Xnest.h"
+
+#include "Display.h"
+#include "Screen.h"
+#include "XNCursor.h"
+#include "Visual.h"
+#include "Keyboard.h"
+#include "Args.h"
+
+xnestCursorFuncRec xnestCursorFuncs = {NULL};
+
+Bool
+xnestRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
+{
+ XImage *ximage;
+ Pixmap source, mask;
+ XColor fg_color, bg_color;
+ unsigned long valuemask;
+ XGCValues values;
+
+ valuemask = GCFunction |
+ GCPlaneMask |
+ GCForeground |
+ GCBackground |
+ GCClipMask;
+
+ values.function = GXcopy;
+ values.plane_mask = AllPlanes;
+ values.foreground = 1L;
+ values.background = 0L;
+ values.clip_mask = None;
+
+ XChangeGC(xnestDisplay, xnestBitmapGC, valuemask, &values);
+
+ source = XCreatePixmap(xnestDisplay,
+ xnestDefaultWindows[pScreen->myNum],
+ pCursor->bits->width,
+ pCursor->bits->height,
+ 1);
+
+ mask = XCreatePixmap(xnestDisplay,
+ xnestDefaultWindows[pScreen->myNum],
+ pCursor->bits->width,
+ pCursor->bits->height,
+ 1);
+
+ ximage = XCreateImage(xnestDisplay,
+ xnestDefaultVisual(pScreen),
+ 1, XYBitmap, 0,
+ (char *)pCursor->bits->source,
+ pCursor->bits->width,
+ pCursor->bits->height,
+ BitmapPad(xnestDisplay), 0);
+
+ XPutImage(xnestDisplay, source, xnestBitmapGC, ximage,
+ 0, 0, 0, 0, pCursor->bits->width, pCursor->bits->height);
+
+ XFree(ximage);
+
+ ximage = XCreateImage(xnestDisplay,
+ xnestDefaultVisual(pScreen),
+ 1, XYBitmap, 0,
+ (char *)pCursor->bits->mask,
+ pCursor->bits->width,
+ pCursor->bits->height,
+ BitmapPad(xnestDisplay), 0);
+
+ XPutImage(xnestDisplay, mask, xnestBitmapGC, ximage,
+ 0, 0, 0, 0, pCursor->bits->width, pCursor->bits->height);
+
+ XFree(ximage);
+
+ fg_color.red = pCursor->foreRed;
+ fg_color.green = pCursor->foreGreen;
+ fg_color.blue = pCursor->foreBlue;
+
+ bg_color.red = pCursor->backRed;
+ bg_color.green = pCursor->backGreen;
+ bg_color.blue = pCursor->backBlue;
+
+ xnestSetCursorPriv(pCursor, pScreen, malloc(sizeof(xnestPrivCursor)));
+ xnestCursor(pCursor, pScreen) =
+ XCreatePixmapCursor(xnestDisplay, source, mask, &fg_color, &bg_color,
+ pCursor->bits->xhot, pCursor->bits->yhot);
+
+ XFreePixmap(xnestDisplay, source);
+ XFreePixmap(xnestDisplay, mask);
+
+ return True;
+}
+
+Bool
+xnestUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
+{
+ XFreeCursor(xnestDisplay, xnestCursor(pCursor, pScreen));
+ free(xnestGetCursorPriv(pCursor, pScreen));
+ return True;
+}
+
+void
+xnestRecolorCursor(ScreenPtr pScreen, CursorPtr pCursor, Bool displayed)
+{
+ XColor fg_color, bg_color;
+
+ fg_color.red = pCursor->foreRed;
+ fg_color.green = pCursor->foreGreen;
+ fg_color.blue = pCursor->foreBlue;
+
+ bg_color.red = pCursor->backRed;
+ bg_color.green = pCursor->backGreen;
+ bg_color.blue = pCursor->backBlue;
+
+ XRecolorCursor(xnestDisplay,
+ xnestCursor(pCursor, pScreen),
+ &fg_color, &bg_color);
+}
+
+void xnestSetCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
+{
+ if (pCursor)
+ {
+ XDefineCursor(xnestDisplay,
+ xnestDefaultWindows[pScreen->myNum],
+ xnestCursor(pCursor, pScreen));
+ }
+}
+
+void
+xnestMoveCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
+{
+}
+
+Bool
+xnestDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
+{
+ xnestCursorFuncPtr pScreenPriv;
+
+ pScreenPriv = (xnestCursorFuncPtr)
+ dixLookupPrivate(&pScreen->devPrivates, xnestCursorScreenKey);
+
+ pScreenPriv->spriteFuncs->DeviceCursorInitialize(pDev, pScreen);
+ return TRUE;
+}
+
+void
+xnestDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen)
+{
+ xnestCursorFuncPtr pScreenPriv;
+
+ pScreenPriv = (xnestCursorFuncPtr)
+ dixLookupPrivate(&pScreen->devPrivates, xnestCursorScreenKey);
+
+ pScreenPriv->spriteFuncs->DeviceCursorCleanup(pDev, pScreen);
+}
diff --git a/xorg-server/hw/xnest/Display.c b/xorg-server/hw/xnest/Display.c
index 01290417c..72c640186 100644
--- a/xorg-server/hw/xnest/Display.c
+++ b/xorg-server/hw/xnest/Display.c
@@ -1,193 +1,193 @@
-/*
-
-Copyright 1993 by Davor Matic
-
-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. Davor Matic makes no representations about
-the suitability of this software for any purpose. It is provided "as
-is" without express or implied warranty.
-
-*/
-
-
-#ifdef HAVE_XNEST_CONFIG_H
-#include <xnest-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "screenint.h"
-#include "input.h"
-#include "misc.h"
-#include "scrnintstr.h"
-#include "servermd.h"
-
-#include "Xnest.h"
-
-#include "Display.h"
-#include "Init.h"
-#include "Args.h"
-
-#include "icon"
-#include "screensaver"
-
-Display *xnestDisplay = NULL;
-XVisualInfo *xnestVisuals;
-int xnestNumVisuals;
-int xnestDefaultVisualIndex;
-Colormap *xnestDefaultColormaps;
-static int xnestNumDefaultColormaps;
-int *xnestDepths;
-int xnestNumDepths;
-XPixmapFormatValues *xnestPixmapFormats;
-int xnestNumPixmapFormats;
-Pixel xnestBlackPixel;
-Pixel xnestWhitePixel;
-Drawable xnestDefaultDrawables[MAXDEPTH + 1];
-Pixmap xnestIconBitmap;
-Pixmap xnestScreenSaverPixmap;
-XlibGC xnestBitmapGC;
-unsigned long xnestEventMask;
-
-void
-xnestOpenDisplay(int argc, char *argv[])
-{
- XVisualInfo vi;
- long mask;
- int i, j;
-
- if (!xnestDoFullGeneration) return;
-
- xnestCloseDisplay();
-
- xnestDisplay = XOpenDisplay(xnestDisplayName);
- if (xnestDisplay == NULL)
- FatalError("Unable to open display \"%s\".\n",
- XDisplayName(xnestDisplayName));
-
- if (xnestSynchronize)
- XSynchronize(xnestDisplay, True);
-
- mask = VisualScreenMask;
- vi.screen = DefaultScreen(xnestDisplay);
- xnestVisuals = XGetVisualInfo(xnestDisplay, mask, &vi, &xnestNumVisuals);
- if (xnestNumVisuals == 0 || xnestVisuals == NULL)
- FatalError("Unable to find any visuals.\n");
-
- if (xnestUserDefaultClass || xnestUserDefaultDepth) {
- xnestDefaultVisualIndex = UNDEFINED;
- for (i = 0; i < xnestNumVisuals; i++)
- if ((!xnestUserDefaultClass ||
- xnestVisuals[i].class == xnestDefaultClass)
- &&
- (!xnestUserDefaultDepth ||
- xnestVisuals[i].depth == xnestDefaultDepth)) {
- xnestDefaultVisualIndex = i;
- break;
- }
- if (xnestDefaultVisualIndex == UNDEFINED)
- FatalError("Unable to find desired default visual.\n");
- }
- else {
- vi.visualid = XVisualIDFromVisual(DefaultVisual(xnestDisplay,
- DefaultScreen(xnestDisplay)));
- xnestDefaultVisualIndex = 0;
- for (i = 0; i < xnestNumVisuals; i++)
- if (vi.visualid == xnestVisuals[i].visualid)
- xnestDefaultVisualIndex = i;
- }
-
- xnestNumDefaultColormaps = xnestNumVisuals;
- xnestDefaultColormaps = (Colormap *)xalloc(xnestNumDefaultColormaps *
- sizeof(Colormap));
- for (i = 0; i < xnestNumDefaultColormaps; i++)
- xnestDefaultColormaps[i] = XCreateColormap(xnestDisplay,
- DefaultRootWindow(xnestDisplay),
- xnestVisuals[i].visual,
- AllocNone);
-
- xnestDepths = XListDepths(xnestDisplay, DefaultScreen(xnestDisplay),
- &xnestNumDepths);
-
- xnestPixmapFormats = XListPixmapFormats(xnestDisplay,
- &xnestNumPixmapFormats);
-
- xnestBlackPixel = BlackPixel(xnestDisplay, DefaultScreen(xnestDisplay));
- xnestWhitePixel = WhitePixel(xnestDisplay, DefaultScreen(xnestDisplay));
-
- if (xnestParentWindow != (Window) 0)
- xnestEventMask = StructureNotifyMask;
- else
- xnestEventMask = 0L;
-
- for (i = 0; i <= MAXDEPTH; i++)
- xnestDefaultDrawables[i] = None;
-
- for (i = 0; i < xnestNumPixmapFormats; i++)
- for (j = 0; j < xnestNumDepths; j++)
- if (xnestPixmapFormats[i].depth == 1 ||
- xnestPixmapFormats[i].depth == xnestDepths[j]) {
- xnestDefaultDrawables[xnestPixmapFormats[i].depth] =
- XCreatePixmap(xnestDisplay, DefaultRootWindow(xnestDisplay),
- 1, 1, xnestPixmapFormats[i].depth);
- }
-
- xnestBitmapGC = XCreateGC(xnestDisplay, xnestDefaultDrawables[1], 0L, NULL);
-
- if (!(xnestUserGeometry & XValue))
- xnestX = 0;
-
- if (!(xnestUserGeometry & YValue))
- xnestY = 0;
-
- if (xnestParentWindow == 0) {
- if (!(xnestUserGeometry & WidthValue))
- xnestWidth = 3 * DisplayWidth(xnestDisplay,
- DefaultScreen(xnestDisplay)) / 4;
-
- if (!(xnestUserGeometry & HeightValue))
- xnestHeight = 3 * DisplayHeight(xnestDisplay,
- DefaultScreen(xnestDisplay)) / 4;
- }
-
- if (!xnestUserBorderWidth)
- xnestBorderWidth = 1;
-
- xnestIconBitmap =
- XCreateBitmapFromData(xnestDisplay,
- DefaultRootWindow(xnestDisplay),
- (char *)icon_bits,
- icon_width,
- icon_height);
-
- xnestScreenSaverPixmap =
- XCreatePixmapFromBitmapData(xnestDisplay,
- DefaultRootWindow(xnestDisplay),
- (char *)screensaver_bits,
- screensaver_width,
- screensaver_height,
- xnestWhitePixel,
- xnestBlackPixel,
- DefaultDepth(xnestDisplay,
- DefaultScreen(xnestDisplay)));
-}
-
-void
-xnestCloseDisplay(void)
-{
- if (!xnestDoFullGeneration || !xnestDisplay) return;
-
- /*
- If xnestDoFullGeneration all x resources will be destroyed upon closing
- the display connection. There is no need to generate extra protocol.
- */
-
- xfree(xnestDefaultColormaps);
- XFree(xnestVisuals);
- XFree(xnestDepths);
- XFree(xnestPixmapFormats);
- XCloseDisplay(xnestDisplay);
-}
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+
+#ifdef HAVE_XNEST_CONFIG_H
+#include <xnest-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "screenint.h"
+#include "input.h"
+#include "misc.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+
+#include "Xnest.h"
+
+#include "Display.h"
+#include "Init.h"
+#include "Args.h"
+
+#include "icon"
+#include "screensaver"
+
+Display *xnestDisplay = NULL;
+XVisualInfo *xnestVisuals;
+int xnestNumVisuals;
+int xnestDefaultVisualIndex;
+Colormap *xnestDefaultColormaps;
+static int xnestNumDefaultColormaps;
+int *xnestDepths;
+int xnestNumDepths;
+XPixmapFormatValues *xnestPixmapFormats;
+int xnestNumPixmapFormats;
+Pixel xnestBlackPixel;
+Pixel xnestWhitePixel;
+Drawable xnestDefaultDrawables[MAXDEPTH + 1];
+Pixmap xnestIconBitmap;
+Pixmap xnestScreenSaverPixmap;
+XlibGC xnestBitmapGC;
+unsigned long xnestEventMask;
+
+void
+xnestOpenDisplay(int argc, char *argv[])
+{
+ XVisualInfo vi;
+ long mask;
+ int i, j;
+
+ if (!xnestDoFullGeneration) return;
+
+ xnestCloseDisplay();
+
+ xnestDisplay = XOpenDisplay(xnestDisplayName);
+ if (xnestDisplay == NULL)
+ FatalError("Unable to open display \"%s\".\n",
+ XDisplayName(xnestDisplayName));
+
+ if (xnestSynchronize)
+ XSynchronize(xnestDisplay, True);
+
+ mask = VisualScreenMask;
+ vi.screen = DefaultScreen(xnestDisplay);
+ xnestVisuals = XGetVisualInfo(xnestDisplay, mask, &vi, &xnestNumVisuals);
+ if (xnestNumVisuals == 0 || xnestVisuals == NULL)
+ FatalError("Unable to find any visuals.\n");
+
+ if (xnestUserDefaultClass || xnestUserDefaultDepth) {
+ xnestDefaultVisualIndex = UNDEFINED;
+ for (i = 0; i < xnestNumVisuals; i++)
+ if ((!xnestUserDefaultClass ||
+ xnestVisuals[i].class == xnestDefaultClass)
+ &&
+ (!xnestUserDefaultDepth ||
+ xnestVisuals[i].depth == xnestDefaultDepth)) {
+ xnestDefaultVisualIndex = i;
+ break;
+ }
+ if (xnestDefaultVisualIndex == UNDEFINED)
+ FatalError("Unable to find desired default visual.\n");
+ }
+ else {
+ vi.visualid = XVisualIDFromVisual(DefaultVisual(xnestDisplay,
+ DefaultScreen(xnestDisplay)));
+ xnestDefaultVisualIndex = 0;
+ for (i = 0; i < xnestNumVisuals; i++)
+ if (vi.visualid == xnestVisuals[i].visualid)
+ xnestDefaultVisualIndex = i;
+ }
+
+ xnestNumDefaultColormaps = xnestNumVisuals;
+ xnestDefaultColormaps = (Colormap *)malloc(xnestNumDefaultColormaps *
+ sizeof(Colormap));
+ for (i = 0; i < xnestNumDefaultColormaps; i++)
+ xnestDefaultColormaps[i] = XCreateColormap(xnestDisplay,
+ DefaultRootWindow(xnestDisplay),
+ xnestVisuals[i].visual,
+ AllocNone);
+
+ xnestDepths = XListDepths(xnestDisplay, DefaultScreen(xnestDisplay),
+ &xnestNumDepths);
+
+ xnestPixmapFormats = XListPixmapFormats(xnestDisplay,
+ &xnestNumPixmapFormats);
+
+ xnestBlackPixel = BlackPixel(xnestDisplay, DefaultScreen(xnestDisplay));
+ xnestWhitePixel = WhitePixel(xnestDisplay, DefaultScreen(xnestDisplay));
+
+ if (xnestParentWindow != (Window) 0)
+ xnestEventMask = StructureNotifyMask;
+ else
+ xnestEventMask = 0L;
+
+ for (i = 0; i <= MAXDEPTH; i++)
+ xnestDefaultDrawables[i] = None;
+
+ for (i = 0; i < xnestNumPixmapFormats; i++)
+ for (j = 0; j < xnestNumDepths; j++)
+ if (xnestPixmapFormats[i].depth == 1 ||
+ xnestPixmapFormats[i].depth == xnestDepths[j]) {
+ xnestDefaultDrawables[xnestPixmapFormats[i].depth] =
+ XCreatePixmap(xnestDisplay, DefaultRootWindow(xnestDisplay),
+ 1, 1, xnestPixmapFormats[i].depth);
+ }
+
+ xnestBitmapGC = XCreateGC(xnestDisplay, xnestDefaultDrawables[1], 0L, NULL);
+
+ if (!(xnestUserGeometry & XValue))
+ xnestX = 0;
+
+ if (!(xnestUserGeometry & YValue))
+ xnestY = 0;
+
+ if (xnestParentWindow == 0) {
+ if (!(xnestUserGeometry & WidthValue))
+ xnestWidth = 3 * DisplayWidth(xnestDisplay,
+ DefaultScreen(xnestDisplay)) / 4;
+
+ if (!(xnestUserGeometry & HeightValue))
+ xnestHeight = 3 * DisplayHeight(xnestDisplay,
+ DefaultScreen(xnestDisplay)) / 4;
+ }
+
+ if (!xnestUserBorderWidth)
+ xnestBorderWidth = 1;
+
+ xnestIconBitmap =
+ XCreateBitmapFromData(xnestDisplay,
+ DefaultRootWindow(xnestDisplay),
+ (char *)icon_bits,
+ icon_width,
+ icon_height);
+
+ xnestScreenSaverPixmap =
+ XCreatePixmapFromBitmapData(xnestDisplay,
+ DefaultRootWindow(xnestDisplay),
+ (char *)screensaver_bits,
+ screensaver_width,
+ screensaver_height,
+ xnestWhitePixel,
+ xnestBlackPixel,
+ DefaultDepth(xnestDisplay,
+ DefaultScreen(xnestDisplay)));
+}
+
+void
+xnestCloseDisplay(void)
+{
+ if (!xnestDoFullGeneration || !xnestDisplay) return;
+
+ /*
+ If xnestDoFullGeneration all x resources will be destroyed upon closing
+ the display connection. There is no need to generate extra protocol.
+ */
+
+ free(xnestDefaultColormaps);
+ XFree(xnestVisuals);
+ XFree(xnestDepths);
+ XFree(xnestPixmapFormats);
+ XCloseDisplay(xnestDisplay);
+}
diff --git a/xorg-server/hw/xnest/Font.c b/xorg-server/hw/xnest/Font.c
index 7b388f0f4..87e622680 100644
--- a/xorg-server/hw/xnest/Font.c
+++ b/xorg-server/hw/xnest/Font.c
@@ -1,86 +1,86 @@
-/*
-
-Copyright 1993 by Davor Matic
-
-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. Davor Matic makes no representations about
-the suitability of this software for any purpose. It is provided "as
-is" without express or implied warranty.
-
-*/
-
-#ifdef HAVE_XNEST_CONFIG_H
-#include <xnest-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xatom.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "regionstr.h"
-#include <X11/fonts/font.h>
-#include <X11/fonts/fontstruct.h>
-#include "scrnintstr.h"
-
-#include "Xnest.h"
-
-#include "Display.h"
-#include "XNFont.h"
-
-int xnestFontPrivateIndex;
-
-Bool
-xnestRealizeFont(ScreenPtr pScreen, FontPtr pFont)
-{
- pointer priv;
- Atom name_atom, value_atom;
- int nprops;
- FontPropPtr props;
- int i;
- const char *name;
-
- FontSetPrivate(pFont, xnestFontPrivateIndex, NULL);
-
- name_atom = MakeAtom("FONT", 4, True);
- value_atom = 0L;
-
- nprops = pFont->info.nprops;
- props = pFont->info.props;
-
- for (i = 0; i < nprops; i++)
- if (props[i].name == name_atom) {
- value_atom = props[i].value;
- break;
- }
-
- if (!value_atom) return False;
-
- name = NameForAtom(value_atom);
-
- if (!name) return False;
-
- priv = (pointer)xalloc(sizeof(xnestPrivFont));
- FontSetPrivate(pFont, xnestFontPrivateIndex, priv);
-
- xnestFontPriv(pFont)->font_struct = XLoadQueryFont(xnestDisplay, name);
-
- if (!xnestFontStruct(pFont)) return False;
-
- return True;
-}
-
-
-Bool
-xnestUnrealizeFont(ScreenPtr pScreen, FontPtr pFont)
-{
- if (xnestFontPriv(pFont)) {
- if (xnestFontStruct(pFont))
- XFreeFont(xnestDisplay, xnestFontStruct(pFont));
- xfree(xnestFontPriv(pFont));
- FontSetPrivate(pFont, xnestFontPrivateIndex, NULL);
- }
- return True;
-}
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifdef HAVE_XNEST_CONFIG_H
+#include <xnest-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xatom.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "regionstr.h"
+#include <X11/fonts/font.h>
+#include <X11/fonts/fontstruct.h>
+#include "scrnintstr.h"
+
+#include "Xnest.h"
+
+#include "Display.h"
+#include "XNFont.h"
+
+int xnestFontPrivateIndex;
+
+Bool
+xnestRealizeFont(ScreenPtr pScreen, FontPtr pFont)
+{
+ pointer priv;
+ Atom name_atom, value_atom;
+ int nprops;
+ FontPropPtr props;
+ int i;
+ const char *name;
+
+ FontSetPrivate(pFont, xnestFontPrivateIndex, NULL);
+
+ name_atom = MakeAtom("FONT", 4, True);
+ value_atom = 0L;
+
+ nprops = pFont->info.nprops;
+ props = pFont->info.props;
+
+ for (i = 0; i < nprops; i++)
+ if (props[i].name == name_atom) {
+ value_atom = props[i].value;
+ break;
+ }
+
+ if (!value_atom) return False;
+
+ name = NameForAtom(value_atom);
+
+ if (!name) return False;
+
+ priv = (pointer)malloc(sizeof(xnestPrivFont));
+ FontSetPrivate(pFont, xnestFontPrivateIndex, priv);
+
+ xnestFontPriv(pFont)->font_struct = XLoadQueryFont(xnestDisplay, name);
+
+ if (!xnestFontStruct(pFont)) return False;
+
+ return True;
+}
+
+
+Bool
+xnestUnrealizeFont(ScreenPtr pScreen, FontPtr pFont)
+{
+ if (xnestFontPriv(pFont)) {
+ if (xnestFontStruct(pFont))
+ XFreeFont(xnestDisplay, xnestFontStruct(pFont));
+ free(xnestFontPriv(pFont));
+ FontSetPrivate(pFont, xnestFontPrivateIndex, NULL);
+ }
+ return True;
+}
diff --git a/xorg-server/hw/xnest/GC.c b/xorg-server/hw/xnest/GC.c
index 65425e98f..9df015728 100644
--- a/xorg-server/hw/xnest/GC.c
+++ b/xorg-server/hw/xnest/GC.c
@@ -1,339 +1,339 @@
-/*
-
-Copyright 1993 by Davor Matic
-
-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. Davor Matic makes no representations about
-the suitability of this software for any purpose. It is provided "as
-is" without express or implied warranty.
-
-*/
-
-#ifdef HAVE_XNEST_CONFIG_H
-#include <xnest-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "gcstruct.h"
-#include "windowstr.h"
-#include "pixmapstr.h"
-#include "scrnintstr.h"
-#include <X11/fonts/fontstruct.h>
-#include "mistruct.h"
-#include "region.h"
-
-#include "Xnest.h"
-
-#include "Display.h"
-#include "XNGC.h"
-#include "GCOps.h"
-#include "Drawable.h"
-#include "XNFont.h"
-#include "Color.h"
-
-static int xnestGCPrivateKeyIndex;
-DevPrivateKey xnestGCPrivateKey = &xnestGCPrivateKeyIndex;
-
-static GCFuncs xnestFuncs = {
- xnestValidateGC,
- xnestChangeGC,
- xnestCopyGC,
- xnestDestroyGC,
- xnestChangeClip,
- xnestDestroyClip,
- xnestCopyClip,
-};
-
-static GCOps xnestOps = {
- xnestFillSpans,
- xnestSetSpans,
- xnestPutImage,
- xnestCopyArea,
- xnestCopyPlane,
- xnestPolyPoint,
- xnestPolylines,
- xnestPolySegment,
- xnestPolyRectangle,
- xnestPolyArc,
- xnestFillPolygon,
- xnestPolyFillRect,
- xnestPolyFillArc,
- xnestPolyText8,
- xnestPolyText16,
- xnestImageText8,
- xnestImageText16,
- xnestImageGlyphBlt,
- xnestPolyGlyphBlt,
- xnestPushPixels
-};
-
-Bool
-xnestCreateGC(GCPtr pGC)
-{
- pGC->clientClipType = CT_NONE;
- pGC->clientClip = NULL;
-
- pGC->funcs = &xnestFuncs;
- pGC->ops = &xnestOps;
-
- pGC->miTranslate = 1;
-
- xnestGCPriv(pGC)->gc = XCreateGC(xnestDisplay,
- xnestDefaultDrawables[pGC->depth],
- 0L, NULL);
- xnestGCPriv(pGC)->nClipRects = 0;
-
- return True;
-}
-
-void
-xnestValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
-{
- pGC->lastWinOrg.x = pDrawable->x;
- pGC->lastWinOrg.y = pDrawable->y;
-}
-
-void
-xnestChangeGC(GCPtr pGC, unsigned long mask)
-{
- XGCValues values;
-
- if (mask & GCFunction)
- values.function = pGC->alu;
-
- if (mask & GCPlaneMask)
- values.plane_mask = pGC->planemask;
-
- if (mask & GCForeground)
- values.foreground = xnestPixel(pGC->fgPixel);
-
- if (mask & GCBackground)
- values.background = xnestPixel(pGC->bgPixel);
-
- if (mask & GCLineWidth)
- values.line_width = pGC->lineWidth;
-
- if (mask & GCLineStyle)
- values.line_style = pGC->lineStyle;
-
- if (mask & GCCapStyle)
- values.cap_style = pGC->capStyle;
-
- if (mask & GCJoinStyle)
- values.join_style = pGC->joinStyle;
-
- if (mask & GCFillStyle)
- values.fill_style = pGC->fillStyle;
-
- if (mask & GCFillRule)
- values.fill_rule = pGC->fillRule;
-
- if (mask & GCTile) {
- if (pGC->tileIsPixel)
- mask &= ~GCTile;
- else
- values.tile = xnestPixmap(pGC->tile.pixmap);
- }
-
- if (mask & GCStipple)
- values.stipple = xnestPixmap(pGC->stipple);
-
- if (mask & GCTileStipXOrigin)
- values.ts_x_origin = pGC->patOrg.x;
-
- if (mask & GCTileStipYOrigin)
- values.ts_y_origin = pGC->patOrg.y;
-
- if (mask & GCFont)
- values.font = xnestFont(pGC->font);
-
- if (mask & GCSubwindowMode)
- values.subwindow_mode = pGC->subWindowMode;
-
- if (mask & GCGraphicsExposures)
- values.graphics_exposures = pGC->graphicsExposures;
-
- if (mask & GCClipXOrigin)
- values.clip_x_origin = pGC->clipOrg.x;
-
- if (mask & GCClipYOrigin)
- values.clip_y_origin = pGC->clipOrg.y;
-
- if (mask & GCClipMask) /* this is handled in change clip */
- mask &= ~GCClipMask;
-
- if (mask & GCDashOffset)
- values.dash_offset = pGC->dashOffset;
-
- if (mask & GCDashList) {
- mask &= ~GCDashList;
- XSetDashes(xnestDisplay, xnestGC(pGC),
- pGC->dashOffset, (char *)pGC->dash, pGC->numInDashList);
- }
-
- if (mask & GCArcMode)
- values.arc_mode = pGC->arcMode;
-
- if (mask)
- XChangeGC(xnestDisplay, xnestGC(pGC), mask, &values);
-}
-
-void
-xnestCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
-{
- XCopyGC(xnestDisplay, xnestGC(pGCSrc), mask, xnestGC(pGCDst));
-}
-
-void
-xnestDestroyGC(GCPtr pGC)
-{
- XFreeGC(xnestDisplay, xnestGC(pGC));
-}
-
-void
-xnestChangeClip(GCPtr pGC, int type, pointer pValue, int nRects)
-{
- int i, size;
- BoxPtr pBox;
- XRectangle *pRects;
-
- xnestDestroyClipHelper(pGC);
-
- switch(type)
- {
- case CT_NONE:
- XSetClipMask(xnestDisplay, xnestGC(pGC), None);
- break;
-
- case CT_REGION:
- nRects = REGION_NUM_RECTS((RegionPtr)pValue);
- size = nRects * sizeof(*pRects);
- pRects = (XRectangle *) xalloc(size);
- pBox = REGION_RECTS((RegionPtr)pValue);
- for (i = nRects; i-- > 0; ) {
- pRects[i].x = pBox[i].x1;
- pRects[i].y = pBox[i].y1;
- pRects[i].width = pBox[i].x2 - pBox[i].x1;
- pRects[i].height = pBox[i].y2 - pBox[i].y1;
- }
- XSetClipRectangles(xnestDisplay, xnestGC(pGC), 0, 0,
- pRects, nRects, Unsorted);
- xfree((char *) pRects);
- break;
-
- case CT_PIXMAP:
- XSetClipMask(xnestDisplay, xnestGC(pGC),
- xnestPixmap((PixmapPtr)pValue));
- /*
- * Need to change into region, so subsequent uses are with
- * current pixmap contents.
- */
- pGC->clientClip = (pointer) (*pGC->pScreen->BitmapToRegion)((PixmapPtr)pValue);
- (*pGC->pScreen->DestroyPixmap)((PixmapPtr)pValue);
- pValue = pGC->clientClip;
- type = CT_REGION;
- break;
-
- case CT_UNSORTED:
- XSetClipRectangles(xnestDisplay, xnestGC(pGC),
- pGC->clipOrg.x, pGC->clipOrg.y,
- (XRectangle *)pValue, nRects, Unsorted);
- break;
-
- case CT_YSORTED:
- XSetClipRectangles(xnestDisplay, xnestGC(pGC),
- pGC->clipOrg.x, pGC->clipOrg.y,
- (XRectangle *)pValue, nRects, YSorted);
- break;
-
- case CT_YXSORTED:
- XSetClipRectangles(xnestDisplay, xnestGC(pGC),
- pGC->clipOrg.x, pGC->clipOrg.y,
- (XRectangle *)pValue, nRects, YXSorted);
- break;
-
- case CT_YXBANDED:
- XSetClipRectangles(xnestDisplay, xnestGC(pGC),
- pGC->clipOrg.x, pGC->clipOrg.y,
- (XRectangle *)pValue, nRects, YXBanded);
- break;
- }
-
- switch(type)
- {
- default:
- break;
-
- case CT_UNSORTED:
- case CT_YSORTED:
- case CT_YXSORTED:
- case CT_YXBANDED:
-
- /*
- * other parts of server can only deal with CT_NONE,
- * CT_PIXMAP and CT_REGION client clips.
- */
- pGC->clientClip = (pointer) RECTS_TO_REGION(pGC->pScreen, nRects,
- (xRectangle *)pValue, type);
- xfree(pValue);
- pValue = pGC->clientClip;
- type = CT_REGION;
-
- break;
- }
-
- pGC->clientClipType = type;
- pGC->clientClip = pValue;
- xnestGCPriv(pGC)->nClipRects = nRects;
-}
-
-void
-xnestDestroyClip(GCPtr pGC)
-{
- xnestDestroyClipHelper(pGC);
-
- XSetClipMask(xnestDisplay, xnestGC(pGC), None);
-
- pGC->clientClipType = CT_NONE;
- pGC->clientClip = NULL;
- xnestGCPriv(pGC)->nClipRects = 0;
-}
-
-void
-xnestDestroyClipHelper(GCPtr pGC)
-{
- switch (pGC->clientClipType)
- {
- default:
- case CT_NONE:
- break;
-
- case CT_REGION:
- REGION_DESTROY(pGC->pScreen, pGC->clientClip);
- break;
- }
-}
-
-void
-xnestCopyClip(GCPtr pGCDst, GCPtr pGCSrc)
-{
- RegionPtr pRgn;
-
- switch (pGCSrc->clientClipType)
- {
- default:
- case CT_NONE:
- xnestDestroyClip(pGCDst);
- break;
-
- case CT_REGION:
- pRgn = REGION_CREATE(pGCDst->pScreen, NULL, 1);
- REGION_COPY(pGCDst->pScreen, pRgn, pGCSrc->clientClip);
- xnestChangeClip(pGCDst, CT_REGION, pRgn, 0);
- break;
- }
-}
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifdef HAVE_XNEST_CONFIG_H
+#include <xnest-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "gcstruct.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include <X11/fonts/fontstruct.h>
+#include "mistruct.h"
+#include "region.h"
+
+#include "Xnest.h"
+
+#include "Display.h"
+#include "XNGC.h"
+#include "GCOps.h"
+#include "Drawable.h"
+#include "XNFont.h"
+#include "Color.h"
+
+static int xnestGCPrivateKeyIndex;
+DevPrivateKey xnestGCPrivateKey = &xnestGCPrivateKeyIndex;
+
+static GCFuncs xnestFuncs = {
+ xnestValidateGC,
+ xnestChangeGC,
+ xnestCopyGC,
+ xnestDestroyGC,
+ xnestChangeClip,
+ xnestDestroyClip,
+ xnestCopyClip,
+};
+
+static GCOps xnestOps = {
+ xnestFillSpans,
+ xnestSetSpans,
+ xnestPutImage,
+ xnestCopyArea,
+ xnestCopyPlane,
+ xnestPolyPoint,
+ xnestPolylines,
+ xnestPolySegment,
+ xnestPolyRectangle,
+ xnestPolyArc,
+ xnestFillPolygon,
+ xnestPolyFillRect,
+ xnestPolyFillArc,
+ xnestPolyText8,
+ xnestPolyText16,
+ xnestImageText8,
+ xnestImageText16,
+ xnestImageGlyphBlt,
+ xnestPolyGlyphBlt,
+ xnestPushPixels
+};
+
+Bool
+xnestCreateGC(GCPtr pGC)
+{
+ pGC->clientClipType = CT_NONE;
+ pGC->clientClip = NULL;
+
+ pGC->funcs = &xnestFuncs;
+ pGC->ops = &xnestOps;
+
+ pGC->miTranslate = 1;
+
+ xnestGCPriv(pGC)->gc = XCreateGC(xnestDisplay,
+ xnestDefaultDrawables[pGC->depth],
+ 0L, NULL);
+ xnestGCPriv(pGC)->nClipRects = 0;
+
+ return True;
+}
+
+void
+xnestValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable)
+{
+ pGC->lastWinOrg.x = pDrawable->x;
+ pGC->lastWinOrg.y = pDrawable->y;
+}
+
+void
+xnestChangeGC(GCPtr pGC, unsigned long mask)
+{
+ XGCValues values;
+
+ if (mask & GCFunction)
+ values.function = pGC->alu;
+
+ if (mask & GCPlaneMask)
+ values.plane_mask = pGC->planemask;
+
+ if (mask & GCForeground)
+ values.foreground = xnestPixel(pGC->fgPixel);
+
+ if (mask & GCBackground)
+ values.background = xnestPixel(pGC->bgPixel);
+
+ if (mask & GCLineWidth)
+ values.line_width = pGC->lineWidth;
+
+ if (mask & GCLineStyle)
+ values.line_style = pGC->lineStyle;
+
+ if (mask & GCCapStyle)
+ values.cap_style = pGC->capStyle;
+
+ if (mask & GCJoinStyle)
+ values.join_style = pGC->joinStyle;
+
+ if (mask & GCFillStyle)
+ values.fill_style = pGC->fillStyle;
+
+ if (mask & GCFillRule)
+ values.fill_rule = pGC->fillRule;
+
+ if (mask & GCTile) {
+ if (pGC->tileIsPixel)
+ mask &= ~GCTile;
+ else
+ values.tile = xnestPixmap(pGC->tile.pixmap);
+ }
+
+ if (mask & GCStipple)
+ values.stipple = xnestPixmap(pGC->stipple);
+
+ if (mask & GCTileStipXOrigin)
+ values.ts_x_origin = pGC->patOrg.x;
+
+ if (mask & GCTileStipYOrigin)
+ values.ts_y_origin = pGC->patOrg.y;
+
+ if (mask & GCFont)
+ values.font = xnestFont(pGC->font);
+
+ if (mask & GCSubwindowMode)
+ values.subwindow_mode = pGC->subWindowMode;
+
+ if (mask & GCGraphicsExposures)
+ values.graphics_exposures = pGC->graphicsExposures;
+
+ if (mask & GCClipXOrigin)
+ values.clip_x_origin = pGC->clipOrg.x;
+
+ if (mask & GCClipYOrigin)
+ values.clip_y_origin = pGC->clipOrg.y;
+
+ if (mask & GCClipMask) /* this is handled in change clip */
+ mask &= ~GCClipMask;
+
+ if (mask & GCDashOffset)
+ values.dash_offset = pGC->dashOffset;
+
+ if (mask & GCDashList) {
+ mask &= ~GCDashList;
+ XSetDashes(xnestDisplay, xnestGC(pGC),
+ pGC->dashOffset, (char *)pGC->dash, pGC->numInDashList);
+ }
+
+ if (mask & GCArcMode)
+ values.arc_mode = pGC->arcMode;
+
+ if (mask)
+ XChangeGC(xnestDisplay, xnestGC(pGC), mask, &values);
+}
+
+void
+xnestCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst)
+{
+ XCopyGC(xnestDisplay, xnestGC(pGCSrc), mask, xnestGC(pGCDst));
+}
+
+void
+xnestDestroyGC(GCPtr pGC)
+{
+ XFreeGC(xnestDisplay, xnestGC(pGC));
+}
+
+void
+xnestChangeClip(GCPtr pGC, int type, pointer pValue, int nRects)
+{
+ int i, size;
+ BoxPtr pBox;
+ XRectangle *pRects;
+
+ xnestDestroyClipHelper(pGC);
+
+ switch(type)
+ {
+ case CT_NONE:
+ XSetClipMask(xnestDisplay, xnestGC(pGC), None);
+ break;
+
+ case CT_REGION:
+ nRects = REGION_NUM_RECTS((RegionPtr)pValue);
+ size = nRects * sizeof(*pRects);
+ pRects = (XRectangle *) malloc(size);
+ pBox = REGION_RECTS((RegionPtr)pValue);
+ for (i = nRects; i-- > 0; ) {
+ pRects[i].x = pBox[i].x1;
+ pRects[i].y = pBox[i].y1;
+ pRects[i].width = pBox[i].x2 - pBox[i].x1;
+ pRects[i].height = pBox[i].y2 - pBox[i].y1;
+ }
+ XSetClipRectangles(xnestDisplay, xnestGC(pGC), 0, 0,
+ pRects, nRects, Unsorted);
+ free((char *) pRects);
+ break;
+
+ case CT_PIXMAP:
+ XSetClipMask(xnestDisplay, xnestGC(pGC),
+ xnestPixmap((PixmapPtr)pValue));
+ /*
+ * Need to change into region, so subsequent uses are with
+ * current pixmap contents.
+ */
+ pGC->clientClip = (pointer) (*pGC->pScreen->BitmapToRegion)((PixmapPtr)pValue);
+ (*pGC->pScreen->DestroyPixmap)((PixmapPtr)pValue);
+ pValue = pGC->clientClip;
+ type = CT_REGION;
+ break;
+
+ case CT_UNSORTED:
+ XSetClipRectangles(xnestDisplay, xnestGC(pGC),
+ pGC->clipOrg.x, pGC->clipOrg.y,
+ (XRectangle *)pValue, nRects, Unsorted);
+ break;
+
+ case CT_YSORTED:
+ XSetClipRectangles(xnestDisplay, xnestGC(pGC),
+ pGC->clipOrg.x, pGC->clipOrg.y,
+ (XRectangle *)pValue, nRects, YSorted);
+ break;
+
+ case CT_YXSORTED:
+ XSetClipRectangles(xnestDisplay, xnestGC(pGC),
+ pGC->clipOrg.x, pGC->clipOrg.y,
+ (XRectangle *)pValue, nRects, YXSorted);
+ break;
+
+ case CT_YXBANDED:
+ XSetClipRectangles(xnestDisplay, xnestGC(pGC),
+ pGC->clipOrg.x, pGC->clipOrg.y,
+ (XRectangle *)pValue, nRects, YXBanded);
+ break;
+ }
+
+ switch(type)
+ {
+ default:
+ break;
+
+ case CT_UNSORTED:
+ case CT_YSORTED:
+ case CT_YXSORTED:
+ case CT_YXBANDED:
+
+ /*
+ * other parts of server can only deal with CT_NONE,
+ * CT_PIXMAP and CT_REGION client clips.
+ */
+ pGC->clientClip = (pointer) RECTS_TO_REGION(pGC->pScreen, nRects,
+ (xRectangle *)pValue, type);
+ free(pValue);
+ pValue = pGC->clientClip;
+ type = CT_REGION;
+
+ break;
+ }
+
+ pGC->clientClipType = type;
+ pGC->clientClip = pValue;
+ xnestGCPriv(pGC)->nClipRects = nRects;
+}
+
+void
+xnestDestroyClip(GCPtr pGC)
+{
+ xnestDestroyClipHelper(pGC);
+
+ XSetClipMask(xnestDisplay, xnestGC(pGC), None);
+
+ pGC->clientClipType = CT_NONE;
+ pGC->clientClip = NULL;
+ xnestGCPriv(pGC)->nClipRects = 0;
+}
+
+void
+xnestDestroyClipHelper(GCPtr pGC)
+{
+ switch (pGC->clientClipType)
+ {
+ default:
+ case CT_NONE:
+ break;
+
+ case CT_REGION:
+ REGION_DESTROY(pGC->pScreen, pGC->clientClip);
+ break;
+ }
+}
+
+void
+xnestCopyClip(GCPtr pGCDst, GCPtr pGCSrc)
+{
+ RegionPtr pRgn;
+
+ switch (pGCSrc->clientClipType)
+ {
+ default:
+ case CT_NONE:
+ xnestDestroyClip(pGCDst);
+ break;
+
+ case CT_REGION:
+ pRgn = REGION_CREATE(pGCDst->pScreen, NULL, 1);
+ REGION_COPY(pGCDst->pScreen, pRgn, pGCSrc->clientClip);
+ xnestChangeClip(pGCDst, CT_REGION, pRgn, 0);
+ break;
+ }
+}
diff --git a/xorg-server/hw/xnest/Keyboard.c b/xorg-server/hw/xnest/Keyboard.c
index 1835c7071..473724a04 100644
--- a/xorg-server/hw/xnest/Keyboard.c
+++ b/xorg-server/hw/xnest/Keyboard.c
@@ -1,257 +1,257 @@
-/*
-
-Copyright 1993 by Davor Matic
-
-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. Davor Matic makes no representations about
-the suitability of this software for any purpose. It is provided "as
-is" without express or implied warranty.
-
-*/
-
-#ifdef HAVE_XNEST_CONFIG_H
-#include <xnest-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include <X11/keysym.h>
-#include "screenint.h"
-#include "inputstr.h"
-#include "misc.h"
-#include "scrnintstr.h"
-#include "servermd.h"
-
-#include "Xnest.h"
-
-#include "Display.h"
-#include "Screen.h"
-#include "Keyboard.h"
-#include "Args.h"
-#include "Events.h"
-
-#include <X11/extensions/XKB.h>
-#include "xkbsrv.h"
-#include <X11/extensions/XKBconfig.h>
-
-extern Bool
-XkbQueryExtension(
- Display * /* dpy */,
- int * /* opcodeReturn */,
- int * /* eventBaseReturn */,
- int * /* errorBaseReturn */,
- int * /* majorRtrn */,
- int * /* minorRtrn */
-);
-
-extern XkbDescPtr XkbGetKeyboard(
- Display * /* dpy */,
- unsigned int /* which */,
- unsigned int /* deviceSpec */
-);
-
-extern Status XkbGetControls(
- Display * /* dpy */,
- unsigned long /* which */,
- XkbDescPtr /* desc */
-);
-
-DeviceIntPtr xnestKeyboardDevice = NULL;
-
-void
-xnestBell(int volume, DeviceIntPtr pDev, pointer ctrl, int cls)
-{
- XBell(xnestDisplay, volume);
-}
-
-void
-DDXRingBell(int volume, int pitch, int duration)
-{
- XBell(xnestDisplay, volume);
-}
-
-void
-xnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl *ctrl)
-{
-#if 0
- unsigned long value_mask;
- XKeyboardControl values;
- int i;
-
- value_mask = KBKeyClickPercent |
- KBBellPercent |
- KBBellPitch |
- KBBellDuration |
- KBAutoRepeatMode;
-
- values.key_click_percent = ctrl->click;
- values.bell_percent = ctrl->bell;
- values.bell_pitch = ctrl->bell_pitch;
- values.bell_duration = ctrl->bell_duration;
- values.auto_repeat_mode = ctrl->autoRepeat ?
- AutoRepeatModeOn : AutoRepeatModeOff;
-
- XChangeKeyboardControl(xnestDisplay, value_mask, &values);
-
- /*
- value_mask = KBKey | KBAutoRepeatMode;
- At this point, we need to walk through the vector and compare it
- to the current server vector. If there are differences, report them.
- */
-
- value_mask = KBLed | KBLedMode;
- for (i = 1; i <= 32; i++) {
- values.led = i;
- values.led_mode = (ctrl->leds & (1 << (i - 1))) ? LedModeOn : LedModeOff;
- XChangeKeyboardControl(xnestDisplay, value_mask, &values);
- }
-#endif
-}
-
-int
-xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
-{
- KeySym *keymap;
- int mapWidth;
- int min_keycode, max_keycode;
- KeySymsRec keySyms;
- int i;
- XKeyboardState values;
- XkbDescPtr xkb;
- int op, event, error, major, minor;
-
- switch (onoff)
- {
- case DEVICE_INIT:
- XDisplayKeycodes(xnestDisplay, &min_keycode, &max_keycode);
-#ifdef _XSERVER64
- {
- KeySym64 *keymap64;
- int i, len;
- keymap64 = XGetKeyboardMapping(xnestDisplay,
- min_keycode,
- max_keycode - min_keycode + 1,
- &mapWidth);
- len = (max_keycode - min_keycode + 1) * mapWidth;
- keymap = (KeySym *)xalloc(len * sizeof(KeySym));
- for(i = 0; i < len; ++i)
- keymap[i] = keymap64[i];
- XFree(keymap64);
- }
-#else
- keymap = XGetKeyboardMapping(xnestDisplay,
- min_keycode,
- max_keycode - min_keycode + 1,
- &mapWidth);
-#endif
-
- keySyms.minKeyCode = min_keycode;
- keySyms.maxKeyCode = max_keycode;
- keySyms.mapWidth = mapWidth;
- keySyms.map = keymap;
-
- if (XkbQueryExtension(xnestDisplay, &op, &event, &error, &major, &minor) == 0) {
- ErrorF("Unable to initialize XKEYBOARD extension.\n");
- goto XkbError;
- }
- xkb = XkbGetKeyboard(xnestDisplay, XkbGBN_AllComponentsMask, XkbUseCoreKbd);
- if (xkb == NULL || xkb->geom == NULL) {
- ErrorF("Couldn't get keyboard.\n");
- goto XkbError;
- }
- XkbGetControls(xnestDisplay, XkbAllControlsMask, xkb);
-
- InitKeyboardDeviceStruct(pDev, NULL,
- xnestBell, xnestChangeKeyboardControl);
- XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls);
- XkbFreeKeyboard(xkb, 0, False);
- xfree(keymap);
- break;
- case DEVICE_ON:
- xnestEventMask |= XNEST_KEYBOARD_EVENT_MASK;
- for (i = 0; i < xnestNumScreens; i++)
- XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
- break;
- case DEVICE_OFF:
- xnestEventMask &= ~XNEST_KEYBOARD_EVENT_MASK;
- for (i = 0; i < xnestNumScreens; i++)
- XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
- break;
- case DEVICE_CLOSE:
- break;
- }
- return Success;
-
-XkbError:
- XGetKeyboardControl(xnestDisplay, &values);
- memmove((char *)defaultKeyboardControl.autoRepeats,
- (char *)values.auto_repeats,
- sizeof(values.auto_repeats));
-
- InitKeyboardDeviceStruct(pDev, NULL,
- xnestBell, xnestChangeKeyboardControl);
- xfree(keymap);
- return Success;
-}
-
-Bool
-LegalModifier(unsigned int key, DeviceIntPtr pDev)
-{
- return TRUE;
-}
-
-void
-xnestUpdateModifierState(unsigned int state)
-{
- DeviceIntPtr pDev = xnestKeyboardDevice;
- KeyClassPtr keyc = pDev->key;
- int i;
- CARD8 mask;
- int xkb_state;
-
- if (!pDev)
- return;
-
- xkb_state = XkbStateFieldFromRec(&pDev->key->xkbInfo->state);
- state = state & 0xff;
-
- if (xkb_state == state)
- return;
-
- for (i = 0, mask = 1; i < 8; i++, mask <<= 1) {
- int key;
-
- /* Modifier is down, but shouldn't be
- */
- if ((xkb_state & mask) && !(state & mask)) {
- int count = keyc->modifierKeyCount[i];
-
- for (key = 0; key < MAP_LENGTH; key++)
- if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
- int bit;
- BYTE *kptr;
-
- kptr = &keyc->down[key >> 3];
- bit = 1 << (key & 7);
-
- if (*kptr & bit)
- xnestQueueKeyEvent(KeyRelease, key);
-
- if (--count == 0)
- break;
- }
- }
-
- /* Modifier shoud be down, but isn't
- */
- if (!(xkb_state & mask) && (state & mask))
- for (key = 0; key < MAP_LENGTH; key++)
- if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
- xnestQueueKeyEvent(KeyPress, key);
- break;
- }
- }
-}
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifdef HAVE_XNEST_CONFIG_H
+#include <xnest-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include "screenint.h"
+#include "inputstr.h"
+#include "misc.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+
+#include "Xnest.h"
+
+#include "Display.h"
+#include "Screen.h"
+#include "Keyboard.h"
+#include "Args.h"
+#include "Events.h"
+
+#include <X11/extensions/XKB.h>
+#include "xkbsrv.h"
+#include <X11/extensions/XKBconfig.h>
+
+extern Bool
+XkbQueryExtension(
+ Display * /* dpy */,
+ int * /* opcodeReturn */,
+ int * /* eventBaseReturn */,
+ int * /* errorBaseReturn */,
+ int * /* majorRtrn */,
+ int * /* minorRtrn */
+);
+
+extern XkbDescPtr XkbGetKeyboard(
+ Display * /* dpy */,
+ unsigned int /* which */,
+ unsigned int /* deviceSpec */
+);
+
+extern Status XkbGetControls(
+ Display * /* dpy */,
+ unsigned long /* which */,
+ XkbDescPtr /* desc */
+);
+
+DeviceIntPtr xnestKeyboardDevice = NULL;
+
+void
+xnestBell(int volume, DeviceIntPtr pDev, pointer ctrl, int cls)
+{
+ XBell(xnestDisplay, volume);
+}
+
+void
+DDXRingBell(int volume, int pitch, int duration)
+{
+ XBell(xnestDisplay, volume);
+}
+
+void
+xnestChangeKeyboardControl(DeviceIntPtr pDev, KeybdCtrl *ctrl)
+{
+#if 0
+ unsigned long value_mask;
+ XKeyboardControl values;
+ int i;
+
+ value_mask = KBKeyClickPercent |
+ KBBellPercent |
+ KBBellPitch |
+ KBBellDuration |
+ KBAutoRepeatMode;
+
+ values.key_click_percent = ctrl->click;
+ values.bell_percent = ctrl->bell;
+ values.bell_pitch = ctrl->bell_pitch;
+ values.bell_duration = ctrl->bell_duration;
+ values.auto_repeat_mode = ctrl->autoRepeat ?
+ AutoRepeatModeOn : AutoRepeatModeOff;
+
+ XChangeKeyboardControl(xnestDisplay, value_mask, &values);
+
+ /*
+ value_mask = KBKey | KBAutoRepeatMode;
+ At this point, we need to walk through the vector and compare it
+ to the current server vector. If there are differences, report them.
+ */
+
+ value_mask = KBLed | KBLedMode;
+ for (i = 1; i <= 32; i++) {
+ values.led = i;
+ values.led_mode = (ctrl->leds & (1 << (i - 1))) ? LedModeOn : LedModeOff;
+ XChangeKeyboardControl(xnestDisplay, value_mask, &values);
+ }
+#endif
+}
+
+int
+xnestKeyboardProc(DeviceIntPtr pDev, int onoff)
+{
+ KeySym *keymap;
+ int mapWidth;
+ int min_keycode, max_keycode;
+ KeySymsRec keySyms;
+ int i;
+ XKeyboardState values;
+ XkbDescPtr xkb;
+ int op, event, error, major, minor;
+
+ switch (onoff)
+ {
+ case DEVICE_INIT:
+ XDisplayKeycodes(xnestDisplay, &min_keycode, &max_keycode);
+#ifdef _XSERVER64
+ {
+ KeySym64 *keymap64;
+ int i, len;
+ keymap64 = XGetKeyboardMapping(xnestDisplay,
+ min_keycode,
+ max_keycode - min_keycode + 1,
+ &mapWidth);
+ len = (max_keycode - min_keycode + 1) * mapWidth;
+ keymap = (KeySym *)malloc(len * sizeof(KeySym));
+ for(i = 0; i < len; ++i)
+ keymap[i] = keymap64[i];
+ XFree(keymap64);
+ }
+#else
+ keymap = XGetKeyboardMapping(xnestDisplay,
+ min_keycode,
+ max_keycode - min_keycode + 1,
+ &mapWidth);
+#endif
+
+ keySyms.minKeyCode = min_keycode;
+ keySyms.maxKeyCode = max_keycode;
+ keySyms.mapWidth = mapWidth;
+ keySyms.map = keymap;
+
+ if (XkbQueryExtension(xnestDisplay, &op, &event, &error, &major, &minor) == 0) {
+ ErrorF("Unable to initialize XKEYBOARD extension.\n");
+ goto XkbError;
+ }
+ xkb = XkbGetKeyboard(xnestDisplay, XkbGBN_AllComponentsMask, XkbUseCoreKbd);
+ if (xkb == NULL || xkb->geom == NULL) {
+ ErrorF("Couldn't get keyboard.\n");
+ goto XkbError;
+ }
+ XkbGetControls(xnestDisplay, XkbAllControlsMask, xkb);
+
+ InitKeyboardDeviceStruct(pDev, NULL,
+ xnestBell, xnestChangeKeyboardControl);
+ XkbDDXChangeControls(pDev, xkb->ctrls, xkb->ctrls);
+ XkbFreeKeyboard(xkb, 0, False);
+ free(keymap);
+ break;
+ case DEVICE_ON:
+ xnestEventMask |= XNEST_KEYBOARD_EVENT_MASK;
+ for (i = 0; i < xnestNumScreens; i++)
+ XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
+ break;
+ case DEVICE_OFF:
+ xnestEventMask &= ~XNEST_KEYBOARD_EVENT_MASK;
+ for (i = 0; i < xnestNumScreens; i++)
+ XSelectInput(xnestDisplay, xnestDefaultWindows[i], xnestEventMask);
+ break;
+ case DEVICE_CLOSE:
+ break;
+ }
+ return Success;
+
+XkbError:
+ XGetKeyboardControl(xnestDisplay, &values);
+ memmove((char *)defaultKeyboardControl.autoRepeats,
+ (char *)values.auto_repeats,
+ sizeof(values.auto_repeats));
+
+ InitKeyboardDeviceStruct(pDev, NULL,
+ xnestBell, xnestChangeKeyboardControl);
+ free(keymap);
+ return Success;
+}
+
+Bool
+LegalModifier(unsigned int key, DeviceIntPtr pDev)
+{
+ return TRUE;
+}
+
+void
+xnestUpdateModifierState(unsigned int state)
+{
+ DeviceIntPtr pDev = xnestKeyboardDevice;
+ KeyClassPtr keyc = pDev->key;
+ int i;
+ CARD8 mask;
+ int xkb_state;
+
+ if (!pDev)
+ return;
+
+ xkb_state = XkbStateFieldFromRec(&pDev->key->xkbInfo->state);
+ state = state & 0xff;
+
+ if (xkb_state == state)
+ return;
+
+ for (i = 0, mask = 1; i < 8; i++, mask <<= 1) {
+ int key;
+
+ /* Modifier is down, but shouldn't be
+ */
+ if ((xkb_state & mask) && !(state & mask)) {
+ int count = keyc->modifierKeyCount[i];
+
+ for (key = 0; key < MAP_LENGTH; key++)
+ if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
+ int bit;
+ BYTE *kptr;
+
+ kptr = &keyc->down[key >> 3];
+ bit = 1 << (key & 7);
+
+ if (*kptr & bit)
+ xnestQueueKeyEvent(KeyRelease, key);
+
+ if (--count == 0)
+ break;
+ }
+ }
+
+ /* Modifier shoud be down, but isn't
+ */
+ if (!(xkb_state & mask) && (state & mask))
+ for (key = 0; key < MAP_LENGTH; key++)
+ if (keyc->xkbInfo->desc->map->modmap[key] & mask) {
+ xnestQueueKeyEvent(KeyPress, key);
+ break;
+ }
+ }
+}
diff --git a/xorg-server/hw/xnest/Pixmap.c b/xorg-server/hw/xnest/Pixmap.c
index 676a2ba95..cd2245b46 100644
--- a/xorg-server/hw/xnest/Pixmap.c
+++ b/xorg-server/hw/xnest/Pixmap.c
@@ -1,141 +1,141 @@
-/*
-
-Copyright 1993 by Davor Matic
-
-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. Davor Matic makes no representations about
-the suitability of this software for any purpose. It is provided "as
-is" without express or implied warranty.
-
-*/
-
-#ifdef HAVE_XNEST_CONFIG_H
-#include <xnest-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "regionstr.h"
-#include "pixmapstr.h"
-#include "scrnintstr.h"
-#include "regionstr.h"
-#include "gc.h"
-#include "servermd.h"
-#include "privates.h"
-#include "mi.h"
-
-#include "Xnest.h"
-
-#include "Display.h"
-#include "Screen.h"
-#include "XNPixmap.h"
-
-static int xnestPixmapPrivateKeyIndex;
-DevPrivateKey xnestPixmapPrivateKey = &xnestPixmapPrivateKeyIndex;
-
-PixmapPtr
-xnestCreatePixmap(ScreenPtr pScreen, int width, int height, int depth,
- unsigned usage_hint)
-{
- PixmapPtr pPixmap;
-
- pPixmap = AllocatePixmap(pScreen, sizeof(xnestPrivPixmap));
- if (!pPixmap)
- return NullPixmap;
- pPixmap->drawable.type = DRAWABLE_PIXMAP;
- pPixmap->drawable.class = 0;
- pPixmap->drawable.depth = depth;
- pPixmap->drawable.bitsPerPixel = depth;
- pPixmap->drawable.id = 0;
- pPixmap->drawable.x = 0;
- pPixmap->drawable.y = 0;
- pPixmap->drawable.width = width;
- pPixmap->drawable.height = height;
- pPixmap->drawable.pScreen = pScreen;
- pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
- pPixmap->refcnt = 1;
- pPixmap->devKind = PixmapBytePad(width, depth);
- pPixmap->usage_hint = usage_hint;
- dixSetPrivate(&pPixmap->devPrivates, xnestPixmapPrivateKey,
- (char *)pPixmap + pScreen->totalPixmapSize);
- if (width && height)
- xnestPixmapPriv(pPixmap)->pixmap =
- XCreatePixmap(xnestDisplay,
- xnestDefaultWindows[pScreen->myNum],
- width, height, depth);
- else
- xnestPixmapPriv(pPixmap)->pixmap = 0;
-
- return pPixmap;
-}
-
-Bool
-xnestDestroyPixmap(PixmapPtr pPixmap)
-{
- if(--pPixmap->refcnt)
- return TRUE;
- XFreePixmap(xnestDisplay, xnestPixmap(pPixmap));
- dixFreePrivates(pPixmap->devPrivates);
- xfree(pPixmap);
- return TRUE;
-}
-
-RegionPtr
-xnestPixmapToRegion(PixmapPtr pPixmap)
-{
- XImage *ximage;
- register RegionPtr pReg, pTmpReg;
- register int x, y;
- unsigned long previousPixel, currentPixel;
- BoxRec Box = { 0, 0, 0, 0 };
- Bool overlap;
-
- ximage = XGetImage(xnestDisplay, xnestPixmap(pPixmap), 0, 0,
- pPixmap->drawable.width, pPixmap->drawable.height,
- 1, XYPixmap);
-
- pReg = REGION_CREATE(pPixmap->drawable.pScreen, NULL, 1);
- pTmpReg = REGION_CREATE(pPixmap->drawable.pScreen, NULL, 1);
- if(!pReg || !pTmpReg) {
- XDestroyImage(ximage);
- return NullRegion;
- }
-
- for (y = 0; y < pPixmap->drawable.height; y++) {
- Box.y1 = y;
- Box.y2 = y + 1;
- previousPixel = 0L;
- for (x = 0; x < pPixmap->drawable.width; x++) {
- currentPixel = XGetPixel(ximage, x, y);
- if (previousPixel != currentPixel) {
- if (previousPixel == 0L) {
- /* left edge */
- Box.x1 = x;
- }
- else if (currentPixel == 0L) {
- /* right edge */
- Box.x2 = x;
- REGION_RESET(pPixmap->drawable.pScreen, pTmpReg, &Box);
- REGION_APPEND(pPixmap->drawable.pScreen, pReg, pTmpReg);
- }
- previousPixel = currentPixel;
- }
- }
- if (previousPixel != 0L) {
- /* right edge because of the end of pixmap */
- Box.x2 = pPixmap->drawable.width;
- REGION_RESET(pPixmap->drawable.pScreen, pTmpReg, &Box);
- REGION_APPEND(pPixmap->drawable.pScreen, pReg, pTmpReg);
- }
- }
-
- REGION_DESTROY(pPixmap->drawable.pScreen, pTmpReg);
- XDestroyImage(ximage);
-
- REGION_VALIDATE(pPixmap->drawable.pScreen, pReg, &overlap);
-
- return(pReg);
-}
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifdef HAVE_XNEST_CONFIG_H
+#include <xnest-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "regionstr.h"
+#include "pixmapstr.h"
+#include "scrnintstr.h"
+#include "regionstr.h"
+#include "gc.h"
+#include "servermd.h"
+#include "privates.h"
+#include "mi.h"
+
+#include "Xnest.h"
+
+#include "Display.h"
+#include "Screen.h"
+#include "XNPixmap.h"
+
+static int xnestPixmapPrivateKeyIndex;
+DevPrivateKey xnestPixmapPrivateKey = &xnestPixmapPrivateKeyIndex;
+
+PixmapPtr
+xnestCreatePixmap(ScreenPtr pScreen, int width, int height, int depth,
+ unsigned usage_hint)
+{
+ PixmapPtr pPixmap;
+
+ pPixmap = AllocatePixmap(pScreen, sizeof(xnestPrivPixmap));
+ if (!pPixmap)
+ return NullPixmap;
+ pPixmap->drawable.type = DRAWABLE_PIXMAP;
+ pPixmap->drawable.class = 0;
+ pPixmap->drawable.depth = depth;
+ pPixmap->drawable.bitsPerPixel = depth;
+ pPixmap->drawable.id = 0;
+ pPixmap->drawable.x = 0;
+ pPixmap->drawable.y = 0;
+ pPixmap->drawable.width = width;
+ pPixmap->drawable.height = height;
+ pPixmap->drawable.pScreen = pScreen;
+ pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pPixmap->refcnt = 1;
+ pPixmap->devKind = PixmapBytePad(width, depth);
+ pPixmap->usage_hint = usage_hint;
+ dixSetPrivate(&pPixmap->devPrivates, xnestPixmapPrivateKey,
+ (char *)pPixmap + pScreen->totalPixmapSize);
+ if (width && height)
+ xnestPixmapPriv(pPixmap)->pixmap =
+ XCreatePixmap(xnestDisplay,
+ xnestDefaultWindows[pScreen->myNum],
+ width, height, depth);
+ else
+ xnestPixmapPriv(pPixmap)->pixmap = 0;
+
+ return pPixmap;
+}
+
+Bool
+xnestDestroyPixmap(PixmapPtr pPixmap)
+{
+ if(--pPixmap->refcnt)
+ return TRUE;
+ XFreePixmap(xnestDisplay, xnestPixmap(pPixmap));
+ dixFreePrivates(pPixmap->devPrivates);
+ free(pPixmap);
+ return TRUE;
+}
+
+RegionPtr
+xnestPixmapToRegion(PixmapPtr pPixmap)
+{
+ XImage *ximage;
+ register RegionPtr pReg, pTmpReg;
+ register int x, y;
+ unsigned long previousPixel, currentPixel;
+ BoxRec Box = { 0, 0, 0, 0 };
+ Bool overlap;
+
+ ximage = XGetImage(xnestDisplay, xnestPixmap(pPixmap), 0, 0,
+ pPixmap->drawable.width, pPixmap->drawable.height,
+ 1, XYPixmap);
+
+ pReg = REGION_CREATE(pPixmap->drawable.pScreen, NULL, 1);
+ pTmpReg = REGION_CREATE(pPixmap->drawable.pScreen, NULL, 1);
+ if(!pReg || !pTmpReg) {
+ XDestroyImage(ximage);
+ return NullRegion;
+ }
+
+ for (y = 0; y < pPixmap->drawable.height; y++) {
+ Box.y1 = y;
+ Box.y2 = y + 1;
+ previousPixel = 0L;
+ for (x = 0; x < pPixmap->drawable.width; x++) {
+ currentPixel = XGetPixel(ximage, x, y);
+ if (previousPixel != currentPixel) {
+ if (previousPixel == 0L) {
+ /* left edge */
+ Box.x1 = x;
+ }
+ else if (currentPixel == 0L) {
+ /* right edge */
+ Box.x2 = x;
+ REGION_RESET(pPixmap->drawable.pScreen, pTmpReg, &Box);
+ REGION_APPEND(pPixmap->drawable.pScreen, pReg, pTmpReg);
+ }
+ previousPixel = currentPixel;
+ }
+ }
+ if (previousPixel != 0L) {
+ /* right edge because of the end of pixmap */
+ Box.x2 = pPixmap->drawable.width;
+ REGION_RESET(pPixmap->drawable.pScreen, pTmpReg, &Box);
+ REGION_APPEND(pPixmap->drawable.pScreen, pReg, pTmpReg);
+ }
+ }
+
+ REGION_DESTROY(pPixmap->drawable.pScreen, pTmpReg);
+ XDestroyImage(ximage);
+
+ REGION_VALIDATE(pPixmap->drawable.pScreen, pReg, &overlap);
+
+ return(pReg);
+}
diff --git a/xorg-server/hw/xnest/Screen.c b/xorg-server/hw/xnest/Screen.c
index ca903d7ac..5a035ac8f 100644
--- a/xorg-server/hw/xnest/Screen.c
+++ b/xorg-server/hw/xnest/Screen.c
@@ -1,421 +1,420 @@
-/*
-
-Copyright 1993 by Davor Matic
-
-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. Davor Matic makes no representations about
-the suitability of this software for any purpose. It is provided "as
-is" without express or implied warranty.
-
-*/
-
-#ifdef HAVE_XNEST_CONFIG_H
-#include <xnest-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "scrnintstr.h"
-#include "dix.h"
-#include "mi.h"
-#include "mibstore.h"
-#include "micmap.h"
-#include "colormapst.h"
-#include "resource.h"
-
-#include "Xnest.h"
-
-#include "Display.h"
-#include "Screen.h"
-#include "XNGC.h"
-#include "GCOps.h"
-#include "Drawable.h"
-#include "XNFont.h"
-#include "Color.h"
-#include "XNCursor.h"
-#include "Visual.h"
-#include "Events.h"
-#include "Init.h"
-#include "mipointer.h"
-#include "Args.h"
-#include "mipointrst.h"
-
-Window xnestDefaultWindows[MAXSCREENS];
-Window xnestScreenSaverWindows[MAXSCREENS];
-static int xnestCursorScreenKeyIndex;
-DevPrivateKey xnestCursorScreenKey = &xnestCursorScreenKeyIndex;
-
-ScreenPtr
-xnestScreen(Window window)
-{
- int i;
-
- for (i = 0; i < xnestNumScreens; i++)
- if (xnestDefaultWindows[i] == window)
- return screenInfo.screens[i];
-
- return NULL;
-}
-
-static int
-offset(unsigned long mask)
-{
- int count;
-
- for (count = 0; !(mask & 1) && count < 32; count++)
- mask >>= 1;
-
- return count;
-}
-
-static Bool
-xnestSaveScreen(ScreenPtr pScreen, int what)
-{
- if (xnestSoftwareScreenSaver)
- return False;
- else {
- switch (what) {
- case SCREEN_SAVER_ON:
- XMapRaised(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
- xnestSetScreenSaverColormapWindow(pScreen);
- break;
-
- case SCREEN_SAVER_OFF:
- XUnmapWindow(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
- xnestSetInstalledColormapWindows(pScreen);
- break;
-
- case SCREEN_SAVER_FORCER:
- lastEventTime = GetTimeInMillis();
- XUnmapWindow(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
- xnestSetInstalledColormapWindows(pScreen);
- break;
-
- case SCREEN_SAVER_CYCLE:
- XUnmapWindow(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
- xnestSetInstalledColormapWindows(pScreen);
- break;
- }
- return True;
- }
-}
-
-static Bool
-xnestCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
-{
- return FALSE;
-}
-
-static void
-xnestCrossScreen(ScreenPtr pScreen, Bool entering)
-{
-}
-
-static miPointerScreenFuncRec xnestPointerCursorFuncs =
-{
- xnestCursorOffScreen,
- xnestCrossScreen,
- miPointerWarpCursor
-};
-
-static miPointerSpriteFuncRec xnestPointerSpriteFuncs =
-{
- xnestRealizeCursor,
- xnestUnrealizeCursor,
- xnestSetCursor,
- xnestMoveCursor,
- xnestDeviceCursorInitialize,
- xnestDeviceCursorCleanup
-};
-
-Bool
-xnestOpenScreen(int index, ScreenPtr pScreen, int argc, char *argv[])
-{
- VisualPtr visuals;
- DepthPtr depths;
- int numVisuals, numDepths;
- int i, j, depthIndex;
- unsigned long valuemask;
- XSetWindowAttributes attributes;
- XWindowAttributes gattributes;
- XSizeHints sizeHints;
- VisualID defaultVisual;
- int rootDepth;
- miPointerScreenPtr PointPriv;
-
- if (!dixRequestPrivate(xnestWindowPrivateKey, sizeof(xnestPrivWin)))
- return False;
- if (!dixRequestPrivate(xnestGCPrivateKey, sizeof(xnestPrivGC)))
- return False;
-
- visuals = (VisualPtr)xalloc(xnestNumVisuals * sizeof(VisualRec));
- numVisuals = 0;
-
- depths = (DepthPtr)xalloc(MAXDEPTH * sizeof(DepthRec));
- depths[0].depth = 1;
- depths[0].numVids = 0;
- depths[0].vids = (VisualID *)xalloc(MAXVISUALSPERDEPTH * sizeof(VisualID));
- numDepths = 1;
-
- for (i = 0; i < xnestNumVisuals; i++) {
- visuals[numVisuals].class = xnestVisuals[i].class;
- visuals[numVisuals].bitsPerRGBValue = xnestVisuals[i].bits_per_rgb;
- visuals[numVisuals].ColormapEntries = xnestVisuals[i].colormap_size;
- visuals[numVisuals].nplanes = xnestVisuals[i].depth;
- visuals[numVisuals].redMask = xnestVisuals[i].red_mask;
- visuals[numVisuals].greenMask = xnestVisuals[i].green_mask;
- visuals[numVisuals].blueMask = xnestVisuals[i].blue_mask;
- visuals[numVisuals].offsetRed = offset(xnestVisuals[i].red_mask);
- visuals[numVisuals].offsetGreen = offset(xnestVisuals[i].green_mask);
- visuals[numVisuals].offsetBlue = offset(xnestVisuals[i].blue_mask);
-
- /* Check for and remove duplicates. */
- for (j = 0; j < numVisuals; j++) {
- if (visuals[numVisuals].class == visuals[j].class &&
- visuals[numVisuals].bitsPerRGBValue == visuals[j].bitsPerRGBValue &&
- visuals[numVisuals].ColormapEntries == visuals[j].ColormapEntries &&
- visuals[numVisuals].nplanes == visuals[j].nplanes &&
- visuals[numVisuals].redMask == visuals[j].redMask &&
- visuals[numVisuals].greenMask == visuals[j].greenMask &&
- visuals[numVisuals].blueMask == visuals[j].blueMask &&
- visuals[numVisuals].offsetRed == visuals[j].offsetRed &&
- visuals[numVisuals].offsetGreen == visuals[j].offsetGreen &&
- visuals[numVisuals].offsetBlue == visuals[j].offsetBlue)
- break;
- }
- if (j < numVisuals)
- break;
-
- visuals[numVisuals].vid = FakeClientID(0);
-
- depthIndex = UNDEFINED;
- for (j = 0; j < numDepths; j++)
- if (depths[j].depth == xnestVisuals[i].depth) {
- depthIndex = j;
- break;
- }
-
- if (depthIndex == UNDEFINED) {
- depthIndex = numDepths;
- depths[depthIndex].depth = xnestVisuals[i].depth;
- depths[depthIndex].numVids = 0;
- depths[depthIndex].vids =
- (VisualID *)xalloc(MAXVISUALSPERDEPTH * sizeof(VisualID));
- numDepths++;
- }
- if (depths[depthIndex].numVids >= MAXVISUALSPERDEPTH) {
- FatalError("Visual table overflow");
- }
- depths[depthIndex].vids[depths[depthIndex].numVids] =
- visuals[numVisuals].vid;
- depths[depthIndex].numVids++;
-
- numVisuals++;
- }
- visuals = (VisualPtr)xrealloc(visuals, numVisuals * sizeof(VisualRec));
-
- defaultVisual = visuals[xnestDefaultVisualIndex].vid;
- rootDepth = visuals[xnestDefaultVisualIndex].nplanes;
-
- if (xnestParentWindow != 0) {
- XGetWindowAttributes(xnestDisplay, xnestParentWindow, &gattributes);
- xnestWidth = gattributes.width;
- xnestHeight = gattributes.height;
- }
-
- /* myNum */
- /* id */
- miScreenInit(pScreen, NULL, xnestWidth, xnestHeight, 1, 1, xnestWidth,
- rootDepth,
- numDepths, depths,
- defaultVisual, /* root visual */
- numVisuals, visuals);
-
-/* miInitializeBackingStore(pScreen); */
-
- pScreen->defColormap = (Colormap) FakeClientID(0);
- pScreen->minInstalledCmaps = MINCMAPS;
- pScreen->maxInstalledCmaps = MAXCMAPS;
- pScreen->backingStoreSupport = NotUseful;
- pScreen->saveUnderSupport = NotUseful;
- pScreen->whitePixel = xnestWhitePixel;
- pScreen->blackPixel = xnestBlackPixel;
- /* rgf */
- /* GCperDepth */
- /* PixmapPerDepth */
- pScreen->devPrivate = NULL;
- /* WindowPrivateLen */
- /* WindowPrivateSizes */
- /* totalWindowSize */
- /* GCPrivateLen */
- /* GCPrivateSizes */
- /* totalGCSize */
-
- /* Random screen procedures */
-
- pScreen->QueryBestSize = xnestQueryBestSize;
- pScreen->SaveScreen = xnestSaveScreen;
- pScreen->GetImage = xnestGetImage;
- pScreen->GetSpans = xnestGetSpans;
- pScreen->PointerNonInterestBox = NULL;
- pScreen->SourceValidate = NULL;
-
- /* Window Procedures */
-
- pScreen->CreateWindow = xnestCreateWindow;
- pScreen->DestroyWindow = xnestDestroyWindow;
- pScreen->PositionWindow = xnestPositionWindow;
- pScreen->ChangeWindowAttributes = xnestChangeWindowAttributes;
- pScreen->RealizeWindow = xnestRealizeWindow;
- pScreen->UnrealizeWindow = xnestUnrealizeWindow;
- pScreen->PostValidateTree = NULL;
- pScreen->WindowExposures = xnestWindowExposures;
- pScreen->CopyWindow = xnestCopyWindow;
- pScreen->ClipNotify = xnestClipNotify;
-
- /* Pixmap procedures */
-
- pScreen->CreatePixmap = xnestCreatePixmap;
- pScreen->DestroyPixmap = xnestDestroyPixmap;
-
- /* Font procedures */
-
- pScreen->RealizeFont = xnestRealizeFont;
- pScreen->UnrealizeFont = xnestUnrealizeFont;
-
- /* GC procedures */
-
- pScreen->CreateGC = xnestCreateGC;
-
- /* Colormap procedures */
-
- pScreen->CreateColormap = xnestCreateColormap;
- pScreen->DestroyColormap = xnestDestroyColormap;
- pScreen->InstallColormap = xnestInstallColormap;
- pScreen->UninstallColormap = xnestUninstallColormap;
- pScreen->ListInstalledColormaps = xnestListInstalledColormaps;
- pScreen->StoreColors = xnestStoreColors;
- pScreen->ResolveColor = xnestResolveColor;
-
- pScreen->BitmapToRegion = xnestPixmapToRegion;
-
- /* OS layer procedures */
-
- pScreen->BlockHandler = (ScreenBlockHandlerProcPtr)NoopDDA;
- pScreen->WakeupHandler = (ScreenWakeupHandlerProcPtr)NoopDDA;
- pScreen->blockData = NULL;
- pScreen->wakeupData = NULL;
-
- miDCInitialize(pScreen, &xnestPointerCursorFuncs); /* init SW rendering */
- PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
- xnestCursorFuncs.spriteFuncs = PointPriv->spriteFuncs;
- dixSetPrivate(&pScreen->devPrivates, xnestCursorScreenKey, &xnestCursorFuncs);
- PointPriv->spriteFuncs = &xnestPointerSpriteFuncs;
-
- pScreen->mmWidth = xnestWidth * DisplayWidthMM(xnestDisplay,
- DefaultScreen(xnestDisplay)) /
- DisplayWidth(xnestDisplay,
- DefaultScreen(xnestDisplay));
- pScreen->mmHeight = xnestHeight * DisplayHeightMM(xnestDisplay,
- DefaultScreen(xnestDisplay)) /
- DisplayHeight(xnestDisplay,
- DefaultScreen(xnestDisplay));
-
- /* overwrite miCloseScreen with our own */
- pScreen->CloseScreen = xnestCloseScreen;
-
- if (!miScreenDevPrivateInit(pScreen, xnestWidth, NULL))
- return FALSE;
-
- /* overwrite miSetShape with our own */
- pScreen->SetShape = xnestSetShape;
-
- /* devPrivates */
-
-#define POSITION_OFFSET (pScreen->myNum * (xnestWidth + xnestHeight) / 32)
-
- if (xnestDoFullGeneration) {
-
- valuemask = CWBackPixel | CWEventMask | CWColormap;
- attributes.background_pixel = xnestWhitePixel;
- attributes.event_mask = xnestEventMask;
- attributes.colormap = xnestDefaultVisualColormap(xnestDefaultVisual(pScreen));
-
- if (xnestParentWindow != 0) {
- xnestDefaultWindows[pScreen->myNum] = xnestParentWindow;
- XSelectInput (xnestDisplay, xnestDefaultWindows[pScreen->myNum],
- xnestEventMask);
- } else
- xnestDefaultWindows[pScreen->myNum] =
- XCreateWindow(xnestDisplay,
- DefaultRootWindow(xnestDisplay),
- xnestX + POSITION_OFFSET,
- xnestY + POSITION_OFFSET,
- xnestWidth, xnestHeight,
- xnestBorderWidth,
- pScreen->rootDepth,
- InputOutput,
- xnestDefaultVisual(pScreen),
- valuemask, &attributes);
-
- if (!xnestWindowName)
- xnestWindowName = argv[0];
-
- sizeHints.flags = PPosition | PSize | PMaxSize;
- sizeHints.x = xnestX + POSITION_OFFSET;
- sizeHints.y = xnestY + POSITION_OFFSET;
- sizeHints.width = sizeHints.max_width = xnestWidth;
- sizeHints.height = sizeHints.max_height = xnestHeight;
- if (xnestUserGeometry & XValue || xnestUserGeometry & YValue)
- sizeHints.flags |= USPosition;
- if (xnestUserGeometry & WidthValue || xnestUserGeometry & HeightValue)
- sizeHints.flags |= USSize;
- XSetStandardProperties(xnestDisplay,
- xnestDefaultWindows[pScreen->myNum],
- xnestWindowName,
- xnestWindowName,
- xnestIconBitmap,
- argv, argc, &sizeHints);
-
- XMapWindow(xnestDisplay, xnestDefaultWindows[pScreen->myNum]);
-
- valuemask = CWBackPixmap | CWColormap;
- attributes.background_pixmap = xnestScreenSaverPixmap;
- attributes.colormap =
- DefaultColormap(xnestDisplay, DefaultScreen(xnestDisplay));
- xnestScreenSaverWindows[pScreen->myNum] =
- XCreateWindow(xnestDisplay,
- xnestDefaultWindows[pScreen->myNum],
- 0, 0, xnestWidth, xnestHeight, 0,
- DefaultDepth(xnestDisplay, DefaultScreen(xnestDisplay)),
- InputOutput,
- DefaultVisual(xnestDisplay, DefaultScreen(xnestDisplay)),
- valuemask, &attributes);
- }
-
- if (!xnestCreateDefaultColormap(pScreen)) return False;
-
- return True;
-}
-
-Bool
-xnestCloseScreen(int index, ScreenPtr pScreen)
-{
- int i;
-
- for (i = 0; i < pScreen->numDepths; i++)
- xfree(pScreen->allowedDepths[i].vids);
- xfree(pScreen->allowedDepths);
- xfree(pScreen->visuals);
- xfree(pScreen->devPrivate);
-
- /*
- If xnestDoFullGeneration all x resources will be destroyed upon closing
- the display connection. There is no need to generate extra protocol.
- */
-
- return True;
-}
+/*
+
+Copyright 1993 by Davor Matic
+
+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. Davor Matic makes no representations about
+the suitability of this software for any purpose. It is provided "as
+is" without express or implied warranty.
+
+*/
+
+#ifdef HAVE_XNEST_CONFIG_H
+#include <xnest-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "scrnintstr.h"
+#include "dix.h"
+#include "mi.h"
+#include "mibstore.h"
+#include "micmap.h"
+#include "colormapst.h"
+#include "resource.h"
+
+#include "Xnest.h"
+
+#include "Display.h"
+#include "Screen.h"
+#include "XNGC.h"
+#include "GCOps.h"
+#include "Drawable.h"
+#include "XNFont.h"
+#include "Color.h"
+#include "XNCursor.h"
+#include "Visual.h"
+#include "Events.h"
+#include "Init.h"
+#include "mipointer.h"
+#include "Args.h"
+#include "mipointrst.h"
+
+Window xnestDefaultWindows[MAXSCREENS];
+Window xnestScreenSaverWindows[MAXSCREENS];
+static int xnestCursorScreenKeyIndex;
+DevPrivateKey xnestCursorScreenKey = &xnestCursorScreenKeyIndex;
+
+ScreenPtr
+xnestScreen(Window window)
+{
+ int i;
+
+ for (i = 0; i < xnestNumScreens; i++)
+ if (xnestDefaultWindows[i] == window)
+ return screenInfo.screens[i];
+
+ return NULL;
+}
+
+static int
+offset(unsigned long mask)
+{
+ int count;
+
+ for (count = 0; !(mask & 1) && count < 32; count++)
+ mask >>= 1;
+
+ return count;
+}
+
+static Bool
+xnestSaveScreen(ScreenPtr pScreen, int what)
+{
+ if (xnestSoftwareScreenSaver)
+ return False;
+ else {
+ switch (what) {
+ case SCREEN_SAVER_ON:
+ XMapRaised(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
+ xnestSetScreenSaverColormapWindow(pScreen);
+ break;
+
+ case SCREEN_SAVER_OFF:
+ XUnmapWindow(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
+ xnestSetInstalledColormapWindows(pScreen);
+ break;
+
+ case SCREEN_SAVER_FORCER:
+ lastEventTime = GetTimeInMillis();
+ XUnmapWindow(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
+ xnestSetInstalledColormapWindows(pScreen);
+ break;
+
+ case SCREEN_SAVER_CYCLE:
+ XUnmapWindow(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]);
+ xnestSetInstalledColormapWindows(pScreen);
+ break;
+ }
+ return True;
+ }
+}
+
+static Bool
+xnestCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
+{
+ return FALSE;
+}
+
+static void
+xnestCrossScreen(ScreenPtr pScreen, Bool entering)
+{
+}
+
+static miPointerScreenFuncRec xnestPointerCursorFuncs =
+{
+ xnestCursorOffScreen,
+ xnestCrossScreen,
+ miPointerWarpCursor
+};
+
+static miPointerSpriteFuncRec xnestPointerSpriteFuncs =
+{
+ xnestRealizeCursor,
+ xnestUnrealizeCursor,
+ xnestSetCursor,
+ xnestMoveCursor,
+ xnestDeviceCursorInitialize,
+ xnestDeviceCursorCleanup
+};
+
+Bool
+xnestOpenScreen(int index, ScreenPtr pScreen, int argc, char *argv[])
+{
+ VisualPtr visuals;
+ DepthPtr depths;
+ int numVisuals, numDepths;
+ int i, j, depthIndex;
+ unsigned long valuemask;
+ XSetWindowAttributes attributes;
+ XWindowAttributes gattributes;
+ XSizeHints sizeHints;
+ VisualID defaultVisual;
+ int rootDepth;
+ miPointerScreenPtr PointPriv;
+
+ if (!dixRequestPrivate(xnestWindowPrivateKey, sizeof(xnestPrivWin)))
+ return False;
+ if (!dixRequestPrivate(xnestGCPrivateKey, sizeof(xnestPrivGC)))
+ return False;
+
+ visuals = (VisualPtr)malloc(xnestNumVisuals * sizeof(VisualRec));
+ numVisuals = 0;
+
+ depths = (DepthPtr)malloc(MAXDEPTH * sizeof(DepthRec));
+ depths[0].depth = 1;
+ depths[0].numVids = 0;
+ depths[0].vids = (VisualID *)malloc(MAXVISUALSPERDEPTH * sizeof(VisualID));
+ numDepths = 1;
+
+ for (i = 0; i < xnestNumVisuals; i++) {
+ visuals[numVisuals].class = xnestVisuals[i].class;
+ visuals[numVisuals].bitsPerRGBValue = xnestVisuals[i].bits_per_rgb;
+ visuals[numVisuals].ColormapEntries = xnestVisuals[i].colormap_size;
+ visuals[numVisuals].nplanes = xnestVisuals[i].depth;
+ visuals[numVisuals].redMask = xnestVisuals[i].red_mask;
+ visuals[numVisuals].greenMask = xnestVisuals[i].green_mask;
+ visuals[numVisuals].blueMask = xnestVisuals[i].blue_mask;
+ visuals[numVisuals].offsetRed = offset(xnestVisuals[i].red_mask);
+ visuals[numVisuals].offsetGreen = offset(xnestVisuals[i].green_mask);
+ visuals[numVisuals].offsetBlue = offset(xnestVisuals[i].blue_mask);
+
+ /* Check for and remove duplicates. */
+ for (j = 0; j < numVisuals; j++) {
+ if (visuals[numVisuals].class == visuals[j].class &&
+ visuals[numVisuals].bitsPerRGBValue == visuals[j].bitsPerRGBValue &&
+ visuals[numVisuals].ColormapEntries == visuals[j].ColormapEntries &&
+ visuals[numVisuals].nplanes == visuals[j].nplanes &&
+ visuals[numVisuals].redMask == visuals[j].redMask &&
+ visuals[numVisuals].greenMask == visuals[j].greenMask &&
+ visuals[numVisuals].blueMask == visuals[j].blueMask &&
+ visuals[numVisuals].offsetRed == visuals[j].offsetRed &&
+ visuals[numVisuals].offsetGreen == visuals[j].offsetGreen &&
+ visuals[numVisuals].offsetBlue == visuals[j].offsetBlue)
+ break;
+ }
+ if (j < numVisuals)
+ break;
+
+ visuals[numVisuals].vid = FakeClientID(0);
+
+ depthIndex = UNDEFINED;
+ for (j = 0; j < numDepths; j++)
+ if (depths[j].depth == xnestVisuals[i].depth) {
+ depthIndex = j;
+ break;
+ }
+
+ if (depthIndex == UNDEFINED) {
+ depthIndex = numDepths;
+ depths[depthIndex].depth = xnestVisuals[i].depth;
+ depths[depthIndex].numVids = 0;
+ depths[depthIndex].vids =
+ (VisualID *)malloc(MAXVISUALSPERDEPTH * sizeof(VisualID));
+ numDepths++;
+ }
+ if (depths[depthIndex].numVids >= MAXVISUALSPERDEPTH) {
+ FatalError("Visual table overflow");
+ }
+ depths[depthIndex].vids[depths[depthIndex].numVids] =
+ visuals[numVisuals].vid;
+ depths[depthIndex].numVids++;
+
+ numVisuals++;
+ }
+ visuals = (VisualPtr)realloc(visuals, numVisuals * sizeof(VisualRec));
+
+ defaultVisual = visuals[xnestDefaultVisualIndex].vid;
+ rootDepth = visuals[xnestDefaultVisualIndex].nplanes;
+
+ if (xnestParentWindow != 0) {
+ XGetWindowAttributes(xnestDisplay, xnestParentWindow, &gattributes);
+ xnestWidth = gattributes.width;
+ xnestHeight = gattributes.height;
+ }
+
+ /* myNum */
+ /* id */
+ miScreenInit(pScreen, NULL, xnestWidth, xnestHeight, 1, 1, xnestWidth,
+ rootDepth,
+ numDepths, depths,
+ defaultVisual, /* root visual */
+ numVisuals, visuals);
+
+/* miInitializeBackingStore(pScreen); */
+
+ pScreen->defColormap = (Colormap) FakeClientID(0);
+ pScreen->minInstalledCmaps = MINCMAPS;
+ pScreen->maxInstalledCmaps = MAXCMAPS;
+ pScreen->backingStoreSupport = NotUseful;
+ pScreen->saveUnderSupport = NotUseful;
+ pScreen->whitePixel = xnestWhitePixel;
+ pScreen->blackPixel = xnestBlackPixel;
+ /* rgf */
+ /* GCperDepth */
+ /* PixmapPerDepth */
+ pScreen->devPrivate = NULL;
+ /* WindowPrivateLen */
+ /* WindowPrivateSizes */
+ /* totalWindowSize */
+ /* GCPrivateLen */
+ /* GCPrivateSizes */
+ /* totalGCSize */
+
+ /* Random screen procedures */
+
+ pScreen->QueryBestSize = xnestQueryBestSize;
+ pScreen->SaveScreen = xnestSaveScreen;
+ pScreen->GetImage = xnestGetImage;
+ pScreen->GetSpans = xnestGetSpans;
+ pScreen->SourceValidate = NULL;
+
+ /* Window Procedures */
+
+ pScreen->CreateWindow = xnestCreateWindow;
+ pScreen->DestroyWindow = xnestDestroyWindow;
+ pScreen->PositionWindow = xnestPositionWindow;
+ pScreen->ChangeWindowAttributes = xnestChangeWindowAttributes;
+ pScreen->RealizeWindow = xnestRealizeWindow;
+ pScreen->UnrealizeWindow = xnestUnrealizeWindow;
+ pScreen->PostValidateTree = NULL;
+ pScreen->WindowExposures = xnestWindowExposures;
+ pScreen->CopyWindow = xnestCopyWindow;
+ pScreen->ClipNotify = xnestClipNotify;
+
+ /* Pixmap procedures */
+
+ pScreen->CreatePixmap = xnestCreatePixmap;
+ pScreen->DestroyPixmap = xnestDestroyPixmap;
+
+ /* Font procedures */
+
+ pScreen->RealizeFont = xnestRealizeFont;
+ pScreen->UnrealizeFont = xnestUnrealizeFont;
+
+ /* GC procedures */
+
+ pScreen->CreateGC = xnestCreateGC;
+
+ /* Colormap procedures */
+
+ pScreen->CreateColormap = xnestCreateColormap;
+ pScreen->DestroyColormap = xnestDestroyColormap;
+ pScreen->InstallColormap = xnestInstallColormap;
+ pScreen->UninstallColormap = xnestUninstallColormap;
+ pScreen->ListInstalledColormaps = xnestListInstalledColormaps;
+ pScreen->StoreColors = xnestStoreColors;
+ pScreen->ResolveColor = xnestResolveColor;
+
+ pScreen->BitmapToRegion = xnestPixmapToRegion;
+
+ /* OS layer procedures */
+
+ pScreen->BlockHandler = (ScreenBlockHandlerProcPtr)NoopDDA;
+ pScreen->WakeupHandler = (ScreenWakeupHandlerProcPtr)NoopDDA;
+ pScreen->blockData = NULL;
+ pScreen->wakeupData = NULL;
+
+ miDCInitialize(pScreen, &xnestPointerCursorFuncs); /* init SW rendering */
+ PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
+ xnestCursorFuncs.spriteFuncs = PointPriv->spriteFuncs;
+ dixSetPrivate(&pScreen->devPrivates, xnestCursorScreenKey, &xnestCursorFuncs);
+ PointPriv->spriteFuncs = &xnestPointerSpriteFuncs;
+
+ pScreen->mmWidth = xnestWidth * DisplayWidthMM(xnestDisplay,
+ DefaultScreen(xnestDisplay)) /
+ DisplayWidth(xnestDisplay,
+ DefaultScreen(xnestDisplay));
+ pScreen->mmHeight = xnestHeight * DisplayHeightMM(xnestDisplay,
+ DefaultScreen(xnestDisplay)) /
+ DisplayHeight(xnestDisplay,
+ DefaultScreen(xnestDisplay));
+
+ /* overwrite miCloseScreen with our own */
+ pScreen->CloseScreen = xnestCloseScreen;
+
+ if (!miScreenDevPrivateInit(pScreen, xnestWidth, NULL))
+ return FALSE;
+
+ /* overwrite miSetShape with our own */
+ pScreen->SetShape = xnestSetShape;
+
+ /* devPrivates */
+
+#define POSITION_OFFSET (pScreen->myNum * (xnestWidth + xnestHeight) / 32)
+
+ if (xnestDoFullGeneration) {
+
+ valuemask = CWBackPixel | CWEventMask | CWColormap;
+ attributes.background_pixel = xnestWhitePixel;
+ attributes.event_mask = xnestEventMask;
+ attributes.colormap = xnestDefaultVisualColormap(xnestDefaultVisual(pScreen));
+
+ if (xnestParentWindow != 0) {
+ xnestDefaultWindows[pScreen->myNum] = xnestParentWindow;
+ XSelectInput (xnestDisplay, xnestDefaultWindows[pScreen->myNum],
+ xnestEventMask);
+ } else
+ xnestDefaultWindows[pScreen->myNum] =
+ XCreateWindow(xnestDisplay,
+ DefaultRootWindow(xnestDisplay),
+ xnestX + POSITION_OFFSET,
+ xnestY + POSITION_OFFSET,
+ xnestWidth, xnestHeight,
+ xnestBorderWidth,
+ pScreen->rootDepth,
+ InputOutput,
+ xnestDefaultVisual(pScreen),
+ valuemask, &attributes);
+
+ if (!xnestWindowName)
+ xnestWindowName = argv[0];
+
+ sizeHints.flags = PPosition | PSize | PMaxSize;
+ sizeHints.x = xnestX + POSITION_OFFSET;
+ sizeHints.y = xnestY + POSITION_OFFSET;
+ sizeHints.width = sizeHints.max_width = xnestWidth;
+ sizeHints.height = sizeHints.max_height = xnestHeight;
+ if (xnestUserGeometry & XValue || xnestUserGeometry & YValue)
+ sizeHints.flags |= USPosition;
+ if (xnestUserGeometry & WidthValue || xnestUserGeometry & HeightValue)
+ sizeHints.flags |= USSize;
+ XSetStandardProperties(xnestDisplay,
+ xnestDefaultWindows[pScreen->myNum],
+ xnestWindowName,
+ xnestWindowName,
+ xnestIconBitmap,
+ argv, argc, &sizeHints);
+
+ XMapWindow(xnestDisplay, xnestDefaultWindows[pScreen->myNum]);
+
+ valuemask = CWBackPixmap | CWColormap;
+ attributes.background_pixmap = xnestScreenSaverPixmap;
+ attributes.colormap =
+ DefaultColormap(xnestDisplay, DefaultScreen(xnestDisplay));
+ xnestScreenSaverWindows[pScreen->myNum] =
+ XCreateWindow(xnestDisplay,
+ xnestDefaultWindows[pScreen->myNum],
+ 0, 0, xnestWidth, xnestHeight, 0,
+ DefaultDepth(xnestDisplay, DefaultScreen(xnestDisplay)),
+ InputOutput,
+ DefaultVisual(xnestDisplay, DefaultScreen(xnestDisplay)),
+ valuemask, &attributes);
+ }
+
+ if (!xnestCreateDefaultColormap(pScreen)) return False;
+
+ return True;
+}
+
+Bool
+xnestCloseScreen(int index, ScreenPtr pScreen)
+{
+ int i;
+
+ for (i = 0; i < pScreen->numDepths; i++)
+ free(pScreen->allowedDepths[i].vids);
+ free(pScreen->allowedDepths);
+ free(pScreen->visuals);
+ free(pScreen->devPrivate);
+
+ /*
+ If xnestDoFullGeneration all x resources will be destroyed upon closing
+ the display connection. There is no need to generate extra protocol.
+ */
+
+ return True;
+}
diff --git a/xorg-server/hw/xquartz/GL/glcontextmodes.c b/xorg-server/hw/xquartz/GL/glcontextmodes.c
index 326c8b235..52a9ca440 100644
--- a/xorg-server/hw/xquartz/GL/glcontextmodes.c
+++ b/xorg-server/hw/xquartz/GL/glcontextmodes.c
@@ -1,550 +1,550 @@
-/*
- * (C) Copyright IBM Corporation 2003
- * 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
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, 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 (including the next
- * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
- * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS 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.
- */
-
-/**
- * \file glcontextmodes.c
- * Utility routines for working with \c __GLcontextModes structures. At
- * some point most or all of these functions will be moved to the Mesa
- * code base.
- *
- * \author Ian Romanick <idr@us.ibm.com>
- */
-
-#if defined(IN_MINI_GLX)
-#include <GL/gl.h>
-#else
-#if defined(HAVE_DIX_CONFIG_H)
-# include <dix-config.h>
-#endif
-#include <X11/X.h>
-#include <GL/glx.h>
-#include "GL/glxint.h"
-#endif
-
-/* Memory macros */
-#if defined(IN_MINI_GLX)
-# include <stdlib.h>
-# include <string.h>
-# define _mesa_malloc(b) malloc(b)
-# define _mesa_free(m) free(m)
-# define _mesa_memset memset
-#else
-# ifdef XFree86Server
-# include <os.h>
-# include <string.h>
-# define _mesa_malloc(b) xalloc(b)
-# define _mesa_free(m) xfree(m)
-# define _mesa_memset memset
-# else
-# include <X11/Xlibint.h>
-# define _mesa_memset memset
-# define _mesa_malloc(b) Xmalloc(b)
-# define _mesa_free(m) Xfree(m)
-# endif /* XFree86Server */
-#endif /* !defined(IN_MINI_GLX) */
-
-#include "glcontextmodes.h"
-
-#if !defined(IN_MINI_GLX)
-#define NUM_VISUAL_TYPES 6
-
-/**
- * Convert an X visual type to a GLX visual type.
- *
- * \param visualType X visual type (i.e., \c TrueColor, \c StaticGray, etc.)
- * to be converted.
- * \return If \c visualType is a valid X visual type, a GLX visual type will
- * be returned. Otherwise \c GLX_NONE will be returned.
- */
-GLint
-_gl_convert_from_x_visual_type( int visualType )
-{
- static const int glx_visual_types[ NUM_VISUAL_TYPES ] = {
- GLX_STATIC_GRAY, GLX_GRAY_SCALE,
- GLX_STATIC_COLOR, GLX_PSEUDO_COLOR,
- GLX_TRUE_COLOR, GLX_DIRECT_COLOR
- };
-
- return ( (unsigned) visualType < NUM_VISUAL_TYPES )
- ? glx_visual_types[ visualType ] : GLX_NONE;
-}
-
-
-/**
- * Convert a GLX visual type to an X visual type.
- *
- * \param visualType GLX visual type (i.e., \c GLX_TRUE_COLOR,
- * \c GLX_STATIC_GRAY, etc.) to be converted.
- * \return If \c visualType is a valid GLX visual type, an X visual type will
- * be returned. Otherwise -1 will be returned.
- */
-GLint
-_gl_convert_to_x_visual_type( int visualType )
-{
- static const int x_visual_types[ NUM_VISUAL_TYPES ] = {
- TrueColor, DirectColor,
- PseudoColor, StaticColor,
- GrayScale, StaticGray
- };
-
- return ( (unsigned) (visualType - GLX_TRUE_COLOR) < NUM_VISUAL_TYPES )
- ? x_visual_types[ visualType - GLX_TRUE_COLOR ] : -1;
-}
-
-
-/**
- * Copy a GLX visual config structure to a GL context mode structure. All
- * of the fields in \c config are copied to \c mode. Additional fields in
- * \c mode that can be derrived from the fields of \c config (i.e.,
- * \c haveDepthBuffer) are also filled in. The remaining fields in \c mode
- * that cannot be derived are set to default values.
- *
- * \param mode Destination GL context mode.
- * \param config Source GLX visual config.
- *
- * \note
- * The \c fbconfigID and \c visualID fields of the \c __GLcontextModes
- * structure will be set to the \c vid of the \c __GLXvisualConfig structure.
- */
-void
-_gl_copy_visual_to_context_mode( __GLcontextModes * mode,
- const __GLXvisualConfig * config )
-{
- __GLcontextModes * const next = mode->next;
-
- (void) _mesa_memset( mode, 0, sizeof( __GLcontextModes ) );
- mode->next = next;
-
- mode->visualID = config->vid;
- mode->visualType = _gl_convert_from_x_visual_type( config->class );
- mode->xRenderable = GL_TRUE;
- mode->fbconfigID = config->vid;
- mode->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT;
-
- mode->rgbMode = (config->rgba != 0);
- mode->renderType = (mode->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
-
- mode->colorIndexMode = !(mode->rgbMode);
- mode->doubleBufferMode = (config->doubleBuffer != 0);
- mode->stereoMode = (config->stereo != 0);
-
- mode->haveAccumBuffer = ((config->accumRedSize +
- config->accumGreenSize +
- config->accumBlueSize +
- config->accumAlphaSize) > 0);
- mode->haveDepthBuffer = (config->depthSize > 0);
- mode->haveStencilBuffer = (config->stencilSize > 0);
-
- mode->redBits = config->redSize;
- mode->greenBits = config->greenSize;
- mode->blueBits = config->blueSize;
- mode->alphaBits = config->alphaSize;
- mode->redMask = config->redMask;
- mode->greenMask = config->greenMask;
- mode->blueMask = config->blueMask;
- mode->alphaMask = config->alphaMask;
- mode->rgbBits = mode->rgbMode ? config->bufferSize : 0;
- mode->indexBits = mode->colorIndexMode ? config->bufferSize : 0;
-
- mode->accumRedBits = config->accumRedSize;
- mode->accumGreenBits = config->accumGreenSize;
- mode->accumBlueBits = config->accumBlueSize;
- mode->accumAlphaBits = config->accumAlphaSize;
- mode->depthBits = config->depthSize;
- mode->stencilBits = config->stencilSize;
-
- mode->numAuxBuffers = config->auxBuffers;
- mode->level = config->level;
-
- mode->visualRating = config->visualRating;
- mode->transparentPixel = config->transparentPixel;
- mode->transparentRed = config->transparentRed;
- mode->transparentGreen = config->transparentGreen;
- mode->transparentBlue = config->transparentBlue;
- mode->transparentAlpha = config->transparentAlpha;
- mode->transparentIndex = config->transparentIndex;
- mode->samples = config->multiSampleSize;
- mode->sampleBuffers = config->nMultiSampleBuffers;
- /* mode->visualSelectGroup = config->visualSelectGroup; ? */
-
- mode->swapMethod = GLX_SWAP_UNDEFINED_OML;
-
- mode->bindToTextureRgb = (mode->rgbMode) ? GL_TRUE : GL_FALSE;
- mode->bindToTextureRgba = (mode->rgbMode && mode->alphaBits) ?
- GL_TRUE : GL_FALSE;
- mode->bindToMipmapTexture = mode->rgbMode ? GL_TRUE : GL_FALSE;
- mode->bindToTextureTargets = mode->rgbMode ?
- GLX_TEXTURE_1D_BIT_EXT | GLX_TEXTURE_2D_BIT_EXT |
- GLX_TEXTURE_RECTANGLE_BIT_EXT : 0;
- mode->yInverted = GL_FALSE;
-}
-
-
-/**
- * Get data from a GL context mode.
- *
- * \param mode GL context mode whose data is to be returned.
- * \param attribute Attribute of \c mode that is to be returned.
- * \param value_return Location to store the data member of \c mode.
- * \return If \c attribute is a valid attribute of \c mode, zero is
- * returned. Otherwise \c GLX_BAD_ATTRIBUTE is returned.
- */
-int
-_gl_get_context_mode_data(const __GLcontextModes *mode, int attribute,
- int *value_return)
-{
- switch (attribute) {
- case GLX_USE_GL:
- *value_return = GL_TRUE;
- return 0;
- case GLX_BUFFER_SIZE:
- *value_return = mode->rgbBits;
- return 0;
- case GLX_RGBA:
- *value_return = mode->rgbMode;
- return 0;
- case GLX_RED_SIZE:
- *value_return = mode->redBits;
- return 0;
- case GLX_GREEN_SIZE:
- *value_return = mode->greenBits;
- return 0;
- case GLX_BLUE_SIZE:
- *value_return = mode->blueBits;
- return 0;
- case GLX_ALPHA_SIZE:
- *value_return = mode->alphaBits;
- return 0;
- case GLX_DOUBLEBUFFER:
- *value_return = mode->doubleBufferMode;
- return 0;
- case GLX_STEREO:
- *value_return = mode->stereoMode;
- return 0;
- case GLX_AUX_BUFFERS:
- *value_return = mode->numAuxBuffers;
- return 0;
- case GLX_DEPTH_SIZE:
- *value_return = mode->depthBits;
- return 0;
- case GLX_STENCIL_SIZE:
- *value_return = mode->stencilBits;
- return 0;
- case GLX_ACCUM_RED_SIZE:
- *value_return = mode->accumRedBits;
- return 0;
- case GLX_ACCUM_GREEN_SIZE:
- *value_return = mode->accumGreenBits;
- return 0;
- case GLX_ACCUM_BLUE_SIZE:
- *value_return = mode->accumBlueBits;
- return 0;
- case GLX_ACCUM_ALPHA_SIZE:
- *value_return = mode->accumAlphaBits;
- return 0;
- case GLX_LEVEL:
- *value_return = mode->level;
- return 0;
- case GLX_TRANSPARENT_TYPE_EXT:
- *value_return = mode->transparentPixel;
- return 0;
- case GLX_TRANSPARENT_RED_VALUE:
- *value_return = mode->transparentRed;
- return 0;
- case GLX_TRANSPARENT_GREEN_VALUE:
- *value_return = mode->transparentGreen;
- return 0;
- case GLX_TRANSPARENT_BLUE_VALUE:
- *value_return = mode->transparentBlue;
- return 0;
- case GLX_TRANSPARENT_ALPHA_VALUE:
- *value_return = mode->transparentAlpha;
- return 0;
- case GLX_TRANSPARENT_INDEX_VALUE:
- *value_return = mode->transparentIndex;
- return 0;
- case GLX_X_VISUAL_TYPE:
- *value_return = mode->visualType;
- return 0;
- case GLX_CONFIG_CAVEAT:
- *value_return = mode->visualRating;
- return 0;
- case GLX_VISUAL_ID:
- *value_return = mode->visualID;
- return 0;
- case GLX_DRAWABLE_TYPE:
- *value_return = mode->drawableType;
- return 0;
- case GLX_RENDER_TYPE:
- *value_return = mode->renderType;
- return 0;
- case GLX_X_RENDERABLE:
- *value_return = mode->xRenderable;
- return 0;
- case GLX_FBCONFIG_ID:
- *value_return = mode->fbconfigID;
- return 0;
- case GLX_MAX_PBUFFER_WIDTH:
- *value_return = mode->maxPbufferWidth;
- return 0;
- case GLX_MAX_PBUFFER_HEIGHT:
- *value_return = mode->maxPbufferHeight;
- return 0;
- case GLX_MAX_PBUFFER_PIXELS:
- *value_return = mode->maxPbufferPixels;
- return 0;
- case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX:
- *value_return = mode->optimalPbufferWidth;
- return 0;
- case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX:
- *value_return = mode->optimalPbufferHeight;
- return 0;
- case GLX_SWAP_METHOD_OML:
- *value_return = mode->swapMethod;
- return 0;
- case GLX_SAMPLE_BUFFERS_SGIS:
- *value_return = mode->sampleBuffers;
- return 0;
- case GLX_SAMPLES_SGIS:
- *value_return = mode->samples;
- return 0;
- case GLX_BIND_TO_TEXTURE_RGB_EXT:
- *value_return = mode->bindToTextureRgb;
- return 0;
- case GLX_BIND_TO_TEXTURE_RGBA_EXT:
- *value_return = mode->bindToTextureRgba;
- return 0;
- case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
- *value_return = mode->bindToMipmapTexture == GL_TRUE ? GL_TRUE :
- GL_FALSE;
- return 0;
- case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
- *value_return = mode->bindToTextureTargets;
- return 0;
- case GLX_Y_INVERTED_EXT:
- *value_return = mode->yInverted;
- return 0;
-
- /* Applications are NOT allowed to query GLX_VISUAL_SELECT_GROUP_SGIX.
- * It is ONLY for communication between the GLX client and the GLX
- * server.
- */
- case GLX_VISUAL_SELECT_GROUP_SGIX:
- default:
- return GLX_BAD_ATTRIBUTE;
- }
-}
-#endif /* !defined(IN_MINI_GLX) */
-
-
-/**
- * Allocate a linked list of \c __GLcontextModes structures. The fields of
- * each structure will be initialized to "reasonable" default values. In
- * most cases this is the default value defined by table 3.4 of the GLX
- * 1.3 specification. This means that most values are either initialized to
- * zero or \c GLX_DONT_CARE (which is -1). As support for additional
- * extensions is added, the new values will be initialized to appropriate
- * values from the extension specification.
- *
- * \param count Number of structures to allocate.
- * \param minimum_size Minimum size of a structure to allocate. This allows
- * for differences in the version of the
- * \c __GLcontextModes stucture used in libGL and in a
- * DRI-based driver.
- * \returns A pointer to the first element in a linked list of \c count
- * stuctures on success, or \c NULL on failure.
- *
- * \warning Use of \c minimum_size does \b not guarantee binary compatibility.
- * The fundamental assumption is that if the \c minimum_size
- * specified by the driver and the size of the \c __GLcontextModes
- * structure in libGL is the same, then the meaning of each byte in
- * the structure is the same in both places. \b Be \b careful!
- * Basically this means that fields have to be added in libGL and
- * then propagated to drivers. Drivers should \b never arbitrarilly
- * extend the \c __GLcontextModes data-structure.
- */
-__GLcontextModes *
-_gl_context_modes_create( unsigned count, size_t minimum_size )
-{
- const size_t size = (minimum_size > sizeof( __GLcontextModes ))
- ? minimum_size : sizeof( __GLcontextModes );
- __GLcontextModes * base = NULL;
- __GLcontextModes ** next;
- unsigned i;
-
- next = & base;
- for ( i = 0 ; i < count ; i++ ) {
- *next = (__GLcontextModes *) _mesa_malloc( size );
- if ( *next == NULL ) {
- _gl_context_modes_destroy( base );
- base = NULL;
- break;
- }
-
- (void) _mesa_memset( *next, 0, size );
- (*next)->visualID = GLX_DONT_CARE;
- (*next)->visualType = GLX_DONT_CARE;
- (*next)->visualRating = GLX_NONE;
- (*next)->transparentPixel = GLX_NONE;
- (*next)->transparentRed = GLX_DONT_CARE;
- (*next)->transparentGreen = GLX_DONT_CARE;
- (*next)->transparentBlue = GLX_DONT_CARE;
- (*next)->transparentAlpha = GLX_DONT_CARE;
- (*next)->transparentIndex = GLX_DONT_CARE;
- (*next)->xRenderable = GLX_DONT_CARE;
- (*next)->fbconfigID = GLX_DONT_CARE;
- (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML;
- (*next)->bindToTextureRgb = GLX_DONT_CARE;
- (*next)->bindToTextureRgba = GLX_DONT_CARE;
- (*next)->bindToMipmapTexture = GLX_DONT_CARE;
- (*next)->bindToTextureTargets = GLX_DONT_CARE;
- (*next)->yInverted = GLX_DONT_CARE;
-
- next = & ((*next)->next);
- }
-
- return base;
-}
-
-
-/**
- * Destroy a linked list of \c __GLcontextModes structures created by
- * \c _gl_context_modes_create.
- *
- * \param modes Linked list of structures to be destroyed. All structres
- * in the list will be freed.
- */
-void
-_gl_context_modes_destroy( __GLcontextModes * modes )
-{
- while ( modes != NULL ) {
- __GLcontextModes * const next = modes->next;
-
- _mesa_free( modes );
- modes = next;
- }
-}
-
-
-/**
- * Find a context mode matching a Visual ID.
- *
- * \param modes List list of context-mode structures to be searched.
- * \param vid Visual ID to be found.
- * \returns A pointer to a context-mode in \c modes if \c vid was found in
- * the list, or \c NULL if it was not.
- */
-
-__GLcontextModes *
-_gl_context_modes_find_visual(__GLcontextModes *modes, int vid)
-{
- __GLcontextModes *m;
-
- for (m = modes; m != NULL; m = m->next)
- if (m->visualID == vid)
- return m;
-
- return NULL;
-}
-
-__GLcontextModes *
-_gl_context_modes_find_fbconfig(__GLcontextModes *modes, int fbid)
-{
- __GLcontextModes *m;
-
- for (m = modes; m != NULL; m = m->next)
- if (m->fbconfigID == fbid)
- return m;
-
- return NULL;
-}
-
-/**
- * Determine if two context-modes are the same. This is intended to be used
- * by libGL implementations to compare to sets of driver generated FBconfigs.
- *
- * \param a Context-mode to be compared.
- * \param b Context-mode to be compared.
- * \returns \c GL_TRUE if the two context-modes are the same. \c GL_FALSE is
- * returned otherwise.
- */
-GLboolean
-_gl_context_modes_are_same( const __GLcontextModes * a,
- const __GLcontextModes * b )
-{
- return( (a->rgbMode == b->rgbMode) &&
- (a->floatMode == b->floatMode) &&
- (a->colorIndexMode == b->colorIndexMode) &&
- (a->doubleBufferMode == b->doubleBufferMode) &&
- (a->stereoMode == b->stereoMode) &&
- (a->redBits == b->redBits) &&
- (a->greenBits == b->greenBits) &&
- (a->blueBits == b->blueBits) &&
- (a->alphaBits == b->alphaBits) &&
-#if 0 /* For some reason these don't get set on the client-side in libGL. */
- (a->redMask == b->redMask) &&
- (a->greenMask == b->greenMask) &&
- (a->blueMask == b->blueMask) &&
- (a->alphaMask == b->alphaMask) &&
-#endif
- (a->rgbBits == b->rgbBits) &&
- (a->indexBits == b->indexBits) &&
- (a->accumRedBits == b->accumRedBits) &&
- (a->accumGreenBits == b->accumGreenBits) &&
- (a->accumBlueBits == b->accumBlueBits) &&
- (a->accumAlphaBits == b->accumAlphaBits) &&
- (a->depthBits == b->depthBits) &&
- (a->stencilBits == b->stencilBits) &&
- (a->numAuxBuffers == b->numAuxBuffers) &&
- (a->level == b->level) &&
- (a->pixmapMode == b->pixmapMode) &&
- (a->visualRating == b->visualRating) &&
-
- (a->transparentPixel == b->transparentPixel) &&
-
- ((a->transparentPixel != GLX_TRANSPARENT_RGB) ||
- ((a->transparentRed == b->transparentRed) &&
- (a->transparentGreen == b->transparentGreen) &&
- (a->transparentBlue == b->transparentBlue) &&
- (a->transparentAlpha == b->transparentAlpha))) &&
-
- ((a->transparentPixel != GLX_TRANSPARENT_INDEX) ||
- (a->transparentIndex == b->transparentIndex)) &&
-
- (a->sampleBuffers == b->sampleBuffers) &&
- (a->samples == b->samples) &&
- ((a->drawableType & b->drawableType) != 0) &&
- (a->renderType == b->renderType) &&
- (a->maxPbufferWidth == b->maxPbufferWidth) &&
- (a->maxPbufferHeight == b->maxPbufferHeight) &&
- (a->maxPbufferPixels == b->maxPbufferPixels) &&
- (a->optimalPbufferWidth == b->optimalPbufferWidth) &&
- (a->optimalPbufferHeight == b->optimalPbufferHeight) &&
- (a->swapMethod == b->swapMethod) &&
- (a->bindToTextureRgb == b->bindToTextureRgb) &&
- (a->bindToTextureRgba == b->bindToTextureRgba) &&
- (a->bindToMipmapTexture == b->bindToMipmapTexture) &&
- (a->bindToTextureTargets == b->bindToTextureTargets) &&
- (a->yInverted == b->yInverted) );
-}
+/*
+ * (C) Copyright IBM Corporation 2003
+ * 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
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, 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 (including the next
+ * paragraph) 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 NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS 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.
+ */
+
+/**
+ * \file glcontextmodes.c
+ * Utility routines for working with \c __GLcontextModes structures. At
+ * some point most or all of these functions will be moved to the Mesa
+ * code base.
+ *
+ * \author Ian Romanick <idr@us.ibm.com>
+ */
+
+#if defined(IN_MINI_GLX)
+#include <GL/gl.h>
+#else
+#if defined(HAVE_DIX_CONFIG_H)
+# include <dix-config.h>
+#endif
+#include <X11/X.h>
+#include <GL/glx.h>
+#include "GL/glxint.h"
+#endif
+
+/* Memory macros */
+#if defined(IN_MINI_GLX)
+# include <stdlib.h>
+# include <string.h>
+# define _mesa_malloc(b) malloc(b)
+# define _mesa_free(m) free(m)
+# define _mesa_memset memset
+#else
+# ifdef XFree86Server
+# include <os.h>
+# include <string.h>
+# define _mesa_malloc(b) malloc(b)
+# define _mesa_free(m) free(m)
+# define _mesa_memset memset
+# else
+# include <X11/Xlibint.h>
+# define _mesa_memset memset
+# define _mesa_malloc(b) Xmalloc(b)
+# define _mesa_free(m) free(m)
+# endif /* XFree86Server */
+#endif /* !defined(IN_MINI_GLX) */
+
+#include "glcontextmodes.h"
+
+#if !defined(IN_MINI_GLX)
+#define NUM_VISUAL_TYPES 6
+
+/**
+ * Convert an X visual type to a GLX visual type.
+ *
+ * \param visualType X visual type (i.e., \c TrueColor, \c StaticGray, etc.)
+ * to be converted.
+ * \return If \c visualType is a valid X visual type, a GLX visual type will
+ * be returned. Otherwise \c GLX_NONE will be returned.
+ */
+GLint
+_gl_convert_from_x_visual_type( int visualType )
+{
+ static const int glx_visual_types[ NUM_VISUAL_TYPES ] = {
+ GLX_STATIC_GRAY, GLX_GRAY_SCALE,
+ GLX_STATIC_COLOR, GLX_PSEUDO_COLOR,
+ GLX_TRUE_COLOR, GLX_DIRECT_COLOR
+ };
+
+ return ( (unsigned) visualType < NUM_VISUAL_TYPES )
+ ? glx_visual_types[ visualType ] : GLX_NONE;
+}
+
+
+/**
+ * Convert a GLX visual type to an X visual type.
+ *
+ * \param visualType GLX visual type (i.e., \c GLX_TRUE_COLOR,
+ * \c GLX_STATIC_GRAY, etc.) to be converted.
+ * \return If \c visualType is a valid GLX visual type, an X visual type will
+ * be returned. Otherwise -1 will be returned.
+ */
+GLint
+_gl_convert_to_x_visual_type( int visualType )
+{
+ static const int x_visual_types[ NUM_VISUAL_TYPES ] = {
+ TrueColor, DirectColor,
+ PseudoColor, StaticColor,
+ GrayScale, StaticGray
+ };
+
+ return ( (unsigned) (visualType - GLX_TRUE_COLOR) < NUM_VISUAL_TYPES )
+ ? x_visual_types[ visualType - GLX_TRUE_COLOR ] : -1;
+}
+
+
+/**
+ * Copy a GLX visual config structure to a GL context mode structure. All
+ * of the fields in \c config are copied to \c mode. Additional fields in
+ * \c mode that can be derrived from the fields of \c config (i.e.,
+ * \c haveDepthBuffer) are also filled in. The remaining fields in \c mode
+ * that cannot be derived are set to default values.
+ *
+ * \param mode Destination GL context mode.
+ * \param config Source GLX visual config.
+ *
+ * \note
+ * The \c fbconfigID and \c visualID fields of the \c __GLcontextModes
+ * structure will be set to the \c vid of the \c __GLXvisualConfig structure.
+ */
+void
+_gl_copy_visual_to_context_mode( __GLcontextModes * mode,
+ const __GLXvisualConfig * config )
+{
+ __GLcontextModes * const next = mode->next;
+
+ (void) _mesa_memset( mode, 0, sizeof( __GLcontextModes ) );
+ mode->next = next;
+
+ mode->visualID = config->vid;
+ mode->visualType = _gl_convert_from_x_visual_type( config->class );
+ mode->xRenderable = GL_TRUE;
+ mode->fbconfigID = config->vid;
+ mode->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT;
+
+ mode->rgbMode = (config->rgba != 0);
+ mode->renderType = (mode->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
+
+ mode->colorIndexMode = !(mode->rgbMode);
+ mode->doubleBufferMode = (config->doubleBuffer != 0);
+ mode->stereoMode = (config->stereo != 0);
+
+ mode->haveAccumBuffer = ((config->accumRedSize +
+ config->accumGreenSize +
+ config->accumBlueSize +
+ config->accumAlphaSize) > 0);
+ mode->haveDepthBuffer = (config->depthSize > 0);
+ mode->haveStencilBuffer = (config->stencilSize > 0);
+
+ mode->redBits = config->redSize;
+ mode->greenBits = config->greenSize;
+ mode->blueBits = config->blueSize;
+ mode->alphaBits = config->alphaSize;
+ mode->redMask = config->redMask;
+ mode->greenMask = config->greenMask;
+ mode->blueMask = config->blueMask;
+ mode->alphaMask = config->alphaMask;
+ mode->rgbBits = mode->rgbMode ? config->bufferSize : 0;
+ mode->indexBits = mode->colorIndexMode ? config->bufferSize : 0;
+
+ mode->accumRedBits = config->accumRedSize;
+ mode->accumGreenBits = config->accumGreenSize;
+ mode->accumBlueBits = config->accumBlueSize;
+ mode->accumAlphaBits = config->accumAlphaSize;
+ mode->depthBits = config->depthSize;
+ mode->stencilBits = config->stencilSize;
+
+ mode->numAuxBuffers = config->auxBuffers;
+ mode->level = config->level;
+
+ mode->visualRating = config->visualRating;
+ mode->transparentPixel = config->transparentPixel;
+ mode->transparentRed = config->transparentRed;
+ mode->transparentGreen = config->transparentGreen;
+ mode->transparentBlue = config->transparentBlue;
+ mode->transparentAlpha = config->transparentAlpha;
+ mode->transparentIndex = config->transparentIndex;
+ mode->samples = config->multiSampleSize;
+ mode->sampleBuffers = config->nMultiSampleBuffers;
+ /* mode->visualSelectGroup = config->visualSelectGroup; ? */
+
+ mode->swapMethod = GLX_SWAP_UNDEFINED_OML;
+
+ mode->bindToTextureRgb = (mode->rgbMode) ? GL_TRUE : GL_FALSE;
+ mode->bindToTextureRgba = (mode->rgbMode && mode->alphaBits) ?
+ GL_TRUE : GL_FALSE;
+ mode->bindToMipmapTexture = mode->rgbMode ? GL_TRUE : GL_FALSE;
+ mode->bindToTextureTargets = mode->rgbMode ?
+ GLX_TEXTURE_1D_BIT_EXT | GLX_TEXTURE_2D_BIT_EXT |
+ GLX_TEXTURE_RECTANGLE_BIT_EXT : 0;
+ mode->yInverted = GL_FALSE;
+}
+
+
+/**
+ * Get data from a GL context mode.
+ *
+ * \param mode GL context mode whose data is to be returned.
+ * \param attribute Attribute of \c mode that is to be returned.
+ * \param value_return Location to store the data member of \c mode.
+ * \return If \c attribute is a valid attribute of \c mode, zero is
+ * returned. Otherwise \c GLX_BAD_ATTRIBUTE is returned.
+ */
+int
+_gl_get_context_mode_data(const __GLcontextModes *mode, int attribute,
+ int *value_return)
+{
+ switch (attribute) {
+ case GLX_USE_GL:
+ *value_return = GL_TRUE;
+ return 0;
+ case GLX_BUFFER_SIZE:
+ *value_return = mode->rgbBits;
+ return 0;
+ case GLX_RGBA:
+ *value_return = mode->rgbMode;
+ return 0;
+ case GLX_RED_SIZE:
+ *value_return = mode->redBits;
+ return 0;
+ case GLX_GREEN_SIZE:
+ *value_return = mode->greenBits;
+ return 0;
+ case GLX_BLUE_SIZE:
+ *value_return = mode->blueBits;
+ return 0;
+ case GLX_ALPHA_SIZE:
+ *value_return = mode->alphaBits;
+ return 0;
+ case GLX_DOUBLEBUFFER:
+ *value_return = mode->doubleBufferMode;
+ return 0;
+ case GLX_STEREO:
+ *value_return = mode->stereoMode;
+ return 0;
+ case GLX_AUX_BUFFERS:
+ *value_return = mode->numAuxBuffers;
+ return 0;
+ case GLX_DEPTH_SIZE:
+ *value_return = mode->depthBits;
+ return 0;
+ case GLX_STENCIL_SIZE:
+ *value_return = mode->stencilBits;
+ return 0;
+ case GLX_ACCUM_RED_SIZE:
+ *value_return = mode->accumRedBits;
+ return 0;
+ case GLX_ACCUM_GREEN_SIZE:
+ *value_return = mode->accumGreenBits;
+ return 0;
+ case GLX_ACCUM_BLUE_SIZE:
+ *value_return = mode->accumBlueBits;
+ return 0;
+ case GLX_ACCUM_ALPHA_SIZE:
+ *value_return = mode->accumAlphaBits;
+ return 0;
+ case GLX_LEVEL:
+ *value_return = mode->level;
+ return 0;
+ case GLX_TRANSPARENT_TYPE_EXT:
+ *value_return = mode->transparentPixel;
+ return 0;
+ case GLX_TRANSPARENT_RED_VALUE:
+ *value_return = mode->transparentRed;
+ return 0;
+ case GLX_TRANSPARENT_GREEN_VALUE:
+ *value_return = mode->transparentGreen;
+ return 0;
+ case GLX_TRANSPARENT_BLUE_VALUE:
+ *value_return = mode->transparentBlue;
+ return 0;
+ case GLX_TRANSPARENT_ALPHA_VALUE:
+ *value_return = mode->transparentAlpha;
+ return 0;
+ case GLX_TRANSPARENT_INDEX_VALUE:
+ *value_return = mode->transparentIndex;
+ return 0;
+ case GLX_X_VISUAL_TYPE:
+ *value_return = mode->visualType;
+ return 0;
+ case GLX_CONFIG_CAVEAT:
+ *value_return = mode->visualRating;
+ return 0;
+ case GLX_VISUAL_ID:
+ *value_return = mode->visualID;
+ return 0;
+ case GLX_DRAWABLE_TYPE:
+ *value_return = mode->drawableType;
+ return 0;
+ case GLX_RENDER_TYPE:
+ *value_return = mode->renderType;
+ return 0;
+ case GLX_X_RENDERABLE:
+ *value_return = mode->xRenderable;
+ return 0;
+ case GLX_FBCONFIG_ID:
+ *value_return = mode->fbconfigID;
+ return 0;
+ case GLX_MAX_PBUFFER_WIDTH:
+ *value_return = mode->maxPbufferWidth;
+ return 0;
+ case GLX_MAX_PBUFFER_HEIGHT:
+ *value_return = mode->maxPbufferHeight;
+ return 0;
+ case GLX_MAX_PBUFFER_PIXELS:
+ *value_return = mode->maxPbufferPixels;
+ return 0;
+ case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX:
+ *value_return = mode->optimalPbufferWidth;
+ return 0;
+ case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX:
+ *value_return = mode->optimalPbufferHeight;
+ return 0;
+ case GLX_SWAP_METHOD_OML:
+ *value_return = mode->swapMethod;
+ return 0;
+ case GLX_SAMPLE_BUFFERS_SGIS:
+ *value_return = mode->sampleBuffers;
+ return 0;
+ case GLX_SAMPLES_SGIS:
+ *value_return = mode->samples;
+ return 0;
+ case GLX_BIND_TO_TEXTURE_RGB_EXT:
+ *value_return = mode->bindToTextureRgb;
+ return 0;
+ case GLX_BIND_TO_TEXTURE_RGBA_EXT:
+ *value_return = mode->bindToTextureRgba;
+ return 0;
+ case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
+ *value_return = mode->bindToMipmapTexture == GL_TRUE ? GL_TRUE :
+ GL_FALSE;
+ return 0;
+ case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
+ *value_return = mode->bindToTextureTargets;
+ return 0;
+ case GLX_Y_INVERTED_EXT:
+ *value_return = mode->yInverted;
+ return 0;
+
+ /* Applications are NOT allowed to query GLX_VISUAL_SELECT_GROUP_SGIX.
+ * It is ONLY for communication between the GLX client and the GLX
+ * server.
+ */
+ case GLX_VISUAL_SELECT_GROUP_SGIX:
+ default:
+ return GLX_BAD_ATTRIBUTE;
+ }
+}
+#endif /* !defined(IN_MINI_GLX) */
+
+
+/**
+ * Allocate a linked list of \c __GLcontextModes structures. The fields of
+ * each structure will be initialized to "reasonable" default values. In
+ * most cases this is the default value defined by table 3.4 of the GLX
+ * 1.3 specification. This means that most values are either initialized to
+ * zero or \c GLX_DONT_CARE (which is -1). As support for additional
+ * extensions is added, the new values will be initialized to appropriate
+ * values from the extension specification.
+ *
+ * \param count Number of structures to allocate.
+ * \param minimum_size Minimum size of a structure to allocate. This allows
+ * for differences in the version of the
+ * \c __GLcontextModes stucture used in libGL and in a
+ * DRI-based driver.
+ * \returns A pointer to the first element in a linked list of \c count
+ * stuctures on success, or \c NULL on failure.
+ *
+ * \warning Use of \c minimum_size does \b not guarantee binary compatibility.
+ * The fundamental assumption is that if the \c minimum_size
+ * specified by the driver and the size of the \c __GLcontextModes
+ * structure in libGL is the same, then the meaning of each byte in
+ * the structure is the same in both places. \b Be \b careful!
+ * Basically this means that fields have to be added in libGL and
+ * then propagated to drivers. Drivers should \b never arbitrarilly
+ * extend the \c __GLcontextModes data-structure.
+ */
+__GLcontextModes *
+_gl_context_modes_create( unsigned count, size_t minimum_size )
+{
+ const size_t size = (minimum_size > sizeof( __GLcontextModes ))
+ ? minimum_size : sizeof( __GLcontextModes );
+ __GLcontextModes * base = NULL;
+ __GLcontextModes ** next;
+ unsigned i;
+
+ next = & base;
+ for ( i = 0 ; i < count ; i++ ) {
+ *next = (__GLcontextModes *) _mesa_malloc( size );
+ if ( *next == NULL ) {
+ _gl_context_modes_destroy( base );
+ base = NULL;
+ break;
+ }
+
+ (void) _mesa_memset( *next, 0, size );
+ (*next)->visualID = GLX_DONT_CARE;
+ (*next)->visualType = GLX_DONT_CARE;
+ (*next)->visualRating = GLX_NONE;
+ (*next)->transparentPixel = GLX_NONE;
+ (*next)->transparentRed = GLX_DONT_CARE;
+ (*next)->transparentGreen = GLX_DONT_CARE;
+ (*next)->transparentBlue = GLX_DONT_CARE;
+ (*next)->transparentAlpha = GLX_DONT_CARE;
+ (*next)->transparentIndex = GLX_DONT_CARE;
+ (*next)->xRenderable = GLX_DONT_CARE;
+ (*next)->fbconfigID = GLX_DONT_CARE;
+ (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML;
+ (*next)->bindToTextureRgb = GLX_DONT_CARE;
+ (*next)->bindToTextureRgba = GLX_DONT_CARE;
+ (*next)->bindToMipmapTexture = GLX_DONT_CARE;
+ (*next)->bindToTextureTargets = GLX_DONT_CARE;
+ (*next)->yInverted = GLX_DONT_CARE;
+
+ next = & ((*next)->next);
+ }
+
+ return base;
+}
+
+
+/**
+ * Destroy a linked list of \c __GLcontextModes structures created by
+ * \c _gl_context_modes_create.
+ *
+ * \param modes Linked list of structures to be destroyed. All structres
+ * in the list will be freed.
+ */
+void
+_gl_context_modes_destroy( __GLcontextModes * modes )
+{
+ while ( modes != NULL ) {
+ __GLcontextModes * const next = modes->next;
+
+ _mesa_free( modes );
+ modes = next;
+ }
+}
+
+
+/**
+ * Find a context mode matching a Visual ID.
+ *
+ * \param modes List list of context-mode structures to be searched.
+ * \param vid Visual ID to be found.
+ * \returns A pointer to a context-mode in \c modes if \c vid was found in
+ * the list, or \c NULL if it was not.
+ */
+
+__GLcontextModes *
+_gl_context_modes_find_visual(__GLcontextModes *modes, int vid)
+{
+ __GLcontextModes *m;
+
+ for (m = modes; m != NULL; m = m->next)
+ if (m->visualID == vid)
+ return m;
+
+ return NULL;
+}
+
+__GLcontextModes *
+_gl_context_modes_find_fbconfig(__GLcontextModes *modes, int fbid)
+{
+ __GLcontextModes *m;
+
+ for (m = modes; m != NULL; m = m->next)
+ if (m->fbconfigID == fbid)
+ return m;
+
+ return NULL;
+}
+
+/**
+ * Determine if two context-modes are the same. This is intended to be used
+ * by libGL implementations to compare to sets of driver generated FBconfigs.
+ *
+ * \param a Context-mode to be compared.
+ * \param b Context-mode to be compared.
+ * \returns \c GL_TRUE if the two context-modes are the same. \c GL_FALSE is
+ * returned otherwise.
+ */
+GLboolean
+_gl_context_modes_are_same( const __GLcontextModes * a,
+ const __GLcontextModes * b )
+{
+ return( (a->rgbMode == b->rgbMode) &&
+ (a->floatMode == b->floatMode) &&
+ (a->colorIndexMode == b->colorIndexMode) &&
+ (a->doubleBufferMode == b->doubleBufferMode) &&
+ (a->stereoMode == b->stereoMode) &&
+ (a->redBits == b->redBits) &&
+ (a->greenBits == b->greenBits) &&
+ (a->blueBits == b->blueBits) &&
+ (a->alphaBits == b->alphaBits) &&
+#if 0 /* For some reason these don't get set on the client-side in libGL. */
+ (a->redMask == b->redMask) &&
+ (a->greenMask == b->greenMask) &&
+ (a->blueMask == b->blueMask) &&
+ (a->alphaMask == b->alphaMask) &&
+#endif
+ (a->rgbBits == b->rgbBits) &&
+ (a->indexBits == b->indexBits) &&
+ (a->accumRedBits == b->accumRedBits) &&
+ (a->accumGreenBits == b->accumGreenBits) &&
+ (a->accumBlueBits == b->accumBlueBits) &&
+ (a->accumAlphaBits == b->accumAlphaBits) &&
+ (a->depthBits == b->depthBits) &&
+ (a->stencilBits == b->stencilBits) &&
+ (a->numAuxBuffers == b->numAuxBuffers) &&
+ (a->level == b->level) &&
+ (a->pixmapMode == b->pixmapMode) &&
+ (a->visualRating == b->visualRating) &&
+
+ (a->transparentPixel == b->transparentPixel) &&
+
+ ((a->transparentPixel != GLX_TRANSPARENT_RGB) ||
+ ((a->transparentRed == b->transparentRed) &&
+ (a->transparentGreen == b->transparentGreen) &&
+ (a->transparentBlue == b->transparentBlue) &&
+ (a->transparentAlpha == b->transparentAlpha))) &&
+
+ ((a->transparentPixel != GLX_TRANSPARENT_INDEX) ||
+ (a->transparentIndex == b->transparentIndex)) &&
+
+ (a->sampleBuffers == b->sampleBuffers) &&
+ (a->samples == b->samples) &&
+ ((a->drawableType & b->drawableType) != 0) &&
+ (a->renderType == b->renderType) &&
+ (a->maxPbufferWidth == b->maxPbufferWidth) &&
+ (a->maxPbufferHeight == b->maxPbufferHeight) &&
+ (a->maxPbufferPixels == b->maxPbufferPixels) &&
+ (a->optimalPbufferWidth == b->optimalPbufferWidth) &&
+ (a->optimalPbufferHeight == b->optimalPbufferHeight) &&
+ (a->swapMethod == b->swapMethod) &&
+ (a->bindToTextureRgb == b->bindToTextureRgb) &&
+ (a->bindToTextureRgba == b->bindToTextureRgba) &&
+ (a->bindToMipmapTexture == b->bindToMipmapTexture) &&
+ (a->bindToTextureTargets == b->bindToTextureTargets) &&
+ (a->yInverted == b->yInverted) );
+}
diff --git a/xorg-server/hw/xquartz/GL/indirect.c b/xorg-server/hw/xquartz/GL/indirect.c
index e56dac1a1..b40f38d31 100644
--- a/xorg-server/hw/xquartz/GL/indirect.c
+++ b/xorg-server/hw/xquartz/GL/indirect.c
@@ -222,7 +222,7 @@ __glXAquaScreenCreateContext(__GLXscreen *screen,
GLAQUA_DEBUG_MSG("glXAquaScreenCreateContext\n");
- context = xcalloc(1, sizeof (__GLXAquaContext));
+ context = calloc(1, sizeof (__GLXAquaContext));
if (context == NULL)
return NULL;
@@ -241,7 +241,7 @@ __glXAquaScreenCreateContext(__GLXscreen *screen,
context->pixelFormat = makeFormat(conf);
if (!context->pixelFormat) {
- xfree(context);
+ free(context);
return NULL;
}
@@ -253,7 +253,7 @@ __glXAquaScreenCreateContext(__GLXscreen *screen,
if (gl_err != 0) {
ErrorF("CGLCreateContext error: %s\n", CGLErrorString(gl_err));
CGLDestroyPixelFormat(context->pixelFormat);
- xfree(context);
+ free(context);
return NULL;
}
@@ -286,7 +286,7 @@ static void __glXAquaContextDestroy(__GLXcontext *baseContext) {
if (context->pixelFormat != NULL)
CGLDestroyPixelFormat(context->pixelFormat);
- xfree(context);
+ free(context);
}
}
@@ -566,7 +566,7 @@ static void __glXAquaScreenDestroy(__GLXscreen *screen) {
GLAQUA_DEBUG_MSG("glXAquaScreenDestroy(%p)\n", screen);
__glXScreenDestroy(screen);
- xfree(screen);
+ free(screen);
}
/* This is called by __glXInitScreens(). */
@@ -578,7 +578,7 @@ static __GLXscreen * __glXAquaScreenProbe(ScreenPtr pScreen) {
if (pScreen == NULL)
return NULL;
- screen = xcalloc(1, sizeof *screen);
+ screen = calloc(1, sizeof *screen);
if(NULL == screen)
return NULL;
@@ -635,7 +635,7 @@ static void __glXAquaDrawableDestroy(__GLXdrawable *base) {
*to validate the test, beyond using gdb with print.
*/
- xfree(glxPriv);
+ free(glxPriv);
}
static __GLXdrawable *
@@ -648,7 +648,7 @@ __glXAquaScreenCreateDrawable(ClientPtr client,
__GLXconfig *conf) {
__GLXAquaDrawable *glxPriv;
- glxPriv = xalloc(sizeof *glxPriv);
+ glxPriv = malloc(sizeof *glxPriv);
if(glxPriv == NULL)
return NULL;
@@ -656,7 +656,7 @@ __glXAquaScreenCreateDrawable(ClientPtr client,
memset(glxPriv, 0, sizeof *glxPriv);
if(!__glXDrawableInit(&glxPriv->base, screen, pDraw, type, glxDrawId, conf)) {
- xfree(glxPriv);
+ free(glxPriv);
return NULL;
}
diff --git a/xorg-server/hw/xquartz/GL/visualConfigs.c b/xorg-server/hw/xquartz/GL/visualConfigs.c
index cecc90265..0d5793262 100644
--- a/xorg-server/hw/xquartz/GL/visualConfigs.c
+++ b/xorg-server/hw/xquartz/GL/visualConfigs.c
@@ -1,285 +1,285 @@
-/*
- * Copyright (c) 2007, 2008 Apple Inc.
- * Copyright (c) 2004 Torrey T. Lyons. All Rights Reserved.
- * Copyright (c) 2002 Greg Parker. All Rights Reserved.
- *
- * Portions of this file are copied from Mesa's xf86glx.c,
- * which contains the following copyright:
- *
- * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
- * 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 ABOVE LISTED COPYRIGHT HOLDER(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.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "dri.h"
-
-#include <OpenGL/OpenGL.h>
-#include <OpenGL/gl.h>
-#include <OpenGL/glext.h>
-#include <OpenGL/CGLContext.h>
-
-#include <GL/glxproto.h>
-#include <windowstr.h>
-#include <resource.h>
-#include <GL/glxint.h>
-#include <GL/glxtokens.h>
-#include <scrnintstr.h>
-#include <glxserver.h>
-#include <glxscreens.h>
-#include <glxdrawable.h>
-#include <glxcontext.h>
-#include <glxext.h>
-#include <glxutil.h>
-#include <glxscreens.h>
-#include <GL/internal/glcore.h>
-
-#include "capabilities.h"
-#include "visualConfigs.h"
-#include "darwinfb.h"
-
-/* Based originally on code from indirect.c which was based on code from i830_dri.c. */
-__GLXconfig *__glXAquaCreateVisualConfigs(int *numConfigsPtr, int screenNumber) {
- int numConfigs = 0;
- __GLXconfig *visualConfigs, *c;
- struct glCapabilities caps;
- struct glCapabilitiesConfig *conf;
- int stereo, depth, aux, buffers, stencil, accum, color, msample;
-
- if(getGlCapabilities(&caps)) {
- ErrorF("error from getGlCapabilities()!\n");
- return NULL;
- }
-
- /*
- conf->stereo is 0 or 1, but we need at least 1 iteration of the loop,
- so we treat a true conf->stereo as 2.
-
- The depth size is 0 or 24. Thus we do 2 iterations for that.
-
- conf->aux_buffers (when available/non-zero) result in 2 iterations instead of 1.
-
- conf->buffers indicates whether we have single or double buffering.
-
- conf->total_stencil_bit_depths
-
- conf->total_color_buffers indicates the RGB/RGBA color depths.
-
- conf->total_accum_buffers iterations for accum (with at least 1 if equal to 0)
-
- conf->total_depth_buffer_depths
-
- conf->multisample_buffers iterations (with at least 1 if equal to 0). We add 1
- for the 0 multisampling config.
-
- */
-
- assert(NULL != caps.configurations);
-
- numConfigs = 0;
-
- for(conf = caps.configurations; conf; conf = conf->next) {
- if(conf->total_color_buffers <= 0)
- continue;
-
- numConfigs += (conf->stereo ? 2 : 1)
- * (conf->aux_buffers ? 2 : 1)
- * conf->buffers
- * ((conf->total_stencil_bit_depths > 0) ? conf->total_stencil_bit_depths : 1)
- * conf->total_color_buffers
- * ((conf->total_accum_buffers > 0) ? conf->total_accum_buffers : 1)
- * conf->total_depth_buffer_depths
- * (conf->multisample_buffers + 1);
- }
-
- if(numConfigsPtr)
- *numConfigsPtr = numConfigs;
-
- visualConfigs = xcalloc(sizeof(*visualConfigs), numConfigs);
-
- if(NULL == visualConfigs) {
- ErrorF("xcalloc failure when allocating visualConfigs\n");
- freeGlCapabilities(&caps);
- return NULL;
- }
-
- c = visualConfigs; /* current buffer */
- for(conf = caps.configurations; conf; conf = conf->next) {
- for(stereo = 0; stereo < (conf->stereo ? 2 : 1); ++stereo) {
- for(aux = 0; aux < (conf->aux_buffers ? 2 : 1); ++aux) {
- for(buffers = 0; buffers < conf->buffers; ++buffers) {
- for(stencil = 0; stencil < ((conf->total_stencil_bit_depths > 0) ?
- conf->total_stencil_bit_depths : 1); ++stencil) {
- for(color = 0; color < conf->total_color_buffers; ++color) {
- for(accum = 0; accum < ((conf->total_accum_buffers > 0) ?
- conf->total_accum_buffers : 1); ++accum) {
- for(depth = 0; depth < conf->total_depth_buffer_depths; ++depth) {
- for(msample = 0; msample < (conf->multisample_buffers + 1); ++msample) {
-
- // Global
- c->visualID = -1;
- c->visualType = GLX_TRUE_COLOR;
- c->next = c + 1;
-
- c->screen = screenNumber;
-
- c->level = 0;
- c->indexBits = 0;
- c->pixmapMode = 0; // TODO: What should this be?
-
- if(conf->accelerated) {
- c->visualRating = GLX_NONE;
- } else {
- c->visualRating = GLX_SLOW_VISUAL_EXT;
- }
-
- c->transparentPixel = GLX_NONE;
- c->transparentRed = GLX_NONE;
- c->transparentGreen = GLX_NONE;
- c->transparentBlue = GLX_NONE;
- c->transparentAlpha = GLX_NONE;
- c->transparentIndex = GLX_NONE;
-
- c->visualSelectGroup = 0;
-
- c->swapMethod = GLX_SWAP_UNDEFINED_OML;
-
- // Stereo
- c->stereoMode = stereo ? TRUE : FALSE;
-
- // Aux buffers
- c->numAuxBuffers = aux ? conf->aux_buffers : 0;
-
- // Double Buffered
- c->doubleBufferMode = buffers ? TRUE : FALSE;
-
- // Stencil Buffer
- if(conf->total_stencil_bit_depths > 0) {
- c->stencilBits = conf->stencil_bit_depths[stencil];
- } else {
- c->stencilBits = 0;
- }
-
- // Color
- if(GLCAPS_COLOR_BUF_INVALID_VALUE != conf->color_buffers[color].a) {
- c->alphaBits = conf->color_buffers[color].a;
- } else {
- c->alphaBits = 0;
- }
- c->redBits = conf->color_buffers[color].r;
- c->greenBits = conf->color_buffers[color].g;
- c->blueBits = conf->color_buffers[color].b;
-
- c->rgbBits = c->alphaBits + c->redBits + c->greenBits + c->blueBits;
-
- c->alphaMask = AM_ARGB(c->alphaBits, c->redBits, c->greenBits, c->blueBits);
- c->redMask = RM_ARGB(c->alphaBits, c->redBits, c->greenBits, c->blueBits);
- c->greenMask = GM_ARGB(c->alphaBits, c->redBits, c->greenBits, c->blueBits);
- c->blueMask = BM_ARGB(c->alphaBits, c->redBits, c->greenBits, c->blueBits);
-
- // Accumulation Buffers
- if(conf->total_accum_buffers > 0) {
- c->accumRedBits = conf->accum_buffers[accum].r;
- c->accumGreenBits = conf->accum_buffers[accum].g;
- c->accumBlueBits = conf->accum_buffers[accum].b;
- if(GLCAPS_COLOR_BUF_INVALID_VALUE != conf->accum_buffers[accum].a) {
- c->accumAlphaBits = conf->accum_buffers[accum].a;
- } else {
- c->accumAlphaBits = 0;
- }
- } else {
- c->accumRedBits = 0;
- c->accumGreenBits = 0;
- c->accumBlueBits = 0;
- c->accumAlphaBits = 0;
- }
-
- // Depth
- c->depthBits = conf->depth_buffers[depth];
-
- // MultiSample
- if(msample > 0) {
- c->samples = conf->multisample_samples;
- c->sampleBuffers = conf->multisample_buffers;
- } else {
- c->samples = 0;
- c->sampleBuffers = 0;
- }
-
- /*
- * The Apple libGL supports GLXPixmaps and
- * GLXPbuffers in direct mode.
- */
- /* SGIX_fbconfig / GLX 1.3 */
- c->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT;
- c->renderType = GLX_RGBA_BIT;
- c->xRenderable = GL_TRUE;
- c->fbconfigID = -1;
-
- /* SGIX_pbuffer / GLX 1.3 */
-
- /*
- * The CGL layer provides a way of retrieving
- * the maximum pbuffer width/height, but only
- * if we create a context and call glGetIntegerv.
- *
- * The following values are from a test program
- * that does so.
- */
- c->maxPbufferWidth = 8192;
- c->maxPbufferHeight = 8192;
- c->maxPbufferPixels = /*Do we need this?*/ 0;
- /*
- * There is no introspection for this sort of thing
- * with CGL. What should we do realistically?
- */
- c->optimalPbufferWidth = 0;
- c->optimalPbufferHeight = 0;
-
- /* EXT_texture_from_pixmap */
- c->bindToTextureRgb = 0;
- c->bindToTextureRgba = 0;
- c->bindToMipmapTexture = 0;
- c->bindToTextureTargets = 0;
- c->yInverted = 0;
-
- c = c->next;
- }
- }
- }
- }
- }
- }
- }
- }
- }
-
- (c-1)->next = NULL;
-
- if (c - visualConfigs != numConfigs) {
- FatalError("numConfigs calculation error in setVisualConfigs! numConfigs is %d i is %d\n", numConfigs, (int)(c - visualConfigs));
- }
-
- freeGlCapabilities(&caps);
- return visualConfigs;
-}
+/*
+ * Copyright (c) 2007, 2008 Apple Inc.
+ * Copyright (c) 2004 Torrey T. Lyons. All Rights Reserved.
+ * Copyright (c) 2002 Greg Parker. All Rights Reserved.
+ *
+ * Portions of this file are copied from Mesa's xf86glx.c,
+ * which contains the following copyright:
+ *
+ * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+ * 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 ABOVE LISTED COPYRIGHT HOLDER(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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "dri.h"
+
+#include <OpenGL/OpenGL.h>
+#include <OpenGL/gl.h>
+#include <OpenGL/glext.h>
+#include <OpenGL/CGLContext.h>
+
+#include <GL/glxproto.h>
+#include <windowstr.h>
+#include <resource.h>
+#include <GL/glxint.h>
+#include <GL/glxtokens.h>
+#include <scrnintstr.h>
+#include <glxserver.h>
+#include <glxscreens.h>
+#include <glxdrawable.h>
+#include <glxcontext.h>
+#include <glxext.h>
+#include <glxutil.h>
+#include <glxscreens.h>
+#include <GL/internal/glcore.h>
+
+#include "capabilities.h"
+#include "visualConfigs.h"
+#include "darwinfb.h"
+
+/* Based originally on code from indirect.c which was based on code from i830_dri.c. */
+__GLXconfig *__glXAquaCreateVisualConfigs(int *numConfigsPtr, int screenNumber) {
+ int numConfigs = 0;
+ __GLXconfig *visualConfigs, *c;
+ struct glCapabilities caps;
+ struct glCapabilitiesConfig *conf;
+ int stereo, depth, aux, buffers, stencil, accum, color, msample;
+
+ if(getGlCapabilities(&caps)) {
+ ErrorF("error from getGlCapabilities()!\n");
+ return NULL;
+ }
+
+ /*
+ conf->stereo is 0 or 1, but we need at least 1 iteration of the loop,
+ so we treat a true conf->stereo as 2.
+
+ The depth size is 0 or 24. Thus we do 2 iterations for that.
+
+ conf->aux_buffers (when available/non-zero) result in 2 iterations instead of 1.
+
+ conf->buffers indicates whether we have single or double buffering.
+
+ conf->total_stencil_bit_depths
+
+ conf->total_color_buffers indicates the RGB/RGBA color depths.
+
+ conf->total_accum_buffers iterations for accum (with at least 1 if equal to 0)
+
+ conf->total_depth_buffer_depths
+
+ conf->multisample_buffers iterations (with at least 1 if equal to 0). We add 1
+ for the 0 multisampling config.
+
+ */
+
+ assert(NULL != caps.configurations);
+
+ numConfigs = 0;
+
+ for(conf = caps.configurations; conf; conf = conf->next) {
+ if(conf->total_color_buffers <= 0)
+ continue;
+
+ numConfigs += (conf->stereo ? 2 : 1)
+ * (conf->aux_buffers ? 2 : 1)
+ * conf->buffers
+ * ((conf->total_stencil_bit_depths > 0) ? conf->total_stencil_bit_depths : 1)
+ * conf->total_color_buffers
+ * ((conf->total_accum_buffers > 0) ? conf->total_accum_buffers : 1)
+ * conf->total_depth_buffer_depths
+ * (conf->multisample_buffers + 1);
+ }
+
+ if(numConfigsPtr)
+ *numConfigsPtr = numConfigs;
+
+ visualConfigs = calloc(sizeof(*visualConfigs), numConfigs);
+
+ if(NULL == visualConfigs) {
+ ErrorF("xcalloc failure when allocating visualConfigs\n");
+ freeGlCapabilities(&caps);
+ return NULL;
+ }
+
+ c = visualConfigs; /* current buffer */
+ for(conf = caps.configurations; conf; conf = conf->next) {
+ for(stereo = 0; stereo < (conf->stereo ? 2 : 1); ++stereo) {
+ for(aux = 0; aux < (conf->aux_buffers ? 2 : 1); ++aux) {
+ for(buffers = 0; buffers < conf->buffers; ++buffers) {
+ for(stencil = 0; stencil < ((conf->total_stencil_bit_depths > 0) ?
+ conf->total_stencil_bit_depths : 1); ++stencil) {
+ for(color = 0; color < conf->total_color_buffers; ++color) {
+ for(accum = 0; accum < ((conf->total_accum_buffers > 0) ?
+ conf->total_accum_buffers : 1); ++accum) {
+ for(depth = 0; depth < conf->total_depth_buffer_depths; ++depth) {
+ for(msample = 0; msample < (conf->multisample_buffers + 1); ++msample) {
+
+ // Global
+ c->visualID = -1;
+ c->visualType = GLX_TRUE_COLOR;
+ c->next = c + 1;
+
+ c->screen = screenNumber;
+
+ c->level = 0;
+ c->indexBits = 0;
+ c->pixmapMode = 0; // TODO: What should this be?
+
+ if(conf->accelerated) {
+ c->visualRating = GLX_NONE;
+ } else {
+ c->visualRating = GLX_SLOW_VISUAL_EXT;
+ }
+
+ c->transparentPixel = GLX_NONE;
+ c->transparentRed = GLX_NONE;
+ c->transparentGreen = GLX_NONE;
+ c->transparentBlue = GLX_NONE;
+ c->transparentAlpha = GLX_NONE;
+ c->transparentIndex = GLX_NONE;
+
+ c->visualSelectGroup = 0;
+
+ c->swapMethod = GLX_SWAP_UNDEFINED_OML;
+
+ // Stereo
+ c->stereoMode = stereo ? TRUE : FALSE;
+
+ // Aux buffers
+ c->numAuxBuffers = aux ? conf->aux_buffers : 0;
+
+ // Double Buffered
+ c->doubleBufferMode = buffers ? TRUE : FALSE;
+
+ // Stencil Buffer
+ if(conf->total_stencil_bit_depths > 0) {
+ c->stencilBits = conf->stencil_bit_depths[stencil];
+ } else {
+ c->stencilBits = 0;
+ }
+
+ // Color
+ if(GLCAPS_COLOR_BUF_INVALID_VALUE != conf->color_buffers[color].a) {
+ c->alphaBits = conf->color_buffers[color].a;
+ } else {
+ c->alphaBits = 0;
+ }
+ c->redBits = conf->color_buffers[color].r;
+ c->greenBits = conf->color_buffers[color].g;
+ c->blueBits = conf->color_buffers[color].b;
+
+ c->rgbBits = c->alphaBits + c->redBits + c->greenBits + c->blueBits;
+
+ c->alphaMask = AM_ARGB(c->alphaBits, c->redBits, c->greenBits, c->blueBits);
+ c->redMask = RM_ARGB(c->alphaBits, c->redBits, c->greenBits, c->blueBits);
+ c->greenMask = GM_ARGB(c->alphaBits, c->redBits, c->greenBits, c->blueBits);
+ c->blueMask = BM_ARGB(c->alphaBits, c->redBits, c->greenBits, c->blueBits);
+
+ // Accumulation Buffers
+ if(conf->total_accum_buffers > 0) {
+ c->accumRedBits = conf->accum_buffers[accum].r;
+ c->accumGreenBits = conf->accum_buffers[accum].g;
+ c->accumBlueBits = conf->accum_buffers[accum].b;
+ if(GLCAPS_COLOR_BUF_INVALID_VALUE != conf->accum_buffers[accum].a) {
+ c->accumAlphaBits = conf->accum_buffers[accum].a;
+ } else {
+ c->accumAlphaBits = 0;
+ }
+ } else {
+ c->accumRedBits = 0;
+ c->accumGreenBits = 0;
+ c->accumBlueBits = 0;
+ c->accumAlphaBits = 0;
+ }
+
+ // Depth
+ c->depthBits = conf->depth_buffers[depth];
+
+ // MultiSample
+ if(msample > 0) {
+ c->samples = conf->multisample_samples;
+ c->sampleBuffers = conf->multisample_buffers;
+ } else {
+ c->samples = 0;
+ c->sampleBuffers = 0;
+ }
+
+ /*
+ * The Apple libGL supports GLXPixmaps and
+ * GLXPbuffers in direct mode.
+ */
+ /* SGIX_fbconfig / GLX 1.3 */
+ c->drawableType = GLX_WINDOW_BIT | GLX_PIXMAP_BIT | GLX_PBUFFER_BIT;
+ c->renderType = GLX_RGBA_BIT;
+ c->xRenderable = GL_TRUE;
+ c->fbconfigID = -1;
+
+ /* SGIX_pbuffer / GLX 1.3 */
+
+ /*
+ * The CGL layer provides a way of retrieving
+ * the maximum pbuffer width/height, but only
+ * if we create a context and call glGetIntegerv.
+ *
+ * The following values are from a test program
+ * that does so.
+ */
+ c->maxPbufferWidth = 8192;
+ c->maxPbufferHeight = 8192;
+ c->maxPbufferPixels = /*Do we need this?*/ 0;
+ /*
+ * There is no introspection for this sort of thing
+ * with CGL. What should we do realistically?
+ */
+ c->optimalPbufferWidth = 0;
+ c->optimalPbufferHeight = 0;
+
+ /* EXT_texture_from_pixmap */
+ c->bindToTextureRgb = 0;
+ c->bindToTextureRgba = 0;
+ c->bindToMipmapTexture = 0;
+ c->bindToTextureTargets = 0;
+ c->yInverted = 0;
+
+ c = c->next;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ (c-1)->next = NULL;
+
+ if (c - visualConfigs != numConfigs) {
+ FatalError("numConfigs calculation error in setVisualConfigs! numConfigs is %d i is %d\n", numConfigs, (int)(c - visualConfigs));
+ }
+
+ freeGlCapabilities(&caps);
+ return visualConfigs;
+}
diff --git a/xorg-server/hw/xquartz/applewm.c b/xorg-server/hw/xquartz/applewm.c
index 15c86de00..b0f811750 100644
--- a/xorg-server/hw/xquartz/applewm.c
+++ b/xorg-server/hw/xquartz/applewm.c
@@ -1,746 +1,746 @@
-/**************************************************************************
-
-Copyright (c) 2002-2007 Apple Inc. All Rights Reserved.
-Copyright (c) 2003 Torrey T. Lyons. 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, sub license, 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 (including the
-next paragraph) 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 NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-**************************************************************************/
-
-#include "sanitizedCarbon.h"
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "quartzCommon.h"
-
-#include "misc.h"
-#include "dixstruct.h"
-#include "globals.h"
-#include "extnsionst.h"
-#include "colormapst.h"
-#include "cursorstr.h"
-#include "scrnintstr.h"
-#include "windowstr.h"
-#include "servermd.h"
-#include "swaprep.h"
-#include "propertyst.h"
-#include <X11/Xatom.h>
-#include "darwin.h"
-#define _APPLEWM_SERVER_
-#include <X11/extensions/applewmproto.h>
-#include "applewmExt.h"
-#include "X11Application.h"
-#include "protocol-versions.h"
-
-#define DEFINE_ATOM_HELPER(func,atom_name) \
-static Atom func (void) { \
- static int generation; \
- static Atom atom; \
- if (generation != serverGeneration) { \
- generation = serverGeneration; \
- atom = MakeAtom (atom_name, strlen (atom_name), TRUE); \
- } \
- return atom; \
-}
-
-DEFINE_ATOM_HELPER(xa_native_screen_origin, "_NATIVE_SCREEN_ORIGIN")
-DEFINE_ATOM_HELPER (xa_apple_no_order_in, "_APPLE_NO_ORDER_IN")
-
-static AppleWMProcsPtr appleWMProcs;
-
-static int WMErrorBase;
-
-static DISPATCH_PROC(ProcAppleWMDispatch);
-static DISPATCH_PROC(SProcAppleWMDispatch);
-
-static unsigned char WMReqCode = 0;
-static int WMEventBase = 0;
-
-static RESTYPE ClientType, EventType; /* resource types for event masks */
-static XID eventResource;
-
-/* Currently selected events */
-static unsigned int eventMask = 0;
-
-static int WMFreeClient (pointer data, XID id);
-static int WMFreeEvents (pointer data, XID id);
-static void SNotifyEvent(xAppleWMNotifyEvent *from, xAppleWMNotifyEvent *to);
-
-typedef struct _WMEvent *WMEventPtr;
-typedef struct _WMEvent {
- WMEventPtr next;
- ClientPtr client;
- XID clientResource;
- unsigned int mask;
-} WMEventRec;
-
-static inline BoxRec
-make_box (int x, int y, int w, int h)
-{
- BoxRec r;
- r.x1 = x;
- r.y1 = y;
- r.x2 = x + w;
- r.y2 = y + h;
- return r;
-}
-
-void
-AppleWMExtensionInit(
- AppleWMProcsPtr procsPtr)
-{
- ExtensionEntry* extEntry;
-
- ClientType = CreateNewResourceType(WMFreeClient, "WMClient");
- EventType = CreateNewResourceType(WMFreeEvents, "WMEvent");
- eventResource = FakeClientID(0);
-
- if (ClientType && EventType &&
- (extEntry = AddExtension(APPLEWMNAME,
- AppleWMNumberEvents,
- AppleWMNumberErrors,
- ProcAppleWMDispatch,
- SProcAppleWMDispatch,
- NULL,
- StandardMinorOpcode)))
- {
- WMReqCode = (unsigned char)extEntry->base;
- WMErrorBase = extEntry->errorBase;
- WMEventBase = extEntry->eventBase;
- EventSwapVector[WMEventBase] = (EventSwapPtr) SNotifyEvent;
- appleWMProcs = procsPtr;
- }
-}
-
-/* Updates the _NATIVE_SCREEN_ORIGIN property on the given root window. */
-void
-AppleWMSetScreenOrigin(
- WindowPtr pWin
-)
-{
- int32_t data[2];
-
- data[0] = (dixScreenOrigins[pWin->drawable.pScreen->myNum].x
- + darwinMainScreenX);
- data[1] = (dixScreenOrigins[pWin->drawable.pScreen->myNum].y
- + darwinMainScreenY);
-
- dixChangeWindowProperty(serverClient, pWin, xa_native_screen_origin(),
- XA_INTEGER, 32, PropModeReplace, 2, data, TRUE);
-}
-
-/* Window managers can set the _APPLE_NO_ORDER_IN property on windows
- that are being genie-restored from the Dock. We want them to
- be mapped but remain ordered-out until the animation
- completes (when the Dock will order them in). */
-Bool
-AppleWMDoReorderWindow(
- WindowPtr pWin
-)
-{
- Atom atom;
- PropertyPtr prop;
- int rc;
-
- atom = xa_apple_no_order_in();
- rc = dixLookupProperty(&prop, pWin, atom, serverClient, DixReadAccess);
-
- if(Success == rc && prop->type == atom)
- return 0;
-
- return 1;
-}
-
-
-static int
-ProcAppleWMQueryVersion(
- register ClientPtr client
-)
-{
- xAppleWMQueryVersionReply rep;
- register int n;
-
- REQUEST_SIZE_MATCH(xAppleWMQueryVersionReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.majorVersion = SERVER_APPLEWM_MAJOR_VERSION;
- rep.minorVersion = SERVER_APPLEWM_MINOR_VERSION;
- rep.patchVersion = SERVER_APPLEWM_PATCH_VERSION;
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- }
- WriteToClient(client, sizeof(xAppleWMQueryVersionReply), (char *)&rep);
- return (client->noClientException);
-}
-
-
-/* events */
-
-static inline void
-updateEventMask (WMEventPtr *pHead)
-{
- WMEventPtr pCur;
-
- eventMask = 0;
- for (pCur = *pHead; pCur != NULL; pCur = pCur->next)
- eventMask |= pCur->mask;
-}
-
-/*ARGSUSED*/
-static int
-WMFreeClient (pointer data, XID id) {
- WMEventPtr pEvent;
- WMEventPtr *pHead, pCur, pPrev;
- int i;
-
- pEvent = (WMEventPtr) data;
- i = dixLookupResourceByType((pointer *)&pHead, eventResource, EventType, serverClient, DixReadAccess | DixWriteAccess | DixDestroyAccess);
- if (i == Success && pHead) {
- pPrev = 0;
- for (pCur = *pHead; pCur && pCur != pEvent; pCur=pCur->next)
- pPrev = pCur;
- if (pCur) {
- if (pPrev)
- pPrev->next = pEvent->next;
- else
- *pHead = pEvent->next;
- }
- updateEventMask (pHead);
- }
- xfree ((pointer) pEvent);
- return 1;
-}
-
-/*ARGSUSED*/
-static int
-WMFreeEvents (pointer data, XID id) {
- WMEventPtr *pHead, pCur, pNext;
-
- pHead = (WMEventPtr *) data;
- for (pCur = *pHead; pCur; pCur = pNext) {
- pNext = pCur->next;
- FreeResource (pCur->clientResource, ClientType);
- xfree ((pointer) pCur);
- }
- xfree ((pointer) pHead);
- eventMask = 0;
- return 1;
-}
-
-static int
-ProcAppleWMSelectInput (register ClientPtr client)
-{
- REQUEST(xAppleWMSelectInputReq);
- WMEventPtr pEvent, pNewEvent, *pHead;
- XID clientResource;
- int i;
-
- REQUEST_SIZE_MATCH (xAppleWMSelectInputReq);
- i = dixLookupResourceByType((pointer *)&pHead, eventResource, EventType, client, DixWriteAccess);
- if (stuff->mask != 0) {
- if (i == Success && pHead) {
- /* check for existing entry. */
- for (pEvent = *pHead; pEvent; pEvent = pEvent->next)
- {
- if (pEvent->client == client)
- {
- pEvent->mask = stuff->mask;
- updateEventMask (pHead);
- return Success;
- }
- }
- }
-
- /* build the entry */
- pNewEvent = (WMEventPtr) xalloc (sizeof (WMEventRec));
- if (!pNewEvent)
- return BadAlloc;
- pNewEvent->next = 0;
- pNewEvent->client = client;
- pNewEvent->mask = stuff->mask;
- /*
- * add a resource that will be deleted when
- * the client goes away
- */
- clientResource = FakeClientID (client->index);
- pNewEvent->clientResource = clientResource;
- if (!AddResource (clientResource, ClientType, (pointer)pNewEvent))
- return BadAlloc;
- /*
- * create a resource to contain a pointer to the list
- * of clients selecting input. This must be indirect as
- * the list may be arbitrarily rearranged which cannot be
- * done through the resource database.
- */
- if (i != Success || !pHead)
- {
- pHead = (WMEventPtr *) xalloc (sizeof (WMEventPtr));
- if (!pHead ||
- !AddResource (eventResource, EventType, (pointer)pHead))
- {
- FreeResource (clientResource, RT_NONE);
- return BadAlloc;
- }
- *pHead = 0;
- }
- pNewEvent->next = *pHead;
- *pHead = pNewEvent;
- updateEventMask (pHead);
- } else if (stuff->mask == 0) {
- /* delete the interest */
- if (i == Success && pHead) {
- pNewEvent = 0;
- for (pEvent = *pHead; pEvent; pEvent = pEvent->next) {
- if (pEvent->client == client)
- break;
- pNewEvent = pEvent;
- }
- if (pEvent) {
- FreeResource (pEvent->clientResource, ClientType);
- if (pNewEvent)
- pNewEvent->next = pEvent->next;
- else
- *pHead = pEvent->next;
- xfree (pEvent);
- updateEventMask (pHead);
- }
- }
- } else {
- client->errorValue = stuff->mask;
- return BadValue;
- }
- return Success;
-}
-
-/*
- * deliver the event
- */
-
-void
-AppleWMSendEvent (int type, unsigned int mask, int which, int arg) {
- WMEventPtr *pHead, pEvent;
- ClientPtr client;
- xAppleWMNotifyEvent se;
- int i;
-
- i = dixLookupResourceByType((pointer *)&pHead, eventResource, EventType, serverClient, DixReadAccess);
- if (i != Success || !pHead)
- return;
- for (pEvent = *pHead; pEvent; pEvent = pEvent->next) {
- client = pEvent->client;
- if ((pEvent->mask & mask) == 0
- || client == serverClient || client->clientGone)
- {
- continue;
- }
- se.type = type + WMEventBase;
- se.kind = which;
- se.arg = arg;
- se.sequenceNumber = client->sequence;
- se.time = currentTime.milliseconds;
- WriteEventsToClient (client, 1, (xEvent *) &se);
- }
-}
-
-/* Safe to call from any thread. */
-unsigned int
-AppleWMSelectedEvents (void)
-{
- return eventMask;
-}
-
-
-/* general utility functions */
-
-static int
-ProcAppleWMDisableUpdate(
- register ClientPtr client
-)
-{
- REQUEST_SIZE_MATCH(xAppleWMDisableUpdateReq);
-
- appleWMProcs->DisableUpdate();
-
- return (client->noClientException);
-}
-
-static int
-ProcAppleWMReenableUpdate(
- register ClientPtr client
-)
-{
- REQUEST_SIZE_MATCH(xAppleWMReenableUpdateReq);
-
- appleWMProcs->EnableUpdate();
-
- return (client->noClientException);
-}
-
-
-/* window functions */
-
-static int
-ProcAppleWMSetWindowMenu(
- register ClientPtr client
-)
-{
- const char *bytes, **items;
- char *shortcuts;
- int max_len, nitems, i, j;
- REQUEST(xAppleWMSetWindowMenuReq);
-
- REQUEST_AT_LEAST_SIZE(xAppleWMSetWindowMenuReq);
-
- nitems = stuff->nitems;
- items = xalloc (sizeof (char *) * nitems);
- shortcuts = xalloc (sizeof (char) * nitems);
-
- max_len = (stuff->length << 2) - sizeof(xAppleWMSetWindowMenuReq);
- bytes = (char *) &stuff[1];
-
- for (i = j = 0; i < max_len && j < nitems;)
- {
- shortcuts[j] = bytes[i++];
- items[j++] = bytes + i;
-
- while (i < max_len)
- {
- if (bytes[i++] == 0)
- break;
- }
- }
- X11ApplicationSetWindowMenu (nitems, items, shortcuts);
- free(items);
- free(shortcuts);
-
- return (client->noClientException);
-}
-
-static int
-ProcAppleWMSetWindowMenuCheck(
- register ClientPtr client
-)
-{
- REQUEST(xAppleWMSetWindowMenuCheckReq);
-
- REQUEST_SIZE_MATCH(xAppleWMSetWindowMenuCheckReq);
- X11ApplicationSetWindowMenuCheck(stuff->index);
- return (client->noClientException);
-}
-
-static int
-ProcAppleWMSetFrontProcess(
- register ClientPtr client
-)
-{
- REQUEST_SIZE_MATCH(xAppleWMSetFrontProcessReq);
-
- X11ApplicationSetFrontProcess();
- return (client->noClientException);
-}
-
-static int
-ProcAppleWMSetWindowLevel(register ClientPtr client)
-{
- REQUEST(xAppleWMSetWindowLevelReq);
- WindowPtr pWin;
- int err;
-
- REQUEST_SIZE_MATCH(xAppleWMSetWindowLevelReq);
-
- if (Success != dixLookupWindow(&pWin, stuff->window, client,
- DixReadAccess))
- return BadValue;
-
- if (stuff->level < 0 || stuff->level >= AppleWMNumWindowLevels) {
- return BadValue;
- }
-
- err = appleWMProcs->SetWindowLevel(pWin, stuff->level);
- if (err != Success) {
- return err;
- }
-
- return (client->noClientException);
-}
-
-static int
-ProcAppleWMSendPSN(register ClientPtr client)
-{
- REQUEST(xAppleWMSendPSNReq);
- int err;
-
- REQUEST_SIZE_MATCH(xAppleWMSendPSNReq);
-
- if(!appleWMProcs->SendPSN)
- return BadRequest;
-
- err = appleWMProcs->SendPSN(stuff->psn_hi, stuff->psn_lo);
- if (err != Success) {
- return err;
- }
-
- return (client->noClientException);
-}
-
-static int
-ProcAppleWMAttachTransient(register ClientPtr client)
-{
- WindowPtr pWinChild, pWinParent;
- REQUEST(xAppleWMAttachTransientReq);
- int err;
-
- REQUEST_SIZE_MATCH(xAppleWMAttachTransientReq);
-
- if(!appleWMProcs->AttachTransient)
- return BadRequest;
-
- if (Success != dixLookupWindow(&pWinChild, stuff->child, client, DixReadAccess))
- return BadValue;
-
- if(stuff->parent) {
- if(Success != dixLookupWindow(&pWinParent, stuff->parent, client, DixReadAccess))
- return BadValue;
- } else {
- pWinParent = NULL;
- }
-
- err = appleWMProcs->AttachTransient(pWinChild, pWinParent);
- if (err != Success) {
- return err;
- }
-
- return (client->noClientException);
-}
-
-static int
-ProcAppleWMSetCanQuit(
- register ClientPtr client
-)
-{
- REQUEST(xAppleWMSetCanQuitReq);
-
- REQUEST_SIZE_MATCH(xAppleWMSetCanQuitReq);
-
- X11ApplicationSetCanQuit(stuff->state);
- return (client->noClientException);
-}
-
-
-/* frame functions */
-
-static int
-ProcAppleWMFrameGetRect(
- register ClientPtr client
-)
-{
- xAppleWMFrameGetRectReply rep;
- BoxRec ir, or, rr;
- REQUEST(xAppleWMFrameGetRectReq);
-
- REQUEST_SIZE_MATCH(xAppleWMFrameGetRectReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- ir = make_box (stuff->ix, stuff->iy, stuff->iw, stuff->ih);
- or = make_box (stuff->ox, stuff->oy, stuff->ow, stuff->oh);
-
- if (appleWMProcs->FrameGetRect(stuff->frame_rect,
- stuff->frame_class,
- &or, &ir, &rr) != Success)
- {
- return BadValue;
- }
-
- rep.x = rr.x1;
- rep.y = rr.y1;
- rep.w = rr.x2 - rr.x1;
- rep.h = rr.y2 - rr.y1;
-
- WriteToClient(client, sizeof(xAppleWMFrameGetRectReply), (char *)&rep);
- return (client->noClientException);
-}
-
-static int
-ProcAppleWMFrameHitTest(
- register ClientPtr client
-)
-{
- xAppleWMFrameHitTestReply rep;
- BoxRec ir, or;
- int ret;
- REQUEST(xAppleWMFrameHitTestReq);
-
- REQUEST_SIZE_MATCH(xAppleWMFrameHitTestReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- ir = make_box (stuff->ix, stuff->iy, stuff->iw, stuff->ih);
- or = make_box (stuff->ox, stuff->oy, stuff->ow, stuff->oh);
-
- if (appleWMProcs->FrameHitTest(stuff->frame_class, stuff->px,
- stuff->py, &or, &ir, &ret) != Success)
- {
- return BadValue;
- }
-
- rep.ret = ret;
-
- WriteToClient(client, sizeof(xAppleWMFrameHitTestReply), (char *)&rep);
- return (client->noClientException);
-}
-
-static int
-ProcAppleWMFrameDraw(
- register ClientPtr client
-)
-{
- BoxRec ir, or;
- unsigned int title_length, title_max;
- unsigned char *title_bytes;
- REQUEST(xAppleWMFrameDrawReq);
- WindowPtr pWin;
-
- REQUEST_AT_LEAST_SIZE(xAppleWMFrameDrawReq);
-
- if (Success != dixLookupWindow(&pWin, stuff->window, client,
- DixReadAccess))
- return BadValue;
-
- ir = make_box (stuff->ix, stuff->iy, stuff->iw, stuff->ih);
- or = make_box (stuff->ox, stuff->oy, stuff->ow, stuff->oh);
-
- title_length = stuff->title_length;
- title_max = (stuff->length << 2) - sizeof(xAppleWMFrameDrawReq);
-
- if (title_max < title_length)
- return BadValue;
-
- title_bytes = (unsigned char *) &stuff[1];
-
- errno = appleWMProcs->FrameDraw(pWin, stuff->frame_class,
- stuff->frame_attr, &or, &ir,
- title_length, title_bytes);
- if (errno != Success) {
- return errno;
- }
-
- return (client->noClientException);
-}
-
-
-/* dispatch */
-
-static int
-ProcAppleWMDispatch (
- register ClientPtr client
-)
-{
- REQUEST(xReq);
-
- switch (stuff->data)
- {
- case X_AppleWMQueryVersion:
- return ProcAppleWMQueryVersion(client);
- }
-
- if (!LocalClient(client))
- return WMErrorBase + AppleWMClientNotLocal;
-
- switch (stuff->data)
- {
- case X_AppleWMSelectInput:
- return ProcAppleWMSelectInput(client);
- case X_AppleWMDisableUpdate:
- return ProcAppleWMDisableUpdate(client);
- case X_AppleWMReenableUpdate:
- return ProcAppleWMReenableUpdate(client);
- case X_AppleWMSetWindowMenu:
- return ProcAppleWMSetWindowMenu(client);
- case X_AppleWMSetWindowMenuCheck:
- return ProcAppleWMSetWindowMenuCheck(client);
- case X_AppleWMSetFrontProcess:
- return ProcAppleWMSetFrontProcess(client);
- case X_AppleWMSetWindowLevel:
- return ProcAppleWMSetWindowLevel(client);
- case X_AppleWMSetCanQuit:
- return ProcAppleWMSetCanQuit(client);
- case X_AppleWMFrameGetRect:
- return ProcAppleWMFrameGetRect(client);
- case X_AppleWMFrameHitTest:
- return ProcAppleWMFrameHitTest(client);
- case X_AppleWMFrameDraw:
- return ProcAppleWMFrameDraw(client);
- case X_AppleWMSendPSN:
- return ProcAppleWMSendPSN(client);
- case X_AppleWMAttachTransient:
- return ProcAppleWMAttachTransient(client);
- default:
- return BadRequest;
- }
-}
-
-static void
-SNotifyEvent(xAppleWMNotifyEvent *from, xAppleWMNotifyEvent *to) {
- to->type = from->type;
- to->kind = from->kind;
- cpswaps (from->sequenceNumber, to->sequenceNumber);
- cpswapl (from->time, to->time);
- cpswapl (from->arg, to->arg);
-}
-
-static int
-SProcAppleWMQueryVersion(
- register ClientPtr client
-)
-{
- register int n;
- REQUEST(xAppleWMQueryVersionReq);
- swaps(&stuff->length, n);
- return ProcAppleWMQueryVersion(client);
-}
-
-static int
-SProcAppleWMDispatch (
- register ClientPtr client
-)
-{
- REQUEST(xReq);
-
- /* It is bound to be non-local when there is byte swapping */
- if (!LocalClient(client))
- return WMErrorBase + AppleWMClientNotLocal;
-
- /* only local clients are allowed WM access */
- switch (stuff->data)
- {
- case X_AppleWMQueryVersion:
- return SProcAppleWMQueryVersion(client);
- default:
- return BadRequest;
- }
-}
+/**************************************************************************
+
+Copyright (c) 2002-2007 Apple Inc. All Rights Reserved.
+Copyright (c) 2003 Torrey T. Lyons. 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, sub license, 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 (including the
+next paragraph) 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 NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+**************************************************************************/
+
+#include "sanitizedCarbon.h"
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "quartzCommon.h"
+
+#include "misc.h"
+#include "dixstruct.h"
+#include "globals.h"
+#include "extnsionst.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "servermd.h"
+#include "swaprep.h"
+#include "propertyst.h"
+#include <X11/Xatom.h>
+#include "darwin.h"
+#define _APPLEWM_SERVER_
+#include <X11/extensions/applewmproto.h>
+#include "applewmExt.h"
+#include "X11Application.h"
+#include "protocol-versions.h"
+
+#define DEFINE_ATOM_HELPER(func,atom_name) \
+static Atom func (void) { \
+ static int generation; \
+ static Atom atom; \
+ if (generation != serverGeneration) { \
+ generation = serverGeneration; \
+ atom = MakeAtom (atom_name, strlen (atom_name), TRUE); \
+ } \
+ return atom; \
+}
+
+DEFINE_ATOM_HELPER(xa_native_screen_origin, "_NATIVE_SCREEN_ORIGIN")
+DEFINE_ATOM_HELPER (xa_apple_no_order_in, "_APPLE_NO_ORDER_IN")
+
+static AppleWMProcsPtr appleWMProcs;
+
+static int WMErrorBase;
+
+static DISPATCH_PROC(ProcAppleWMDispatch);
+static DISPATCH_PROC(SProcAppleWMDispatch);
+
+static unsigned char WMReqCode = 0;
+static int WMEventBase = 0;
+
+static RESTYPE ClientType, EventType; /* resource types for event masks */
+static XID eventResource;
+
+/* Currently selected events */
+static unsigned int eventMask = 0;
+
+static int WMFreeClient (pointer data, XID id);
+static int WMFreeEvents (pointer data, XID id);
+static void SNotifyEvent(xAppleWMNotifyEvent *from, xAppleWMNotifyEvent *to);
+
+typedef struct _WMEvent *WMEventPtr;
+typedef struct _WMEvent {
+ WMEventPtr next;
+ ClientPtr client;
+ XID clientResource;
+ unsigned int mask;
+} WMEventRec;
+
+static inline BoxRec
+make_box (int x, int y, int w, int h)
+{
+ BoxRec r;
+ r.x1 = x;
+ r.y1 = y;
+ r.x2 = x + w;
+ r.y2 = y + h;
+ return r;
+}
+
+void
+AppleWMExtensionInit(
+ AppleWMProcsPtr procsPtr)
+{
+ ExtensionEntry* extEntry;
+
+ ClientType = CreateNewResourceType(WMFreeClient, "WMClient");
+ EventType = CreateNewResourceType(WMFreeEvents, "WMEvent");
+ eventResource = FakeClientID(0);
+
+ if (ClientType && EventType &&
+ (extEntry = AddExtension(APPLEWMNAME,
+ AppleWMNumberEvents,
+ AppleWMNumberErrors,
+ ProcAppleWMDispatch,
+ SProcAppleWMDispatch,
+ NULL,
+ StandardMinorOpcode)))
+ {
+ WMReqCode = (unsigned char)extEntry->base;
+ WMErrorBase = extEntry->errorBase;
+ WMEventBase = extEntry->eventBase;
+ EventSwapVector[WMEventBase] = (EventSwapPtr) SNotifyEvent;
+ appleWMProcs = procsPtr;
+ }
+}
+
+/* Updates the _NATIVE_SCREEN_ORIGIN property on the given root window. */
+void
+AppleWMSetScreenOrigin(
+ WindowPtr pWin
+)
+{
+ int32_t data[2];
+
+ data[0] = (dixScreenOrigins[pWin->drawable.pScreen->myNum].x
+ + darwinMainScreenX);
+ data[1] = (dixScreenOrigins[pWin->drawable.pScreen->myNum].y
+ + darwinMainScreenY);
+
+ dixChangeWindowProperty(serverClient, pWin, xa_native_screen_origin(),
+ XA_INTEGER, 32, PropModeReplace, 2, data, TRUE);
+}
+
+/* Window managers can set the _APPLE_NO_ORDER_IN property on windows
+ that are being genie-restored from the Dock. We want them to
+ be mapped but remain ordered-out until the animation
+ completes (when the Dock will order them in). */
+Bool
+AppleWMDoReorderWindow(
+ WindowPtr pWin
+)
+{
+ Atom atom;
+ PropertyPtr prop;
+ int rc;
+
+ atom = xa_apple_no_order_in();
+ rc = dixLookupProperty(&prop, pWin, atom, serverClient, DixReadAccess);
+
+ if(Success == rc && prop->type == atom)
+ return 0;
+
+ return 1;
+}
+
+
+static int
+ProcAppleWMQueryVersion(
+ register ClientPtr client
+)
+{
+ xAppleWMQueryVersionReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH(xAppleWMQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = SERVER_APPLEWM_MAJOR_VERSION;
+ rep.minorVersion = SERVER_APPLEWM_MINOR_VERSION;
+ rep.patchVersion = SERVER_APPLEWM_PATCH_VERSION;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ }
+ WriteToClient(client, sizeof(xAppleWMQueryVersionReply), (char *)&rep);
+ return Success;
+}
+
+
+/* events */
+
+static inline void
+updateEventMask (WMEventPtr *pHead)
+{
+ WMEventPtr pCur;
+
+ eventMask = 0;
+ for (pCur = *pHead; pCur != NULL; pCur = pCur->next)
+ eventMask |= pCur->mask;
+}
+
+/*ARGSUSED*/
+static int
+WMFreeClient (pointer data, XID id) {
+ WMEventPtr pEvent;
+ WMEventPtr *pHead, pCur, pPrev;
+ int i;
+
+ pEvent = (WMEventPtr) data;
+ i = dixLookupResourceByType((pointer *)&pHead, eventResource, EventType, serverClient, DixReadAccess | DixWriteAccess | DixDestroyAccess);
+ if (i == Success && pHead) {
+ pPrev = 0;
+ for (pCur = *pHead; pCur && pCur != pEvent; pCur=pCur->next)
+ pPrev = pCur;
+ if (pCur) {
+ if (pPrev)
+ pPrev->next = pEvent->next;
+ else
+ *pHead = pEvent->next;
+ }
+ updateEventMask (pHead);
+ }
+ free((pointer) pEvent);
+ return 1;
+}
+
+/*ARGSUSED*/
+static int
+WMFreeEvents (pointer data, XID id) {
+ WMEventPtr *pHead, pCur, pNext;
+
+ pHead = (WMEventPtr *) data;
+ for (pCur = *pHead; pCur; pCur = pNext) {
+ pNext = pCur->next;
+ FreeResource (pCur->clientResource, ClientType);
+ free((pointer) pCur);
+ }
+ free((pointer) pHead);
+ eventMask = 0;
+ return 1;
+}
+
+static int
+ProcAppleWMSelectInput (register ClientPtr client)
+{
+ REQUEST(xAppleWMSelectInputReq);
+ WMEventPtr pEvent, pNewEvent, *pHead;
+ XID clientResource;
+ int i;
+
+ REQUEST_SIZE_MATCH (xAppleWMSelectInputReq);
+ i = dixLookupResourceByType((pointer *)&pHead, eventResource, EventType, client, DixWriteAccess);
+ if (stuff->mask != 0) {
+ if (i == Success && pHead) {
+ /* check for existing entry. */
+ for (pEvent = *pHead; pEvent; pEvent = pEvent->next)
+ {
+ if (pEvent->client == client)
+ {
+ pEvent->mask = stuff->mask;
+ updateEventMask (pHead);
+ return Success;
+ }
+ }
+ }
+
+ /* build the entry */
+ pNewEvent = (WMEventPtr) malloc(sizeof (WMEventRec));
+ if (!pNewEvent)
+ return BadAlloc;
+ pNewEvent->next = 0;
+ pNewEvent->client = client;
+ pNewEvent->mask = stuff->mask;
+ /*
+ * add a resource that will be deleted when
+ * the client goes away
+ */
+ clientResource = FakeClientID (client->index);
+ pNewEvent->clientResource = clientResource;
+ if (!AddResource (clientResource, ClientType, (pointer)pNewEvent))
+ return BadAlloc;
+ /*
+ * create a resource to contain a pointer to the list
+ * of clients selecting input. This must be indirect as
+ * the list may be arbitrarily rearranged which cannot be
+ * done through the resource database.
+ */
+ if (i != Success || !pHead)
+ {
+ pHead = (WMEventPtr *) malloc(sizeof (WMEventPtr));
+ if (!pHead ||
+ !AddResource (eventResource, EventType, (pointer)pHead))
+ {
+ FreeResource (clientResource, RT_NONE);
+ return BadAlloc;
+ }
+ *pHead = 0;
+ }
+ pNewEvent->next = *pHead;
+ *pHead = pNewEvent;
+ updateEventMask (pHead);
+ } else if (stuff->mask == 0) {
+ /* delete the interest */
+ if (i == Success && pHead) {
+ pNewEvent = 0;
+ for (pEvent = *pHead; pEvent; pEvent = pEvent->next) {
+ if (pEvent->client == client)
+ break;
+ pNewEvent = pEvent;
+ }
+ if (pEvent) {
+ FreeResource (pEvent->clientResource, ClientType);
+ if (pNewEvent)
+ pNewEvent->next = pEvent->next;
+ else
+ *pHead = pEvent->next;
+ free(pEvent);
+ updateEventMask (pHead);
+ }
+ }
+ } else {
+ client->errorValue = stuff->mask;
+ return BadValue;
+ }
+ return Success;
+}
+
+/*
+ * deliver the event
+ */
+
+void
+AppleWMSendEvent (int type, unsigned int mask, int which, int arg) {
+ WMEventPtr *pHead, pEvent;
+ ClientPtr client;
+ xAppleWMNotifyEvent se;
+ int i;
+
+ i = dixLookupResourceByType((pointer *)&pHead, eventResource, EventType, serverClient, DixReadAccess);
+ if (i != Success || !pHead)
+ return;
+ for (pEvent = *pHead; pEvent; pEvent = pEvent->next) {
+ client = pEvent->client;
+ if ((pEvent->mask & mask) == 0
+ || client == serverClient || client->clientGone)
+ {
+ continue;
+ }
+ se.type = type + WMEventBase;
+ se.kind = which;
+ se.arg = arg;
+ se.sequenceNumber = client->sequence;
+ se.time = currentTime.milliseconds;
+ WriteEventsToClient (client, 1, (xEvent *) &se);
+ }
+}
+
+/* Safe to call from any thread. */
+unsigned int
+AppleWMSelectedEvents (void)
+{
+ return eventMask;
+}
+
+
+/* general utility functions */
+
+static int
+ProcAppleWMDisableUpdate(
+ register ClientPtr client
+)
+{
+ REQUEST_SIZE_MATCH(xAppleWMDisableUpdateReq);
+
+ appleWMProcs->DisableUpdate();
+
+ return Success;
+}
+
+static int
+ProcAppleWMReenableUpdate(
+ register ClientPtr client
+)
+{
+ REQUEST_SIZE_MATCH(xAppleWMReenableUpdateReq);
+
+ appleWMProcs->EnableUpdate();
+
+ return Success;
+}
+
+
+/* window functions */
+
+static int
+ProcAppleWMSetWindowMenu(
+ register ClientPtr client
+)
+{
+ const char *bytes, **items;
+ char *shortcuts;
+ int max_len, nitems, i, j;
+ REQUEST(xAppleWMSetWindowMenuReq);
+
+ REQUEST_AT_LEAST_SIZE(xAppleWMSetWindowMenuReq);
+
+ nitems = stuff->nitems;
+ items = malloc(sizeof (char *) * nitems);
+ shortcuts = malloc(sizeof (char) * nitems);
+
+ max_len = (stuff->length << 2) - sizeof(xAppleWMSetWindowMenuReq);
+ bytes = (char *) &stuff[1];
+
+ for (i = j = 0; i < max_len && j < nitems;)
+ {
+ shortcuts[j] = bytes[i++];
+ items[j++] = bytes + i;
+
+ while (i < max_len)
+ {
+ if (bytes[i++] == 0)
+ break;
+ }
+ }
+ X11ApplicationSetWindowMenu (nitems, items, shortcuts);
+ free(items);
+ free(shortcuts);
+
+ return Success;
+}
+
+static int
+ProcAppleWMSetWindowMenuCheck(
+ register ClientPtr client
+)
+{
+ REQUEST(xAppleWMSetWindowMenuCheckReq);
+
+ REQUEST_SIZE_MATCH(xAppleWMSetWindowMenuCheckReq);
+ X11ApplicationSetWindowMenuCheck(stuff->index);
+ return Success;
+}
+
+static int
+ProcAppleWMSetFrontProcess(
+ register ClientPtr client
+)
+{
+ REQUEST_SIZE_MATCH(xAppleWMSetFrontProcessReq);
+
+ X11ApplicationSetFrontProcess();
+ return Success;
+}
+
+static int
+ProcAppleWMSetWindowLevel(register ClientPtr client)
+{
+ REQUEST(xAppleWMSetWindowLevelReq);
+ WindowPtr pWin;
+ int err;
+
+ REQUEST_SIZE_MATCH(xAppleWMSetWindowLevelReq);
+
+ if (Success != dixLookupWindow(&pWin, stuff->window, client,
+ DixReadAccess))
+ return BadValue;
+
+ if (stuff->level < 0 || stuff->level >= AppleWMNumWindowLevels) {
+ return BadValue;
+ }
+
+ err = appleWMProcs->SetWindowLevel(pWin, stuff->level);
+ if (err != Success) {
+ return err;
+ }
+
+ return Success;
+}
+
+static int
+ProcAppleWMSendPSN(register ClientPtr client)
+{
+ REQUEST(xAppleWMSendPSNReq);
+ int err;
+
+ REQUEST_SIZE_MATCH(xAppleWMSendPSNReq);
+
+ if(!appleWMProcs->SendPSN)
+ return BadRequest;
+
+ err = appleWMProcs->SendPSN(stuff->psn_hi, stuff->psn_lo);
+ if (err != Success) {
+ return err;
+ }
+
+ return Success;
+}
+
+static int
+ProcAppleWMAttachTransient(register ClientPtr client)
+{
+ WindowPtr pWinChild, pWinParent;
+ REQUEST(xAppleWMAttachTransientReq);
+ int err;
+
+ REQUEST_SIZE_MATCH(xAppleWMAttachTransientReq);
+
+ if(!appleWMProcs->AttachTransient)
+ return BadRequest;
+
+ if (Success != dixLookupWindow(&pWinChild, stuff->child, client, DixReadAccess))
+ return BadValue;
+
+ if(stuff->parent) {
+ if(Success != dixLookupWindow(&pWinParent, stuff->parent, client, DixReadAccess))
+ return BadValue;
+ } else {
+ pWinParent = NULL;
+ }
+
+ err = appleWMProcs->AttachTransient(pWinChild, pWinParent);
+ if (err != Success) {
+ return err;
+ }
+
+ return Success;
+}
+
+static int
+ProcAppleWMSetCanQuit(
+ register ClientPtr client
+)
+{
+ REQUEST(xAppleWMSetCanQuitReq);
+
+ REQUEST_SIZE_MATCH(xAppleWMSetCanQuitReq);
+
+ X11ApplicationSetCanQuit(stuff->state);
+ return Success;
+}
+
+
+/* frame functions */
+
+static int
+ProcAppleWMFrameGetRect(
+ register ClientPtr client
+)
+{
+ xAppleWMFrameGetRectReply rep;
+ BoxRec ir, or, rr;
+ REQUEST(xAppleWMFrameGetRectReq);
+
+ REQUEST_SIZE_MATCH(xAppleWMFrameGetRectReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ ir = make_box (stuff->ix, stuff->iy, stuff->iw, stuff->ih);
+ or = make_box (stuff->ox, stuff->oy, stuff->ow, stuff->oh);
+
+ if (appleWMProcs->FrameGetRect(stuff->frame_rect,
+ stuff->frame_class,
+ &or, &ir, &rr) != Success)
+ {
+ return BadValue;
+ }
+
+ rep.x = rr.x1;
+ rep.y = rr.y1;
+ rep.w = rr.x2 - rr.x1;
+ rep.h = rr.y2 - rr.y1;
+
+ WriteToClient(client, sizeof(xAppleWMFrameGetRectReply), (char *)&rep);
+ return Success;
+}
+
+static int
+ProcAppleWMFrameHitTest(
+ register ClientPtr client
+)
+{
+ xAppleWMFrameHitTestReply rep;
+ BoxRec ir, or;
+ int ret;
+ REQUEST(xAppleWMFrameHitTestReq);
+
+ REQUEST_SIZE_MATCH(xAppleWMFrameHitTestReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ ir = make_box (stuff->ix, stuff->iy, stuff->iw, stuff->ih);
+ or = make_box (stuff->ox, stuff->oy, stuff->ow, stuff->oh);
+
+ if (appleWMProcs->FrameHitTest(stuff->frame_class, stuff->px,
+ stuff->py, &or, &ir, &ret) != Success)
+ {
+ return BadValue;
+ }
+
+ rep.ret = ret;
+
+ WriteToClient(client, sizeof(xAppleWMFrameHitTestReply), (char *)&rep);
+ return Success;
+}
+
+static int
+ProcAppleWMFrameDraw(
+ register ClientPtr client
+)
+{
+ BoxRec ir, or;
+ unsigned int title_length, title_max;
+ unsigned char *title_bytes;
+ REQUEST(xAppleWMFrameDrawReq);
+ WindowPtr pWin;
+
+ REQUEST_AT_LEAST_SIZE(xAppleWMFrameDrawReq);
+
+ if (Success != dixLookupWindow(&pWin, stuff->window, client,
+ DixReadAccess))
+ return BadValue;
+
+ ir = make_box (stuff->ix, stuff->iy, stuff->iw, stuff->ih);
+ or = make_box (stuff->ox, stuff->oy, stuff->ow, stuff->oh);
+
+ title_length = stuff->title_length;
+ title_max = (stuff->length << 2) - sizeof(xAppleWMFrameDrawReq);
+
+ if (title_max < title_length)
+ return BadValue;
+
+ title_bytes = (unsigned char *) &stuff[1];
+
+ errno = appleWMProcs->FrameDraw(pWin, stuff->frame_class,
+ stuff->frame_attr, &or, &ir,
+ title_length, title_bytes);
+ if (errno != Success) {
+ return errno;
+ }
+
+ return Success;
+}
+
+
+/* dispatch */
+
+static int
+ProcAppleWMDispatch (
+ register ClientPtr client
+)
+{
+ REQUEST(xReq);
+
+ switch (stuff->data)
+ {
+ case X_AppleWMQueryVersion:
+ return ProcAppleWMQueryVersion(client);
+ }
+
+ if (!LocalClient(client))
+ return WMErrorBase + AppleWMClientNotLocal;
+
+ switch (stuff->data)
+ {
+ case X_AppleWMSelectInput:
+ return ProcAppleWMSelectInput(client);
+ case X_AppleWMDisableUpdate:
+ return ProcAppleWMDisableUpdate(client);
+ case X_AppleWMReenableUpdate:
+ return ProcAppleWMReenableUpdate(client);
+ case X_AppleWMSetWindowMenu:
+ return ProcAppleWMSetWindowMenu(client);
+ case X_AppleWMSetWindowMenuCheck:
+ return ProcAppleWMSetWindowMenuCheck(client);
+ case X_AppleWMSetFrontProcess:
+ return ProcAppleWMSetFrontProcess(client);
+ case X_AppleWMSetWindowLevel:
+ return ProcAppleWMSetWindowLevel(client);
+ case X_AppleWMSetCanQuit:
+ return ProcAppleWMSetCanQuit(client);
+ case X_AppleWMFrameGetRect:
+ return ProcAppleWMFrameGetRect(client);
+ case X_AppleWMFrameHitTest:
+ return ProcAppleWMFrameHitTest(client);
+ case X_AppleWMFrameDraw:
+ return ProcAppleWMFrameDraw(client);
+ case X_AppleWMSendPSN:
+ return ProcAppleWMSendPSN(client);
+ case X_AppleWMAttachTransient:
+ return ProcAppleWMAttachTransient(client);
+ default:
+ return BadRequest;
+ }
+}
+
+static void
+SNotifyEvent(xAppleWMNotifyEvent *from, xAppleWMNotifyEvent *to) {
+ to->type = from->type;
+ to->kind = from->kind;
+ cpswaps (from->sequenceNumber, to->sequenceNumber);
+ cpswapl (from->time, to->time);
+ cpswapl (from->arg, to->arg);
+}
+
+static int
+SProcAppleWMQueryVersion(
+ register ClientPtr client
+)
+{
+ register int n;
+ REQUEST(xAppleWMQueryVersionReq);
+ swaps(&stuff->length, n);
+ return ProcAppleWMQueryVersion(client);
+}
+
+static int
+SProcAppleWMDispatch (
+ register ClientPtr client
+)
+{
+ REQUEST(xReq);
+
+ /* It is bound to be non-local when there is byte swapping */
+ if (!LocalClient(client))
+ return WMErrorBase + AppleWMClientNotLocal;
+
+ /* only local clients are allowed WM access */
+ switch (stuff->data)
+ {
+ case X_AppleWMQueryVersion:
+ return SProcAppleWMQueryVersion(client);
+ default:
+ return BadRequest;
+ }
+}
diff --git a/xorg-server/hw/xquartz/darwin.c b/xorg-server/hw/xquartz/darwin.c
index 1fb158b26..ed9543eb2 100644
--- a/xorg-server/hw/xquartz/darwin.c
+++ b/xorg-server/hw/xquartz/darwin.c
@@ -1,908 +1,908 @@
-/**************************************************************
- *
- * Xquartz initialization code
- *
- * Copyright (c) 2007-2008 Apple Inc.
- * Copyright (c) 2001-2004 Torrey T. Lyons. 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 ABOVE LISTED COPYRIGHT HOLDER(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(s) of the above copyright
- * holders shall not be used in advertising or otherwise to promote the sale,
- * use or other dealings in this Software without prior written authorization.
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "os.h"
-#include "servermd.h"
-#include "inputstr.h"
-#include "scrnintstr.h"
-#include "mibstore.h" // mi backing store implementation
-#include "mipointer.h" // mi software cursor
-#include "micmap.h" // mi colormap code
-#include "fb.h" // fb framebuffer code
-#include "site.h"
-#include "globals.h"
-#include "dix.h"
-#include "xkbsrv.h"
-
-#include <X11/extensions/XI.h>
-#include <X11/extensions/XIproto.h>
-#include "exevents.h"
-#include "extinit.h"
-
-#include "xserver-properties.h"
-
-#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/syslimits.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#define HAS_UTSNAME 1
-#include <sys/utsname.h>
-
-#define NO_CFPLUGIN
-#include <IOKit/hidsystem/IOHIDLib.h>
-
-#ifdef MITSHM
-#include "shmint.h"
-#endif
-
-#include "darwin.h"
-#include "darwinEvents.h"
-#include "quartzKeyboard.h"
-#include "quartz.h"
-
-#ifdef ENABLE_DEBUG_LOG
-FILE *debug_log_fp = NULL;
-#endif
-
-/*
- * X server shared global variables
- */
-int darwinScreensFound = 0;
-static int darwinScreenKeyIndex;
-DevPrivateKey darwinScreenKey = &darwinScreenKeyIndex;
-io_connect_t darwinParamConnect = 0;
-int darwinEventReadFD = -1;
-int darwinEventWriteFD = -1;
-// int darwinMouseAccelChange = 1;
-int darwinFakeButtons = 0;
-
-// location of X11's (0,0) point in global screen coordinates
-int darwinMainScreenX = 0;
-int darwinMainScreenY = 0;
-
-// parameters read from the command line or user preferences
-int darwinDesiredDepth = -1;
-int darwinSyncKeymap = FALSE;
-
-// modifier masks for faking mouse buttons - ANY of these bits trigger it (not all)
-#ifdef NX_DEVICELCMDKEYMASK
-int darwinFakeMouse2Mask = NX_DEVICELALTKEYMASK | NX_DEVICERALTKEYMASK;
-int darwinFakeMouse3Mask = NX_DEVICELCMDKEYMASK | NX_DEVICERCMDKEYMASK;
-#else
-int darwinFakeMouse2Mask = NX_ALTERNATEMASK;
-int darwinFakeMouse3Mask = NX_COMMANDMASK;
-#endif
-
-// Modifier mask for overriding event delivery to appkit (might be useful to set this to rcommand for input menu
-unsigned int darwinAppKitModMask = 0; // Any of these bits
-
-// Modifier mask for items in the Window menu (0 and -1 cause shortcuts to be disabled)
-unsigned int windowItemModMask = NX_COMMANDMASK;
-
-// devices
-DeviceIntPtr darwinKeyboard = NULL;
-DeviceIntPtr darwinPointer = NULL;
-DeviceIntPtr darwinTabletCurrent = NULL;
-DeviceIntPtr darwinTabletStylus = NULL;
-DeviceIntPtr darwinTabletCursor = NULL;
-DeviceIntPtr darwinTabletEraser = NULL;
-
-// Common pixmap formats
-static PixmapFormatRec formats[] = {
- { 1, 1, BITMAP_SCANLINE_PAD },
- { 4, 8, BITMAP_SCANLINE_PAD },
- { 8, 8, BITMAP_SCANLINE_PAD },
- { 15, 16, BITMAP_SCANLINE_PAD },
- { 16, 16, BITMAP_SCANLINE_PAD },
- { 24, 32, BITMAP_SCANLINE_PAD },
- { 32, 32, BITMAP_SCANLINE_PAD }
-};
-const int NUMFORMATS = sizeof(formats)/sizeof(formats[0]);
-
-#ifndef OSNAME
-#define OSNAME " Darwin"
-#endif
-#ifndef OSVENDOR
-#define OSVENDOR ""
-#endif
-#ifndef PRE_RELEASE
-#define PRE_RELEASE XORG_VERSION_SNAP
-#endif
-#ifndef BUILD_DATE
-#define BUILD_DATE ""
-#endif
-#ifndef XORG_RELEASE
-#define XORG_RELEASE "?"
-#endif
-
-void
-DarwinPrintBanner(void)
-{
- // this should change depending on which specific server we are building
- ErrorF("Xquartz starting:\n");
- ErrorF("X.Org X Server %s\nBuild Date: %s\n", XSERVER_VERSION, BUILD_DATE );
-}
-
-
-/*
- * DarwinSaveScreen
- * X screensaver support. Not implemented.
- */
-static Bool DarwinSaveScreen(ScreenPtr pScreen, int on)
-{
- // FIXME
- if (on == SCREEN_SAVER_FORCER) {
- } else if (on == SCREEN_SAVER_ON) {
- } else {
- }
- return TRUE;
-}
-
-/*
- * DarwinScreenInit
- * This is a callback from dix during AddScreen() from InitOutput().
- * Initialize the screen and communicate information about it back to dix.
- */
-static Bool DarwinScreenInit(int index, ScreenPtr pScreen, int argc, char **argv) {
- int dpi;
- static int foundIndex = 0;
- Bool ret;
- DarwinFramebufferPtr dfb;
-
- // reset index of found screens for each server generation
- if (index == 0) {
- foundIndex = 0;
-
- // reset the visual list
- miClearVisualTypes();
- }
-
- // allocate space for private per screen storage
- dfb = xalloc(sizeof(DarwinFramebufferRec));
-
- // SCREEN_PRIV(pScreen) = dfb;
- dixSetPrivate(&pScreen->devPrivates, darwinScreenKey, dfb);
-
- // setup hardware/mode specific details
- ret = QuartzAddScreen(foundIndex, pScreen);
- foundIndex++;
- if (! ret)
- return FALSE;
-
- // setup a single visual appropriate for our pixel type
- if(!miSetVisualTypesAndMasks(dfb->depth, dfb->visuals, dfb->bitsPerRGB,
- dfb->preferredCVC, dfb->redMask,
- dfb->greenMask, dfb->blueMask)) {
- return FALSE;
- }
-
-// TODO: Make PseudoColor visuals not suck in TrueColor mode
-// if(dfb->depth > 8)
-// miSetVisualTypesAndMasks(8, PseudoColorMask, 8, PseudoColor, 0, 0, 0);
- if(dfb->depth > 15)
- miSetVisualTypesAndMasks(15, TrueColorMask, 5, TrueColor, RM_ARGB(0,5,5,5), GM_ARGB(0,5,5,5), BM_ARGB(0,5,5,5));
- if(dfb->depth > 24)
- miSetVisualTypesAndMasks(24, TrueColorMask, 8, TrueColor, RM_ARGB(0,8,8,8), GM_ARGB(0,8,8,8), BM_ARGB(0,8,8,8));
-
- miSetPixmapDepths();
-
- // machine independent screen init
- // setup _Screen structure in pScreen
- if (monitorResolution)
- dpi = monitorResolution;
- else
- dpi = 96;
-
- // initialize fb
- if (! fbScreenInit(pScreen,
- dfb->framebuffer, // pointer to screen bitmap
- dfb->width, dfb->height, // screen size in pixels
- dpi, dpi, // dots per inch
- dfb->pitch/(dfb->bitsPerPixel/8), // pixel width of framebuffer
- dfb->bitsPerPixel)) // bits per pixel for screen
- {
- return FALSE;
- }
-
- if (! fbPictureInit(pScreen, 0, 0)) {
- return FALSE;
- }
-
-#ifdef MITSHM
- ShmRegisterFbFuncs(pScreen);
-#endif
-
- // this must be initialized (why doesn't X have a default?)
- pScreen->SaveScreen = DarwinSaveScreen;
-
- // finish mode dependent screen setup including cursor support
- if (!QuartzSetupScreen(index, pScreen)) {
- return FALSE;
- }
-
- // create and install the default colormap and
- // set pScreen->blackPixel / pScreen->white
- if (!miCreateDefColormap( pScreen )) {
- return FALSE;
- }
-
- dixScreenOrigins[index].x = dfb->x;
- dixScreenOrigins[index].y = dfb->y;
-
- /* ErrorF("Screen %d added: %dx%d @ (%d,%d)\n",
- index, dfb->width, dfb->height, dfb->x, dfb->y); */
-
- return TRUE;
-}
-
-/*
- =============================================================================
-
- mouse and keyboard callbacks
-
- =============================================================================
-*/
-
-/*
- * DarwinMouseProc: Handle the initialization, etc. of a mouse
- */
-static int DarwinMouseProc(DeviceIntPtr pPointer, int what) {
-#define NBUTTONS 7
-#define NAXES 2
- // 7 buttons: left, right, middle, then four scroll wheel "buttons"
- CARD8 map[NBUTTONS + 1] = {0, 1, 2, 3, 4, 5, 6, 7};
- Atom btn_labels[NBUTTONS] = {0};
- Atom axes_labels[NAXES] = {0};
-
- switch (what) {
- case DEVICE_INIT:
- pPointer->public.on = FALSE;
-
- btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
- btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
- btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
- btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
- btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
- btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
- btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
-
- axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
- axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
-
-
- // Set button map.
- InitPointerDeviceStruct((DevicePtr)pPointer, map, NBUTTONS,
- btn_labels,
- (PtrCtrlProcPtr)NoopDDA,
- GetMotionHistorySize(), NAXES,
- axes_labels);
- pPointer->valuator->mode = Absolute; // Relative
- InitAbsoluteClassDeviceStruct(pPointer);
-// InitValuatorAxisStruct(pPointer, 0, 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1);
-// InitValuatorAxisStruct(pPointer, 1, 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1);
- break;
- case DEVICE_ON:
- pPointer->public.on = TRUE;
- AddEnabledDevice( darwinEventReadFD );
- return Success;
- case DEVICE_CLOSE:
- case DEVICE_OFF:
- pPointer->public.on = FALSE;
- RemoveEnabledDevice(darwinEventReadFD);
- return Success;
- }
-
- return Success;
-#undef NBUTTONS
-#undef NAXES
-}
-
-static int DarwinTabletProc(DeviceIntPtr pPointer, int what) {
-#define NBUTTONS 3
-#define NAXES 5
- CARD8 map[NBUTTONS + 1] = {0, 1, 2, 3};
- Atom btn_labels[NBUTTONS] = {0};
- Atom axes_labels[NAXES] = {0};
-
- switch (what) {
- case DEVICE_INIT:
- pPointer->public.on = FALSE;
-
- btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
- btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
- btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
-
- axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X);
- axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y);
- axes_labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_PRESSURE);
- axes_labels[3] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_TILT_X);
- axes_labels[4] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_TILT_Y);
-
- // Set button map.
- InitPointerDeviceStruct((DevicePtr)pPointer, map, NBUTTONS,
- btn_labels,
- (PtrCtrlProcPtr)NoopDDA,
- GetMotionHistorySize(), NAXES,
- axes_labels);
- pPointer->valuator->mode = Absolute; // Relative
- InitProximityClassDeviceStruct(pPointer);
- InitAbsoluteClassDeviceStruct(pPointer);
-
- InitValuatorAxisStruct(pPointer, 0, axes_labels[0], 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1);
- InitValuatorAxisStruct(pPointer, 1, axes_labels[1], 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1);
- InitValuatorAxisStruct(pPointer, 2, axes_labels[2], 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1);
- InitValuatorAxisStruct(pPointer, 3, axes_labels[3], -XQUARTZ_VALUATOR_LIMIT, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1);
- InitValuatorAxisStruct(pPointer, 4, axes_labels[4], -XQUARTZ_VALUATOR_LIMIT, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1);
-// pPointer->use = IsXExtensionDevice;
- break;
- case DEVICE_ON:
- pPointer->public.on = TRUE;
- AddEnabledDevice( darwinEventReadFD );
- return Success;
- case DEVICE_CLOSE:
- case DEVICE_OFF:
- pPointer->public.on = FALSE;
- RemoveEnabledDevice(darwinEventReadFD);
- return Success;
- }
- return Success;
-#undef NBUTTONS
-#undef NAXES
-}
-
-/*
- * DarwinKeybdProc
- * Callback from X
- */
-static int DarwinKeybdProc( DeviceIntPtr pDev, int onoff )
-{
- switch ( onoff ) {
- case DEVICE_INIT:
- DarwinKeyboardInit( pDev );
- break;
- case DEVICE_ON:
- pDev->public.on = TRUE;
- AddEnabledDevice( darwinEventReadFD );
- break;
- case DEVICE_OFF:
- pDev->public.on = FALSE;
- RemoveEnabledDevice( darwinEventReadFD );
- break;
- case DEVICE_CLOSE:
- break;
- }
-
- return Success;
-}
-
-/*
-===========================================================================
-
- Utility routines
-
-===========================================================================
-*/
-
-/*
- * DarwinParseModifierList
- * Parse a list of modifier names and return a corresponding modifier mask
- */
-int DarwinParseModifierList(const char *constmodifiers, int separatelr)
-{
- int result = 0;
-
- if (constmodifiers) {
- char *modifiers = strdup(constmodifiers);
- char *modifier;
- int nxkey;
- char *p = modifiers;
-
- while (p) {
- modifier = strsep(&p, " ,+&|/"); // allow lots of separators
- nxkey = DarwinModifierStringToNXMask(modifier, separatelr);
- if(nxkey)
- result |= nxkey;
- else
- ErrorF("fakebuttons: Unknown modifier \"%s\"\n", modifier);
- }
- free(modifiers);
- }
- return result;
-}
-
-/*
-===========================================================================
-
- Functions needed to link against device independent X
-
-===========================================================================
-*/
-
-/*
- * InitInput
- * Register the keyboard and mouse devices
- */
-void InitInput( int argc, char **argv )
-{
- XkbRMLVOSet rmlvo = { .rules = "base", .model = "empty", .layout = "empty",
- .variant = NULL, .options = NULL };
- /* We need to really have rules... or something... */
- XkbSetRulesDflts(&rmlvo);
-
- darwinKeyboard = AddInputDevice(serverClient, DarwinKeybdProc, TRUE);
- RegisterKeyboardDevice( darwinKeyboard );
- darwinKeyboard->name = strdup("keyboard");
-
- /* here's the snippet from the current gdk sources:
- if (!strcmp (tmp_name, "pointer"))
- gdkdev->info.source = GDK_SOURCE_MOUSE;
- else if (!strcmp (tmp_name, "wacom") ||
- !strcmp (tmp_name, "pen"))
- gdkdev->info.source = GDK_SOURCE_PEN;
- else if (!strcmp (tmp_name, "eraser"))
- gdkdev->info.source = GDK_SOURCE_ERASER;
- else if (!strcmp (tmp_name, "cursor"))
- gdkdev->info.source = GDK_SOURCE_CURSOR;
- else
- gdkdev->info.source = GDK_SOURCE_PEN;
- */
-
- darwinPointer = AddInputDevice(serverClient, DarwinMouseProc, TRUE);
- RegisterPointerDevice( darwinPointer );
- darwinPointer->name = strdup("pointer");
-
- darwinTabletStylus = AddInputDevice(serverClient, DarwinTabletProc, TRUE);
- RegisterPointerDevice( darwinTabletStylus );
- darwinTabletStylus->name = strdup("pen");
-
- darwinTabletCursor = AddInputDevice(serverClient, DarwinTabletProc, TRUE);
- RegisterPointerDevice( darwinTabletCursor );
- darwinTabletCursor->name = strdup("cursor");
-
- darwinTabletEraser = AddInputDevice(serverClient, DarwinTabletProc, TRUE);
- RegisterPointerDevice( darwinTabletEraser );
- darwinTabletEraser->name = strdup("eraser");
-
- darwinTabletCurrent = darwinTabletStylus;
-
- DarwinEQInit();
-
- QuartzInitInput(argc, argv);
-}
-
-
-/*
- * DarwinAdjustScreenOrigins
- * Shift all screens so the X11 (0, 0) coordinate is at the top
- * left of the global screen coordinates.
- *
- * Screens can be arranged so the top left isn't on any screen, so
- * instead use the top left of the leftmost screen as (0,0). This
- * may mean some screen space is in -y, but it's better that (0,0)
- * be onscreen, or else default xterms disappear. It's better that
- * -y be used than -x, because when popup menus are forced
- * "onscreen" by dumb window managers like twm, they'll shift the
- * menus down instead of left, which still looks funny but is an
- * easier target to hit.
- */
-void
-DarwinAdjustScreenOrigins(ScreenInfo *pScreenInfo)
-{
- int i, left, top;
-
- left = dixScreenOrigins[0].x;
- top = dixScreenOrigins[0].y;
-
- /* Find leftmost screen. If there's a tie, take the topmost of the two. */
- for (i = 1; i < pScreenInfo->numScreens; i++) {
- if (dixScreenOrigins[i].x < left ||
- (dixScreenOrigins[i].x == left && dixScreenOrigins[i].y < top))
- {
- left = dixScreenOrigins[i].x;
- top = dixScreenOrigins[i].y;
- }
- }
-
- darwinMainScreenX = left;
- darwinMainScreenY = top;
-
- DEBUG_LOG("top = %d, left=%d\n", top, left);
-
- /* Shift all screens so that there is a screen whose top left
- * is at X11 (0,0) and at global screen coordinate
- * (darwinMainScreenX, darwinMainScreenY).
- */
-
- if (darwinMainScreenX != 0 || darwinMainScreenY != 0) {
- for (i = 0; i < pScreenInfo->numScreens; i++) {
- dixScreenOrigins[i].x -= darwinMainScreenX;
- dixScreenOrigins[i].y -= darwinMainScreenY;
- DEBUG_LOG("Screen %d placed at X11 coordinate (%d,%d).\n",
- i, dixScreenOrigins[i].x, dixScreenOrigins[i].y);
- }
- }
-}
-
-
-/*
- * InitOutput
- * Initialize screenInfo for all actually accessible framebuffers.
- *
- * The display mode dependent code gets called three times. The mode
- * specific InitOutput routines are expected to discover the number
- * of potentially useful screens and cache routes to them internally.
- * Inside DarwinScreenInit are two other mode specific calls.
- * A mode specific AddScreen routine is called for each screen to
- * actually initialize the screen with the ScreenPtr structure.
- * After other screen setup has been done, a mode specific
- * SetupScreen function can be called to finalize screen setup.
- */
-void InitOutput( ScreenInfo *pScreenInfo, int argc, char **argv )
-{
- int i;
-
- pScreenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
- pScreenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
- pScreenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
- pScreenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
-
- // List how we want common pixmap formats to be padded
- pScreenInfo->numPixmapFormats = NUMFORMATS;
- for (i = 0; i < NUMFORMATS; i++)
- pScreenInfo->formats[i] = formats[i];
-
- // Discover screens and do mode specific initialization
- QuartzInitOutput(argc, argv);
-
- // Add screens
- for (i = 0; i < darwinScreensFound; i++) {
- AddScreen(DarwinScreenInit, argc, argv);
- }
-
- DarwinAdjustScreenOrigins(pScreenInfo);
-}
-
-
-/*
- * OsVendorFatalError
- */
-void OsVendorFatalError( void )
-{
- ErrorF( " OsVendorFatalError\n" );
-}
-
-
-/*
- * OsVendorInit
- * Initialization of Darwin OS support.
- */
-void OsVendorInit(void)
-{
- if (serverGeneration == 1) {
- DarwinPrintBanner();
-#ifdef ENABLE_DEBUG_LOG
- {
- char *home_dir=NULL, *log_file_path=NULL;
- home_dir = getenv("HOME");
- if (home_dir) asprintf(&log_file_path, "%s/%s", home_dir, DEBUG_LOG_NAME);
- if (log_file_path) {
- if (!access(log_file_path, F_OK)) {
- debug_log_fp = fopen(log_file_path, "a");
- if (debug_log_fp) ErrorF("Debug logging enabled to %s\n", log_file_path);
- }
- free(log_file_path);
- }
- }
-#endif
- }
-}
-
-
-/*
- * ddxProcessArgument
- * Process device-dependent command line args. Returns 0 if argument is
- * not device dependent, otherwise Count of number of elements of argv
- * that are part of a device dependent commandline option.
- */
-int ddxProcessArgument( int argc, char *argv[], int i )
-{
-// if ( !strcmp( argv[i], "-fullscreen" ) ) {
-// ErrorF( "Running full screen in parallel with Mac OS X Quartz window server.\n" );
-// return 1;
-// }
-
-// if ( !strcmp( argv[i], "-rootless" ) ) {
-// ErrorF( "Running rootless inside Mac OS X window server.\n" );
-// return 1;
-// }
-
- // This command line arg is passed when launched from the Aqua GUI.
- if ( !strncmp( argv[i], "-psn_", 5 ) ) {
- return 1;
- }
-
- if ( !strcmp( argv[i], "-fakebuttons" ) ) {
- darwinFakeButtons = TRUE;
- ErrorF( "Faking a three button mouse\n" );
- return 1;
- }
-
- if ( !strcmp( argv[i], "-nofakebuttons" ) ) {
- darwinFakeButtons = FALSE;
- ErrorF( "Not faking a three button mouse\n" );
- return 1;
- }
-
- if (!strcmp( argv[i], "-fakemouse2" ) ) {
- if ( i == argc-1 ) {
- FatalError( "-fakemouse2 must be followed by a modifer list\n" );
- }
- if (!strcasecmp(argv[i+1], "none") || !strcmp(argv[i+1], ""))
- darwinFakeMouse2Mask = 0;
- else
- darwinFakeMouse2Mask = DarwinParseModifierList(argv[i+1], 1);
- ErrorF("Modifier mask to fake mouse button 2 = 0x%x\n",
- darwinFakeMouse2Mask);
- return 2;
- }
-
- if (!strcmp( argv[i], "-fakemouse3" ) ) {
- if ( i == argc-1 ) {
- FatalError( "-fakemouse3 must be followed by a modifer list\n" );
- }
- if (!strcasecmp(argv[i+1], "none") || !strcmp(argv[i+1], ""))
- darwinFakeMouse3Mask = 0;
- else
- darwinFakeMouse3Mask = DarwinParseModifierList(argv[i+1], 1);
- ErrorF("Modifier mask to fake mouse button 3 = 0x%x\n",
- darwinFakeMouse3Mask);
- return 2;
- }
-
- if ( !strcmp( argv[i], "+synckeymap" ) ) {
- darwinSyncKeymap = TRUE;
- return 1;
- }
-
- if ( !strcmp( argv[i], "-synckeymap" ) ) {
- darwinSyncKeymap = FALSE;
- return 1;
- }
-
- if ( !strcmp( argv[i], "-depth" ) ) {
- if ( i == argc-1 ) {
- FatalError( "-depth must be followed by a number\n" );
- }
- darwinDesiredDepth = atoi( argv[i+1] );
- if(darwinDesiredDepth != -1 &&
- darwinDesiredDepth != 8 &&
- darwinDesiredDepth != 15 &&
- darwinDesiredDepth != 24) {
- FatalError( "Unsupported pixel depth. Use 8, 15, or 24 bits\n" );
- }
-
- ErrorF( "Attempting to use pixel depth of %i\n", darwinDesiredDepth );
- return 2;
- }
-
- if (!strcmp( argv[i], "-showconfig" ) || !strcmp( argv[i], "-version" )) {
- DarwinPrintBanner();
- exit(0);
- }
-
- return 0;
-}
-
-
-/*
- * ddxUseMsg --
- * Print out correct use of device dependent commandline options.
- * Maybe the user now knows what really to do ...
- */
-void ddxUseMsg( void )
-{
- ErrorF("\n");
- ErrorF("\n");
- ErrorF("Device Dependent Usage:\n");
- ErrorF("\n");
- ErrorF("-depth <8,15,24> : use this bit depth.\n");
- ErrorF("-fakebuttons : fake a three button mouse with Command and Option keys.\n");
- ErrorF("-nofakebuttons : don't fake a three button mouse.\n");
- ErrorF("-fakemouse2 <modifiers> : fake middle mouse button with modifier keys.\n");
- ErrorF("-fakemouse3 <modifiers> : fake right mouse button with modifier keys.\n");
- ErrorF(" ex: -fakemouse2 \"option,shift\" = option-shift-click is middle button.\n");
- ErrorF("-version : show the server version.\n");
- ErrorF("\n");
-}
-
-
-/*
- * ddxGiveUp --
- * Device dependent cleanup. Called by dix before normal server death.
- */
-void ddxGiveUp( void )
-{
- ErrorF( "Quitting Xquartz\n" );
-}
-
-
-/*
- * AbortDDX --
- * DDX - specific abort routine. Called by AbortServer(). The attempt is
- * made to restore all original setting of the displays. Also all devices
- * are closed.
- */
-void AbortDDX( void )
-{
- ErrorF( " AbortDDX\n" );
- OsAbort();
-}
-
-#include "mivalidate.h" // for union _Validate used by windowstr.h
-#include "windowstr.h" // for struct _Window
-#include "scrnintstr.h" // for struct _Screen
-
-// This is copied from Xserver/hw/xfree86/common/xf86Helper.c.
-// Quartz mode uses this when switching in and out of Quartz.
-// Quartz or IOKit can use this when waking from sleep.
-// Copyright (c) 1997-1998 by The XFree86 Project, Inc.
-
-/*
- * xf86SetRootClip --
- * Enable or disable rendering to the screen by
- * setting the root clip list and revalidating
- * all of the windows
- */
-
-void
-xf86SetRootClip (ScreenPtr pScreen, int enable)
-{
- WindowPtr pWin = WindowTable[pScreen->myNum];
- WindowPtr pChild;
- Bool WasViewable = (Bool)(pWin->viewable);
- Bool anyMarked = TRUE;
- RegionPtr pOldClip = NULL, bsExposed;
- WindowPtr pLayerWin;
- BoxRec box;
-
- if (WasViewable)
- {
- for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
- {
- (void) (*pScreen->MarkOverlappedWindows)(pChild,
- pChild,
- &pLayerWin);
- }
- (*pScreen->MarkWindow) (pWin);
- anyMarked = TRUE;
- if (pWin->valdata)
- {
- if (HasBorder (pWin))
- {
- RegionPtr borderVisible;
-
- borderVisible = REGION_CREATE(pScreen, NullBox, 1);
- REGION_SUBTRACT(pScreen, borderVisible,
- &pWin->borderClip, &pWin->winSize);
- pWin->valdata->before.borderVisible = borderVisible;
- }
- pWin->valdata->before.resized = TRUE;
- }
- }
-
- /*
- * Use REGION_BREAK to avoid optimizations in ValidateTree
- * that assume the root borderClip can't change well, normally
- * it doesn't...)
- */
- if (enable)
- {
- box.x1 = 0;
- box.y1 = 0;
- box.x2 = pScreen->width;
- box.y2 = pScreen->height;
- REGION_RESET(pScreen, &pWin->borderClip, &box);
- REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
- }
- else
- {
- REGION_EMPTY(pScreen, &pWin->borderClip);
- REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
- }
-
- ResizeChildrenWinSize (pWin, 0, 0, 0, 0);
-
- if (WasViewable)
- {
- if (pWin->backStorage)
- {
- pOldClip = REGION_CREATE(pScreen, NullBox, 1);
- REGION_COPY(pScreen, pOldClip, &pWin->clipList);
- }
-
- if (pWin->firstChild)
- {
- anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin->firstChild,
- pWin->firstChild,
- (WindowPtr *)NULL);
- }
- else
- {
- (*pScreen->MarkWindow) (pWin);
- anyMarked = TRUE;
- }
-
-
- if (anyMarked)
- (*pScreen->ValidateTree)(pWin, NullWindow, VTOther);
- }
-
- if (pWin->backStorage &&
- ((pWin->backingStore == Always) || WasViewable))
- {
- if (!WasViewable)
- pOldClip = &pWin->clipList; /* a convenient empty region */
- bsExposed = (*pScreen->TranslateBackingStore)
- (pWin, 0, 0, pOldClip,
- pWin->drawable.x, pWin->drawable.y);
- if (WasViewable)
- REGION_DESTROY(pScreen, pOldClip);
- if (bsExposed)
- {
- RegionPtr valExposed = NullRegion;
-
- if (pWin->valdata)
- valExposed = &pWin->valdata->after.exposed;
- (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
- if (valExposed)
- REGION_EMPTY(pScreen, valExposed);
- REGION_DESTROY(pScreen, bsExposed);
- }
- }
- if (WasViewable)
- {
- if (anyMarked)
- (*pScreen->HandleExposures)(pWin);
- if (anyMarked && pScreen->PostValidateTree)
- (*pScreen->PostValidateTree)(pWin, NullWindow, VTOther);
- }
- if (pWin->realized)
- WindowsRestructured ();
- FlushAllOutput ();
-}
+/**************************************************************
+ *
+ * Xquartz initialization code
+ *
+ * Copyright (c) 2007-2008 Apple Inc.
+ * Copyright (c) 2001-2004 Torrey T. Lyons. 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 ABOVE LISTED COPYRIGHT HOLDER(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(s) of the above copyright
+ * holders shall not be used in advertising or otherwise to promote the sale,
+ * use or other dealings in this Software without prior written authorization.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "os.h"
+#include "servermd.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "mibstore.h" // mi backing store implementation
+#include "mipointer.h" // mi software cursor
+#include "micmap.h" // mi colormap code
+#include "fb.h" // fb framebuffer code
+#include "site.h"
+#include "globals.h"
+#include "dix.h"
+#include "xkbsrv.h"
+
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XIproto.h>
+#include "exevents.h"
+#include "extinit.h"
+
+#include "xserver-properties.h"
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/syslimits.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#define HAS_UTSNAME 1
+#include <sys/utsname.h>
+
+#define NO_CFPLUGIN
+#include <IOKit/hidsystem/IOHIDLib.h>
+
+#ifdef MITSHM
+#include "shmint.h"
+#endif
+
+#include "darwin.h"
+#include "darwinEvents.h"
+#include "quartzKeyboard.h"
+#include "quartz.h"
+
+#ifdef ENABLE_DEBUG_LOG
+FILE *debug_log_fp = NULL;
+#endif
+
+/*
+ * X server shared global variables
+ */
+int darwinScreensFound = 0;
+static int darwinScreenKeyIndex;
+DevPrivateKey darwinScreenKey = &darwinScreenKeyIndex;
+io_connect_t darwinParamConnect = 0;
+int darwinEventReadFD = -1;
+int darwinEventWriteFD = -1;
+// int darwinMouseAccelChange = 1;
+int darwinFakeButtons = 0;
+
+// location of X11's (0,0) point in global screen coordinates
+int darwinMainScreenX = 0;
+int darwinMainScreenY = 0;
+
+// parameters read from the command line or user preferences
+int darwinDesiredDepth = -1;
+int darwinSyncKeymap = FALSE;
+
+// modifier masks for faking mouse buttons - ANY of these bits trigger it (not all)
+#ifdef NX_DEVICELCMDKEYMASK
+int darwinFakeMouse2Mask = NX_DEVICELALTKEYMASK | NX_DEVICERALTKEYMASK;
+int darwinFakeMouse3Mask = NX_DEVICELCMDKEYMASK | NX_DEVICERCMDKEYMASK;
+#else
+int darwinFakeMouse2Mask = NX_ALTERNATEMASK;
+int darwinFakeMouse3Mask = NX_COMMANDMASK;
+#endif
+
+// Modifier mask for overriding event delivery to appkit (might be useful to set this to rcommand for input menu
+unsigned int darwinAppKitModMask = 0; // Any of these bits
+
+// Modifier mask for items in the Window menu (0 and -1 cause shortcuts to be disabled)
+unsigned int windowItemModMask = NX_COMMANDMASK;
+
+// devices
+DeviceIntPtr darwinKeyboard = NULL;
+DeviceIntPtr darwinPointer = NULL;
+DeviceIntPtr darwinTabletCurrent = NULL;
+DeviceIntPtr darwinTabletStylus = NULL;
+DeviceIntPtr darwinTabletCursor = NULL;
+DeviceIntPtr darwinTabletEraser = NULL;
+
+// Common pixmap formats
+static PixmapFormatRec formats[] = {
+ { 1, 1, BITMAP_SCANLINE_PAD },
+ { 4, 8, BITMAP_SCANLINE_PAD },
+ { 8, 8, BITMAP_SCANLINE_PAD },
+ { 15, 16, BITMAP_SCANLINE_PAD },
+ { 16, 16, BITMAP_SCANLINE_PAD },
+ { 24, 32, BITMAP_SCANLINE_PAD },
+ { 32, 32, BITMAP_SCANLINE_PAD }
+};
+const int NUMFORMATS = sizeof(formats)/sizeof(formats[0]);
+
+#ifndef OSNAME
+#define OSNAME " Darwin"
+#endif
+#ifndef OSVENDOR
+#define OSVENDOR ""
+#endif
+#ifndef PRE_RELEASE
+#define PRE_RELEASE XORG_VERSION_SNAP
+#endif
+#ifndef BUILD_DATE
+#define BUILD_DATE ""
+#endif
+#ifndef XORG_RELEASE
+#define XORG_RELEASE "?"
+#endif
+
+void
+DarwinPrintBanner(void)
+{
+ // this should change depending on which specific server we are building
+ ErrorF("Xquartz starting:\n");
+ ErrorF("X.Org X Server %s\nBuild Date: %s\n", XSERVER_VERSION, BUILD_DATE );
+}
+
+
+/*
+ * DarwinSaveScreen
+ * X screensaver support. Not implemented.
+ */
+static Bool DarwinSaveScreen(ScreenPtr pScreen, int on)
+{
+ // FIXME
+ if (on == SCREEN_SAVER_FORCER) {
+ } else if (on == SCREEN_SAVER_ON) {
+ } else {
+ }
+ return TRUE;
+}
+
+/*
+ * DarwinScreenInit
+ * This is a callback from dix during AddScreen() from InitOutput().
+ * Initialize the screen and communicate information about it back to dix.
+ */
+static Bool DarwinScreenInit(int index, ScreenPtr pScreen, int argc, char **argv) {
+ int dpi;
+ static int foundIndex = 0;
+ Bool ret;
+ DarwinFramebufferPtr dfb;
+
+ // reset index of found screens for each server generation
+ if (index == 0) {
+ foundIndex = 0;
+
+ // reset the visual list
+ miClearVisualTypes();
+ }
+
+ // allocate space for private per screen storage
+ dfb = malloc(sizeof(DarwinFramebufferRec));
+
+ // SCREEN_PRIV(pScreen) = dfb;
+ dixSetPrivate(&pScreen->devPrivates, darwinScreenKey, dfb);
+
+ // setup hardware/mode specific details
+ ret = QuartzAddScreen(foundIndex, pScreen);
+ foundIndex++;
+ if (! ret)
+ return FALSE;
+
+ // setup a single visual appropriate for our pixel type
+ if(!miSetVisualTypesAndMasks(dfb->depth, dfb->visuals, dfb->bitsPerRGB,
+ dfb->preferredCVC, dfb->redMask,
+ dfb->greenMask, dfb->blueMask)) {
+ return FALSE;
+ }
+
+// TODO: Make PseudoColor visuals not suck in TrueColor mode
+// if(dfb->depth > 8)
+// miSetVisualTypesAndMasks(8, PseudoColorMask, 8, PseudoColor, 0, 0, 0);
+ if(dfb->depth > 15)
+ miSetVisualTypesAndMasks(15, TrueColorMask, 5, TrueColor, RM_ARGB(0,5,5,5), GM_ARGB(0,5,5,5), BM_ARGB(0,5,5,5));
+ if(dfb->depth > 24)
+ miSetVisualTypesAndMasks(24, TrueColorMask, 8, TrueColor, RM_ARGB(0,8,8,8), GM_ARGB(0,8,8,8), BM_ARGB(0,8,8,8));
+
+ miSetPixmapDepths();
+
+ // machine independent screen init
+ // setup _Screen structure in pScreen
+ if (monitorResolution)
+ dpi = monitorResolution;
+ else
+ dpi = 96;
+
+ // initialize fb
+ if (! fbScreenInit(pScreen,
+ dfb->framebuffer, // pointer to screen bitmap
+ dfb->width, dfb->height, // screen size in pixels
+ dpi, dpi, // dots per inch
+ dfb->pitch/(dfb->bitsPerPixel/8), // pixel width of framebuffer
+ dfb->bitsPerPixel)) // bits per pixel for screen
+ {
+ return FALSE;
+ }
+
+ if (! fbPictureInit(pScreen, 0, 0)) {
+ return FALSE;
+ }
+
+#ifdef MITSHM
+ ShmRegisterFbFuncs(pScreen);
+#endif
+
+ // this must be initialized (why doesn't X have a default?)
+ pScreen->SaveScreen = DarwinSaveScreen;
+
+ // finish mode dependent screen setup including cursor support
+ if (!QuartzSetupScreen(index, pScreen)) {
+ return FALSE;
+ }
+
+ // create and install the default colormap and
+ // set pScreen->blackPixel / pScreen->white
+ if (!miCreateDefColormap( pScreen )) {
+ return FALSE;
+ }
+
+ dixScreenOrigins[index].x = dfb->x;
+ dixScreenOrigins[index].y = dfb->y;
+
+ /* ErrorF("Screen %d added: %dx%d @ (%d,%d)\n",
+ index, dfb->width, dfb->height, dfb->x, dfb->y); */
+
+ return TRUE;
+}
+
+/*
+ =============================================================================
+
+ mouse and keyboard callbacks
+
+ =============================================================================
+*/
+
+/*
+ * DarwinMouseProc: Handle the initialization, etc. of a mouse
+ */
+static int DarwinMouseProc(DeviceIntPtr pPointer, int what) {
+#define NBUTTONS 7
+#define NAXES 2
+ // 7 buttons: left, right, middle, then four scroll wheel "buttons"
+ CARD8 map[NBUTTONS + 1] = {0, 1, 2, 3, 4, 5, 6, 7};
+ Atom btn_labels[NBUTTONS] = {0};
+ Atom axes_labels[NAXES] = {0};
+
+ switch (what) {
+ case DEVICE_INIT:
+ pPointer->public.on = FALSE;
+
+ btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
+ btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
+ btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
+ btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
+ btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
+ btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
+ btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
+
+ axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
+ axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
+
+
+ // Set button map.
+ InitPointerDeviceStruct((DevicePtr)pPointer, map, NBUTTONS,
+ btn_labels,
+ (PtrCtrlProcPtr)NoopDDA,
+ GetMotionHistorySize(), NAXES,
+ axes_labels);
+ pPointer->valuator->mode = Absolute; // Relative
+ InitAbsoluteClassDeviceStruct(pPointer);
+// InitValuatorAxisStruct(pPointer, 0, 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1);
+// InitValuatorAxisStruct(pPointer, 1, 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1);
+ break;
+ case DEVICE_ON:
+ pPointer->public.on = TRUE;
+ AddEnabledDevice( darwinEventReadFD );
+ return Success;
+ case DEVICE_CLOSE:
+ case DEVICE_OFF:
+ pPointer->public.on = FALSE;
+ RemoveEnabledDevice(darwinEventReadFD);
+ return Success;
+ }
+
+ return Success;
+#undef NBUTTONS
+#undef NAXES
+}
+
+static int DarwinTabletProc(DeviceIntPtr pPointer, int what) {
+#define NBUTTONS 3
+#define NAXES 5
+ CARD8 map[NBUTTONS + 1] = {0, 1, 2, 3};
+ Atom btn_labels[NBUTTONS] = {0};
+ Atom axes_labels[NAXES] = {0};
+
+ switch (what) {
+ case DEVICE_INIT:
+ pPointer->public.on = FALSE;
+
+ btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
+ btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
+ btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
+
+ axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_X);
+ axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_Y);
+ axes_labels[2] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_PRESSURE);
+ axes_labels[3] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_TILT_X);
+ axes_labels[4] = XIGetKnownProperty(AXIS_LABEL_PROP_ABS_TILT_Y);
+
+ // Set button map.
+ InitPointerDeviceStruct((DevicePtr)pPointer, map, NBUTTONS,
+ btn_labels,
+ (PtrCtrlProcPtr)NoopDDA,
+ GetMotionHistorySize(), NAXES,
+ axes_labels);
+ pPointer->valuator->mode = Absolute; // Relative
+ InitProximityClassDeviceStruct(pPointer);
+ InitAbsoluteClassDeviceStruct(pPointer);
+
+ InitValuatorAxisStruct(pPointer, 0, axes_labels[0], 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1);
+ InitValuatorAxisStruct(pPointer, 1, axes_labels[1], 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1);
+ InitValuatorAxisStruct(pPointer, 2, axes_labels[2], 0, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1);
+ InitValuatorAxisStruct(pPointer, 3, axes_labels[3], -XQUARTZ_VALUATOR_LIMIT, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1);
+ InitValuatorAxisStruct(pPointer, 4, axes_labels[4], -XQUARTZ_VALUATOR_LIMIT, XQUARTZ_VALUATOR_LIMIT, 1, 0, 1);
+// pPointer->use = IsXExtensionDevice;
+ break;
+ case DEVICE_ON:
+ pPointer->public.on = TRUE;
+ AddEnabledDevice( darwinEventReadFD );
+ return Success;
+ case DEVICE_CLOSE:
+ case DEVICE_OFF:
+ pPointer->public.on = FALSE;
+ RemoveEnabledDevice(darwinEventReadFD);
+ return Success;
+ }
+ return Success;
+#undef NBUTTONS
+#undef NAXES
+}
+
+/*
+ * DarwinKeybdProc
+ * Callback from X
+ */
+static int DarwinKeybdProc( DeviceIntPtr pDev, int onoff )
+{
+ switch ( onoff ) {
+ case DEVICE_INIT:
+ DarwinKeyboardInit( pDev );
+ break;
+ case DEVICE_ON:
+ pDev->public.on = TRUE;
+ AddEnabledDevice( darwinEventReadFD );
+ break;
+ case DEVICE_OFF:
+ pDev->public.on = FALSE;
+ RemoveEnabledDevice( darwinEventReadFD );
+ break;
+ case DEVICE_CLOSE:
+ break;
+ }
+
+ return Success;
+}
+
+/*
+===========================================================================
+
+ Utility routines
+
+===========================================================================
+*/
+
+/*
+ * DarwinParseModifierList
+ * Parse a list of modifier names and return a corresponding modifier mask
+ */
+int DarwinParseModifierList(const char *constmodifiers, int separatelr)
+{
+ int result = 0;
+
+ if (constmodifiers) {
+ char *modifiers = strdup(constmodifiers);
+ char *modifier;
+ int nxkey;
+ char *p = modifiers;
+
+ while (p) {
+ modifier = strsep(&p, " ,+&|/"); // allow lots of separators
+ nxkey = DarwinModifierStringToNXMask(modifier, separatelr);
+ if(nxkey)
+ result |= nxkey;
+ else
+ ErrorF("fakebuttons: Unknown modifier \"%s\"\n", modifier);
+ }
+ free(modifiers);
+ }
+ return result;
+}
+
+/*
+===========================================================================
+
+ Functions needed to link against device independent X
+
+===========================================================================
+*/
+
+/*
+ * InitInput
+ * Register the keyboard and mouse devices
+ */
+void InitInput( int argc, char **argv )
+{
+ XkbRMLVOSet rmlvo = { .rules = "base", .model = "empty", .layout = "empty",
+ .variant = NULL, .options = NULL };
+ /* We need to really have rules... or something... */
+ XkbSetRulesDflts(&rmlvo);
+
+ darwinKeyboard = AddInputDevice(serverClient, DarwinKeybdProc, TRUE);
+ RegisterKeyboardDevice( darwinKeyboard );
+ darwinKeyboard->name = strdup("keyboard");
+
+ /* here's the snippet from the current gdk sources:
+ if (!strcmp (tmp_name, "pointer"))
+ gdkdev->info.source = GDK_SOURCE_MOUSE;
+ else if (!strcmp (tmp_name, "wacom") ||
+ !strcmp (tmp_name, "pen"))
+ gdkdev->info.source = GDK_SOURCE_PEN;
+ else if (!strcmp (tmp_name, "eraser"))
+ gdkdev->info.source = GDK_SOURCE_ERASER;
+ else if (!strcmp (tmp_name, "cursor"))
+ gdkdev->info.source = GDK_SOURCE_CURSOR;
+ else
+ gdkdev->info.source = GDK_SOURCE_PEN;
+ */
+
+ darwinPointer = AddInputDevice(serverClient, DarwinMouseProc, TRUE);
+ RegisterPointerDevice( darwinPointer );
+ darwinPointer->name = strdup("pointer");
+
+ darwinTabletStylus = AddInputDevice(serverClient, DarwinTabletProc, TRUE);
+ RegisterPointerDevice( darwinTabletStylus );
+ darwinTabletStylus->name = strdup("pen");
+
+ darwinTabletCursor = AddInputDevice(serverClient, DarwinTabletProc, TRUE);
+ RegisterPointerDevice( darwinTabletCursor );
+ darwinTabletCursor->name = strdup("cursor");
+
+ darwinTabletEraser = AddInputDevice(serverClient, DarwinTabletProc, TRUE);
+ RegisterPointerDevice( darwinTabletEraser );
+ darwinTabletEraser->name = strdup("eraser");
+
+ darwinTabletCurrent = darwinTabletStylus;
+
+ DarwinEQInit();
+
+ QuartzInitInput(argc, argv);
+}
+
+
+/*
+ * DarwinAdjustScreenOrigins
+ * Shift all screens so the X11 (0, 0) coordinate is at the top
+ * left of the global screen coordinates.
+ *
+ * Screens can be arranged so the top left isn't on any screen, so
+ * instead use the top left of the leftmost screen as (0,0). This
+ * may mean some screen space is in -y, but it's better that (0,0)
+ * be onscreen, or else default xterms disappear. It's better that
+ * -y be used than -x, because when popup menus are forced
+ * "onscreen" by dumb window managers like twm, they'll shift the
+ * menus down instead of left, which still looks funny but is an
+ * easier target to hit.
+ */
+void
+DarwinAdjustScreenOrigins(ScreenInfo *pScreenInfo)
+{
+ int i, left, top;
+
+ left = dixScreenOrigins[0].x;
+ top = dixScreenOrigins[0].y;
+
+ /* Find leftmost screen. If there's a tie, take the topmost of the two. */
+ for (i = 1; i < pScreenInfo->numScreens; i++) {
+ if (dixScreenOrigins[i].x < left ||
+ (dixScreenOrigins[i].x == left && dixScreenOrigins[i].y < top))
+ {
+ left = dixScreenOrigins[i].x;
+ top = dixScreenOrigins[i].y;
+ }
+ }
+
+ darwinMainScreenX = left;
+ darwinMainScreenY = top;
+
+ DEBUG_LOG("top = %d, left=%d\n", top, left);
+
+ /* Shift all screens so that there is a screen whose top left
+ * is at X11 (0,0) and at global screen coordinate
+ * (darwinMainScreenX, darwinMainScreenY).
+ */
+
+ if (darwinMainScreenX != 0 || darwinMainScreenY != 0) {
+ for (i = 0; i < pScreenInfo->numScreens; i++) {
+ dixScreenOrigins[i].x -= darwinMainScreenX;
+ dixScreenOrigins[i].y -= darwinMainScreenY;
+ DEBUG_LOG("Screen %d placed at X11 coordinate (%d,%d).\n",
+ i, dixScreenOrigins[i].x, dixScreenOrigins[i].y);
+ }
+ }
+}
+
+
+/*
+ * InitOutput
+ * Initialize screenInfo for all actually accessible framebuffers.
+ *
+ * The display mode dependent code gets called three times. The mode
+ * specific InitOutput routines are expected to discover the number
+ * of potentially useful screens and cache routes to them internally.
+ * Inside DarwinScreenInit are two other mode specific calls.
+ * A mode specific AddScreen routine is called for each screen to
+ * actually initialize the screen with the ScreenPtr structure.
+ * After other screen setup has been done, a mode specific
+ * SetupScreen function can be called to finalize screen setup.
+ */
+void InitOutput( ScreenInfo *pScreenInfo, int argc, char **argv )
+{
+ int i;
+
+ pScreenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
+ pScreenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
+ pScreenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
+ pScreenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
+
+ // List how we want common pixmap formats to be padded
+ pScreenInfo->numPixmapFormats = NUMFORMATS;
+ for (i = 0; i < NUMFORMATS; i++)
+ pScreenInfo->formats[i] = formats[i];
+
+ // Discover screens and do mode specific initialization
+ QuartzInitOutput(argc, argv);
+
+ // Add screens
+ for (i = 0; i < darwinScreensFound; i++) {
+ AddScreen(DarwinScreenInit, argc, argv);
+ }
+
+ DarwinAdjustScreenOrigins(pScreenInfo);
+}
+
+
+/*
+ * OsVendorFatalError
+ */
+void OsVendorFatalError( void )
+{
+ ErrorF( " OsVendorFatalError\n" );
+}
+
+
+/*
+ * OsVendorInit
+ * Initialization of Darwin OS support.
+ */
+void OsVendorInit(void)
+{
+ if (serverGeneration == 1) {
+ DarwinPrintBanner();
+#ifdef ENABLE_DEBUG_LOG
+ {
+ char *home_dir=NULL, *log_file_path=NULL;
+ home_dir = getenv("HOME");
+ if (home_dir) asprintf(&log_file_path, "%s/%s", home_dir, DEBUG_LOG_NAME);
+ if (log_file_path) {
+ if (!access(log_file_path, F_OK)) {
+ debug_log_fp = fopen(log_file_path, "a");
+ if (debug_log_fp) ErrorF("Debug logging enabled to %s\n", log_file_path);
+ }
+ free(log_file_path);
+ }
+ }
+#endif
+ }
+}
+
+
+/*
+ * ddxProcessArgument
+ * Process device-dependent command line args. Returns 0 if argument is
+ * not device dependent, otherwise Count of number of elements of argv
+ * that are part of a device dependent commandline option.
+ */
+int ddxProcessArgument( int argc, char *argv[], int i )
+{
+// if ( !strcmp( argv[i], "-fullscreen" ) ) {
+// ErrorF( "Running full screen in parallel with Mac OS X Quartz window server.\n" );
+// return 1;
+// }
+
+// if ( !strcmp( argv[i], "-rootless" ) ) {
+// ErrorF( "Running rootless inside Mac OS X window server.\n" );
+// return 1;
+// }
+
+ // This command line arg is passed when launched from the Aqua GUI.
+ if ( !strncmp( argv[i], "-psn_", 5 ) ) {
+ return 1;
+ }
+
+ if ( !strcmp( argv[i], "-fakebuttons" ) ) {
+ darwinFakeButtons = TRUE;
+ ErrorF( "Faking a three button mouse\n" );
+ return 1;
+ }
+
+ if ( !strcmp( argv[i], "-nofakebuttons" ) ) {
+ darwinFakeButtons = FALSE;
+ ErrorF( "Not faking a three button mouse\n" );
+ return 1;
+ }
+
+ if (!strcmp( argv[i], "-fakemouse2" ) ) {
+ if ( i == argc-1 ) {
+ FatalError( "-fakemouse2 must be followed by a modifer list\n" );
+ }
+ if (!strcasecmp(argv[i+1], "none") || !strcmp(argv[i+1], ""))
+ darwinFakeMouse2Mask = 0;
+ else
+ darwinFakeMouse2Mask = DarwinParseModifierList(argv[i+1], 1);
+ ErrorF("Modifier mask to fake mouse button 2 = 0x%x\n",
+ darwinFakeMouse2Mask);
+ return 2;
+ }
+
+ if (!strcmp( argv[i], "-fakemouse3" ) ) {
+ if ( i == argc-1 ) {
+ FatalError( "-fakemouse3 must be followed by a modifer list\n" );
+ }
+ if (!strcasecmp(argv[i+1], "none") || !strcmp(argv[i+1], ""))
+ darwinFakeMouse3Mask = 0;
+ else
+ darwinFakeMouse3Mask = DarwinParseModifierList(argv[i+1], 1);
+ ErrorF("Modifier mask to fake mouse button 3 = 0x%x\n",
+ darwinFakeMouse3Mask);
+ return 2;
+ }
+
+ if ( !strcmp( argv[i], "+synckeymap" ) ) {
+ darwinSyncKeymap = TRUE;
+ return 1;
+ }
+
+ if ( !strcmp( argv[i], "-synckeymap" ) ) {
+ darwinSyncKeymap = FALSE;
+ return 1;
+ }
+
+ if ( !strcmp( argv[i], "-depth" ) ) {
+ if ( i == argc-1 ) {
+ FatalError( "-depth must be followed by a number\n" );
+ }
+ darwinDesiredDepth = atoi( argv[i+1] );
+ if(darwinDesiredDepth != -1 &&
+ darwinDesiredDepth != 8 &&
+ darwinDesiredDepth != 15 &&
+ darwinDesiredDepth != 24) {
+ FatalError( "Unsupported pixel depth. Use 8, 15, or 24 bits\n" );
+ }
+
+ ErrorF( "Attempting to use pixel depth of %i\n", darwinDesiredDepth );
+ return 2;
+ }
+
+ if (!strcmp( argv[i], "-showconfig" ) || !strcmp( argv[i], "-version" )) {
+ DarwinPrintBanner();
+ exit(0);
+ }
+
+ return 0;
+}
+
+
+/*
+ * ddxUseMsg --
+ * Print out correct use of device dependent commandline options.
+ * Maybe the user now knows what really to do ...
+ */
+void ddxUseMsg( void )
+{
+ ErrorF("\n");
+ ErrorF("\n");
+ ErrorF("Device Dependent Usage:\n");
+ ErrorF("\n");
+ ErrorF("-depth <8,15,24> : use this bit depth.\n");
+ ErrorF("-fakebuttons : fake a three button mouse with Command and Option keys.\n");
+ ErrorF("-nofakebuttons : don't fake a three button mouse.\n");
+ ErrorF("-fakemouse2 <modifiers> : fake middle mouse button with modifier keys.\n");
+ ErrorF("-fakemouse3 <modifiers> : fake right mouse button with modifier keys.\n");
+ ErrorF(" ex: -fakemouse2 \"option,shift\" = option-shift-click is middle button.\n");
+ ErrorF("-version : show the server version.\n");
+ ErrorF("\n");
+}
+
+
+/*
+ * ddxGiveUp --
+ * Device dependent cleanup. Called by dix before normal server death.
+ */
+void ddxGiveUp( void )
+{
+ ErrorF( "Quitting Xquartz\n" );
+}
+
+
+/*
+ * AbortDDX --
+ * DDX - specific abort routine. Called by AbortServer(). The attempt is
+ * made to restore all original setting of the displays. Also all devices
+ * are closed.
+ */
+void AbortDDX( void )
+{
+ ErrorF( " AbortDDX\n" );
+ OsAbort();
+}
+
+#include "mivalidate.h" // for union _Validate used by windowstr.h
+#include "windowstr.h" // for struct _Window
+#include "scrnintstr.h" // for struct _Screen
+
+// This is copied from Xserver/hw/xfree86/common/xf86Helper.c.
+// Quartz mode uses this when switching in and out of Quartz.
+// Quartz or IOKit can use this when waking from sleep.
+// Copyright (c) 1997-1998 by The XFree86 Project, Inc.
+
+/*
+ * xf86SetRootClip --
+ * Enable or disable rendering to the screen by
+ * setting the root clip list and revalidating
+ * all of the windows
+ */
+
+void
+xf86SetRootClip (ScreenPtr pScreen, int enable)
+{
+ WindowPtr pWin = WindowTable[pScreen->myNum];
+ WindowPtr pChild;
+ Bool WasViewable = (Bool)(pWin->viewable);
+ Bool anyMarked = TRUE;
+ RegionPtr pOldClip = NULL, bsExposed;
+ WindowPtr pLayerWin;
+ BoxRec box;
+
+ if (WasViewable)
+ {
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+ {
+ (void) (*pScreen->MarkOverlappedWindows)(pChild,
+ pChild,
+ &pLayerWin);
+ }
+ (*pScreen->MarkWindow) (pWin);
+ anyMarked = TRUE;
+ if (pWin->valdata)
+ {
+ if (HasBorder (pWin))
+ {
+ RegionPtr borderVisible;
+
+ borderVisible = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_SUBTRACT(pScreen, borderVisible,
+ &pWin->borderClip, &pWin->winSize);
+ pWin->valdata->before.borderVisible = borderVisible;
+ }
+ pWin->valdata->before.resized = TRUE;
+ }
+ }
+
+ /*
+ * Use REGION_BREAK to avoid optimizations in ValidateTree
+ * that assume the root borderClip can't change well, normally
+ * it doesn't...)
+ */
+ if (enable)
+ {
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pScreen->width;
+ box.y2 = pScreen->height;
+ REGION_RESET(pScreen, &pWin->borderClip, &box);
+ REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
+ }
+ else
+ {
+ REGION_EMPTY(pScreen, &pWin->borderClip);
+ REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
+ }
+
+ ResizeChildrenWinSize (pWin, 0, 0, 0, 0);
+
+ if (WasViewable)
+ {
+ if (pWin->backStorage)
+ {
+ pOldClip = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_COPY(pScreen, pOldClip, &pWin->clipList);
+ }
+
+ if (pWin->firstChild)
+ {
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin->firstChild,
+ pWin->firstChild,
+ (WindowPtr *)NULL);
+ }
+ else
+ {
+ (*pScreen->MarkWindow) (pWin);
+ anyMarked = TRUE;
+ }
+
+
+ if (anyMarked)
+ (*pScreen->ValidateTree)(pWin, NullWindow, VTOther);
+ }
+
+ if (pWin->backStorage &&
+ ((pWin->backingStore == Always) || WasViewable))
+ {
+ if (!WasViewable)
+ pOldClip = &pWin->clipList; /* a convenient empty region */
+ bsExposed = (*pScreen->TranslateBackingStore)
+ (pWin, 0, 0, pOldClip,
+ pWin->drawable.x, pWin->drawable.y);
+ if (WasViewable)
+ REGION_DESTROY(pScreen, pOldClip);
+ if (bsExposed)
+ {
+ RegionPtr valExposed = NullRegion;
+
+ if (pWin->valdata)
+ valExposed = &pWin->valdata->after.exposed;
+ (*pScreen->WindowExposures) (pWin, valExposed, bsExposed);
+ if (valExposed)
+ REGION_EMPTY(pScreen, valExposed);
+ REGION_DESTROY(pScreen, bsExposed);
+ }
+ }
+ if (WasViewable)
+ {
+ if (anyMarked)
+ (*pScreen->HandleExposures)(pWin);
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pWin, NullWindow, VTOther);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+ FlushAllOutput ();
+}
diff --git a/xorg-server/hw/xquartz/pseudoramiX.c b/xorg-server/hw/xquartz/pseudoramiX.c
index 1de7af6dc..1a357528c 100644
--- a/xorg-server/hw/xquartz/pseudoramiX.c
+++ b/xorg-server/hw/xquartz/pseudoramiX.c
@@ -1,471 +1,471 @@
-/*
- * Minimal implementation of PanoramiX/Xinerama
- *
- * This is used in rootless mode where the underlying window server
- * already provides an abstracted view of multiple screens as one
- * large screen area.
- *
- * This code is largely based on panoramiX.c, which contains the
- * following copyright notice:
- */
-/*****************************************************************
-Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
-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.
-
-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
-DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
-BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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 Digital Equipment Corporation
-shall not be used in advertising or otherwise to promote the sale, use or other
-dealings in this Software without prior written authorization from Digital
-Equipment Corporation.
-******************************************************************/
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "darwin.h"
-#include "pseudoramiX.h"
-#include "extnsionst.h"
-#include "dixstruct.h"
-#include "window.h"
-#include <X11/extensions/panoramiXproto.h>
-#include "globals.h"
-
-Bool noPseudoramiXExtension = FALSE;
-
-extern int ProcPanoramiXQueryVersion (ClientPtr client);
-
-static void PseudoramiXResetProc(ExtensionEntry *extEntry);
-
-static int ProcPseudoramiXQueryVersion(ClientPtr client);
-static int ProcPseudoramiXGetState(ClientPtr client);
-static int ProcPseudoramiXGetScreenCount(ClientPtr client);
-static int ProcPseudoramiXGetScreenSize(ClientPtr client);
-static int ProcPseudoramiXIsActive(ClientPtr client);
-static int ProcPseudoramiXQueryScreens(ClientPtr client);
-static int ProcPseudoramiXDispatch(ClientPtr client);
-
-static int SProcPseudoramiXQueryVersion(ClientPtr client);
-static int SProcPseudoramiXGetState(ClientPtr client);
-static int SProcPseudoramiXGetScreenCount(ClientPtr client);
-static int SProcPseudoramiXGetScreenSize(ClientPtr client);
-static int SProcPseudoramiXIsActive(ClientPtr client);
-static int SProcPseudoramiXQueryScreens(ClientPtr client);
-static int SProcPseudoramiXDispatch(ClientPtr client);
-
-
-typedef struct {
- int x;
- int y;
- int w;
- int h;
-} PseudoramiXScreenRec;
-
-static PseudoramiXScreenRec *pseudoramiXScreens = NULL;
-static int pseudoramiXScreensAllocated = 0;
-static int pseudoramiXNumScreens = 0;
-static unsigned long pseudoramiXGeneration = 0;
-
-
-// Add a PseudoramiX screen.
-// The rest of the X server will know nothing about this screen.
-// Can be called before or after extension init.
-// Screens must be re-added once per generation.
-void
-PseudoramiXAddScreen(int x, int y, int w, int h)
-{
- PseudoramiXScreenRec *s;
-
- if (noPseudoramiXExtension) return;
-
- if (pseudoramiXNumScreens == pseudoramiXScreensAllocated) {
- pseudoramiXScreensAllocated += pseudoramiXScreensAllocated + 1;
- pseudoramiXScreens = xrealloc(pseudoramiXScreens,
- pseudoramiXScreensAllocated *
- sizeof(PseudoramiXScreenRec));
- }
-
- DEBUG_LOG("x: %d, y: %d, w: %d, h: %d\n", x, y, w, h);
-
- s = &pseudoramiXScreens[pseudoramiXNumScreens++];
- s->x = x;
- s->y = y;
- s->w = w;
- s->h = h;
-}
-
-
-// Initialize PseudoramiX.
-// Copied from PanoramiXExtensionInit
-void PseudoramiXExtensionInit(int argc, char *argv[])
-{
- Bool success = FALSE;
- ExtensionEntry *extEntry;
-
- if (noPseudoramiXExtension) return;
-
- TRACE();
-
- /* Even with only one screen we need to enable PseudoramiX to allow
- dynamic screen configuration changes. */
-#if 0
- if (pseudoramiXNumScreens == 1) {
- // Only one screen - disable Xinerama extension.
- noPseudoramiXExtension = TRUE;
- return;
- }
-#endif
-
- if (pseudoramiXGeneration != serverGeneration) {
- extEntry = AddExtension(PANORAMIX_PROTOCOL_NAME, 0, 0,
- ProcPseudoramiXDispatch,
- SProcPseudoramiXDispatch,
- PseudoramiXResetProc,
- StandardMinorOpcode);
- if (!extEntry) {
- ErrorF("PseudoramiXExtensionInit(): AddExtension failed\n");
- } else {
- pseudoramiXGeneration = serverGeneration;
- success = TRUE;
- }
- }
-
- if (!success) {
- ErrorF("%s Extension (PseudoramiX) failed to initialize\n",
- PANORAMIX_PROTOCOL_NAME);
- return;
- }
-}
-
-
-void PseudoramiXResetScreens(void)
-{
- TRACE();
-
- pseudoramiXNumScreens = 0;
-}
-
-
-static void PseudoramiXResetProc(ExtensionEntry *extEntry)
-{
- TRACE();
-
- PseudoramiXResetScreens();
-}
-
-
-// was PanoramiX
-static int ProcPseudoramiXQueryVersion(ClientPtr client)
-{
- TRACE();
-
- return ProcPanoramiXQueryVersion(client);
-}
-
-
-// was PanoramiX
-static int ProcPseudoramiXGetState(ClientPtr client)
-{
- REQUEST(xPanoramiXGetStateReq);
- WindowPtr pWin;
- xPanoramiXGetStateReply rep;
- register int n, rc;
-
- TRACE();
-
- REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
- rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
- if (rc != Success)
- return rc;
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.state = !noPseudoramiXExtension;
- if (client->swapped) {
- swaps (&rep.sequenceNumber, n);
- swapl (&rep.length, n);
- swaps (&rep.state, n);
- }
- WriteToClient (client, sizeof (xPanoramiXGetStateReply), (char *) &rep);
- return client->noClientException;
-}
-
-
-// was PanoramiX
-static int ProcPseudoramiXGetScreenCount(ClientPtr client)
-{
- REQUEST(xPanoramiXGetScreenCountReq);
- WindowPtr pWin;
- xPanoramiXGetScreenCountReply rep;
- register int n, rc;
-
- TRACE();
-
- REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
- rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
- if (rc != Success)
- return rc;
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.ScreenCount = pseudoramiXNumScreens;
- if (client->swapped) {
- swaps (&rep.sequenceNumber, n);
- swapl (&rep.length, n);
- swaps (&rep.ScreenCount, n);
- }
- WriteToClient (client, sizeof(xPanoramiXGetScreenCountReply), (char *)&rep);
- return client->noClientException;
-}
-
-
-// was PanoramiX
-static int ProcPseudoramiXGetScreenSize(ClientPtr client)
-{
- REQUEST(xPanoramiXGetScreenSizeReq);
- WindowPtr pWin;
- xPanoramiXGetScreenSizeReply rep;
- register int n, rc;
-
- TRACE();
-
- REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
- rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
- if (rc != Success)
- return rc;
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- /* screen dimensions */
- rep.width = pseudoramiXScreens[stuff->screen].w;
- // was panoramiXdataPtr[stuff->screen].width;
- rep.height = pseudoramiXScreens[stuff->screen].h;
- // was panoramiXdataPtr[stuff->screen].height;
- if (client->swapped) {
- swaps (&rep.sequenceNumber, n);
- swapl (&rep.length, n);
- swaps (&rep.width, n);
- swaps (&rep.height, n);
- }
- WriteToClient (client, sizeof(xPanoramiXGetScreenSizeReply), (char *)&rep);
- return client->noClientException;
-}
-
-
-// was Xinerama
-static int ProcPseudoramiXIsActive(ClientPtr client)
-{
- /* REQUEST(xXineramaIsActiveReq); */
- xXineramaIsActiveReply rep;
-
- TRACE();
-
- REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.state = !noPseudoramiXExtension;
- if (client->swapped) {
- register int n;
- swaps (&rep.sequenceNumber, n);
- swapl (&rep.length, n);
- swapl (&rep.state, n);
- }
- WriteToClient (client, sizeof (xXineramaIsActiveReply), (char *) &rep);
- return client->noClientException;
-}
-
-
-// was Xinerama
-static int ProcPseudoramiXQueryScreens(ClientPtr client)
-{
- /* REQUEST(xXineramaQueryScreensReq); */
- xXineramaQueryScreensReply rep;
-
- DEBUG_LOG("noPseudoramiXExtension=%d, pseudoramiXNumScreens=%d\n", noPseudoramiXExtension, pseudoramiXNumScreens);
-
- REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
-
- rep.type = X_Reply;
- rep.sequenceNumber = client->sequence;
- rep.number = noPseudoramiXExtension ? 0 : pseudoramiXNumScreens;
- rep.length = bytes_to_int32(rep.number * sz_XineramaScreenInfo);
- if (client->swapped) {
- register int n;
- swaps (&rep.sequenceNumber, n);
- swapl (&rep.length, n);
- swapl (&rep.number, n);
- }
- WriteToClient (client, sizeof (xXineramaQueryScreensReply), (char *) &rep);
-
- if (!noPseudoramiXExtension) {
- xXineramaScreenInfo scratch;
- int i;
-
- for(i = 0; i < pseudoramiXNumScreens; i++) {
- scratch.x_org = pseudoramiXScreens[i].x;
- scratch.y_org = pseudoramiXScreens[i].y;
- scratch.width = pseudoramiXScreens[i].w;
- scratch.height = pseudoramiXScreens[i].h;
-
- if(client->swapped) {
- register int n;
- swaps (&scratch.x_org, n);
- swaps (&scratch.y_org, n);
- swaps (&scratch.width, n);
- swaps (&scratch.height, n);
- }
- WriteToClient (client, sz_XineramaScreenInfo, (char *) &scratch);
- }
- }
-
- return client->noClientException;
-}
-
-
-// was PanoramiX
-static int ProcPseudoramiXDispatch (ClientPtr client)
-{ REQUEST(xReq);
- TRACE();
- switch (stuff->data)
- {
- case X_PanoramiXQueryVersion:
- return ProcPseudoramiXQueryVersion(client);
- case X_PanoramiXGetState:
- return ProcPseudoramiXGetState(client);
- case X_PanoramiXGetScreenCount:
- return ProcPseudoramiXGetScreenCount(client);
- case X_PanoramiXGetScreenSize:
- return ProcPseudoramiXGetScreenSize(client);
- case X_XineramaIsActive:
- return ProcPseudoramiXIsActive(client);
- case X_XineramaQueryScreens:
- return ProcPseudoramiXQueryScreens(client);
- }
- return BadRequest;
-}
-
-
-
-static int
-SProcPseudoramiXQueryVersion (ClientPtr client)
-{
- REQUEST(xPanoramiXQueryVersionReq);
- register int n;
-
- TRACE();
-
- swaps(&stuff->length,n);
- REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq);
- return ProcPseudoramiXQueryVersion(client);
-}
-
-static int
-SProcPseudoramiXGetState(ClientPtr client)
-{
- REQUEST(xPanoramiXGetStateReq);
- register int n;
-
- TRACE();
-
- swaps (&stuff->length, n);
- REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
- return ProcPseudoramiXGetState(client);
-}
-
-static int
-SProcPseudoramiXGetScreenCount(ClientPtr client)
-{
- REQUEST(xPanoramiXGetScreenCountReq);
- register int n;
-
- TRACE();
-
- swaps (&stuff->length, n);
- REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
- return ProcPseudoramiXGetScreenCount(client);
-}
-
-static int
-SProcPseudoramiXGetScreenSize(ClientPtr client)
-{
- REQUEST(xPanoramiXGetScreenSizeReq);
- register int n;
-
- TRACE();
-
- swaps (&stuff->length, n);
- REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
- return ProcPseudoramiXGetScreenSize(client);
-}
-
-
-static int
-SProcPseudoramiXIsActive(ClientPtr client)
-{
- REQUEST(xXineramaIsActiveReq);
- register int n;
-
- TRACE();
-
- swaps (&stuff->length, n);
- REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
- return ProcPseudoramiXIsActive(client);
-}
-
-
-static int
-SProcPseudoramiXQueryScreens(ClientPtr client)
-{
- REQUEST(xXineramaQueryScreensReq);
- register int n;
-
- TRACE();
-
- swaps (&stuff->length, n);
- REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
- return ProcPseudoramiXQueryScreens(client);
-}
-
-
-static int
-SProcPseudoramiXDispatch (ClientPtr client)
-{ REQUEST(xReq);
-
- TRACE();
-
- switch (stuff->data)
- {
- case X_PanoramiXQueryVersion:
- return SProcPseudoramiXQueryVersion(client);
- case X_PanoramiXGetState:
- return SProcPseudoramiXGetState(client);
- case X_PanoramiXGetScreenCount:
- return SProcPseudoramiXGetScreenCount(client);
- case X_PanoramiXGetScreenSize:
- return SProcPseudoramiXGetScreenSize(client);
- case X_XineramaIsActive:
- return SProcPseudoramiXIsActive(client);
- case X_XineramaQueryScreens:
- return SProcPseudoramiXQueryScreens(client);
- }
- return BadRequest;
-}
+/*
+ * Minimal implementation of PanoramiX/Xinerama
+ *
+ * This is used in rootless mode where the underlying window server
+ * already provides an abstracted view of multiple screens as one
+ * large screen area.
+ *
+ * This code is largely based on panoramiX.c, which contains the
+ * following copyright notice:
+ */
+/*****************************************************************
+Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
+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.
+
+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
+DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
+BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL 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 Digital Equipment Corporation
+shall not be used in advertising or otherwise to promote the sale, use or other
+dealings in this Software without prior written authorization from Digital
+Equipment Corporation.
+******************************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "darwin.h"
+#include "pseudoramiX.h"
+#include "extnsionst.h"
+#include "dixstruct.h"
+#include "window.h"
+#include <X11/extensions/panoramiXproto.h>
+#include "globals.h"
+
+Bool noPseudoramiXExtension = FALSE;
+
+extern int ProcPanoramiXQueryVersion (ClientPtr client);
+
+static void PseudoramiXResetProc(ExtensionEntry *extEntry);
+
+static int ProcPseudoramiXQueryVersion(ClientPtr client);
+static int ProcPseudoramiXGetState(ClientPtr client);
+static int ProcPseudoramiXGetScreenCount(ClientPtr client);
+static int ProcPseudoramiXGetScreenSize(ClientPtr client);
+static int ProcPseudoramiXIsActive(ClientPtr client);
+static int ProcPseudoramiXQueryScreens(ClientPtr client);
+static int ProcPseudoramiXDispatch(ClientPtr client);
+
+static int SProcPseudoramiXQueryVersion(ClientPtr client);
+static int SProcPseudoramiXGetState(ClientPtr client);
+static int SProcPseudoramiXGetScreenCount(ClientPtr client);
+static int SProcPseudoramiXGetScreenSize(ClientPtr client);
+static int SProcPseudoramiXIsActive(ClientPtr client);
+static int SProcPseudoramiXQueryScreens(ClientPtr client);
+static int SProcPseudoramiXDispatch(ClientPtr client);
+
+
+typedef struct {
+ int x;
+ int y;
+ int w;
+ int h;
+} PseudoramiXScreenRec;
+
+static PseudoramiXScreenRec *pseudoramiXScreens = NULL;
+static int pseudoramiXScreensAllocated = 0;
+static int pseudoramiXNumScreens = 0;
+static unsigned long pseudoramiXGeneration = 0;
+
+
+// Add a PseudoramiX screen.
+// The rest of the X server will know nothing about this screen.
+// Can be called before or after extension init.
+// Screens must be re-added once per generation.
+void
+PseudoramiXAddScreen(int x, int y, int w, int h)
+{
+ PseudoramiXScreenRec *s;
+
+ if (noPseudoramiXExtension) return;
+
+ if (pseudoramiXNumScreens == pseudoramiXScreensAllocated) {
+ pseudoramiXScreensAllocated += pseudoramiXScreensAllocated + 1;
+ pseudoramiXScreens = realloc(pseudoramiXScreens,
+ pseudoramiXScreensAllocated *
+ sizeof(PseudoramiXScreenRec));
+ }
+
+ DEBUG_LOG("x: %d, y: %d, w: %d, h: %d\n", x, y, w, h);
+
+ s = &pseudoramiXScreens[pseudoramiXNumScreens++];
+ s->x = x;
+ s->y = y;
+ s->w = w;
+ s->h = h;
+}
+
+
+// Initialize PseudoramiX.
+// Copied from PanoramiXExtensionInit
+void PseudoramiXExtensionInit(int argc, char *argv[])
+{
+ Bool success = FALSE;
+ ExtensionEntry *extEntry;
+
+ if (noPseudoramiXExtension) return;
+
+ TRACE();
+
+ /* Even with only one screen we need to enable PseudoramiX to allow
+ dynamic screen configuration changes. */
+#if 0
+ if (pseudoramiXNumScreens == 1) {
+ // Only one screen - disable Xinerama extension.
+ noPseudoramiXExtension = TRUE;
+ return;
+ }
+#endif
+
+ if (pseudoramiXGeneration != serverGeneration) {
+ extEntry = AddExtension(PANORAMIX_PROTOCOL_NAME, 0, 0,
+ ProcPseudoramiXDispatch,
+ SProcPseudoramiXDispatch,
+ PseudoramiXResetProc,
+ StandardMinorOpcode);
+ if (!extEntry) {
+ ErrorF("PseudoramiXExtensionInit(): AddExtension failed\n");
+ } else {
+ pseudoramiXGeneration = serverGeneration;
+ success = TRUE;
+ }
+ }
+
+ if (!success) {
+ ErrorF("%s Extension (PseudoramiX) failed to initialize\n",
+ PANORAMIX_PROTOCOL_NAME);
+ return;
+ }
+}
+
+
+void PseudoramiXResetScreens(void)
+{
+ TRACE();
+
+ pseudoramiXNumScreens = 0;
+}
+
+
+static void PseudoramiXResetProc(ExtensionEntry *extEntry)
+{
+ TRACE();
+
+ PseudoramiXResetScreens();
+}
+
+
+// was PanoramiX
+static int ProcPseudoramiXQueryVersion(ClientPtr client)
+{
+ TRACE();
+
+ return ProcPanoramiXQueryVersion(client);
+}
+
+
+// was PanoramiX
+static int ProcPseudoramiXGetState(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetStateReq);
+ WindowPtr pWin;
+ xPanoramiXGetStateReply rep;
+ register int n, rc;
+
+ TRACE();
+
+ REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.state = !noPseudoramiXExtension;
+ if (client->swapped) {
+ swaps (&rep.sequenceNumber, n);
+ swapl (&rep.length, n);
+ swaps (&rep.state, n);
+ }
+ WriteToClient (client, sizeof (xPanoramiXGetStateReply), (char *) &rep);
+ return Success;
+}
+
+
+// was PanoramiX
+static int ProcPseudoramiXGetScreenCount(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetScreenCountReq);
+ WindowPtr pWin;
+ xPanoramiXGetScreenCountReply rep;
+ register int n, rc;
+
+ TRACE();
+
+ REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.ScreenCount = pseudoramiXNumScreens;
+ if (client->swapped) {
+ swaps (&rep.sequenceNumber, n);
+ swapl (&rep.length, n);
+ swaps (&rep.ScreenCount, n);
+ }
+ WriteToClient (client, sizeof(xPanoramiXGetScreenCountReply), (char *)&rep);
+ return Success;
+}
+
+
+// was PanoramiX
+static int ProcPseudoramiXGetScreenSize(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetScreenSizeReq);
+ WindowPtr pWin;
+ xPanoramiXGetScreenSizeReply rep;
+ register int n, rc;
+
+ TRACE();
+
+ REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ /* screen dimensions */
+ rep.width = pseudoramiXScreens[stuff->screen].w;
+ // was panoramiXdataPtr[stuff->screen].width;
+ rep.height = pseudoramiXScreens[stuff->screen].h;
+ // was panoramiXdataPtr[stuff->screen].height;
+ if (client->swapped) {
+ swaps (&rep.sequenceNumber, n);
+ swapl (&rep.length, n);
+ swaps (&rep.width, n);
+ swaps (&rep.height, n);
+ }
+ WriteToClient (client, sizeof(xPanoramiXGetScreenSizeReply), (char *)&rep);
+ return Success;
+}
+
+
+// was Xinerama
+static int ProcPseudoramiXIsActive(ClientPtr client)
+{
+ /* REQUEST(xXineramaIsActiveReq); */
+ xXineramaIsActiveReply rep;
+
+ TRACE();
+
+ REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.state = !noPseudoramiXExtension;
+ if (client->swapped) {
+ register int n;
+ swaps (&rep.sequenceNumber, n);
+ swapl (&rep.length, n);
+ swapl (&rep.state, n);
+ }
+ WriteToClient (client, sizeof (xXineramaIsActiveReply), (char *) &rep);
+ return Success;
+}
+
+
+// was Xinerama
+static int ProcPseudoramiXQueryScreens(ClientPtr client)
+{
+ /* REQUEST(xXineramaQueryScreensReq); */
+ xXineramaQueryScreensReply rep;
+
+ DEBUG_LOG("noPseudoramiXExtension=%d, pseudoramiXNumScreens=%d\n", noPseudoramiXExtension, pseudoramiXNumScreens);
+
+ REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.number = noPseudoramiXExtension ? 0 : pseudoramiXNumScreens;
+ rep.length = bytes_to_int32(rep.number * sz_XineramaScreenInfo);
+ if (client->swapped) {
+ register int n;
+ swaps (&rep.sequenceNumber, n);
+ swapl (&rep.length, n);
+ swapl (&rep.number, n);
+ }
+ WriteToClient (client, sizeof (xXineramaQueryScreensReply), (char *) &rep);
+
+ if (!noPseudoramiXExtension) {
+ xXineramaScreenInfo scratch;
+ int i;
+
+ for(i = 0; i < pseudoramiXNumScreens; i++) {
+ scratch.x_org = pseudoramiXScreens[i].x;
+ scratch.y_org = pseudoramiXScreens[i].y;
+ scratch.width = pseudoramiXScreens[i].w;
+ scratch.height = pseudoramiXScreens[i].h;
+
+ if(client->swapped) {
+ register int n;
+ swaps (&scratch.x_org, n);
+ swaps (&scratch.y_org, n);
+ swaps (&scratch.width, n);
+ swaps (&scratch.height, n);
+ }
+ WriteToClient (client, sz_XineramaScreenInfo, (char *) &scratch);
+ }
+ }
+
+ return Success;
+}
+
+
+// was PanoramiX
+static int ProcPseudoramiXDispatch (ClientPtr client)
+{ REQUEST(xReq);
+ TRACE();
+ switch (stuff->data)
+ {
+ case X_PanoramiXQueryVersion:
+ return ProcPseudoramiXQueryVersion(client);
+ case X_PanoramiXGetState:
+ return ProcPseudoramiXGetState(client);
+ case X_PanoramiXGetScreenCount:
+ return ProcPseudoramiXGetScreenCount(client);
+ case X_PanoramiXGetScreenSize:
+ return ProcPseudoramiXGetScreenSize(client);
+ case X_XineramaIsActive:
+ return ProcPseudoramiXIsActive(client);
+ case X_XineramaQueryScreens:
+ return ProcPseudoramiXQueryScreens(client);
+ }
+ return BadRequest;
+}
+
+
+
+static int
+SProcPseudoramiXQueryVersion (ClientPtr client)
+{
+ REQUEST(xPanoramiXQueryVersionReq);
+ register int n;
+
+ TRACE();
+
+ swaps(&stuff->length,n);
+ REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq);
+ return ProcPseudoramiXQueryVersion(client);
+}
+
+static int
+SProcPseudoramiXGetState(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetStateReq);
+ register int n;
+
+ TRACE();
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
+ return ProcPseudoramiXGetState(client);
+}
+
+static int
+SProcPseudoramiXGetScreenCount(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetScreenCountReq);
+ register int n;
+
+ TRACE();
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
+ return ProcPseudoramiXGetScreenCount(client);
+}
+
+static int
+SProcPseudoramiXGetScreenSize(ClientPtr client)
+{
+ REQUEST(xPanoramiXGetScreenSizeReq);
+ register int n;
+
+ TRACE();
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
+ return ProcPseudoramiXGetScreenSize(client);
+}
+
+
+static int
+SProcPseudoramiXIsActive(ClientPtr client)
+{
+ REQUEST(xXineramaIsActiveReq);
+ register int n;
+
+ TRACE();
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
+ return ProcPseudoramiXIsActive(client);
+}
+
+
+static int
+SProcPseudoramiXQueryScreens(ClientPtr client)
+{
+ REQUEST(xXineramaQueryScreensReq);
+ register int n;
+
+ TRACE();
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
+ return ProcPseudoramiXQueryScreens(client);
+}
+
+
+static int
+SProcPseudoramiXDispatch (ClientPtr client)
+{ REQUEST(xReq);
+
+ TRACE();
+
+ switch (stuff->data)
+ {
+ case X_PanoramiXQueryVersion:
+ return SProcPseudoramiXQueryVersion(client);
+ case X_PanoramiXGetState:
+ return SProcPseudoramiXGetState(client);
+ case X_PanoramiXGetScreenCount:
+ return SProcPseudoramiXGetScreenCount(client);
+ case X_PanoramiXGetScreenSize:
+ return SProcPseudoramiXGetScreenSize(client);
+ case X_XineramaIsActive:
+ return SProcPseudoramiXIsActive(client);
+ case X_XineramaQueryScreens:
+ return SProcPseudoramiXQueryScreens(client);
+ }
+ return BadRequest;
+}
diff --git a/xorg-server/hw/xquartz/quartz.c b/xorg-server/hw/xquartz/quartz.c
index a8c0d4b47..e073b0586 100644
--- a/xorg-server/hw/xquartz/quartz.c
+++ b/xorg-server/hw/xquartz/quartz.c
@@ -1,449 +1,448 @@
-/*
- *
- * Quartz-specific support for the Darwin X Server
- *
- * Copyright (c) 2001-2004 Greg Parker and Torrey T. Lyons.
- * 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 ABOVE LISTED COPYRIGHT HOLDER(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(s) of the above copyright
- * holders shall not be used in advertising or otherwise to promote the sale,
- * use or other dealings in this Software without prior written authorization.
- */
-
-#include "sanitizedCarbon.h"
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "quartzCommon.h"
-#include "inputstr.h"
-#include "quartz.h"
-#include "darwin.h"
-#include "darwinEvents.h"
-#include "pseudoramiX.h"
-#define _APPLEWM_SERVER_
-#include "applewmExt.h"
-
-#include "X11Application.h"
-
-#include <X11/extensions/applewmconst.h>
-#include <X11/extensions/randr.h>
-
-// X headers
-#include "scrnintstr.h"
-#include "windowstr.h"
-#include "colormapst.h"
-#include "globals.h"
-#include "mi.h"
-
-// System headers
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <IOKit/pwr_mgt/IOPMLib.h>
-
-#include <rootlessCommon.h>
-#include <Xplugin.h>
-
-#define FAKE_RANDR 1
-
-// Shared global variables for Quartz modes
-int quartzEventWriteFD = -1;
-int quartzUseSysBeep = 0;
-int quartzUseAGL = 1;
-int quartzEnableKeyEquivalents = 1;
-int quartzServerVisible = FALSE;
-int quartzServerQuitting = FALSE;
-static int quartzScreenKeyIndex;
-DevPrivateKey quartzScreenKey = &quartzScreenKeyIndex;
-int aquaMenuBarHeight = 0;
-QuartzModeProcsPtr quartzProcs = NULL;
-const char *quartzOpenGLBundle = NULL;
-int quartzFullscreenDisableHotkeys = TRUE;
-int quartzOptionSendsAlt = FALSE;
-
-#if defined(RANDR) && !defined(FAKE_RANDR)
-Bool QuartzRandRGetInfo (ScreenPtr pScreen, Rotation *rotations) {
- return FALSE;
-}
-
-Bool QuartzRandRSetConfig (ScreenPtr pScreen,
- Rotation randr,
- int rate,
- RRScreenSizePtr pSize) {
- return FALSE;
-}
-
-Bool QuartzRandRInit (ScreenPtr pScreen) {
- rrScrPrivPtr pScrPriv;
-
- if (!RRScreenInit (pScreen)) return FALSE;
-
- pScrPriv = rrGetScrPriv(pScreen);
- pScrPriv->rrGetInfo = QuartzRandRGetInfo;
- pScrPriv->rrSetConfig = QuartzRandRSetConfig;
- return TRUE;
-}
-#endif
-
-/*
-===========================================================================
-
- Screen functions
-
-===========================================================================
-*/
-
-/*
- * QuartzAddScreen
- * Do mode dependent initialization of each screen for Quartz.
- */
-Bool QuartzAddScreen(
- int index,
- ScreenPtr pScreen)
-{
- // allocate space for private per screen Quartz specific storage
- QuartzScreenPtr displayInfo = xcalloc(sizeof(QuartzScreenRec), 1);
-
- // QUARTZ_PRIV(pScreen) = displayInfo;
- dixSetPrivate(&pScreen->devPrivates, quartzScreenKey, displayInfo);
-
- // do Quartz mode specific initialization
- return quartzProcs->AddScreen(index, pScreen);
-}
-
-
-/*
- * QuartzSetupScreen
- * Finalize mode specific setup of each screen.
- */
-Bool QuartzSetupScreen(
- int index,
- ScreenPtr pScreen)
-{
- // do Quartz mode specific setup
- if (! quartzProcs->SetupScreen(index, pScreen))
- return FALSE;
-
- // setup cursor support
- if (! quartzProcs->InitCursor(pScreen))
- return FALSE;
-
- return TRUE;
-}
-
-
-/*
- * QuartzInitOutput
- * Quartz display initialization.
- */
-void QuartzInitOutput(
- int argc,
- char **argv )
-{
- if (!RegisterBlockAndWakeupHandlers(QuartzBlockHandler,
- QuartzWakeupHandler,
- NULL))
- {
- FatalError("Could not register block and wakeup handlers.");
- }
-
-#if defined(RANDR) && !defined(FAKE_RANDR)
- if(!QuartzRandRInit(pScreen))
- FatalError("Failed to init RandR extension.\n");
-#endif
-
- // Do display mode specific initialization
- quartzProcs->DisplayInit();
-}
-
-
-/*
- * QuartzInitInput
- * Inform the main thread the X server is ready to handle events.
- */
-void QuartzInitInput(
- int argc,
- char **argv )
-{
- X11ApplicationSetCanQuit(0);
- X11ApplicationServerReady();
- // Do final display mode specific initialization before handling events
- if (quartzProcs->InitInput)
- quartzProcs->InitInput(argc, argv);
-}
-
-
-#ifdef FAKE_RANDR
-
-static const int padlength[4] = {0, 3, 2, 1};
-
-static void
-RREditConnectionInfo (ScreenPtr pScreen)
-{
- xConnSetup *connSetup;
- char *vendor;
- xPixmapFormat *formats;
- xWindowRoot *root;
- xDepth *depth;
- xVisualType *visual;
- int screen = 0;
- int d;
-
- connSetup = (xConnSetup *) ConnectionInfo;
- vendor = (char *) connSetup + sizeof (xConnSetup);
- formats = (xPixmapFormat *) ((char *) vendor +
- connSetup->nbytesVendor +
- padlength[connSetup->nbytesVendor & 3]);
- root = (xWindowRoot *) ((char *) formats +
- sizeof (xPixmapFormat) * screenInfo.numPixmapFormats);
- while (screen != pScreen->myNum)
- {
- depth = (xDepth *) ((char *) root +
- sizeof (xWindowRoot));
- for (d = 0; d < root->nDepths; d++)
- {
- visual = (xVisualType *) ((char *) depth +
- sizeof (xDepth));
- depth = (xDepth *) ((char *) visual +
- depth->nVisuals * sizeof (xVisualType));
- }
- root = (xWindowRoot *) ((char *) depth);
- screen++;
- }
- root->pixWidth = pScreen->width;
- root->pixHeight = pScreen->height;
- root->mmWidth = pScreen->mmWidth;
- root->mmHeight = pScreen->mmHeight;
-}
-#endif
-
-void QuartzUpdateScreens(void) {
- ScreenPtr pScreen;
- WindowPtr pRoot;
- int x, y, width, height, sx, sy;
- xEvent e;
- BoxRec bounds;
-
- if (noPseudoramiXExtension || screenInfo.numScreens != 1)
- {
- /* FIXME: if not using Xinerama, we have multiple screens, and
- to do this properly may need to add or remove screens. Which
- isn't possible. So don't do anything. Another reason why
- we default to running with Xinerama. */
-
- return;
- }
-
- pScreen = screenInfo.screens[0];
-
- PseudoramiXResetScreens();
- quartzProcs->AddPseudoramiXScreens(&x, &y, &width, &height);
-
- dixScreenOrigins[pScreen->myNum].x = x;
- dixScreenOrigins[pScreen->myNum].y = y;
- pScreen->mmWidth = pScreen->mmWidth * ((double) width / pScreen->width);
- pScreen->mmHeight = pScreen->mmHeight * ((double) height / pScreen->height);
- pScreen->width = width;
- pScreen->height = height;
-
- DarwinAdjustScreenOrigins(&screenInfo);
- quartzProcs->UpdateScreen(pScreen);
-
- /* DarwinAdjustScreenOrigins or UpdateScreen may change dixScreenOrigins,
- * so use it rather than x/y
- */
- sx = dixScreenOrigins[pScreen->myNum].x + darwinMainScreenX;
- sy = dixScreenOrigins[pScreen->myNum].y + darwinMainScreenY;
-
- /* Adjust the root window. */
- pRoot = WindowTable[pScreen->myNum];
- AppleWMSetScreenOrigin(pRoot);
- pScreen->ResizeWindow(pRoot, x - sx, y - sy, width, height, NULL);
- //pScreen->PaintWindowBackground (pRoot, &pRoot->borderClip, PW_BACKGROUND);
- miPaintWindow(pRoot, &pRoot->borderClip, PW_BACKGROUND);
-
- /* <rdar://problem/7770779> pointer events are clipped to old display region after display reconfiguration
- * http://xquartz.macosforge.org/trac/ticket/346
- */
- bounds.x1 = 0;
- bounds.x2 = width;
- bounds.y1 = 0;
- bounds.y2 = height;
- pScreen->ConstrainCursor(inputInfo.pointer, pScreen, &bounds);
- inputInfo.pointer->spriteInfo->sprite->physLimits = bounds;
- inputInfo.pointer->spriteInfo->sprite->hotLimits = bounds;
-
- DEBUG_LOG("Root Window: %dx%d @ (%d, %d) darwinMainScreen (%d, %d) xy (%d, %d) dixScreenOrigins (%d, %d)\n", width, height, x - sx, y - sy, darwinMainScreenX, darwinMainScreenY, x, y, dixScreenOrigins[pScreen->myNum].x, dixScreenOrigins[pScreen->myNum].y);
-
- /* Send an event for the root reconfigure */
- e.u.u.type = ConfigureNotify;
- e.u.configureNotify.window = pRoot->drawable.id;
- e.u.configureNotify.aboveSibling = None;
- e.u.configureNotify.x = x - sx;
- e.u.configureNotify.y = y - sy;
- e.u.configureNotify.width = width;
- e.u.configureNotify.height = height;
- e.u.configureNotify.borderWidth = wBorderWidth(pRoot);
- e.u.configureNotify.override = pRoot->overrideRedirect;
- DeliverEvents(pRoot, &e, 1, NullWindow);
-
-#ifdef FAKE_RANDR
- RREditConnectionInfo(pScreen);
-#endif
-}
-
-void QuartzSetFullscreen(Bool state) {
-
- DEBUG_LOG("QuartzSetFullscreen: state=%d\n", state);
-
- if(quartzHasRoot == state)
- return;
-
- quartzHasRoot = state;
-
- xp_disable_update ();
-
- if (!quartzHasRoot && !quartzEnableRootless)
- RootlessHideAllWindows();
-
- RootlessUpdateRooted(quartzHasRoot);
-
- if (quartzHasRoot && !quartzEnableRootless)
- RootlessShowAllWindows ();
-
- if (quartzHasRoot || quartzEnableRootless) {
- RootlessRepositionWindows(screenInfo.screens[0]);
- }
-
- /* Somehow the menubar manages to interfere with our event stream
- * in fullscreen mode, even though it's not visible.
- */
- X11ApplicationShowHideMenubar(!quartzHasRoot);
-
- xp_reenable_update ();
-
- if (quartzFullscreenDisableHotkeys)
- xp_disable_hot_keys(quartzHasRoot);
-}
-
-void QuartzSetRootless(Bool state) {
- if(quartzEnableRootless == state)
- return;
-
- quartzEnableRootless = state;
-
- xp_disable_update();
-
- /* When in rootless, the menubar is not part of the screen, so we need to update our screens on toggle */
- QuartzUpdateScreens();
-
- if(!quartzHasRoot) {
- if(!quartzEnableRootless) {
- RootlessHideAllWindows();
- } else {
- RootlessShowAllWindows();
- }
- }
-
- X11ApplicationShowHideMenubar(!quartzHasRoot);
-
- xp_reenable_update();
-
- if (!quartzEnableRootless && quartzFullscreenDisableHotkeys)
- xp_disable_hot_keys(quartzHasRoot);
-}
-
-/*
- * QuartzShow
- * Show the X server on screen. Does nothing if already shown.
- * Calls mode specific screen resume to restore the X clip regions
- * (if needed) and the X server cursor state.
- */
-void QuartzShow(void) {
- int i;
-
- if (quartzServerVisible)
- return;
-
- quartzServerVisible = TRUE;
- for (i = 0; i < screenInfo.numScreens; i++) {
- if (screenInfo.screens[i]) {
- quartzProcs->ResumeScreen(screenInfo.screens[i]);
- }
- }
-
- if (!quartzEnableRootless)
- QuartzSetFullscreen(TRUE);
-}
-
-
-/*
- * QuartzHide
- * Remove the X server display from the screen. Does nothing if already
- * hidden. Calls mode specific screen suspend to set X clip regions to
- * prevent drawing (if needed) and restore the Aqua cursor.
- */
-void QuartzHide(void)
-{
- int i;
-
- if (quartzServerVisible) {
- for (i = 0; i < screenInfo.numScreens; i++) {
- if (screenInfo.screens[i]) {
- quartzProcs->SuspendScreen(screenInfo.screens[i]);
- }
- }
- }
-
- QuartzSetFullscreen(FALSE);
- quartzServerVisible = FALSE;
-}
-
-
-/*
- * QuartzSetRootClip
- * Enable or disable rendering to the X screen.
- */
-void QuartzSetRootClip(
- BOOL enable)
-{
- int i;
-
- if (!quartzServerVisible)
- return;
-
- for (i = 0; i < screenInfo.numScreens; i++) {
- if (screenInfo.screens[i]) {
- xf86SetRootClip(screenInfo.screens[i], enable);
- }
- }
-}
-
-/*
- * QuartzSpaceChanged
- * Unmap offscreen windows, map onscreen windows
- */
-void QuartzSpaceChanged(uint32_t space_id) {
- /* Do something special here, so we don't depend on quartz-wm for spaces to work... */
- DEBUG_LOG("Space Changed (%u) ... do something interesting...\n", space_id);
-}
+/*
+ *
+ * Quartz-specific support for the Darwin X Server
+ *
+ * Copyright (c) 2001-2004 Greg Parker and Torrey T. Lyons.
+ * 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 ABOVE LISTED COPYRIGHT HOLDER(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(s) of the above copyright
+ * holders shall not be used in advertising or otherwise to promote the sale,
+ * use or other dealings in this Software without prior written authorization.
+ */
+
+#include "sanitizedCarbon.h"
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "quartzCommon.h"
+#include "inputstr.h"
+#include "quartz.h"
+#include "darwin.h"
+#include "darwinEvents.h"
+#include "pseudoramiX.h"
+#define _APPLEWM_SERVER_
+#include "applewmExt.h"
+
+#include "X11Application.h"
+
+#include <X11/extensions/applewmconst.h>
+#include <X11/extensions/randr.h>
+
+// X headers
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "colormapst.h"
+#include "globals.h"
+#include "mi.h"
+
+// System headers
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <IOKit/pwr_mgt/IOPMLib.h>
+
+#include <rootlessCommon.h>
+#include <Xplugin.h>
+
+#define FAKE_RANDR 1
+
+// Shared global variables for Quartz modes
+int quartzEventWriteFD = -1;
+int quartzUseSysBeep = 0;
+int quartzUseAGL = 1;
+int quartzEnableKeyEquivalents = 1;
+int quartzServerVisible = FALSE;
+int quartzServerQuitting = FALSE;
+static int quartzScreenKeyIndex;
+DevPrivateKey quartzScreenKey = &quartzScreenKeyIndex;
+int aquaMenuBarHeight = 0;
+QuartzModeProcsPtr quartzProcs = NULL;
+const char *quartzOpenGLBundle = NULL;
+int quartzFullscreenDisableHotkeys = TRUE;
+int quartzOptionSendsAlt = FALSE;
+
+#if defined(RANDR) && !defined(FAKE_RANDR)
+Bool QuartzRandRGetInfo (ScreenPtr pScreen, Rotation *rotations) {
+ return FALSE;
+}
+
+Bool QuartzRandRSetConfig (ScreenPtr pScreen,
+ Rotation randr,
+ int rate,
+ RRScreenSizePtr pSize) {
+ return FALSE;
+}
+
+Bool QuartzRandRInit (ScreenPtr pScreen) {
+ rrScrPrivPtr pScrPriv;
+
+ if (!RRScreenInit (pScreen)) return FALSE;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+ pScrPriv->rrGetInfo = QuartzRandRGetInfo;
+ pScrPriv->rrSetConfig = QuartzRandRSetConfig;
+ return TRUE;
+}
+#endif
+
+/*
+===========================================================================
+
+ Screen functions
+
+===========================================================================
+*/
+
+/*
+ * QuartzAddScreen
+ * Do mode dependent initialization of each screen for Quartz.
+ */
+Bool QuartzAddScreen(
+ int index,
+ ScreenPtr pScreen)
+{
+ // allocate space for private per screen Quartz specific storage
+ QuartzScreenPtr displayInfo = calloc(sizeof(QuartzScreenRec), 1);
+
+ // QUARTZ_PRIV(pScreen) = displayInfo;
+ dixSetPrivate(&pScreen->devPrivates, quartzScreenKey, displayInfo);
+
+ // do Quartz mode specific initialization
+ return quartzProcs->AddScreen(index, pScreen);
+}
+
+
+/*
+ * QuartzSetupScreen
+ * Finalize mode specific setup of each screen.
+ */
+Bool QuartzSetupScreen(
+ int index,
+ ScreenPtr pScreen)
+{
+ // do Quartz mode specific setup
+ if (! quartzProcs->SetupScreen(index, pScreen))
+ return FALSE;
+
+ // setup cursor support
+ if (! quartzProcs->InitCursor(pScreen))
+ return FALSE;
+
+ return TRUE;
+}
+
+
+/*
+ * QuartzInitOutput
+ * Quartz display initialization.
+ */
+void QuartzInitOutput(
+ int argc,
+ char **argv )
+{
+ if (!RegisterBlockAndWakeupHandlers(QuartzBlockHandler,
+ QuartzWakeupHandler,
+ NULL))
+ {
+ FatalError("Could not register block and wakeup handlers.");
+ }
+
+#if defined(RANDR) && !defined(FAKE_RANDR)
+ if(!QuartzRandRInit(pScreen))
+ FatalError("Failed to init RandR extension.\n");
+#endif
+
+ // Do display mode specific initialization
+ quartzProcs->DisplayInit();
+}
+
+
+/*
+ * QuartzInitInput
+ * Inform the main thread the X server is ready to handle events.
+ */
+void QuartzInitInput(
+ int argc,
+ char **argv )
+{
+ X11ApplicationSetCanQuit(0);
+ X11ApplicationServerReady();
+ // Do final display mode specific initialization before handling events
+ if (quartzProcs->InitInput)
+ quartzProcs->InitInput(argc, argv);
+}
+
+
+#ifdef FAKE_RANDR
+
+static const int padlength[4] = {0, 3, 2, 1};
+
+static void
+RREditConnectionInfo (ScreenPtr pScreen)
+{
+ xConnSetup *connSetup;
+ char *vendor;
+ xPixmapFormat *formats;
+ xWindowRoot *root;
+ xDepth *depth;
+ xVisualType *visual;
+ int screen = 0;
+ int d;
+
+ connSetup = (xConnSetup *) ConnectionInfo;
+ vendor = (char *) connSetup + sizeof (xConnSetup);
+ formats = (xPixmapFormat *) ((char *) vendor +
+ connSetup->nbytesVendor +
+ padlength[connSetup->nbytesVendor & 3]);
+ root = (xWindowRoot *) ((char *) formats +
+ sizeof (xPixmapFormat) * screenInfo.numPixmapFormats);
+ while (screen != pScreen->myNum)
+ {
+ depth = (xDepth *) ((char *) root +
+ sizeof (xWindowRoot));
+ for (d = 0; d < root->nDepths; d++)
+ {
+ visual = (xVisualType *) ((char *) depth +
+ sizeof (xDepth));
+ depth = (xDepth *) ((char *) visual +
+ depth->nVisuals * sizeof (xVisualType));
+ }
+ root = (xWindowRoot *) ((char *) depth);
+ screen++;
+ }
+ root->pixWidth = pScreen->width;
+ root->pixHeight = pScreen->height;
+ root->mmWidth = pScreen->mmWidth;
+ root->mmHeight = pScreen->mmHeight;
+}
+#endif
+
+void QuartzUpdateScreens(void) {
+ ScreenPtr pScreen;
+ WindowPtr pRoot;
+ int x, y, width, height, sx, sy;
+ xEvent e;
+ BoxRec bounds;
+
+ if (noPseudoramiXExtension || screenInfo.numScreens != 1)
+ {
+ /* FIXME: if not using Xinerama, we have multiple screens, and
+ to do this properly may need to add or remove screens. Which
+ isn't possible. So don't do anything. Another reason why
+ we default to running with Xinerama. */
+
+ return;
+ }
+
+ pScreen = screenInfo.screens[0];
+
+ PseudoramiXResetScreens();
+ quartzProcs->AddPseudoramiXScreens(&x, &y, &width, &height);
+
+ dixScreenOrigins[pScreen->myNum].x = x;
+ dixScreenOrigins[pScreen->myNum].y = y;
+ pScreen->mmWidth = pScreen->mmWidth * ((double) width / pScreen->width);
+ pScreen->mmHeight = pScreen->mmHeight * ((double) height / pScreen->height);
+ pScreen->width = width;
+ pScreen->height = height;
+
+ DarwinAdjustScreenOrigins(&screenInfo);
+ quartzProcs->UpdateScreen(pScreen);
+
+ /* DarwinAdjustScreenOrigins or UpdateScreen may change dixScreenOrigins,
+ * so use it rather than x/y
+ */
+ sx = dixScreenOrigins[pScreen->myNum].x + darwinMainScreenX;
+ sy = dixScreenOrigins[pScreen->myNum].y + darwinMainScreenY;
+
+ /* Adjust the root window. */
+ pRoot = WindowTable[pScreen->myNum];
+ AppleWMSetScreenOrigin(pRoot);
+ pScreen->ResizeWindow(pRoot, x - sx, y - sy, width, height, NULL);
+ miPaintWindow(pRoot, &pRoot->borderClip, PW_BACKGROUND);
+
+ /* <rdar://problem/7770779> pointer events are clipped to old display region after display reconfiguration
+ * http://xquartz.macosforge.org/trac/ticket/346
+ */
+ bounds.x1 = 0;
+ bounds.x2 = width;
+ bounds.y1 = 0;
+ bounds.y2 = height;
+ pScreen->ConstrainCursor(inputInfo.pointer, pScreen, &bounds);
+ inputInfo.pointer->spriteInfo->sprite->physLimits = bounds;
+ inputInfo.pointer->spriteInfo->sprite->hotLimits = bounds;
+
+ DEBUG_LOG("Root Window: %dx%d @ (%d, %d) darwinMainScreen (%d, %d) xy (%d, %d) dixScreenOrigins (%d, %d)\n", width, height, x - sx, y - sy, darwinMainScreenX, darwinMainScreenY, x, y, dixScreenOrigins[pScreen->myNum].x, dixScreenOrigins[pScreen->myNum].y);
+
+ /* Send an event for the root reconfigure */
+ e.u.u.type = ConfigureNotify;
+ e.u.configureNotify.window = pRoot->drawable.id;
+ e.u.configureNotify.aboveSibling = None;
+ e.u.configureNotify.x = x - sx;
+ e.u.configureNotify.y = y - sy;
+ e.u.configureNotify.width = width;
+ e.u.configureNotify.height = height;
+ e.u.configureNotify.borderWidth = wBorderWidth(pRoot);
+ e.u.configureNotify.override = pRoot->overrideRedirect;
+ DeliverEvents(pRoot, &e, 1, NullWindow);
+
+#ifdef FAKE_RANDR
+ RREditConnectionInfo(pScreen);
+#endif
+}
+
+void QuartzSetFullscreen(Bool state) {
+
+ DEBUG_LOG("QuartzSetFullscreen: state=%d\n", state);
+
+ if(quartzHasRoot == state)
+ return;
+
+ quartzHasRoot = state;
+
+ xp_disable_update ();
+
+ if (!quartzHasRoot && !quartzEnableRootless)
+ RootlessHideAllWindows();
+
+ RootlessUpdateRooted(quartzHasRoot);
+
+ if (quartzHasRoot && !quartzEnableRootless)
+ RootlessShowAllWindows ();
+
+ if (quartzHasRoot || quartzEnableRootless) {
+ RootlessRepositionWindows(screenInfo.screens[0]);
+ }
+
+ /* Somehow the menubar manages to interfere with our event stream
+ * in fullscreen mode, even though it's not visible.
+ */
+ X11ApplicationShowHideMenubar(!quartzHasRoot);
+
+ xp_reenable_update ();
+
+ if (quartzFullscreenDisableHotkeys)
+ xp_disable_hot_keys(quartzHasRoot);
+}
+
+void QuartzSetRootless(Bool state) {
+ if(quartzEnableRootless == state)
+ return;
+
+ quartzEnableRootless = state;
+
+ xp_disable_update();
+
+ /* When in rootless, the menubar is not part of the screen, so we need to update our screens on toggle */
+ QuartzUpdateScreens();
+
+ if(!quartzHasRoot) {
+ if(!quartzEnableRootless) {
+ RootlessHideAllWindows();
+ } else {
+ RootlessShowAllWindows();
+ }
+ }
+
+ X11ApplicationShowHideMenubar(!quartzHasRoot);
+
+ xp_reenable_update();
+
+ if (!quartzEnableRootless && quartzFullscreenDisableHotkeys)
+ xp_disable_hot_keys(quartzHasRoot);
+}
+
+/*
+ * QuartzShow
+ * Show the X server on screen. Does nothing if already shown.
+ * Calls mode specific screen resume to restore the X clip regions
+ * (if needed) and the X server cursor state.
+ */
+void QuartzShow(void) {
+ int i;
+
+ if (quartzServerVisible)
+ return;
+
+ quartzServerVisible = TRUE;
+ for (i = 0; i < screenInfo.numScreens; i++) {
+ if (screenInfo.screens[i]) {
+ quartzProcs->ResumeScreen(screenInfo.screens[i]);
+ }
+ }
+
+ if (!quartzEnableRootless)
+ QuartzSetFullscreen(TRUE);
+}
+
+
+/*
+ * QuartzHide
+ * Remove the X server display from the screen. Does nothing if already
+ * hidden. Calls mode specific screen suspend to set X clip regions to
+ * prevent drawing (if needed) and restore the Aqua cursor.
+ */
+void QuartzHide(void)
+{
+ int i;
+
+ if (quartzServerVisible) {
+ for (i = 0; i < screenInfo.numScreens; i++) {
+ if (screenInfo.screens[i]) {
+ quartzProcs->SuspendScreen(screenInfo.screens[i]);
+ }
+ }
+ }
+
+ QuartzSetFullscreen(FALSE);
+ quartzServerVisible = FALSE;
+}
+
+
+/*
+ * QuartzSetRootClip
+ * Enable or disable rendering to the X screen.
+ */
+void QuartzSetRootClip(
+ BOOL enable)
+{
+ int i;
+
+ if (!quartzServerVisible)
+ return;
+
+ for (i = 0; i < screenInfo.numScreens; i++) {
+ if (screenInfo.screens[i]) {
+ xf86SetRootClip(screenInfo.screens[i], enable);
+ }
+ }
+}
+
+/*
+ * QuartzSpaceChanged
+ * Unmap offscreen windows, map onscreen windows
+ */
+void QuartzSpaceChanged(uint32_t space_id) {
+ /* Do something special here, so we don't depend on quartz-wm for spaces to work... */
+ DEBUG_LOG("Space Changed (%u) ... do something interesting...\n", space_id);
+}
diff --git a/xorg-server/hw/xquartz/xpr/appledri.c b/xorg-server/hw/xquartz/xpr/appledri.c
index 74a4ec315..87cb9016a 100644
--- a/xorg-server/hw/xquartz/xpr/appledri.c
+++ b/xorg-server/hw/xquartz/xpr/appledri.c
@@ -1,429 +1,429 @@
-/**************************************************************************
-
-Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
-Copyright 2000 VA Linux Systems, Inc.
-Copyright (c) 2002, 2009 Apple Computer, 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, sub license, 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 (including the
-next paragraph) 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 NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Kevin E. Martin <martin@valinux.com>
- * Jens Owen <jens@valinux.com>
- * Rickard E. (Rik) Faith <faith@valinux.com>
- *
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include "misc.h"
-#include "dixstruct.h"
-#include "extnsionst.h"
-#include "colormapst.h"
-#include "cursorstr.h"
-#include "scrnintstr.h"
-#include "servermd.h"
-#define _APPLEDRI_SERVER_
-#include "appledristr.h"
-#include "swaprep.h"
-#include "dri.h"
-#include "dristruct.h"
-#include "xpr.h"
-#include "x-hash.h"
-#include "protocol-versions.h"
-
-static int DRIErrorBase = 0;
-
-static DISPATCH_PROC(ProcAppleDRIDispatch);
-static DISPATCH_PROC(SProcAppleDRIDispatch);
-
-static void AppleDRIResetProc(ExtensionEntry* extEntry);
-static int ProcAppleDRICreatePixmap(ClientPtr client);
-
-static unsigned char DRIReqCode = 0;
-static int DRIEventBase = 0;
-
-static void SNotifyEvent(xAppleDRINotifyEvent *from, xAppleDRINotifyEvent *to);
-
-typedef struct _DRIEvent *DRIEventPtr;
-typedef struct _DRIEvent {
- DRIEventPtr next;
- ClientPtr client;
- XID clientResource;
- unsigned int mask;
-} DRIEventRec;
-
-
-void
-AppleDRIExtensionInit(void)
-{
- ExtensionEntry* extEntry;
-
- if (DRIExtensionInit() &&
- (extEntry = AddExtension(APPLEDRINAME,
- AppleDRINumberEvents,
- AppleDRINumberErrors,
- ProcAppleDRIDispatch,
- SProcAppleDRIDispatch,
- AppleDRIResetProc,
- StandardMinorOpcode))) {
- DRIReqCode = (unsigned char)extEntry->base;
- DRIErrorBase = extEntry->errorBase;
- DRIEventBase = extEntry->eventBase;
- EventSwapVector[DRIEventBase] = (EventSwapPtr) SNotifyEvent;
- }
-}
-
-/*ARGSUSED*/
-static void
-AppleDRIResetProc (
- ExtensionEntry* extEntry
-)
-{
- DRIReset();
-}
-
-static int
-ProcAppleDRIQueryVersion(
- register ClientPtr client
-)
-{
- xAppleDRIQueryVersionReply rep;
- register int n;
-
- REQUEST_SIZE_MATCH(xAppleDRIQueryVersionReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.majorVersion = SERVER_APPLEDRI_MAJOR_VERSION;
- rep.minorVersion = SERVER_APPLEDRI_MINOR_VERSION;
- rep.patchVersion = SERVER_APPLEDRI_PATCH_VERSION;
- if (client->swapped) {
- swaps(&rep.sequenceNumber, n);
- swapl(&rep.length, n);
- }
- WriteToClient(client, sizeof(xAppleDRIQueryVersionReply), (char *)&rep);
- return (client->noClientException);
-}
-
-
-/* surfaces */
-
-static int
-ProcAppleDRIQueryDirectRenderingCapable(
- register ClientPtr client
-)
-{
- xAppleDRIQueryDirectRenderingCapableReply rep;
- Bool isCapable;
-
- REQUEST(xAppleDRIQueryDirectRenderingCapableReq);
- REQUEST_SIZE_MATCH(xAppleDRIQueryDirectRenderingCapableReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- if (!DRIQueryDirectRenderingCapable( screenInfo.screens[stuff->screen],
- &isCapable)) {
- return BadValue;
- }
- rep.isCapable = isCapable;
-
- if (!LocalClient(client))
- rep.isCapable = 0;
-
- WriteToClient(client,
- sizeof(xAppleDRIQueryDirectRenderingCapableReply), (char *)&rep);
- return (client->noClientException);
-}
-
-static int
-ProcAppleDRIAuthConnection(
- register ClientPtr client
-)
-{
- xAppleDRIAuthConnectionReply rep;
-
- REQUEST(xAppleDRIAuthConnectionReq);
- REQUEST_SIZE_MATCH(xAppleDRIAuthConnectionReq);
-
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
- rep.authenticated = 1;
-
- if (!DRIAuthConnection( screenInfo.screens[stuff->screen], stuff->magic)) {
- ErrorF("Failed to authenticate %u\n", (unsigned int)stuff->magic);
- rep.authenticated = 0;
- }
- WriteToClient(client, sizeof(xAppleDRIAuthConnectionReply), (char *)&rep);
- return (client->noClientException);
-}
-
-static void surface_notify(
- void *_arg,
- void *data
-)
-{
- DRISurfaceNotifyArg *arg = _arg;
- int client_index = (int) x_cvt_vptr_to_uint(data);
- ClientPtr client;
- xAppleDRINotifyEvent se;
-
- if (client_index < 0 || client_index >= currentMaxClients)
- return;
-
- client = clients[client_index];
- if (client == NULL || client == serverClient || client->clientGone)
- return;
-
- se.type = DRIEventBase + AppleDRISurfaceNotify;
- se.kind = arg->kind;
- se.arg = arg->id;
- se.sequenceNumber = client->sequence;
- se.time = currentTime.milliseconds;
- WriteEventsToClient (client, 1, (xEvent *) &se);
-}
-
-static int
-ProcAppleDRICreateSurface(
- ClientPtr client
-)
-{
- xAppleDRICreateSurfaceReply rep;
- DrawablePtr pDrawable;
- xp_surface_id sid;
- unsigned int key[2];
- int rc;
-
- REQUEST(xAppleDRICreateSurfaceReq);
- REQUEST_SIZE_MATCH(xAppleDRICreateSurfaceReq);
- rep.type = X_Reply;
- rep.length = 0;
- rep.sequenceNumber = client->sequence;
-
- rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
- DixReadAccess);
- if (rc != Success)
- return rc;
-
- rep.key_0 = rep.key_1 = rep.uid = 0;
-
- if (!DRICreateSurface( screenInfo.screens[stuff->screen],
- (Drawable)stuff->drawable, pDrawable,
- stuff->client_id, &sid, key,
- surface_notify,
- x_cvt_uint_to_vptr(client->index))) {
- return BadValue;
- }
-
- rep.key_0 = key[0];
- rep.key_1 = key[1];
- rep.uid = sid;
-
- WriteToClient(client, sizeof(xAppleDRICreateSurfaceReply), (char *)&rep);
- return (client->noClientException);
-}
-
-static int
-ProcAppleDRIDestroySurface(
- register ClientPtr client
-)
-{
- int rc;
- REQUEST(xAppleDRIDestroySurfaceReq);
- DrawablePtr pDrawable;
- REQUEST_SIZE_MATCH(xAppleDRIDestroySurfaceReq);
-
- rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
- DixReadAccess);
- if (rc != Success)
- return rc;
-
- if (!DRIDestroySurface( screenInfo.screens[stuff->screen],
- (Drawable)stuff->drawable,
- pDrawable, NULL, NULL)) {
- return BadValue;
- }
-
- return (client->noClientException);
-}
-
-static int
-ProcAppleDRICreatePixmap(ClientPtr client)
-{
- REQUEST(xAppleDRICreatePixmapReq);
- DrawablePtr pDrawable;
- int rc;
- char path[PATH_MAX];
- xAppleDRICreatePixmapReply rep;
- int width, height, pitch, bpp;
- void *ptr;
-
- REQUEST_SIZE_MATCH(xAppleDRICreatePixmapReq);
-
- rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
- DixReadAccess);
-
- if(rc != Success)
- return rc;
-
- if(!DRICreatePixmap(screenInfo.screens[stuff->screen],
- (Drawable)stuff->drawable,
- pDrawable,
- path, PATH_MAX)) {
- return BadValue;
- }
-
- if(!DRIGetPixmapData(pDrawable, &width, &height,
- &pitch, &bpp, &ptr)) {
- return BadValue;
- }
-
- rep.stringLength = strlen(path) + 1;
-
- /* No need for swapping, because this only runs if LocalClient is true. */
- rep.type = X_Reply;
- rep.length = sizeof(rep) + rep.stringLength;
- rep.sequenceNumber = client->sequence;
- rep.width = width;
- rep.height = height;
- rep.pitch = pitch;
- rep.bpp = bpp;
- rep.size = pitch * height;
-
- if(sizeof(rep) != sz_xAppleDRICreatePixmapReply)
- ErrorF("error sizeof(rep) is %zu\n", sizeof(rep));
-
- WriteReplyToClient(client, sizeof(rep), &rep);
- (void)WriteToClient(client, rep.stringLength, path);
-
- return (client->noClientException);
-}
-
-static int
-ProcAppleDRIDestroyPixmap(ClientPtr client)
-{
- DrawablePtr pDrawable;
- int rc;
- REQUEST(xAppleDRIDestroyPixmapReq);
- REQUEST_SIZE_MATCH(xAppleDRIDestroyPixmapReq);
-
- rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
- DixReadAccess);
-
- if(rc != Success)
- return rc;
-
- DRIDestroyPixmap(pDrawable);
-
- return (client->noClientException);
-}
-
-/* dispatch */
-
-static int
-ProcAppleDRIDispatch (
- register ClientPtr client
-)
-{
- REQUEST(xReq);
-
- switch (stuff->data)
- {
- case X_AppleDRIQueryVersion:
- return ProcAppleDRIQueryVersion(client);
- case X_AppleDRIQueryDirectRenderingCapable:
- return ProcAppleDRIQueryDirectRenderingCapable(client);
- }
-
- if (!LocalClient(client))
- return DRIErrorBase + AppleDRIClientNotLocal;
-
- switch (stuff->data)
- {
- case X_AppleDRIAuthConnection:
- return ProcAppleDRIAuthConnection(client);
- case X_AppleDRICreateSurface:
- return ProcAppleDRICreateSurface(client);
- case X_AppleDRIDestroySurface:
- return ProcAppleDRIDestroySurface(client);
- case X_AppleDRICreatePixmap:
- return ProcAppleDRICreatePixmap(client);
- case X_AppleDRIDestroyPixmap:
- return ProcAppleDRIDestroyPixmap(client);
-
- default:
- return BadRequest;
- }
-}
-
-static void
-SNotifyEvent(
- xAppleDRINotifyEvent *from,
- xAppleDRINotifyEvent *to
-)
-{
- to->type = from->type;
- to->kind = from->kind;
- cpswaps (from->sequenceNumber, to->sequenceNumber);
- cpswapl (from->time, to->time);
- cpswapl (from->arg, to->arg);
-}
-
-static int
-SProcAppleDRIQueryVersion(
- register ClientPtr client
-)
-{
- register int n;
- REQUEST(xAppleDRIQueryVersionReq);
- swaps(&stuff->length, n);
- return ProcAppleDRIQueryVersion(client);
-}
-
-static int
-SProcAppleDRIDispatch (
- register ClientPtr client
-)
-{
- REQUEST(xReq);
-
- /* It is bound to be non-local when there is byte swapping */
- if (!LocalClient(client))
- return DRIErrorBase + AppleDRIClientNotLocal;
-
- /* only local clients are allowed DRI access */
- switch (stuff->data)
- {
- case X_AppleDRIQueryVersion:
- return SProcAppleDRIQueryVersion(client);
- default:
- return BadRequest;
- }
-}
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+Copyright 2000 VA Linux Systems, Inc.
+Copyright (c) 2002, 2009 Apple Computer, 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, sub license, 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 (including the
+next paragraph) 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 NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Kevin E. Martin <martin@valinux.com>
+ * Jens Owen <jens@valinux.com>
+ * Rickard E. (Rik) Faith <faith@valinux.com>
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+#define _APPLEDRI_SERVER_
+#include "appledristr.h"
+#include "swaprep.h"
+#include "dri.h"
+#include "dristruct.h"
+#include "xpr.h"
+#include "x-hash.h"
+#include "protocol-versions.h"
+
+static int DRIErrorBase = 0;
+
+static DISPATCH_PROC(ProcAppleDRIDispatch);
+static DISPATCH_PROC(SProcAppleDRIDispatch);
+
+static void AppleDRIResetProc(ExtensionEntry* extEntry);
+static int ProcAppleDRICreatePixmap(ClientPtr client);
+
+static unsigned char DRIReqCode = 0;
+static int DRIEventBase = 0;
+
+static void SNotifyEvent(xAppleDRINotifyEvent *from, xAppleDRINotifyEvent *to);
+
+typedef struct _DRIEvent *DRIEventPtr;
+typedef struct _DRIEvent {
+ DRIEventPtr next;
+ ClientPtr client;
+ XID clientResource;
+ unsigned int mask;
+} DRIEventRec;
+
+
+void
+AppleDRIExtensionInit(void)
+{
+ ExtensionEntry* extEntry;
+
+ if (DRIExtensionInit() &&
+ (extEntry = AddExtension(APPLEDRINAME,
+ AppleDRINumberEvents,
+ AppleDRINumberErrors,
+ ProcAppleDRIDispatch,
+ SProcAppleDRIDispatch,
+ AppleDRIResetProc,
+ StandardMinorOpcode))) {
+ DRIReqCode = (unsigned char)extEntry->base;
+ DRIErrorBase = extEntry->errorBase;
+ DRIEventBase = extEntry->eventBase;
+ EventSwapVector[DRIEventBase] = (EventSwapPtr) SNotifyEvent;
+ }
+}
+
+/*ARGSUSED*/
+static void
+AppleDRIResetProc (
+ ExtensionEntry* extEntry
+)
+{
+ DRIReset();
+}
+
+static int
+ProcAppleDRIQueryVersion(
+ register ClientPtr client
+)
+{
+ xAppleDRIQueryVersionReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH(xAppleDRIQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = SERVER_APPLEDRI_MAJOR_VERSION;
+ rep.minorVersion = SERVER_APPLEDRI_MINOR_VERSION;
+ rep.patchVersion = SERVER_APPLEDRI_PATCH_VERSION;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ }
+ WriteToClient(client, sizeof(xAppleDRIQueryVersionReply), (char *)&rep);
+ return Success;
+}
+
+
+/* surfaces */
+
+static int
+ProcAppleDRIQueryDirectRenderingCapable(
+ register ClientPtr client
+)
+{
+ xAppleDRIQueryDirectRenderingCapableReply rep;
+ Bool isCapable;
+
+ REQUEST(xAppleDRIQueryDirectRenderingCapableReq);
+ REQUEST_SIZE_MATCH(xAppleDRIQueryDirectRenderingCapableReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ if (!DRIQueryDirectRenderingCapable( screenInfo.screens[stuff->screen],
+ &isCapable)) {
+ return BadValue;
+ }
+ rep.isCapable = isCapable;
+
+ if (!LocalClient(client))
+ rep.isCapable = 0;
+
+ WriteToClient(client,
+ sizeof(xAppleDRIQueryDirectRenderingCapableReply), (char *)&rep);
+ return Success;
+}
+
+static int
+ProcAppleDRIAuthConnection(
+ register ClientPtr client
+)
+{
+ xAppleDRIAuthConnectionReply rep;
+
+ REQUEST(xAppleDRIAuthConnectionReq);
+ REQUEST_SIZE_MATCH(xAppleDRIAuthConnectionReq);
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.authenticated = 1;
+
+ if (!DRIAuthConnection( screenInfo.screens[stuff->screen], stuff->magic)) {
+ ErrorF("Failed to authenticate %u\n", (unsigned int)stuff->magic);
+ rep.authenticated = 0;
+ }
+ WriteToClient(client, sizeof(xAppleDRIAuthConnectionReply), (char *)&rep);
+ return Success;
+}
+
+static void surface_notify(
+ void *_arg,
+ void *data
+)
+{
+ DRISurfaceNotifyArg *arg = _arg;
+ int client_index = (int) x_cvt_vptr_to_uint(data);
+ ClientPtr client;
+ xAppleDRINotifyEvent se;
+
+ if (client_index < 0 || client_index >= currentMaxClients)
+ return;
+
+ client = clients[client_index];
+ if (client == NULL || client == serverClient || client->clientGone)
+ return;
+
+ se.type = DRIEventBase + AppleDRISurfaceNotify;
+ se.kind = arg->kind;
+ se.arg = arg->id;
+ se.sequenceNumber = client->sequence;
+ se.time = currentTime.milliseconds;
+ WriteEventsToClient (client, 1, (xEvent *) &se);
+}
+
+static int
+ProcAppleDRICreateSurface(
+ ClientPtr client
+)
+{
+ xAppleDRICreateSurfaceReply rep;
+ DrawablePtr pDrawable;
+ xp_surface_id sid;
+ unsigned int key[2];
+ int rc;
+
+ REQUEST(xAppleDRICreateSurfaceReq);
+ REQUEST_SIZE_MATCH(xAppleDRICreateSurfaceReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
+ DixReadAccess);
+ if (rc != Success)
+ return rc;
+
+ rep.key_0 = rep.key_1 = rep.uid = 0;
+
+ if (!DRICreateSurface( screenInfo.screens[stuff->screen],
+ (Drawable)stuff->drawable, pDrawable,
+ stuff->client_id, &sid, key,
+ surface_notify,
+ x_cvt_uint_to_vptr(client->index))) {
+ return BadValue;
+ }
+
+ rep.key_0 = key[0];
+ rep.key_1 = key[1];
+ rep.uid = sid;
+
+ WriteToClient(client, sizeof(xAppleDRICreateSurfaceReply), (char *)&rep);
+ return Success;
+}
+
+static int
+ProcAppleDRIDestroySurface(
+ register ClientPtr client
+)
+{
+ int rc;
+ REQUEST(xAppleDRIDestroySurfaceReq);
+ DrawablePtr pDrawable;
+ REQUEST_SIZE_MATCH(xAppleDRIDestroySurfaceReq);
+
+ rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
+ DixReadAccess);
+ if (rc != Success)
+ return rc;
+
+ if (!DRIDestroySurface( screenInfo.screens[stuff->screen],
+ (Drawable)stuff->drawable,
+ pDrawable, NULL, NULL)) {
+ return BadValue;
+ }
+
+ return Success;
+}
+
+static int
+ProcAppleDRICreatePixmap(ClientPtr client)
+{
+ REQUEST(xAppleDRICreatePixmapReq);
+ DrawablePtr pDrawable;
+ int rc;
+ char path[PATH_MAX];
+ xAppleDRICreatePixmapReply rep;
+ int width, height, pitch, bpp;
+ void *ptr;
+
+ REQUEST_SIZE_MATCH(xAppleDRICreatePixmapReq);
+
+ rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
+ DixReadAccess);
+
+ if(rc != Success)
+ return rc;
+
+ if(!DRICreatePixmap(screenInfo.screens[stuff->screen],
+ (Drawable)stuff->drawable,
+ pDrawable,
+ path, PATH_MAX)) {
+ return BadValue;
+ }
+
+ if(!DRIGetPixmapData(pDrawable, &width, &height,
+ &pitch, &bpp, &ptr)) {
+ return BadValue;
+ }
+
+ rep.stringLength = strlen(path) + 1;
+
+ /* No need for swapping, because this only runs if LocalClient is true. */
+ rep.type = X_Reply;
+ rep.length = sizeof(rep) + rep.stringLength;
+ rep.sequenceNumber = client->sequence;
+ rep.width = width;
+ rep.height = height;
+ rep.pitch = pitch;
+ rep.bpp = bpp;
+ rep.size = pitch * height;
+
+ if(sizeof(rep) != sz_xAppleDRICreatePixmapReply)
+ ErrorF("error sizeof(rep) is %zu\n", sizeof(rep));
+
+ WriteReplyToClient(client, sizeof(rep), &rep);
+ (void)WriteToClient(client, rep.stringLength, path);
+
+ return Success;
+}
+
+static int
+ProcAppleDRIDestroyPixmap(ClientPtr client)
+{
+ DrawablePtr pDrawable;
+ int rc;
+ REQUEST(xAppleDRIDestroyPixmapReq);
+ REQUEST_SIZE_MATCH(xAppleDRIDestroyPixmapReq);
+
+ rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
+ DixReadAccess);
+
+ if(rc != Success)
+ return rc;
+
+ DRIDestroyPixmap(pDrawable);
+
+ return Success;
+}
+
+/* dispatch */
+
+static int
+ProcAppleDRIDispatch (
+ register ClientPtr client
+)
+{
+ REQUEST(xReq);
+
+ switch (stuff->data)
+ {
+ case X_AppleDRIQueryVersion:
+ return ProcAppleDRIQueryVersion(client);
+ case X_AppleDRIQueryDirectRenderingCapable:
+ return ProcAppleDRIQueryDirectRenderingCapable(client);
+ }
+
+ if (!LocalClient(client))
+ return DRIErrorBase + AppleDRIClientNotLocal;
+
+ switch (stuff->data)
+ {
+ case X_AppleDRIAuthConnection:
+ return ProcAppleDRIAuthConnection(client);
+ case X_AppleDRICreateSurface:
+ return ProcAppleDRICreateSurface(client);
+ case X_AppleDRIDestroySurface:
+ return ProcAppleDRIDestroySurface(client);
+ case X_AppleDRICreatePixmap:
+ return ProcAppleDRICreatePixmap(client);
+ case X_AppleDRIDestroyPixmap:
+ return ProcAppleDRIDestroyPixmap(client);
+
+ default:
+ return BadRequest;
+ }
+}
+
+static void
+SNotifyEvent(
+ xAppleDRINotifyEvent *from,
+ xAppleDRINotifyEvent *to
+)
+{
+ to->type = from->type;
+ to->kind = from->kind;
+ cpswaps (from->sequenceNumber, to->sequenceNumber);
+ cpswapl (from->time, to->time);
+ cpswapl (from->arg, to->arg);
+}
+
+static int
+SProcAppleDRIQueryVersion(
+ register ClientPtr client
+)
+{
+ register int n;
+ REQUEST(xAppleDRIQueryVersionReq);
+ swaps(&stuff->length, n);
+ return ProcAppleDRIQueryVersion(client);
+}
+
+static int
+SProcAppleDRIDispatch (
+ register ClientPtr client
+)
+{
+ REQUEST(xReq);
+
+ /* It is bound to be non-local when there is byte swapping */
+ if (!LocalClient(client))
+ return DRIErrorBase + AppleDRIClientNotLocal;
+
+ /* only local clients are allowed DRI access */
+ switch (stuff->data)
+ {
+ case X_AppleDRIQueryVersion:
+ return SProcAppleDRIQueryVersion(client);
+ default:
+ return BadRequest;
+ }
+}
diff --git a/xorg-server/hw/xquartz/xpr/dri.c b/xorg-server/hw/xquartz/xpr/dri.c
index 0a58b29f3..363809d0d 100644
--- a/xorg-server/hw/xquartz/xpr/dri.c
+++ b/xorg-server/hw/xquartz/xpr/dri.c
@@ -1,953 +1,953 @@
-/**************************************************************************
-
-Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
-Copyright 2000 VA Linux Systems, Inc.
-Copyright (c) 2002, 2009 Apple Computer, 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, sub license, 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 (including the
-next paragraph) 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 NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
-
-**************************************************************************/
-
-/*
- * Authors:
- * Jens Owen <jens@valinux.com>
- * Rickard E. (Rik) Faith <faith@valinux.com>
- *
- */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#ifdef XFree86LOADER
-#include "xf86.h"
-#include "xf86_ansic.h"
-#else
-#include <sys/time.h>
-#include <unistd.h>
-#endif
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include "misc.h"
-#include "dixstruct.h"
-#include "extnsionst.h"
-#include "colormapst.h"
-#include "cursorstr.h"
-#include "scrnintstr.h"
-#include "windowstr.h"
-#include "servermd.h"
-#define _APPLEDRI_SERVER_
-#include "appledristr.h"
-#include "swaprep.h"
-#include "dri.h"
-#include "dristruct.h"
-#include "mi.h"
-#include "mipointer.h"
-#include "rootless.h"
-#include "x-hash.h"
-#include "x-hook.h"
-#include "driWrap.h"
-
-#include <AvailabilityMacros.h>
-
-static int DRIScreenPrivKeyIndex;
-static DevPrivateKey DRIScreenPrivKey = &DRIScreenPrivKeyIndex;
-static int DRIWindowPrivKeyIndex;
-static DevPrivateKey DRIWindowPrivKey = &DRIWindowPrivKeyIndex;
-static int DRIPixmapPrivKeyIndex;
-static DevPrivateKey DRIPixmapPrivKey = &DRIPixmapPrivKeyIndex;
-static int DRIPixmapBufferPrivKeyIndex;
-static DevPrivateKey DRIPixmapBufferPrivKey = &DRIPixmapBufferPrivKeyIndex;
-
-static RESTYPE DRIDrawablePrivResType;
-
-static x_hash_table *surface_hash; /* maps surface ids -> drawablePrivs */
-
-static Bool DRIFreePixmapImp(DrawablePtr pDrawable);
-
-/* FIXME: don't hardcode this? */
-#define CG_INFO_FILE "/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Resources/Info-macos.plist"
-
-/* Corresponds to SU Jaguar Green */
-#define CG_REQUIRED_MAJOR 1
-#define CG_REQUIRED_MINOR 157
-#define CG_REQUIRED_MICRO 11
-
-typedef struct {
- DrawablePtr pDrawable;
- int refCount;
- int bytesPerPixel;
- int width;
- int height;
- char shmPath[PATH_MAX];
- int fd; /* From shm_open (for now) */
- size_t length; /* length of buffer */
- void *buffer;
-} DRIPixmapBuffer, *DRIPixmapBufferPtr;
-
-/* Returns version as major.minor.micro in 10.10.10 fixed form */
-static unsigned int
-get_cg_version (void)
-{
- static unsigned int version;
-
- FILE *fh;
- char *ptr;
-
- if (version != 0)
- return version;
-
- /* I tried CFBundleGetVersion, but it returns zero, so.. */
-
- fh = fopen (CG_INFO_FILE, "r");
- if (fh != NULL)
- {
- char buf[256];
-
- while (fgets (buf, sizeof (buf), fh) != NULL)
- {
- unsigned char c;
-
- if (!strstr (buf, "<key>CFBundleShortVersionString</key>")
- || fgets (buf, sizeof (buf), fh) == NULL)
- {
- continue;
- }
-
- ptr = strstr (buf, "<string>");
- if (ptr == NULL)
- continue;
-
- ptr += strlen ("<string>");
-
- /* Now PTR points to "MAJOR.MINOR.MICRO". */
-
- version = 0;
-
- again:
- switch ((c = *ptr++))
- {
- case '.':
- version = version * 1024;
- goto again;
-
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- version = ((version & ~0x3ff)
- + (version & 0x3ff) * 10 + (c - '0'));
- goto again;
- }
- break;
- }
-
- fclose (fh);
- }
-
- return version;
-}
-
-static Bool
-test_cg_version (unsigned int major, unsigned int minor, unsigned int micro)
-{
- unsigned int cg_ver = get_cg_version ();
-
- unsigned int cg_major = (cg_ver >> 20) & 0x3ff;
- unsigned int cg_minor = (cg_ver >> 10) & 0x3ff;
- unsigned int cg_micro = cg_ver & 0x3ff;
-
- if (cg_major > major)
- return TRUE;
- else if (cg_major < major)
- return FALSE;
-
- /* cg_major == major */
-
- if (cg_minor > minor)
- return TRUE;
- else if (cg_minor < minor)
- return FALSE;
-
- /* cg_minor == minor */
-
- if (cg_micro < micro)
- return FALSE;
-
- return TRUE;
-}
-
-Bool
-DRIScreenInit(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv;
- int i;
-
- pDRIPriv = (DRIScreenPrivPtr) xcalloc(1, sizeof(DRIScreenPrivRec));
- if (!pDRIPriv) {
- dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL);
- return FALSE;
- }
-
- dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, pDRIPriv);
- pDRIPriv->directRenderingSupport = TRUE;
- pDRIPriv->nrWindows = 0;
-
- /* Need recent cg for window access update */
- if (!test_cg_version (CG_REQUIRED_MAJOR,
- CG_REQUIRED_MINOR,
- CG_REQUIRED_MICRO))
- {
- ErrorF ("[DRI] disabled direct rendering; requires CoreGraphics %d.%d.%d\n",
- CG_REQUIRED_MAJOR, CG_REQUIRED_MINOR, CG_REQUIRED_MICRO);
-
- pDRIPriv->directRenderingSupport = FALSE;
-
- /* Note we don't nuke the dri private, since we need it for
- managing indirect surfaces. */
- }
-
- /* Initialize drawable tables */
- for (i = 0; i < DRI_MAX_DRAWABLES; i++) {
- pDRIPriv->DRIDrawables[i] = NULL;
- }
-
- return TRUE;
-}
-
-Bool
-DRIFinishScreenInit(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- /* Wrap DRI support */
- pDRIPriv->wrap.ValidateTree = pScreen->ValidateTree;
- pScreen->ValidateTree = DRIValidateTree;
-
- pDRIPriv->wrap.PostValidateTree = pScreen->PostValidateTree;
- pScreen->PostValidateTree = DRIPostValidateTree;
-
- pDRIPriv->wrap.WindowExposures = pScreen->WindowExposures;
- pScreen->WindowExposures = DRIWindowExposures;
-
- pDRIPriv->wrap.CopyWindow = pScreen->CopyWindow;
- pScreen->CopyWindow = DRICopyWindow;
-
- pDRIPriv->wrap.ClipNotify = pScreen->ClipNotify;
- pScreen->ClipNotify = DRIClipNotify;
-
- // ErrorF("[DRI] screen %d installation complete\n", pScreen->myNum);
-
- return DRIWrapInit(pScreen);
-}
-
-void
-DRICloseScreen(ScreenPtr pScreen)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if (pDRIPriv && pDRIPriv->directRenderingSupport) {
- xfree(pDRIPriv);
- dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL);
- }
-}
-
-Bool
-DRIExtensionInit(void)
-{
- DRIDrawablePrivResType = CreateNewResourceType(DRIDrawablePrivDelete,
- "DRIDrawable");
-
- return (DRIDrawablePrivResType != 0);
-}
-
-void
-DRIReset(void)
-{
- /*
- * This stub routine is called when the X Server recycles, resources
- * allocated by DRIExtensionInit need to be managed here.
- *
- * Currently this routine is a stub because all the interesting resources
- * are managed via the screen init process.
- */
-}
-
-Bool
-DRIQueryDirectRenderingCapable(ScreenPtr pScreen, Bool* isCapable)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if (pDRIPriv)
- *isCapable = pDRIPriv->directRenderingSupport;
- else
- *isCapable = FALSE;
-
- return TRUE;
-}
-
-Bool
-DRIAuthConnection(ScreenPtr pScreen, unsigned int magic)
-{
-#if 0
- /* FIXME: something? */
-
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if (drmAuthMagic(pDRIPriv->drmFD, magic)) return FALSE;
-#endif
- return TRUE;
-}
-
-static void
-DRIUpdateSurface(DRIDrawablePrivPtr pDRIDrawablePriv, DrawablePtr pDraw)
-{
- xp_window_changes wc;
- unsigned int flags = 0;
-
- if (pDRIDrawablePriv->sid == 0)
- return;
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
- wc.depth = (pDraw->bitsPerPixel == 32 ? XP_DEPTH_ARGB8888
- : pDraw->bitsPerPixel == 16 ? XP_DEPTH_RGB555 : XP_DEPTH_NIL);
- if (wc.depth != XP_DEPTH_NIL)
- flags |= XP_DEPTH;
-#endif
-
- if (pDraw->type == DRAWABLE_WINDOW) {
- WindowPtr pWin = (WindowPtr) pDraw;
- WindowPtr pTopWin = TopLevelParent(pWin);
-
- wc.x = pWin->drawable.x - (pTopWin->drawable.x - pTopWin->borderWidth);
- wc.y = pWin->drawable.y - (pTopWin->drawable.y - pTopWin->borderWidth);
- wc.width = pWin->drawable.width + 2 * pWin->borderWidth;
- wc.height = pWin->drawable.height + 2 * pWin->borderWidth;
- wc.bit_gravity = XP_GRAVITY_NONE;
-
- wc.shape_nrects = REGION_NUM_RECTS(&pWin->clipList);
- wc.shape_rects = REGION_RECTS(&pWin->clipList);
- wc.shape_tx = - (pTopWin->drawable.x - pTopWin->borderWidth);
- wc.shape_ty = - (pTopWin->drawable.y - pTopWin->borderWidth);
-
- flags |= XP_BOUNDS | XP_SHAPE;
-
- } else if (pDraw->type == DRAWABLE_PIXMAP) {
- wc.x = 0;
- wc.y = 0;
- wc.width = pDraw->width;
- wc.height = pDraw->height;
- wc.bit_gravity = XP_GRAVITY_NONE;
- flags |= XP_BOUNDS;
- }
-
- xp_configure_surface(pDRIDrawablePriv->sid, flags, &wc);
-}
-
-/* Return NULL if an error occurs. */
-static DRIDrawablePrivPtr
-CreateSurfaceForWindow(ScreenPtr pScreen, WindowPtr pWin, xp_window_id *widPtr) {
- DRIDrawablePrivPtr pDRIDrawablePriv;
- xp_window_id wid = 0;
-
- *widPtr = 0;
-
- pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
-
- if (pDRIDrawablePriv == NULL) {
- xp_error err;
- xp_window_changes wc;
-
- /* allocate a DRI Window Private record */
- if (!(pDRIDrawablePriv = xalloc(sizeof(*pDRIDrawablePriv)))) {
- return NULL;
- }
-
- pDRIDrawablePriv->pDraw = (DrawablePtr)pWin;
- pDRIDrawablePriv->pScreen = pScreen;
- pDRIDrawablePriv->refCount = 0;
- pDRIDrawablePriv->drawableIndex = -1;
- pDRIDrawablePriv->notifiers = NULL;
-
- /* find the physical window */
- wid = x_cvt_vptr_to_uint(RootlessFrameForWindow(pWin, TRUE));
-
- if (wid == 0) {
- xfree(pDRIDrawablePriv);
- return NULL;
- }
-
- /* allocate the physical surface */
- err = xp_create_surface(wid, &pDRIDrawablePriv->sid);
-
- if (err != Success) {
- xfree(pDRIDrawablePriv);
- return NULL;
- }
-
- /* Make it visible */
- wc.stack_mode = XP_MAPPED_ABOVE;
- wc.sibling = 0;
- err = xp_configure_surface(pDRIDrawablePriv->sid, XP_STACKING, &wc);
-
- if (err != Success) {
- xp_destroy_surface(pDRIDrawablePriv->sid);
- xfree(pDRIDrawablePriv);
- return NULL;
- }
-
- /* save private off of preallocated index */
- dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey,
- pDRIDrawablePriv);
- }
-
- *widPtr = wid;
-
- return pDRIDrawablePriv;
-}
-
-/* Return NULL if an error occurs. */
-static DRIDrawablePrivPtr
-CreateSurfaceForPixmap(ScreenPtr pScreen, PixmapPtr pPix) {
- DRIDrawablePrivPtr pDRIDrawablePriv;
-
- pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPix);
-
- if (pDRIDrawablePriv == NULL) {
- xp_error err;
-
- /* allocate a DRI Window Private record */
- if (!(pDRIDrawablePriv = xcalloc(1, sizeof(*pDRIDrawablePriv)))) {
- return NULL;
- }
-
- pDRIDrawablePriv->pDraw = (DrawablePtr)pPix;
- pDRIDrawablePriv->pScreen = pScreen;
- pDRIDrawablePriv->refCount = 0;
- pDRIDrawablePriv->drawableIndex = -1;
- pDRIDrawablePriv->notifiers = NULL;
-
- /* Passing a null window id to Xplugin in 10.3+ asks for
- an accelerated offscreen surface. */
-
- err = xp_create_surface(0, &pDRIDrawablePriv->sid);
- if (err != Success) {
- xfree(pDRIDrawablePriv);
- return NULL;
- }
-
- /*
- * The DRIUpdateSurface will be called to resize the surface
- * after this function, if the export is successful.
- */
-
- /* save private off of preallocated index */
- dixSetPrivate(&pPix->devPrivates, DRIPixmapPrivKey,
- pDRIDrawablePriv);
- }
-
- return pDRIDrawablePriv;
-}
-
-
-Bool
-DRICreateSurface(ScreenPtr pScreen, Drawable id,
- DrawablePtr pDrawable, xp_client_id client_id,
- xp_surface_id *surface_id, unsigned int ret_key[2],
- void (*notify) (void *arg, void *data), void *notify_data)
-{
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- xp_window_id wid = 0;
- DRIDrawablePrivPtr pDRIDrawablePriv;
-
- if (pDrawable->type == DRAWABLE_WINDOW) {
- pDRIDrawablePriv = CreateSurfaceForWindow(pScreen,
- (WindowPtr)pDrawable, &wid);
-
- if(NULL == pDRIDrawablePriv)
- return FALSE; /*error*/
- }
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
- else if (pDrawable->type == DRAWABLE_PIXMAP) {
- pDRIDrawablePriv = CreateSurfaceForPixmap(pScreen,
- (PixmapPtr)pDrawable);
-
- if(NULL == pDRIDrawablePriv)
- return FALSE; /*error*/
- }
-#endif
- else { /* for GLX 1.3, a PBuffer */
- /* NOT_DONE */
- return FALSE;
- }
-
-
- /* Finish initialization of new surfaces */
- if (pDRIDrawablePriv->refCount == 0) {
- unsigned int key[2] = {0};
- xp_error err;
-
- /* try to give the client access to the surface */
- if (client_id != 0) {
- /*
- * Xplugin accepts a 0 wid if the surface id is offscreen, such
- * as for a pixmap.
- */
- err = xp_export_surface(wid, pDRIDrawablePriv->sid,
- client_id, key);
- if (err != Success) {
- xp_destroy_surface(pDRIDrawablePriv->sid);
- xfree(pDRIDrawablePriv);
-
- /*
- * Now set the dix privates to NULL that were previously set.
- * This prevents reusing an invalid pointer.
- */
- if(pDrawable->type == DRAWABLE_WINDOW) {
- WindowPtr pWin = (WindowPtr)pDrawable;
-
- dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey, NULL);
- } else if(pDrawable->type == DRAWABLE_PIXMAP) {
- PixmapPtr pPix = (PixmapPtr)pDrawable;
-
- dixSetPrivate(&pPix->devPrivates, DRIPixmapPrivKey, NULL);
- }
-
- return FALSE;
- }
- }
-
- pDRIDrawablePriv->key[0] = key[0];
- pDRIDrawablePriv->key[1] = key[1];
-
- ++pDRIPriv->nrWindows;
-
- /* and stash it by surface id */
- if (surface_hash == NULL)
- surface_hash = x_hash_table_new(NULL, NULL, NULL, NULL);
- x_hash_table_insert(surface_hash,
- x_cvt_uint_to_vptr(pDRIDrawablePriv->sid), pDRIDrawablePriv);
-
- /* track this in case this window is destroyed */
- AddResource(id, DRIDrawablePrivResType, (pointer)pDrawable);
-
- /* Initialize shape */
- DRIUpdateSurface(pDRIDrawablePriv, pDrawable);
- }
-
- pDRIDrawablePriv->refCount++;
-
- *surface_id = pDRIDrawablePriv->sid;
-
- if (ret_key != NULL) {
- ret_key[0] = pDRIDrawablePriv->key[0];
- ret_key[1] = pDRIDrawablePriv->key[1];
- }
-
- if (notify != NULL) {
- pDRIDrawablePriv->notifiers = x_hook_add(pDRIDrawablePriv->notifiers,
- notify, notify_data);
- }
-
- return TRUE;
-}
-
-Bool
-DRIDestroySurface(ScreenPtr pScreen, Drawable id, DrawablePtr pDrawable,
- void (*notify) (void *, void *), void *notify_data)
-{
- DRIDrawablePrivPtr pDRIDrawablePriv;
-
- if (pDrawable->type == DRAWABLE_WINDOW) {
- pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW((WindowPtr)pDrawable);
- } else if (pDrawable->type == DRAWABLE_PIXMAP) {
- pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP((PixmapPtr)pDrawable);
- } else {
- return FALSE;
- }
-
- if (pDRIDrawablePriv != NULL) {
- if (notify != NULL) {
- pDRIDrawablePriv->notifiers = x_hook_remove(pDRIDrawablePriv->notifiers,
- notify, notify_data);
- }
- if (--pDRIDrawablePriv->refCount <= 0) {
- /* This calls back to DRIDrawablePrivDelete
- which frees the private area */
- FreeResourceByType(id, DRIDrawablePrivResType, FALSE);
- }
- }
-
- return TRUE;
-}
-
-Bool
-DRIDrawablePrivDelete(pointer pResource, XID id)
-{
- DrawablePtr pDrawable = (DrawablePtr)pResource;
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pDrawable->pScreen);
- DRIDrawablePrivPtr pDRIDrawablePriv = NULL;
- WindowPtr pWin = NULL;
- PixmapPtr pPix = NULL;
-
- if (pDrawable->type == DRAWABLE_WINDOW) {
- pWin = (WindowPtr)pDrawable;
- pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
- } else if (pDrawable->type == DRAWABLE_PIXMAP) {
- pPix = (PixmapPtr)pDrawable;
- pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPix);
- }
-
- if (pDRIDrawablePriv == NULL) {
- return DRIFreePixmapImp(pDrawable);
- }
-
- if (pDRIDrawablePriv->drawableIndex != -1) {
- /* release drawable table entry */
- pDRIPriv->DRIDrawables[pDRIDrawablePriv->drawableIndex] = NULL;
- }
-
- if (pDRIDrawablePriv->sid != 0) {
- xp_destroy_surface(pDRIDrawablePriv->sid);
- x_hash_table_remove(surface_hash, x_cvt_uint_to_vptr(pDRIDrawablePriv->sid));
- }
-
- if (pDRIDrawablePriv->notifiers != NULL)
- x_hook_free(pDRIDrawablePriv->notifiers);
-
- xfree(pDRIDrawablePriv);
-
- if (pDrawable->type == DRAWABLE_WINDOW) {
- dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey, NULL);
- } else if (pDrawable->type == DRAWABLE_PIXMAP) {
- dixSetPrivate(&pPix->devPrivates, DRIPixmapPrivKey, NULL);
- }
-
- --pDRIPriv->nrWindows;
-
- return TRUE;
-}
-
-void
-DRIWindowExposures(WindowPtr pWin, RegionPtr prgn, RegionPtr bsreg)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
-
- if (pDRIDrawablePriv) {
- /* FIXME: something? */
- }
-
- pScreen->WindowExposures = pDRIPriv->wrap.WindowExposures;
-
- (*pScreen->WindowExposures)(pWin, prgn, bsreg);
-
- pDRIPriv->wrap.WindowExposures = pScreen->WindowExposures;
- pScreen->WindowExposures = DRIWindowExposures;
-}
-
-void
-DRICopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIDrawablePrivPtr pDRIDrawablePriv;
-
- if (pDRIPriv->nrWindows > 0) {
- pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
- if (pDRIDrawablePriv != NULL) {
- DRIUpdateSurface(pDRIDrawablePriv, &pWin->drawable);
- }
- }
-
- /* unwrap */
- pScreen->CopyWindow = pDRIPriv->wrap.CopyWindow;
-
- /* call lower layers */
- (*pScreen->CopyWindow)(pWin, ptOldOrg, prgnSrc);
-
- /* rewrap */
- pDRIPriv->wrap.CopyWindow = pScreen->CopyWindow;
- pScreen->CopyWindow = DRICopyWindow;
-}
-
-int
-DRIValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind)
-{
- ScreenPtr pScreen = pParent->drawable.pScreen;
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- int returnValue;
-
- /* unwrap */
- pScreen->ValidateTree = pDRIPriv->wrap.ValidateTree;
-
- /* call lower layers */
- returnValue = (*pScreen->ValidateTree)(pParent, pChild, kind);
-
- /* rewrap */
- pDRIPriv->wrap.ValidateTree = pScreen->ValidateTree;
- pScreen->ValidateTree = DRIValidateTree;
-
- return returnValue;
-}
-
-void
-DRIPostValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind)
-{
- ScreenPtr pScreen;
- DRIScreenPrivPtr pDRIPriv;
-
- if (pParent) {
- pScreen = pParent->drawable.pScreen;
- } else {
- pScreen = pChild->drawable.pScreen;
- }
- pDRIPriv = DRI_SCREEN_PRIV(pScreen);
-
- if (pDRIPriv->wrap.PostValidateTree) {
- /* unwrap */
- pScreen->PostValidateTree = pDRIPriv->wrap.PostValidateTree;
-
- /* call lower layers */
- (*pScreen->PostValidateTree)(pParent, pChild, kind);
-
- /* rewrap */
- pDRIPriv->wrap.PostValidateTree = pScreen->PostValidateTree;
- pScreen->PostValidateTree = DRIPostValidateTree;
- }
-}
-
-void
-DRIClipNotify(WindowPtr pWin, int dx, int dy)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
- DRIDrawablePrivPtr pDRIDrawablePriv;
-
- if ((pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin))) {
- DRIUpdateSurface(pDRIDrawablePriv, &pWin->drawable);
- }
-
- if (pDRIPriv->wrap.ClipNotify) {
- pScreen->ClipNotify = pDRIPriv->wrap.ClipNotify;
-
- (*pScreen->ClipNotify)(pWin, dx, dy);
-
- pDRIPriv->wrap.ClipNotify = pScreen->ClipNotify;
- pScreen->ClipNotify = DRIClipNotify;
- }
-}
-
-/* This lets us get at the unwrapped functions so that they can correctly
- * call the lower level functions, and choose whether they will be
- * called at every level of recursion (eg in validatetree).
- */
-DRIWrappedFuncsRec *
-DRIGetWrappedFuncs(ScreenPtr pScreen)
-{
- return &(DRI_SCREEN_PRIV(pScreen)->wrap);
-}
-
-void
-DRIQueryVersion(int *majorVersion,
- int *minorVersion,
- int *patchVersion)
-{
- *majorVersion = APPLE_DRI_MAJOR_VERSION;
- *minorVersion = APPLE_DRI_MINOR_VERSION;
- *patchVersion = APPLE_DRI_PATCH_VERSION;
-}
-
-void
-DRISurfaceNotify(xp_surface_id id, int kind)
-{
- DRIDrawablePrivPtr pDRIDrawablePriv = NULL;
- DRISurfaceNotifyArg arg;
-
- arg.id = id;
- arg.kind = kind;
-
- if (surface_hash != NULL)
- {
- pDRIDrawablePriv = x_hash_table_lookup(surface_hash,
- x_cvt_uint_to_vptr(id), NULL);
- }
-
- if (pDRIDrawablePriv == NULL)
- return;
-
- if (kind == AppleDRISurfaceNotifyDestroyed)
- {
- pDRIDrawablePriv->sid = 0;
- x_hash_table_remove(surface_hash, x_cvt_uint_to_vptr(id));
- }
-
- x_hook_run(pDRIDrawablePriv->notifiers, &arg);
-
- if (kind == AppleDRISurfaceNotifyDestroyed)
- {
- /* Kill off the handle. */
-
- FreeResourceByType(pDRIDrawablePriv->pDraw->id,
- DRIDrawablePrivResType, FALSE);
- }
-}
-
-Bool DRICreatePixmap(ScreenPtr pScreen, Drawable id,
- DrawablePtr pDrawable, char *path,
- size_t pathmax)
-{
- DRIPixmapBufferPtr shared;
- PixmapPtr pPix;
-
- if(pDrawable->type != DRAWABLE_PIXMAP)
- return FALSE;
-
- pPix = (PixmapPtr)pDrawable;
-
- shared = xalloc(sizeof(*shared));
- if(NULL == shared) {
- FatalError("failed to allocate DRIPixmapBuffer in %s\n", __func__);
- }
-
- shared->pDrawable = pDrawable;
- shared->refCount = 1;
-
- if(pDrawable->bitsPerPixel >= 24) {
- shared->bytesPerPixel = 4;
- } else if(pDrawable->bitsPerPixel <= 16) {
- shared->bytesPerPixel = 2;
- }
-
- shared->width = pDrawable->width;
- shared->height = pDrawable->height;
-
- if(-1 == snprintf(shared->shmPath, sizeof(shared->shmPath),
- "%d_0x%lx", getpid(),
- (unsigned long)id)) {
- FatalError("buffer overflow in %s\n", __func__);
- }
-
- shared->fd = shm_open(shared->shmPath,
- O_RDWR | O_EXCL | O_CREAT,
- S_IRUSR | S_IWUSR | S_IROTH | S_IWOTH);
-
- if(-1 == shared->fd) {
- xfree(shared);
- return FALSE;
- }
-
- shared->length = shared->width * shared->height * shared->bytesPerPixel;
-
- if(-1 == ftruncate(shared->fd, shared->length)) {
- ErrorF("failed to ftruncate (extend) file.");
- shm_unlink(shared->shmPath);
- close(shared->fd);
- xfree(shared);
- return FALSE;
- }
-
- shared->buffer = mmap(NULL, shared->length,
- PROT_READ | PROT_WRITE,
- MAP_FILE | MAP_SHARED, shared->fd, 0);
-
- if(MAP_FAILED == shared->buffer) {
- ErrorF("failed to mmap shared memory.");
- shm_unlink(shared->shmPath);
- close(shared->fd);
- xfree(shared);
- return FALSE;
- }
-
- strncpy(path, shared->shmPath, pathmax);
- path[pathmax - 1] = '\0';
-
- dixSetPrivate(&pPix->devPrivates, DRIPixmapBufferPrivKey, shared);
-
- AddResource(id, DRIDrawablePrivResType, (pointer)pDrawable);
-
- return TRUE;
-}
-
-
-Bool DRIGetPixmapData(DrawablePtr pDrawable, int *width, int *height,
- int *pitch, int *bpp, void **ptr) {
- PixmapPtr pPix;
- DRIPixmapBufferPtr shared;
-
- if(pDrawable->type != DRAWABLE_PIXMAP)
- return FALSE;
-
- pPix = (PixmapPtr)pDrawable;
-
- shared = dixLookupPrivate(&pPix->devPrivates, DRIPixmapBufferPrivKey);
-
- if(NULL == shared)
- return FALSE;
-
- assert(pDrawable->width == shared->width);
- assert(pDrawable->height == shared->height);
-
- *width = shared->width;
- *height = shared->height;
- *bpp = shared->bytesPerPixel;
- *pitch = shared->width * shared->bytesPerPixel;
- *ptr = shared->buffer;
-
- return TRUE;
-}
-
-static Bool
-DRIFreePixmapImp(DrawablePtr pDrawable) {
- DRIPixmapBufferPtr shared;
- PixmapPtr pPix;
-
- if(pDrawable->type != DRAWABLE_PIXMAP)
- return FALSE;
-
- pPix = (PixmapPtr)pDrawable;
-
- shared = dixLookupPrivate(&pPix->devPrivates, DRIPixmapBufferPrivKey);
-
- if(NULL == shared)
- return FALSE;
-
- close(shared->fd);
- munmap(shared->buffer, shared->length);
- shm_unlink(shared->shmPath);
- xfree(shared);
-
- dixSetPrivate(&pPix->devPrivates, DRIPixmapBufferPrivKey, (pointer)NULL);
-
- return TRUE;
-}
-
-void
-DRIDestroyPixmap(DrawablePtr pDrawable) {
- if(DRIFreePixmapImp(pDrawable))
- FreeResourceByType(pDrawable->id, DRIDrawablePrivResType, FALSE);
-
-}
+/**************************************************************************
+
+Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+Copyright 2000 VA Linux Systems, Inc.
+Copyright (c) 2002, 2009 Apple Computer, 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, sub license, 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 (including the
+next paragraph) 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 NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS 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.
+
+**************************************************************************/
+
+/*
+ * Authors:
+ * Jens Owen <jens@valinux.com>
+ * Rickard E. (Rik) Faith <faith@valinux.com>
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifdef XFree86LOADER
+#include "xf86.h"
+#include "xf86_ansic.h"
+#else
+#include <sys/time.h>
+#include <unistd.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "misc.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "servermd.h"
+#define _APPLEDRI_SERVER_
+#include "appledristr.h"
+#include "swaprep.h"
+#include "dri.h"
+#include "dristruct.h"
+#include "mi.h"
+#include "mipointer.h"
+#include "rootless.h"
+#include "x-hash.h"
+#include "x-hook.h"
+#include "driWrap.h"
+
+#include <AvailabilityMacros.h>
+
+static int DRIScreenPrivKeyIndex;
+static DevPrivateKey DRIScreenPrivKey = &DRIScreenPrivKeyIndex;
+static int DRIWindowPrivKeyIndex;
+static DevPrivateKey DRIWindowPrivKey = &DRIWindowPrivKeyIndex;
+static int DRIPixmapPrivKeyIndex;
+static DevPrivateKey DRIPixmapPrivKey = &DRIPixmapPrivKeyIndex;
+static int DRIPixmapBufferPrivKeyIndex;
+static DevPrivateKey DRIPixmapBufferPrivKey = &DRIPixmapBufferPrivKeyIndex;
+
+static RESTYPE DRIDrawablePrivResType;
+
+static x_hash_table *surface_hash; /* maps surface ids -> drawablePrivs */
+
+static Bool DRIFreePixmapImp(DrawablePtr pDrawable);
+
+/* FIXME: don't hardcode this? */
+#define CG_INFO_FILE "/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreGraphics.framework/Resources/Info-macos.plist"
+
+/* Corresponds to SU Jaguar Green */
+#define CG_REQUIRED_MAJOR 1
+#define CG_REQUIRED_MINOR 157
+#define CG_REQUIRED_MICRO 11
+
+typedef struct {
+ DrawablePtr pDrawable;
+ int refCount;
+ int bytesPerPixel;
+ int width;
+ int height;
+ char shmPath[PATH_MAX];
+ int fd; /* From shm_open (for now) */
+ size_t length; /* length of buffer */
+ void *buffer;
+} DRIPixmapBuffer, *DRIPixmapBufferPtr;
+
+/* Returns version as major.minor.micro in 10.10.10 fixed form */
+static unsigned int
+get_cg_version (void)
+{
+ static unsigned int version;
+
+ FILE *fh;
+ char *ptr;
+
+ if (version != 0)
+ return version;
+
+ /* I tried CFBundleGetVersion, but it returns zero, so.. */
+
+ fh = fopen (CG_INFO_FILE, "r");
+ if (fh != NULL)
+ {
+ char buf[256];
+
+ while (fgets (buf, sizeof (buf), fh) != NULL)
+ {
+ unsigned char c;
+
+ if (!strstr (buf, "<key>CFBundleShortVersionString</key>")
+ || fgets (buf, sizeof (buf), fh) == NULL)
+ {
+ continue;
+ }
+
+ ptr = strstr (buf, "<string>");
+ if (ptr == NULL)
+ continue;
+
+ ptr += strlen ("<string>");
+
+ /* Now PTR points to "MAJOR.MINOR.MICRO". */
+
+ version = 0;
+
+ again:
+ switch ((c = *ptr++))
+ {
+ case '.':
+ version = version * 1024;
+ goto again;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ version = ((version & ~0x3ff)
+ + (version & 0x3ff) * 10 + (c - '0'));
+ goto again;
+ }
+ break;
+ }
+
+ fclose (fh);
+ }
+
+ return version;
+}
+
+static Bool
+test_cg_version (unsigned int major, unsigned int minor, unsigned int micro)
+{
+ unsigned int cg_ver = get_cg_version ();
+
+ unsigned int cg_major = (cg_ver >> 20) & 0x3ff;
+ unsigned int cg_minor = (cg_ver >> 10) & 0x3ff;
+ unsigned int cg_micro = cg_ver & 0x3ff;
+
+ if (cg_major > major)
+ return TRUE;
+ else if (cg_major < major)
+ return FALSE;
+
+ /* cg_major == major */
+
+ if (cg_minor > minor)
+ return TRUE;
+ else if (cg_minor < minor)
+ return FALSE;
+
+ /* cg_minor == minor */
+
+ if (cg_micro < micro)
+ return FALSE;
+
+ return TRUE;
+}
+
+Bool
+DRIScreenInit(ScreenPtr pScreen)
+{
+ DRIScreenPrivPtr pDRIPriv;
+ int i;
+
+ pDRIPriv = (DRIScreenPrivPtr) calloc(1, sizeof(DRIScreenPrivRec));
+ if (!pDRIPriv) {
+ dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL);
+ return FALSE;
+ }
+
+ dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, pDRIPriv);
+ pDRIPriv->directRenderingSupport = TRUE;
+ pDRIPriv->nrWindows = 0;
+
+ /* Need recent cg for window access update */
+ if (!test_cg_version (CG_REQUIRED_MAJOR,
+ CG_REQUIRED_MINOR,
+ CG_REQUIRED_MICRO))
+ {
+ ErrorF ("[DRI] disabled direct rendering; requires CoreGraphics %d.%d.%d\n",
+ CG_REQUIRED_MAJOR, CG_REQUIRED_MINOR, CG_REQUIRED_MICRO);
+
+ pDRIPriv->directRenderingSupport = FALSE;
+
+ /* Note we don't nuke the dri private, since we need it for
+ managing indirect surfaces. */
+ }
+
+ /* Initialize drawable tables */
+ for (i = 0; i < DRI_MAX_DRAWABLES; i++) {
+ pDRIPriv->DRIDrawables[i] = NULL;
+ }
+
+ return TRUE;
+}
+
+Bool
+DRIFinishScreenInit(ScreenPtr pScreen)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ /* Wrap DRI support */
+ pDRIPriv->wrap.ValidateTree = pScreen->ValidateTree;
+ pScreen->ValidateTree = DRIValidateTree;
+
+ pDRIPriv->wrap.PostValidateTree = pScreen->PostValidateTree;
+ pScreen->PostValidateTree = DRIPostValidateTree;
+
+ pDRIPriv->wrap.WindowExposures = pScreen->WindowExposures;
+ pScreen->WindowExposures = DRIWindowExposures;
+
+ pDRIPriv->wrap.CopyWindow = pScreen->CopyWindow;
+ pScreen->CopyWindow = DRICopyWindow;
+
+ pDRIPriv->wrap.ClipNotify = pScreen->ClipNotify;
+ pScreen->ClipNotify = DRIClipNotify;
+
+ // ErrorF("[DRI] screen %d installation complete\n", pScreen->myNum);
+
+ return DRIWrapInit(pScreen);
+}
+
+void
+DRICloseScreen(ScreenPtr pScreen)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if (pDRIPriv && pDRIPriv->directRenderingSupport) {
+ free(pDRIPriv);
+ dixSetPrivate(&pScreen->devPrivates, DRIScreenPrivKey, NULL);
+ }
+}
+
+Bool
+DRIExtensionInit(void)
+{
+ DRIDrawablePrivResType = CreateNewResourceType(DRIDrawablePrivDelete,
+ "DRIDrawable");
+
+ return (DRIDrawablePrivResType != 0);
+}
+
+void
+DRIReset(void)
+{
+ /*
+ * This stub routine is called when the X Server recycles, resources
+ * allocated by DRIExtensionInit need to be managed here.
+ *
+ * Currently this routine is a stub because all the interesting resources
+ * are managed via the screen init process.
+ */
+}
+
+Bool
+DRIQueryDirectRenderingCapable(ScreenPtr pScreen, Bool* isCapable)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if (pDRIPriv)
+ *isCapable = pDRIPriv->directRenderingSupport;
+ else
+ *isCapable = FALSE;
+
+ return TRUE;
+}
+
+Bool
+DRIAuthConnection(ScreenPtr pScreen, unsigned int magic)
+{
+#if 0
+ /* FIXME: something? */
+
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if (drmAuthMagic(pDRIPriv->drmFD, magic)) return FALSE;
+#endif
+ return TRUE;
+}
+
+static void
+DRIUpdateSurface(DRIDrawablePrivPtr pDRIDrawablePriv, DrawablePtr pDraw)
+{
+ xp_window_changes wc;
+ unsigned int flags = 0;
+
+ if (pDRIDrawablePriv->sid == 0)
+ return;
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+ wc.depth = (pDraw->bitsPerPixel == 32 ? XP_DEPTH_ARGB8888
+ : pDraw->bitsPerPixel == 16 ? XP_DEPTH_RGB555 : XP_DEPTH_NIL);
+ if (wc.depth != XP_DEPTH_NIL)
+ flags |= XP_DEPTH;
+#endif
+
+ if (pDraw->type == DRAWABLE_WINDOW) {
+ WindowPtr pWin = (WindowPtr) pDraw;
+ WindowPtr pTopWin = TopLevelParent(pWin);
+
+ wc.x = pWin->drawable.x - (pTopWin->drawable.x - pTopWin->borderWidth);
+ wc.y = pWin->drawable.y - (pTopWin->drawable.y - pTopWin->borderWidth);
+ wc.width = pWin->drawable.width + 2 * pWin->borderWidth;
+ wc.height = pWin->drawable.height + 2 * pWin->borderWidth;
+ wc.bit_gravity = XP_GRAVITY_NONE;
+
+ wc.shape_nrects = REGION_NUM_RECTS(&pWin->clipList);
+ wc.shape_rects = REGION_RECTS(&pWin->clipList);
+ wc.shape_tx = - (pTopWin->drawable.x - pTopWin->borderWidth);
+ wc.shape_ty = - (pTopWin->drawable.y - pTopWin->borderWidth);
+
+ flags |= XP_BOUNDS | XP_SHAPE;
+
+ } else if (pDraw->type == DRAWABLE_PIXMAP) {
+ wc.x = 0;
+ wc.y = 0;
+ wc.width = pDraw->width;
+ wc.height = pDraw->height;
+ wc.bit_gravity = XP_GRAVITY_NONE;
+ flags |= XP_BOUNDS;
+ }
+
+ xp_configure_surface(pDRIDrawablePriv->sid, flags, &wc);
+}
+
+/* Return NULL if an error occurs. */
+static DRIDrawablePrivPtr
+CreateSurfaceForWindow(ScreenPtr pScreen, WindowPtr pWin, xp_window_id *widPtr) {
+ DRIDrawablePrivPtr pDRIDrawablePriv;
+ xp_window_id wid = 0;
+
+ *widPtr = 0;
+
+ pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
+
+ if (pDRIDrawablePriv == NULL) {
+ xp_error err;
+ xp_window_changes wc;
+
+ /* allocate a DRI Window Private record */
+ if (!(pDRIDrawablePriv = malloc(sizeof(*pDRIDrawablePriv)))) {
+ return NULL;
+ }
+
+ pDRIDrawablePriv->pDraw = (DrawablePtr)pWin;
+ pDRIDrawablePriv->pScreen = pScreen;
+ pDRIDrawablePriv->refCount = 0;
+ pDRIDrawablePriv->drawableIndex = -1;
+ pDRIDrawablePriv->notifiers = NULL;
+
+ /* find the physical window */
+ wid = x_cvt_vptr_to_uint(RootlessFrameForWindow(pWin, TRUE));
+
+ if (wid == 0) {
+ free(pDRIDrawablePriv);
+ return NULL;
+ }
+
+ /* allocate the physical surface */
+ err = xp_create_surface(wid, &pDRIDrawablePriv->sid);
+
+ if (err != Success) {
+ free(pDRIDrawablePriv);
+ return NULL;
+ }
+
+ /* Make it visible */
+ wc.stack_mode = XP_MAPPED_ABOVE;
+ wc.sibling = 0;
+ err = xp_configure_surface(pDRIDrawablePriv->sid, XP_STACKING, &wc);
+
+ if (err != Success) {
+ xp_destroy_surface(pDRIDrawablePriv->sid);
+ free(pDRIDrawablePriv);
+ return NULL;
+ }
+
+ /* save private off of preallocated index */
+ dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey,
+ pDRIDrawablePriv);
+ }
+
+ *widPtr = wid;
+
+ return pDRIDrawablePriv;
+}
+
+/* Return NULL if an error occurs. */
+static DRIDrawablePrivPtr
+CreateSurfaceForPixmap(ScreenPtr pScreen, PixmapPtr pPix) {
+ DRIDrawablePrivPtr pDRIDrawablePriv;
+
+ pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPix);
+
+ if (pDRIDrawablePriv == NULL) {
+ xp_error err;
+
+ /* allocate a DRI Window Private record */
+ if (!(pDRIDrawablePriv = calloc(1, sizeof(*pDRIDrawablePriv)))) {
+ return NULL;
+ }
+
+ pDRIDrawablePriv->pDraw = (DrawablePtr)pPix;
+ pDRIDrawablePriv->pScreen = pScreen;
+ pDRIDrawablePriv->refCount = 0;
+ pDRIDrawablePriv->drawableIndex = -1;
+ pDRIDrawablePriv->notifiers = NULL;
+
+ /* Passing a null window id to Xplugin in 10.3+ asks for
+ an accelerated offscreen surface. */
+
+ err = xp_create_surface(0, &pDRIDrawablePriv->sid);
+ if (err != Success) {
+ free(pDRIDrawablePriv);
+ return NULL;
+ }
+
+ /*
+ * The DRIUpdateSurface will be called to resize the surface
+ * after this function, if the export is successful.
+ */
+
+ /* save private off of preallocated index */
+ dixSetPrivate(&pPix->devPrivates, DRIPixmapPrivKey,
+ pDRIDrawablePriv);
+ }
+
+ return pDRIDrawablePriv;
+}
+
+
+Bool
+DRICreateSurface(ScreenPtr pScreen, Drawable id,
+ DrawablePtr pDrawable, xp_client_id client_id,
+ xp_surface_id *surface_id, unsigned int ret_key[2],
+ void (*notify) (void *arg, void *data), void *notify_data)
+{
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ xp_window_id wid = 0;
+ DRIDrawablePrivPtr pDRIDrawablePriv;
+
+ if (pDrawable->type == DRAWABLE_WINDOW) {
+ pDRIDrawablePriv = CreateSurfaceForWindow(pScreen,
+ (WindowPtr)pDrawable, &wid);
+
+ if(NULL == pDRIDrawablePriv)
+ return FALSE; /*error*/
+ }
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+ else if (pDrawable->type == DRAWABLE_PIXMAP) {
+ pDRIDrawablePriv = CreateSurfaceForPixmap(pScreen,
+ (PixmapPtr)pDrawable);
+
+ if(NULL == pDRIDrawablePriv)
+ return FALSE; /*error*/
+ }
+#endif
+ else { /* for GLX 1.3, a PBuffer */
+ /* NOT_DONE */
+ return FALSE;
+ }
+
+
+ /* Finish initialization of new surfaces */
+ if (pDRIDrawablePriv->refCount == 0) {
+ unsigned int key[2] = {0};
+ xp_error err;
+
+ /* try to give the client access to the surface */
+ if (client_id != 0) {
+ /*
+ * Xplugin accepts a 0 wid if the surface id is offscreen, such
+ * as for a pixmap.
+ */
+ err = xp_export_surface(wid, pDRIDrawablePriv->sid,
+ client_id, key);
+ if (err != Success) {
+ xp_destroy_surface(pDRIDrawablePriv->sid);
+ free(pDRIDrawablePriv);
+
+ /*
+ * Now set the dix privates to NULL that were previously set.
+ * This prevents reusing an invalid pointer.
+ */
+ if(pDrawable->type == DRAWABLE_WINDOW) {
+ WindowPtr pWin = (WindowPtr)pDrawable;
+
+ dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey, NULL);
+ } else if(pDrawable->type == DRAWABLE_PIXMAP) {
+ PixmapPtr pPix = (PixmapPtr)pDrawable;
+
+ dixSetPrivate(&pPix->devPrivates, DRIPixmapPrivKey, NULL);
+ }
+
+ return FALSE;
+ }
+ }
+
+ pDRIDrawablePriv->key[0] = key[0];
+ pDRIDrawablePriv->key[1] = key[1];
+
+ ++pDRIPriv->nrWindows;
+
+ /* and stash it by surface id */
+ if (surface_hash == NULL)
+ surface_hash = x_hash_table_new(NULL, NULL, NULL, NULL);
+ x_hash_table_insert(surface_hash,
+ x_cvt_uint_to_vptr(pDRIDrawablePriv->sid), pDRIDrawablePriv);
+
+ /* track this in case this window is destroyed */
+ AddResource(id, DRIDrawablePrivResType, (pointer)pDrawable);
+
+ /* Initialize shape */
+ DRIUpdateSurface(pDRIDrawablePriv, pDrawable);
+ }
+
+ pDRIDrawablePriv->refCount++;
+
+ *surface_id = pDRIDrawablePriv->sid;
+
+ if (ret_key != NULL) {
+ ret_key[0] = pDRIDrawablePriv->key[0];
+ ret_key[1] = pDRIDrawablePriv->key[1];
+ }
+
+ if (notify != NULL) {
+ pDRIDrawablePriv->notifiers = x_hook_add(pDRIDrawablePriv->notifiers,
+ notify, notify_data);
+ }
+
+ return TRUE;
+}
+
+Bool
+DRIDestroySurface(ScreenPtr pScreen, Drawable id, DrawablePtr pDrawable,
+ void (*notify) (void *, void *), void *notify_data)
+{
+ DRIDrawablePrivPtr pDRIDrawablePriv;
+
+ if (pDrawable->type == DRAWABLE_WINDOW) {
+ pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW((WindowPtr)pDrawable);
+ } else if (pDrawable->type == DRAWABLE_PIXMAP) {
+ pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP((PixmapPtr)pDrawable);
+ } else {
+ return FALSE;
+ }
+
+ if (pDRIDrawablePriv != NULL) {
+ if (notify != NULL) {
+ pDRIDrawablePriv->notifiers = x_hook_remove(pDRIDrawablePriv->notifiers,
+ notify, notify_data);
+ }
+ if (--pDRIDrawablePriv->refCount <= 0) {
+ /* This calls back to DRIDrawablePrivDelete
+ which frees the private area */
+ FreeResourceByType(id, DRIDrawablePrivResType, FALSE);
+ }
+ }
+
+ return TRUE;
+}
+
+Bool
+DRIDrawablePrivDelete(pointer pResource, XID id)
+{
+ DrawablePtr pDrawable = (DrawablePtr)pResource;
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pDrawable->pScreen);
+ DRIDrawablePrivPtr pDRIDrawablePriv = NULL;
+ WindowPtr pWin = NULL;
+ PixmapPtr pPix = NULL;
+
+ if (pDrawable->type == DRAWABLE_WINDOW) {
+ pWin = (WindowPtr)pDrawable;
+ pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
+ } else if (pDrawable->type == DRAWABLE_PIXMAP) {
+ pPix = (PixmapPtr)pDrawable;
+ pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPix);
+ }
+
+ if (pDRIDrawablePriv == NULL) {
+ return DRIFreePixmapImp(pDrawable);
+ }
+
+ if (pDRIDrawablePriv->drawableIndex != -1) {
+ /* release drawable table entry */
+ pDRIPriv->DRIDrawables[pDRIDrawablePriv->drawableIndex] = NULL;
+ }
+
+ if (pDRIDrawablePriv->sid != 0) {
+ xp_destroy_surface(pDRIDrawablePriv->sid);
+ x_hash_table_remove(surface_hash, x_cvt_uint_to_vptr(pDRIDrawablePriv->sid));
+ }
+
+ if (pDRIDrawablePriv->notifiers != NULL)
+ x_hook_free(pDRIDrawablePriv->notifiers);
+
+ free(pDRIDrawablePriv);
+
+ if (pDrawable->type == DRAWABLE_WINDOW) {
+ dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey, NULL);
+ } else if (pDrawable->type == DRAWABLE_PIXMAP) {
+ dixSetPrivate(&pPix->devPrivates, DRIPixmapPrivKey, NULL);
+ }
+
+ --pDRIPriv->nrWindows;
+
+ return TRUE;
+}
+
+void
+DRIWindowExposures(WindowPtr pWin, RegionPtr prgn, RegionPtr bsreg)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIDrawablePrivPtr pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
+
+ if (pDRIDrawablePriv) {
+ /* FIXME: something? */
+ }
+
+ pScreen->WindowExposures = pDRIPriv->wrap.WindowExposures;
+
+ (*pScreen->WindowExposures)(pWin, prgn, bsreg);
+
+ pDRIPriv->wrap.WindowExposures = pScreen->WindowExposures;
+ pScreen->WindowExposures = DRIWindowExposures;
+}
+
+void
+DRICopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIDrawablePrivPtr pDRIDrawablePriv;
+
+ if (pDRIPriv->nrWindows > 0) {
+ pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
+ if (pDRIDrawablePriv != NULL) {
+ DRIUpdateSurface(pDRIDrawablePriv, &pWin->drawable);
+ }
+ }
+
+ /* unwrap */
+ pScreen->CopyWindow = pDRIPriv->wrap.CopyWindow;
+
+ /* call lower layers */
+ (*pScreen->CopyWindow)(pWin, ptOldOrg, prgnSrc);
+
+ /* rewrap */
+ pDRIPriv->wrap.CopyWindow = pScreen->CopyWindow;
+ pScreen->CopyWindow = DRICopyWindow;
+}
+
+int
+DRIValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind)
+{
+ ScreenPtr pScreen = pParent->drawable.pScreen;
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ int returnValue;
+
+ /* unwrap */
+ pScreen->ValidateTree = pDRIPriv->wrap.ValidateTree;
+
+ /* call lower layers */
+ returnValue = (*pScreen->ValidateTree)(pParent, pChild, kind);
+
+ /* rewrap */
+ pDRIPriv->wrap.ValidateTree = pScreen->ValidateTree;
+ pScreen->ValidateTree = DRIValidateTree;
+
+ return returnValue;
+}
+
+void
+DRIPostValidateTree(WindowPtr pParent, WindowPtr pChild, VTKind kind)
+{
+ ScreenPtr pScreen;
+ DRIScreenPrivPtr pDRIPriv;
+
+ if (pParent) {
+ pScreen = pParent->drawable.pScreen;
+ } else {
+ pScreen = pChild->drawable.pScreen;
+ }
+ pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+
+ if (pDRIPriv->wrap.PostValidateTree) {
+ /* unwrap */
+ pScreen->PostValidateTree = pDRIPriv->wrap.PostValidateTree;
+
+ /* call lower layers */
+ (*pScreen->PostValidateTree)(pParent, pChild, kind);
+
+ /* rewrap */
+ pDRIPriv->wrap.PostValidateTree = pScreen->PostValidateTree;
+ pScreen->PostValidateTree = DRIPostValidateTree;
+ }
+}
+
+void
+DRIClipNotify(WindowPtr pWin, int dx, int dy)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
+ DRIDrawablePrivPtr pDRIDrawablePriv;
+
+ if ((pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin))) {
+ DRIUpdateSurface(pDRIDrawablePriv, &pWin->drawable);
+ }
+
+ if (pDRIPriv->wrap.ClipNotify) {
+ pScreen->ClipNotify = pDRIPriv->wrap.ClipNotify;
+
+ (*pScreen->ClipNotify)(pWin, dx, dy);
+
+ pDRIPriv->wrap.ClipNotify = pScreen->ClipNotify;
+ pScreen->ClipNotify = DRIClipNotify;
+ }
+}
+
+/* This lets us get at the unwrapped functions so that they can correctly
+ * call the lower level functions, and choose whether they will be
+ * called at every level of recursion (eg in validatetree).
+ */
+DRIWrappedFuncsRec *
+DRIGetWrappedFuncs(ScreenPtr pScreen)
+{
+ return &(DRI_SCREEN_PRIV(pScreen)->wrap);
+}
+
+void
+DRIQueryVersion(int *majorVersion,
+ int *minorVersion,
+ int *patchVersion)
+{
+ *majorVersion = APPLE_DRI_MAJOR_VERSION;
+ *minorVersion = APPLE_DRI_MINOR_VERSION;
+ *patchVersion = APPLE_DRI_PATCH_VERSION;
+}
+
+void
+DRISurfaceNotify(xp_surface_id id, int kind)
+{
+ DRIDrawablePrivPtr pDRIDrawablePriv = NULL;
+ DRISurfaceNotifyArg arg;
+
+ arg.id = id;
+ arg.kind = kind;
+
+ if (surface_hash != NULL)
+ {
+ pDRIDrawablePriv = x_hash_table_lookup(surface_hash,
+ x_cvt_uint_to_vptr(id), NULL);
+ }
+
+ if (pDRIDrawablePriv == NULL)
+ return;
+
+ if (kind == AppleDRISurfaceNotifyDestroyed)
+ {
+ pDRIDrawablePriv->sid = 0;
+ x_hash_table_remove(surface_hash, x_cvt_uint_to_vptr(id));
+ }
+
+ x_hook_run(pDRIDrawablePriv->notifiers, &arg);
+
+ if (kind == AppleDRISurfaceNotifyDestroyed)
+ {
+ /* Kill off the handle. */
+
+ FreeResourceByType(pDRIDrawablePriv->pDraw->id,
+ DRIDrawablePrivResType, FALSE);
+ }
+}
+
+Bool DRICreatePixmap(ScreenPtr pScreen, Drawable id,
+ DrawablePtr pDrawable, char *path,
+ size_t pathmax)
+{
+ DRIPixmapBufferPtr shared;
+ PixmapPtr pPix;
+
+ if(pDrawable->type != DRAWABLE_PIXMAP)
+ return FALSE;
+
+ pPix = (PixmapPtr)pDrawable;
+
+ shared = malloc(sizeof(*shared));
+ if(NULL == shared) {
+ FatalError("failed to allocate DRIPixmapBuffer in %s\n", __func__);
+ }
+
+ shared->pDrawable = pDrawable;
+ shared->refCount = 1;
+
+ if(pDrawable->bitsPerPixel >= 24) {
+ shared->bytesPerPixel = 4;
+ } else if(pDrawable->bitsPerPixel <= 16) {
+ shared->bytesPerPixel = 2;
+ }
+
+ shared->width = pDrawable->width;
+ shared->height = pDrawable->height;
+
+ if(-1 == snprintf(shared->shmPath, sizeof(shared->shmPath),
+ "%d_0x%lx", getpid(),
+ (unsigned long)id)) {
+ FatalError("buffer overflow in %s\n", __func__);
+ }
+
+ shared->fd = shm_open(shared->shmPath,
+ O_RDWR | O_EXCL | O_CREAT,
+ S_IRUSR | S_IWUSR | S_IROTH | S_IWOTH);
+
+ if(-1 == shared->fd) {
+ free(shared);
+ return FALSE;
+ }
+
+ shared->length = shared->width * shared->height * shared->bytesPerPixel;
+
+ if(-1 == ftruncate(shared->fd, shared->length)) {
+ ErrorF("failed to ftruncate (extend) file.");
+ shm_unlink(shared->shmPath);
+ close(shared->fd);
+ free(shared);
+ return FALSE;
+ }
+
+ shared->buffer = mmap(NULL, shared->length,
+ PROT_READ | PROT_WRITE,
+ MAP_FILE | MAP_SHARED, shared->fd, 0);
+
+ if(MAP_FAILED == shared->buffer) {
+ ErrorF("failed to mmap shared memory.");
+ shm_unlink(shared->shmPath);
+ close(shared->fd);
+ free(shared);
+ return FALSE;
+ }
+
+ strncpy(path, shared->shmPath, pathmax);
+ path[pathmax - 1] = '\0';
+
+ dixSetPrivate(&pPix->devPrivates, DRIPixmapBufferPrivKey, shared);
+
+ AddResource(id, DRIDrawablePrivResType, (pointer)pDrawable);
+
+ return TRUE;
+}
+
+
+Bool DRIGetPixmapData(DrawablePtr pDrawable, int *width, int *height,
+ int *pitch, int *bpp, void **ptr) {
+ PixmapPtr pPix;
+ DRIPixmapBufferPtr shared;
+
+ if(pDrawable->type != DRAWABLE_PIXMAP)
+ return FALSE;
+
+ pPix = (PixmapPtr)pDrawable;
+
+ shared = dixLookupPrivate(&pPix->devPrivates, DRIPixmapBufferPrivKey);
+
+ if(NULL == shared)
+ return FALSE;
+
+ assert(pDrawable->width == shared->width);
+ assert(pDrawable->height == shared->height);
+
+ *width = shared->width;
+ *height = shared->height;
+ *bpp = shared->bytesPerPixel;
+ *pitch = shared->width * shared->bytesPerPixel;
+ *ptr = shared->buffer;
+
+ return TRUE;
+}
+
+static Bool
+DRIFreePixmapImp(DrawablePtr pDrawable) {
+ DRIPixmapBufferPtr shared;
+ PixmapPtr pPix;
+
+ if(pDrawable->type != DRAWABLE_PIXMAP)
+ return FALSE;
+
+ pPix = (PixmapPtr)pDrawable;
+
+ shared = dixLookupPrivate(&pPix->devPrivates, DRIPixmapBufferPrivKey);
+
+ if(NULL == shared)
+ return FALSE;
+
+ close(shared->fd);
+ munmap(shared->buffer, shared->length);
+ shm_unlink(shared->shmPath);
+ free(shared);
+
+ dixSetPrivate(&pPix->devPrivates, DRIPixmapBufferPrivKey, (pointer)NULL);
+
+ return TRUE;
+}
+
+void
+DRIDestroyPixmap(DrawablePtr pDrawable) {
+ if(DRIFreePixmapImp(pDrawable))
+ FreeResourceByType(pDrawable->id, DRIDrawablePrivResType, FALSE);
+
+}
diff --git a/xorg-server/hw/xquartz/xpr/driWrap.c b/xorg-server/hw/xquartz/xpr/driWrap.c
index 8c57fd4bd..2e23cbbf5 100644
--- a/xorg-server/hw/xquartz/xpr/driWrap.c
+++ b/xorg-server/hw/xquartz/xpr/driWrap.c
@@ -1,547 +1,547 @@
-/*
-Copyright (c) 2009 Apple Computer, 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, sub license, 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 (including the
-next paragraph) 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 NON-INFRINGEMENT.
-IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
-ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-*/
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include <stddef.h>
-#include "mi.h"
-#include "scrnintstr.h"
-#include "gcstruct.h"
-#include "pixmapstr.h"
-#include "windowstr.h"
-#include "dixfontstr.h"
-#include "mivalidate.h"
-#include "driWrap.h"
-#include "dri.h"
-
-#include <OpenGL/OpenGL.h>
-
-typedef struct {
- GCOps *originalOps;
- GCOps *driOps;
-} DRIGCRec;
-
-typedef struct {
- GCOps *originalOps;
- CreateGCProcPtr CreateGC;
-} DRIWrapScreenRec;
-
-typedef struct {
- Bool didSave;
- int devKind;
- DevUnion devPrivate;
-} DRISavedDrawableState;
-
-static int driGCKeyIndex;
-static DevPrivateKey driGCKey = &driGCKeyIndex;
-
-static int driWrapScreenKeyIndex;
-static DevPrivateKey driWrapScreenKey = &driWrapScreenKeyIndex;
-
-static GCOps driGCOps;
-
-#define wrap(priv, real, member, func) { \
- priv->member = real->member; \
- real->member = func; \
- }
-
-#define unwrap(priv, real, member) { \
- real->member = priv->member; \
- }
-
-static DRIGCRec *
-DRIGetGCPriv(GCPtr pGC) {
- return dixLookupPrivate(&pGC->devPrivates, driGCKey);
-}
-
-static void
-DRIUnwrapGC(GCPtr pGC) {
- DRIGCRec *pGCPriv = DRIGetGCPriv(pGC);
-
- pGC->ops = pGCPriv->originalOps;
-}
-
-static void
-DRIWrapGC(GCPtr pGC) {
- DRIGCRec *pGCPriv = DRIGetGCPriv(pGC);
-
- pGC->ops = pGCPriv->driOps;
-}
-
-static void
-DRISurfaceSetDrawable(DrawablePtr pDraw,
- DRISavedDrawableState *saved) {
- saved->didSave = FALSE;
-
- if(pDraw->type == DRAWABLE_PIXMAP) {
- int pitch, width, height, bpp;
- void *buffer;
-
- if(DRIGetPixmapData(pDraw, &width, &height, &pitch, &bpp, &buffer)) {
- PixmapPtr pPix = (PixmapPtr)pDraw;
-
- saved->devKind = pPix->devKind;
- saved->devPrivate.ptr = pPix->devPrivate.ptr;
- saved->didSave = TRUE;
-
- pPix->devKind = pitch;
- pPix->devPrivate.ptr = buffer;
- }
- }
-}
-
-static void
-DRISurfaceRestoreDrawable(DrawablePtr pDraw,
- DRISavedDrawableState *saved) {
- PixmapPtr pPix = (PixmapPtr)pDraw;
-
- if(!saved->didSave)
- return;
-
- pPix->devKind = saved->devKind;
- pPix->devPrivate.ptr = saved->devPrivate.ptr;
-}
-
-static void
-DRIFillSpans(DrawablePtr dst, GCPtr pGC, int nInit,
- DDXPointPtr pptInit, int *pwidthInit,
- int sorted) {
- DRISavedDrawableState saved;
-
- DRISurfaceSetDrawable(dst, &saved);
-
- DRIUnwrapGC(pGC);
-
- pGC->ops->FillSpans(dst, pGC, nInit, pptInit, pwidthInit, sorted);
-
- DRIWrapGC(pGC);
-
- DRISurfaceRestoreDrawable(dst, &saved);
-}
-
-static void
-DRISetSpans(DrawablePtr dst, GCPtr pGC, char *pSrc,
- DDXPointPtr pptInit, int *pwidthInit,
- int nspans, int sorted) {
- DRISavedDrawableState saved;
-
- DRISurfaceSetDrawable(dst, &saved);
-
- DRIUnwrapGC(pGC);
-
- pGC->ops->SetSpans(dst, pGC, pSrc, pptInit, pwidthInit, nspans, sorted);
-
- DRIWrapGC(pGC);
-
- DRISurfaceRestoreDrawable(dst, &saved);
-}
-
-static void
-DRIPutImage(DrawablePtr dst, GCPtr pGC,
- int depth, int x, int y, int w, int h,
- int leftPad, int format, char *pBits) {
- DRISavedDrawableState saved;
-
- DRISurfaceSetDrawable(dst, &saved);
-
- DRIUnwrapGC(pGC);
-
- pGC->ops->PutImage(dst, pGC, depth, x, y, w, h, leftPad, format, pBits);
-
- DRIWrapGC(pGC);
-
- DRISurfaceRestoreDrawable(dst, &saved);
-}
-
-static RegionPtr
-DRICopyArea(DrawablePtr pSrc, DrawablePtr dst, GCPtr pGC,
- int srcx, int srcy, int w, int h,
- int dstx, int dsty) {
- RegionPtr pReg;
- DRISavedDrawableState pSrcSaved, dstSaved;
-
- DRISurfaceSetDrawable(pSrc, &pSrcSaved);
- DRISurfaceSetDrawable(dst, &dstSaved);
-
- DRIUnwrapGC(pGC);
-
- pReg = pGC->ops->CopyArea(pSrc, dst, pGC, srcx, srcy, w, h, dstx, dsty);
-
- DRIWrapGC(pGC);
-
- DRISurfaceRestoreDrawable(pSrc, &pSrcSaved);
- DRISurfaceRestoreDrawable(dst, &dstSaved);
-
- return pReg;
-}
-
-static RegionPtr
-DRICopyPlane(DrawablePtr pSrc, DrawablePtr dst,
- GCPtr pGC, int srcx, int srcy,
- int w, int h, int dstx, int dsty,
- unsigned long plane) {
- RegionPtr pReg;
- DRISavedDrawableState pSrcSaved, dstSaved;
-
- DRISurfaceSetDrawable(pSrc, &pSrcSaved);
- DRISurfaceSetDrawable(dst, &dstSaved);
-
-
- DRIUnwrapGC(pGC);
-
- pReg = pGC->ops->CopyPlane(pSrc, dst, pGC, srcx, srcy, w, h, dstx, dsty,
- plane);
-
- DRIWrapGC(pGC);
-
- DRISurfaceRestoreDrawable(pSrc, &pSrcSaved);
- DRISurfaceRestoreDrawable(dst, &dstSaved);
-
- return pReg;
-}
-
-static void
-DRIPolyPoint(DrawablePtr dst, GCPtr pGC,
- int mode, int npt, DDXPointPtr pptInit) {
- DRISavedDrawableState saved;
-
- DRISurfaceSetDrawable(dst, &saved);
-
- DRIUnwrapGC(pGC);
-
- pGC->ops->PolyPoint(dst, pGC, mode, npt, pptInit);
-
- DRIWrapGC(pGC);
-
- DRISurfaceRestoreDrawable(dst, &saved);
-}
-
-static void
-DRIPolylines(DrawablePtr dst, GCPtr pGC,
- int mode, int npt, DDXPointPtr pptInit) {
- DRISavedDrawableState saved;
-
- DRISurfaceSetDrawable(dst, &saved);
-
- DRIUnwrapGC(pGC);
-
- pGC->ops->Polylines(dst, pGC, mode, npt, pptInit);
-
- DRIWrapGC(pGC);
-
- DRISurfaceRestoreDrawable(dst, &saved);
-}
-
-static void
-DRIPolySegment(DrawablePtr dst, GCPtr pGC,
- int nseg, xSegment *pSeg) {
- DRISavedDrawableState saved;
-
- DRISurfaceSetDrawable(dst, &saved);
-
- DRIUnwrapGC(pGC);
-
- pGC->ops->PolySegment(dst, pGC, nseg, pSeg);
-
- DRIWrapGC(pGC);
-
- DRISurfaceRestoreDrawable(dst, &saved);
-}
-
-static void
-DRIPolyRectangle(DrawablePtr dst, GCPtr pGC,
- int nRects, xRectangle *pRects) {
- DRISavedDrawableState saved;
-
- DRISurfaceSetDrawable(dst, &saved);
-
- DRIUnwrapGC(pGC);
-
- pGC->ops->PolyRectangle(dst, pGC, nRects, pRects);
-
- DRIWrapGC(pGC);
-
- DRISurfaceRestoreDrawable(dst, &saved);
-}
-static void
-DRIPolyArc(DrawablePtr dst, GCPtr pGC, int narcs, xArc *parcs) {
- DRISavedDrawableState saved;
-
- DRISurfaceSetDrawable(dst, &saved);
-
- DRIUnwrapGC(pGC);
-
- pGC->ops->PolyArc(dst, pGC, narcs, parcs);
-
- DRIWrapGC(pGC);
-
- DRISurfaceRestoreDrawable(dst, &saved);
-}
-
-static void
-DRIFillPolygon(DrawablePtr dst, GCPtr pGC,
- int shape, int mode, int count,
- DDXPointPtr pptInit) {
- DRISavedDrawableState saved;
-
- DRISurfaceSetDrawable(dst, &saved);
-
- DRIUnwrapGC(pGC);
-
- pGC->ops->FillPolygon(dst, pGC, shape, mode, count, pptInit);
-
- DRIWrapGC(pGC);
-
- DRISurfaceRestoreDrawable(dst, &saved);
-}
-
-static void
-DRIPolyFillRect(DrawablePtr dst, GCPtr pGC,
- int nRectsInit, xRectangle *pRectsInit) {
- DRISavedDrawableState saved;
-
- DRISurfaceSetDrawable(dst, &saved);
-
- DRIUnwrapGC(pGC);
-
- pGC->ops->PolyFillRect(dst, pGC, nRectsInit, pRectsInit);
-
- DRIWrapGC(pGC);
-
- DRISurfaceRestoreDrawable(dst, &saved);
-}
-
-static void
-DRIPolyFillArc(DrawablePtr dst, GCPtr pGC,
- int narcsInit, xArc *parcsInit) {
- DRISavedDrawableState saved;
-
- DRISurfaceSetDrawable(dst, &saved);
-
- DRIUnwrapGC(pGC);
-
- pGC->ops->PolyFillArc(dst, pGC, narcsInit, parcsInit);
-
- DRIWrapGC(pGC);
-
- DRISurfaceRestoreDrawable(dst, &saved);
-}
-
-static int
-DRIPolyText8(DrawablePtr dst, GCPtr pGC,
- int x, int y, int count, char *chars) {
- int ret;
- DRISavedDrawableState saved;
-
- DRISurfaceSetDrawable(dst, &saved);
-
- DRIUnwrapGC(pGC);
-
- ret = pGC->ops->PolyText8(dst, pGC, x, y, count, chars);
-
- DRIWrapGC(pGC);
-
- DRISurfaceRestoreDrawable(dst, &saved);
-
- return ret;
-}
-
-static int
-DRIPolyText16(DrawablePtr dst, GCPtr pGC,
- int x, int y, int count, unsigned short *chars) {
- int ret;
- DRISavedDrawableState saved;
-
- DRISurfaceSetDrawable(dst, &saved);
-
- DRIUnwrapGC(pGC);
-
- ret = pGC->ops->PolyText16(dst, pGC, x, y, count, chars);
-
- DRIWrapGC(pGC);
-
- DRISurfaceRestoreDrawable(dst, &saved);
-
- return ret;
-}
-
-static void
-DRIImageText8(DrawablePtr dst, GCPtr pGC,
- int x, int y, int count, char *chars) {
- DRISavedDrawableState saved;
-
- DRISurfaceSetDrawable(dst, &saved);
-
- DRIUnwrapGC(pGC);
-
- pGC->ops->ImageText8(dst, pGC, x, y, count, chars);
-
- DRIWrapGC(pGC);
-
- DRISurfaceRestoreDrawable(dst, &saved);
-}
-
-static void
-DRIImageText16(DrawablePtr dst, GCPtr pGC,
- int x, int y, int count, unsigned short *chars) {
- DRISavedDrawableState saved;
-
- DRISurfaceSetDrawable(dst, &saved);
-
- DRIUnwrapGC(pGC);
-
- pGC->ops->ImageText16(dst, pGC, x, y, count, chars);
-
- DRIWrapGC(pGC);
-
- DRISurfaceRestoreDrawable(dst, &saved);
-}
-
-static void
-DRIImageGlyphBlt(DrawablePtr dst, GCPtr pGC,
- int x, int y, unsigned int nglyphInit,
- CharInfoPtr *ppciInit, pointer unused) {
- DRISavedDrawableState saved;
-
- DRISurfaceSetDrawable(dst, &saved);
-
- DRIUnwrapGC(pGC);
-
- pGC->ops->ImageGlyphBlt(dst, pGC, x, y, nglyphInit, ppciInit, unused);
-
- DRIWrapGC(pGC);
-
- DRISurfaceRestoreDrawable(dst, &saved);
-}
-
-static void DRIPolyGlyphBlt(DrawablePtr dst, GCPtr pGC,
- int x, int y, unsigned int nglyph,
- CharInfoPtr *ppci, pointer pglyphBase) {
- DRISavedDrawableState saved;
-
- DRISurfaceSetDrawable(dst, &saved);
-
- DRIUnwrapGC(pGC);
-
- pGC->ops->PolyGlyphBlt(dst, pGC, x, y, nglyph, ppci, pglyphBase);
-
- DRIWrapGC(pGC);
-
- DRISurfaceRestoreDrawable(dst, &saved);
-}
-
-static void
-DRIPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr dst,
- int dx, int dy, int xOrg, int yOrg) {
- DRISavedDrawableState bitMapSaved, dstSaved;
-
- DRISurfaceSetDrawable(&pBitMap->drawable, &bitMapSaved);
- DRISurfaceSetDrawable(dst, &dstSaved);
-
- DRIUnwrapGC(pGC);
-
- pGC->ops->PushPixels(pGC, pBitMap, dst, dx, dy, xOrg, yOrg);
-
- DRIWrapGC(pGC);
-
- DRISurfaceRestoreDrawable(&pBitMap->drawable, &bitMapSaved);
- DRISurfaceRestoreDrawable(dst, &dstSaved);
-}
-
-
-static GCOps driGCOps = {
- DRIFillSpans,
- DRISetSpans,
- DRIPutImage,
- DRICopyArea,
- DRICopyPlane,
- DRIPolyPoint,
- DRIPolylines,
- DRIPolySegment,
- DRIPolyRectangle,
- DRIPolyArc,
- DRIFillPolygon,
- DRIPolyFillRect,
- DRIPolyFillArc,
- DRIPolyText8,
- DRIPolyText16,
- DRIImageText8,
- DRIImageText16,
- DRIImageGlyphBlt,
- DRIPolyGlyphBlt,
- DRIPushPixels
-};
-
-
-static Bool
-DRICreateGC(GCPtr pGC) {
- ScreenPtr pScreen = pGC->pScreen;
- DRIWrapScreenRec *pScreenPriv;
- DRIGCRec *pGCPriv;
- Bool ret;
-
- pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, driWrapScreenKey);
-
- pGCPriv = DRIGetGCPriv(pGC);
-
- unwrap(pScreenPriv, pScreen, CreateGC);
- ret = pScreen->CreateGC(pGC);
-
- if(ret) {
- pGCPriv->originalOps = pGC->ops;
- pGC->ops = &driGCOps;
- pGCPriv->driOps = &driGCOps;
- }
-
- wrap(pScreenPriv, pScreen, CreateGC, DRICreateGC);
-
- return ret;
-}
-
-
-/* Return false if an error occurred. */
-Bool
-DRIWrapInit(ScreenPtr pScreen) {
- DRIWrapScreenRec *pScreenPriv;
-
- if(!dixRequestPrivate(driGCKey, sizeof(DRIGCRec)))
- return FALSE;
-
- if(!dixRequestPrivate(driWrapScreenKey, sizeof(DRIWrapScreenRec)))
- return FALSE;
-
- pScreenPriv = xalloc(sizeof(*pScreenPriv));
-
- if(NULL == pScreenPriv)
- return FALSE;
-
- pScreenPriv->CreateGC = pScreen->CreateGC;
- pScreen->CreateGC = DRICreateGC;
-
- dixSetPrivate(&pScreen->devPrivates, driWrapScreenKey, pScreenPriv);
-
- return TRUE;
-}
+/*
+Copyright (c) 2009 Apple Computer, 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, sub license, 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 (including the
+next paragraph) 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 NON-INFRINGEMENT.
+IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <stddef.h>
+#include "mi.h"
+#include "scrnintstr.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "windowstr.h"
+#include "dixfontstr.h"
+#include "mivalidate.h"
+#include "driWrap.h"
+#include "dri.h"
+
+#include <OpenGL/OpenGL.h>
+
+typedef struct {
+ GCOps *originalOps;
+ GCOps *driOps;
+} DRIGCRec;
+
+typedef struct {
+ GCOps *originalOps;
+ CreateGCProcPtr CreateGC;
+} DRIWrapScreenRec;
+
+typedef struct {
+ Bool didSave;
+ int devKind;
+ DevUnion devPrivate;
+} DRISavedDrawableState;
+
+static int driGCKeyIndex;
+static DevPrivateKey driGCKey = &driGCKeyIndex;
+
+static int driWrapScreenKeyIndex;
+static DevPrivateKey driWrapScreenKey = &driWrapScreenKeyIndex;
+
+static GCOps driGCOps;
+
+#define wrap(priv, real, member, func) { \
+ priv->member = real->member; \
+ real->member = func; \
+ }
+
+#define unwrap(priv, real, member) { \
+ real->member = priv->member; \
+ }
+
+static DRIGCRec *
+DRIGetGCPriv(GCPtr pGC) {
+ return dixLookupPrivate(&pGC->devPrivates, driGCKey);
+}
+
+static void
+DRIUnwrapGC(GCPtr pGC) {
+ DRIGCRec *pGCPriv = DRIGetGCPriv(pGC);
+
+ pGC->ops = pGCPriv->originalOps;
+}
+
+static void
+DRIWrapGC(GCPtr pGC) {
+ DRIGCRec *pGCPriv = DRIGetGCPriv(pGC);
+
+ pGC->ops = pGCPriv->driOps;
+}
+
+static void
+DRISurfaceSetDrawable(DrawablePtr pDraw,
+ DRISavedDrawableState *saved) {
+ saved->didSave = FALSE;
+
+ if(pDraw->type == DRAWABLE_PIXMAP) {
+ int pitch, width, height, bpp;
+ void *buffer;
+
+ if(DRIGetPixmapData(pDraw, &width, &height, &pitch, &bpp, &buffer)) {
+ PixmapPtr pPix = (PixmapPtr)pDraw;
+
+ saved->devKind = pPix->devKind;
+ saved->devPrivate.ptr = pPix->devPrivate.ptr;
+ saved->didSave = TRUE;
+
+ pPix->devKind = pitch;
+ pPix->devPrivate.ptr = buffer;
+ }
+ }
+}
+
+static void
+DRISurfaceRestoreDrawable(DrawablePtr pDraw,
+ DRISavedDrawableState *saved) {
+ PixmapPtr pPix = (PixmapPtr)pDraw;
+
+ if(!saved->didSave)
+ return;
+
+ pPix->devKind = saved->devKind;
+ pPix->devPrivate.ptr = saved->devPrivate.ptr;
+}
+
+static void
+DRIFillSpans(DrawablePtr dst, GCPtr pGC, int nInit,
+ DDXPointPtr pptInit, int *pwidthInit,
+ int sorted) {
+ DRISavedDrawableState saved;
+
+ DRISurfaceSetDrawable(dst, &saved);
+
+ DRIUnwrapGC(pGC);
+
+ pGC->ops->FillSpans(dst, pGC, nInit, pptInit, pwidthInit, sorted);
+
+ DRIWrapGC(pGC);
+
+ DRISurfaceRestoreDrawable(dst, &saved);
+}
+
+static void
+DRISetSpans(DrawablePtr dst, GCPtr pGC, char *pSrc,
+ DDXPointPtr pptInit, int *pwidthInit,
+ int nspans, int sorted) {
+ DRISavedDrawableState saved;
+
+ DRISurfaceSetDrawable(dst, &saved);
+
+ DRIUnwrapGC(pGC);
+
+ pGC->ops->SetSpans(dst, pGC, pSrc, pptInit, pwidthInit, nspans, sorted);
+
+ DRIWrapGC(pGC);
+
+ DRISurfaceRestoreDrawable(dst, &saved);
+}
+
+static void
+DRIPutImage(DrawablePtr dst, GCPtr pGC,
+ int depth, int x, int y, int w, int h,
+ int leftPad, int format, char *pBits) {
+ DRISavedDrawableState saved;
+
+ DRISurfaceSetDrawable(dst, &saved);
+
+ DRIUnwrapGC(pGC);
+
+ pGC->ops->PutImage(dst, pGC, depth, x, y, w, h, leftPad, format, pBits);
+
+ DRIWrapGC(pGC);
+
+ DRISurfaceRestoreDrawable(dst, &saved);
+}
+
+static RegionPtr
+DRICopyArea(DrawablePtr pSrc, DrawablePtr dst, GCPtr pGC,
+ int srcx, int srcy, int w, int h,
+ int dstx, int dsty) {
+ RegionPtr pReg;
+ DRISavedDrawableState pSrcSaved, dstSaved;
+
+ DRISurfaceSetDrawable(pSrc, &pSrcSaved);
+ DRISurfaceSetDrawable(dst, &dstSaved);
+
+ DRIUnwrapGC(pGC);
+
+ pReg = pGC->ops->CopyArea(pSrc, dst, pGC, srcx, srcy, w, h, dstx, dsty);
+
+ DRIWrapGC(pGC);
+
+ DRISurfaceRestoreDrawable(pSrc, &pSrcSaved);
+ DRISurfaceRestoreDrawable(dst, &dstSaved);
+
+ return pReg;
+}
+
+static RegionPtr
+DRICopyPlane(DrawablePtr pSrc, DrawablePtr dst,
+ GCPtr pGC, int srcx, int srcy,
+ int w, int h, int dstx, int dsty,
+ unsigned long plane) {
+ RegionPtr pReg;
+ DRISavedDrawableState pSrcSaved, dstSaved;
+
+ DRISurfaceSetDrawable(pSrc, &pSrcSaved);
+ DRISurfaceSetDrawable(dst, &dstSaved);
+
+
+ DRIUnwrapGC(pGC);
+
+ pReg = pGC->ops->CopyPlane(pSrc, dst, pGC, srcx, srcy, w, h, dstx, dsty,
+ plane);
+
+ DRIWrapGC(pGC);
+
+ DRISurfaceRestoreDrawable(pSrc, &pSrcSaved);
+ DRISurfaceRestoreDrawable(dst, &dstSaved);
+
+ return pReg;
+}
+
+static void
+DRIPolyPoint(DrawablePtr dst, GCPtr pGC,
+ int mode, int npt, DDXPointPtr pptInit) {
+ DRISavedDrawableState saved;
+
+ DRISurfaceSetDrawable(dst, &saved);
+
+ DRIUnwrapGC(pGC);
+
+ pGC->ops->PolyPoint(dst, pGC, mode, npt, pptInit);
+
+ DRIWrapGC(pGC);
+
+ DRISurfaceRestoreDrawable(dst, &saved);
+}
+
+static void
+DRIPolylines(DrawablePtr dst, GCPtr pGC,
+ int mode, int npt, DDXPointPtr pptInit) {
+ DRISavedDrawableState saved;
+
+ DRISurfaceSetDrawable(dst, &saved);
+
+ DRIUnwrapGC(pGC);
+
+ pGC->ops->Polylines(dst, pGC, mode, npt, pptInit);
+
+ DRIWrapGC(pGC);
+
+ DRISurfaceRestoreDrawable(dst, &saved);
+}
+
+static void
+DRIPolySegment(DrawablePtr dst, GCPtr pGC,
+ int nseg, xSegment *pSeg) {
+ DRISavedDrawableState saved;
+
+ DRISurfaceSetDrawable(dst, &saved);
+
+ DRIUnwrapGC(pGC);
+
+ pGC->ops->PolySegment(dst, pGC, nseg, pSeg);
+
+ DRIWrapGC(pGC);
+
+ DRISurfaceRestoreDrawable(dst, &saved);
+}
+
+static void
+DRIPolyRectangle(DrawablePtr dst, GCPtr pGC,
+ int nRects, xRectangle *pRects) {
+ DRISavedDrawableState saved;
+
+ DRISurfaceSetDrawable(dst, &saved);
+
+ DRIUnwrapGC(pGC);
+
+ pGC->ops->PolyRectangle(dst, pGC, nRects, pRects);
+
+ DRIWrapGC(pGC);
+
+ DRISurfaceRestoreDrawable(dst, &saved);
+}
+static void
+DRIPolyArc(DrawablePtr dst, GCPtr pGC, int narcs, xArc *parcs) {
+ DRISavedDrawableState saved;
+
+ DRISurfaceSetDrawable(dst, &saved);
+
+ DRIUnwrapGC(pGC);
+
+ pGC->ops->PolyArc(dst, pGC, narcs, parcs);
+
+ DRIWrapGC(pGC);
+
+ DRISurfaceRestoreDrawable(dst, &saved);
+}
+
+static void
+DRIFillPolygon(DrawablePtr dst, GCPtr pGC,
+ int shape, int mode, int count,
+ DDXPointPtr pptInit) {
+ DRISavedDrawableState saved;
+
+ DRISurfaceSetDrawable(dst, &saved);
+
+ DRIUnwrapGC(pGC);
+
+ pGC->ops->FillPolygon(dst, pGC, shape, mode, count, pptInit);
+
+ DRIWrapGC(pGC);
+
+ DRISurfaceRestoreDrawable(dst, &saved);
+}
+
+static void
+DRIPolyFillRect(DrawablePtr dst, GCPtr pGC,
+ int nRectsInit, xRectangle *pRectsInit) {
+ DRISavedDrawableState saved;
+
+ DRISurfaceSetDrawable(dst, &saved);
+
+ DRIUnwrapGC(pGC);
+
+ pGC->ops->PolyFillRect(dst, pGC, nRectsInit, pRectsInit);
+
+ DRIWrapGC(pGC);
+
+ DRISurfaceRestoreDrawable(dst, &saved);
+}
+
+static void
+DRIPolyFillArc(DrawablePtr dst, GCPtr pGC,
+ int narcsInit, xArc *parcsInit) {
+ DRISavedDrawableState saved;
+
+ DRISurfaceSetDrawable(dst, &saved);
+
+ DRIUnwrapGC(pGC);
+
+ pGC->ops->PolyFillArc(dst, pGC, narcsInit, parcsInit);
+
+ DRIWrapGC(pGC);
+
+ DRISurfaceRestoreDrawable(dst, &saved);
+}
+
+static int
+DRIPolyText8(DrawablePtr dst, GCPtr pGC,
+ int x, int y, int count, char *chars) {
+ int ret;
+ DRISavedDrawableState saved;
+
+ DRISurfaceSetDrawable(dst, &saved);
+
+ DRIUnwrapGC(pGC);
+
+ ret = pGC->ops->PolyText8(dst, pGC, x, y, count, chars);
+
+ DRIWrapGC(pGC);
+
+ DRISurfaceRestoreDrawable(dst, &saved);
+
+ return ret;
+}
+
+static int
+DRIPolyText16(DrawablePtr dst, GCPtr pGC,
+ int x, int y, int count, unsigned short *chars) {
+ int ret;
+ DRISavedDrawableState saved;
+
+ DRISurfaceSetDrawable(dst, &saved);
+
+ DRIUnwrapGC(pGC);
+
+ ret = pGC->ops->PolyText16(dst, pGC, x, y, count, chars);
+
+ DRIWrapGC(pGC);
+
+ DRISurfaceRestoreDrawable(dst, &saved);
+
+ return ret;
+}
+
+static void
+DRIImageText8(DrawablePtr dst, GCPtr pGC,
+ int x, int y, int count, char *chars) {
+ DRISavedDrawableState saved;
+
+ DRISurfaceSetDrawable(dst, &saved);
+
+ DRIUnwrapGC(pGC);
+
+ pGC->ops->ImageText8(dst, pGC, x, y, count, chars);
+
+ DRIWrapGC(pGC);
+
+ DRISurfaceRestoreDrawable(dst, &saved);
+}
+
+static void
+DRIImageText16(DrawablePtr dst, GCPtr pGC,
+ int x, int y, int count, unsigned short *chars) {
+ DRISavedDrawableState saved;
+
+ DRISurfaceSetDrawable(dst, &saved);
+
+ DRIUnwrapGC(pGC);
+
+ pGC->ops->ImageText16(dst, pGC, x, y, count, chars);
+
+ DRIWrapGC(pGC);
+
+ DRISurfaceRestoreDrawable(dst, &saved);
+}
+
+static void
+DRIImageGlyphBlt(DrawablePtr dst, GCPtr pGC,
+ int x, int y, unsigned int nglyphInit,
+ CharInfoPtr *ppciInit, pointer unused) {
+ DRISavedDrawableState saved;
+
+ DRISurfaceSetDrawable(dst, &saved);
+
+ DRIUnwrapGC(pGC);
+
+ pGC->ops->ImageGlyphBlt(dst, pGC, x, y, nglyphInit, ppciInit, unused);
+
+ DRIWrapGC(pGC);
+
+ DRISurfaceRestoreDrawable(dst, &saved);
+}
+
+static void DRIPolyGlyphBlt(DrawablePtr dst, GCPtr pGC,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci, pointer pglyphBase) {
+ DRISavedDrawableState saved;
+
+ DRISurfaceSetDrawable(dst, &saved);
+
+ DRIUnwrapGC(pGC);
+
+ pGC->ops->PolyGlyphBlt(dst, pGC, x, y, nglyph, ppci, pglyphBase);
+
+ DRIWrapGC(pGC);
+
+ DRISurfaceRestoreDrawable(dst, &saved);
+}
+
+static void
+DRIPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr dst,
+ int dx, int dy, int xOrg, int yOrg) {
+ DRISavedDrawableState bitMapSaved, dstSaved;
+
+ DRISurfaceSetDrawable(&pBitMap->drawable, &bitMapSaved);
+ DRISurfaceSetDrawable(dst, &dstSaved);
+
+ DRIUnwrapGC(pGC);
+
+ pGC->ops->PushPixels(pGC, pBitMap, dst, dx, dy, xOrg, yOrg);
+
+ DRIWrapGC(pGC);
+
+ DRISurfaceRestoreDrawable(&pBitMap->drawable, &bitMapSaved);
+ DRISurfaceRestoreDrawable(dst, &dstSaved);
+}
+
+
+static GCOps driGCOps = {
+ DRIFillSpans,
+ DRISetSpans,
+ DRIPutImage,
+ DRICopyArea,
+ DRICopyPlane,
+ DRIPolyPoint,
+ DRIPolylines,
+ DRIPolySegment,
+ DRIPolyRectangle,
+ DRIPolyArc,
+ DRIFillPolygon,
+ DRIPolyFillRect,
+ DRIPolyFillArc,
+ DRIPolyText8,
+ DRIPolyText16,
+ DRIImageText8,
+ DRIImageText16,
+ DRIImageGlyphBlt,
+ DRIPolyGlyphBlt,
+ DRIPushPixels
+};
+
+
+static Bool
+DRICreateGC(GCPtr pGC) {
+ ScreenPtr pScreen = pGC->pScreen;
+ DRIWrapScreenRec *pScreenPriv;
+ DRIGCRec *pGCPriv;
+ Bool ret;
+
+ pScreenPriv = dixLookupPrivate(&pScreen->devPrivates, driWrapScreenKey);
+
+ pGCPriv = DRIGetGCPriv(pGC);
+
+ unwrap(pScreenPriv, pScreen, CreateGC);
+ ret = pScreen->CreateGC(pGC);
+
+ if(ret) {
+ pGCPriv->originalOps = pGC->ops;
+ pGC->ops = &driGCOps;
+ pGCPriv->driOps = &driGCOps;
+ }
+
+ wrap(pScreenPriv, pScreen, CreateGC, DRICreateGC);
+
+ return ret;
+}
+
+
+/* Return false if an error occurred. */
+Bool
+DRIWrapInit(ScreenPtr pScreen) {
+ DRIWrapScreenRec *pScreenPriv;
+
+ if(!dixRequestPrivate(driGCKey, sizeof(DRIGCRec)))
+ return FALSE;
+
+ if(!dixRequestPrivate(driWrapScreenKey, sizeof(DRIWrapScreenRec)))
+ return FALSE;
+
+ pScreenPriv = malloc(sizeof(*pScreenPriv));
+
+ if(NULL == pScreenPriv)
+ return FALSE;
+
+ pScreenPriv->CreateGC = pScreen->CreateGC;
+ pScreen->CreateGC = DRICreateGC;
+
+ dixSetPrivate(&pScreen->devPrivates, driWrapScreenKey, pScreenPriv);
+
+ return TRUE;
+}
diff --git a/xorg-server/hw/xquartz/xpr/x-hook.c b/xorg-server/hw/xquartz/xpr/x-hook.c
index 5b850fe88..c65b6fc68 100644
--- a/xorg-server/hw/xquartz/xpr/x-hook.c
+++ b/xorg-server/hw/xquartz/xpr/x-hook.c
@@ -1,120 +1,120 @@
-/* x-hook.c
-
- Copyright (c) 2003 Apple Computer, 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 ABOVE LISTED COPYRIGHT
- HOLDER(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(s) of the above
- copyright holders shall not be used in advertising or otherwise to
- promote the sale, use or other dealings in this Software without
- prior written authorization. */
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "x-hook.h"
-#include <stdlib.h>
-#include <assert.h>
-#include "os.h"
-
-#define CELL_NEW(f,d) X_PFX (list_prepend) ((x_list *) (f), (d))
-#define CELL_FREE(c) X_PFX (list_free_1) (c)
-#define CELL_FUN(c) ((x_hook_function *) ((c)->next))
-#define CELL_DATA(c) ((c)->data)
-
-X_EXTERN x_list *
-X_PFX (hook_add) (x_list *lst, x_hook_function *fun, void *data)
-{
- return X_PFX (list_prepend) (lst, CELL_NEW (fun, data));
-}
-
-X_EXTERN x_list *
-X_PFX (hook_remove) (x_list *lst, x_hook_function *fun, void *data)
-{
- x_list *node, *cell;
- x_list *to_delete = NULL;
-
- for (node = lst; node != NULL; node = node->next)
- {
- cell = node->data;
- if (CELL_FUN (cell) == fun && CELL_DATA (cell) == data)
- to_delete = X_PFX (list_prepend) (to_delete, cell);
- }
-
- for (node = to_delete; node != NULL; node = node->next)
- {
- cell = node->data;
- lst = X_PFX (list_remove) (lst, cell);
- CELL_FREE (cell);
- }
-
- X_PFX (list_free) (to_delete);
- return lst;
-}
-
-X_EXTERN void
-X_PFX (hook_run) (x_list *lst, void *arg)
-{
- x_list *node, *cell;
- x_hook_function **fun;
- void **data;
- int length, i;
-
- if(!lst)
- return;
-
- length = X_PFX (list_length) (lst);
- fun = xalloc (sizeof (x_hook_function *) * length);
- data = xalloc (sizeof (void *) * length);
-
- if(!fun || !data) {
- FatalError("Failed to allocate memory in %s\n", __func__);
- }
-
- for (i = 0, node = lst; node != NULL; node = node->next, i++)
- {
- cell = node->data;
- fun[i] = CELL_FUN (cell);
- data[i] = CELL_DATA (cell);
- }
-
- for (i = 0; i < length; i++)
- {
- (*fun[i]) (arg, data[i]);
- }
-
- xfree(fun);
- xfree(data);
-}
-
-X_EXTERN void
-X_PFX (hook_free) (x_list *lst)
-{
- x_list *node;
-
- for (node = lst; node != NULL; node = node->next)
- {
- CELL_FREE (node->data);
- }
-
- X_PFX (list_free) (lst);
-}
+/* x-hook.c
+
+ Copyright (c) 2003 Apple Computer, 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 ABOVE LISTED COPYRIGHT
+ HOLDER(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(s) of the above
+ copyright holders shall not be used in advertising or otherwise to
+ promote the sale, use or other dealings in this Software without
+ prior written authorization. */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "x-hook.h"
+#include <stdlib.h>
+#include <assert.h>
+#include "os.h"
+
+#define CELL_NEW(f,d) X_PFX (list_prepend) ((x_list *) (f), (d))
+#define CELL_FREE(c) X_PFX (list_free_1) (c)
+#define CELL_FUN(c) ((x_hook_function *) ((c)->next))
+#define CELL_DATA(c) ((c)->data)
+
+X_EXTERN x_list *
+X_PFX (hook_add) (x_list *lst, x_hook_function *fun, void *data)
+{
+ return X_PFX (list_prepend) (lst, CELL_NEW (fun, data));
+}
+
+X_EXTERN x_list *
+X_PFX (hook_remove) (x_list *lst, x_hook_function *fun, void *data)
+{
+ x_list *node, *cell;
+ x_list *to_delete = NULL;
+
+ for (node = lst; node != NULL; node = node->next)
+ {
+ cell = node->data;
+ if (CELL_FUN (cell) == fun && CELL_DATA (cell) == data)
+ to_delete = X_PFX (list_prepend) (to_delete, cell);
+ }
+
+ for (node = to_delete; node != NULL; node = node->next)
+ {
+ cell = node->data;
+ lst = X_PFX (list_remove) (lst, cell);
+ CELL_FREE (cell);
+ }
+
+ X_PFX (list_free) (to_delete);
+ return lst;
+}
+
+X_EXTERN void
+X_PFX (hook_run) (x_list *lst, void *arg)
+{
+ x_list *node, *cell;
+ x_hook_function **fun;
+ void **data;
+ int length, i;
+
+ if(!lst)
+ return;
+
+ length = X_PFX (list_length) (lst);
+ fun = malloc(sizeof (x_hook_function *) * length);
+ data = malloc(sizeof (void *) * length);
+
+ if(!fun || !data) {
+ FatalError("Failed to allocate memory in %s\n", __func__);
+ }
+
+ for (i = 0, node = lst; node != NULL; node = node->next, i++)
+ {
+ cell = node->data;
+ fun[i] = CELL_FUN (cell);
+ data[i] = CELL_DATA (cell);
+ }
+
+ for (i = 0; i < length; i++)
+ {
+ (*fun[i]) (arg, data[i]);
+ }
+
+ free(fun);
+ free(data);
+}
+
+X_EXTERN void
+X_PFX (hook_free) (x_list *lst)
+{
+ x_list *node;
+
+ for (node = lst; node != NULL; node = node->next)
+ {
+ CELL_FREE (node->data);
+ }
+
+ X_PFX (list_free) (lst);
+}
diff --git a/xorg-server/hw/xquartz/xpr/xprCursor.c b/xorg-server/hw/xquartz/xpr/xprCursor.c
index fbaf825de..df9eef95e 100644
--- a/xorg-server/hw/xquartz/xpr/xprCursor.c
+++ b/xorg-server/hw/xquartz/xpr/xprCursor.c
@@ -1,418 +1,418 @@
-/**************************************************************
- *
- * Xplugin cursor support
- *
- * Copyright (c) 2001 Torrey T. Lyons and Greg Parker.
- * Copyright (c) 2002 Apple Computer, 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 ABOVE LISTED COPYRIGHT HOLDER(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(s) of the above copyright
- * holders shall not be used in advertising or otherwise to promote the sale,
- * use or other dealings in this Software without prior written authorization.
- */
-
-#include "sanitizedCarbon.h"
-
-#ifdef HAVE_DIX_CONFIG_H
-#include <dix-config.h>
-#endif
-
-#include "quartzCommon.h"
-#include "xpr.h"
-#include "darwin.h"
-#include "darwinEvents.h"
-#include <Xplugin.h>
-
-#include "mi.h"
-#include "scrnintstr.h"
-#include "cursorstr.h"
-#include "mipointrst.h"
-#include "windowstr.h"
-#include "globals.h"
-#include "servermd.h"
-#include "dixevents.h"
-#include "x-hash.h"
-
-typedef struct {
- int cursorVisible;
- QueryBestSizeProcPtr QueryBestSize;
- miPointerSpriteFuncPtr spriteFuncs;
-} QuartzCursorScreenRec, *QuartzCursorScreenPtr;
-
-static int darwinCursorScreenKeyIndex;
-static DevPrivateKey darwinCursorScreenKey = &darwinCursorScreenKeyIndex;
-
-#define CURSOR_PRIV(pScreen) ((QuartzCursorScreenPtr) \
- dixLookupPrivate(&pScreen->devPrivates, darwinCursorScreenKey))
-
-
-static Bool
-load_cursor(CursorPtr src, int screen)
-{
- uint32_t *data;
- uint32_t rowbytes;
- int width, height;
- int hot_x, hot_y;
-
- uint32_t fg_color, bg_color;
- uint8_t *srow, *sptr;
- uint8_t *mrow, *mptr;
- uint32_t *drow, *dptr;
- unsigned xcount, ycount;
-
- xp_error err;
-
- width = src->bits->width;
- height = src->bits->height;
- hot_x = src->bits->xhot;
- hot_y = src->bits->yhot;
-
-#ifdef ARGB_CURSOR
- if (src->bits->argb != NULL)
- {
-#if BITMAP_BIT_ORDER == MSBFirst
- rowbytes = src->bits->width * sizeof (CARD32);
- data = (uint32_t *) src->bits->argb;
-#else
- const uint32_t *be_data=(uint32_t *) src->bits->argb;
- unsigned i;
- rowbytes = src->bits->width * sizeof (CARD32);
- data = xalloc(rowbytes * src->bits->height);
- if(!data) {
- FatalError("Failed to allocate memory in %s\n", __func__);
- }
- for(i=0;i<(src->bits->width*src->bits->height);i++)
- data[i]=ntohl(be_data[i]);
-#endif
- }
- else
-#endif
- {
- fg_color = 0xFF00 | (src->foreRed >> 8);
- fg_color <<= 16;
- fg_color |= src->foreGreen & 0xFF00;
- fg_color |= src->foreBlue >> 8;
-
- bg_color = 0xFF00 | (src->backRed >> 8);
- bg_color <<= 16;
- bg_color |= src->backGreen & 0xFF00;
- bg_color |= src->backBlue >> 8;
-
- fg_color = htonl(fg_color);
- bg_color = htonl(bg_color);
-
- /* round up to 8 pixel boundary so we can convert whole bytes */
- rowbytes = ((src->bits->width * 4) + 31) & ~31;
- data = xalloc(rowbytes * src->bits->height);
- if(!data) {
- FatalError("Failed to allocate memory in %s\n", __func__);
- }
-
- if (!src->bits->emptyMask)
- {
- ycount = src->bits->height;
- srow = src->bits->source; mrow = src->bits->mask;
- drow = data;
-
- while (ycount-- > 0)
- {
- xcount = bits_to_bytes(src->bits->width);
- sptr = srow; mptr = mrow;
- dptr = drow;
-
- while (xcount-- > 0)
- {
- uint8_t s, m;
- int i;
-
- s = *sptr++; m = *mptr++;
- for (i = 0; i < 8; i++)
- {
-#if BITMAP_BIT_ORDER == MSBFirst
- if (m & 128)
- *dptr++ = (s & 128) ? fg_color : bg_color;
- else
- *dptr++ = 0;
- s <<= 1; m <<= 1;
-#else
- if (m & 1)
- *dptr++ = (s & 1) ? fg_color : bg_color;
- else
- *dptr++ = 0;
- s >>= 1; m >>= 1;
-#endif
- }
- }
-
- srow += BitmapBytePad(src->bits->width);
- mrow += BitmapBytePad(src->bits->width);
- drow = (uint32_t *) ((char *) drow + rowbytes);
- }
- }
- else
- {
- memset(data, 0, src->bits->height * rowbytes);
- }
- }
-
- err = xp_set_cursor(width, height, hot_x, hot_y, data, rowbytes);
- xfree(data);
- return err == Success;
-}
-
-
-/*
-===========================================================================
-
- Pointer sprite functions
-
-===========================================================================
-*/
-
-/*
- * QuartzRealizeCursor
- * Convert the X cursor representation to native format if possible.
- */
-static Bool
-QuartzRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
-{
- if(pCursor == NULL || pCursor->bits == NULL)
- return FALSE;
-
- /* FIXME: cache ARGB8888 representation? */
-
- return TRUE;
-}
-
-
-/*
- * QuartzUnrealizeCursor
- * Free the storage space associated with a realized cursor.
- */
-static Bool
-QuartzUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
-{
- return TRUE;
-}
-
-
-/*
- * QuartzSetCursor
- * Set the cursor sprite and position.
- */
-static void
-QuartzSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
-{
- QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
-
- if (!quartzServerVisible)
- return;
-
- if (pCursor == NULL)
- {
- if (ScreenPriv->cursorVisible)
- {
- xp_hide_cursor();
- ScreenPriv->cursorVisible = FALSE;
- }
- }
- else
- {
- load_cursor(pCursor, pScreen->myNum);
-
- if (!ScreenPriv->cursorVisible)
- {
- xp_show_cursor();
- ScreenPriv->cursorVisible = TRUE;
- }
- }
-}
-
-/*
- * QuartzMoveCursor
- * Move the cursor. This is a noop for us.
- */
-static void
-QuartzMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
-{
-}
-
-/*
-===========================================================================
-
- Pointer screen functions
-
-===========================================================================
-*/
-
-/*
- * QuartzCursorOffScreen
- */
-static Bool
-QuartzCursorOffScreen(ScreenPtr *pScreen, int *x, int *y)
-{
- return FALSE;
-}
-
-
-/*
- * QuartzCrossScreen
- */
-static void
-QuartzCrossScreen(ScreenPtr pScreen, Bool entering)
-{
- return;
-}
-
-
-/*
- * QuartzWarpCursor
- * Change the cursor position without generating an event or motion history.
- * The input coordinates (x,y) are in pScreen-local X11 coordinates.
- *
- */
-static void
-QuartzWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
-{
- if (quartzServerVisible)
- {
- int sx, sy;
-
- sx = dixScreenOrigins[pScreen->myNum].x + darwinMainScreenX;
- sy = dixScreenOrigins[pScreen->myNum].y + darwinMainScreenY;
-
- CGWarpMouseCursorPosition(CGPointMake(sx + x, sy + y));
- }
-
- miPointerWarpCursor(pDev, pScreen, x, y);
- miPointerUpdateSprite(pDev);
-}
-
-
-static miPointerScreenFuncRec quartzScreenFuncsRec = {
- QuartzCursorOffScreen,
- QuartzCrossScreen,
- QuartzWarpCursor,
- NULL,
- NULL
-};
-
-
-/*
-===========================================================================
-
- Other screen functions
-
-===========================================================================
-*/
-
-/*
- * QuartzCursorQueryBestSize
- * Handle queries for best cursor size
- */
-static void
-QuartzCursorQueryBestSize(int class, unsigned short *width,
- unsigned short *height, ScreenPtr pScreen)
-{
- QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
-
- if (class == CursorShape)
- {
- /* FIXME: query window server? */
- *width = 32;
- *height = 32;
- }
- else
- {
- (*ScreenPriv->QueryBestSize)(class, width, height, pScreen);
- }
-}
-
-/*
- * QuartzInitCursor
- * Initialize cursor support
- */
-Bool
-QuartzInitCursor(ScreenPtr pScreen)
-{
- QuartzCursorScreenPtr ScreenPriv;
- miPointerScreenPtr PointPriv;
-
- /* initialize software cursor handling (always needed as backup) */
- if (!miDCInitialize(pScreen, &quartzScreenFuncsRec))
- return FALSE;
-
- ScreenPriv = xcalloc(1, sizeof(QuartzCursorScreenRec));
- if (ScreenPriv == NULL)
- return FALSE;
-
- /* CURSOR_PRIV(pScreen) = ScreenPriv; */
- dixSetPrivate(&pScreen->devPrivates, darwinCursorScreenKey, ScreenPriv);
-
- /* override some screen procedures */
- ScreenPriv->QueryBestSize = pScreen->QueryBestSize;
- pScreen->QueryBestSize = QuartzCursorQueryBestSize;
-
- PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
-
- ScreenPriv->spriteFuncs = PointPriv->spriteFuncs;
-
- PointPriv->spriteFuncs->RealizeCursor = QuartzRealizeCursor;
- PointPriv->spriteFuncs->UnrealizeCursor = QuartzUnrealizeCursor;
- PointPriv->spriteFuncs->SetCursor = QuartzSetCursor;
- PointPriv->spriteFuncs->MoveCursor = QuartzMoveCursor;
-
- ScreenPriv->cursorVisible = TRUE;
- return TRUE;
-}
-
-/*
- * QuartzSuspendXCursor
- * X server is hiding. Restore the Aqua cursor.
- */
-void
-QuartzSuspendXCursor(ScreenPtr pScreen)
-{
-}
-
-
-/*
- * QuartzResumeXCursor
- * X server is showing. Restore the X cursor.
- */
-void
-QuartzResumeXCursor(ScreenPtr pScreen)
-{
- WindowPtr pWin;
- CursorPtr pCursor;
-
- /* TODO: Tablet? */
-
- pWin = GetSpriteWindow(darwinPointer);
- if (pWin->drawable.pScreen != pScreen)
- return;
-
- pCursor = GetSpriteCursor(darwinPointer);
- if (pCursor == NULL)
- return;
-
- QuartzSetCursor(darwinPointer, pScreen, pCursor, /* x */ 0, /* y */ 0);
-}
+/**************************************************************
+ *
+ * Xplugin cursor support
+ *
+ * Copyright (c) 2001 Torrey T. Lyons and Greg Parker.
+ * Copyright (c) 2002 Apple Computer, 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 ABOVE LISTED COPYRIGHT HOLDER(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(s) of the above copyright
+ * holders shall not be used in advertising or otherwise to promote the sale,
+ * use or other dealings in this Software without prior written authorization.
+ */
+
+#include "sanitizedCarbon.h"
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include "quartzCommon.h"
+#include "xpr.h"
+#include "darwin.h"
+#include "darwinEvents.h"
+#include <Xplugin.h>
+
+#include "mi.h"
+#include "scrnintstr.h"
+#include "cursorstr.h"
+#include "mipointrst.h"
+#include "windowstr.h"
+#include "globals.h"
+#include "servermd.h"
+#include "dixevents.h"
+#include "x-hash.h"
+
+typedef struct {
+ int cursorVisible;
+ QueryBestSizeProcPtr QueryBestSize;
+ miPointerSpriteFuncPtr spriteFuncs;
+} QuartzCursorScreenRec, *QuartzCursorScreenPtr;
+
+static int darwinCursorScreenKeyIndex;
+static DevPrivateKey darwinCursorScreenKey = &darwinCursorScreenKeyIndex;
+
+#define CURSOR_PRIV(pScreen) ((QuartzCursorScreenPtr) \
+ dixLookupPrivate(&pScreen->devPrivates, darwinCursorScreenKey))
+
+
+static Bool
+load_cursor(CursorPtr src, int screen)
+{
+ uint32_t *data;
+ uint32_t rowbytes;
+ int width, height;
+ int hot_x, hot_y;
+
+ uint32_t fg_color, bg_color;
+ uint8_t *srow, *sptr;
+ uint8_t *mrow, *mptr;
+ uint32_t *drow, *dptr;
+ unsigned xcount, ycount;
+
+ xp_error err;
+
+ width = src->bits->width;
+ height = src->bits->height;
+ hot_x = src->bits->xhot;
+ hot_y = src->bits->yhot;
+
+#ifdef ARGB_CURSOR
+ if (src->bits->argb != NULL)
+ {
+#if BITMAP_BIT_ORDER == MSBFirst
+ rowbytes = src->bits->width * sizeof (CARD32);
+ data = (uint32_t *) src->bits->argb;
+#else
+ const uint32_t *be_data=(uint32_t *) src->bits->argb;
+ unsigned i;
+ rowbytes = src->bits->width * sizeof (CARD32);
+ data = malloc(rowbytes * src->bits->height);
+ if(!data) {
+ FatalError("Failed to allocate memory in %s\n", __func__);
+ }
+ for(i=0;i<(src->bits->width*src->bits->height);i++)
+ data[i]=ntohl(be_data[i]);
+#endif
+ }
+ else
+#endif
+ {
+ fg_color = 0xFF00 | (src->foreRed >> 8);
+ fg_color <<= 16;
+ fg_color |= src->foreGreen & 0xFF00;
+ fg_color |= src->foreBlue >> 8;
+
+ bg_color = 0xFF00 | (src->backRed >> 8);
+ bg_color <<= 16;
+ bg_color |= src->backGreen & 0xFF00;
+ bg_color |= src->backBlue >> 8;
+
+ fg_color = htonl(fg_color);
+ bg_color = htonl(bg_color);
+
+ /* round up to 8 pixel boundary so we can convert whole bytes */
+ rowbytes = ((src->bits->width * 4) + 31) & ~31;
+ data = malloc(rowbytes * src->bits->height);
+ if(!data) {
+ FatalError("Failed to allocate memory in %s\n", __func__);
+ }
+
+ if (!src->bits->emptyMask)
+ {
+ ycount = src->bits->height;
+ srow = src->bits->source; mrow = src->bits->mask;
+ drow = data;
+
+ while (ycount-- > 0)
+ {
+ xcount = bits_to_bytes(src->bits->width);
+ sptr = srow; mptr = mrow;
+ dptr = drow;
+
+ while (xcount-- > 0)
+ {
+ uint8_t s, m;
+ int i;
+
+ s = *sptr++; m = *mptr++;
+ for (i = 0; i < 8; i++)
+ {
+#if BITMAP_BIT_ORDER == MSBFirst
+ if (m & 128)
+ *dptr++ = (s & 128) ? fg_color : bg_color;
+ else
+ *dptr++ = 0;
+ s <<= 1; m <<= 1;
+#else
+ if (m & 1)
+ *dptr++ = (s & 1) ? fg_color : bg_color;
+ else
+ *dptr++ = 0;
+ s >>= 1; m >>= 1;
+#endif
+ }
+ }
+
+ srow += BitmapBytePad(src->bits->width);
+ mrow += BitmapBytePad(src->bits->width);
+ drow = (uint32_t *) ((char *) drow + rowbytes);
+ }
+ }
+ else
+ {
+ memset(data, 0, src->bits->height * rowbytes);
+ }
+ }
+
+ err = xp_set_cursor(width, height, hot_x, hot_y, data, rowbytes);
+ free(data);
+ return err == Success;
+}
+
+
+/*
+===========================================================================
+
+ Pointer sprite functions
+
+===========================================================================
+*/
+
+/*
+ * QuartzRealizeCursor
+ * Convert the X cursor representation to native format if possible.
+ */
+static Bool
+QuartzRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
+{
+ if(pCursor == NULL || pCursor->bits == NULL)
+ return FALSE;
+
+ /* FIXME: cache ARGB8888 representation? */
+
+ return TRUE;
+}
+
+
+/*
+ * QuartzUnrealizeCursor
+ * Free the storage space associated with a realized cursor.
+ */
+static Bool
+QuartzUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
+{
+ return TRUE;
+}
+
+
+/*
+ * QuartzSetCursor
+ * Set the cursor sprite and position.
+ */
+static void
+QuartzSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
+{
+ QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
+
+ if (!quartzServerVisible)
+ return;
+
+ if (pCursor == NULL)
+ {
+ if (ScreenPriv->cursorVisible)
+ {
+ xp_hide_cursor();
+ ScreenPriv->cursorVisible = FALSE;
+ }
+ }
+ else
+ {
+ load_cursor(pCursor, pScreen->myNum);
+
+ if (!ScreenPriv->cursorVisible)
+ {
+ xp_show_cursor();
+ ScreenPriv->cursorVisible = TRUE;
+ }
+ }
+}
+
+/*
+ * QuartzMoveCursor
+ * Move the cursor. This is a noop for us.
+ */
+static void
+QuartzMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
+{
+}
+
+/*
+===========================================================================
+
+ Pointer screen functions
+
+===========================================================================
+*/
+
+/*
+ * QuartzCursorOffScreen
+ */
+static Bool
+QuartzCursorOffScreen(ScreenPtr *pScreen, int *x, int *y)
+{
+ return FALSE;
+}
+
+
+/*
+ * QuartzCrossScreen
+ */
+static void
+QuartzCrossScreen(ScreenPtr pScreen, Bool entering)
+{
+ return;
+}
+
+
+/*
+ * QuartzWarpCursor
+ * Change the cursor position without generating an event or motion history.
+ * The input coordinates (x,y) are in pScreen-local X11 coordinates.
+ *
+ */
+static void
+QuartzWarpCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
+{
+ if (quartzServerVisible)
+ {
+ int sx, sy;
+
+ sx = dixScreenOrigins[pScreen->myNum].x + darwinMainScreenX;
+ sy = dixScreenOrigins[pScreen->myNum].y + darwinMainScreenY;
+
+ CGWarpMouseCursorPosition(CGPointMake(sx + x, sy + y));
+ }
+
+ miPointerWarpCursor(pDev, pScreen, x, y);
+ miPointerUpdateSprite(pDev);
+}
+
+
+static miPointerScreenFuncRec quartzScreenFuncsRec = {
+ QuartzCursorOffScreen,
+ QuartzCrossScreen,
+ QuartzWarpCursor,
+ NULL,
+ NULL
+};
+
+
+/*
+===========================================================================
+
+ Other screen functions
+
+===========================================================================
+*/
+
+/*
+ * QuartzCursorQueryBestSize
+ * Handle queries for best cursor size
+ */
+static void
+QuartzCursorQueryBestSize(int class, unsigned short *width,
+ unsigned short *height, ScreenPtr pScreen)
+{
+ QuartzCursorScreenPtr ScreenPriv = CURSOR_PRIV(pScreen);
+
+ if (class == CursorShape)
+ {
+ /* FIXME: query window server? */
+ *width = 32;
+ *height = 32;
+ }
+ else
+ {
+ (*ScreenPriv->QueryBestSize)(class, width, height, pScreen);
+ }
+}
+
+/*
+ * QuartzInitCursor
+ * Initialize cursor support
+ */
+Bool
+QuartzInitCursor(ScreenPtr pScreen)
+{
+ QuartzCursorScreenPtr ScreenPriv;
+ miPointerScreenPtr PointPriv;
+
+ /* initialize software cursor handling (always needed as backup) */
+ if (!miDCInitialize(pScreen, &quartzScreenFuncsRec))
+ return FALSE;
+
+ ScreenPriv = calloc(1, sizeof(QuartzCursorScreenRec));
+ if (ScreenPriv == NULL)
+ return FALSE;
+
+ /* CURSOR_PRIV(pScreen) = ScreenPriv; */
+ dixSetPrivate(&pScreen->devPrivates, darwinCursorScreenKey, ScreenPriv);
+
+ /* override some screen procedures */
+ ScreenPriv->QueryBestSize = pScreen->QueryBestSize;
+ pScreen->QueryBestSize = QuartzCursorQueryBestSize;
+
+ PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey);
+
+ ScreenPriv->spriteFuncs = PointPriv->spriteFuncs;
+
+ PointPriv->spriteFuncs->RealizeCursor = QuartzRealizeCursor;
+ PointPriv->spriteFuncs->UnrealizeCursor = QuartzUnrealizeCursor;
+ PointPriv->spriteFuncs->SetCursor = QuartzSetCursor;
+ PointPriv->spriteFuncs->MoveCursor = QuartzMoveCursor;
+
+ ScreenPriv->cursorVisible = TRUE;
+ return TRUE;
+}
+
+/*
+ * QuartzSuspendXCursor
+ * X server is hiding. Restore the Aqua cursor.
+ */
+void
+QuartzSuspendXCursor(ScreenPtr pScreen)
+{
+}
+
+
+/*
+ * QuartzResumeXCursor
+ * X server is showing. Restore the X cursor.
+ */
+void
+QuartzResumeXCursor(ScreenPtr pScreen)
+{
+ WindowPtr pWin;
+ CursorPtr pCursor;
+
+ /* TODO: Tablet? */
+
+ pWin = GetSpriteWindow(darwinPointer);
+ if (pWin->drawable.pScreen != pScreen)
+ return;
+
+ pCursor = GetSpriteCursor(darwinPointer);
+ if (pCursor == NULL)
+ return;
+
+ QuartzSetCursor(darwinPointer, pScreen, pCursor, /* x */ 0, /* y */ 0);
+}
diff --git a/xorg-server/hw/xquartz/xpr/xprScreen.c b/xorg-server/hw/xquartz/xpr/xprScreen.c
index 44067862f..bc68f7923 100644
--- a/xorg-server/hw/xquartz/xpr/xprScreen.c
+++ b/xorg-server/hw/xquartz/xpr/xprScreen.c
@@ -195,7 +195,7 @@ xprAddPseudoramiXScreens(int *x, int *y, int *width, int *height)
return;
}
- displayList = xalloc(displayCount * sizeof(CGDirectDisplayID));
+ displayList = malloc(displayCount * sizeof(CGDirectDisplayID));
if(!displayList)
FatalError("Unable to allocate memory for list of displays.\n");
CGGetActiveDisplayList(displayCount, displayList, &displayCount);
@@ -232,7 +232,7 @@ xprAddPseudoramiXScreens(int *x, int *y, int *width, int *height)
frame.size.width, frame.size.height);
}
- xfree(displayList);
+ free(displayList);
}
/*
diff --git a/xorg-server/hw/xwin/glx/indirect.c b/xorg-server/hw/xwin/glx/indirect.c
index 48094a69e..08c16f85d 100644
--- a/xorg-server/hw/xwin/glx/indirect.c
+++ b/xorg-server/hw/xwin/glx/indirect.c
@@ -1,2464 +1,2464 @@
-/*
- * File: indirect.c
- * Purpose: A GLX implementation that uses Windows OpenGL library
- *
- * Authors: Alexander Gottwald
- * Jon TURNEY
- *
- * Copyright (c) Jon TURNEY 2009
- * Copyright (c) Alexander Gottwald 2004
- *
- * Portions of this file are copied from GL/apple/indirect.c,
- * which contains the following copyright:
- *
- * Copyright (c) 2007, 2008, 2009 Apple Inc.
- * Copyright (c) 2004 Torrey T. Lyons. All Rights Reserved.
- * Copyright (c) 2002 Greg Parker. All Rights Reserved.
- *
- * Portions of this file are copied from Mesa's xf86glx.c,
- * which contains the following copyright:
- *
- * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
- * 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 ABOVE LISTED COPYRIGHT HOLDER(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.
- */
-
-/*
- TODO:
- - hook up remaining unimplemented extensions
- - research what guarantees glXWaitX, glXWaitGL are supposed to offer, and implement then
- using GdiFlush and/or glFinish
- - pbuffer clobbering: we don't get async notification, but can we arrange to emit the
- event when we notice it's been clobbered? at the very least, check if it's been clobbered
- before using it?
- - are the __GLXConfig * we get handed back ones we are made (so we can extend the structure
- with privates?) Or are they created inside the GLX core as well?
-*/
-
-/*
- MSDN clarifications:
-
- It says SetPixelFormat()'s PIXELFORMATDESCRIPTOR pointer argument has no effect
- except on metafiles, this seems to mean that as it's ok to supply NULL if the DC
- is not for a metafile
-
- wglMakeCurrent ignores the hdc if hglrc is NULL, so wglMakeCurrent(NULL, NULL)
- is used to make no context current
-
-*/
-
-#ifdef HAVE_XWIN_CONFIG_H
-#include <xwin-config.h>
-#endif
-
-#include "glwindows.h"
-#include <glx/glxserver.h>
-#include <glx/glxutil.h>
-#include <glx/extension_string.h>
-#include <GL/glxtokens.h>
-
-#include <winpriv.h>
-#include <wgl_ext_api.h>
-#include "win.h"
-#include <winmsg.h>
-
-extern Bool g_fXdmcpEnabled;
-extern Bool g_fNativeGl;
-
-#define NUM_ELEMENTS(x) (sizeof(x)/ sizeof(x[1]))
-
-/* ---------------------------------------------------------------------- */
-/*
- * structure definitions
- */
-
-typedef struct __GLXWinContext __GLXWinContext;
-typedef struct __GLXWinDrawable __GLXWinDrawable;
-typedef struct __GLXWinScreen glxWinScreen;
-typedef struct __GLXWinConfig GLXWinConfig;
-
-struct __GLXWinContext {
- __GLXcontext base;
- HGLRC ctx; /* Windows GL Context */
- HDC hDC; /* Windows device context */
- HDC hreadDC; /* Windows device read context */
- __GLXWinContext *shareContext; /* Context with which we will share display lists and textures */
- HWND hwnd; /* For detecting when HWND has changed */
- HWND hreadwnd;
-};
-
-struct __GLXWinDrawable
-{
- __GLXdrawable base;
- __GLXWinContext *drawContext;
-
- /* If this drawable is GLX_DRAWABLE_PBUFFER */
- HPBUFFERARB hPbuffer;
-
- /* If this drawable is GLX_DRAWABLE_PIXMAP */
- HDC dibDC;
- HBITMAP hDIB;
- HBITMAP hOldDIB; /* original DIB for DC */
- void *pOldBits; /* original pBits for this drawable's pixmap */
-};
-
-struct __GLXWinScreen
-{
- __GLXscreen base;
-
- /* Supported GLX extensions */
- unsigned char glx_enable_bits[__GLX_EXT_BYTES];
-
- Bool has_WGL_ARB_multisample;
- Bool has_WGL_ARB_pixel_format;
- Bool has_WGL_ARB_pbuffer;
- Bool has_WGL_ARB_render_texture;
-
- /* wrapped screen functions */
- RealizeWindowProcPtr RealizeWindow;
- UnrealizeWindowProcPtr UnrealizeWindow;
- DestroyWindowProcPtr DestroyWindow;
- CopyWindowProcPtr CopyWindow;
- PositionWindowProcPtr PositionWindow;
-};
-
-struct __GLXWinConfig
-{
- __GLXconfig base;
- int pixelFormatIndex;
-};
-
-/* ---------------------------------------------------------------------- */
-/*
- * Various debug helpers
- */
-
-#ifdef _DEBUG
-void GLWIN_DEBUG_HWND(HWND hwnd)
-{
- if (glxWinDebugSettings.dumpHWND)
- {
- char buffer[1024];
- RECT Rect;
- HDC hDc=GetDC(hwnd);
-
- if (GetWindowText(hwnd, buffer, sizeof(buffer))==0) *buffer=0;
- GetWindowRect(hwnd,&Rect);
-
- GLWIN_DEBUG_MSG("Got HWND %p (hdc %p) for window '%s' (%d,%d,%d,%d)", hwnd, hDc, buffer, Rect.left, Rect.top, Rect.right, Rect.bottom);
- ReleaseDC(hwnd,hDc);
- }
-}
-
-void GLWIN_HDC_DEBUG_MSG(const char *Message, HDC hDc, HWND hwnd)
-{
- char buffer[1024];
- RECT Rect;
-
- if (GetWindowText(hwnd, buffer, sizeof(buffer))==0) *buffer=0;
- GetWindowRect(hwnd,&Rect);
-
- GLWIN_DEBUG_MSG("Got HDC %p (hwnd %p) for window '%s' (%d,%d,%d,%d)", hDc, hwnd, buffer, Rect.left, Rect.top, Rect.right, Rect.bottom);
-
-}
-
-glxWinDebugSettingsRec glxWinDebugSettings = { 0, 0, 0, 0, 0, 0};
-
-static void glxWinInitDebugSettings(void)
-{
- char *envptr;
-
- envptr = getenv("GLWIN_ENABLE_DEBUG");
- if (envptr != NULL)
- glxWinDebugSettings.enableDebug = (atoi(envptr) == 1);
-
- envptr = getenv("GLWIN_ENABLE_TRACE");
- if (envptr != NULL)
- glxWinDebugSettings.enableTrace = (atoi(envptr) == 1);
-
- envptr = getenv("GLWIN_DUMP_PFD");
- if (envptr != NULL)
- glxWinDebugSettings.dumpPFD = (atoi(envptr) == 1);
-
- envptr = getenv("GLWIN_DUMP_HWND");
- if (envptr != NULL)
- glxWinDebugSettings.dumpHWND = (atoi(envptr) == 1);
-
- envptr = getenv("GLWIN_DUMP_DC");
- if (envptr != NULL)
- glxWinDebugSettings.dumpDC = (atoi(envptr) == 1);
-
- envptr = getenv("GLWIN_ENABLE_GLCALL_TRACE");
- if (envptr != NULL)
- glxWinDebugSettings.enableGLcallTrace = (atoi(envptr) == 1);
-
- envptr = getenv("GLWIN_ENABLE_WGLCALL_TRACE");
- if (envptr != NULL)
- glxWinDebugSettings.enableWGLcallTrace = (atoi(envptr) == 1);
-
- envptr = getenv("GLWIN_DEBUG_ALL");
- if (envptr != NULL)
- {
- glxWinDebugSettings.enableDebug = 1;
- glxWinDebugSettings.enableTrace = 1;
- glxWinDebugSettings.dumpPFD = 1;
- glxWinDebugSettings.dumpHWND = 1;
- glxWinDebugSettings.dumpDC = 1;
- glxWinDebugSettings.enableGLcallTrace = 1;
- glxWinDebugSettings.enableWGLcallTrace = 1;
- }
-}
-#endif
-
-static
-const char *glxWinErrorMessage(void)
-{
- static char errorbuffer[1024];
- DWORD Error=GetLastError();
- int offset;
-
- sprintf(errorbuffer, "%p ",Error);
- offset=strlen(errorbuffer);
-
- if (!FormatMessage(
- FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- Error,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- (LPTSTR) &errorbuffer[offset],
- sizeof(errorbuffer),
- NULL ))
- {
- snprintf(errorbuffer, sizeof(errorbuffer), "Unknown error in FormatMessage: %08x!", (unsigned)GetLastError());
- }
-
- if (errorbuffer[strlen(errorbuffer)-1] == '\n')
- errorbuffer[strlen(errorbuffer)-1] = 0;
-
- return errorbuffer;
-}
-
-static void pfdOut(const PIXELFORMATDESCRIPTOR *pfd);
-
-#ifdef _DEBUG
-
-#define DUMP_PFD_FLAG(flag) \
- if (pfd->dwFlags & flag) { \
- ErrorF("%s%s", pipesym, #flag); \
- pipesym = " | "; \
- }
-
-static void pfdOut(const PIXELFORMATDESCRIPTOR *pfd)
-{
- const char *pipesym = ""; /* will be set after first flag dump */
- ErrorF("PIXELFORMATDESCRIPTOR:\n");
- ErrorF("nSize = %u\n", pfd->nSize);
- ErrorF("nVersion = %u\n", pfd->nVersion);
- ErrorF("dwFlags = %lu = {", pfd->dwFlags);
- DUMP_PFD_FLAG(PFD_DOUBLEBUFFER);
- DUMP_PFD_FLAG(PFD_STEREO);
- DUMP_PFD_FLAG(PFD_DRAW_TO_WINDOW);
- DUMP_PFD_FLAG(PFD_DRAW_TO_BITMAP);
- DUMP_PFD_FLAG(PFD_SUPPORT_GDI);
- DUMP_PFD_FLAG(PFD_SUPPORT_OPENGL);
- DUMP_PFD_FLAG(PFD_GENERIC_FORMAT);
- DUMP_PFD_FLAG(PFD_NEED_PALETTE);
- DUMP_PFD_FLAG(PFD_NEED_SYSTEM_PALETTE);
- DUMP_PFD_FLAG(PFD_SWAP_EXCHANGE);
- DUMP_PFD_FLAG(PFD_SWAP_COPY);
- DUMP_PFD_FLAG(PFD_SWAP_LAYER_BUFFERS);
- DUMP_PFD_FLAG(PFD_GENERIC_ACCELERATED);
- DUMP_PFD_FLAG(PFD_DEPTH_DONTCARE);
- DUMP_PFD_FLAG(PFD_DOUBLEBUFFER_DONTCARE);
- DUMP_PFD_FLAG(PFD_STEREO_DONTCARE);
- ErrorF("}\n");
-
- ErrorF("iPixelType = %hu = %s\n", pfd->iPixelType,
- (pfd->iPixelType == PFD_TYPE_RGBA ? "PFD_TYPE_RGBA" : "PFD_TYPE_COLORINDEX"));
- ErrorF("cColorBits = %hhu\n", pfd->cColorBits);
- ErrorF("cRedBits = %hhu\n", pfd->cRedBits);
- ErrorF("cRedShift = %hhu\n", pfd->cRedShift);
- ErrorF("cGreenBits = %hhu\n", pfd->cGreenBits);
- ErrorF("cGreenShift = %hhu\n", pfd->cGreenShift);
- ErrorF("cBlueBits = %hhu\n", pfd->cBlueBits);
- ErrorF("cBlueShift = %hhu\n", pfd->cBlueShift);
- ErrorF("cAlphaBits = %hhu\n", pfd->cAlphaBits);
- ErrorF("cAlphaShift = %hhu\n", pfd->cAlphaShift);
- ErrorF("cAccumBits = %hhu\n", pfd->cAccumBits);
- ErrorF("cAccumRedBits = %hhu\n", pfd->cAccumRedBits);
- ErrorF("cAccumGreenBits = %hhu\n", pfd->cAccumGreenBits);
- ErrorF("cAccumBlueBits = %hhu\n", pfd->cAccumBlueBits);
- ErrorF("cAccumAlphaBits = %hhu\n", pfd->cAccumAlphaBits);
- ErrorF("cDepthBits = %hhu\n", pfd->cDepthBits);
- ErrorF("cStencilBits = %hhu\n", pfd->cStencilBits);
- ErrorF("cAuxBuffers = %hhu\n", pfd->cAuxBuffers);
- ErrorF("iLayerType = %hhu\n", pfd->iLayerType);
- ErrorF("bReserved = %hhu\n", pfd->bReserved);
- ErrorF("dwLayerMask = %lu\n", pfd->dwLayerMask);
- ErrorF("dwVisibleMask = %lu\n", pfd->dwVisibleMask);
- ErrorF("dwDamageMask = %lu\n", pfd->dwDamageMask);
- ErrorF("\n");
-}
-
-static const char *
-visual_class_name(int cls)
-{
- switch (cls) {
- case GLX_STATIC_COLOR:
- return "StaticColor";
- case GLX_PSEUDO_COLOR:
- return "PseudoColor";
- case GLX_STATIC_GRAY:
- return "StaticGray";
- case GLX_GRAY_SCALE:
- return "GrayScale";
- case GLX_TRUE_COLOR:
- return "TrueColor";
- case GLX_DIRECT_COLOR:
- return "DirectColor";
- default:
- return "-none-";
- }
-}
-
-static const char *
-swap_method_name(int mthd)
-{
- switch (mthd)
- {
- case GLX_SWAP_EXCHANGE_OML:
- return "xchg";
- case GLX_SWAP_COPY_OML:
- return "copy";
- case GLX_SWAP_UNDEFINED_OML:
- return " ";
- default:
- return "????";
- }
-}
-
-static void
-fbConfigsDump(unsigned int n, __GLXconfig *c)
-{
- ErrorF("%d fbConfigs\n", n);
- ErrorF("pxf vis fb render Ste aux accum MS drawable Group/\n");
- ErrorF("idx ID ID VisualType Depth Lvl RGB CI DB Swap reo R G B A Z S buf AR AG AB AA bufs num W P Pb Float Trans Caveat\n");
- ErrorF("-----------------------------------------------------------------------------------------------------------------------------\n");
-
- while (c != NULL)
- {
- unsigned int i = ((GLXWinConfig *)c)->pixelFormatIndex;
-
- ErrorF("%3d %2x %2x "
- "%-11s"
- " %3d %3d %s %s %s %s %s "
- "%2d %2d %2d %2d "
- "%2d %2d "
- "%2d "
- "%2d %2d %2d %2d"
- " %2d %2d"
- " %s %s %s "
- " %s "
- " %s "
- " %d %s"
- "\n",
- i, c->visualID, c->fbconfigID,
- visual_class_name(c->visualType),
- c->rgbBits ? c->rgbBits : c->indexBits,
- c->level,
- (c->renderType & GLX_RGBA_BIT) ? "y" : ".",
- (c->renderType & GLX_COLOR_INDEX_BIT) ? "y" : ".",
- c->doubleBufferMode ? "y" : ".",
- swap_method_name(c->swapMethod),
- c->stereoMode ? "y" : ".",
- c->redBits, c->greenBits, c->blueBits, c->alphaBits,
- c->depthBits, c->stencilBits,
- c->numAuxBuffers,
- c->accumRedBits, c->accumGreenBits, c->accumBlueBits, c->accumAlphaBits,
- c->sampleBuffers, c->samples,
- (c->drawableType & GLX_WINDOW_BIT) ? "y" : ".",
- (c->drawableType & GLX_PIXMAP_BIT) ? "y" : ".",
- (c->drawableType & GLX_PBUFFER_BIT) ? "y" : ".",
- ".",
- (c->transparentPixel != GLX_NONE_EXT) ? "y" : ".",
- c->visualSelectGroup, (c->visualRating == GLX_SLOW_VISUAL_EXT) ? "*" : " ");
-
- c = c->next;
- }
-}
-#endif
-
-/* ---------------------------------------------------------------------- */
-/*
- * Forward declarations
- */
-
-static __GLXscreen *glxWinScreenProbe(ScreenPtr pScreen);
-static __GLXcontext *glxWinCreateContext(__GLXscreen *screen,
- __GLXconfig *modes,
- __GLXcontext *baseShareContext);
-static __GLXdrawable *glxWinCreateDrawable(ClientPtr client,
- __GLXscreen *screen,
- DrawablePtr pDraw,
- XID drawId,
- int type,
- XID glxDrawId,
- __GLXconfig *conf);
-
-static Bool glxWinRealizeWindow(WindowPtr pWin);
-static Bool glxWinUnrealizeWindow(WindowPtr pWin);
-static Bool glxWinDestroyWindow(WindowPtr pWin);
-static void glxWinCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
-static Bool glxWinPositionWindow(WindowPtr pWindow, int x, int y);
-
-static HDC glxWinMakeDC(__GLXWinContext *gc, __GLXWinDrawable *draw, HWND *hwnd);
-static void glxWinReleaseDC(HWND hwnd, HDC hdc, __GLXWinDrawable *draw);
-
-static void glxWinCreateConfigs(HDC dc, glxWinScreen *screen);
-static void glxWinCreateConfigsExt(HDC hdc, glxWinScreen *screen);
-static int fbConfigToPixelFormat(__GLXconfig *mode, PIXELFORMATDESCRIPTOR *pfdret, int drawableTypeOverride);
-static int fbConfigToPixelFormatIndex(HDC hdc, __GLXconfig *mode, int drawableTypeOverride, glxWinScreen *winScreen);
-
-/* ---------------------------------------------------------------------- */
-/*
- * The GLX provider
- */
-
-__GLXprovider __glXWGLProvider = {
- glxWinScreenProbe,
- "Win32 native WGL",
- NULL
-};
-
-void
-glxWinPushNativeProvider(void)
-{
- if (g_fNativeGl)
- GlxPushProvider(&__glXWGLProvider);
-}
-
-/* ---------------------------------------------------------------------- */
-/*
- * Screen functions
- */
-
-static void
-glxWinScreenDestroy(__GLXscreen *screen)
-{
- GLWIN_DEBUG_MSG("glxWinScreenDestroy(%p)", screen);
- __glXScreenDestroy(screen);
- xfree(screen);
-}
-
-static int
-glxWinScreenSwapInterval(__GLXdrawable *drawable, int interval)
-{
- BOOL ret = wglSwapIntervalEXTWrapper(interval);
- if (!ret)
- {
- ErrorF("wglSwapIntervalEXT interval %d failed:%s\n", interval, glxWinErrorMessage());
- }
- return ret;
-}
-
-static LRESULT CALLBACK GlxWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- if (uMsg== WM_NCHITTEST)
- {
- return HTTRANSPARENT;
- }
- else
- return DefWindowProc(hwnd, uMsg, wParam, lParam);
-}
-
-/*
- Report the extensions split and formatted to avoid overflowing a line
- */
-static void
-glxLogExtensions(const char *prefix, const char *extensions)
-{
- int length = 0;
- char *strl;
- char *str = xalloc(strlen(extensions) + 1);
-
- if (str == NULL)
- {
- ErrorF("glxLogExtensions: xalloc error\n");
- return;
- }
-
- str[strlen(extensions)] = '\0';
- strncpy (str, extensions, strlen(extensions));
-
- strl = strtok(str, " ");
- winDebug("%s%s", prefix, strl);
- length = strlen(prefix) + strlen(strl);
-
- while (1)
- {
- strl = strtok(NULL, " ");
- if (strl == NULL) break;
-
- if (length + strlen(strl) + 1 > 120)
- {
- winDebug("\n");
- winDebug("%s",prefix);
- length = strlen(prefix);
- }
- else
- {
- winDebug(" ");
- length++;
- }
-
- winDebug("%s", strl);
- length = length + strlen(strl);
- }
-
- winDebug("\n");
-
- xfree(str);
-}
-
-/* This is called by GlxExtensionInit() asking the GLX provider if it can handle the screen... */
-static __GLXscreen *
-glxWinScreenProbe(ScreenPtr pScreen)
-{
- glxWinScreen *screen;
- const char *gl_extensions;
- const char *wgl_extensions;
- HWND hwnd;
- HDC hdc;
- HGLRC hglrc;
-
- GLWIN_DEBUG_MSG("glxWinScreenProbe");
-
-#ifdef _DEBUG
- glxWinInitDebugSettings();
-#endif
-
- if (pScreen == NULL)
- return NULL;
-
- if (!winCheckScreenAiglxIsSupported(pScreen))
- {
- LogMessage(X_ERROR,"AIGLX: No native OpenGL in modes with a root window\n");
- return NULL;
- }
-
- screen = xcalloc(1, sizeof(glxWinScreen));
-
- if (NULL == screen)
- return NULL;
-
- /* Wrap RealizeWindow, UnrealizeWindow and CopyWindow on this screen */
- screen->RealizeWindow = pScreen->RealizeWindow;
- pScreen->RealizeWindow = glxWinRealizeWindow;
- screen->UnrealizeWindow = pScreen->UnrealizeWindow;
- pScreen->UnrealizeWindow = glxWinUnrealizeWindow;
- screen->CopyWindow = pScreen->CopyWindow;
- pScreen->CopyWindow = glxWinCopyWindow;
- screen->PositionWindow = pScreen->PositionWindow;
- pScreen->PositionWindow = glxWinPositionWindow;
- screen->DestroyWindow = pScreen->DestroyWindow;
- pScreen->DestroyWindow = glxWinDestroyWindow;
-
- /* Dump out some useful information about the native renderer */
-
- // create window class
- {
- static wATOM glTestWndClass = 0;
- if (glTestWndClass == 0)
- {
- WNDCLASSEX wc;
- glTestWndClass=1;
- wc.cbSize = sizeof(WNDCLASSEX);
- wc.style = CS_OWNDC ;
- wc.lpfnWndProc = GlxWindowProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = 0;
- wc.hInstance = GetModuleHandle(NULL);
- wc.hIcon = 0;
- wc.hCursor = 0;
- wc.hbrBackground = 0;
- wc.lpszMenuName = NULL;
- wc.lpszClassName = WIN_GL_WINDOW_CLASS;
- wc.hIconSm = 0;
- RegisterClassEx (&wc);
- }
- }
-
- // create an invisible window for a scratch DC
- hwnd = CreateWindowExA(0,
- WIN_GL_WINDOW_CLASS,
- "XWin GL Renderer Capabilities Test Window",
- 0, 0, 0, 0, 0, NULL, NULL, GetModuleHandle(NULL), NULL);
- if (hwnd == NULL)
- LogMessage(X_ERROR,"AIGLX: Couldn't create a window for render capabilities testing\n");
-
- hdc = GetDC(hwnd);
-
- // we must set a pixel format before we can create a context, just use the first one...
- SetPixelFormat(hdc, 1, NULL);
- hglrc = wglCreateContext(hdc);
- wglMakeCurrent(hdc, hglrc);
-
- // initialize wgl extension proc pointers (don't call them before here...)
- // (but we need to have a current context for them to be resolvable)
- wglResolveExtensionProcs();
-
- winDebug("GL_VERSION: %s\n", glGetStringWrapperNonstatic(GL_VERSION));
- winDebug("GL_VENDOR: %s\n", glGetStringWrapperNonstatic(GL_VENDOR));
- winDebug("GL_RENDERER: %s\n", glGetStringWrapperNonstatic(GL_RENDERER));
- gl_extensions = (const char *)glGetStringWrapperNonstatic(GL_EXTENSIONS);
- glxLogExtensions("GL_EXTENSIONS: ", gl_extensions);
- wgl_extensions = wglGetExtensionsStringARBWrapper(hdc);
- if (!wgl_extensions) wgl_extensions = "";
- glxLogExtensions("WGL_EXTENSIONS: ", wgl_extensions);
-
- // Can you see the problem here? The extensions string is DC specific
- // Different DCs for windows on a multimonitor system driven by multiple cards
- // might have completely different capabilities. Of course, good luck getting
- // those screens to be accelerated in XP and earlier...
-
- {
- // testing facility to not use any WGL extensions
- char *envptr = getenv("GLWIN_NO_WGL_EXTENSIONS");
- if ((envptr != NULL) && (atoi(envptr) != 0))
- {
- ErrorF("GLWIN_NO_WGL_EXTENSIONS is set, ignoring WGL_EXTENSIONS\n");
- wgl_extensions = "";
- }
- }
-
- {
- Bool glx_sgi_make_current_read = FALSE;
-
- //
- // Based on the WGL extensions available, enable various GLX extensions
- // XXX: make this table-driven ?
- //
- memset(screen->glx_enable_bits, 0, __GLX_EXT_BYTES);
-
- __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_visual_info");
- __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_visual_rating");
- __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_import_context");
- __glXEnableExtension(screen->glx_enable_bits, "GLX_OML_swap_method");
- __glXEnableExtension(screen->glx_enable_bits, "GLX_SGIX_fbconfig");
-
- if (strstr(wgl_extensions, "WGL_ARB_make_current_read"))
- {
- __glXEnableExtension(screen->glx_enable_bits, "GLX_SGI_make_current_read");
- LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_make_current_read\n");
- glx_sgi_make_current_read = TRUE;
- }
-
- if (strstr(gl_extensions, "GL_WIN_swap_hint"))
- {
- __glXEnableExtension(screen->glx_enable_bits, "GLX_MESA_copy_sub_buffer");
- LogMessage(X_INFO, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n");
- }
-
- if (strstr(wgl_extensions, "WGL_EXT_swap_control"))
- {
- __glXEnableExtension(screen->glx_enable_bits, "GLX_SGI_swap_control");
- __glXEnableExtension(screen->glx_enable_bits, "GLX_MESA_swap_control");
- LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_swap_control and GLX_MESA_swap_control\n");
- }
-
-/* // Hmm? screen->texOffset */
-/* if (strstr(wgl_extensions, "WGL_ARB_render_texture")) */
-/* { */
-/* __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_texture_from_pixmap"); */
-/* LogMessage(X_INFO, "AIGLX: GLX_EXT_texture_from_pixmap backed by buffer objects\n"); */
-/* screen->has_WGL_ARB_render_texture = TRUE; */
-/* } */
-
- if (strstr(wgl_extensions, "WGL_ARB_pbuffer"))
- {
- __glXEnableExtension(screen->glx_enable_bits, "GLX_SGIX_pbuffer");
- LogMessage(X_INFO, "AIGLX: enabled GLX_SGIX_pbuffer\n");
- screen->has_WGL_ARB_pbuffer = TRUE;
- }
-
- if (strstr(wgl_extensions, "WGL_ARB_multisample"))
- {
- __glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_multisample");
- __glXEnableExtension(screen->glx_enable_bits, "GLX_SGIS_multisample");
- LogMessage(X_INFO, "AIGLX: enabled GLX_ARB_multisample and GLX_SGIS_multisample\n");
- screen->has_WGL_ARB_multisample = TRUE;
- }
-
- screen->base.destroy = glxWinScreenDestroy;
- screen->base.createContext = glxWinCreateContext;
- screen->base.createDrawable = glxWinCreateDrawable;
- screen->base.swapInterval = glxWinScreenSwapInterval;
- screen->base.hyperpipeFuncs = NULL;
- screen->base.swapBarrierFuncs = NULL;
- screen->base.pScreen = pScreen;
-
- if (strstr(wgl_extensions, "WGL_ARB_pixel_format"))
- {
- glxWinCreateConfigsExt(hdc, screen);
- screen->has_WGL_ARB_pixel_format = TRUE;
- }
- else
- {
- glxWinCreateConfigs(hdc, screen);
- screen->has_WGL_ARB_pixel_format = FALSE;
- }
- // Initializes screen->base.fbconfigs and screen->base.numFBConfigs
-
- /* These will be set by __glXScreenInit */
- screen->base.visuals = NULL;
- screen->base.numVisuals = 0;
-
- __glXScreenInit(&screen->base, pScreen);
-
-#ifdef _DEBUG
- // dump out fbConfigs now fbConfigIds and visualIDs have been assigned
- fbConfigsDump(screen->base.numFBConfigs, screen->base.fbconfigs);
-#endif
-
- // Override the GL extensions string set by __glXScreenInit()
- screen->base.GLextensions = xstrdup(gl_extensions);
-
- // Generate the GLX extensions string (overrides that set by __glXScreenInit())
- {
- unsigned int buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL);
- if (buffer_size > 0)
- {
- if (screen->base.GLXextensions != NULL)
- {
- xfree(screen->base.GLXextensions);
- }
-
- screen->base.GLXextensions = xnfalloc(buffer_size);
- __glXGetExtensionString(screen->glx_enable_bits, screen->base.GLXextensions);
- }
- }
-
- //
- // Override the GLX version (__glXScreenInit() sets it to "1.2")
- // if we have all the needed extensionsto operate as a higher version
- //
- // SGIX_fbconfig && SGIX_pbuffer && SGI_make_current_read -> 1.3
- // ARB_multisample -> 1.4
- //
- if (screen->has_WGL_ARB_pbuffer && glx_sgi_make_current_read)
- {
- xfree(screen->base.GLXversion);
-
- if (screen->has_WGL_ARB_multisample)
- {
- screen->base.GLXversion = xstrdup("1.4");
- screen->base.GLXmajor = 1;
- screen->base.GLXminor = 4;
- }
- else
- {
- screen->base.GLXversion = xstrdup("1.3");
- screen->base.GLXmajor = 1;
- screen->base.GLXminor = 3;
- }
- LogMessage(X_INFO, "AIGLX: Set GLX version to %s\n", screen->base.GLXversion);
- }
- }
-
- wglMakeCurrent(NULL, NULL);
- wglDeleteContext(hglrc);
- ReleaseDC(hwnd, hdc);
- DestroyWindow(hwnd);
-
- return &screen->base;
-}
-
-/* ---------------------------------------------------------------------- */
-/*
- * Window functions
- */
-
-static Bool
-glxWinRealizeWindow(WindowPtr pWin)
-{
- Bool result;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- glxWinScreen *screenPriv = (glxWinScreen *) glxGetScreen(pScreen);
- winWindowPriv(pWin);
-
- GLWIN_DEBUG_MSG("glxWinRealizeWindow");
-
- /* Allow the window to be created (RootlessRealizeWindow is inside our wrap) */
- pScreen->RealizeWindow = screenPriv->RealizeWindow;
- result = pScreen->RealizeWindow(pWin);
- pScreen->RealizeWindow = glxWinRealizeWindow;
-
- // Check if ze need to move the window\n
- if (pWinPriv->GlCtxWnd && pWinPriv->hWnd)
- {
- ShowWindow(pWinPriv->hWnd,SW_SHOW);
- }
- return result;
-}
-
-
-static void
-glxWinCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
-{
- __GLXWinDrawable *pGlxDraw;
- ScreenPtr pScreen = pWindow->drawable.pScreen;
- glxWinScreen *screenPriv = (glxWinScreen *) glxGetScreen(pScreen);
-
- GLWIN_TRACE_MSG("glxWinCopyWindow pWindow %p", pWindow);
-
- dixLookupResourceByType((pointer) &pGlxDraw, pWindow->drawable.id, __glXDrawableRes,
- NullClient, DixUnknownAccess);
-
-
- /*
- Discard any CopyWindow requests if a GL drawing context is pointing at the window
-
- For regions which are being drawn by GL, the shadow framebuffer doesn't have the
- correct bits, so we wish to avoid shadow framebuffer damage occuring, which will
- cause those incorrect bits to be transferred to the display....
- */
- if (pGlxDraw && pGlxDraw->drawContext)
- {
- GLWIN_DEBUG_MSG("glxWinCopyWindow: discarding");
- return;
- }
-
- GLWIN_DEBUG_MSG("glxWinCopyWindow - passing to hw layer");
-
- pScreen->CopyWindow = screenPriv->CopyWindow;
- pScreen->CopyWindow(pWindow, ptOldOrg, prgnSrc);
- pScreen->CopyWindow = glxWinCopyWindow;
-
-}
-
-static Bool
-glxWinPositionWindow(WindowPtr pWin, int x, int y)
-{
- Bool result;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- glxWinScreen *screenPriv = (glxWinScreen *) glxGetScreen(pScreen);
- winWindowPriv(pWin);
-
- pScreen->PositionWindow = screenPriv->PositionWindow;
- result = pScreen->PositionWindow(pWin, x, y);
- pScreen->PositionWindow = glxWinPositionWindow;
-
- if (pWinPriv->GlCtxWnd && pWinPriv->hWnd)
- {
- MoveWindow(pWinPriv->hWnd,
- pWin->drawable.x,
- pWin->drawable.y,
- pWin->drawable.width,
- pWin->drawable.height,
- FALSE);
- }
- return result;
-}
-
-
-static Bool
-glxWinUnrealizeWindow(WindowPtr pWin)
-{
- Bool result;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- glxWinScreen *screenPriv = (glxWinScreen *)glxGetScreen(pScreen);
- winWindowPriv(pWin);
-
- GLWIN_DEBUG_MSG("glxWinUnrealizeWindow");
-
- pScreen->UnrealizeWindow = screenPriv->UnrealizeWindow;
- result = pScreen->UnrealizeWindow(pWin);
- pScreen->UnrealizeWindow = glxWinUnrealizeWindow;
-
- if (pWinPriv->GlCtxWnd && pWinPriv->hWnd)
- ShowWindow(pWinPriv->hWnd,SW_HIDE);
-
- return result;
-}
-
-static Bool
-glxWinDestroyWindow(WindowPtr pWin)
-{
- Bool result;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- glxWinScreen *screenPriv = (glxWinScreen *)glxGetScreen(pScreen);
- winWindowPriv(pWin);
-
- GLWIN_DEBUG_MSG("glxWinDestroyWindow");
-
- if (pWinPriv->GlCtxWnd && pWinPriv->hWnd)
- {
- __GLXWinDrawable *pGlxDraw;
-
- dixLookupResourceByType((pointer) &pGlxDraw, pWin->drawable.id, __glXDrawableRes, NullClient, DixUnknownAccess);
-
- if (pGlxDraw && pGlxDraw->drawContext)
- {
- if (pGlxDraw->drawContext->hwnd!=pWinPriv->hWnd)
- ErrorF("Wrong assumption\n");
- glxWinReleaseDC(pGlxDraw->drawContext->hwnd, pGlxDraw->drawContext->hDC, pGlxDraw);
- pGlxDraw->drawContext->hDC=NULL;
- pGlxDraw->drawContext->hwnd=NULL;
- }
- DestroyWindow(pWinPriv->hWnd);
- pWinPriv->hWnd=NULL;
- pWinPriv->GlCtxWnd=0;
- }
-
- pScreen->DestroyWindow = screenPriv->DestroyWindow;
- result = pScreen->DestroyWindow(pWin);
- pScreen->DestroyWindow = glxWinDestroyWindow;
-
- return result;
-}
-
-/* ---------------------------------------------------------------------- */
-/*
- * Drawable functions
- */
-
-static GLboolean
-glxWinDrawableSwapBuffers(ClientPtr client, __GLXdrawable *base)
-{
- BOOL ret;
- __GLXWinDrawable *draw = (__GLXWinDrawable *)base;
-
- /* Swap buffers on the last active context for drawing on the drawable */
- if (draw->drawContext == NULL)
- {
- GLWIN_TRACE_MSG("glxWinSwapBuffers - no context for drawable");
- return GL_FALSE;
- }
-
- GLWIN_TRACE_MSG("glxWinSwapBuffers on drawable %p, last context %p (native ctx %p)", base, draw->drawContext, draw->drawContext->ctx);
-
- /*
- draw->drawContext->base.drawPriv will not be set if the context is not current anymore,
- but if it is, it should point to this drawable....
- */
- assert((draw->drawContext->base.drawPriv == NULL) || (draw->drawContext->base.drawPriv == base));
-
- ret = SwapBuffers(draw->drawContext->hDC);
-
- if (!ret)
- {
- ErrorF("wglSwapBuffers failed: %s\n", glxWinErrorMessage());
- return GL_FALSE;
- }
-
- return GL_TRUE;
-}
-
-static void
-glxWinDrawableCopySubBuffer(__GLXdrawable *drawable,
- int x, int y, int w, int h)
-{
- glAddSwapHintRectWINWrapperNonstatic(x, y, w, h);
- glxWinDrawableSwapBuffers(NULL, drawable);
-}
-
-static void
-glxWinDrawableDestroy(__GLXdrawable *base)
-{
- __GLXWinDrawable *glxPriv = (__GLXWinDrawable *)base;
-
- if (glxPriv->drawContext && (__glXLastContext == &((glxPriv->drawContext)->base)))
- {
- // if this context is current and has unflushed commands, say we have flushed them
- // (don't actually flush them, the window is going away anyhow, and an implict flush occurs
- // on the next context change)
- // (GLX core considers it an error when we try to select a new current context if the old one
- // has unflushed commands, but the window has disappeared..)
- __GLX_NOTE_FLUSHED_CMDS(__glXLastContext);
- __glXLastContext = NULL;
- }
-
- if (glxPriv->hPbuffer)
- if (!wglDestroyPbufferARBWrapper(glxPriv->hPbuffer))
- {
- ErrorF("wglDestroyPbufferARB failed: %s\n", glxWinErrorMessage());
- }
-
- if (glxPriv->dibDC)
- {
- // restore the default DIB
- SelectObject(glxPriv->dibDC, glxPriv->hOldDIB);
-
- if (!DeleteDC(glxPriv->dibDC))
- {
- ErrorF("DeleteDC failed: %s\n", glxWinErrorMessage());
- }
- }
-
- if (glxPriv->hDIB)
- {
- if (!DeleteObject(glxPriv->hDIB))
- {
- ErrorF("DeleteObject failed: %s\n", glxWinErrorMessage());
- }
-
- ((PixmapPtr)glxPriv->base.pDraw)->devPrivate.ptr = glxPriv->pOldBits;
- }
-
- GLWIN_DEBUG_MSG("glxWinDestroyDrawable");
- xfree(glxPriv);
-}
-
-static __GLXdrawable *
-glxWinCreateDrawable(ClientPtr client,
- __GLXscreen *screen,
- DrawablePtr pDraw,
- XID drawId,
- int type,
- XID glxDrawId,
- __GLXconfig *conf)
-{
- __GLXWinDrawable *glxPriv;
-
- glxPriv = xcalloc(1,sizeof(*glxPriv));
-
- if (glxPriv == NULL)
- return NULL;
-
- if(!__glXDrawableInit(&glxPriv->base, screen, pDraw, type, glxDrawId, conf)) {
- xfree(glxPriv);
- return NULL;
- }
-
- glxPriv->base.destroy = glxWinDrawableDestroy;
- glxPriv->base.swapBuffers = glxWinDrawableSwapBuffers;
- glxPriv->base.copySubBuffer = glxWinDrawableCopySubBuffer;
- // glxPriv->base.waitX what are these for?
- // glxPriv->base.waitGL
-
- GLWIN_DEBUG_MSG("glxWinCreateDrawable %p", glxPriv);
-
- return &glxPriv->base;
-}
-
-/* ---------------------------------------------------------------------- */
-/*
- * Texture functions
- */
-
-static
-int glxWinBindTexImage(__GLXcontext *baseContext,
- int buffer,
- __GLXdrawable *pixmap)
-{
- ErrorF("glxWinBindTexImage: not implemented\n");
- return FALSE;
-}
-
-static
-int glxWinReleaseTexImage(__GLXcontext *baseContext,
- int buffer,
- __GLXdrawable *pixmap)
-{
- ErrorF(" glxWinReleaseTexImage: not implemented\n");
- return FALSE;
-}
-
-/* ---------------------------------------------------------------------- */
-/*
- * Lazy update context implementation
- *
- * WGL contexts are created for a specific HDC, so we cannot create the WGL
- * context in glxWinCreateContext(), we must defer creation until the context
- * is actually used on a specifc drawable which is connected to a native window,
- * pbuffer or DIB
- *
- * The WGL context may be used on other, compatible HDCs, so we don't need to
- * recreate it for every new native window
- *
- * XXX: I wonder why we can't create the WGL context on the screen HDC ?
- * Basically we assume all HDCs are compatible at the moment: if they are not
- * we are in a muddle, there was some code in the old implementation to attempt
- * to transparently migrate a context to a new DC by copying state and sharing
- * lists with the old one...
- */
-
-static void
-glxWinSetPixelFormat(__GLXWinContext *gc, HDC hdc, int bppOverride, int drawableTypeOverride)
-{
- __GLXscreen *screen = gc->base.pGlxScreen;
- glxWinScreen *winScreen = (glxWinScreen *)screen;
-
- __GLXconfig *config = gc->base.config;
- GLXWinConfig *winConfig = (GLXWinConfig *)config;
-
- GLWIN_DEBUG_MSG("glxWinSetPixelFormat: pixelFormatIndex %d", winConfig->pixelFormatIndex);
-
- /*
- Normally, we can just use the the pixelFormatIndex corresponding
- to the fbconfig which has been specified by the client
- */
-
- if (!((bppOverride && (bppOverride != (config->redBits + config->greenBits + config->blueBits) ))
- || ((config->drawableType & drawableTypeOverride) == 0)))
- {
- if (!SetPixelFormat(hdc, winConfig->pixelFormatIndex, NULL))
- {
- ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage());
- return;
- }
-
- return;
- }
-
- /*
- However, in certain special cases this pixel format will be incompatible with the
- use we are going to put it to, so we need to re-evaluate the pixel format to use:
-
- 1) When PFD_DRAW_TO_BITMAP is set, ChoosePixelFormat() always returns a format with
- the cColorBits we asked for, so we need to ensure it matches the bpp of the bitmap
-
- 2) Applications may assume that visuals selected with glXChooseVisual() work with
- pixmap drawables (there is no attribute to explicitly query for pixmap drawable
- support as there is for glXChooseFBConfig())
- (it's arguable this is an error in the application, but we try to make it work)
-
- pixmap rendering is always slow for us, so we don't want to choose those visuals
- by default, but if the actual drawable type we're trying to select the context
- on (drawableTypeOverride) isn't supported by the selected fbConfig, reconsider
- and see if we can find a suitable one...
- */
- ErrorF("glxWinSetPixelFormat: having second thoughts: cColorbits %d, bppOveride %d; config->drawableType %d, drawableTypeOverride %d\n",
- (config->redBits + config->greenBits + config->blueBits), bppOverride, config->drawableType, drawableTypeOverride);
-
- if (!winScreen->has_WGL_ARB_pixel_format)
- {
- PIXELFORMATDESCRIPTOR pfd;
- int pixelFormat;
-
- /* convert fbConfig to PFD */
- if (fbConfigToPixelFormat(gc->base.config, &pfd, drawableTypeOverride))
- {
- ErrorF("glxWinSetPixelFormat: fbConfigToPixelFormat failed\n");
- return;
- }
-
-#ifdef _DEBUG
- if (glxWinDebugSettings.dumpPFD)
- pfdOut(&pfd);
-#endif
-
- if (bppOverride)
- {
- GLWIN_DEBUG_MSG("glxWinSetPixelFormat: Forcing bpp from %d to %d\n", pfd.cColorBits, bppOverride);
- pfd.cColorBits = bppOverride;
- }
-
- pixelFormat = ChoosePixelFormat(hdc, &pfd);
- if (pixelFormat == 0)
- {
- ErrorF("ChoosePixelFormat error: %s\n", glxWinErrorMessage());
- return;
- }
-
- GLWIN_DEBUG_MSG("ChoosePixelFormat: chose pixelFormatIndex %d", pixelFormat);
- ErrorF("ChoosePixelFormat: chose pixelFormatIndex %d (rather than %d as originally planned)\n", pixelFormat, winConfig->pixelFormatIndex);
-
- if (!SetPixelFormat(hdc, pixelFormat, &pfd))
- {
- ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage());
- return;
- }
- }
- else
- {
- int pixelFormat = fbConfigToPixelFormatIndex(hdc, gc->base.config, drawableTypeOverride, winScreen);
- if (pixelFormat == 0)
- {
- ErrorF("wglChoosePixelFormat error: %s\n", glxWinErrorMessage());
- return;
- }
-
- GLWIN_DEBUG_MSG("wglChoosePixelFormat: chose pixelFormatIndex %d", pixelFormat);
- ErrorF("wglChoosePixelFormat: chose pixelFormatIndex %d (rather than %d as originally planned)\n", pixelFormat, winConfig->pixelFormatIndex);
-
- if (!SetPixelFormat(hdc, pixelFormat, NULL))
- {
- ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage());
- return;
- }
- }
-}
-
-static HDC
-glxWinMakeDC(__GLXWinContext *gc, __GLXWinDrawable *draw, HWND *hwnd)
-{
- HDC hdc = NULL;
- *hwnd = NULL;
-
- if (draw == NULL)
- {
- GLWIN_TRACE_MSG("No drawable for context %p (native ctx %p)", gc, gc->ctx);
- return NULL;
- }
-
- switch (draw->base.type)
- {
- case GLX_DRAWABLE_WINDOW:
- {
- WindowPtr pWin;
-
- pWin = (WindowPtr) draw->base.pDraw;
- if (pWin == NULL)
- {
- GLWIN_TRACE_MSG("for drawable %p, no WindowPtr", pWin);
- return NULL;
- }
-
- *hwnd = winGetWindowInfo(pWin);
-
- if (*hwnd == NULL)
- {
- ErrorF("No HWND error: %s\n", glxWinErrorMessage());
- return NULL;
- }
-
- hdc = GetDC(*hwnd);
-
- if (hdc == NULL)
- ErrorF("GetDC error: %s: hwnd %x, gc %p, gc->ctx %p ,gc->hwnd %p\n", glxWinErrorMessage(), *hwnd, gc, gc->ctx, gc->hwnd);
-
- if (gc->hDC)
- {
- glxWinReleaseDC(gc->hwnd, gc->hDC, draw);
- gc->hDC=NULL;
- }
-#ifdef _DEBUG
- if (glxWinDebugSettings.enableTrace)
- GLWIN_DEBUG_HWND(*hwnd);
-
- GLWIN_TRACE_MSG("for context %p (native ctx %p), hWnd changed from %p to %p", gc, gc->ctx, gc->hwnd, *hwnd);
-#endif
- gc->hwnd = *hwnd;
-
- /* Check if we need to set the pixelformat */
- {
- winWindowPriv(pWin);
- if (!pWinPriv->PixelFormatSet)
- {
- pWinPriv->PixelFormatSet=TRUE;
- /* We must select a pixelformat, but SetPixelFormat can only be called once for a window... */
- glxWinSetPixelFormat(gc, hdc, 0, GLX_WINDOW_BIT);
- }
- }
- }
- break;
-
- case GLX_DRAWABLE_PBUFFER:
- {
- hdc = wglGetPbufferDCARBWrapper(draw->hPbuffer);
-
- if (hdc == NULL)
- ErrorF("GetDC (pbuffer) error: %s\n", glxWinErrorMessage());
- }
- break;
-
- case GLX_DRAWABLE_PIXMAP:
- {
- hdc = draw->dibDC;
-#ifdef _DEBUG
- if (glxWinDebugSettings.dumpDC)
- GLWIN_DEBUG_MSG("Got PIXMAP HDC %p for window %p", hdc, *hwnd);
-#endif
- }
- break;
-
- default:
- {
- ErrorF("glxWinMakeDC: tried to makeDC for unhandled drawable type %d\n", draw->base.type);
- }
- }
-
-#ifdef _DEBUG
- if (glxWinDebugSettings.dumpDC)
- GLWIN_HDC_DEBUG_MSG("Got HDC %p for window %p", hdc, *hwnd);
-#endif
-
- return hdc;
-}
-
-static void
-glxWinReleaseDC(HWND hwnd, HDC hdc,__GLXWinDrawable *draw)
-{
- switch (draw->base.type)
- {
- case GLX_DRAWABLE_WINDOW:
- {
- ReleaseDC(hwnd, hdc);
- }
- break;
-
- case GLX_DRAWABLE_PBUFFER:
- {
- if (!wglReleasePbufferDCARBWrapper(draw->hPbuffer, hdc))
- {
- ErrorF("wglReleasePbufferDCARB error: %s\n", glxWinErrorMessage());
- }
- }
- break;
-
- case GLX_DRAWABLE_PIXMAP:
- {
- // don't release DC, the memory DC lives as long as the bitmap
-
- // We must ensure that all GDI drawing into the bitmap has completed
- // in case we subsequently access the bits from it
- GdiFlush();
- }
- break;
-
- default:
- {
- ErrorF("glxWinReleaseDC: tried to releaseDC for unhandled drawable type %d\n", draw->base.type);
- }
- }
-}
-
-static void
-glxWinDeferredCreateContext(__GLXWinContext *gc, __GLXWinDrawable *draw)
-{
- HWND hwnd;
- GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: attach context %p to drawable %p", gc, draw);
-
- switch (draw->base.type)
- {
- case GLX_DRAWABLE_WINDOW:
- {
- WindowPtr pWin = (WindowPtr) draw->base.pDraw;
-
- if (!(gc->base.config->drawableType & GLX_WINDOW_BIT))
- {
- ErrorF("glxWinDeferredCreateContext: tried to attach a context whose fbConfig doesn't have drawableType GLX_WINDOW_BIT to a GLX_DRAWABLE_WINDOW drawable\n");
- }
-
- if (pWin == NULL)
- {
- GLWIN_DEBUG_MSG("Deferring until X window is created");
- return;
- }
-
- GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: pWin %p", pWin);
-
- if (winGetWindowInfo(pWin) == NULL)
- {
- GLWIN_DEBUG_MSG("Deferring until native window is created");
- return;
- }
- }
- break;
-
- case GLX_DRAWABLE_PBUFFER:
- {
- if (draw->hPbuffer == NULL)
- {
- __GLXscreen *screen;
- glxWinScreen *winScreen;
- int pixelFormat;
- // XXX: which DC are supposed to use???
- HDC screenDC = GetDC(NULL);
-
- if (!(gc->base.config->drawableType & GLX_PBUFFER_BIT))
- {
- ErrorF("glxWinDeferredCreateContext: tried to attach a context whose fbConfig doesn't have drawableType GLX_PBUFFER_BIT to a GLX_DRAWABLE_PBUFFER drawable\n");
- }
-
- screen = gc->base.pGlxScreen;
- winScreen = (glxWinScreen *)screen;
-
- pixelFormat = fbConfigToPixelFormatIndex(screenDC, gc->base.config, GLX_DRAWABLE_PBUFFER, winScreen);
- if (pixelFormat == 0)
- {
- ErrorF("wglChoosePixelFormat error: %s\n", glxWinErrorMessage());
- return;
- }
-
- draw->hPbuffer = wglCreatePbufferARBWrapper(screenDC, pixelFormat, draw->base.pDraw->width, draw->base.pDraw->height, NULL);
- ReleaseDC(NULL, screenDC);
-
- if (draw->hPbuffer == NULL)
- {
- ErrorF("wglCreatePbufferARBWrapper error: %s\n", glxWinErrorMessage());
- return;
- }
-
- GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: pBuffer %p created for drawable %p", draw->hPbuffer, draw);
- }
- }
- break;
-
- case GLX_DRAWABLE_PIXMAP:
- {
- if (draw->dibDC == NULL)
- {
- BITMAPINFOHEADER bmpHeader;
- void *pBits;
-
- memset (&bmpHeader, 0, sizeof(BITMAPINFOHEADER));
- bmpHeader.biSize = sizeof(BITMAPINFOHEADER);
- bmpHeader.biWidth = draw->base.pDraw->width;
- bmpHeader.biHeight = draw->base.pDraw->height;
- bmpHeader.biPlanes = 1;
- bmpHeader.biBitCount = draw->base.pDraw->bitsPerPixel;
- bmpHeader.biCompression = BI_RGB;
-
- if (!(gc->base.config->drawableType & GLX_PIXMAP_BIT))
- {
- ErrorF("glxWinDeferredCreateContext: tried to attach a context whose fbConfig doesn't have drawableType GLX_PIXMAP_BIT to a GLX_DRAWABLE_PIXMAP drawable\n");
- }
-
- draw->dibDC = CreateCompatibleDC(NULL);
- if (draw->dibDC == NULL)
- {
- ErrorF("CreateCompatibleDC error: %s\n", glxWinErrorMessage());
- return;
- }
-
- draw->hDIB = CreateDIBSection(draw->dibDC, (BITMAPINFO *)&bmpHeader, DIB_RGB_COLORS, &pBits, 0, 0);
- if (draw->dibDC == NULL)
- {
- ErrorF("CreateDIBSection error: %s\n", glxWinErrorMessage());
- return;
- }
-
- // XXX: CreateDIBSection insists on allocating the bitmap memory for us, so we're going to
- // need some jiggery pokery to point the underlying X Drawable's bitmap at the same set of bits
- // so that they can be read with XGetImage as well as glReadPixels, assuming the formats are
- // even compatible ...
- draw->pOldBits = ((PixmapPtr)draw->base.pDraw)->devPrivate.ptr;
- ((PixmapPtr)draw->base.pDraw)->devPrivate.ptr = pBits;
-
- // Select the DIB into the DC
- draw->hOldDIB = SelectObject(draw->dibDC, draw->hDIB);
- if (!draw->hOldDIB)
- {
- ErrorF("SelectObject error: %s\n", glxWinErrorMessage());
- }
-
- // Set the pixel format of the bitmap
- glxWinSetPixelFormat(gc, draw->dibDC, draw->base.pDraw->bitsPerPixel, GLX_PIXMAP_BIT);
-
- GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: DIB bitmap %p created for drawable %p", draw->hDIB, draw);
- }
- }
- break;
-
- default:
- {
- ErrorF("glxWinDeferredCreateContext: tried to attach unhandled drawable type %d\n", draw->base.type);
- return;
- }
- }
-
- gc->hDC = glxWinMakeDC(gc, draw, &hwnd);
- gc->ctx = wglCreateContext(gc->hDC);
-
- if (gc->ctx == NULL)
- {
- glxWinReleaseDC(hwnd, gc->hDC, draw);
- gc->hDC=0;
-
- ErrorF("wglCreateContext error: %s\n", glxWinErrorMessage());
- return;
- }
-
- GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: attached context %p to native context %p drawable %p", gc, gc->ctx, draw);
-
- // if the native context was created successfully, shareLists if needed
- if (gc->ctx && gc->shareContext)
- {
- GLWIN_DEBUG_MSG("glxWinCreateContextReal shareLists with context %p (native ctx %p)", gc->shareContext, gc->shareContext->ctx);
-
- if (!wglShareLists(gc->shareContext->ctx, gc->ctx))
- {
- ErrorF("wglShareLists error: %s\n", glxWinErrorMessage());
- }
- }
-}
-
-/* ---------------------------------------------------------------------- */
-/*
- * Context functions
- */
-
-
-/* Context manipulation routines should return TRUE on success, FALSE on failure */
-static int
-glxWinContextMakeCurrent(__GLXcontext *base)
-{
- __GLXWinContext *gc = (__GLXWinContext *)base;
- BOOL ret;
- __GLXWinDrawable *drawPriv;
-
-#ifdef _DEBUG
- GLWIN_TRACE_MSG("glxWinContextMakeCurrent context %p (native ctx %p)", gc, gc->ctx);
- glWinCallDelta();
-#endif
-
- /* Keep a note of the last active context in the drawable */
- drawPriv = (__GLXWinDrawable *)gc->base.drawPriv;
- drawPriv->drawContext = gc;
-
- if (gc->ctx == NULL)
- {
- glxWinDeferredCreateContext(gc, drawPriv);
- }
-
- if (gc->ctx == NULL)
- {
- ErrorF("glxWinContextMakeCurrent: Native context is NULL\n");
- return FALSE;
- }
-
- if ((gc->base.readPriv != NULL) && (gc->base.readPriv != gc->base.drawPriv))
- {
- // XXX: should only occur with WGL_ARB_make_current_read
- /*
- If there is a separate read drawable, create a separate read DC, and
- use the wglMakeContextCurrent extension to make the context current drawing
- to one DC and reading from the other
- */
- gc->hreadDC = glxWinMakeDC(gc, (__GLXWinDrawable *)gc->base.readPriv, &gc->hreadwnd);
- if (gc->hreadDC == NULL)
- {
- ErrorF("glxWinMakeDC failed for readDC\n");
- return FALSE;
- }
-
- ret = wglMakeContextCurrentARBWrapper(gc->hDC, gc->hreadDC, gc->ctx);
- if (!ret)
- {
- ErrorF("wglMakeContextCurrentARBWrapper error: %s\n", glxWinErrorMessage());
- }
- }
- else
- {
- /* Otherwise, just use wglMakeCurrent */
- if (!gc->hDC)
- {
- /* It probably has been release by loseCurrent, so create it again */
- gc->hDC = glxWinMakeDC(gc, drawPriv, &gc->hwnd);
- }
- ret = wglMakeCurrent(gc->hDC, gc->ctx);
- if (!ret)
- {
- DWORD ErrorCode=GetLastError();
- ErrorF("wglMakeCurrent error: %x dc %p ctx %p\n", ErrorCode,gc->hDC,gc->ctx);
- if (!ErrorCode)
- {
- ErrorF("Error code was 0, assuming no error.\n");
- ret=TRUE;
- }
- }
- }
-
- // apparently make current could fail if the context is current in a different thread,
- // but that shouldn't be able to happen in the current server...
-
- return ret;
-}
-
-static int
-glxWinContextLoseCurrent(__GLXcontext *base)
-{
- BOOL ret=TRUE;
- __GLXWinContext *gc = (__GLXWinContext *)base;
-
-#ifdef _DEBUG
- GLWIN_TRACE_MSG("glxWinContextLoseCurrent context %p (native ctx %p)", gc, gc->ctx);
- glWinCallDelta();
-#endif
-
-
- if (wglGetCurrentContext()==gc->ctx)
- {
- /* Only do this when we are sure we are currently the active, otherwise we are deactivating the wrong one (this is happening!!!) */
- ret = wglMakeCurrent(NULL, NULL);
- if (!ret)
- ErrorF("glxWinContextLoseCurrent error: %s\n", glxWinErrorMessage());
- }
- else
- {
- return FALSE;
- }
-
- /* Since drawPriv is going to be set to zero in the context, we have to release the DC to */
- if (gc->hDC && gc->base.drawPriv) glxWinReleaseDC(gc->hwnd, gc->hDC, (__GLXWinDrawable *)gc->base.drawPriv);
- if (gc->hreadDC && gc->base.readPriv) glxWinReleaseDC(gc->hreadwnd, gc->hreadDC, (__GLXWinDrawable *)gc->base.readPriv);
- gc->hDC=NULL;
- gc->hreadDC=NULL;
-
- base->isCurrent=FALSE; /* It looks like glx is not doing this */
-
- return ret;
-}
-
-static int
-glxWinContextCopy(__GLXcontext *dst_base, __GLXcontext *src_base, unsigned long mask)
-{
- __GLXWinContext *dst = (__GLXWinContext *)dst_base;
- __GLXWinContext *src = (__GLXWinContext *)src_base;
- BOOL ret;
-
- GLWIN_DEBUG_MSG("glxWinContextCopy");
-
- ret = wglCopyContext(src->ctx, dst->ctx, mask);
- if (!ret)
- {
- ErrorF("wglCopyContext error: %s\n", glxWinErrorMessage());
- }
-
- return ret;
-}
-
-static int
-glxWinContextForceCurrent(__GLXcontext *base)
-{
- /* wglMakeCurrent always flushes the previous context, so this is equivalent to glxWinContextMakeCurrent */
- return glxWinContextMakeCurrent(base);
-}
-
-static void
-glxWinContextDestroy(__GLXcontext *base)
-{
- __GLXWinContext *gc = (__GLXWinContext *)base;
-
- if (gc != NULL)
- {
- GLWIN_DEBUG_MSG("GLXcontext %p destroyed (native ctx %p)", base, gc->ctx);
-
- if (gc->ctx)
- {
- BOOL ret;
- /* It's bad style to delete the context while it's still current */
- if (wglGetCurrentContext() == gc->ctx)
- {
- wglMakeCurrent(NULL, NULL);
- }
-
- ret = wglDeleteContext(gc->ctx);
- if (!ret)
- ErrorF("wglDeleteContext error: %s\n", glxWinErrorMessage());
- if (gc->base.drawPriv && gc->hDC) glxWinReleaseDC(gc->hwnd, gc->hDC, (__GLXWinDrawable *)gc->base.drawPriv);
- if (gc->base.readPriv && gc->hreadDC) glxWinReleaseDC(gc->hreadwnd, gc->hreadDC, (__GLXWinDrawable *)gc->base.readPriv);
- gc->hDC=NULL;
- gc->hreadDC=NULL;
- gc->ctx = NULL;
- }
-
- xfree(gc);
- }
-}
-
-static __GLXcontext *
-glxWinCreateContext(__GLXscreen *screen,
- __GLXconfig *modes,
- __GLXcontext *baseShareContext)
-{
- __GLXWinContext *context;
- __GLXWinContext *shareContext = (__GLXWinContext *)baseShareContext;
-
- static __GLXtextureFromPixmap glxWinTextureFromPixmap =
- {
- glxWinBindTexImage,
- glxWinReleaseTexImage
- };
-
- context = (__GLXWinContext *)xcalloc(1, sizeof(__GLXWinContext));
-
- if (!context)
- return NULL;
-
- memset(context, 0, sizeof *context);
- context->base.destroy = glxWinContextDestroy;
- context->base.makeCurrent = glxWinContextMakeCurrent;
- context->base.loseCurrent = glxWinContextLoseCurrent;
- context->base.copy = glxWinContextCopy;
- context->base.forceCurrent = glxWinContextForceCurrent;
- context->base.textureFromPixmap = &glxWinTextureFromPixmap;
- context->base.config = modes;
- context->base.pGlxScreen = screen;
-
- // actual native GL context creation is deferred until attach()
- //context->ctx = NULL; already done with memset
- context->shareContext = shareContext;
-
- glWinSetupDispatchTable();
-
- GLWIN_DEBUG_MSG("GLXcontext %p created", context);
-
- return &(context->base);
-}
-
-/* ---------------------------------------------------------------------- */
-/*
- * Utility functions
- */
-
-static int
-fbConfigToPixelFormat(__GLXconfig *mode, PIXELFORMATDESCRIPTOR *pfdret, int drawableTypeOverride)
-{
- PIXELFORMATDESCRIPTOR pfd = {
- sizeof(PIXELFORMATDESCRIPTOR), /* size of this pfd */
- 1, /* version number */
- PFD_SUPPORT_OPENGL, /* support OpenGL */
- PFD_TYPE_RGBA, /* RGBA type */
- 24, /* 24-bit color depth */
- 0, 0, 0, 0, 0, 0, /* color bits ignored */
- 0, /* no alpha buffer */
- 0, /* shift bit ignored */
- 0, /* no accumulation buffer */
- 0, 0, 0, 0, /* accum bits ignored */
- 32, /* 32-bit z-buffer */
- 0, /* no stencil buffer */
- 0, /* no auxiliary buffer */
- PFD_MAIN_PLANE, /* main layer */
- 0, /* reserved */
- 0, 0, 0 /* layer masks ignored */
- };
-
- if ((mode->drawableType | drawableTypeOverride) & GLX_WINDOW_BIT)
- pfd.dwFlags |= PFD_DRAW_TO_WINDOW; /* support window */
-
- if ((mode->drawableType | drawableTypeOverride) & GLX_PIXMAP_BIT)
- pfd.dwFlags |= (PFD_DRAW_TO_BITMAP | PFD_SUPPORT_GDI); /* supports software rendering to bitmap */
-
- if (mode->stereoMode) {
- pfd.dwFlags |= PFD_STEREO;
- }
- if (mode->doubleBufferMode) {
- pfd.dwFlags |= PFD_DOUBLEBUFFER;
- }
-
- pfd.iPixelType = PFD_TYPE_RGBA;
- pfd.cColorBits = mode->redBits + mode->greenBits + mode->blueBits;
- pfd.cRedBits = mode->redBits;
- pfd.cRedShift = 0; /* FIXME */
- pfd.cGreenBits = mode->greenBits;
- pfd.cGreenShift = 0; /* FIXME */
- pfd.cBlueBits = mode->blueBits;
- pfd.cBlueShift = 0; /* FIXME */
- pfd.cAlphaBits = mode->alphaBits;
- pfd.cAlphaShift = 0; /* FIXME */
-
- pfd.cAccumBits = mode->accumRedBits + mode->accumGreenBits + mode->accumBlueBits + mode->accumAlphaBits;
- pfd.cAccumRedBits = mode->accumRedBits;
- pfd.cAccumGreenBits = mode->accumGreenBits;
- pfd.cAccumBlueBits = mode->accumBlueBits;
- pfd.cAccumAlphaBits = mode->accumAlphaBits;
-
- pfd.cDepthBits = mode->depthBits;
- pfd.cStencilBits = mode->stencilBits;
- pfd.cAuxBuffers = mode->numAuxBuffers;
-
- /* mode->level ? */
- /* mode->pixmapMode ? */
-
- *pfdret = pfd;
-
- return 0;
-}
-
-#define SET_ATTR_VALUE(attr, value) { attribList[i++] = attr; attribList[i++] = value; assert(i < NUM_ELEMENTS(attribList)); }
-
-static int
-fbConfigToPixelFormatIndex(HDC hdc, __GLXconfig *mode, int drawableTypeOverride, glxWinScreen *winScreen)
-{
- UINT numFormats;
- unsigned int i = 0;
-
- /* convert fbConfig to attr-value list */
- int attribList[60];
-
- SET_ATTR_VALUE(WGL_SUPPORT_OPENGL_ARB, TRUE);
- SET_ATTR_VALUE(WGL_PIXEL_TYPE_ARB, (mode->visualType == GLX_TRUE_COLOR) ? WGL_TYPE_RGBA_ARB : WGL_TYPE_COLORINDEX_ARB);
- SET_ATTR_VALUE(WGL_COLOR_BITS_ARB, (mode->visualType == GLX_TRUE_COLOR) ? mode->rgbBits : mode->indexBits);
- SET_ATTR_VALUE(WGL_RED_BITS_ARB, mode->redBits);
- SET_ATTR_VALUE(WGL_GREEN_BITS_ARB, mode->greenBits);
- SET_ATTR_VALUE(WGL_BLUE_BITS_ARB, mode->blueBits);
- SET_ATTR_VALUE(WGL_ALPHA_BITS_ARB, mode->alphaBits);
- SET_ATTR_VALUE(WGL_ACCUM_RED_BITS_ARB, mode->accumRedBits);
- SET_ATTR_VALUE(WGL_ACCUM_GREEN_BITS_ARB, mode->accumGreenBits);
- SET_ATTR_VALUE(WGL_ACCUM_BLUE_BITS_ARB, mode->accumBlueBits);
- SET_ATTR_VALUE(WGL_ACCUM_ALPHA_BITS_ARB, mode->accumAlphaBits);
- SET_ATTR_VALUE(WGL_DEPTH_BITS_ARB, mode->depthBits);
- SET_ATTR_VALUE(WGL_STENCIL_BITS_ARB, mode->stencilBits);
- SET_ATTR_VALUE(WGL_AUX_BUFFERS_ARB, mode->numAuxBuffers);
-
- if (mode->doubleBufferMode)
- SET_ATTR_VALUE(WGL_DOUBLE_BUFFER_ARB, TRUE);
-
- if (mode->stereoMode)
- SET_ATTR_VALUE(WGL_STEREO_ARB, TRUE);
-
- // Some attributes are only added to the list if the value requested is not 'don't care', as exactly matching that is daft..
- if (mode->swapMethod == GLX_SWAP_EXCHANGE_OML)
- SET_ATTR_VALUE(WGL_SWAP_METHOD_ARB, WGL_SWAP_EXCHANGE_ARB);
-
- if (mode->swapMethod == GLX_SWAP_COPY_OML)
- SET_ATTR_VALUE(WGL_SWAP_COPY_ARB, TRUE);
-
- // XXX: this should probably be the other way around, but that messes up drawableTypeOverride
- if (mode->visualRating == GLX_SLOW_VISUAL_EXT)
- SET_ATTR_VALUE(WGL_ACCELERATION_ARB, WGL_NO_ACCELERATION_ARB);
-
- // must support all the drawable types the mode supports
- if ((mode->drawableType | drawableTypeOverride) & GLX_WINDOW_BIT)
- SET_ATTR_VALUE(WGL_DRAW_TO_WINDOW_ARB,TRUE);
-
- // XXX: this is a horrible hacky heuristic, in fact this whole drawableTypeOverride thing is a bad idea
- // try to avoid asking for formats which don't exist (by not asking for all when adjusting the config to include the drawableTypeOverride)
- if (drawableTypeOverride == GLX_WINDOW_BIT)
- {
- if (mode->drawableType & GLX_PIXMAP_BIT)
- SET_ATTR_VALUE(WGL_DRAW_TO_BITMAP_ARB, TRUE);
-
- if (mode->drawableType & GLX_PBUFFER_BIT)
- if (winScreen->has_WGL_ARB_pbuffer)
- SET_ATTR_VALUE(WGL_DRAW_TO_PBUFFER_ARB, TRUE);
- }
- else
- {
- if (drawableTypeOverride & GLX_PIXMAP_BIT)
- SET_ATTR_VALUE(WGL_DRAW_TO_BITMAP_ARB, TRUE);
-
- if (drawableTypeOverride & GLX_PBUFFER_BIT)
- if (winScreen->has_WGL_ARB_pbuffer)
- SET_ATTR_VALUE(WGL_DRAW_TO_PBUFFER_ARB, TRUE);
- }
-
- SET_ATTR_VALUE(0, 0); // terminator
-
- /* choose the first match */
- {
- int pixelFormatIndex;
-
- if (!wglChoosePixelFormatARBWrapper(hdc, attribList, NULL, 1, &pixelFormatIndex, &numFormats))
- {
- ErrorF("wglChoosePixelFormat error: %s\n", glxWinErrorMessage());
- }
- else
- {
- if (numFormats > 0)
- {
- GLWIN_DEBUG_MSG("wglChoosePixelFormat: chose pixelFormatIndex %d)", pixelFormatIndex);
- return pixelFormatIndex;
- }
- else
- ErrorF("wglChoosePixelFormat couldn't decide\n");
- }
- }
-
- return 0;
-}
-
-/* ---------------------------------------------------------------------- */
-
-#define BITS_AND_SHIFT_TO_MASK(bits,mask) (((1<<(bits))-1) << (mask))
-
-//
-// Create the GLXconfigs using DescribePixelFormat()
-//
-static void
-glxWinCreateConfigs(HDC hdc, glxWinScreen *screen)
-{
- GLXWinConfig *c, *result, *prev = NULL;
- int numConfigs = 0;
- int i = 0;
- int n = 0;
- PIXELFORMATDESCRIPTOR pfd;
-
- GLWIN_DEBUG_MSG("glxWinCreateConfigs");
-
- screen->base.numFBConfigs = 0;
- screen->base.fbconfigs = NULL;
-
- // get the number of pixelformats
- numConfigs = DescribePixelFormat(hdc, 1, sizeof(PIXELFORMATDESCRIPTOR), NULL);
- GLWIN_DEBUG_MSG("DescribePixelFormat says %d possible pixel formats", numConfigs);
-
- /* alloc */
- result = xalloc(sizeof(GLXWinConfig) * numConfigs);
-
- if (NULL == result)
- {
- return;
- }
-
- memset(result, 0, sizeof(GLXWinConfig) * numConfigs);
- n = 0;
-
- /* fill in configs */
- for (i = 0; i < numConfigs; i++)
- {
- int rc;
-
- c = &(result[i]);
- c->base.next = NULL;
- c->pixelFormatIndex = i+1;
-
- rc = DescribePixelFormat(hdc, i+1, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
-
- if (!rc)
- {
- ErrorF("DescribePixelFormat failed for index %d, error %s\n", i+1, glxWinErrorMessage());
- break;
- }
-
-#ifdef _DEBUG
- if (glxWinDebugSettings.dumpPFD)
- pfdOut(&pfd);
-#endif
-
- if (!(pfd.dwFlags & (PFD_DRAW_TO_WINDOW | PFD_DRAW_TO_BITMAP)) || !(pfd.dwFlags & PFD_SUPPORT_OPENGL))
- {
- GLWIN_DEBUG_MSG("pixelFormat %d has unsuitable flags 0x%08lx, skipping", i+1, pfd.dwFlags);
- continue;
- }
-
- c->base.doubleBufferMode = (pfd.dwFlags & PFD_DOUBLEBUFFER) ? GL_TRUE : GL_FALSE;
- c->base.stereoMode = (pfd.dwFlags & PFD_STEREO) ? GL_TRUE : GL_FALSE;
-
- c->base.redBits = pfd.cRedBits;
- c->base.greenBits = pfd.cGreenBits;
- c->base.blueBits = pfd.cBlueBits;
- c->base.alphaBits = pfd.cAlphaBits;
-
- c->base.redMask = BITS_AND_SHIFT_TO_MASK(pfd.cRedBits, pfd.cRedShift);
- c->base.greenMask = BITS_AND_SHIFT_TO_MASK(pfd.cGreenBits, pfd.cGreenShift);
- c->base.blueMask = BITS_AND_SHIFT_TO_MASK(pfd.cBlueBits, pfd.cBlueShift);
- c->base.alphaMask = BITS_AND_SHIFT_TO_MASK(pfd.cAlphaBits, pfd.cAlphaShift);
-
- c->base.rgbBits = pfd.cColorBits;
-
- if (pfd.iPixelType == PFD_TYPE_COLORINDEX)
- {
- c->base.indexBits = pfd.cColorBits;
- }
- else
- {
- c->base.indexBits = 0;
- }
-
- c->base.accumRedBits = pfd.cAccumRedBits;
- c->base.accumGreenBits = pfd.cAccumGreenBits;
- c->base.accumBlueBits = pfd.cAccumBlueBits;
- c->base.accumAlphaBits = pfd.cAccumAlphaBits;
- // pfd.cAccumBits;
-
- c->base.depthBits = pfd.cDepthBits;
- c->base.stencilBits = pfd.cStencilBits;
- c->base.numAuxBuffers = pfd.cAuxBuffers;
-
- // pfd.iLayerType; // ignored
- c->base.level = 0;
- // pfd.dwLayerMask; // ignored
- // pfd.dwDamageMask; // ignored
-
- c->base.pixmapMode = 0;
- c->base.visualID = -1; // will be set by __glXScreenInit()
-
- /* EXT_visual_rating / GLX 1.2 */
- if (pfd.dwFlags & PFD_GENERIC_FORMAT)
- {
- c->base.visualRating = GLX_SLOW_VISUAL_EXT;
- }
- else
- {
- // PFD_GENERIC_ACCELERATED is not considered, so this may be MCD or ICD acclerated...
- c->base.visualRating = GLX_NONE_EXT;
- }
-
- /* EXT_visual_info / GLX 1.2 */
- if (pfd.iPixelType == PFD_TYPE_COLORINDEX)
- {
- c->base.visualType = GLX_STATIC_COLOR;
- }
- else
- {
- c->base.visualType = GLX_TRUE_COLOR;
- }
-
- // pfd.dwVisibleMask; ???
- c->base.transparentPixel = GLX_NONE;
- c->base.transparentRed = GLX_NONE;
- c->base.transparentGreen = GLX_NONE;
- c->base.transparentBlue = GLX_NONE;
- c->base.transparentAlpha = GLX_NONE;
- c->base.transparentIndex = GLX_NONE;
-
- /* ARB_multisample / SGIS_multisample */
- c->base.sampleBuffers = 0;
- c->base.samples = 0;
-
- /* SGIX_fbconfig / GLX 1.3 */
- c->base.drawableType = (((pfd.dwFlags & PFD_DRAW_TO_WINDOW) ? GLX_WINDOW_BIT : 0)
- | ((pfd.dwFlags & PFD_DRAW_TO_BITMAP) ? GLX_PIXMAP_BIT : 0));
-
- if (pfd.iPixelType == PFD_TYPE_COLORINDEX)
- {
- c->base.renderType = GLX_RGBA_BIT | GLX_COLOR_INDEX_BIT;
- }
- else
- {
- c->base.renderType = GLX_RGBA_BIT;
- }
-
- c->base.xRenderable = GL_TRUE;
- c->base.fbconfigID = -1; // will be set by __glXScreenInit()
-
- /* SGIX_pbuffer / GLX 1.3 */
- // XXX: How can we find these values out ???
- c->base.maxPbufferWidth = -1;
- c->base.maxPbufferHeight = -1;
- c->base.maxPbufferPixels = -1;
- c->base.optimalPbufferWidth = 0; // there is no optimal value
- c->base.optimalPbufferHeight = 0;
-
- /* SGIX_visual_select_group */
- // arrange for visuals with the best acceleration to be preferred in selection
- switch (pfd.dwFlags & (PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED))
- {
- case 0:
- c->base.visualSelectGroup = 2;
- break;
-
- case PFD_GENERIC_ACCELERATED:
- c->base.visualSelectGroup = 1;
- break;
-
- case PFD_GENERIC_FORMAT:
- c->base.visualSelectGroup = 0;
- break;
-
- default:
- ;
- // "can't happen"
- }
-
- /* OML_swap_method */
- if (pfd.dwFlags & PFD_SWAP_EXCHANGE)
- c->base.swapMethod = GLX_SWAP_EXCHANGE_OML;
- else if (pfd.dwFlags & PFD_SWAP_COPY)
- c->base.swapMethod = GLX_SWAP_COPY_OML;
- else
- c->base.swapMethod = GLX_SWAP_UNDEFINED_OML;
-
- /* EXT_import_context */
- c->base.screen = screen->base.pScreen->myNum;
-
- /* EXT_texture_from_pixmap */
- c->base.bindToTextureRgb = -1;
- c->base.bindToTextureRgba = -1;
- c->base.bindToMipmapTexture = -1;
- c->base.bindToTextureTargets = -1;
- c->base.yInverted = -1;
-
- n++;
-
- // update previous config to point to this config
- if (prev)
- prev->base.next = &(c->base);
-
- prev = c;
- }
-
- GLWIN_DEBUG_MSG("found %d pixelFormats suitable for conversion to fbConfigs", n);
-
- screen->base.numFBConfigs = n;
- screen->base.fbconfigs = &(result->base);
-}
-
-// helper function to access an attribute value from an attribute value array by attribute
-static
-int getAttrValue(const int attrs[], int values[], unsigned int num, int attr, int fallback)
-{
- unsigned int i;
- for (i = 0; i < num; i++)
- {
- if (attrs[i] == attr)
- {
- GLWIN_TRACE_MSG("getAttrValue attr 0x%x, value %d", attr, values[i]);
- return values[i];
- }
- }
-
- ErrorF("getAttrValue failed to find attr 0x%x, using default value %d\n", attr, fallback);
- return fallback;
-}
-
-//
-// Create the GLXconfigs using wglGetPixelFormatAttribfvARB() extension
-//
-static void
-glxWinCreateConfigsExt(HDC hdc, glxWinScreen *screen)
-{
- GLXWinConfig *c, *result, *prev = NULL;
- int i = 0;
- int n = 0;
-
- const int attr = WGL_NUMBER_PIXEL_FORMATS_ARB;
- int numConfigs;
-
- int attrs[50];
- unsigned int num_attrs = 0;
-
- GLWIN_DEBUG_MSG("glxWinCreateConfigsExt");
-
- screen->base.numFBConfigs = 0;
- screen->base.fbconfigs = NULL;
-
- if (!wglGetPixelFormatAttribivARBWrapper(hdc, 0, 0, 1, &attr, &numConfigs))
- {
- ErrorF("wglGetPixelFormatAttribivARB failed for WGL_NUMBER_PIXEL_FORMATS_ARB: %s\n", glxWinErrorMessage());
- return;
- }
-
- GLWIN_DEBUG_MSG("wglGetPixelFormatAttribivARB says %d possible pixel formats", numConfigs);
-
- /* alloc */
- result = xalloc(sizeof(GLXWinConfig) * numConfigs);
-
- if (NULL == result)
- {
- return;
- }
-
- memset(result, 0, sizeof(GLXWinConfig) * numConfigs);
- n = 0;
-
-#define ADD_ATTR(a) { attrs[num_attrs++] = a; assert(num_attrs < NUM_ELEMENTS(attrs)); }
-
- ADD_ATTR(WGL_DRAW_TO_WINDOW_ARB);
- ADD_ATTR(WGL_DRAW_TO_BITMAP_ARB);
- ADD_ATTR(WGL_ACCELERATION_ARB);
- ADD_ATTR(WGL_SWAP_LAYER_BUFFERS_ARB);
- ADD_ATTR(WGL_NUMBER_OVERLAYS_ARB);
- ADD_ATTR(WGL_NUMBER_UNDERLAYS_ARB);
- ADD_ATTR(WGL_TRANSPARENT_ARB);
- ADD_ATTR(WGL_TRANSPARENT_RED_VALUE_ARB);
- ADD_ATTR(WGL_TRANSPARENT_GREEN_VALUE_ARB);
- ADD_ATTR(WGL_TRANSPARENT_GREEN_VALUE_ARB);
- ADD_ATTR(WGL_TRANSPARENT_ALPHA_VALUE_ARB);
- ADD_ATTR(WGL_SUPPORT_OPENGL_ARB);
- ADD_ATTR(WGL_DOUBLE_BUFFER_ARB);
- ADD_ATTR(WGL_STEREO_ARB);
- ADD_ATTR(WGL_PIXEL_TYPE_ARB);
- ADD_ATTR(WGL_COLOR_BITS_ARB);
- ADD_ATTR(WGL_RED_BITS_ARB);
- ADD_ATTR(WGL_RED_SHIFT_ARB);
- ADD_ATTR(WGL_GREEN_BITS_ARB);
- ADD_ATTR(WGL_GREEN_SHIFT_ARB);
- ADD_ATTR(WGL_BLUE_BITS_ARB);
- ADD_ATTR(WGL_BLUE_SHIFT_ARB);
- ADD_ATTR(WGL_ALPHA_BITS_ARB);
- ADD_ATTR(WGL_ALPHA_SHIFT_ARB);
- ADD_ATTR(WGL_ACCUM_RED_BITS_ARB);
- ADD_ATTR(WGL_ACCUM_GREEN_BITS_ARB);
- ADD_ATTR(WGL_ACCUM_BLUE_BITS_ARB);
- ADD_ATTR(WGL_ACCUM_ALPHA_BITS_ARB);
- ADD_ATTR(WGL_DEPTH_BITS_ARB);
- ADD_ATTR(WGL_STENCIL_BITS_ARB);
- ADD_ATTR(WGL_AUX_BUFFERS_ARB);
- ADD_ATTR(WGL_SWAP_METHOD_ARB);
-
- if (screen->has_WGL_ARB_multisample)
- {
- // we may not query these attrs if WGL_ARB_multisample is not offered
- ADD_ATTR(WGL_SAMPLE_BUFFERS_ARB);
- ADD_ATTR(WGL_SAMPLES_ARB);
- }
-
- if (screen->has_WGL_ARB_render_texture)
- {
- // we may not query these attrs if WGL_ARB_render_texture is not offered
- ADD_ATTR(WGL_BIND_TO_TEXTURE_RGB_ARB);
- ADD_ATTR(WGL_BIND_TO_TEXTURE_RGBA_ARB);
- }
-
- if (screen->has_WGL_ARB_pbuffer)
- {
- // we may not query these attrs if WGL_ARB_pbuffer is not offered
- ADD_ATTR(WGL_DRAW_TO_PBUFFER_ARB);
- ADD_ATTR(WGL_MAX_PBUFFER_PIXELS_ARB);
- ADD_ATTR(WGL_MAX_PBUFFER_WIDTH_ARB);
- ADD_ATTR(WGL_MAX_PBUFFER_HEIGHT_ARB);
- }
-
- /* fill in configs */
- for (i = 0; i < numConfigs; i++)
- {
- int sizevalues=num_attrs*sizeof(int);
- int *values=(int*)_alloca(sizevalues);
-
- memset(values,0,sizevalues);
-
- c = &(result[i]);
- c->base.next = NULL;
- c->pixelFormatIndex = i+1;
-
- if (!wglGetPixelFormatAttribivARBWrapper(hdc, i+1, 0, num_attrs, attrs, values))
- {
- ErrorF("wglGetPixelFormatAttribivARB failed for index %d, error %s\n", i+1, glxWinErrorMessage());
- break;
- }
-
-#define ATTR_VALUE(a, d) getAttrValue(attrs, values, num_attrs, (a), (d))
-
- if (!ATTR_VALUE(WGL_SUPPORT_OPENGL_ARB, 0))
- {
- GLWIN_DEBUG_MSG("pixelFormat %d isn't WGL_SUPPORT_OPENGL_ARB, skipping", i+1);
- continue;
- }
-
- c->base.doubleBufferMode = ATTR_VALUE(WGL_DOUBLE_BUFFER_ARB, 0) ? GL_TRUE : GL_FALSE;
- c->base.stereoMode = ATTR_VALUE(WGL_STEREO_ARB, 0) ? GL_TRUE : GL_FALSE;
-
- c->base.redBits = ATTR_VALUE(WGL_RED_BITS_ARB, 0);
- c->base.greenBits = ATTR_VALUE(WGL_GREEN_BITS_ARB, 0);
- c->base.blueBits = ATTR_VALUE(WGL_BLUE_BITS_ARB, 0);
- c->base.alphaBits = ATTR_VALUE(WGL_ALPHA_BITS_ARB, 0);
-
- c->base.redMask = BITS_AND_SHIFT_TO_MASK(c->base.redBits, ATTR_VALUE(WGL_RED_SHIFT_ARB, 0));
- c->base.greenMask = BITS_AND_SHIFT_TO_MASK(c->base.greenBits, ATTR_VALUE(WGL_GREEN_SHIFT_ARB, 0));
- c->base.blueMask = BITS_AND_SHIFT_TO_MASK(c->base.blueBits, ATTR_VALUE(WGL_BLUE_SHIFT_ARB, 0));
- c->base.alphaMask = BITS_AND_SHIFT_TO_MASK(c->base.alphaBits, ATTR_VALUE(WGL_ALPHA_SHIFT_ARB, 0));
-
- switch (ATTR_VALUE(WGL_PIXEL_TYPE_ARB, 0))
- {
- case WGL_TYPE_COLORINDEX_ARB:
- c->base.indexBits = ATTR_VALUE(WGL_COLOR_BITS_ARB, 0);
- c->base.rgbBits = 0;
- c->base.visualType = GLX_STATIC_COLOR;
- break;
-
- case WGL_TYPE_RGBA_FLOAT_ARB:
- GLWIN_DEBUG_MSG("pixelFormat %d is WGL_TYPE_RGBA_FLOAT_ARB, skipping", i+1);
- continue;
-
- case WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT:
- GLWIN_DEBUG_MSG("pixelFormat %d is WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT, skipping", i+1);
- continue;
-
- case WGL_TYPE_RGBA_ARB:
- c->base.indexBits = 0;
- c->base.rgbBits = ATTR_VALUE(WGL_COLOR_BITS_ARB, 0);
- c->base.visualType = GLX_TRUE_COLOR;
- break;
-
- default:
- ErrorF("wglGetPixelFormatAttribivARB returned unknown value 0x%x for WGL_PIXEL_TYPE_ARB\n", ATTR_VALUE(WGL_PIXEL_TYPE_ARB, 0));
- continue;
- }
-
- c->base.accumRedBits = ATTR_VALUE(WGL_ACCUM_RED_BITS_ARB, 0);
- c->base.accumGreenBits = ATTR_VALUE(WGL_ACCUM_GREEN_BITS_ARB, 0);
- c->base.accumBlueBits = ATTR_VALUE(WGL_ACCUM_BLUE_BITS_ARB, 0);
- c->base.accumAlphaBits = ATTR_VALUE(WGL_ACCUM_ALPHA_BITS_ARB, 0);
-
- c->base.depthBits = ATTR_VALUE(WGL_DEPTH_BITS_ARB, 0);
- c->base.stencilBits = ATTR_VALUE(WGL_STENCIL_BITS_ARB, 0);
- c->base.numAuxBuffers = ATTR_VALUE(WGL_AUX_BUFFERS_ARB, 0);
-
- {
- int layers = ATTR_VALUE(WGL_NUMBER_OVERLAYS_ARB,0) + ATTR_VALUE(WGL_NUMBER_UNDERLAYS_ARB, 0);
-
- if (layers > 0)
- {
- ErrorF("pixelFormat %d: has %d overlay, %d underlays which aren't currently handled", i, ATTR_VALUE(WGL_NUMBER_OVERLAYS_ARB,0), ATTR_VALUE(WGL_NUMBER_UNDERLAYS_ARB, 0));
- // XXX: need to iterate over layers?
- }
- }
- c->base.level = 0;
-
- c->base.pixmapMode = 0; // ???
- c->base.visualID = -1; // will be set by __glXScreenInit()
-
- /* EXT_visual_rating / GLX 1.2 */
- switch (ATTR_VALUE(WGL_ACCELERATION_ARB, 0))
- {
- default:
- ErrorF("wglGetPixelFormatAttribivARB returned unknown value 0x%x for WGL_ACCELERATION_ARB\n", ATTR_VALUE(WGL_ACCELERATION_ARB, 0));
-
- case WGL_NO_ACCELERATION_ARB:
- c->base.visualRating = GLX_SLOW_VISUAL_EXT;
- break;
-
- case WGL_GENERIC_ACCELERATION_ARB:
- case WGL_FULL_ACCELERATION_ARB:
- c->base.visualRating = GLX_NONE_EXT;
- break;
- }
-
- /* EXT_visual_info / GLX 1.2 */
- // c->base.visualType is set above
- if (ATTR_VALUE(WGL_TRANSPARENT_ARB, 0))
- {
- c->base.transparentPixel = (c->base.visualType == GLX_TRUE_COLOR) ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT;
- c->base.transparentRed = ATTR_VALUE(WGL_TRANSPARENT_RED_VALUE_ARB, 0);
- c->base.transparentGreen = ATTR_VALUE(WGL_TRANSPARENT_GREEN_VALUE_ARB, 0);
- c->base.transparentBlue = ATTR_VALUE(WGL_TRANSPARENT_BLUE_VALUE_ARB, 0);
- c->base.transparentAlpha = ATTR_VALUE(WGL_TRANSPARENT_ALPHA_VALUE_ARB, 0);
- c->base.transparentIndex = ATTR_VALUE(WGL_TRANSPARENT_INDEX_VALUE_ARB, 0);
- }
- else
- {
- c->base.transparentPixel = GLX_NONE_EXT;
- c->base.transparentRed = GLX_NONE;
- c->base.transparentGreen = GLX_NONE;
- c->base.transparentBlue = GLX_NONE;
- c->base.transparentAlpha = GLX_NONE;
- c->base.transparentIndex = GLX_NONE;
- }
-
- /* ARB_multisample / SGIS_multisample */
- if (screen->has_WGL_ARB_multisample)
- {
- c->base.sampleBuffers = ATTR_VALUE(WGL_SAMPLE_BUFFERS_ARB, 0);
- c->base.samples = ATTR_VALUE(WGL_SAMPLES_ARB, 0);
- }
- else
- {
- c->base.sampleBuffers = 0;
- c->base.samples = 0;
- }
-
- /* SGIX_fbconfig / GLX 1.3 */
- c->base.drawableType = ((ATTR_VALUE(WGL_DRAW_TO_WINDOW_ARB, 0) ? GLX_WINDOW_BIT : 0)
- | (ATTR_VALUE(WGL_DRAW_TO_BITMAP_ARB, 0) ? GLX_PIXMAP_BIT : 0)
- | (ATTR_VALUE(WGL_DRAW_TO_PBUFFER_ARB, 0) ? GLX_PBUFFER_BIT : 0));
-
- /*
- Assume OpenGL RGBA rendering is available on all visuals
- (it is specified to render to red component in single-channel visuals,
- if supported, but there doesn't seem to be any mechanism to check if it
- is supported)
-
- Color index rendering is only supported on single-channel visuals
- */
- if (c->base.visualType == GLX_STATIC_COLOR)
- {
- c->base.renderType = GLX_RGBA_BIT | GLX_COLOR_INDEX_BIT;
- }
- else
- {
- c->base.renderType = GLX_RGBA_BIT;
- }
-
- c->base.xRenderable = GL_TRUE;
- c->base.fbconfigID = -1; // will be set by __glXScreenInit()
-
- /* SGIX_pbuffer / GLX 1.3 */
- if (screen->has_WGL_ARB_pbuffer)
- {
- c->base.maxPbufferWidth = ATTR_VALUE(WGL_MAX_PBUFFER_WIDTH_ARB, -1);
- c->base.maxPbufferHeight = ATTR_VALUE(WGL_MAX_PBUFFER_HEIGHT_ARB, -1);
- c->base.maxPbufferPixels = ATTR_VALUE(WGL_MAX_PBUFFER_PIXELS_ARB, -1);
- }
- else
- {
- c->base.maxPbufferWidth = -1;
- c->base.maxPbufferHeight = -1;
- c->base.maxPbufferPixels = -1;
- }
- c->base.optimalPbufferWidth = 0; // there is no optimal value
- c->base.optimalPbufferHeight = 0;
-
- /* SGIX_visual_select_group */
- // arrange for visuals with the best acceleration to be preferred in selection
- switch (ATTR_VALUE(WGL_ACCELERATION_ARB, 0))
- {
- case WGL_FULL_ACCELERATION_ARB:
- c->base.visualSelectGroup = 2;
- break;
-
- case WGL_GENERIC_ACCELERATION_ARB:
- c->base.visualSelectGroup = 1;
- break;
-
- default:
- case WGL_NO_ACCELERATION_ARB:
- c->base.visualSelectGroup = 0;
- break;
- }
-
- /* OML_swap_method */
- switch (ATTR_VALUE(WGL_SWAP_METHOD_ARB, 0))
- {
- case WGL_SWAP_EXCHANGE_ARB:
- c->base.swapMethod = GLX_SWAP_EXCHANGE_OML;
- break;
-
- case WGL_SWAP_COPY_ARB:
- c->base.swapMethod = GLX_SWAP_COPY_OML;
- break;
-
- default:
- ErrorF("wglGetPixelFormatAttribivARB returned unknown value 0x%x for WGL_SWAP_METHOD_ARB\n", ATTR_VALUE(WGL_SWAP_METHOD_ARB, 0));
-
- case WGL_SWAP_UNDEFINED_ARB:
- c->base.swapMethod = GLX_SWAP_UNDEFINED_OML;
- }
-
- /* EXT_import_context */
- c->base.screen = screen->base.pScreen->myNum;
-
- /* EXT_texture_from_pixmap */
- /*
- Mesa's DRI configs always have bindToTextureRgb/Rgba TRUE (see driCreateConfigs(), so setting
- bindToTextureRgb/bindToTextureRgba to FALSE means that swrast can't find any fbConfigs to use,
- so setting these to 0, even if we know bindToTexture isn't available, isn't a good idea...
- */
- if (screen->has_WGL_ARB_render_texture)
- {
- c->base.bindToTextureRgb = ATTR_VALUE(WGL_BIND_TO_TEXTURE_RGB_ARB, -1);
- c->base.bindToTextureRgba = ATTR_VALUE(WGL_BIND_TO_TEXTURE_RGBA_ARB, -1);
- }
- else
- {
- c->base.bindToTextureRgb = -1;
- c->base.bindToTextureRgba = -1;
- }
- c->base.bindToMipmapTexture = -1;
- c->base.bindToTextureTargets = GLX_TEXTURE_1D_BIT_EXT | GLX_TEXTURE_2D_BIT_EXT | GLX_TEXTURE_RECTANGLE_BIT_EXT;
- c->base.yInverted = -1;
-
- n++;
-
- // update previous config to point to this config
- if (prev)
- prev->base.next = &(c->base);
-
- prev = c;
- }
-
- screen->base.numFBConfigs = n;
- screen->base.fbconfigs = &(result->base);
-}
+/*
+ * File: indirect.c
+ * Purpose: A GLX implementation that uses Windows OpenGL library
+ *
+ * Authors: Alexander Gottwald
+ * Jon TURNEY
+ *
+ * Copyright (c) Jon TURNEY 2009
+ * Copyright (c) Alexander Gottwald 2004
+ *
+ * Portions of this file are copied from GL/apple/indirect.c,
+ * which contains the following copyright:
+ *
+ * Copyright (c) 2007, 2008, 2009 Apple Inc.
+ * Copyright (c) 2004 Torrey T. Lyons. All Rights Reserved.
+ * Copyright (c) 2002 Greg Parker. All Rights Reserved.
+ *
+ * Portions of this file are copied from Mesa's xf86glx.c,
+ * which contains the following copyright:
+ *
+ * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+ * 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 ABOVE LISTED COPYRIGHT HOLDER(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.
+ */
+
+/*
+ TODO:
+ - hook up remaining unimplemented extensions
+ - research what guarantees glXWaitX, glXWaitGL are supposed to offer, and implement then
+ using GdiFlush and/or glFinish
+ - pbuffer clobbering: we don't get async notification, but can we arrange to emit the
+ event when we notice it's been clobbered? at the very least, check if it's been clobbered
+ before using it?
+ - are the __GLXConfig * we get handed back ones we are made (so we can extend the structure
+ with privates?) Or are they created inside the GLX core as well?
+*/
+
+/*
+ MSDN clarifications:
+
+ It says SetPixelFormat()'s PIXELFORMATDESCRIPTOR pointer argument has no effect
+ except on metafiles, this seems to mean that as it's ok to supply NULL if the DC
+ is not for a metafile
+
+ wglMakeCurrent ignores the hdc if hglrc is NULL, so wglMakeCurrent(NULL, NULL)
+ is used to make no context current
+
+*/
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+
+#include "glwindows.h"
+#include <glx/glxserver.h>
+#include <glx/glxutil.h>
+#include <glx/extension_string.h>
+#include <GL/glxtokens.h>
+
+#include <winpriv.h>
+#include <wgl_ext_api.h>
+#include "win.h"
+#include <winmsg.h>
+
+extern Bool g_fXdmcpEnabled;
+extern Bool g_fNativeGl;
+
+#define NUM_ELEMENTS(x) (sizeof(x)/ sizeof(x[1]))
+
+/* ---------------------------------------------------------------------- */
+/*
+ * structure definitions
+ */
+
+typedef struct __GLXWinContext __GLXWinContext;
+typedef struct __GLXWinDrawable __GLXWinDrawable;
+typedef struct __GLXWinScreen glxWinScreen;
+typedef struct __GLXWinConfig GLXWinConfig;
+
+struct __GLXWinContext {
+ __GLXcontext base;
+ HGLRC ctx; /* Windows GL Context */
+ HDC hDC; /* Windows device context */
+ HDC hreadDC; /* Windows device read context */
+ __GLXWinContext *shareContext; /* Context with which we will share display lists and textures */
+ HWND hwnd; /* For detecting when HWND has changed */
+ HWND hreadwnd;
+};
+
+struct __GLXWinDrawable
+{
+ __GLXdrawable base;
+ __GLXWinContext *drawContext;
+
+ /* If this drawable is GLX_DRAWABLE_PBUFFER */
+ HPBUFFERARB hPbuffer;
+
+ /* If this drawable is GLX_DRAWABLE_PIXMAP */
+ HDC dibDC;
+ HBITMAP hDIB;
+ HBITMAP hOldDIB; /* original DIB for DC */
+ void *pOldBits; /* original pBits for this drawable's pixmap */
+};
+
+struct __GLXWinScreen
+{
+ __GLXscreen base;
+
+ /* Supported GLX extensions */
+ unsigned char glx_enable_bits[__GLX_EXT_BYTES];
+
+ Bool has_WGL_ARB_multisample;
+ Bool has_WGL_ARB_pixel_format;
+ Bool has_WGL_ARB_pbuffer;
+ Bool has_WGL_ARB_render_texture;
+
+ /* wrapped screen functions */
+ RealizeWindowProcPtr RealizeWindow;
+ UnrealizeWindowProcPtr UnrealizeWindow;
+ DestroyWindowProcPtr DestroyWindow;
+ CopyWindowProcPtr CopyWindow;
+ PositionWindowProcPtr PositionWindow;
+};
+
+struct __GLXWinConfig
+{
+ __GLXconfig base;
+ int pixelFormatIndex;
+};
+
+/* ---------------------------------------------------------------------- */
+/*
+ * Various debug helpers
+ */
+
+#ifdef _DEBUG
+void GLWIN_DEBUG_HWND(HWND hwnd)
+{
+ if (glxWinDebugSettings.dumpHWND)
+ {
+ char buffer[1024];
+ RECT Rect;
+ HDC hDc=GetDC(hwnd);
+
+ if (GetWindowText(hwnd, buffer, sizeof(buffer))==0) *buffer=0;
+ GetWindowRect(hwnd,&Rect);
+
+ GLWIN_DEBUG_MSG("Got HWND %p (hdc %p) for window '%s' (%d,%d,%d,%d)", hwnd, hDc, buffer, Rect.left, Rect.top, Rect.right, Rect.bottom);
+ ReleaseDC(hwnd,hDc);
+ }
+}
+
+void GLWIN_HDC_DEBUG_MSG(const char *Message, HDC hDc, HWND hwnd)
+{
+ char buffer[1024];
+ RECT Rect;
+
+ if (GetWindowText(hwnd, buffer, sizeof(buffer))==0) *buffer=0;
+ GetWindowRect(hwnd,&Rect);
+
+ GLWIN_DEBUG_MSG("Got HDC %p (hwnd %p) for window '%s' (%d,%d,%d,%d)", hDc, hwnd, buffer, Rect.left, Rect.top, Rect.right, Rect.bottom);
+
+}
+
+glxWinDebugSettingsRec glxWinDebugSettings = { 0, 0, 0, 0, 0, 0};
+
+static void glxWinInitDebugSettings(void)
+{
+ char *envptr;
+
+ envptr = getenv("GLWIN_ENABLE_DEBUG");
+ if (envptr != NULL)
+ glxWinDebugSettings.enableDebug = (atoi(envptr) == 1);
+
+ envptr = getenv("GLWIN_ENABLE_TRACE");
+ if (envptr != NULL)
+ glxWinDebugSettings.enableTrace = (atoi(envptr) == 1);
+
+ envptr = getenv("GLWIN_DUMP_PFD");
+ if (envptr != NULL)
+ glxWinDebugSettings.dumpPFD = (atoi(envptr) == 1);
+
+ envptr = getenv("GLWIN_DUMP_HWND");
+ if (envptr != NULL)
+ glxWinDebugSettings.dumpHWND = (atoi(envptr) == 1);
+
+ envptr = getenv("GLWIN_DUMP_DC");
+ if (envptr != NULL)
+ glxWinDebugSettings.dumpDC = (atoi(envptr) == 1);
+
+ envptr = getenv("GLWIN_ENABLE_GLCALL_TRACE");
+ if (envptr != NULL)
+ glxWinDebugSettings.enableGLcallTrace = (atoi(envptr) == 1);
+
+ envptr = getenv("GLWIN_ENABLE_WGLCALL_TRACE");
+ if (envptr != NULL)
+ glxWinDebugSettings.enableWGLcallTrace = (atoi(envptr) == 1);
+
+ envptr = getenv("GLWIN_DEBUG_ALL");
+ if (envptr != NULL)
+ {
+ glxWinDebugSettings.enableDebug = 1;
+ glxWinDebugSettings.enableTrace = 1;
+ glxWinDebugSettings.dumpPFD = 1;
+ glxWinDebugSettings.dumpHWND = 1;
+ glxWinDebugSettings.dumpDC = 1;
+ glxWinDebugSettings.enableGLcallTrace = 1;
+ glxWinDebugSettings.enableWGLcallTrace = 1;
+ }
+}
+#endif
+
+static
+const char *glxWinErrorMessage(void)
+{
+ static char errorbuffer[1024];
+ DWORD Error=GetLastError();
+ int offset;
+
+ sprintf(errorbuffer, "%p ",Error);
+ offset=strlen(errorbuffer);
+
+ if (!FormatMessage(
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ Error,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) &errorbuffer[offset],
+ sizeof(errorbuffer),
+ NULL ))
+ {
+ snprintf(errorbuffer, sizeof(errorbuffer), "Unknown error in FormatMessage: %08x!", (unsigned)GetLastError());
+ }
+
+ if (errorbuffer[strlen(errorbuffer)-1] == '\n')
+ errorbuffer[strlen(errorbuffer)-1] = 0;
+
+ return errorbuffer;
+}
+
+static void pfdOut(const PIXELFORMATDESCRIPTOR *pfd);
+
+#ifdef _DEBUG
+
+#define DUMP_PFD_FLAG(flag) \
+ if (pfd->dwFlags & flag) { \
+ ErrorF("%s%s", pipesym, #flag); \
+ pipesym = " | "; \
+ }
+
+static void pfdOut(const PIXELFORMATDESCRIPTOR *pfd)
+{
+ const char *pipesym = ""; /* will be set after first flag dump */
+ ErrorF("PIXELFORMATDESCRIPTOR:\n");
+ ErrorF("nSize = %u\n", pfd->nSize);
+ ErrorF("nVersion = %u\n", pfd->nVersion);
+ ErrorF("dwFlags = %lu = {", pfd->dwFlags);
+ DUMP_PFD_FLAG(PFD_DOUBLEBUFFER);
+ DUMP_PFD_FLAG(PFD_STEREO);
+ DUMP_PFD_FLAG(PFD_DRAW_TO_WINDOW);
+ DUMP_PFD_FLAG(PFD_DRAW_TO_BITMAP);
+ DUMP_PFD_FLAG(PFD_SUPPORT_GDI);
+ DUMP_PFD_FLAG(PFD_SUPPORT_OPENGL);
+ DUMP_PFD_FLAG(PFD_GENERIC_FORMAT);
+ DUMP_PFD_FLAG(PFD_NEED_PALETTE);
+ DUMP_PFD_FLAG(PFD_NEED_SYSTEM_PALETTE);
+ DUMP_PFD_FLAG(PFD_SWAP_EXCHANGE);
+ DUMP_PFD_FLAG(PFD_SWAP_COPY);
+ DUMP_PFD_FLAG(PFD_SWAP_LAYER_BUFFERS);
+ DUMP_PFD_FLAG(PFD_GENERIC_ACCELERATED);
+ DUMP_PFD_FLAG(PFD_DEPTH_DONTCARE);
+ DUMP_PFD_FLAG(PFD_DOUBLEBUFFER_DONTCARE);
+ DUMP_PFD_FLAG(PFD_STEREO_DONTCARE);
+ ErrorF("}\n");
+
+ ErrorF("iPixelType = %hu = %s\n", pfd->iPixelType,
+ (pfd->iPixelType == PFD_TYPE_RGBA ? "PFD_TYPE_RGBA" : "PFD_TYPE_COLORINDEX"));
+ ErrorF("cColorBits = %hhu\n", pfd->cColorBits);
+ ErrorF("cRedBits = %hhu\n", pfd->cRedBits);
+ ErrorF("cRedShift = %hhu\n", pfd->cRedShift);
+ ErrorF("cGreenBits = %hhu\n", pfd->cGreenBits);
+ ErrorF("cGreenShift = %hhu\n", pfd->cGreenShift);
+ ErrorF("cBlueBits = %hhu\n", pfd->cBlueBits);
+ ErrorF("cBlueShift = %hhu\n", pfd->cBlueShift);
+ ErrorF("cAlphaBits = %hhu\n", pfd->cAlphaBits);
+ ErrorF("cAlphaShift = %hhu\n", pfd->cAlphaShift);
+ ErrorF("cAccumBits = %hhu\n", pfd->cAccumBits);
+ ErrorF("cAccumRedBits = %hhu\n", pfd->cAccumRedBits);
+ ErrorF("cAccumGreenBits = %hhu\n", pfd->cAccumGreenBits);
+ ErrorF("cAccumBlueBits = %hhu\n", pfd->cAccumBlueBits);
+ ErrorF("cAccumAlphaBits = %hhu\n", pfd->cAccumAlphaBits);
+ ErrorF("cDepthBits = %hhu\n", pfd->cDepthBits);
+ ErrorF("cStencilBits = %hhu\n", pfd->cStencilBits);
+ ErrorF("cAuxBuffers = %hhu\n", pfd->cAuxBuffers);
+ ErrorF("iLayerType = %hhu\n", pfd->iLayerType);
+ ErrorF("bReserved = %hhu\n", pfd->bReserved);
+ ErrorF("dwLayerMask = %lu\n", pfd->dwLayerMask);
+ ErrorF("dwVisibleMask = %lu\n", pfd->dwVisibleMask);
+ ErrorF("dwDamageMask = %lu\n", pfd->dwDamageMask);
+ ErrorF("\n");
+}
+
+static const char *
+visual_class_name(int cls)
+{
+ switch (cls) {
+ case GLX_STATIC_COLOR:
+ return "StaticColor";
+ case GLX_PSEUDO_COLOR:
+ return "PseudoColor";
+ case GLX_STATIC_GRAY:
+ return "StaticGray";
+ case GLX_GRAY_SCALE:
+ return "GrayScale";
+ case GLX_TRUE_COLOR:
+ return "TrueColor";
+ case GLX_DIRECT_COLOR:
+ return "DirectColor";
+ default:
+ return "-none-";
+ }
+}
+
+static const char *
+swap_method_name(int mthd)
+{
+ switch (mthd)
+ {
+ case GLX_SWAP_EXCHANGE_OML:
+ return "xchg";
+ case GLX_SWAP_COPY_OML:
+ return "copy";
+ case GLX_SWAP_UNDEFINED_OML:
+ return " ";
+ default:
+ return "????";
+ }
+}
+
+static void
+fbConfigsDump(unsigned int n, __GLXconfig *c)
+{
+ ErrorF("%d fbConfigs\n", n);
+ ErrorF("pxf vis fb render Ste aux accum MS drawable Group/\n");
+ ErrorF("idx ID ID VisualType Depth Lvl RGB CI DB Swap reo R G B A Z S buf AR AG AB AA bufs num W P Pb Float Trans Caveat\n");
+ ErrorF("-----------------------------------------------------------------------------------------------------------------------------\n");
+
+ while (c != NULL)
+ {
+ unsigned int i = ((GLXWinConfig *)c)->pixelFormatIndex;
+
+ ErrorF("%3d %2x %2x "
+ "%-11s"
+ " %3d %3d %s %s %s %s %s "
+ "%2d %2d %2d %2d "
+ "%2d %2d "
+ "%2d "
+ "%2d %2d %2d %2d"
+ " %2d %2d"
+ " %s %s %s "
+ " %s "
+ " %s "
+ " %d %s"
+ "\n",
+ i, c->visualID, c->fbconfigID,
+ visual_class_name(c->visualType),
+ c->rgbBits ? c->rgbBits : c->indexBits,
+ c->level,
+ (c->renderType & GLX_RGBA_BIT) ? "y" : ".",
+ (c->renderType & GLX_COLOR_INDEX_BIT) ? "y" : ".",
+ c->doubleBufferMode ? "y" : ".",
+ swap_method_name(c->swapMethod),
+ c->stereoMode ? "y" : ".",
+ c->redBits, c->greenBits, c->blueBits, c->alphaBits,
+ c->depthBits, c->stencilBits,
+ c->numAuxBuffers,
+ c->accumRedBits, c->accumGreenBits, c->accumBlueBits, c->accumAlphaBits,
+ c->sampleBuffers, c->samples,
+ (c->drawableType & GLX_WINDOW_BIT) ? "y" : ".",
+ (c->drawableType & GLX_PIXMAP_BIT) ? "y" : ".",
+ (c->drawableType & GLX_PBUFFER_BIT) ? "y" : ".",
+ ".",
+ (c->transparentPixel != GLX_NONE_EXT) ? "y" : ".",
+ c->visualSelectGroup, (c->visualRating == GLX_SLOW_VISUAL_EXT) ? "*" : " ");
+
+ c = c->next;
+ }
+}
+#endif
+
+/* ---------------------------------------------------------------------- */
+/*
+ * Forward declarations
+ */
+
+static __GLXscreen *glxWinScreenProbe(ScreenPtr pScreen);
+static __GLXcontext *glxWinCreateContext(__GLXscreen *screen,
+ __GLXconfig *modes,
+ __GLXcontext *baseShareContext);
+static __GLXdrawable *glxWinCreateDrawable(ClientPtr client,
+ __GLXscreen *screen,
+ DrawablePtr pDraw,
+ XID drawId,
+ int type,
+ XID glxDrawId,
+ __GLXconfig *conf);
+
+static Bool glxWinRealizeWindow(WindowPtr pWin);
+static Bool glxWinUnrealizeWindow(WindowPtr pWin);
+static Bool glxWinDestroyWindow(WindowPtr pWin);
+static void glxWinCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
+static Bool glxWinPositionWindow(WindowPtr pWindow, int x, int y);
+
+static HDC glxWinMakeDC(__GLXWinContext *gc, __GLXWinDrawable *draw, HWND *hwnd);
+static void glxWinReleaseDC(HWND hwnd, HDC hdc, __GLXWinDrawable *draw);
+
+static void glxWinCreateConfigs(HDC dc, glxWinScreen *screen);
+static void glxWinCreateConfigsExt(HDC hdc, glxWinScreen *screen);
+static int fbConfigToPixelFormat(__GLXconfig *mode, PIXELFORMATDESCRIPTOR *pfdret, int drawableTypeOverride);
+static int fbConfigToPixelFormatIndex(HDC hdc, __GLXconfig *mode, int drawableTypeOverride, glxWinScreen *winScreen);
+
+/* ---------------------------------------------------------------------- */
+/*
+ * The GLX provider
+ */
+
+__GLXprovider __glXWGLProvider = {
+ glxWinScreenProbe,
+ "Win32 native WGL",
+ NULL
+};
+
+void
+glxWinPushNativeProvider(void)
+{
+ if (g_fNativeGl)
+ GlxPushProvider(&__glXWGLProvider);
+}
+
+/* ---------------------------------------------------------------------- */
+/*
+ * Screen functions
+ */
+
+static void
+glxWinScreenDestroy(__GLXscreen *screen)
+{
+ GLWIN_DEBUG_MSG("glxWinScreenDestroy(%p)", screen);
+ __glXScreenDestroy(screen);
+ free(screen);
+}
+
+static int
+glxWinScreenSwapInterval(__GLXdrawable *drawable, int interval)
+{
+ BOOL ret = wglSwapIntervalEXTWrapper(interval);
+ if (!ret)
+ {
+ ErrorF("wglSwapIntervalEXT interval %d failed:%s\n", interval, glxWinErrorMessage());
+ }
+ return ret;
+}
+
+static LRESULT CALLBACK GlxWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ if (uMsg== WM_NCHITTEST)
+ {
+ return HTTRANSPARENT;
+ }
+ else
+ return DefWindowProc(hwnd, uMsg, wParam, lParam);
+}
+
+/*
+ Report the extensions split and formatted to avoid overflowing a line
+ */
+static void
+glxLogExtensions(const char *prefix, const char *extensions)
+{
+ int length = 0;
+ char *strl;
+ char *str = malloc(strlen(extensions) + 1);
+
+ if (str == NULL)
+ {
+ ErrorF("glxLogExtensions: xalloc error\n");
+ return;
+ }
+
+ str[strlen(extensions)] = '\0';
+ strncpy (str, extensions, strlen(extensions));
+
+ strl = strtok(str, " ");
+ winDebug("%s%s", prefix, strl);
+ length = strlen(prefix) + strlen(strl);
+
+ while (1)
+ {
+ strl = strtok(NULL, " ");
+ if (strl == NULL) break;
+
+ if (length + strlen(strl) + 1 > 120)
+ {
+ winDebug("\n");
+ winDebug("%s",prefix);
+ length = strlen(prefix);
+ }
+ else
+ {
+ winDebug(" ");
+ length++;
+ }
+
+ winDebug("%s", strl);
+ length = length + strlen(strl);
+ }
+
+ winDebug("\n");
+
+ free(str);
+}
+
+/* This is called by GlxExtensionInit() asking the GLX provider if it can handle the screen... */
+static __GLXscreen *
+glxWinScreenProbe(ScreenPtr pScreen)
+{
+ glxWinScreen *screen;
+ const char *gl_extensions;
+ const char *wgl_extensions;
+ HWND hwnd;
+ HDC hdc;
+ HGLRC hglrc;
+
+ GLWIN_DEBUG_MSG("glxWinScreenProbe");
+
+#ifdef _DEBUG
+ glxWinInitDebugSettings();
+#endif
+
+ if (pScreen == NULL)
+ return NULL;
+
+ if (!winCheckScreenAiglxIsSupported(pScreen))
+ {
+ LogMessage(X_ERROR,"AIGLX: No native OpenGL in modes with a root window\n");
+ return NULL;
+ }
+
+ screen = calloc(1, sizeof(glxWinScreen));
+
+ if (NULL == screen)
+ return NULL;
+
+ /* Wrap RealizeWindow, UnrealizeWindow and CopyWindow on this screen */
+ screen->RealizeWindow = pScreen->RealizeWindow;
+ pScreen->RealizeWindow = glxWinRealizeWindow;
+ screen->UnrealizeWindow = pScreen->UnrealizeWindow;
+ pScreen->UnrealizeWindow = glxWinUnrealizeWindow;
+ screen->CopyWindow = pScreen->CopyWindow;
+ pScreen->CopyWindow = glxWinCopyWindow;
+ screen->PositionWindow = pScreen->PositionWindow;
+ pScreen->PositionWindow = glxWinPositionWindow;
+ screen->DestroyWindow = pScreen->DestroyWindow;
+ pScreen->DestroyWindow = glxWinDestroyWindow;
+
+ /* Dump out some useful information about the native renderer */
+
+ // create window class
+ {
+ static wATOM glTestWndClass = 0;
+ if (glTestWndClass == 0)
+ {
+ WNDCLASSEX wc;
+ glTestWndClass=1;
+ wc.cbSize = sizeof(WNDCLASSEX);
+ wc.style = CS_OWNDC ;
+ wc.lpfnWndProc = GlxWindowProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = GetModuleHandle(NULL);
+ wc.hIcon = 0;
+ wc.hCursor = 0;
+ wc.hbrBackground = 0;
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = WIN_GL_WINDOW_CLASS;
+ wc.hIconSm = 0;
+ RegisterClassEx (&wc);
+ }
+ }
+
+ // create an invisible window for a scratch DC
+ hwnd = CreateWindowExA(0,
+ WIN_GL_WINDOW_CLASS,
+ "XWin GL Renderer Capabilities Test Window",
+ 0, 0, 0, 0, 0, NULL, NULL, GetModuleHandle(NULL), NULL);
+ if (hwnd == NULL)
+ LogMessage(X_ERROR,"AIGLX: Couldn't create a window for render capabilities testing\n");
+
+ hdc = GetDC(hwnd);
+
+ // we must set a pixel format before we can create a context, just use the first one...
+ SetPixelFormat(hdc, 1, NULL);
+ hglrc = wglCreateContext(hdc);
+ wglMakeCurrent(hdc, hglrc);
+
+ // initialize wgl extension proc pointers (don't call them before here...)
+ // (but we need to have a current context for them to be resolvable)
+ wglResolveExtensionProcs();
+
+ winDebug("GL_VERSION: %s\n", glGetStringWrapperNonstatic(GL_VERSION));
+ winDebug("GL_VENDOR: %s\n", glGetStringWrapperNonstatic(GL_VENDOR));
+ winDebug("GL_RENDERER: %s\n", glGetStringWrapperNonstatic(GL_RENDERER));
+ gl_extensions = (const char *)glGetStringWrapperNonstatic(GL_EXTENSIONS);
+ glxLogExtensions("GL_EXTENSIONS: ", gl_extensions);
+ wgl_extensions = wglGetExtensionsStringARBWrapper(hdc);
+ if (!wgl_extensions) wgl_extensions = "";
+ glxLogExtensions("WGL_EXTENSIONS: ", wgl_extensions);
+
+ // Can you see the problem here? The extensions string is DC specific
+ // Different DCs for windows on a multimonitor system driven by multiple cards
+ // might have completely different capabilities. Of course, good luck getting
+ // those screens to be accelerated in XP and earlier...
+
+ {
+ // testing facility to not use any WGL extensions
+ char *envptr = getenv("GLWIN_NO_WGL_EXTENSIONS");
+ if ((envptr != NULL) && (atoi(envptr) != 0))
+ {
+ ErrorF("GLWIN_NO_WGL_EXTENSIONS is set, ignoring WGL_EXTENSIONS\n");
+ wgl_extensions = "";
+ }
+ }
+
+ {
+ Bool glx_sgi_make_current_read = FALSE;
+
+ //
+ // Based on the WGL extensions available, enable various GLX extensions
+ // XXX: make this table-driven ?
+ //
+ memset(screen->glx_enable_bits, 0, __GLX_EXT_BYTES);
+
+ __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_visual_info");
+ __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_visual_rating");
+ __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_import_context");
+ __glXEnableExtension(screen->glx_enable_bits, "GLX_OML_swap_method");
+ __glXEnableExtension(screen->glx_enable_bits, "GLX_SGIX_fbconfig");
+
+ if (strstr(wgl_extensions, "WGL_ARB_make_current_read"))
+ {
+ __glXEnableExtension(screen->glx_enable_bits, "GLX_SGI_make_current_read");
+ LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_make_current_read\n");
+ glx_sgi_make_current_read = TRUE;
+ }
+
+ if (strstr(gl_extensions, "GL_WIN_swap_hint"))
+ {
+ __glXEnableExtension(screen->glx_enable_bits, "GLX_MESA_copy_sub_buffer");
+ LogMessage(X_INFO, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n");
+ }
+
+ if (strstr(wgl_extensions, "WGL_EXT_swap_control"))
+ {
+ __glXEnableExtension(screen->glx_enable_bits, "GLX_SGI_swap_control");
+ __glXEnableExtension(screen->glx_enable_bits, "GLX_MESA_swap_control");
+ LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_swap_control and GLX_MESA_swap_control\n");
+ }
+
+/* // Hmm? screen->texOffset */
+/* if (strstr(wgl_extensions, "WGL_ARB_render_texture")) */
+/* { */
+/* __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_texture_from_pixmap"); */
+/* LogMessage(X_INFO, "AIGLX: GLX_EXT_texture_from_pixmap backed by buffer objects\n"); */
+/* screen->has_WGL_ARB_render_texture = TRUE; */
+/* } */
+
+ if (strstr(wgl_extensions, "WGL_ARB_pbuffer"))
+ {
+ __glXEnableExtension(screen->glx_enable_bits, "GLX_SGIX_pbuffer");
+ LogMessage(X_INFO, "AIGLX: enabled GLX_SGIX_pbuffer\n");
+ screen->has_WGL_ARB_pbuffer = TRUE;
+ }
+
+ if (strstr(wgl_extensions, "WGL_ARB_multisample"))
+ {
+ __glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_multisample");
+ __glXEnableExtension(screen->glx_enable_bits, "GLX_SGIS_multisample");
+ LogMessage(X_INFO, "AIGLX: enabled GLX_ARB_multisample and GLX_SGIS_multisample\n");
+ screen->has_WGL_ARB_multisample = TRUE;
+ }
+
+ screen->base.destroy = glxWinScreenDestroy;
+ screen->base.createContext = glxWinCreateContext;
+ screen->base.createDrawable = glxWinCreateDrawable;
+ screen->base.swapInterval = glxWinScreenSwapInterval;
+ screen->base.hyperpipeFuncs = NULL;
+ screen->base.swapBarrierFuncs = NULL;
+ screen->base.pScreen = pScreen;
+
+ if (strstr(wgl_extensions, "WGL_ARB_pixel_format"))
+ {
+ glxWinCreateConfigsExt(hdc, screen);
+ screen->has_WGL_ARB_pixel_format = TRUE;
+ }
+ else
+ {
+ glxWinCreateConfigs(hdc, screen);
+ screen->has_WGL_ARB_pixel_format = FALSE;
+ }
+ // Initializes screen->base.fbconfigs and screen->base.numFBConfigs
+
+ /* These will be set by __glXScreenInit */
+ screen->base.visuals = NULL;
+ screen->base.numVisuals = 0;
+
+ __glXScreenInit(&screen->base, pScreen);
+
+#ifdef _DEBUG
+ // dump out fbConfigs now fbConfigIds and visualIDs have been assigned
+ fbConfigsDump(screen->base.numFBConfigs, screen->base.fbconfigs);
+#endif
+
+ // Override the GL extensions string set by __glXScreenInit()
+ screen->base.GLextensions = xstrdup(gl_extensions);
+
+ // Generate the GLX extensions string (overrides that set by __glXScreenInit())
+ {
+ unsigned int buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL);
+ if (buffer_size > 0)
+ {
+ if (screen->base.GLXextensions != NULL)
+ {
+ free(screen->base.GLXextensions);
+ }
+
+ screen->base.GLXextensions = xnfalloc(buffer_size);
+ __glXGetExtensionString(screen->glx_enable_bits, screen->base.GLXextensions);
+ }
+ }
+
+ //
+ // Override the GLX version (__glXScreenInit() sets it to "1.2")
+ // if we have all the needed extensionsto operate as a higher version
+ //
+ // SGIX_fbconfig && SGIX_pbuffer && SGI_make_current_read -> 1.3
+ // ARB_multisample -> 1.4
+ //
+ if (screen->has_WGL_ARB_pbuffer && glx_sgi_make_current_read)
+ {
+ free(screen->base.GLXversion);
+
+ if (screen->has_WGL_ARB_multisample)
+ {
+ screen->base.GLXversion = xstrdup("1.4");
+ screen->base.GLXmajor = 1;
+ screen->base.GLXminor = 4;
+ }
+ else
+ {
+ screen->base.GLXversion = xstrdup("1.3");
+ screen->base.GLXmajor = 1;
+ screen->base.GLXminor = 3;
+ }
+ LogMessage(X_INFO, "AIGLX: Set GLX version to %s\n", screen->base.GLXversion);
+ }
+ }
+
+ wglMakeCurrent(NULL, NULL);
+ wglDeleteContext(hglrc);
+ ReleaseDC(hwnd, hdc);
+ DestroyWindow(hwnd);
+
+ return &screen->base;
+}
+
+/* ---------------------------------------------------------------------- */
+/*
+ * Window functions
+ */
+
+static Bool
+glxWinRealizeWindow(WindowPtr pWin)
+{
+ Bool result;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ glxWinScreen *screenPriv = (glxWinScreen *) glxGetScreen(pScreen);
+ winWindowPriv(pWin);
+
+ GLWIN_DEBUG_MSG("glxWinRealizeWindow");
+
+ /* Allow the window to be created (RootlessRealizeWindow is inside our wrap) */
+ pScreen->RealizeWindow = screenPriv->RealizeWindow;
+ result = pScreen->RealizeWindow(pWin);
+ pScreen->RealizeWindow = glxWinRealizeWindow;
+
+ // Check if ze need to move the window\n
+ if (pWinPriv->GlCtxWnd && pWinPriv->hWnd)
+ {
+ ShowWindow(pWinPriv->hWnd,SW_SHOW);
+ }
+ return result;
+}
+
+
+static void
+glxWinCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+{
+ __GLXWinDrawable *pGlxDraw;
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ glxWinScreen *screenPriv = (glxWinScreen *) glxGetScreen(pScreen);
+
+ GLWIN_TRACE_MSG("glxWinCopyWindow pWindow %p", pWindow);
+
+ dixLookupResourceByType((pointer) &pGlxDraw, pWindow->drawable.id, __glXDrawableRes,
+ NullClient, DixUnknownAccess);
+
+
+ /*
+ Discard any CopyWindow requests if a GL drawing context is pointing at the window
+
+ For regions which are being drawn by GL, the shadow framebuffer doesn't have the
+ correct bits, so we wish to avoid shadow framebuffer damage occuring, which will
+ cause those incorrect bits to be transferred to the display....
+ */
+ if (pGlxDraw && pGlxDraw->drawContext)
+ {
+ GLWIN_DEBUG_MSG("glxWinCopyWindow: discarding");
+ return;
+ }
+
+ GLWIN_DEBUG_MSG("glxWinCopyWindow - passing to hw layer");
+
+ pScreen->CopyWindow = screenPriv->CopyWindow;
+ pScreen->CopyWindow(pWindow, ptOldOrg, prgnSrc);
+ pScreen->CopyWindow = glxWinCopyWindow;
+
+}
+
+static Bool
+glxWinPositionWindow(WindowPtr pWin, int x, int y)
+{
+ Bool result;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ glxWinScreen *screenPriv = (glxWinScreen *) glxGetScreen(pScreen);
+ winWindowPriv(pWin);
+
+ pScreen->PositionWindow = screenPriv->PositionWindow;
+ result = pScreen->PositionWindow(pWin, x, y);
+ pScreen->PositionWindow = glxWinPositionWindow;
+
+ if (pWinPriv->GlCtxWnd && pWinPriv->hWnd)
+ {
+ MoveWindow(pWinPriv->hWnd,
+ pWin->drawable.x,
+ pWin->drawable.y,
+ pWin->drawable.width,
+ pWin->drawable.height,
+ FALSE);
+ }
+ return result;
+}
+
+
+static Bool
+glxWinUnrealizeWindow(WindowPtr pWin)
+{
+ Bool result;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ glxWinScreen *screenPriv = (glxWinScreen *)glxGetScreen(pScreen);
+ winWindowPriv(pWin);
+
+ GLWIN_DEBUG_MSG("glxWinUnrealizeWindow");
+
+ pScreen->UnrealizeWindow = screenPriv->UnrealizeWindow;
+ result = pScreen->UnrealizeWindow(pWin);
+ pScreen->UnrealizeWindow = glxWinUnrealizeWindow;
+
+ if (pWinPriv->GlCtxWnd && pWinPriv->hWnd)
+ ShowWindow(pWinPriv->hWnd,SW_HIDE);
+
+ return result;
+}
+
+static Bool
+glxWinDestroyWindow(WindowPtr pWin)
+{
+ Bool result;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ glxWinScreen *screenPriv = (glxWinScreen *)glxGetScreen(pScreen);
+ winWindowPriv(pWin);
+
+ GLWIN_DEBUG_MSG("glxWinDestroyWindow");
+
+ if (pWinPriv->GlCtxWnd && pWinPriv->hWnd)
+ {
+ __GLXWinDrawable *pGlxDraw;
+
+ dixLookupResourceByType((pointer) &pGlxDraw, pWin->drawable.id, __glXDrawableRes, NullClient, DixUnknownAccess);
+
+ if (pGlxDraw && pGlxDraw->drawContext)
+ {
+ if (pGlxDraw->drawContext->hwnd!=pWinPriv->hWnd)
+ ErrorF("Wrong assumption\n");
+ glxWinReleaseDC(pGlxDraw->drawContext->hwnd, pGlxDraw->drawContext->hDC, pGlxDraw);
+ pGlxDraw->drawContext->hDC=NULL;
+ pGlxDraw->drawContext->hwnd=NULL;
+ }
+ DestroyWindow(pWinPriv->hWnd);
+ pWinPriv->hWnd=NULL;
+ pWinPriv->GlCtxWnd=0;
+ }
+
+ pScreen->DestroyWindow = screenPriv->DestroyWindow;
+ result = pScreen->DestroyWindow(pWin);
+ pScreen->DestroyWindow = glxWinDestroyWindow;
+
+ return result;
+}
+
+/* ---------------------------------------------------------------------- */
+/*
+ * Drawable functions
+ */
+
+static GLboolean
+glxWinDrawableSwapBuffers(ClientPtr client, __GLXdrawable *base)
+{
+ BOOL ret;
+ __GLXWinDrawable *draw = (__GLXWinDrawable *)base;
+
+ /* Swap buffers on the last active context for drawing on the drawable */
+ if (draw->drawContext == NULL)
+ {
+ GLWIN_TRACE_MSG("glxWinSwapBuffers - no context for drawable");
+ return GL_FALSE;
+ }
+
+ GLWIN_TRACE_MSG("glxWinSwapBuffers on drawable %p, last context %p (native ctx %p)", base, draw->drawContext, draw->drawContext->ctx);
+
+ /*
+ draw->drawContext->base.drawPriv will not be set if the context is not current anymore,
+ but if it is, it should point to this drawable....
+ */
+ assert((draw->drawContext->base.drawPriv == NULL) || (draw->drawContext->base.drawPriv == base));
+
+ ret = SwapBuffers(draw->drawContext->hDC);
+
+ if (!ret)
+ {
+ ErrorF("wglSwapBuffers failed: %s\n", glxWinErrorMessage());
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+static void
+glxWinDrawableCopySubBuffer(__GLXdrawable *drawable,
+ int x, int y, int w, int h)
+{
+ glAddSwapHintRectWINWrapperNonstatic(x, y, w, h);
+ glxWinDrawableSwapBuffers(NULL, drawable);
+}
+
+static void
+glxWinDrawableDestroy(__GLXdrawable *base)
+{
+ __GLXWinDrawable *glxPriv = (__GLXWinDrawable *)base;
+
+ if (glxPriv->drawContext && (__glXLastContext == &((glxPriv->drawContext)->base)))
+ {
+ // if this context is current and has unflushed commands, say we have flushed them
+ // (don't actually flush them, the window is going away anyhow, and an implict flush occurs
+ // on the next context change)
+ // (GLX core considers it an error when we try to select a new current context if the old one
+ // has unflushed commands, but the window has disappeared..)
+ __GLX_NOTE_FLUSHED_CMDS(__glXLastContext);
+ __glXLastContext = NULL;
+ }
+
+ if (glxPriv->hPbuffer)
+ if (!wglDestroyPbufferARBWrapper(glxPriv->hPbuffer))
+ {
+ ErrorF("wglDestroyPbufferARB failed: %s\n", glxWinErrorMessage());
+ }
+
+ if (glxPriv->dibDC)
+ {
+ // restore the default DIB
+ SelectObject(glxPriv->dibDC, glxPriv->hOldDIB);
+
+ if (!DeleteDC(glxPriv->dibDC))
+ {
+ ErrorF("DeleteDC failed: %s\n", glxWinErrorMessage());
+ }
+ }
+
+ if (glxPriv->hDIB)
+ {
+ if (!DeleteObject(glxPriv->hDIB))
+ {
+ ErrorF("DeleteObject failed: %s\n", glxWinErrorMessage());
+ }
+
+ ((PixmapPtr)glxPriv->base.pDraw)->devPrivate.ptr = glxPriv->pOldBits;
+ }
+
+ GLWIN_DEBUG_MSG("glxWinDestroyDrawable");
+ free(glxPriv);
+}
+
+static __GLXdrawable *
+glxWinCreateDrawable(ClientPtr client,
+ __GLXscreen *screen,
+ DrawablePtr pDraw,
+ XID drawId,
+ int type,
+ XID glxDrawId,
+ __GLXconfig *conf)
+{
+ __GLXWinDrawable *glxPriv;
+
+ glxPriv = calloc(1,sizeof(*glxPriv));
+
+ if (glxPriv == NULL)
+ return NULL;
+
+ if(!__glXDrawableInit(&glxPriv->base, screen, pDraw, type, glxDrawId, conf)) {
+ free(glxPriv);
+ return NULL;
+ }
+
+ glxPriv->base.destroy = glxWinDrawableDestroy;
+ glxPriv->base.swapBuffers = glxWinDrawableSwapBuffers;
+ glxPriv->base.copySubBuffer = glxWinDrawableCopySubBuffer;
+ // glxPriv->base.waitX what are these for?
+ // glxPriv->base.waitGL
+
+ GLWIN_DEBUG_MSG("glxWinCreateDrawable %p", glxPriv);
+
+ return &glxPriv->base;
+}
+
+/* ---------------------------------------------------------------------- */
+/*
+ * Texture functions
+ */
+
+static
+int glxWinBindTexImage(__GLXcontext *baseContext,
+ int buffer,
+ __GLXdrawable *pixmap)
+{
+ ErrorF("glxWinBindTexImage: not implemented\n");
+ return FALSE;
+}
+
+static
+int glxWinReleaseTexImage(__GLXcontext *baseContext,
+ int buffer,
+ __GLXdrawable *pixmap)
+{
+ ErrorF(" glxWinReleaseTexImage: not implemented\n");
+ return FALSE;
+}
+
+/* ---------------------------------------------------------------------- */
+/*
+ * Lazy update context implementation
+ *
+ * WGL contexts are created for a specific HDC, so we cannot create the WGL
+ * context in glxWinCreateContext(), we must defer creation until the context
+ * is actually used on a specifc drawable which is connected to a native window,
+ * pbuffer or DIB
+ *
+ * The WGL context may be used on other, compatible HDCs, so we don't need to
+ * recreate it for every new native window
+ *
+ * XXX: I wonder why we can't create the WGL context on the screen HDC ?
+ * Basically we assume all HDCs are compatible at the moment: if they are not
+ * we are in a muddle, there was some code in the old implementation to attempt
+ * to transparently migrate a context to a new DC by copying state and sharing
+ * lists with the old one...
+ */
+
+static void
+glxWinSetPixelFormat(__GLXWinContext *gc, HDC hdc, int bppOverride, int drawableTypeOverride)
+{
+ __GLXscreen *screen = gc->base.pGlxScreen;
+ glxWinScreen *winScreen = (glxWinScreen *)screen;
+
+ __GLXconfig *config = gc->base.config;
+ GLXWinConfig *winConfig = (GLXWinConfig *)config;
+
+ GLWIN_DEBUG_MSG("glxWinSetPixelFormat: pixelFormatIndex %d", winConfig->pixelFormatIndex);
+
+ /*
+ Normally, we can just use the the pixelFormatIndex corresponding
+ to the fbconfig which has been specified by the client
+ */
+
+ if (!((bppOverride && (bppOverride != (config->redBits + config->greenBits + config->blueBits) ))
+ || ((config->drawableType & drawableTypeOverride) == 0)))
+ {
+ if (!SetPixelFormat(hdc, winConfig->pixelFormatIndex, NULL))
+ {
+ ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage());
+ return;
+ }
+
+ return;
+ }
+
+ /*
+ However, in certain special cases this pixel format will be incompatible with the
+ use we are going to put it to, so we need to re-evaluate the pixel format to use:
+
+ 1) When PFD_DRAW_TO_BITMAP is set, ChoosePixelFormat() always returns a format with
+ the cColorBits we asked for, so we need to ensure it matches the bpp of the bitmap
+
+ 2) Applications may assume that visuals selected with glXChooseVisual() work with
+ pixmap drawables (there is no attribute to explicitly query for pixmap drawable
+ support as there is for glXChooseFBConfig())
+ (it's arguable this is an error in the application, but we try to make it work)
+
+ pixmap rendering is always slow for us, so we don't want to choose those visuals
+ by default, but if the actual drawable type we're trying to select the context
+ on (drawableTypeOverride) isn't supported by the selected fbConfig, reconsider
+ and see if we can find a suitable one...
+ */
+ ErrorF("glxWinSetPixelFormat: having second thoughts: cColorbits %d, bppOveride %d; config->drawableType %d, drawableTypeOverride %d\n",
+ (config->redBits + config->greenBits + config->blueBits), bppOverride, config->drawableType, drawableTypeOverride);
+
+ if (!winScreen->has_WGL_ARB_pixel_format)
+ {
+ PIXELFORMATDESCRIPTOR pfd;
+ int pixelFormat;
+
+ /* convert fbConfig to PFD */
+ if (fbConfigToPixelFormat(gc->base.config, &pfd, drawableTypeOverride))
+ {
+ ErrorF("glxWinSetPixelFormat: fbConfigToPixelFormat failed\n");
+ return;
+ }
+
+#ifdef _DEBUG
+ if (glxWinDebugSettings.dumpPFD)
+ pfdOut(&pfd);
+#endif
+
+ if (bppOverride)
+ {
+ GLWIN_DEBUG_MSG("glxWinSetPixelFormat: Forcing bpp from %d to %d\n", pfd.cColorBits, bppOverride);
+ pfd.cColorBits = bppOverride;
+ }
+
+ pixelFormat = ChoosePixelFormat(hdc, &pfd);
+ if (pixelFormat == 0)
+ {
+ ErrorF("ChoosePixelFormat error: %s\n", glxWinErrorMessage());
+ return;
+ }
+
+ GLWIN_DEBUG_MSG("ChoosePixelFormat: chose pixelFormatIndex %d", pixelFormat);
+ ErrorF("ChoosePixelFormat: chose pixelFormatIndex %d (rather than %d as originally planned)\n", pixelFormat, winConfig->pixelFormatIndex);
+
+ if (!SetPixelFormat(hdc, pixelFormat, &pfd))
+ {
+ ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage());
+ return;
+ }
+ }
+ else
+ {
+ int pixelFormat = fbConfigToPixelFormatIndex(hdc, gc->base.config, drawableTypeOverride, winScreen);
+ if (pixelFormat == 0)
+ {
+ ErrorF("wglChoosePixelFormat error: %s\n", glxWinErrorMessage());
+ return;
+ }
+
+ GLWIN_DEBUG_MSG("wglChoosePixelFormat: chose pixelFormatIndex %d", pixelFormat);
+ ErrorF("wglChoosePixelFormat: chose pixelFormatIndex %d (rather than %d as originally planned)\n", pixelFormat, winConfig->pixelFormatIndex);
+
+ if (!SetPixelFormat(hdc, pixelFormat, NULL))
+ {
+ ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage());
+ return;
+ }
+ }
+}
+
+static HDC
+glxWinMakeDC(__GLXWinContext *gc, __GLXWinDrawable *draw, HWND *hwnd)
+{
+ HDC hdc = NULL;
+ *hwnd = NULL;
+
+ if (draw == NULL)
+ {
+ GLWIN_TRACE_MSG("No drawable for context %p (native ctx %p)", gc, gc->ctx);
+ return NULL;
+ }
+
+ switch (draw->base.type)
+ {
+ case GLX_DRAWABLE_WINDOW:
+ {
+ WindowPtr pWin;
+
+ pWin = (WindowPtr) draw->base.pDraw;
+ if (pWin == NULL)
+ {
+ GLWIN_TRACE_MSG("for drawable %p, no WindowPtr", pWin);
+ return NULL;
+ }
+
+ *hwnd = winGetWindowInfo(pWin);
+
+ if (*hwnd == NULL)
+ {
+ ErrorF("No HWND error: %s\n", glxWinErrorMessage());
+ return NULL;
+ }
+
+ hdc = GetDC(*hwnd);
+
+ if (hdc == NULL)
+ ErrorF("GetDC error: %s: hwnd %x, gc %p, gc->ctx %p ,gc->hwnd %p\n", glxWinErrorMessage(), *hwnd, gc, gc->ctx, gc->hwnd);
+
+ if (gc->hDC)
+ {
+ glxWinReleaseDC(gc->hwnd, gc->hDC, draw);
+ gc->hDC=NULL;
+ }
+#ifdef _DEBUG
+ if (glxWinDebugSettings.enableTrace)
+ GLWIN_DEBUG_HWND(*hwnd);
+
+ GLWIN_TRACE_MSG("for context %p (native ctx %p), hWnd changed from %p to %p", gc, gc->ctx, gc->hwnd, *hwnd);
+#endif
+ gc->hwnd = *hwnd;
+
+ /* Check if we need to set the pixelformat */
+ {
+ winWindowPriv(pWin);
+ if (!pWinPriv->PixelFormatSet)
+ {
+ pWinPriv->PixelFormatSet=TRUE;
+ /* We must select a pixelformat, but SetPixelFormat can only be called once for a window... */
+ glxWinSetPixelFormat(gc, hdc, 0, GLX_WINDOW_BIT);
+ }
+ }
+ }
+ break;
+
+ case GLX_DRAWABLE_PBUFFER:
+ {
+ hdc = wglGetPbufferDCARBWrapper(draw->hPbuffer);
+
+ if (hdc == NULL)
+ ErrorF("GetDC (pbuffer) error: %s\n", glxWinErrorMessage());
+ }
+ break;
+
+ case GLX_DRAWABLE_PIXMAP:
+ {
+ hdc = draw->dibDC;
+#ifdef _DEBUG
+ if (glxWinDebugSettings.dumpDC)
+ GLWIN_DEBUG_MSG("Got PIXMAP HDC %p for window %p", hdc, *hwnd);
+#endif
+ }
+ break;
+
+ default:
+ {
+ ErrorF("glxWinMakeDC: tried to makeDC for unhandled drawable type %d\n", draw->base.type);
+ }
+ }
+
+#ifdef _DEBUG
+ if (glxWinDebugSettings.dumpDC)
+ GLWIN_HDC_DEBUG_MSG("Got HDC %p for window %p", hdc, *hwnd);
+#endif
+
+ return hdc;
+}
+
+static void
+glxWinReleaseDC(HWND hwnd, HDC hdc,__GLXWinDrawable *draw)
+{
+ switch (draw->base.type)
+ {
+ case GLX_DRAWABLE_WINDOW:
+ {
+ ReleaseDC(hwnd, hdc);
+ }
+ break;
+
+ case GLX_DRAWABLE_PBUFFER:
+ {
+ if (!wglReleasePbufferDCARBWrapper(draw->hPbuffer, hdc))
+ {
+ ErrorF("wglReleasePbufferDCARB error: %s\n", glxWinErrorMessage());
+ }
+ }
+ break;
+
+ case GLX_DRAWABLE_PIXMAP:
+ {
+ // don't release DC, the memory DC lives as long as the bitmap
+
+ // We must ensure that all GDI drawing into the bitmap has completed
+ // in case we subsequently access the bits from it
+ GdiFlush();
+ }
+ break;
+
+ default:
+ {
+ ErrorF("glxWinReleaseDC: tried to releaseDC for unhandled drawable type %d\n", draw->base.type);
+ }
+ }
+}
+
+static void
+glxWinDeferredCreateContext(__GLXWinContext *gc, __GLXWinDrawable *draw)
+{
+ HWND hwnd;
+ GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: attach context %p to drawable %p", gc, draw);
+
+ switch (draw->base.type)
+ {
+ case GLX_DRAWABLE_WINDOW:
+ {
+ WindowPtr pWin = (WindowPtr) draw->base.pDraw;
+
+ if (!(gc->base.config->drawableType & GLX_WINDOW_BIT))
+ {
+ ErrorF("glxWinDeferredCreateContext: tried to attach a context whose fbConfig doesn't have drawableType GLX_WINDOW_BIT to a GLX_DRAWABLE_WINDOW drawable\n");
+ }
+
+ if (pWin == NULL)
+ {
+ GLWIN_DEBUG_MSG("Deferring until X window is created");
+ return;
+ }
+
+ GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: pWin %p", pWin);
+
+ if (winGetWindowInfo(pWin) == NULL)
+ {
+ GLWIN_DEBUG_MSG("Deferring until native window is created");
+ return;
+ }
+ }
+ break;
+
+ case GLX_DRAWABLE_PBUFFER:
+ {
+ if (draw->hPbuffer == NULL)
+ {
+ __GLXscreen *screen;
+ glxWinScreen *winScreen;
+ int pixelFormat;
+ // XXX: which DC are supposed to use???
+ HDC screenDC = GetDC(NULL);
+
+ if (!(gc->base.config->drawableType & GLX_PBUFFER_BIT))
+ {
+ ErrorF("glxWinDeferredCreateContext: tried to attach a context whose fbConfig doesn't have drawableType GLX_PBUFFER_BIT to a GLX_DRAWABLE_PBUFFER drawable\n");
+ }
+
+ screen = gc->base.pGlxScreen;
+ winScreen = (glxWinScreen *)screen;
+
+ pixelFormat = fbConfigToPixelFormatIndex(screenDC, gc->base.config, GLX_DRAWABLE_PBUFFER, winScreen);
+ if (pixelFormat == 0)
+ {
+ ErrorF("wglChoosePixelFormat error: %s\n", glxWinErrorMessage());
+ return;
+ }
+
+ draw->hPbuffer = wglCreatePbufferARBWrapper(screenDC, pixelFormat, draw->base.pDraw->width, draw->base.pDraw->height, NULL);
+ ReleaseDC(NULL, screenDC);
+
+ if (draw->hPbuffer == NULL)
+ {
+ ErrorF("wglCreatePbufferARBWrapper error: %s\n", glxWinErrorMessage());
+ return;
+ }
+
+ GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: pBuffer %p created for drawable %p", draw->hPbuffer, draw);
+ }
+ }
+ break;
+
+ case GLX_DRAWABLE_PIXMAP:
+ {
+ if (draw->dibDC == NULL)
+ {
+ BITMAPINFOHEADER bmpHeader;
+ void *pBits;
+
+ memset (&bmpHeader, 0, sizeof(BITMAPINFOHEADER));
+ bmpHeader.biSize = sizeof(BITMAPINFOHEADER);
+ bmpHeader.biWidth = draw->base.pDraw->width;
+ bmpHeader.biHeight = draw->base.pDraw->height;
+ bmpHeader.biPlanes = 1;
+ bmpHeader.biBitCount = draw->base.pDraw->bitsPerPixel;
+ bmpHeader.biCompression = BI_RGB;
+
+ if (!(gc->base.config->drawableType & GLX_PIXMAP_BIT))
+ {
+ ErrorF("glxWinDeferredCreateContext: tried to attach a context whose fbConfig doesn't have drawableType GLX_PIXMAP_BIT to a GLX_DRAWABLE_PIXMAP drawable\n");
+ }
+
+ draw->dibDC = CreateCompatibleDC(NULL);
+ if (draw->dibDC == NULL)
+ {
+ ErrorF("CreateCompatibleDC error: %s\n", glxWinErrorMessage());
+ return;
+ }
+
+ draw->hDIB = CreateDIBSection(draw->dibDC, (BITMAPINFO *)&bmpHeader, DIB_RGB_COLORS, &pBits, 0, 0);
+ if (draw->dibDC == NULL)
+ {
+ ErrorF("CreateDIBSection error: %s\n", glxWinErrorMessage());
+ return;
+ }
+
+ // XXX: CreateDIBSection insists on allocating the bitmap memory for us, so we're going to
+ // need some jiggery pokery to point the underlying X Drawable's bitmap at the same set of bits
+ // so that they can be read with XGetImage as well as glReadPixels, assuming the formats are
+ // even compatible ...
+ draw->pOldBits = ((PixmapPtr)draw->base.pDraw)->devPrivate.ptr;
+ ((PixmapPtr)draw->base.pDraw)->devPrivate.ptr = pBits;
+
+ // Select the DIB into the DC
+ draw->hOldDIB = SelectObject(draw->dibDC, draw->hDIB);
+ if (!draw->hOldDIB)
+ {
+ ErrorF("SelectObject error: %s\n", glxWinErrorMessage());
+ }
+
+ // Set the pixel format of the bitmap
+ glxWinSetPixelFormat(gc, draw->dibDC, draw->base.pDraw->bitsPerPixel, GLX_PIXMAP_BIT);
+
+ GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: DIB bitmap %p created for drawable %p", draw->hDIB, draw);
+ }
+ }
+ break;
+
+ default:
+ {
+ ErrorF("glxWinDeferredCreateContext: tried to attach unhandled drawable type %d\n", draw->base.type);
+ return;
+ }
+ }
+
+ gc->hDC = glxWinMakeDC(gc, draw, &hwnd);
+ gc->ctx = wglCreateContext(gc->hDC);
+
+ if (gc->ctx == NULL)
+ {
+ glxWinReleaseDC(hwnd, gc->hDC, draw);
+ gc->hDC=0;
+
+ ErrorF("wglCreateContext error: %s\n", glxWinErrorMessage());
+ return;
+ }
+
+ GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: attached context %p to native context %p drawable %p", gc, gc->ctx, draw);
+
+ // if the native context was created successfully, shareLists if needed
+ if (gc->ctx && gc->shareContext)
+ {
+ GLWIN_DEBUG_MSG("glxWinCreateContextReal shareLists with context %p (native ctx %p)", gc->shareContext, gc->shareContext->ctx);
+
+ if (!wglShareLists(gc->shareContext->ctx, gc->ctx))
+ {
+ ErrorF("wglShareLists error: %s\n", glxWinErrorMessage());
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+/*
+ * Context functions
+ */
+
+
+/* Context manipulation routines should return TRUE on success, FALSE on failure */
+static int
+glxWinContextMakeCurrent(__GLXcontext *base)
+{
+ __GLXWinContext *gc = (__GLXWinContext *)base;
+ BOOL ret;
+ __GLXWinDrawable *drawPriv;
+
+#ifdef _DEBUG
+ GLWIN_TRACE_MSG("glxWinContextMakeCurrent context %p (native ctx %p)", gc, gc->ctx);
+ glWinCallDelta();
+#endif
+
+ /* Keep a note of the last active context in the drawable */
+ drawPriv = (__GLXWinDrawable *)gc->base.drawPriv;
+ drawPriv->drawContext = gc;
+
+ if (gc->ctx == NULL)
+ {
+ glxWinDeferredCreateContext(gc, drawPriv);
+ }
+
+ if (gc->ctx == NULL)
+ {
+ ErrorF("glxWinContextMakeCurrent: Native context is NULL\n");
+ return FALSE;
+ }
+
+ if ((gc->base.readPriv != NULL) && (gc->base.readPriv != gc->base.drawPriv))
+ {
+ // XXX: should only occur with WGL_ARB_make_current_read
+ /*
+ If there is a separate read drawable, create a separate read DC, and
+ use the wglMakeContextCurrent extension to make the context current drawing
+ to one DC and reading from the other
+ */
+ gc->hreadDC = glxWinMakeDC(gc, (__GLXWinDrawable *)gc->base.readPriv, &gc->hreadwnd);
+ if (gc->hreadDC == NULL)
+ {
+ ErrorF("glxWinMakeDC failed for readDC\n");
+ return FALSE;
+ }
+
+ ret = wglMakeContextCurrentARBWrapper(gc->hDC, gc->hreadDC, gc->ctx);
+ if (!ret)
+ {
+ ErrorF("wglMakeContextCurrentARBWrapper error: %s\n", glxWinErrorMessage());
+ }
+ }
+ else
+ {
+ /* Otherwise, just use wglMakeCurrent */
+ if (!gc->hDC)
+ {
+ /* It probably has been release by loseCurrent, so create it again */
+ gc->hDC = glxWinMakeDC(gc, drawPriv, &gc->hwnd);
+ }
+ ret = wglMakeCurrent(gc->hDC, gc->ctx);
+ if (!ret)
+ {
+ DWORD ErrorCode=GetLastError();
+ ErrorF("wglMakeCurrent error: %x dc %p ctx %p\n", ErrorCode,gc->hDC,gc->ctx);
+ if (!ErrorCode)
+ {
+ ErrorF("Error code was 0, assuming no error.\n");
+ ret=TRUE;
+ }
+ }
+ }
+
+ // apparently make current could fail if the context is current in a different thread,
+ // but that shouldn't be able to happen in the current server...
+
+ return ret;
+}
+
+static int
+glxWinContextLoseCurrent(__GLXcontext *base)
+{
+ BOOL ret=TRUE;
+ __GLXWinContext *gc = (__GLXWinContext *)base;
+
+#ifdef _DEBUG
+ GLWIN_TRACE_MSG("glxWinContextLoseCurrent context %p (native ctx %p)", gc, gc->ctx);
+ glWinCallDelta();
+#endif
+
+
+ if (wglGetCurrentContext()==gc->ctx)
+ {
+ /* Only do this when we are sure we are currently the active, otherwise we are deactivating the wrong one (this is happening!!!) */
+ ret = wglMakeCurrent(NULL, NULL);
+ if (!ret)
+ ErrorF("glxWinContextLoseCurrent error: %s\n", glxWinErrorMessage());
+ }
+ else
+ {
+ return FALSE;
+ }
+
+ /* Since drawPriv is going to be set to zero in the context, we have to release the DC to */
+ if (gc->hDC && gc->base.drawPriv) glxWinReleaseDC(gc->hwnd, gc->hDC, (__GLXWinDrawable *)gc->base.drawPriv);
+ if (gc->hreadDC && gc->base.readPriv) glxWinReleaseDC(gc->hreadwnd, gc->hreadDC, (__GLXWinDrawable *)gc->base.readPriv);
+ gc->hDC=NULL;
+ gc->hreadDC=NULL;
+
+ base->isCurrent=FALSE; /* It looks like glx is not doing this */
+
+ return ret;
+}
+
+static int
+glxWinContextCopy(__GLXcontext *dst_base, __GLXcontext *src_base, unsigned long mask)
+{
+ __GLXWinContext *dst = (__GLXWinContext *)dst_base;
+ __GLXWinContext *src = (__GLXWinContext *)src_base;
+ BOOL ret;
+
+ GLWIN_DEBUG_MSG("glxWinContextCopy");
+
+ ret = wglCopyContext(src->ctx, dst->ctx, mask);
+ if (!ret)
+ {
+ ErrorF("wglCopyContext error: %s\n", glxWinErrorMessage());
+ }
+
+ return ret;
+}
+
+static int
+glxWinContextForceCurrent(__GLXcontext *base)
+{
+ /* wglMakeCurrent always flushes the previous context, so this is equivalent to glxWinContextMakeCurrent */
+ return glxWinContextMakeCurrent(base);
+}
+
+static void
+glxWinContextDestroy(__GLXcontext *base)
+{
+ __GLXWinContext *gc = (__GLXWinContext *)base;
+
+ if (gc != NULL)
+ {
+ GLWIN_DEBUG_MSG("GLXcontext %p destroyed (native ctx %p)", base, gc->ctx);
+
+ if (gc->ctx)
+ {
+ BOOL ret;
+ /* It's bad style to delete the context while it's still current */
+ if (wglGetCurrentContext() == gc->ctx)
+ {
+ wglMakeCurrent(NULL, NULL);
+ }
+
+ ret = wglDeleteContext(gc->ctx);
+ if (!ret)
+ ErrorF("wglDeleteContext error: %s\n", glxWinErrorMessage());
+ if (gc->base.drawPriv && gc->hDC) glxWinReleaseDC(gc->hwnd, gc->hDC, (__GLXWinDrawable *)gc->base.drawPriv);
+ if (gc->base.readPriv && gc->hreadDC) glxWinReleaseDC(gc->hreadwnd, gc->hreadDC, (__GLXWinDrawable *)gc->base.readPriv);
+ gc->hDC=NULL;
+ gc->hreadDC=NULL;
+ gc->ctx = NULL;
+ }
+
+ free(gc);
+ }
+}
+
+static __GLXcontext *
+glxWinCreateContext(__GLXscreen *screen,
+ __GLXconfig *modes,
+ __GLXcontext *baseShareContext)
+{
+ __GLXWinContext *context;
+ __GLXWinContext *shareContext = (__GLXWinContext *)baseShareContext;
+
+ static __GLXtextureFromPixmap glxWinTextureFromPixmap =
+ {
+ glxWinBindTexImage,
+ glxWinReleaseTexImage
+ };
+
+ context = (__GLXWinContext *)calloc(1, sizeof(__GLXWinContext));
+
+ if (!context)
+ return NULL;
+
+ memset(context, 0, sizeof *context);
+ context->base.destroy = glxWinContextDestroy;
+ context->base.makeCurrent = glxWinContextMakeCurrent;
+ context->base.loseCurrent = glxWinContextLoseCurrent;
+ context->base.copy = glxWinContextCopy;
+ context->base.forceCurrent = glxWinContextForceCurrent;
+ context->base.textureFromPixmap = &glxWinTextureFromPixmap;
+ context->base.config = modes;
+ context->base.pGlxScreen = screen;
+
+ // actual native GL context creation is deferred until attach()
+ //context->ctx = NULL; already done with memset
+ context->shareContext = shareContext;
+
+ glWinSetupDispatchTable();
+
+ GLWIN_DEBUG_MSG("GLXcontext %p created", context);
+
+ return &(context->base);
+}
+
+/* ---------------------------------------------------------------------- */
+/*
+ * Utility functions
+ */
+
+static int
+fbConfigToPixelFormat(__GLXconfig *mode, PIXELFORMATDESCRIPTOR *pfdret, int drawableTypeOverride)
+{
+ PIXELFORMATDESCRIPTOR pfd = {
+ sizeof(PIXELFORMATDESCRIPTOR), /* size of this pfd */
+ 1, /* version number */
+ PFD_SUPPORT_OPENGL, /* support OpenGL */
+ PFD_TYPE_RGBA, /* RGBA type */
+ 24, /* 24-bit color depth */
+ 0, 0, 0, 0, 0, 0, /* color bits ignored */
+ 0, /* no alpha buffer */
+ 0, /* shift bit ignored */
+ 0, /* no accumulation buffer */
+ 0, 0, 0, 0, /* accum bits ignored */
+ 32, /* 32-bit z-buffer */
+ 0, /* no stencil buffer */
+ 0, /* no auxiliary buffer */
+ PFD_MAIN_PLANE, /* main layer */
+ 0, /* reserved */
+ 0, 0, 0 /* layer masks ignored */
+ };
+
+ if ((mode->drawableType | drawableTypeOverride) & GLX_WINDOW_BIT)
+ pfd.dwFlags |= PFD_DRAW_TO_WINDOW; /* support window */
+
+ if ((mode->drawableType | drawableTypeOverride) & GLX_PIXMAP_BIT)
+ pfd.dwFlags |= (PFD_DRAW_TO_BITMAP | PFD_SUPPORT_GDI); /* supports software rendering to bitmap */
+
+ if (mode->stereoMode) {
+ pfd.dwFlags |= PFD_STEREO;
+ }
+ if (mode->doubleBufferMode) {
+ pfd.dwFlags |= PFD_DOUBLEBUFFER;
+ }
+
+ pfd.iPixelType = PFD_TYPE_RGBA;
+ pfd.cColorBits = mode->redBits + mode->greenBits + mode->blueBits;
+ pfd.cRedBits = mode->redBits;
+ pfd.cRedShift = 0; /* FIXME */
+ pfd.cGreenBits = mode->greenBits;
+ pfd.cGreenShift = 0; /* FIXME */
+ pfd.cBlueBits = mode->blueBits;
+ pfd.cBlueShift = 0; /* FIXME */
+ pfd.cAlphaBits = mode->alphaBits;
+ pfd.cAlphaShift = 0; /* FIXME */
+
+ pfd.cAccumBits = mode->accumRedBits + mode->accumGreenBits + mode->accumBlueBits + mode->accumAlphaBits;
+ pfd.cAccumRedBits = mode->accumRedBits;
+ pfd.cAccumGreenBits = mode->accumGreenBits;
+ pfd.cAccumBlueBits = mode->accumBlueBits;
+ pfd.cAccumAlphaBits = mode->accumAlphaBits;
+
+ pfd.cDepthBits = mode->depthBits;
+ pfd.cStencilBits = mode->stencilBits;
+ pfd.cAuxBuffers = mode->numAuxBuffers;
+
+ /* mode->level ? */
+ /* mode->pixmapMode ? */
+
+ *pfdret = pfd;
+
+ return 0;
+}
+
+#define SET_ATTR_VALUE(attr, value) { attribList[i++] = attr; attribList[i++] = value; assert(i < NUM_ELEMENTS(attribList)); }
+
+static int
+fbConfigToPixelFormatIndex(HDC hdc, __GLXconfig *mode, int drawableTypeOverride, glxWinScreen *winScreen)
+{
+ UINT numFormats;
+ unsigned int i = 0;
+
+ /* convert fbConfig to attr-value list */
+ int attribList[60];
+
+ SET_ATTR_VALUE(WGL_SUPPORT_OPENGL_ARB, TRUE);
+ SET_ATTR_VALUE(WGL_PIXEL_TYPE_ARB, (mode->visualType == GLX_TRUE_COLOR) ? WGL_TYPE_RGBA_ARB : WGL_TYPE_COLORINDEX_ARB);
+ SET_ATTR_VALUE(WGL_COLOR_BITS_ARB, (mode->visualType == GLX_TRUE_COLOR) ? mode->rgbBits : mode->indexBits);
+ SET_ATTR_VALUE(WGL_RED_BITS_ARB, mode->redBits);
+ SET_ATTR_VALUE(WGL_GREEN_BITS_ARB, mode->greenBits);
+ SET_ATTR_VALUE(WGL_BLUE_BITS_ARB, mode->blueBits);
+ SET_ATTR_VALUE(WGL_ALPHA_BITS_ARB, mode->alphaBits);
+ SET_ATTR_VALUE(WGL_ACCUM_RED_BITS_ARB, mode->accumRedBits);
+ SET_ATTR_VALUE(WGL_ACCUM_GREEN_BITS_ARB, mode->accumGreenBits);
+ SET_ATTR_VALUE(WGL_ACCUM_BLUE_BITS_ARB, mode->accumBlueBits);
+ SET_ATTR_VALUE(WGL_ACCUM_ALPHA_BITS_ARB, mode->accumAlphaBits);
+ SET_ATTR_VALUE(WGL_DEPTH_BITS_ARB, mode->depthBits);
+ SET_ATTR_VALUE(WGL_STENCIL_BITS_ARB, mode->stencilBits);
+ SET_ATTR_VALUE(WGL_AUX_BUFFERS_ARB, mode->numAuxBuffers);
+
+ if (mode->doubleBufferMode)
+ SET_ATTR_VALUE(WGL_DOUBLE_BUFFER_ARB, TRUE);
+
+ if (mode->stereoMode)
+ SET_ATTR_VALUE(WGL_STEREO_ARB, TRUE);
+
+ // Some attributes are only added to the list if the value requested is not 'don't care', as exactly matching that is daft..
+ if (mode->swapMethod == GLX_SWAP_EXCHANGE_OML)
+ SET_ATTR_VALUE(WGL_SWAP_METHOD_ARB, WGL_SWAP_EXCHANGE_ARB);
+
+ if (mode->swapMethod == GLX_SWAP_COPY_OML)
+ SET_ATTR_VALUE(WGL_SWAP_COPY_ARB, TRUE);
+
+ // XXX: this should probably be the other way around, but that messes up drawableTypeOverride
+ if (mode->visualRating == GLX_SLOW_VISUAL_EXT)
+ SET_ATTR_VALUE(WGL_ACCELERATION_ARB, WGL_NO_ACCELERATION_ARB);
+
+ // must support all the drawable types the mode supports
+ if ((mode->drawableType | drawableTypeOverride) & GLX_WINDOW_BIT)
+ SET_ATTR_VALUE(WGL_DRAW_TO_WINDOW_ARB,TRUE);
+
+ // XXX: this is a horrible hacky heuristic, in fact this whole drawableTypeOverride thing is a bad idea
+ // try to avoid asking for formats which don't exist (by not asking for all when adjusting the config to include the drawableTypeOverride)
+ if (drawableTypeOverride == GLX_WINDOW_BIT)
+ {
+ if (mode->drawableType & GLX_PIXMAP_BIT)
+ SET_ATTR_VALUE(WGL_DRAW_TO_BITMAP_ARB, TRUE);
+
+ if (mode->drawableType & GLX_PBUFFER_BIT)
+ if (winScreen->has_WGL_ARB_pbuffer)
+ SET_ATTR_VALUE(WGL_DRAW_TO_PBUFFER_ARB, TRUE);
+ }
+ else
+ {
+ if (drawableTypeOverride & GLX_PIXMAP_BIT)
+ SET_ATTR_VALUE(WGL_DRAW_TO_BITMAP_ARB, TRUE);
+
+ if (drawableTypeOverride & GLX_PBUFFER_BIT)
+ if (winScreen->has_WGL_ARB_pbuffer)
+ SET_ATTR_VALUE(WGL_DRAW_TO_PBUFFER_ARB, TRUE);
+ }
+
+ SET_ATTR_VALUE(0, 0); // terminator
+
+ /* choose the first match */
+ {
+ int pixelFormatIndex;
+
+ if (!wglChoosePixelFormatARBWrapper(hdc, attribList, NULL, 1, &pixelFormatIndex, &numFormats))
+ {
+ ErrorF("wglChoosePixelFormat error: %s\n", glxWinErrorMessage());
+ }
+ else
+ {
+ if (numFormats > 0)
+ {
+ GLWIN_DEBUG_MSG("wglChoosePixelFormat: chose pixelFormatIndex %d)", pixelFormatIndex);
+ return pixelFormatIndex;
+ }
+ else
+ ErrorF("wglChoosePixelFormat couldn't decide\n");
+ }
+ }
+
+ return 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+#define BITS_AND_SHIFT_TO_MASK(bits,mask) (((1<<(bits))-1) << (mask))
+
+//
+// Create the GLXconfigs using DescribePixelFormat()
+//
+static void
+glxWinCreateConfigs(HDC hdc, glxWinScreen *screen)
+{
+ GLXWinConfig *c, *result, *prev = NULL;
+ int numConfigs = 0;
+ int i = 0;
+ int n = 0;
+ PIXELFORMATDESCRIPTOR pfd;
+
+ GLWIN_DEBUG_MSG("glxWinCreateConfigs");
+
+ screen->base.numFBConfigs = 0;
+ screen->base.fbconfigs = NULL;
+
+ // get the number of pixelformats
+ numConfigs = DescribePixelFormat(hdc, 1, sizeof(PIXELFORMATDESCRIPTOR), NULL);
+ GLWIN_DEBUG_MSG("DescribePixelFormat says %d possible pixel formats", numConfigs);
+
+ /* alloc */
+ result = malloc(sizeof(GLXWinConfig) * numConfigs);
+
+ if (NULL == result)
+ {
+ return;
+ }
+
+ memset(result, 0, sizeof(GLXWinConfig) * numConfigs);
+ n = 0;
+
+ /* fill in configs */
+ for (i = 0; i < numConfigs; i++)
+ {
+ int rc;
+
+ c = &(result[i]);
+ c->base.next = NULL;
+ c->pixelFormatIndex = i+1;
+
+ rc = DescribePixelFormat(hdc, i+1, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
+
+ if (!rc)
+ {
+ ErrorF("DescribePixelFormat failed for index %d, error %s\n", i+1, glxWinErrorMessage());
+ break;
+ }
+
+#ifdef _DEBUG
+ if (glxWinDebugSettings.dumpPFD)
+ pfdOut(&pfd);
+#endif
+
+ if (!(pfd.dwFlags & (PFD_DRAW_TO_WINDOW | PFD_DRAW_TO_BITMAP)) || !(pfd.dwFlags & PFD_SUPPORT_OPENGL))
+ {
+ GLWIN_DEBUG_MSG("pixelFormat %d has unsuitable flags 0x%08lx, skipping", i+1, pfd.dwFlags);
+ continue;
+ }
+
+ c->base.doubleBufferMode = (pfd.dwFlags & PFD_DOUBLEBUFFER) ? GL_TRUE : GL_FALSE;
+ c->base.stereoMode = (pfd.dwFlags & PFD_STEREO) ? GL_TRUE : GL_FALSE;
+
+ c->base.redBits = pfd.cRedBits;
+ c->base.greenBits = pfd.cGreenBits;
+ c->base.blueBits = pfd.cBlueBits;
+ c->base.alphaBits = pfd.cAlphaBits;
+
+ c->base.redMask = BITS_AND_SHIFT_TO_MASK(pfd.cRedBits, pfd.cRedShift);
+ c->base.greenMask = BITS_AND_SHIFT_TO_MASK(pfd.cGreenBits, pfd.cGreenShift);
+ c->base.blueMask = BITS_AND_SHIFT_TO_MASK(pfd.cBlueBits, pfd.cBlueShift);
+ c->base.alphaMask = BITS_AND_SHIFT_TO_MASK(pfd.cAlphaBits, pfd.cAlphaShift);
+
+ c->base.rgbBits = pfd.cColorBits;
+
+ if (pfd.iPixelType == PFD_TYPE_COLORINDEX)
+ {
+ c->base.indexBits = pfd.cColorBits;
+ }
+ else
+ {
+ c->base.indexBits = 0;
+ }
+
+ c->base.accumRedBits = pfd.cAccumRedBits;
+ c->base.accumGreenBits = pfd.cAccumGreenBits;
+ c->base.accumBlueBits = pfd.cAccumBlueBits;
+ c->base.accumAlphaBits = pfd.cAccumAlphaBits;
+ // pfd.cAccumBits;
+
+ c->base.depthBits = pfd.cDepthBits;
+ c->base.stencilBits = pfd.cStencilBits;
+ c->base.numAuxBuffers = pfd.cAuxBuffers;
+
+ // pfd.iLayerType; // ignored
+ c->base.level = 0;
+ // pfd.dwLayerMask; // ignored
+ // pfd.dwDamageMask; // ignored
+
+ c->base.pixmapMode = 0;
+ c->base.visualID = -1; // will be set by __glXScreenInit()
+
+ /* EXT_visual_rating / GLX 1.2 */
+ if (pfd.dwFlags & PFD_GENERIC_FORMAT)
+ {
+ c->base.visualRating = GLX_SLOW_VISUAL_EXT;
+ }
+ else
+ {
+ // PFD_GENERIC_ACCELERATED is not considered, so this may be MCD or ICD acclerated...
+ c->base.visualRating = GLX_NONE_EXT;
+ }
+
+ /* EXT_visual_info / GLX 1.2 */
+ if (pfd.iPixelType == PFD_TYPE_COLORINDEX)
+ {
+ c->base.visualType = GLX_STATIC_COLOR;
+ }
+ else
+ {
+ c->base.visualType = GLX_TRUE_COLOR;
+ }
+
+ // pfd.dwVisibleMask; ???
+ c->base.transparentPixel = GLX_NONE;
+ c->base.transparentRed = GLX_NONE;
+ c->base.transparentGreen = GLX_NONE;
+ c->base.transparentBlue = GLX_NONE;
+ c->base.transparentAlpha = GLX_NONE;
+ c->base.transparentIndex = GLX_NONE;
+
+ /* ARB_multisample / SGIS_multisample */
+ c->base.sampleBuffers = 0;
+ c->base.samples = 0;
+
+ /* SGIX_fbconfig / GLX 1.3 */
+ c->base.drawableType = (((pfd.dwFlags & PFD_DRAW_TO_WINDOW) ? GLX_WINDOW_BIT : 0)
+ | ((pfd.dwFlags & PFD_DRAW_TO_BITMAP) ? GLX_PIXMAP_BIT : 0));
+
+ if (pfd.iPixelType == PFD_TYPE_COLORINDEX)
+ {
+ c->base.renderType = GLX_RGBA_BIT | GLX_COLOR_INDEX_BIT;
+ }
+ else
+ {
+ c->base.renderType = GLX_RGBA_BIT;
+ }
+
+ c->base.xRenderable = GL_TRUE;
+ c->base.fbconfigID = -1; // will be set by __glXScreenInit()
+
+ /* SGIX_pbuffer / GLX 1.3 */
+ // XXX: How can we find these values out ???
+ c->base.maxPbufferWidth = -1;
+ c->base.maxPbufferHeight = -1;
+ c->base.maxPbufferPixels = -1;
+ c->base.optimalPbufferWidth = 0; // there is no optimal value
+ c->base.optimalPbufferHeight = 0;
+
+ /* SGIX_visual_select_group */
+ // arrange for visuals with the best acceleration to be preferred in selection
+ switch (pfd.dwFlags & (PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED))
+ {
+ case 0:
+ c->base.visualSelectGroup = 2;
+ break;
+
+ case PFD_GENERIC_ACCELERATED:
+ c->base.visualSelectGroup = 1;
+ break;
+
+ case PFD_GENERIC_FORMAT:
+ c->base.visualSelectGroup = 0;
+ break;
+
+ default:
+ ;
+ // "can't happen"
+ }
+
+ /* OML_swap_method */
+ if (pfd.dwFlags & PFD_SWAP_EXCHANGE)
+ c->base.swapMethod = GLX_SWAP_EXCHANGE_OML;
+ else if (pfd.dwFlags & PFD_SWAP_COPY)
+ c->base.swapMethod = GLX_SWAP_COPY_OML;
+ else
+ c->base.swapMethod = GLX_SWAP_UNDEFINED_OML;
+
+ /* EXT_import_context */
+ c->base.screen = screen->base.pScreen->myNum;
+
+ /* EXT_texture_from_pixmap */
+ c->base.bindToTextureRgb = -1;
+ c->base.bindToTextureRgba = -1;
+ c->base.bindToMipmapTexture = -1;
+ c->base.bindToTextureTargets = -1;
+ c->base.yInverted = -1;
+
+ n++;
+
+ // update previous config to point to this config
+ if (prev)
+ prev->base.next = &(c->base);
+
+ prev = c;
+ }
+
+ GLWIN_DEBUG_MSG("found %d pixelFormats suitable for conversion to fbConfigs", n);
+
+ screen->base.numFBConfigs = n;
+ screen->base.fbconfigs = &(result->base);
+}
+
+// helper function to access an attribute value from an attribute value array by attribute
+static
+int getAttrValue(const int attrs[], int values[], unsigned int num, int attr, int fallback)
+{
+ unsigned int i;
+ for (i = 0; i < num; i++)
+ {
+ if (attrs[i] == attr)
+ {
+ GLWIN_TRACE_MSG("getAttrValue attr 0x%x, value %d", attr, values[i]);
+ return values[i];
+ }
+ }
+
+ ErrorF("getAttrValue failed to find attr 0x%x, using default value %d\n", attr, fallback);
+ return fallback;
+}
+
+//
+// Create the GLXconfigs using wglGetPixelFormatAttribfvARB() extension
+//
+static void
+glxWinCreateConfigsExt(HDC hdc, glxWinScreen *screen)
+{
+ GLXWinConfig *c, *result, *prev = NULL;
+ int i = 0;
+ int n = 0;
+
+ const int attr = WGL_NUMBER_PIXEL_FORMATS_ARB;
+ int numConfigs;
+
+ int attrs[50];
+ unsigned int num_attrs = 0;
+
+ GLWIN_DEBUG_MSG("glxWinCreateConfigsExt");
+
+ screen->base.numFBConfigs = 0;
+ screen->base.fbconfigs = NULL;
+
+ if (!wglGetPixelFormatAttribivARBWrapper(hdc, 0, 0, 1, &attr, &numConfigs))
+ {
+ ErrorF("wglGetPixelFormatAttribivARB failed for WGL_NUMBER_PIXEL_FORMATS_ARB: %s\n", glxWinErrorMessage());
+ return;
+ }
+
+ GLWIN_DEBUG_MSG("wglGetPixelFormatAttribivARB says %d possible pixel formats", numConfigs);
+
+ /* alloc */
+ result = malloc(sizeof(GLXWinConfig) * numConfigs);
+
+ if (NULL == result)
+ {
+ return;
+ }
+
+ memset(result, 0, sizeof(GLXWinConfig) * numConfigs);
+ n = 0;
+
+#define ADD_ATTR(a) { attrs[num_attrs++] = a; assert(num_attrs < NUM_ELEMENTS(attrs)); }
+
+ ADD_ATTR(WGL_DRAW_TO_WINDOW_ARB);
+ ADD_ATTR(WGL_DRAW_TO_BITMAP_ARB);
+ ADD_ATTR(WGL_ACCELERATION_ARB);
+ ADD_ATTR(WGL_SWAP_LAYER_BUFFERS_ARB);
+ ADD_ATTR(WGL_NUMBER_OVERLAYS_ARB);
+ ADD_ATTR(WGL_NUMBER_UNDERLAYS_ARB);
+ ADD_ATTR(WGL_TRANSPARENT_ARB);
+ ADD_ATTR(WGL_TRANSPARENT_RED_VALUE_ARB);
+ ADD_ATTR(WGL_TRANSPARENT_GREEN_VALUE_ARB);
+ ADD_ATTR(WGL_TRANSPARENT_GREEN_VALUE_ARB);
+ ADD_ATTR(WGL_TRANSPARENT_ALPHA_VALUE_ARB);
+ ADD_ATTR(WGL_SUPPORT_OPENGL_ARB);
+ ADD_ATTR(WGL_DOUBLE_BUFFER_ARB);
+ ADD_ATTR(WGL_STEREO_ARB);
+ ADD_ATTR(WGL_PIXEL_TYPE_ARB);
+ ADD_ATTR(WGL_COLOR_BITS_ARB);
+ ADD_ATTR(WGL_RED_BITS_ARB);
+ ADD_ATTR(WGL_RED_SHIFT_ARB);
+ ADD_ATTR(WGL_GREEN_BITS_ARB);
+ ADD_ATTR(WGL_GREEN_SHIFT_ARB);
+ ADD_ATTR(WGL_BLUE_BITS_ARB);
+ ADD_ATTR(WGL_BLUE_SHIFT_ARB);
+ ADD_ATTR(WGL_ALPHA_BITS_ARB);
+ ADD_ATTR(WGL_ALPHA_SHIFT_ARB);
+ ADD_ATTR(WGL_ACCUM_RED_BITS_ARB);
+ ADD_ATTR(WGL_ACCUM_GREEN_BITS_ARB);
+ ADD_ATTR(WGL_ACCUM_BLUE_BITS_ARB);
+ ADD_ATTR(WGL_ACCUM_ALPHA_BITS_ARB);
+ ADD_ATTR(WGL_DEPTH_BITS_ARB);
+ ADD_ATTR(WGL_STENCIL_BITS_ARB);
+ ADD_ATTR(WGL_AUX_BUFFERS_ARB);
+ ADD_ATTR(WGL_SWAP_METHOD_ARB);
+
+ if (screen->has_WGL_ARB_multisample)
+ {
+ // we may not query these attrs if WGL_ARB_multisample is not offered
+ ADD_ATTR(WGL_SAMPLE_BUFFERS_ARB);
+ ADD_ATTR(WGL_SAMPLES_ARB);
+ }
+
+ if (screen->has_WGL_ARB_render_texture)
+ {
+ // we may not query these attrs if WGL_ARB_render_texture is not offered
+ ADD_ATTR(WGL_BIND_TO_TEXTURE_RGB_ARB);
+ ADD_ATTR(WGL_BIND_TO_TEXTURE_RGBA_ARB);
+ }
+
+ if (screen->has_WGL_ARB_pbuffer)
+ {
+ // we may not query these attrs if WGL_ARB_pbuffer is not offered
+ ADD_ATTR(WGL_DRAW_TO_PBUFFER_ARB);
+ ADD_ATTR(WGL_MAX_PBUFFER_PIXELS_ARB);
+ ADD_ATTR(WGL_MAX_PBUFFER_WIDTH_ARB);
+ ADD_ATTR(WGL_MAX_PBUFFER_HEIGHT_ARB);
+ }
+
+ /* fill in configs */
+ for (i = 0; i < numConfigs; i++)
+ {
+ int sizevalues=num_attrs*sizeof(int);
+ int *values=(int*)_alloca(sizevalues);
+
+ memset(values,0,sizevalues);
+
+ c = &(result[i]);
+ c->base.next = NULL;
+ c->pixelFormatIndex = i+1;
+
+ if (!wglGetPixelFormatAttribivARBWrapper(hdc, i+1, 0, num_attrs, attrs, values))
+ {
+ ErrorF("wglGetPixelFormatAttribivARB failed for index %d, error %s\n", i+1, glxWinErrorMessage());
+ break;
+ }
+
+#define ATTR_VALUE(a, d) getAttrValue(attrs, values, num_attrs, (a), (d))
+
+ if (!ATTR_VALUE(WGL_SUPPORT_OPENGL_ARB, 0))
+ {
+ GLWIN_DEBUG_MSG("pixelFormat %d isn't WGL_SUPPORT_OPENGL_ARB, skipping", i+1);
+ continue;
+ }
+
+ c->base.doubleBufferMode = ATTR_VALUE(WGL_DOUBLE_BUFFER_ARB, 0) ? GL_TRUE : GL_FALSE;
+ c->base.stereoMode = ATTR_VALUE(WGL_STEREO_ARB, 0) ? GL_TRUE : GL_FALSE;
+
+ c->base.redBits = ATTR_VALUE(WGL_RED_BITS_ARB, 0);
+ c->base.greenBits = ATTR_VALUE(WGL_GREEN_BITS_ARB, 0);
+ c->base.blueBits = ATTR_VALUE(WGL_BLUE_BITS_ARB, 0);
+ c->base.alphaBits = ATTR_VALUE(WGL_ALPHA_BITS_ARB, 0);
+
+ c->base.redMask = BITS_AND_SHIFT_TO_MASK(c->base.redBits, ATTR_VALUE(WGL_RED_SHIFT_ARB, 0));
+ c->base.greenMask = BITS_AND_SHIFT_TO_MASK(c->base.greenBits, ATTR_VALUE(WGL_GREEN_SHIFT_ARB, 0));
+ c->base.blueMask = BITS_AND_SHIFT_TO_MASK(c->base.blueBits, ATTR_VALUE(WGL_BLUE_SHIFT_ARB, 0));
+ c->base.alphaMask = BITS_AND_SHIFT_TO_MASK(c->base.alphaBits, ATTR_VALUE(WGL_ALPHA_SHIFT_ARB, 0));
+
+ switch (ATTR_VALUE(WGL_PIXEL_TYPE_ARB, 0))
+ {
+ case WGL_TYPE_COLORINDEX_ARB:
+ c->base.indexBits = ATTR_VALUE(WGL_COLOR_BITS_ARB, 0);
+ c->base.rgbBits = 0;
+ c->base.visualType = GLX_STATIC_COLOR;
+ break;
+
+ case WGL_TYPE_RGBA_FLOAT_ARB:
+ GLWIN_DEBUG_MSG("pixelFormat %d is WGL_TYPE_RGBA_FLOAT_ARB, skipping", i+1);
+ continue;
+
+ case WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT:
+ GLWIN_DEBUG_MSG("pixelFormat %d is WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT, skipping", i+1);
+ continue;
+
+ case WGL_TYPE_RGBA_ARB:
+ c->base.indexBits = 0;
+ c->base.rgbBits = ATTR_VALUE(WGL_COLOR_BITS_ARB, 0);
+ c->base.visualType = GLX_TRUE_COLOR;
+ break;
+
+ default:
+ ErrorF("wglGetPixelFormatAttribivARB returned unknown value 0x%x for WGL_PIXEL_TYPE_ARB\n", ATTR_VALUE(WGL_PIXEL_TYPE_ARB, 0));
+ continue;
+ }
+
+ c->base.accumRedBits = ATTR_VALUE(WGL_ACCUM_RED_BITS_ARB, 0);
+ c->base.accumGreenBits = ATTR_VALUE(WGL_ACCUM_GREEN_BITS_ARB, 0);
+ c->base.accumBlueBits = ATTR_VALUE(WGL_ACCUM_BLUE_BITS_ARB, 0);
+ c->base.accumAlphaBits = ATTR_VALUE(WGL_ACCUM_ALPHA_BITS_ARB, 0);
+
+ c->base.depthBits = ATTR_VALUE(WGL_DEPTH_BITS_ARB, 0);
+ c->base.stencilBits = ATTR_VALUE(WGL_STENCIL_BITS_ARB, 0);
+ c->base.numAuxBuffers = ATTR_VALUE(WGL_AUX_BUFFERS_ARB, 0);
+
+ {
+ int layers = ATTR_VALUE(WGL_NUMBER_OVERLAYS_ARB,0) + ATTR_VALUE(WGL_NUMBER_UNDERLAYS_ARB, 0);
+
+ if (layers > 0)
+ {
+ ErrorF("pixelFormat %d: has %d overlay, %d underlays which aren't currently handled", i, ATTR_VALUE(WGL_NUMBER_OVERLAYS_ARB,0), ATTR_VALUE(WGL_NUMBER_UNDERLAYS_ARB, 0));
+ // XXX: need to iterate over layers?
+ }
+ }
+ c->base.level = 0;
+
+ c->base.pixmapMode = 0; // ???
+ c->base.visualID = -1; // will be set by __glXScreenInit()
+
+ /* EXT_visual_rating / GLX 1.2 */
+ switch (ATTR_VALUE(WGL_ACCELERATION_ARB, 0))
+ {
+ default:
+ ErrorF("wglGetPixelFormatAttribivARB returned unknown value 0x%x for WGL_ACCELERATION_ARB\n", ATTR_VALUE(WGL_ACCELERATION_ARB, 0));
+
+ case WGL_NO_ACCELERATION_ARB:
+ c->base.visualRating = GLX_SLOW_VISUAL_EXT;
+ break;
+
+ case WGL_GENERIC_ACCELERATION_ARB:
+ case WGL_FULL_ACCELERATION_ARB:
+ c->base.visualRating = GLX_NONE_EXT;
+ break;
+ }
+
+ /* EXT_visual_info / GLX 1.2 */
+ // c->base.visualType is set above
+ if (ATTR_VALUE(WGL_TRANSPARENT_ARB, 0))
+ {
+ c->base.transparentPixel = (c->base.visualType == GLX_TRUE_COLOR) ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT;
+ c->base.transparentRed = ATTR_VALUE(WGL_TRANSPARENT_RED_VALUE_ARB, 0);
+ c->base.transparentGreen = ATTR_VALUE(WGL_TRANSPARENT_GREEN_VALUE_ARB, 0);
+ c->base.transparentBlue = ATTR_VALUE(WGL_TRANSPARENT_BLUE_VALUE_ARB, 0);
+ c->base.transparentAlpha = ATTR_VALUE(WGL_TRANSPARENT_ALPHA_VALUE_ARB, 0);
+ c->base.transparentIndex = ATTR_VALUE(WGL_TRANSPARENT_INDEX_VALUE_ARB, 0);
+ }
+ else
+ {
+ c->base.transparentPixel = GLX_NONE_EXT;
+ c->base.transparentRed = GLX_NONE;
+ c->base.transparentGreen = GLX_NONE;
+ c->base.transparentBlue = GLX_NONE;
+ c->base.transparentAlpha = GLX_NONE;
+ c->base.transparentIndex = GLX_NONE;
+ }
+
+ /* ARB_multisample / SGIS_multisample */
+ if (screen->has_WGL_ARB_multisample)
+ {
+ c->base.sampleBuffers = ATTR_VALUE(WGL_SAMPLE_BUFFERS_ARB, 0);
+ c->base.samples = ATTR_VALUE(WGL_SAMPLES_ARB, 0);
+ }
+ else
+ {
+ c->base.sampleBuffers = 0;
+ c->base.samples = 0;
+ }
+
+ /* SGIX_fbconfig / GLX 1.3 */
+ c->base.drawableType = ((ATTR_VALUE(WGL_DRAW_TO_WINDOW_ARB, 0) ? GLX_WINDOW_BIT : 0)
+ | (ATTR_VALUE(WGL_DRAW_TO_BITMAP_ARB, 0) ? GLX_PIXMAP_BIT : 0)
+ | (ATTR_VALUE(WGL_DRAW_TO_PBUFFER_ARB, 0) ? GLX_PBUFFER_BIT : 0));
+
+ /*
+ Assume OpenGL RGBA rendering is available on all visuals
+ (it is specified to render to red component in single-channel visuals,
+ if supported, but there doesn't seem to be any mechanism to check if it
+ is supported)
+
+ Color index rendering is only supported on single-channel visuals
+ */
+ if (c->base.visualType == GLX_STATIC_COLOR)
+ {
+ c->base.renderType = GLX_RGBA_BIT | GLX_COLOR_INDEX_BIT;
+ }
+ else
+ {
+ c->base.renderType = GLX_RGBA_BIT;
+ }
+
+ c->base.xRenderable = GL_TRUE;
+ c->base.fbconfigID = -1; // will be set by __glXScreenInit()
+
+ /* SGIX_pbuffer / GLX 1.3 */
+ if (screen->has_WGL_ARB_pbuffer)
+ {
+ c->base.maxPbufferWidth = ATTR_VALUE(WGL_MAX_PBUFFER_WIDTH_ARB, -1);
+ c->base.maxPbufferHeight = ATTR_VALUE(WGL_MAX_PBUFFER_HEIGHT_ARB, -1);
+ c->base.maxPbufferPixels = ATTR_VALUE(WGL_MAX_PBUFFER_PIXELS_ARB, -1);
+ }
+ else
+ {
+ c->base.maxPbufferWidth = -1;
+ c->base.maxPbufferHeight = -1;
+ c->base.maxPbufferPixels = -1;
+ }
+ c->base.optimalPbufferWidth = 0; // there is no optimal value
+ c->base.optimalPbufferHeight = 0;
+
+ /* SGIX_visual_select_group */
+ // arrange for visuals with the best acceleration to be preferred in selection
+ switch (ATTR_VALUE(WGL_ACCELERATION_ARB, 0))
+ {
+ case WGL_FULL_ACCELERATION_ARB:
+ c->base.visualSelectGroup = 2;
+ break;
+
+ case WGL_GENERIC_ACCELERATION_ARB:
+ c->base.visualSelectGroup = 1;
+ break;
+
+ default:
+ case WGL_NO_ACCELERATION_ARB:
+ c->base.visualSelectGroup = 0;
+ break;
+ }
+
+ /* OML_swap_method */
+ switch (ATTR_VALUE(WGL_SWAP_METHOD_ARB, 0))
+ {
+ case WGL_SWAP_EXCHANGE_ARB:
+ c->base.swapMethod = GLX_SWAP_EXCHANGE_OML;
+ break;
+
+ case WGL_SWAP_COPY_ARB:
+ c->base.swapMethod = GLX_SWAP_COPY_OML;
+ break;
+
+ default:
+ ErrorF("wglGetPixelFormatAttribivARB returned unknown value 0x%x for WGL_SWAP_METHOD_ARB\n", ATTR_VALUE(WGL_SWAP_METHOD_ARB, 0));
+
+ case WGL_SWAP_UNDEFINED_ARB:
+ c->base.swapMethod = GLX_SWAP_UNDEFINED_OML;
+ }
+
+ /* EXT_import_context */
+ c->base.screen = screen->base.pScreen->myNum;
+
+ /* EXT_texture_from_pixmap */
+ /*
+ Mesa's DRI configs always have bindToTextureRgb/Rgba TRUE (see driCreateConfigs(), so setting
+ bindToTextureRgb/bindToTextureRgba to FALSE means that swrast can't find any fbConfigs to use,
+ so setting these to 0, even if we know bindToTexture isn't available, isn't a good idea...
+ */
+ if (screen->has_WGL_ARB_render_texture)
+ {
+ c->base.bindToTextureRgb = ATTR_VALUE(WGL_BIND_TO_TEXTURE_RGB_ARB, -1);
+ c->base.bindToTextureRgba = ATTR_VALUE(WGL_BIND_TO_TEXTURE_RGBA_ARB, -1);
+ }
+ else
+ {
+ c->base.bindToTextureRgb = -1;
+ c->base.bindToTextureRgba = -1;
+ }
+ c->base.bindToMipmapTexture = -1;
+ c->base.bindToTextureTargets = GLX_TEXTURE_1D_BIT_EXT | GLX_TEXTURE_2D_BIT_EXT | GLX_TEXTURE_RECTANGLE_BIT_EXT;
+ c->base.yInverted = -1;
+
+ n++;
+
+ // update previous config to point to this config
+ if (prev)
+ prev->base.next = &(c->base);
+
+ prev = c;
+ }
+
+ screen->base.numFBConfigs = n;
+ screen->base.fbconfigs = &(result->base);
+}
diff --git a/xorg-server/hw/xwin/win.h b/xorg-server/hw/xwin/win.h
index bb069afce..d0a41f9ea 100644
--- a/xorg-server/hw/xwin/win.h
+++ b/xorg-server/hw/xwin/win.h
@@ -1,1442 +1,1442 @@
-/*
- *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: Dakshinamurthy Karra
- * Suhaib M Siddiqi
- * Peter Busch
- * Harold L Hunt II
- * Kensuke Matsuzaki
- */
-
-#ifndef _WIN_H_
-#define _WIN_H_
-
-#ifndef NO
-#define NO 0
-#endif
-#ifndef YES
-#define YES 1
-#endif
-
-/* WM_XBUTTON Messages. They should go into w32api. */
-#ifndef WM_XBUTTONDOWN
-# define WM_XBUTTONDOWN 523
-#endif
-#ifndef WM_XBUTTONUP
-# define WM_XBUTTONUP 524
-#endif
-#ifndef WM_XBUTTONDBLCLK
-# define WM_XBUTTONDBLCLK 525
-#endif
-
-
-#define WIN_DEFAULT_BPP 0
-#define WIN_DEFAULT_WHITEPIXEL 255
-#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_REFRESH 0
-#define WIN_DEFAULT_WIN_KILL TRUE
-#define WIN_DEFAULT_UNIX_KILL FALSE
-#define WIN_DEFAULT_CLIP_UPDATES_NBOXES 0
-#ifdef XWIN_EMULATEPSEUDO
-#define WIN_DEFAULT_EMULATE_PSEUDO FALSE
-#endif
-#define WIN_DEFAULT_USER_GAVE_HEIGHT_AND_WIDTH FALSE
-
-#define WIN_DIB_MAXIMUM_SIZE 0x08000000 /* 16 MB on Windows 95, 98, Me */
-#define WIN_DIB_MAXIMUM_SIZE_MB (WIN_DIB_MAXIMUM_SIZE / 8 / 1024 / 1024)
-
-/*
- * Windows only supports 256 color palettes
- */
-#define WIN_NUM_PALETTE_ENTRIES 256
-
-/*
- * Number of times to call Restore in an attempt to restore the primary surface
- */
-#define WIN_REGAIN_SURFACE_RETRIES 1
-
-/*
- * Build a supported display depths mask by shifting one to the left
- * by the number of bits in the supported depth.
- */
-#define WIN_SUPPORTED_BPPS ( (1 << (32 - 1)) | (1 << (24 - 1)) \
- | (1 << (16 - 1)) | (1 << (15 - 1)) \
- | (1 << ( 8 - 1)))
-#define WIN_CHECK_DEPTH YES
-
-/*
- * Timer IDs for WM_TIMER
- */
-#define WIN_E3B_TIMER_ID 1
-#define WIN_POLLING_MOUSE_TIMER_ID 2
-
-#define MOUSE_POLLING_INTERVAL 50
-
-#define WIN_E3B_OFF -1
-#define WIN_FD_INVALID -1
-
-#define WIN_SERVER_NONE 0x0L /* 0 */
-#define WIN_SERVER_SHADOW_GDI 0x1L /* 1 */
-#define WIN_SERVER_SHADOW_DD 0x2L /* 2 */
-#define WIN_SERVER_SHADOW_DDNL 0x4L /* 4 */
-#ifdef XWIN_PRIMARYFB
-#define WIN_SERVER_PRIMARY_DD 0x8L /* 8 */
-#endif
-#ifdef XWIN_NATIVEGDI
-# define WIN_SERVER_NATIVE_GDI 0x10L /* 16 */
-#endif
-
-#define AltMapIndex Mod1MapIndex
-#define NumLockMapIndex Mod2MapIndex
-#define AltLangMapIndex Mod3MapIndex
-#define KanaMapIndex Mod4MapIndex
-#define ScrollLockMapIndex Mod5MapIndex
-
-#define WIN_MOD_LALT 0x00000001
-#define WIN_MOD_RALT 0x00000002
-#define WIN_MOD_LCONTROL 0x00000004
-#define WIN_MOD_RCONTROL 0x00000008
-
-#define WIN_24BPP_MASK_RED 0x00FF0000
-#define WIN_24BPP_MASK_GREEN 0x0000FF00
-#define WIN_24BPP_MASK_BLUE 0x000000FF
-
-#define WIN_MAX_KEYS_PER_KEY 4
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <stdio.h>
-
-#include <errno.h>
-#if defined(XWIN_MULTIWINDOWEXTWM) || defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
-#define HANDLE void *
-#ifdef _MSC_VER
-typedef int pid_t;
-#endif
-#include <pthread.h>
-#undef HANDLE
-#endif
-
-#ifdef HAS_MMAP
-#include <sys/mman.h>
-#ifndef MAP_FILE
-#define MAP_FILE 0
-#endif /* MAP_FILE */
-#endif /* HAS_MMAP */
-
-#include <X11/X.h>
-#include <X11/Xproto.h>
-#include <X11/Xos.h>
-#include <X11/Xprotostr.h>
-#include "scrnintstr.h"
-#include "pixmapstr.h"
-#include "pixmap.h"
-#include "region.h"
-#include "gcstruct.h"
-#include "colormap.h"
-#include "colormapst.h"
-#include "miscstruct.h"
-#include "servermd.h"
-#include "windowstr.h"
-#include "mi.h"
-#include "micmap.h"
-#include "mifillarc.h"
-#include "mifpoly.h"
-#include "mibstore.h"
-#include "input.h"
-#include "mipointer.h"
-#include "X11/keysym.h"
-#include "mibstore.h"
-#include "micoord.h"
-#include "dix.h"
-#include "miline.h"
-#include "shadow.h"
-#include "fb.h"
-#include "rootless.h"
-
-#include "mipict.h"
-#include "picturestr.h"
-
-#ifdef RANDR
-#include "randrstr.h"
-#endif
-
-/*
- * Windows headers
- */
-#include "winms.h"
-#include "winresource.h"
-
-
-/*
- * Define Windows constants
- */
-
-#define WM_TRAYICON (WM_USER + 1000)
-#define WM_INIT_SYS_MENU (WM_USER + 1001)
-#define WM_GIVEUP (WM_USER + 1002)
-
-
-/* Local includes */
-#include "winwindow.h"
-#include "winmsg.h"
-
-#define PROFILEPOINT(point,thresh)\
-{\
-static unsigned int PROFPT##point = 0;\
-if (++PROFPT##point % thresh == 0)\
-ErrorF (#point ": PROFILEPOINT hit %u times\n", PROFPT##point);\
-}
-
-
-/* We use xor this macro for detecting toggle key state changes */
-#define WIN_XOR(a,b) ((!(a) && (b)) || ((a) && !(b)))
-
-#define DEFINE_ATOM_HELPER(func,atom_name) \
-static Atom func (void) { \
- static int generation; \
- static Atom atom; \
- if (generation != serverGeneration) { \
- generation = serverGeneration; \
- atom = MakeAtom (atom_name, strlen (atom_name), TRUE); \
- } \
- return atom; \
-}
-
-/*
- * Typedefs for engine dependent function pointers
- */
-
-typedef Bool (*winAllocateFBProcPtr)(ScreenPtr);
-
-typedef void (*winShadowUpdateProcPtr)(ScreenPtr, shadowBufPtr);
-
-typedef Bool (*winCloseScreenProcPtr)(int, ScreenPtr);
-
-typedef Bool (*winInitVisualsProcPtr)(ScreenPtr);
-
-typedef Bool (*winAdjustVideoModeProcPtr)(ScreenPtr);
-
-typedef Bool (*winCreateBoundingWindowProcPtr)(ScreenPtr);
-
-typedef Bool (*winFinishScreenInitProcPtr)(int, ScreenPtr, int, char **);
-
-typedef Bool (*winBltExposedRegionsProcPtr)(ScreenPtr);
-
-typedef Bool (*winActivateAppProcPtr)(ScreenPtr);
-
-typedef Bool (*winRedrawScreenProcPtr)(ScreenPtr pScreen);
-
-typedef Bool (*winRealizeInstalledPaletteProcPtr)(ScreenPtr pScreen);
-
-typedef Bool (*winInstallColormapProcPtr)(ColormapPtr pColormap);
-
-typedef Bool (*winStoreColorsProcPtr)(ColormapPtr pmap,
- int ndef, xColorItem *pdefs);
-
-typedef Bool (*winCreateColormapProcPtr)(ColormapPtr pColormap);
-
-typedef Bool (*winDestroyColormapProcPtr)(ColormapPtr pColormap);
-
-typedef Bool (*winHotKeyAltTabProcPtr)(ScreenPtr);
-
-typedef Bool (*winCreatePrimarySurfaceProcPtr)(ScreenPtr);
-
-typedef Bool (*winReleasePrimarySurfaceProcPtr)(ScreenPtr);
-
-typedef Bool (*winFinishCreateWindowsWindowProcPtr)(WindowPtr pWin);
-
-typedef Bool (*winCreateScreenResourcesProc)(ScreenPtr);
-
-/* Typedef for DIX wrapper functions */
-typedef int (*winDispatchProcPtr) (ClientPtr);
-
-
-/*
- * GC (graphics context) privates
- */
-
-typedef struct
-{
- HDC hdc;
- HDC hdcMem;
-} winPrivGCRec, *winPrivGCPtr;
-
-
-/*
- * Pixmap privates
- */
-
-typedef struct
-{
- HDC hdcSelected;
- HBITMAP hBitmap;
- BYTE *pbBits;
- DWORD dwScanlineBytes;
- BITMAPINFOHEADER *pbmih;
-} winPrivPixmapRec, *winPrivPixmapPtr;
-
-
-/*
- * Colormap privates
- */
-
-typedef struct
-{
- HPALETTE hPalette;
- LPDIRECTDRAWPALETTE lpDDPalette;
- RGBQUAD rgbColors[WIN_NUM_PALETTE_ENTRIES];
- PALETTEENTRY peColors[WIN_NUM_PALETTE_ENTRIES];
-} winPrivCmapRec, *winPrivCmapPtr;
-
-/*
- * Windows Cursor handling.
- */
-
-typedef struct {
- /* from GetSystemMetrics */
- int sm_cx;
- int sm_cy;
-
- BOOL visible;
- HCURSOR handle;
- QueryBestSizeProcPtr QueryBestSize;
- miPointerSpriteFuncPtr spriteFuncs;
-} winCursorRec;
-
-/*
- * Screen information structure that we need before privates are available
- * in the server startup sequence.
- */
-
-typedef struct
-{
- ScreenPtr pScreen;
-
- /* Did the user specify a height and width? */
- Bool fUserGaveHeightAndWidth;
-
- DWORD dwScreen;
- DWORD dwUserWidth;
- DWORD dwUserHeight;
- DWORD dwWidth;
- DWORD dwHeight;
- DWORD dwWidth_mm;
- DWORD dwHeight_mm;
- DWORD dwPaddedWidth;
-
- /* Did the user specify a screen position? */
- Bool fUserGavePosition;
- DWORD dwInitialX;
- DWORD dwInitialY;
-
- /*
- * dwStride is the number of whole pixels that occupy a scanline,
- * including those pixels that are not displayed. This is basically
- * a rounding up of the width.
- */
- DWORD dwStride;
-
- /* Offset of the screen in the window when using scrollbars */
- DWORD dwXOffset;
- DWORD dwYOffset;
-
- DWORD dwBPP;
- DWORD dwDepth;
- DWORD dwRefreshRate;
- char *pfb;
- DWORD dwEngine;
- DWORD dwEnginePreferred;
- DWORD dwClipUpdatesNBoxes;
-#ifdef XWIN_EMULATEPSEUDO
- Bool fEmulatePseudo;
-#endif
- Bool fFullScreen;
- Bool fDecoration;
-#ifdef XWIN_MULTIWINDOWEXTWM
- Bool fMWExtWM;
- Bool fInternalWM;
- Bool fAnotherWMRunning;
-#endif
- Bool fRootless;
-#ifdef XWIN_MULTIWINDOW
- Bool fMultiWindow;
-#endif
-#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
- Bool fMultiMonitorOverride;
-#endif
- Bool fMultipleMonitors;
- Bool fLessPointer;
- Bool fScrollbars;
- Bool fNoTrayIcon;
- int iE3BTimeout;
- /* Windows (Alt+F4) and Unix (Ctrl+Alt+Backspace) Killkey */
- Bool fUseWinKillKey;
- Bool fUseUnixKillKey;
- Bool fIgnoreInput;
-
- /* Did the user explicitly set this screen? */
- Bool fExplicitScreen;
-} winScreenInfo, *winScreenInfoPtr;
-
-
-/*
- * Screen privates
- */
-
-typedef struct _winPrivScreenRec
-{
- winScreenInfoPtr pScreenInfo;
-
- Bool fEnabled;
- Bool fClosed;
- Bool fActive;
- Bool fBadDepth;
-
- int iDeltaZ;
-
- int iConnectedClients;
-
- CloseScreenProcPtr CloseScreen;
-
- DWORD dwRedMask;
- DWORD dwGreenMask;
- DWORD dwBlueMask;
- DWORD dwBitsPerRGB;
-
- DWORD dwModeKeyStates;
-
- /* Handle to icons that must be freed */
- HICON hiconNotifyIcon;
-
- /* Last width, height, and depth of the Windows display */
- DWORD dwLastWindowsWidth;
- DWORD dwLastWindowsHeight;
- DWORD dwLastWindowsBitsPixel;
-
- /* Palette management */
- ColormapPtr pcmapInstalled;
-
- /* Pointer to the root visual so we only have to look it up once */
- VisualPtr pRootVisual;
-
- /* 3 button emulation variables */
- int iE3BCachedPress;
- Bool fE3BFakeButton2Sent;
-
- /* Privates used by shadow fb GDI server */
- HBITMAP hbmpShadow;
- HDC hdcScreen;
- HDC hdcShadow;
- HWND hwndScreen;
-
- /* Privates used by shadow fb and primary fb DirectDraw servers */
- LPDIRECTDRAW pdd;
- LPDIRECTDRAWSURFACE pddsPrimary;
- LPDIRECTDRAW2 pdd2;
-
- /* Privates used by shadow fb DirectDraw server */
- LPDIRECTDRAWSURFACE pddsShadow;
- LPDDSURFACEDESC pddsdShadow;
-
-#ifdef XWIN_PRIMARYFB
- /* Privates used by primary fb DirectDraw server */
- LPDIRECTDRAWSURFACE pddsOffscreen;
- LPDDSURFACEDESC pddsdOffscreen;
- LPDDSURFACEDESC pddsdPrimary;
-#endif
-
- /* Privates used by shadow fb DirectDraw Nonlocking server */
- LPDIRECTDRAW4 pdd4;
- LPDIRECTDRAWSURFACE4 pddsShadow4;
- LPDIRECTDRAWSURFACE4 pddsPrimary4;
- BOOL fRetryCreateSurface;
-
- /* Privates used by both shadow fb DirectDraw servers */
- LPDIRECTDRAWCLIPPER pddcPrimary;
-
-#ifdef XWIN_MULTIWINDOWEXTWM
- /* Privates used by multi-window external window manager */
- RootlessFrameID widTop;
- Bool fRestacking;
-#endif
-
-#ifdef XWIN_MULTIWINDOW
- /* Privates used by multi-window */
- pthread_t ptWMProc;
- pthread_t ptXMsgProc;
- void *pWMInfo;
-#endif
-
-#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
- /* Privates used by both multi-window and rootless */
- Bool fRootWindowShown;
-#endif
-
-#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
- /* Privates used for any module running in a seperate thread */
- pthread_mutex_t pmServerStarted;
- Bool fServerStarted;
-#endif
-
- /* Engine specific functions */
- winAllocateFBProcPtr pwinAllocateFB;
- winShadowUpdateProcPtr pwinShadowUpdate;
- winCloseScreenProcPtr pwinCloseScreen;
- winInitVisualsProcPtr pwinInitVisuals;
- winAdjustVideoModeProcPtr pwinAdjustVideoMode;
- winCreateBoundingWindowProcPtr pwinCreateBoundingWindow;
- winFinishScreenInitProcPtr pwinFinishScreenInit;
- winBltExposedRegionsProcPtr pwinBltExposedRegions;
- winActivateAppProcPtr pwinActivateApp;
- winRedrawScreenProcPtr pwinRedrawScreen;
- winRealizeInstalledPaletteProcPtr pwinRealizeInstalledPalette;
- winInstallColormapProcPtr pwinInstallColormap;
- winStoreColorsProcPtr pwinStoreColors;
- winCreateColormapProcPtr pwinCreateColormap;
- winDestroyColormapProcPtr pwinDestroyColormap;
- winHotKeyAltTabProcPtr pwinHotKeyAltTab;
- winCreatePrimarySurfaceProcPtr pwinCreatePrimarySurface;
- winReleasePrimarySurfaceProcPtr pwinReleasePrimarySurface;
-
- winCreateScreenResourcesProc pwinCreateScreenResources;
-
-#ifdef XWIN_MULTIWINDOW
- /* Window Procedures for MultiWindow mode */
- winFinishCreateWindowsWindowProcPtr pwinFinishCreateWindowsWindow;
-#endif
-
- /* Window Procedures for Rootless mode */
- CreateWindowProcPtr CreateWindow;
- DestroyWindowProcPtr DestroyWindow;
- PositionWindowProcPtr PositionWindow;
- ChangeWindowAttributesProcPtr ChangeWindowAttributes;
- RealizeWindowProcPtr RealizeWindow;
- UnrealizeWindowProcPtr UnrealizeWindow;
- ValidateTreeProcPtr ValidateTree;
- PostValidateTreeProcPtr PostValidateTree;
- WindowExposuresProcPtr WindowExposures;
- CopyWindowProcPtr CopyWindow;
- ClearToBackgroundProcPtr ClearToBackground;
- ClipNotifyProcPtr ClipNotify;
- RestackWindowProcPtr RestackWindow;
- ReparentWindowProcPtr ReparentWindow;
- ResizeWindowProcPtr ResizeWindow;
- MoveWindowProcPtr MoveWindow;
- SetShapeProcPtr SetShape;
-
-#ifdef XWIN_NATIVEGDI
- RealizeFontProcPtr RealizeFont;
- UnrealizeFontProcPtr UnrealizeFont;
-#endif
-
- winCursorRec cursor;
-} winPrivScreenRec;
-
-
-#ifdef XWIN_MULTIWINDOWEXTWM
-typedef struct {
- RootlessWindowPtr pFrame;
- HWND hWnd;
- int dwWidthBytes;
- BITMAPINFOHEADER *pbmihShadow;
- HBITMAP hbmpShadow;
- HDC hdcShadow;
- HDC hdcScreen;
- BOOL fResized;
- BOOL fRestackingNow;
- BOOL fClose;
- BOOL fMovingOrSizing;
- BOOL fDestroyed;//for debug
- char *pfb;
-} win32RootlessWindowRec, *win32RootlessWindowPtr;
-#endif
-
-
-typedef struct {
- pointer value;
- XID id;
-} WindowIDPairRec, *WindowIDPairPtr;
-
-
-/*
- * Extern declares for general global variables
- */
-
-extern winScreenInfo * g_ScreenInfo;
-extern miPointerScreenFuncRec g_winPointerCursorFuncs;
-extern DWORD g_dwEvents;
-#ifdef HAS_DEVWINDOWS
-extern int g_fdMessageQueue;
-#endif
-extern DevPrivateKey g_iScreenPrivateKey;
-extern DevPrivateKey g_iCmapPrivateKey;
-extern DevPrivateKey g_iGCPrivateKey;
-extern DevPrivateKey g_iPixmapPrivateKey;
-extern DevPrivateKey g_iWindowPrivateKey;
-extern unsigned long g_ulServerGeneration;
-extern DWORD g_dwEnginesSupported;
-extern HINSTANCE g_hInstance;
-extern int g_copyROP[];
-extern int g_patternROP[];
-extern const char * g_pszQueryHost;
-extern DeviceIntPtr g_pwinPointer;
-extern DeviceIntPtr g_pwinKeyboard;
-
-
-/*
- * Extern declares for dynamically loaded libraries and function pointers
- */
-
-extern HMODULE g_hmodDirectDraw;
-extern FARPROC g_fpDirectDrawCreate;
-extern FARPROC g_fpDirectDrawCreateClipper;
-
-extern HMODULE g_hmodCommonControls;
-extern FARPROC g_fpTrackMouseEvent;
-
-
-/*
- * Screen privates macros
- */
-
-#define winGetScreenPriv(pScreen) ((winPrivScreenPtr) \
- dixLookupPrivate(&(pScreen)->devPrivates, g_iScreenPrivateKey))
-
-#define winSetScreenPriv(pScreen,v) \
- dixSetPrivate(&(pScreen)->devPrivates, g_iScreenPrivateKey, v)
-
-#define winScreenPriv(pScreen) \
- winPrivScreenPtr pScreenPriv = winGetScreenPriv(pScreen)
-
-
-/*
- * Colormap privates macros
- */
-
-#define winGetCmapPriv(pCmap) ((winPrivCmapPtr) \
- dixLookupPrivate(&(pCmap)->devPrivates, g_iCmapPrivateKey))
-
-#define winSetCmapPriv(pCmap,v) \
- dixSetPrivate(&(pCmap)->devPrivates, g_iCmapPrivateKey, v)
-
-#define winCmapPriv(pCmap) \
- winPrivCmapPtr pCmapPriv = winGetCmapPriv(pCmap)
-
-
-/*
- * GC privates macros
- */
-
-#define winGetGCPriv(pGC) ((winPrivGCPtr) \
- dixLookupPrivate(&(pGC)->devPrivates, g_iGCPrivateKey))
-
-#define winSetGCPriv(pGC,v) \
- dixSetPrivate(&(pGC)->devPrivates, g_iGCPrivateKey, v)
-
-#define winGCPriv(pGC) \
- winPrivGCPtr pGCPriv = winGetGCPriv(pGC)
-
-
-/*
- * Pixmap privates macros
- */
-
-#define winGetPixmapPriv(pPixmap) ((winPrivPixmapPtr) \
- dixLookupPrivate(&(pPixmap)->devPrivates, g_iPixmapPrivateKey))
-
-#define winSetPixmapPriv(pPixmap,v) \
- dixLookupPrivate(&(pPixmap)->devPrivates, g_iPixmapPrivateKey, v)
-
-#define winPixmapPriv(pPixmap) \
- winPrivPixmapPtr pPixmapPriv = winGetPixmapPriv(pPixmap)
-
-
-/*
- * Window privates macros
- */
-
-#define winGetWindowPriv(pWin) ((winPrivWinPtr) \
- dixLookupPrivate(&(pWin)->devPrivates, g_iWindowPrivateKey))
-
-#define winSetWindowPriv(pWin,v) \
- dixLookupPrivate(&(pWin)->devPrivates, g_iWindowPrivateKey, v)
-
-#define winWindowPriv(pWin) \
- winPrivWinPtr pWinPriv = winGetWindowPriv(pWin)
-
-/*
- * wrapper macros
- */
-#define _WIN_WRAP(priv, real, mem, func) {\
- priv->mem = real->mem; \
- real->mem = func; \
-}
-
-#define _WIN_UNWRAP(priv, real, mem) {\
- real->mem = priv->mem; \
-}
-
-#define WIN_WRAP(mem, func) _WIN_WRAP(pScreenPriv, pScreen, mem, func)
-
-#define WIN_UNWRAP(mem) _WIN_UNWRAP(pScreenPriv, pScreen, mem)
-
-/*
- * BEGIN DDX and DIX Function Prototypes
- */
-
-
-/*
- * winallpriv.c
- */
-
-Bool
-winAllocatePrivates (ScreenPtr pScreen);
-
-Bool
-winInitCmapPrivates (ColormapPtr pCmap, int index);
-
-Bool
-winAllocateCmapPrivates (ColormapPtr pCmap);
-
-
-/*
- * winauth.c
- */
-
-#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
-Bool
-winGenerateAuthorization (void);
-void winSetAuthorization(void);
-#endif
-
-
-/*
- * winblock.c
- */
-
-void
-winBlockHandler (int nScreen,
- pointer pBlockData,
- pointer pTimeout,
- pointer pReadMask);
-
-
-#ifdef XWIN_NATIVEGDI
-/*
- * winclip.c
- */
-
-RegionPtr
-winPixmapToRegionNativeGDI (PixmapPtr pPix);
-#endif
-
-
-#ifdef XWIN_CLIPBOARD
-/*
- * winclipboardinit.c
- */
-
-Bool
-winInitClipboard (void);
-
-void
-winFixClipboardChain (void);
-#endif
-
-
-/*
- * wincmap.c
- */
-
-void
-winSetColormapFunctions (ScreenPtr pScreen);
-
-Bool
-winCreateDefColormap (ScreenPtr pScreen);
-
-
-/*
- * wincreatewnd.c
- */
-
-Bool
-winCreateBoundingWindowFullScreen (ScreenPtr pScreen);
-
-Bool
-winCreateBoundingWindowWindowed (ScreenPtr pScreen);
-
-
-/*
- * windialogs.c
- */
-
-int
-GetLiveClients (winPrivScreenPtr pScreenPriv);
-
-void
-winDisplayExitDialog (winPrivScreenPtr pScreenPriv);
-
-void
-winDisplayDepthChangeDialog (winPrivScreenPtr pScreenPriv);
-
-void
-winDisplayAboutDialog (winPrivScreenPtr pScreenPriv);
-
-
-/*
- * winengine.c
- */
-
-void
-winDetectSupportedEngines (void);
-
-Bool
-winSetEngine (ScreenPtr pScreen);
-
-Bool
-winGetDDProcAddresses (void);
-
-
-/*
- * winerror.c
- */
-
-#ifdef DDXOSVERRORF
-void
-OSVenderVErrorF (const char *pszFormat, va_list va_args);
-#endif
-
-void
-winMessageBoxF (const char *pszError, UINT uType, ...);
-
-
-#ifdef XWIN_NATIVEGDI
-/*
- * winfillsp.c
- */
-
-void
-winFillSpansNativeGDI (DrawablePtr pDrawable,
- GCPtr pGC,
- int nSpans,
- DDXPointPtr pPoints,
- int *pWidths,
- int fSorted);
-#endif
-
-
-#ifdef XWIN_NATIVEGDI
-/*
- * winfont.c
- */
-
-Bool
-winRealizeFontNativeGDI (ScreenPtr pScreen, FontPtr pFont);
-
-Bool
-winUnrealizeFontNativeGDI (ScreenPtr pScreen, FontPtr pFont);
-#endif
-
-
-#ifdef XWIN_NATIVEGDI
-/*
- * wingc.c
- */
-
-Bool
-winCreateGCNativeGDI (GCPtr pGC);
-#endif
-
-
-#ifdef XWIN_NATIVEGDI
-/*
- * wingetsp.c
- */
-
-void
-winGetSpansNativeGDI (DrawablePtr pDrawable,
- int wMax,
- DDXPointPtr pPoints,
- int *pWidths,
- int nSpans,
- char *pDst);
-#endif
-
-
-/*
- * winglobals.c
- */
-
-void
-winInitializeGlobals (void);
-
-
-/*
- * winkeybd.c
- */
-
-void
-winTranslateKey (WPARAM wParam, LPARAM lParam, int *piScanCode);
-
-int
-winKeybdProc (DeviceIntPtr pDeviceInt, int iState);
-
-void
-winInitializeModeKeyStates (void);
-
-void
-winRestoreModeKeyStates (void);
-
-Bool
-winIsFakeCtrl_L (UINT message, WPARAM wParam, LPARAM lParam);
-
-void
-winKeybdReleaseKeys (void);
-
-void
-winSendKeyEvent (DWORD dwKey, Bool fDown);
-
-BOOL
-winCheckKeyPressed(WPARAM wParam, LPARAM lParam);
-
-void
-winFixShiftKeys (int iScanCode);
-
-/*
- * winkeyhook.c
- */
-
-Bool
-winInstallKeyboardHookLL (void);
-
-void
-winRemoveKeyboardHookLL (void);
-
-
-/*
- * winmisc.c
- */
-
-#ifdef XWIN_NATIVEGDI
-void
-winQueryBestSizeNativeGDI (int class, unsigned short *pWidth,
- unsigned short *pHeight, ScreenPtr pScreen);
-#endif
-
-CARD8
-winCountBits (DWORD dw);
-
-Bool
-winUpdateFBPointer (ScreenPtr pScreen, void *pbits);
-
-#ifdef XWIN_NATIVEGDI
-BOOL
-winPaintBackground (HWND hwnd, COLORREF colorref);
-#endif
-
-
-/*
- * winmouse.c
- */
-
-int
-winMouseProc (DeviceIntPtr pDeviceInt, int iState);
-
-int
-winMouseWheel (ScreenPtr pScreen, int iDeltaZ);
-
-void
-winMouseButtonsSendEvent (int iEventType, int iButton);
-
-int
-winMouseButtonsHandle (ScreenPtr pScreen,
- int iEventType, int iButton,
- WPARAM wParam);
-
-void
-winEnqueueMotion(int x, int y);
-
-#ifdef XWIN_NATIVEGDI
-/*
- * winnativegdi.c
- */
-
-HBITMAP
-winCreateDIBNativeGDI (int iWidth, int iHeight, int iDepth,
- BYTE **ppbBits, BITMAPINFO **ppbmi);
-
-Bool
-winSetEngineFunctionsNativeGDI (ScreenPtr pScreen);
-#endif
-
-
-#ifdef XWIN_PRIMARYFB
-/*
- * winpfbddd.c
- */
-
-Bool
-winSetEngineFunctionsPrimaryDD (ScreenPtr pScreen);
-#endif
-
-
-#ifdef XWIN_NATIVEGDI
-/*
- * winpixmap.c
- */
-
-PixmapPtr
-winCreatePixmapNativeGDI (ScreenPtr pScreen, int width, int height, int depth,
- unsigned usage_hint);
-
-Bool
-winDestroyPixmapNativeGDI (PixmapPtr pPixmap);
-
-Bool
-winModifyPixmapHeaderNativeGDI (PixmapPtr pPixmap,
- int iWidth, int iHeight,
- int iDepth,
- int iBitsPerPixel,
- int devKind,
- pointer pPixData);
-#endif
-
-#ifdef XWIN_NATIVEGDI
-/*
- * winpolyline.c
- */
-
-void
-winPolyLineNativeGDI (DrawablePtr pDrawable,
- GCPtr pGC,
- int mode,
- int npt,
- DDXPointPtr ppt);
-#endif
-
-
-#ifdef XWIN_NATIVEGDI
-/*
- * winpushpxl.c
- */
-
-void
-winPushPixels (GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDrawable,
- int dx, int dy, int xOrg, int yOrg);
-#endif
-
-
-/*
- * winscrinit.c
- */
-
-Bool
-winScreenInit (int index,
- ScreenPtr pScreen,
- int argc, char **argv);
-
-Bool
-winFinishScreenInitFB (int index,
- ScreenPtr pScreen,
- int argc, char **argv);
-
-#if defined(XWIN_NATIVEGDI)
-Bool
-winFinishScreenInitNativeGDI (int index,
- ScreenPtr pScreen,
- int argc, char **argv);
-#endif
-
-
-#ifdef XWIN_NATIVEGDI
-/*
- * winsetsp.c
- */
-
-void
-winSetSpansNativeGDI (DrawablePtr pDrawable,
- GCPtr pGC,
- char *pSrc,
- DDXPointPtr pPoints,
- int *pWidth,
- int nSpans,
- int fSorted);
-#endif
-
-
-/*
- * winshaddd.c
- */
-
-Bool
-winSetEngineFunctionsShadowDD (ScreenPtr pScreen);
-
-
-/*
- * winshadddnl.c
- */
-
-Bool
-winSetEngineFunctionsShadowDDNL (ScreenPtr pScreen);
-
-
-/*
- * winshadgdi.c
- */
-
-Bool
-winSetEngineFunctionsShadowGDI (ScreenPtr pScreen);
-
-
-/*
- * winwakeup.c
- */
-
-void
-winWakeupHandler (int nScreen,
- pointer pWakeupData,
- unsigned long ulResult,
- pointer pReadmask);
-
-
-/*
- * winwindow.c
- */
-
-#ifdef XWIN_NATIVEGDI
-Bool
-winCreateWindowNativeGDI (WindowPtr pWin);
-
-Bool
-winDestroyWindowNativeGDI (WindowPtr pWin);
-
-Bool
-winPositionWindowNativeGDI (WindowPtr pWin, int x, int y);
-
-void
-winCopyWindowNativeGDI (WindowPtr pWin,
- DDXPointRec ptOldOrg,
- RegionPtr prgnSrc);
-
-Bool
-winChangeWindowAttributesNativeGDI (WindowPtr pWin, unsigned long mask);
-
-Bool
-winUnmapWindowNativeGDI (WindowPtr pWindow);
-
-Bool
-winMapWindowNativeGDI (WindowPtr pWindow);
-#endif
-
-Bool
-winCreateWindowRootless (WindowPtr pWindow);
-
-Bool
-winDestroyWindowRootless (WindowPtr pWindow);
-
-Bool
-winPositionWindowRootless (WindowPtr pWindow, int x, int y);
-
-Bool
-winChangeWindowAttributesRootless (WindowPtr pWindow, unsigned long mask);
-
-Bool
-winUnmapWindowRootless (WindowPtr pWindow);
-
-Bool
-winMapWindowRootless (WindowPtr pWindow);
-
-void
-winSetShapeRootless (WindowPtr pWindow);
-
-
-/*
- * winmultiwindowicons.c - Used by both multi-window and Win32Rootless
- */
-
-HICON
-winXIconToHICON (WindowPtr pWin, int iconSize);
-
-void
-winSelectIcons(WindowPtr pWin, HICON *pIcon, HICON *pSmallIcon);
-
-#ifdef XWIN_MULTIWINDOW
-/*
- * winmultiwindowshape.c
- */
-
-void
-winReshapeMultiWindow (WindowPtr pWin);
-
-void
-winSetShapeMultiWindow (WindowPtr pWindow);
-
-void
-winUpdateRgnMultiWindow (WindowPtr pWindow);
-#endif
-
-
-#ifdef XWIN_MULTIWINDOW
-/*
- * winmultiwindowwindow.c
- */
-
-Bool
-winCreateWindowMultiWindow (WindowPtr pWindow);
-
-Bool
-winDestroyWindowMultiWindow (WindowPtr pWindow);
-
-Bool
-winPositionWindowMultiWindow (WindowPtr pWindow, int x, int y);
-
-Bool
-winChangeWindowAttributesMultiWindow (WindowPtr pWindow, unsigned long mask);
-
-Bool
-winUnmapWindowMultiWindow (WindowPtr pWindow);
-
-Bool
-winMapWindowMultiWindow (WindowPtr pWindow);
-
-void
-winReparentWindowMultiWindow (WindowPtr pWin, WindowPtr pPriorParent);
-
-void
-winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib);
-
-void
-winReorderWindowsMultiWindow (void);
-
-void
-winResizeWindowMultiWindow (WindowPtr pWin, int x, int y, unsigned int w,
- unsigned int h, WindowPtr pSib);
-void
-winMoveWindowMultiWindow (WindowPtr pWin, int x, int y,
- WindowPtr pSib, VTKind kind);
-
-void
-winCopyWindowMultiWindow (WindowPtr pWin, DDXPointRec oldpt,
- RegionPtr oldRegion);
-
-XID
-winGetWindowID (WindowPtr pWin);
-
-int
-winAdjustXWindow (WindowPtr pWin, HWND hwnd);
-#endif
-
-
-#ifdef XWIN_MULTIWINDOW
-/*
- * winmultiwindowwndproc.c
- */
-
-LRESULT CALLBACK
-winTopLevelWindowProc (HWND hwnd, UINT message,
- WPARAM wParam, LPARAM lParam);
-#endif
-
-
-/*
- * wintrayicon.c
- */
-
-void
-winInitNotifyIcon (winPrivScreenPtr pScreenPriv, Bool Modify);
-
-void
-winDeleteNotifyIcon (winPrivScreenPtr pScreenPriv);
-
-LRESULT
-winHandleIconMessage (HWND hwnd, UINT message,
- WPARAM wParam, LPARAM lParam,
- winPrivScreenPtr pScreenPriv);
-
-
-/*
- * winwndproc.c
- */
-
-LRESULT CALLBACK
-winWindowProc (HWND hWnd, UINT message,
- WPARAM wParam, LPARAM lParam);
-
-
-#ifdef XWIN_MULTIWINDOWEXTWM
-/*
- * winwin32rootless.c
- */
-
-Bool
-winMWExtWMCreateFrame (RootlessWindowPtr pFrame, ScreenPtr pScreen,
- int newX, int newY, RegionPtr pShape);
-
-void
-winMWExtWMDestroyFrame (RootlessFrameID wid);
-
-void
-winMWExtWMMoveFrame (RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY);
-
-void
-winMWExtWMResizeFrame (RootlessFrameID wid, ScreenPtr pScreen,
- int newX, int newY, unsigned int newW, unsigned int newH,
- unsigned int gravity);
-
-void
-winMWExtWMRestackFrame (RootlessFrameID wid, RootlessFrameID nextWid);
-
-void
-winMWExtWMReshapeFrame (RootlessFrameID wid, RegionPtr pShape);
-
-void
-winMWExtWMUnmapFrame (RootlessFrameID wid);
-
-void
-winMWExtWMStartDrawing (RootlessFrameID wid, char **pixelData, int *bytesPerRow);
-
-void
-winMWExtWMStopDrawing (RootlessFrameID wid, Bool flush);
-
-void
-winMWExtWMUpdateRegion (RootlessFrameID wid, RegionPtr pDamage);
-
-void
-winMWExtWMDamageRects (RootlessFrameID wid, int count, const BoxRec *rects,
- int shift_x, int shift_y);
-
-void
-winMWExtWMRootlessSwitchWindow (RootlessWindowPtr pFrame, WindowPtr oldWin);
-
-void
-winMWExtWMCopyBytes (unsigned int width, unsigned int height,
- const void *src, unsigned int srcRowBytes,
- void *dst, unsigned int dstRowBytes);
-
-void
-winMWExtWMFillBytes (unsigned int width, unsigned int height, unsigned int value,
- void *dst, unsigned int dstRowBytes);
-
-int
-winMWExtWMCompositePixels (unsigned int width, unsigned int height, unsigned int function,
- void *src[2], unsigned int srcRowBytes[2],
- void *mask, unsigned int maskRowBytes,
- void *dst[2], unsigned int dstRowBytes[2]);
-
-void
-winMWExtWMCopyWindow (RootlessFrameID wid, int dstNrects, const BoxRec *dstRects,
- int dx, int dy);
-#endif
-
-
-#ifdef XWIN_MULTIWINDOWEXTWM
-/*
- * winwin32rootlesswindow.c
- */
-
-void
-winMWExtWMReorderWindows (ScreenPtr pScreen);
-
-void
-winMWExtWMMoveXWindow (WindowPtr pWin, int x, int y);
-
-void
-winMWExtWMResizeXWindow (WindowPtr pWin, int w, int h);
-
-void
-winMWExtWMMoveResizeXWindow (WindowPtr pWin, int x, int y, int w, int h);
-
-void
-winMWExtWMUpdateIcon (Window id);
-
-void
-winMWExtWMUpdateWindowDecoration (win32RootlessWindowPtr pRLWinPriv,
- winScreenInfoPtr pScreenInfo);
-
-wBOOL CALLBACK
-winMWExtWMDecorateWindow (HWND hwnd, LPARAM lParam);
-
-Bool
-winIsInternalWMRunning (winScreenInfoPtr pScreenInfo);
-
-void
-winMWExtWMRestackWindows (ScreenPtr pScreen);
-#endif
-
-
-#ifdef XWIN_MULTIWINDOWEXTWM
-/*
- * winwin32rootlesswndproc.c
- */
-
-LRESULT CALLBACK
-winMWExtWMWindowProc (HWND hwnd, UINT message,
- WPARAM wParam, LPARAM lParam);
-#endif
-
-
-/*
- * winwindowswm.c
- */
-
-void
-winWindowsWMSendEvent (int type, unsigned int mask, int which, int arg,
- Window window, int x, int y, int w, int h);
-
-void
-winWindowsWMExtensionInit (void);
-
-/*
- * wincursor.c
- */
-
-Bool
-winInitCursor (ScreenPtr pScreen);
-
-/*
- * winprocarg.c
- */
-void
-winInitializeScreens(int maxscreens);
-
-/*
- * windisplay.c
- */
-
-void
-winGetDisplayName(char *szDisplay, unsigned int screen);
-
-/*
- * END DDX and DIX Function Prototypes
- */
-
-#endif /* _WIN_H_ */
-
+/*
+ *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: Dakshinamurthy Karra
+ * Suhaib M Siddiqi
+ * Peter Busch
+ * Harold L Hunt II
+ * Kensuke Matsuzaki
+ */
+
+#ifndef _WIN_H_
+#define _WIN_H_
+
+#ifndef NO
+#define NO 0
+#endif
+#ifndef YES
+#define YES 1
+#endif
+
+/* WM_XBUTTON Messages. They should go into w32api. */
+#ifndef WM_XBUTTONDOWN
+# define WM_XBUTTONDOWN 523
+#endif
+#ifndef WM_XBUTTONUP
+# define WM_XBUTTONUP 524
+#endif
+#ifndef WM_XBUTTONDBLCLK
+# define WM_XBUTTONDBLCLK 525
+#endif
+
+
+#define WIN_DEFAULT_BPP 0
+#define WIN_DEFAULT_WHITEPIXEL 255
+#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_REFRESH 0
+#define WIN_DEFAULT_WIN_KILL TRUE
+#define WIN_DEFAULT_UNIX_KILL FALSE
+#define WIN_DEFAULT_CLIP_UPDATES_NBOXES 0
+#ifdef XWIN_EMULATEPSEUDO
+#define WIN_DEFAULT_EMULATE_PSEUDO FALSE
+#endif
+#define WIN_DEFAULT_USER_GAVE_HEIGHT_AND_WIDTH FALSE
+
+#define WIN_DIB_MAXIMUM_SIZE 0x08000000 /* 16 MB on Windows 95, 98, Me */
+#define WIN_DIB_MAXIMUM_SIZE_MB (WIN_DIB_MAXIMUM_SIZE / 8 / 1024 / 1024)
+
+/*
+ * Windows only supports 256 color palettes
+ */
+#define WIN_NUM_PALETTE_ENTRIES 256
+
+/*
+ * Number of times to call Restore in an attempt to restore the primary surface
+ */
+#define WIN_REGAIN_SURFACE_RETRIES 1
+
+/*
+ * Build a supported display depths mask by shifting one to the left
+ * by the number of bits in the supported depth.
+ */
+#define WIN_SUPPORTED_BPPS ( (1 << (32 - 1)) | (1 << (24 - 1)) \
+ | (1 << (16 - 1)) | (1 << (15 - 1)) \
+ | (1 << ( 8 - 1)))
+#define WIN_CHECK_DEPTH YES
+
+/*
+ * Timer IDs for WM_TIMER
+ */
+#define WIN_E3B_TIMER_ID 1
+#define WIN_POLLING_MOUSE_TIMER_ID 2
+
+#define MOUSE_POLLING_INTERVAL 50
+
+#define WIN_E3B_OFF -1
+#define WIN_FD_INVALID -1
+
+#define WIN_SERVER_NONE 0x0L /* 0 */
+#define WIN_SERVER_SHADOW_GDI 0x1L /* 1 */
+#define WIN_SERVER_SHADOW_DD 0x2L /* 2 */
+#define WIN_SERVER_SHADOW_DDNL 0x4L /* 4 */
+#ifdef XWIN_PRIMARYFB
+#define WIN_SERVER_PRIMARY_DD 0x8L /* 8 */
+#endif
+#ifdef XWIN_NATIVEGDI
+# define WIN_SERVER_NATIVE_GDI 0x10L /* 16 */
+#endif
+
+#define AltMapIndex Mod1MapIndex
+#define NumLockMapIndex Mod2MapIndex
+#define AltLangMapIndex Mod3MapIndex
+#define KanaMapIndex Mod4MapIndex
+#define ScrollLockMapIndex Mod5MapIndex
+
+#define WIN_MOD_LALT 0x00000001
+#define WIN_MOD_RALT 0x00000002
+#define WIN_MOD_LCONTROL 0x00000004
+#define WIN_MOD_RCONTROL 0x00000008
+
+#define WIN_24BPP_MASK_RED 0x00FF0000
+#define WIN_24BPP_MASK_GREEN 0x0000FF00
+#define WIN_24BPP_MASK_BLUE 0x000000FF
+
+#define WIN_MAX_KEYS_PER_KEY 4
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+
+#include <errno.h>
+#if defined(XWIN_MULTIWINDOWEXTWM) || defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
+#define HANDLE void *
+#ifdef _MSC_VER
+typedef int pid_t;
+#endif
+#include <pthread.h>
+#undef HANDLE
+#endif
+
+#ifdef HAS_MMAP
+#include <sys/mman.h>
+#ifndef MAP_FILE
+#define MAP_FILE 0
+#endif /* MAP_FILE */
+#endif /* HAS_MMAP */
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/Xos.h>
+#include <X11/Xprotostr.h>
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "pixmap.h"
+#include "region.h"
+#include "gcstruct.h"
+#include "colormap.h"
+#include "colormapst.h"
+#include "miscstruct.h"
+#include "servermd.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "micmap.h"
+#include "mifillarc.h"
+#include "mifpoly.h"
+#include "mibstore.h"
+#include "input.h"
+#include "mipointer.h"
+#include "X11/keysym.h"
+#include "mibstore.h"
+#include "micoord.h"
+#include "dix.h"
+#include "miline.h"
+#include "shadow.h"
+#include "fb.h"
+#include "rootless.h"
+
+#include "mipict.h"
+#include "picturestr.h"
+
+#ifdef RANDR
+#include "randrstr.h"
+#endif
+
+/*
+ * Windows headers
+ */
+#include "winms.h"
+#include "winresource.h"
+
+
+/*
+ * Define Windows constants
+ */
+
+#define WM_TRAYICON (WM_USER + 1000)
+#define WM_INIT_SYS_MENU (WM_USER + 1001)
+#define WM_GIVEUP (WM_USER + 1002)
+
+
+/* Local includes */
+#include "winwindow.h"
+#include "winmsg.h"
+
+#define PROFILEPOINT(point,thresh)\
+{\
+static unsigned int PROFPT##point = 0;\
+if (++PROFPT##point % thresh == 0)\
+ErrorF (#point ": PROFILEPOINT hit %u times\n", PROFPT##point);\
+}
+
+
+/* We use xor this macro for detecting toggle key state changes */
+#define WIN_XOR(a,b) ((!(a) && (b)) || ((a) && !(b)))
+
+#define DEFINE_ATOM_HELPER(func,atom_name) \
+static Atom func (void) { \
+ static int generation; \
+ static Atom atom; \
+ if (generation != serverGeneration) { \
+ generation = serverGeneration; \
+ atom = MakeAtom (atom_name, strlen (atom_name), TRUE); \
+ } \
+ return atom; \
+}
+
+/*
+ * Typedefs for engine dependent function pointers
+ */
+
+typedef Bool (*winAllocateFBProcPtr)(ScreenPtr);
+
+typedef void (*winShadowUpdateProcPtr)(ScreenPtr, shadowBufPtr);
+
+typedef Bool (*winCloseScreenProcPtr)(int, ScreenPtr);
+
+typedef Bool (*winInitVisualsProcPtr)(ScreenPtr);
+
+typedef Bool (*winAdjustVideoModeProcPtr)(ScreenPtr);
+
+typedef Bool (*winCreateBoundingWindowProcPtr)(ScreenPtr);
+
+typedef Bool (*winFinishScreenInitProcPtr)(int, ScreenPtr, int, char **);
+
+typedef Bool (*winBltExposedRegionsProcPtr)(ScreenPtr);
+
+typedef Bool (*winActivateAppProcPtr)(ScreenPtr);
+
+typedef Bool (*winRedrawScreenProcPtr)(ScreenPtr pScreen);
+
+typedef Bool (*winRealizeInstalledPaletteProcPtr)(ScreenPtr pScreen);
+
+typedef Bool (*winInstallColormapProcPtr)(ColormapPtr pColormap);
+
+typedef Bool (*winStoreColorsProcPtr)(ColormapPtr pmap,
+ int ndef, xColorItem *pdefs);
+
+typedef Bool (*winCreateColormapProcPtr)(ColormapPtr pColormap);
+
+typedef Bool (*winDestroyColormapProcPtr)(ColormapPtr pColormap);
+
+typedef Bool (*winHotKeyAltTabProcPtr)(ScreenPtr);
+
+typedef Bool (*winCreatePrimarySurfaceProcPtr)(ScreenPtr);
+
+typedef Bool (*winReleasePrimarySurfaceProcPtr)(ScreenPtr);
+
+typedef Bool (*winFinishCreateWindowsWindowProcPtr)(WindowPtr pWin);
+
+typedef Bool (*winCreateScreenResourcesProc)(ScreenPtr);
+
+/* Typedef for DIX wrapper functions */
+typedef int (*winDispatchProcPtr) (ClientPtr);
+
+
+/*
+ * GC (graphics context) privates
+ */
+
+typedef struct
+{
+ HDC hdc;
+ HDC hdcMem;
+} winPrivGCRec, *winPrivGCPtr;
+
+
+/*
+ * Pixmap privates
+ */
+
+typedef struct
+{
+ HDC hdcSelected;
+ HBITMAP hBitmap;
+ BYTE *pbBits;
+ DWORD dwScanlineBytes;
+ BITMAPINFOHEADER *pbmih;
+} winPrivPixmapRec, *winPrivPixmapPtr;
+
+
+/*
+ * Colormap privates
+ */
+
+typedef struct
+{
+ HPALETTE hPalette;
+ LPDIRECTDRAWPALETTE lpDDPalette;
+ RGBQUAD rgbColors[WIN_NUM_PALETTE_ENTRIES];
+ PALETTEENTRY peColors[WIN_NUM_PALETTE_ENTRIES];
+} winPrivCmapRec, *winPrivCmapPtr;
+
+/*
+ * Windows Cursor handling.
+ */
+
+typedef struct {
+ /* from GetSystemMetrics */
+ int sm_cx;
+ int sm_cy;
+
+ BOOL visible;
+ HCURSOR handle;
+ QueryBestSizeProcPtr QueryBestSize;
+ miPointerSpriteFuncPtr spriteFuncs;
+} winCursorRec;
+
+/*
+ * Screen information structure that we need before privates are available
+ * in the server startup sequence.
+ */
+
+typedef struct
+{
+ ScreenPtr pScreen;
+
+ /* Did the user specify a height and width? */
+ Bool fUserGaveHeightAndWidth;
+
+ DWORD dwScreen;
+ DWORD dwUserWidth;
+ DWORD dwUserHeight;
+ DWORD dwWidth;
+ DWORD dwHeight;
+ DWORD dwWidth_mm;
+ DWORD dwHeight_mm;
+ DWORD dwPaddedWidth;
+
+ /* Did the user specify a screen position? */
+ Bool fUserGavePosition;
+ DWORD dwInitialX;
+ DWORD dwInitialY;
+
+ /*
+ * dwStride is the number of whole pixels that occupy a scanline,
+ * including those pixels that are not displayed. This is basically
+ * a rounding up of the width.
+ */
+ DWORD dwStride;
+
+ /* Offset of the screen in the window when using scrollbars */
+ DWORD dwXOffset;
+ DWORD dwYOffset;
+
+ DWORD dwBPP;
+ DWORD dwDepth;
+ DWORD dwRefreshRate;
+ char *pfb;
+ DWORD dwEngine;
+ DWORD dwEnginePreferred;
+ DWORD dwClipUpdatesNBoxes;
+#ifdef XWIN_EMULATEPSEUDO
+ Bool fEmulatePseudo;
+#endif
+ Bool fFullScreen;
+ Bool fDecoration;
+#ifdef XWIN_MULTIWINDOWEXTWM
+ Bool fMWExtWM;
+ Bool fInternalWM;
+ Bool fAnotherWMRunning;
+#endif
+ Bool fRootless;
+#ifdef XWIN_MULTIWINDOW
+ Bool fMultiWindow;
+#endif
+#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
+ Bool fMultiMonitorOverride;
+#endif
+ Bool fMultipleMonitors;
+ Bool fLessPointer;
+ Bool fScrollbars;
+ Bool fNoTrayIcon;
+ int iE3BTimeout;
+ /* Windows (Alt+F4) and Unix (Ctrl+Alt+Backspace) Killkey */
+ Bool fUseWinKillKey;
+ Bool fUseUnixKillKey;
+ Bool fIgnoreInput;
+
+ /* Did the user explicitly set this screen? */
+ Bool fExplicitScreen;
+} winScreenInfo, *winScreenInfoPtr;
+
+
+/*
+ * Screen privates
+ */
+
+typedef struct _winPrivScreenRec
+{
+ winScreenInfoPtr pScreenInfo;
+
+ Bool fEnabled;
+ Bool fClosed;
+ Bool fActive;
+ Bool fBadDepth;
+
+ int iDeltaZ;
+
+ int iConnectedClients;
+
+ CloseScreenProcPtr CloseScreen;
+
+ DWORD dwRedMask;
+ DWORD dwGreenMask;
+ DWORD dwBlueMask;
+ DWORD dwBitsPerRGB;
+
+ DWORD dwModeKeyStates;
+
+ /* Handle to icons that must be freed */
+ HICON hiconNotifyIcon;
+
+ /* Last width, height, and depth of the Windows display */
+ DWORD dwLastWindowsWidth;
+ DWORD dwLastWindowsHeight;
+ DWORD dwLastWindowsBitsPixel;
+
+ /* Palette management */
+ ColormapPtr pcmapInstalled;
+
+ /* Pointer to the root visual so we only have to look it up once */
+ VisualPtr pRootVisual;
+
+ /* 3 button emulation variables */
+ int iE3BCachedPress;
+ Bool fE3BFakeButton2Sent;
+
+ /* Privates used by shadow fb GDI server */
+ HBITMAP hbmpShadow;
+ HDC hdcScreen;
+ HDC hdcShadow;
+ HWND hwndScreen;
+
+ /* Privates used by shadow fb and primary fb DirectDraw servers */
+ LPDIRECTDRAW pdd;
+ LPDIRECTDRAWSURFACE pddsPrimary;
+ LPDIRECTDRAW2 pdd2;
+
+ /* Privates used by shadow fb DirectDraw server */
+ LPDIRECTDRAWSURFACE pddsShadow;
+ LPDDSURFACEDESC pddsdShadow;
+
+#ifdef XWIN_PRIMARYFB
+ /* Privates used by primary fb DirectDraw server */
+ LPDIRECTDRAWSURFACE pddsOffscreen;
+ LPDDSURFACEDESC pddsdOffscreen;
+ LPDDSURFACEDESC pddsdPrimary;
+#endif
+
+ /* Privates used by shadow fb DirectDraw Nonlocking server */
+ LPDIRECTDRAW4 pdd4;
+ LPDIRECTDRAWSURFACE4 pddsShadow4;
+ LPDIRECTDRAWSURFACE4 pddsPrimary4;
+ BOOL fRetryCreateSurface;
+
+ /* Privates used by both shadow fb DirectDraw servers */
+ LPDIRECTDRAWCLIPPER pddcPrimary;
+
+#ifdef XWIN_MULTIWINDOWEXTWM
+ /* Privates used by multi-window external window manager */
+ RootlessFrameID widTop;
+ Bool fRestacking;
+#endif
+
+#ifdef XWIN_MULTIWINDOW
+ /* Privates used by multi-window */
+ pthread_t ptWMProc;
+ pthread_t ptXMsgProc;
+ void *pWMInfo;
+#endif
+
+#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
+ /* Privates used by both multi-window and rootless */
+ Bool fRootWindowShown;
+#endif
+
+#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
+ /* Privates used for any module running in a seperate thread */
+ pthread_mutex_t pmServerStarted;
+ Bool fServerStarted;
+#endif
+
+ /* Engine specific functions */
+ winAllocateFBProcPtr pwinAllocateFB;
+ winShadowUpdateProcPtr pwinShadowUpdate;
+ winCloseScreenProcPtr pwinCloseScreen;
+ winInitVisualsProcPtr pwinInitVisuals;
+ winAdjustVideoModeProcPtr pwinAdjustVideoMode;
+ winCreateBoundingWindowProcPtr pwinCreateBoundingWindow;
+ winFinishScreenInitProcPtr pwinFinishScreenInit;
+ winBltExposedRegionsProcPtr pwinBltExposedRegions;
+ winActivateAppProcPtr pwinActivateApp;
+ winRedrawScreenProcPtr pwinRedrawScreen;
+ winRealizeInstalledPaletteProcPtr pwinRealizeInstalledPalette;
+ winInstallColormapProcPtr pwinInstallColormap;
+ winStoreColorsProcPtr pwinStoreColors;
+ winCreateColormapProcPtr pwinCreateColormap;
+ winDestroyColormapProcPtr pwinDestroyColormap;
+ winHotKeyAltTabProcPtr pwinHotKeyAltTab;
+ winCreatePrimarySurfaceProcPtr pwinCreatePrimarySurface;
+ winReleasePrimarySurfaceProcPtr pwinReleasePrimarySurface;
+
+ winCreateScreenResourcesProc pwinCreateScreenResources;
+
+#ifdef XWIN_MULTIWINDOW
+ /* Window Procedures for MultiWindow mode */
+ winFinishCreateWindowsWindowProcPtr pwinFinishCreateWindowsWindow;
+#endif
+
+ /* Window Procedures for Rootless mode */
+ CreateWindowProcPtr CreateWindow;
+ DestroyWindowProcPtr DestroyWindow;
+ PositionWindowProcPtr PositionWindow;
+ ChangeWindowAttributesProcPtr ChangeWindowAttributes;
+ RealizeWindowProcPtr RealizeWindow;
+ UnrealizeWindowProcPtr UnrealizeWindow;
+ ValidateTreeProcPtr ValidateTree;
+ PostValidateTreeProcPtr PostValidateTree;
+ WindowExposuresProcPtr WindowExposures;
+ CopyWindowProcPtr CopyWindow;
+ ClearToBackgroundProcPtr ClearToBackground;
+ ClipNotifyProcPtr ClipNotify;
+ RestackWindowProcPtr RestackWindow;
+ ReparentWindowProcPtr ReparentWindow;
+ ResizeWindowProcPtr ResizeWindow;
+ MoveWindowProcPtr MoveWindow;
+ SetShapeProcPtr SetShape;
+
+#ifdef XWIN_NATIVEGDI
+ RealizeFontProcPtr RealizeFont;
+ UnrealizeFontProcPtr UnrealizeFont;
+#endif
+
+ winCursorRec cursor;
+} winPrivScreenRec;
+
+
+#ifdef XWIN_MULTIWINDOWEXTWM
+typedef struct {
+ RootlessWindowPtr pFrame;
+ HWND hWnd;
+ int dwWidthBytes;
+ BITMAPINFOHEADER *pbmihShadow;
+ HBITMAP hbmpShadow;
+ HDC hdcShadow;
+ HDC hdcScreen;
+ BOOL fResized;
+ BOOL fRestackingNow;
+ BOOL fClose;
+ BOOL fMovingOrSizing;
+ BOOL fDestroyed;//for debug
+ char *pfb;
+} win32RootlessWindowRec, *win32RootlessWindowPtr;
+#endif
+
+
+typedef struct {
+ pointer value;
+ XID id;
+} WindowIDPairRec, *WindowIDPairPtr;
+
+
+/*
+ * Extern declares for general global variables
+ */
+
+extern winScreenInfo * g_ScreenInfo;
+extern miPointerScreenFuncRec g_winPointerCursorFuncs;
+extern DWORD g_dwEvents;
+#ifdef HAS_DEVWINDOWS
+extern int g_fdMessageQueue;
+#endif
+extern DevPrivateKey g_iScreenPrivateKey;
+extern DevPrivateKey g_iCmapPrivateKey;
+extern DevPrivateKey g_iGCPrivateKey;
+extern DevPrivateKey g_iPixmapPrivateKey;
+extern DevPrivateKey g_iWindowPrivateKey;
+extern unsigned long g_ulServerGeneration;
+extern DWORD g_dwEnginesSupported;
+extern HINSTANCE g_hInstance;
+extern int g_copyROP[];
+extern int g_patternROP[];
+extern const char * g_pszQueryHost;
+extern DeviceIntPtr g_pwinPointer;
+extern DeviceIntPtr g_pwinKeyboard;
+
+
+/*
+ * Extern declares for dynamically loaded libraries and function pointers
+ */
+
+extern HMODULE g_hmodDirectDraw;
+extern FARPROC g_fpDirectDrawCreate;
+extern FARPROC g_fpDirectDrawCreateClipper;
+
+extern HMODULE g_hmodCommonControls;
+extern FARPROC g_fpTrackMouseEvent;
+
+
+/*
+ * Screen privates macros
+ */
+
+#define winGetScreenPriv(pScreen) ((winPrivScreenPtr) \
+ dixLookupPrivate(&(pScreen)->devPrivates, g_iScreenPrivateKey))
+
+#define winSetScreenPriv(pScreen,v) \
+ dixSetPrivate(&(pScreen)->devPrivates, g_iScreenPrivateKey, v)
+
+#define winScreenPriv(pScreen) \
+ winPrivScreenPtr pScreenPriv = winGetScreenPriv(pScreen)
+
+
+/*
+ * Colormap privates macros
+ */
+
+#define winGetCmapPriv(pCmap) ((winPrivCmapPtr) \
+ dixLookupPrivate(&(pCmap)->devPrivates, g_iCmapPrivateKey))
+
+#define winSetCmapPriv(pCmap,v) \
+ dixSetPrivate(&(pCmap)->devPrivates, g_iCmapPrivateKey, v)
+
+#define winCmapPriv(pCmap) \
+ winPrivCmapPtr pCmapPriv = winGetCmapPriv(pCmap)
+
+
+/*
+ * GC privates macros
+ */
+
+#define winGetGCPriv(pGC) ((winPrivGCPtr) \
+ dixLookupPrivate(&(pGC)->devPrivates, g_iGCPrivateKey))
+
+#define winSetGCPriv(pGC,v) \
+ dixSetPrivate(&(pGC)->devPrivates, g_iGCPrivateKey, v)
+
+#define winGCPriv(pGC) \
+ winPrivGCPtr pGCPriv = winGetGCPriv(pGC)
+
+
+/*
+ * Pixmap privates macros
+ */
+
+#define winGetPixmapPriv(pPixmap) ((winPrivPixmapPtr) \
+ dixLookupPrivate(&(pPixmap)->devPrivates, g_iPixmapPrivateKey))
+
+#define winSetPixmapPriv(pPixmap,v) \
+ dixLookupPrivate(&(pPixmap)->devPrivates, g_iPixmapPrivateKey, v)
+
+#define winPixmapPriv(pPixmap) \
+ winPrivPixmapPtr pPixmapPriv = winGetPixmapPriv(pPixmap)
+
+
+/*
+ * Window privates macros
+ */
+
+#define winGetWindowPriv(pWin) ((winPrivWinPtr) \
+ dixLookupPrivate(&(pWin)->devPrivates, g_iWindowPrivateKey))
+
+#define winSetWindowPriv(pWin,v) \
+ dixLookupPrivate(&(pWin)->devPrivates, g_iWindowPrivateKey, v)
+
+#define winWindowPriv(pWin) \
+ winPrivWinPtr pWinPriv = winGetWindowPriv(pWin)
+
+/*
+ * wrapper macros
+ */
+#define _WIN_WRAP(priv, real, mem, func) {\
+ priv->mem = real->mem; \
+ real->mem = func; \
+}
+
+#define _WIN_UNWRAP(priv, real, mem) {\
+ real->mem = priv->mem; \
+}
+
+#define WIN_WRAP(mem, func) _WIN_WRAP(pScreenPriv, pScreen, mem, func)
+
+#define WIN_UNWRAP(mem) _WIN_UNWRAP(pScreenPriv, pScreen, mem)
+
+/*
+ * BEGIN DDX and DIX Function Prototypes
+ */
+
+
+/*
+ * winallpriv.c
+ */
+
+Bool
+winAllocatePrivates (ScreenPtr pScreen);
+
+Bool
+winInitCmapPrivates (ColormapPtr pCmap, int index);
+
+Bool
+winAllocateCmapPrivates (ColormapPtr pCmap);
+
+
+/*
+ * winauth.c
+ */
+
+#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
+Bool
+winGenerateAuthorization (void);
+void winSetAuthorization(void);
+#endif
+
+
+/*
+ * winblock.c
+ */
+
+void
+winBlockHandler (int nScreen,
+ pointer pBlockData,
+ pointer pTimeout,
+ pointer pReadMask);
+
+
+#ifdef XWIN_NATIVEGDI
+/*
+ * winclip.c
+ */
+
+RegionPtr
+winPixmapToRegionNativeGDI (PixmapPtr pPix);
+#endif
+
+
+#ifdef XWIN_CLIPBOARD
+/*
+ * winclipboardinit.c
+ */
+
+Bool
+winInitClipboard (void);
+
+void
+winFixClipboardChain (void);
+#endif
+
+
+/*
+ * wincmap.c
+ */
+
+void
+winSetColormapFunctions (ScreenPtr pScreen);
+
+Bool
+winCreateDefColormap (ScreenPtr pScreen);
+
+
+/*
+ * wincreatewnd.c
+ */
+
+Bool
+winCreateBoundingWindowFullScreen (ScreenPtr pScreen);
+
+Bool
+winCreateBoundingWindowWindowed (ScreenPtr pScreen);
+
+
+/*
+ * windialogs.c
+ */
+
+int
+GetLiveClients (winPrivScreenPtr pScreenPriv);
+
+void
+winDisplayExitDialog (winPrivScreenPtr pScreenPriv);
+
+void
+winDisplayDepthChangeDialog (winPrivScreenPtr pScreenPriv);
+
+void
+winDisplayAboutDialog (winPrivScreenPtr pScreenPriv);
+
+
+/*
+ * winengine.c
+ */
+
+void
+winDetectSupportedEngines (void);
+
+Bool
+winSetEngine (ScreenPtr pScreen);
+
+Bool
+winGetDDProcAddresses (void);
+
+
+/*
+ * winerror.c
+ */
+
+#ifdef DDXOSVERRORF
+void
+OSVenderVErrorF (const char *pszFormat, va_list va_args);
+#endif
+
+void
+winMessageBoxF (const char *pszError, UINT uType, ...);
+
+
+#ifdef XWIN_NATIVEGDI
+/*
+ * winfillsp.c
+ */
+
+void
+winFillSpansNativeGDI (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nSpans,
+ DDXPointPtr pPoints,
+ int *pWidths,
+ int fSorted);
+#endif
+
+
+#ifdef XWIN_NATIVEGDI
+/*
+ * winfont.c
+ */
+
+Bool
+winRealizeFontNativeGDI (ScreenPtr pScreen, FontPtr pFont);
+
+Bool
+winUnrealizeFontNativeGDI (ScreenPtr pScreen, FontPtr pFont);
+#endif
+
+
+#ifdef XWIN_NATIVEGDI
+/*
+ * wingc.c
+ */
+
+Bool
+winCreateGCNativeGDI (GCPtr pGC);
+#endif
+
+
+#ifdef XWIN_NATIVEGDI
+/*
+ * wingetsp.c
+ */
+
+void
+winGetSpansNativeGDI (DrawablePtr pDrawable,
+ int wMax,
+ DDXPointPtr pPoints,
+ int *pWidths,
+ int nSpans,
+ char *pDst);
+#endif
+
+
+/*
+ * winglobals.c
+ */
+
+void
+winInitializeGlobals (void);
+
+
+/*
+ * winkeybd.c
+ */
+
+void
+winTranslateKey (WPARAM wParam, LPARAM lParam, int *piScanCode);
+
+int
+winKeybdProc (DeviceIntPtr pDeviceInt, int iState);
+
+void
+winInitializeModeKeyStates (void);
+
+void
+winRestoreModeKeyStates (void);
+
+Bool
+winIsFakeCtrl_L (UINT message, WPARAM wParam, LPARAM lParam);
+
+void
+winKeybdReleaseKeys (void);
+
+void
+winSendKeyEvent (DWORD dwKey, Bool fDown);
+
+BOOL
+winCheckKeyPressed(WPARAM wParam, LPARAM lParam);
+
+void
+winFixShiftKeys (int iScanCode);
+
+/*
+ * winkeyhook.c
+ */
+
+Bool
+winInstallKeyboardHookLL (void);
+
+void
+winRemoveKeyboardHookLL (void);
+
+
+/*
+ * winmisc.c
+ */
+
+#ifdef XWIN_NATIVEGDI
+void
+winQueryBestSizeNativeGDI (int class, unsigned short *pWidth,
+ unsigned short *pHeight, ScreenPtr pScreen);
+#endif
+
+CARD8
+winCountBits (DWORD dw);
+
+Bool
+winUpdateFBPointer (ScreenPtr pScreen, void *pbits);
+
+#ifdef XWIN_NATIVEGDI
+BOOL
+winPaintBackground (HWND hwnd, COLORREF colorref);
+#endif
+
+
+/*
+ * winmouse.c
+ */
+
+int
+winMouseProc (DeviceIntPtr pDeviceInt, int iState);
+
+int
+winMouseWheel (ScreenPtr pScreen, int iDeltaZ);
+
+void
+winMouseButtonsSendEvent (int iEventType, int iButton);
+
+int
+winMouseButtonsHandle (ScreenPtr pScreen,
+ int iEventType, int iButton,
+ WPARAM wParam);
+
+void
+winEnqueueMotion(int x, int y);
+
+#ifdef XWIN_NATIVEGDI
+/*
+ * winnativegdi.c
+ */
+
+HBITMAP
+winCreateDIBNativeGDI (int iWidth, int iHeight, int iDepth,
+ BYTE **ppbBits, BITMAPINFO **ppbmi);
+
+Bool
+winSetEngineFunctionsNativeGDI (ScreenPtr pScreen);
+#endif
+
+
+#ifdef XWIN_PRIMARYFB
+/*
+ * winpfbddd.c
+ */
+
+Bool
+winSetEngineFunctionsPrimaryDD (ScreenPtr pScreen);
+#endif
+
+
+#ifdef XWIN_NATIVEGDI
+/*
+ * winpixmap.c
+ */
+
+PixmapPtr
+winCreatePixmapNativeGDI (ScreenPtr pScreen, int width, int height, int depth,
+ unsigned usage_hint);
+
+Bool
+winDestroyPixmapNativeGDI (PixmapPtr pPixmap);
+
+Bool
+winModifyPixmapHeaderNativeGDI (PixmapPtr pPixmap,
+ int iWidth, int iHeight,
+ int iDepth,
+ int iBitsPerPixel,
+ int devKind,
+ pointer pPixData);
+#endif
+
+#ifdef XWIN_NATIVEGDI
+/*
+ * winpolyline.c
+ */
+
+void
+winPolyLineNativeGDI (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr ppt);
+#endif
+
+
+#ifdef XWIN_NATIVEGDI
+/*
+ * winpushpxl.c
+ */
+
+void
+winPushPixels (GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDrawable,
+ int dx, int dy, int xOrg, int yOrg);
+#endif
+
+
+/*
+ * winscrinit.c
+ */
+
+Bool
+winScreenInit (int index,
+ ScreenPtr pScreen,
+ int argc, char **argv);
+
+Bool
+winFinishScreenInitFB (int index,
+ ScreenPtr pScreen,
+ int argc, char **argv);
+
+#if defined(XWIN_NATIVEGDI)
+Bool
+winFinishScreenInitNativeGDI (int index,
+ ScreenPtr pScreen,
+ int argc, char **argv);
+#endif
+
+
+#ifdef XWIN_NATIVEGDI
+/*
+ * winsetsp.c
+ */
+
+void
+winSetSpansNativeGDI (DrawablePtr pDrawable,
+ GCPtr pGC,
+ char *pSrc,
+ DDXPointPtr pPoints,
+ int *pWidth,
+ int nSpans,
+ int fSorted);
+#endif
+
+
+/*
+ * winshaddd.c
+ */
+
+Bool
+winSetEngineFunctionsShadowDD (ScreenPtr pScreen);
+
+
+/*
+ * winshadddnl.c
+ */
+
+Bool
+winSetEngineFunctionsShadowDDNL (ScreenPtr pScreen);
+
+
+/*
+ * winshadgdi.c
+ */
+
+Bool
+winSetEngineFunctionsShadowGDI (ScreenPtr pScreen);
+
+
+/*
+ * winwakeup.c
+ */
+
+void
+winWakeupHandler (int nScreen,
+ pointer pWakeupData,
+ unsigned long ulResult,
+ pointer pReadmask);
+
+
+/*
+ * winwindow.c
+ */
+
+#ifdef XWIN_NATIVEGDI
+Bool
+winCreateWindowNativeGDI (WindowPtr pWin);
+
+Bool
+winDestroyWindowNativeGDI (WindowPtr pWin);
+
+Bool
+winPositionWindowNativeGDI (WindowPtr pWin, int x, int y);
+
+void
+winCopyWindowNativeGDI (WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc);
+
+Bool
+winChangeWindowAttributesNativeGDI (WindowPtr pWin, unsigned long mask);
+
+Bool
+winUnmapWindowNativeGDI (WindowPtr pWindow);
+
+Bool
+winMapWindowNativeGDI (WindowPtr pWindow);
+#endif
+
+Bool
+winCreateWindowRootless (WindowPtr pWindow);
+
+Bool
+winDestroyWindowRootless (WindowPtr pWindow);
+
+Bool
+winPositionWindowRootless (WindowPtr pWindow, int x, int y);
+
+Bool
+winChangeWindowAttributesRootless (WindowPtr pWindow, unsigned long mask);
+
+Bool
+winUnmapWindowRootless (WindowPtr pWindow);
+
+Bool
+winMapWindowRootless (WindowPtr pWindow);
+
+void
+winSetShapeRootless (WindowPtr pWindow);
+
+
+/*
+ * winmultiwindowicons.c - Used by both multi-window and Win32Rootless
+ */
+
+HICON
+winXIconToHICON (WindowPtr pWin, int iconSize);
+
+void
+winSelectIcons(WindowPtr pWin, HICON *pIcon, HICON *pSmallIcon);
+
+#ifdef XWIN_MULTIWINDOW
+/*
+ * winmultiwindowshape.c
+ */
+
+void
+winReshapeMultiWindow (WindowPtr pWin);
+
+void
+winSetShapeMultiWindow (WindowPtr pWindow);
+
+void
+winUpdateRgnMultiWindow (WindowPtr pWindow);
+#endif
+
+
+#ifdef XWIN_MULTIWINDOW
+/*
+ * winmultiwindowwindow.c
+ */
+
+Bool
+winCreateWindowMultiWindow (WindowPtr pWindow);
+
+Bool
+winDestroyWindowMultiWindow (WindowPtr pWindow);
+
+Bool
+winPositionWindowMultiWindow (WindowPtr pWindow, int x, int y);
+
+Bool
+winChangeWindowAttributesMultiWindow (WindowPtr pWindow, unsigned long mask);
+
+Bool
+winUnmapWindowMultiWindow (WindowPtr pWindow);
+
+Bool
+winMapWindowMultiWindow (WindowPtr pWindow);
+
+void
+winReparentWindowMultiWindow (WindowPtr pWin, WindowPtr pPriorParent);
+
+void
+winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib);
+
+void
+winReorderWindowsMultiWindow (void);
+
+void
+winResizeWindowMultiWindow (WindowPtr pWin, int x, int y, unsigned int w,
+ unsigned int h, WindowPtr pSib);
+void
+winMoveWindowMultiWindow (WindowPtr pWin, int x, int y,
+ WindowPtr pSib, VTKind kind);
+
+void
+winCopyWindowMultiWindow (WindowPtr pWin, DDXPointRec oldpt,
+ RegionPtr oldRegion);
+
+XID
+winGetWindowID (WindowPtr pWin);
+
+int
+winAdjustXWindow (WindowPtr pWin, HWND hwnd);
+#endif
+
+
+#ifdef XWIN_MULTIWINDOW
+/*
+ * winmultiwindowwndproc.c
+ */
+
+LRESULT CALLBACK
+winTopLevelWindowProc (HWND hwnd, UINT message,
+ WPARAM wParam, LPARAM lParam);
+#endif
+
+
+/*
+ * wintrayicon.c
+ */
+
+void
+winInitNotifyIcon (winPrivScreenPtr pScreenPriv, Bool Modify);
+
+void
+winDeleteNotifyIcon (winPrivScreenPtr pScreenPriv);
+
+LRESULT
+winHandleIconMessage (HWND hwnd, UINT message,
+ WPARAM wParam, LPARAM lParam,
+ winPrivScreenPtr pScreenPriv);
+
+
+/*
+ * winwndproc.c
+ */
+
+LRESULT CALLBACK
+winWindowProc (HWND hWnd, UINT message,
+ WPARAM wParam, LPARAM lParam);
+
+
+#ifdef XWIN_MULTIWINDOWEXTWM
+/*
+ * winwin32rootless.c
+ */
+
+Bool
+winMWExtWMCreateFrame (RootlessWindowPtr pFrame, ScreenPtr pScreen,
+ int newX, int newY, RegionPtr pShape);
+
+void
+winMWExtWMDestroyFrame (RootlessFrameID wid);
+
+void
+winMWExtWMMoveFrame (RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY);
+
+void
+winMWExtWMResizeFrame (RootlessFrameID wid, ScreenPtr pScreen,
+ int newX, int newY, unsigned int newW, unsigned int newH,
+ unsigned int gravity);
+
+void
+winMWExtWMRestackFrame (RootlessFrameID wid, RootlessFrameID nextWid);
+
+void
+winMWExtWMReshapeFrame (RootlessFrameID wid, RegionPtr pShape);
+
+void
+winMWExtWMUnmapFrame (RootlessFrameID wid);
+
+void
+winMWExtWMStartDrawing (RootlessFrameID wid, char **pixelData, int *bytesPerRow);
+
+void
+winMWExtWMStopDrawing (RootlessFrameID wid, Bool flush);
+
+void
+winMWExtWMUpdateRegion (RootlessFrameID wid, RegionPtr pDamage);
+
+void
+winMWExtWMDamageRects (RootlessFrameID wid, int count, const BoxRec *rects,
+ int shift_x, int shift_y);
+
+void
+winMWExtWMRootlessSwitchWindow (RootlessWindowPtr pFrame, WindowPtr oldWin);
+
+void
+winMWExtWMCopyBytes (unsigned int width, unsigned int height,
+ const void *src, unsigned int srcRowBytes,
+ void *dst, unsigned int dstRowBytes);
+
+void
+winMWExtWMFillBytes (unsigned int width, unsigned int height, unsigned int value,
+ void *dst, unsigned int dstRowBytes);
+
+int
+winMWExtWMCompositePixels (unsigned int width, unsigned int height, unsigned int function,
+ void *src[2], unsigned int srcRowBytes[2],
+ void *mask, unsigned int maskRowBytes,
+ void *dst[2], unsigned int dstRowBytes[2]);
+
+void
+winMWExtWMCopyWindow (RootlessFrameID wid, int dstNrects, const BoxRec *dstRects,
+ int dx, int dy);
+#endif
+
+
+#ifdef XWIN_MULTIWINDOWEXTWM
+/*
+ * winwin32rootlesswindow.c
+ */
+
+void
+winMWExtWMReorderWindows (ScreenPtr pScreen);
+
+void
+winMWExtWMMoveXWindow (WindowPtr pWin, int x, int y);
+
+void
+winMWExtWMResizeXWindow (WindowPtr pWin, int w, int h);
+
+void
+winMWExtWMMoveResizeXWindow (WindowPtr pWin, int x, int y, int w, int h);
+
+void
+winMWExtWMUpdateIcon (Window id);
+
+void
+winMWExtWMUpdateWindowDecoration (win32RootlessWindowPtr pRLWinPriv,
+ winScreenInfoPtr pScreenInfo);
+
+wBOOL CALLBACK
+winMWExtWMDecorateWindow (HWND hwnd, LPARAM lParam);
+
+Bool
+winIsInternalWMRunning (winScreenInfoPtr pScreenInfo);
+
+void
+winMWExtWMRestackWindows (ScreenPtr pScreen);
+#endif
+
+
+#ifdef XWIN_MULTIWINDOWEXTWM
+/*
+ * winwin32rootlesswndproc.c
+ */
+
+LRESULT CALLBACK
+winMWExtWMWindowProc (HWND hwnd, UINT message,
+ WPARAM wParam, LPARAM lParam);
+#endif
+
+
+/*
+ * winwindowswm.c
+ */
+
+void
+winWindowsWMSendEvent (int type, unsigned int mask, int which, int arg,
+ Window window, int x, int y, int w, int h);
+
+void
+winWindowsWMExtensionInit (void);
+
+/*
+ * wincursor.c
+ */
+
+Bool
+winInitCursor (ScreenPtr pScreen);
+
+/*
+ * winprocarg.c
+ */
+void
+winInitializeScreens(int maxscreens);
+
+/*
+ * windisplay.c
+ */
+
+void
+winGetDisplayName(char *szDisplay, unsigned int screen);
+
+/*
+ * END DDX and DIX Function Prototypes
+ */
+
+#endif /* _WIN_H_ */
+
diff --git a/xorg-server/hw/xwin/winauth.c b/xorg-server/hw/xwin/winauth.c
index 581098694..10bce693b 100644
--- a/xorg-server/hw/xwin/winauth.c
+++ b/xorg-server/hw/xwin/winauth.c
@@ -163,7 +163,7 @@ winGenerateAuthorization (void)
#ifdef XCSECURITY
/* Allocate structure for additional auth information */
pAuth = (SecurityAuthorizationPtr)
- xalloc (sizeof (SecurityAuthorizationRec));
+ malloc(sizeof (SecurityAuthorizationRec));
if (!(pAuth))
{
ErrorF ("winGenerateAuthorization - Failed allocating "
@@ -199,7 +199,7 @@ winGenerateAuthorization (void)
auth_bailout:
if (fFreeAuth)
- xfree (pAuth);
+ free(pAuth);
return FALSE;
}
diff --git a/xorg-server/hw/xwin/winconfig.c b/xorg-server/hw/xwin/winconfig.c
index c3b9dcc35..afdf6926e 100644
--- a/xorg-server/hw/xwin/winconfig.c
+++ b/xorg-server/hw/xwin/winconfig.c
@@ -390,10 +390,10 @@ winConfigKeyboard (DeviceIntPtr pDevice)
(1000 / g_winInfo.keyboard.rate) < 1)
{
ErrorF ("\"%s\" is not a valid AutoRepeat value", s);
- xfree(s);
+ free(s);
return FALSE;
}
- xfree(s);
+ free(s);
winDebug ("AutoRepeat: %ld %ld\n",
g_winInfo.keyboard.delay, g_winInfo.keyboard.rate);
}
diff --git a/xorg-server/hw/xwin/windialogs.c b/xorg-server/hw/xwin/windialogs.c
index adbec19cb..17d4d3226 100644
--- a/xorg-server/hw/xwin/windialogs.c
+++ b/xorg-server/hw/xwin/windialogs.c
@@ -373,7 +373,7 @@ winExitDlgProc (HWND hDialog, UINT message,
/* Set the number of connected clients */
SetWindowText (GetDlgItem (hDialog, IDC_CLIENTS_CONNECTED),
pszConnectedClients);
- xfree (pszConnectedClients);
+ free(pszConnectedClients);
}
return TRUE;
diff --git a/xorg-server/hw/xwin/winerror.c b/xorg-server/hw/xwin/winerror.c
index 7cbfd65e2..2e706009c 100644
--- a/xorg-server/hw/xwin/winerror.c
+++ b/xorg-server/hw/xwin/winerror.c
@@ -1,170 +1,170 @@
-/*
- *Copyright (C) 2001-2004 Harold L Hunt II 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 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
- */
-
-#ifdef HAVE_XWIN_CONFIG_H
-#include <xwin-config.h>
-#endif
-#ifdef XVENDORNAME
-#define VENDOR_STRING XVENDORNAME
-#define VENDOR_CONTACT BUILDERADDR
-#endif
-
-#include <../xfree86/common/xorgVersion.h>
-#include "win.h"
-
-/* References to external symbols */
-extern char * g_pszCommandLine;
-extern const char * g_pszLogFile;
-extern Bool g_fSilentFatalError;
-extern Bool g_fSilentDupError;
-extern Bool g_fLogInited;
-
-#ifdef DDXOSVERRORF
-/* Prototype */
-void
-OsVendorVErrorF (const char *pszFormat, va_list va_args);
-
-void
-OsVendorVErrorF (const char *pszFormat, va_list va_args)
-{
-#if defined(XWIN_CLIPBOARD) || defined (XWIN_MULTIWINDOW)
- /* make sure the clipboard and multiwindow threads do not interfere the
- * main thread */
- static pthread_mutex_t s_pmPrinting = PTHREAD_MUTEX_INITIALIZER;
-
- /* Lock the printing mutex */
- pthread_mutex_lock (&s_pmPrinting);
-#endif
-
- /*
- If we want to silence it,
- detect if we are going to abort due to duplication error
- */
- if (g_fSilentDupError)
- {
- if ((strcmp(pszFormat,
- "InitOutput - Duplicate invocation on display "
- "number: %s. Exiting.\n") == 0)
- || (strcmp(pszFormat,
- "Server is already active for display %s\n%s %s\n%s\n") == 0)
- || (strcmp(pszFormat,
- "MakeAllCOTSServerListeners: server already running\n") == 0))
- {
- g_fSilentFatalError = TRUE;
- }
- }
-
- /* Print the error message to a log file, could be stderr */
- LogVWrite (0, pszFormat, va_args);
-
-#if defined(XWIN_CLIPBOARD) || defined (XWIN_MULTIWINDOW)
- /* Unlock the printing mutex */
- pthread_mutex_unlock (&s_pmPrinting);
-#endif
-}
-#endif
-
-
-/*
- * os/util.c/FatalError () calls our vendor ErrorF, so the message
- * from a FatalError will be logged. Thus, the message for the
- * fatal error is not passed to this function.
- *
- * Attempt to do last-ditch, safe, important cleanup here.
- */
-void
-OsVendorFatalError (void)
-{
- /* Don't give duplicate warning if UseMsg was called */
- if (g_fSilentFatalError)
- return;
-
- if (!g_fLogInited) {
- g_fLogInited = TRUE;
- g_pszLogFile = LogInit (g_pszLogFile, NULL);
- }
- LogClose ();
-
- winMessageBoxF (
- "A fatal error has occurred and " PROJECT_NAME " will now exit.\n" \
- "Please open %s for more information.\n",
- MB_ICONERROR, (g_pszLogFile?g_pszLogFile:"the logfile"));
-}
-
-
-/*
- * winMessageBoxF - Print a formatted error message in a useful
- * message box.
- */
-
-void
-winMessageBoxF (const char *pszError, UINT uType, ...)
-{
- char * pszErrorF = NULL;
- char * pszMsgBox = NULL;
- va_list args;
-
- va_start(args, uType);
- pszErrorF = Xvprintf(pszError, args);
- va_end(args);
- if (!pszErrorF)
- goto winMessageBoxF_Cleanup;
-
-#define MESSAGEBOXF \
- "%s\n" \
- "Vendor: %s\n" \
- "Release: %d.%d.%d.%d (%d)\n" \
- "Contact: %s\n" \
- "%s\n\n" \
- "XWin was started with the following command-line:\n\n" \
- "%s\n"
-
- pszMsgBox = Xprintf (MESSAGEBOXF,
- pszErrorF, VENDOR_STRING,
- XORG_VERSION_MAJOR, XORG_VERSION_MINOR, XORG_VERSION_PATCH, XORG_VERSION_SNAP, XORG_VERSION_CURRENT,
- VENDOR_CONTACT,
- BUILDERSTRING,
- g_pszCommandLine);
- if (!pszMsgBox)
- goto winMessageBoxF_Cleanup;
-
- /* Display the message box string */
- MessageBox (NULL,
- pszMsgBox,
- PROJECT_NAME,
- MB_OK | uType);
-
- winMessageBoxF_Cleanup:
- if (pszErrorF)
- xfree (pszErrorF);
- if (pszMsgBox)
- xfree (pszMsgBox);
-#undef MESSAGEBOXF
-}
+/*
+ *Copyright (C) 2001-2004 Harold L Hunt II 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 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
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#ifdef XVENDORNAME
+#define VENDOR_STRING XVENDORNAME
+#define VENDOR_CONTACT BUILDERADDR
+#endif
+
+#include <../xfree86/common/xorgVersion.h>
+#include "win.h"
+
+/* References to external symbols */
+extern char * g_pszCommandLine;
+extern const char * g_pszLogFile;
+extern Bool g_fSilentFatalError;
+extern Bool g_fSilentDupError;
+extern Bool g_fLogInited;
+
+#ifdef DDXOSVERRORF
+/* Prototype */
+void
+OsVendorVErrorF (const char *pszFormat, va_list va_args);
+
+void
+OsVendorVErrorF (const char *pszFormat, va_list va_args)
+{
+#if defined(XWIN_CLIPBOARD) || defined (XWIN_MULTIWINDOW)
+ /* make sure the clipboard and multiwindow threads do not interfere the
+ * main thread */
+ static pthread_mutex_t s_pmPrinting = PTHREAD_MUTEX_INITIALIZER;
+
+ /* Lock the printing mutex */
+ pthread_mutex_lock (&s_pmPrinting);
+#endif
+
+ /*
+ If we want to silence it,
+ detect if we are going to abort due to duplication error
+ */
+ if (g_fSilentDupError)
+ {
+ if ((strcmp(pszFormat,
+ "InitOutput - Duplicate invocation on display "
+ "number: %s. Exiting.\n") == 0)
+ || (strcmp(pszFormat,
+ "Server is already active for display %s\n%s %s\n%s\n") == 0)
+ || (strcmp(pszFormat,
+ "MakeAllCOTSServerListeners: server already running\n") == 0))
+ {
+ g_fSilentFatalError = TRUE;
+ }
+ }
+
+ /* Print the error message to a log file, could be stderr */
+ LogVWrite (0, pszFormat, va_args);
+
+#if defined(XWIN_CLIPBOARD) || defined (XWIN_MULTIWINDOW)
+ /* Unlock the printing mutex */
+ pthread_mutex_unlock (&s_pmPrinting);
+#endif
+}
+#endif
+
+
+/*
+ * os/util.c/FatalError () calls our vendor ErrorF, so the message
+ * from a FatalError will be logged. Thus, the message for the
+ * fatal error is not passed to this function.
+ *
+ * Attempt to do last-ditch, safe, important cleanup here.
+ */
+void
+OsVendorFatalError (void)
+{
+ /* Don't give duplicate warning if UseMsg was called */
+ if (g_fSilentFatalError)
+ return;
+
+ if (!g_fLogInited) {
+ g_fLogInited = TRUE;
+ g_pszLogFile = LogInit (g_pszLogFile, NULL);
+ }
+ LogClose ();
+
+ winMessageBoxF (
+ "A fatal error has occurred and " PROJECT_NAME " will now exit.\n" \
+ "Please open %s for more information.\n",
+ MB_ICONERROR, (g_pszLogFile?g_pszLogFile:"the logfile"));
+}
+
+
+/*
+ * winMessageBoxF - Print a formatted error message in a useful
+ * message box.
+ */
+
+void
+winMessageBoxF (const char *pszError, UINT uType, ...)
+{
+ char * pszErrorF = NULL;
+ char * pszMsgBox = NULL;
+ va_list args;
+
+ va_start(args, uType);
+ pszErrorF = Xvprintf(pszError, args);
+ va_end(args);
+ if (!pszErrorF)
+ goto winMessageBoxF_Cleanup;
+
+#define MESSAGEBOXF \
+ "%s\n" \
+ "Vendor: %s\n" \
+ "Release: %d.%d.%d.%d (%d)\n" \
+ "Contact: %s\n" \
+ "%s\n\n" \
+ "XWin was started with the following command-line:\n\n" \
+ "%s\n"
+
+ pszMsgBox = Xprintf (MESSAGEBOXF,
+ pszErrorF, VENDOR_STRING,
+ XORG_VERSION_MAJOR, XORG_VERSION_MINOR, XORG_VERSION_PATCH, XORG_VERSION_SNAP, XORG_VERSION_CURRENT,
+ VENDOR_CONTACT,
+ BUILDERSTRING,
+ g_pszCommandLine);
+ if (!pszMsgBox)
+ goto winMessageBoxF_Cleanup;
+
+ /* Display the message box string */
+ MessageBox (NULL,
+ pszMsgBox,
+ PROJECT_NAME,
+ MB_OK | uType);
+
+ winMessageBoxF_Cleanup:
+ if (pszErrorF)
+ free(pszErrorF);
+ if (pszMsgBox)
+ free(pszMsgBox);
+#undef MESSAGEBOXF
+}
diff --git a/xorg-server/hw/xwin/winvideo.c b/xorg-server/hw/xwin/winvideo.c
index 529ca76d3..42f46f405 100644
--- a/xorg-server/hw/xwin/winvideo.c
+++ b/xorg-server/hw/xwin/winvideo.c
@@ -1,210 +1,210 @@
-/*
- *Copyright (C) 2003-2004 Harold L Hunt II 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 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
- */
-
-#ifdef HAVE_XWIN_CONFIG_H
-#include <xwin-config.h>
-#endif
-#include "win.h"
-#include <X11/extensions/Xv.h>
-#include <X11/extensions/Xvproto.h>
-
-void
-winInitVideo (ScreenPtr pScreen);
-
-/*
- * winInitVideo - Initialize support for the X Video (Xv) Extension.
- */
-
-void
-winInitVideo (ScreenPtr pScreen)
-{
- winScreenPriv(pScreen);
- winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
-
- if (pScreenInfo->dwBPP > 8)
- {
-
- }
-
-
-}
-
-
-
-
-
-
-
-#if 0
-#include "../xfree86/common/xf86.h"
-#include "../Xext/xvdix.h"
-#include "../xfree86/common/xf86xv.h"
-#include <X11/extensions/Xv.h>
-#endif
-
-#include "win.h"
-
-
-
-#if 0
-/* client libraries expect an encoding */
-static XF86VideoEncodingRec DummyEncoding[1] =
-{
- {
- 0,
- "XV_IMAGE",
- IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT,
- {1, 1}
- }
-};
-
-#define NUM_FORMATS 3
-
-static XF86VideoFormatRec Formats[NUM_FORMATS] =
-{
- {15, TrueColor}, {16, TrueColor}, {24, TrueColor}
-};
-
-#define NUM_ATTRIBUTES 3
-
-static XF86AttributeRec Attributes[NUM_ATTRIBUTES] =
-{
- {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"},
- {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"},
- {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"}
-};
-
-#define NUM_IMAGES 4
-
-static XF86ImageRec Images[NUM_IMAGES] =
-{
- XVIMAGE_YUY2,
- XVIMAGE_YV12,
- XVIMAGE_I420,
- XVIMAGE_UYVY
-};
-
-
-
-/*
- * winInitVideo - Initialize support for the X Video (Xv) Extension.
- */
-
-void
-winInitVideo (ScreenPtr pScreen)
-{
- winScreenPriv(pScreen);
- winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
- XF86VideoAdaptorPtr newAdaptor = NULL;
-
- if (pScreenInfo->dwBPP > 8)
- {
- newAdaptor = I810SetupImageVideo (pScreen);
- I810InitOffscreenImages (pScreen);
- }
-
- xf86XVScreenInit (pScreen, adaptors, 1);
-}
-
-
-static XF86VideoAdaptorPtr
-winSetupImageVideo (ScreenPtr pScreen)
-{
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
-#if 0
- I810Ptr pI810 = I810PTR(pScrn);
-#endif
- XF86VideoAdaptorPtr adapt;
-
- if (!(adapt = xcalloc (1, sizeof(XF86VideoAdaptorRec))))
- return NULL;
-
- adapt->type = XvWindowMask | XvInputMask | XvImageMask;
- adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
- adapt->name = PROJECT_NAME " Video Overlay";
- adapt->nEncodings = 1;
- adapt->pEncodings = DummyEncoding;
- adapt->nFormats = NUM_FORMATS;
- adapt->pFormats = Formats;
- adapt->nPorts = 1;
- adapt->pPortPrivates = NULL;
-
- adapt->pPortPrivates[0].ptr = NULL;
- adapt->pAttributes = Attributes;
- adapt->nImages = NUM_IMAGES;
- adapt->nAttributes = NUM_ATTRIBUTES;
- adapt->pImages = Images;
- adapt->PutVideo = NULL;
- adapt->PutStill = NULL;
- adapt->GetVideo = NULL;
- adapt->GetStill = NULL;
-#if 0
- adapt->StopVideo = I810StopVideo;
- adapt->SetPortAttribute = I810SetPortAttribute;
- adapt->GetPortAttribute = I810GetPortAttribute;
- adapt->QueryBestSize = I810QueryBestSize;
- adapt->PutImage = I810PutImage;
- adapt->QueryImageAttributes = I810QueryImageAttributes;
-#endif
-
-#if 0
- pPriv->colorKey = pI810->colorKey & ((1 << pScrn->depth) - 1);
-#endif
- pPriv->videoStatus = 0;
- pPriv->brightness = 0;
- pPriv->contrast = 64;
- pPriv->linear = NULL;
- pPriv->currentBuf = 0;
-
-#if 0
- /* gotta uninit this someplace */
- REGION_NULL(pScreen, &pPriv->clip);
-#endif
-
-#if 0
- pI810->adaptor = adapt;
-
- pI810->BlockHandler = pScreen->BlockHandler;
- pScreen->BlockHandler = I810BlockHandler;
-#endif
-
-#if 0
- xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
- xvContrast = MAKE_ATOM("XV_CONTRAST");
- xvColorKey = MAKE_ATOM("XV_COLORKEY");
-#endif
-
-#if 0
- I810ResetVideo(pScrn);
-#endif
-
- return adapt;
-}
-#endif
+/*
+ *Copyright (C) 2003-2004 Harold L Hunt II 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 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
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "win.h"
+#include <X11/extensions/Xv.h>
+#include <X11/extensions/Xvproto.h>
+
+void
+winInitVideo (ScreenPtr pScreen);
+
+/*
+ * winInitVideo - Initialize support for the X Video (Xv) Extension.
+ */
+
+void
+winInitVideo (ScreenPtr pScreen)
+{
+ winScreenPriv(pScreen);
+ winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+
+ if (pScreenInfo->dwBPP > 8)
+ {
+
+ }
+
+
+}
+
+
+
+
+
+
+
+#if 0
+#include "../xfree86/common/xf86.h"
+#include "../Xext/xvdix.h"
+#include "../xfree86/common/xf86xv.h"
+#include <X11/extensions/Xv.h>
+#endif
+
+#include "win.h"
+
+
+
+#if 0
+/* client libraries expect an encoding */
+static XF86VideoEncodingRec DummyEncoding[1] =
+{
+ {
+ 0,
+ "XV_IMAGE",
+ IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT,
+ {1, 1}
+ }
+};
+
+#define NUM_FORMATS 3
+
+static XF86VideoFormatRec Formats[NUM_FORMATS] =
+{
+ {15, TrueColor}, {16, TrueColor}, {24, TrueColor}
+};
+
+#define NUM_ATTRIBUTES 3
+
+static XF86AttributeRec Attributes[NUM_ATTRIBUTES] =
+{
+ {XvSettable | XvGettable, 0, (1 << 24) - 1, "XV_COLORKEY"},
+ {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"},
+ {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"}
+};
+
+#define NUM_IMAGES 4
+
+static XF86ImageRec Images[NUM_IMAGES] =
+{
+ XVIMAGE_YUY2,
+ XVIMAGE_YV12,
+ XVIMAGE_I420,
+ XVIMAGE_UYVY
+};
+
+
+
+/*
+ * winInitVideo - Initialize support for the X Video (Xv) Extension.
+ */
+
+void
+winInitVideo (ScreenPtr pScreen)
+{
+ winScreenPriv(pScreen);
+ winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+ XF86VideoAdaptorPtr newAdaptor = NULL;
+
+ if (pScreenInfo->dwBPP > 8)
+ {
+ newAdaptor = I810SetupImageVideo (pScreen);
+ I810InitOffscreenImages (pScreen);
+ }
+
+ xf86XVScreenInit (pScreen, adaptors, 1);
+}
+
+
+static XF86VideoAdaptorPtr
+winSetupImageVideo (ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+#if 0
+ I810Ptr pI810 = I810PTR(pScrn);
+#endif
+ XF86VideoAdaptorPtr adapt;
+
+ if (!(adapt = calloc(1, sizeof(XF86VideoAdaptorRec))))
+ return NULL;
+
+ adapt->type = XvWindowMask | XvInputMask | XvImageMask;
+ adapt->flags = VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
+ adapt->name = PROJECT_NAME " Video Overlay";
+ adapt->nEncodings = 1;
+ adapt->pEncodings = DummyEncoding;
+ adapt->nFormats = NUM_FORMATS;
+ adapt->pFormats = Formats;
+ adapt->nPorts = 1;
+ adapt->pPortPrivates = NULL;
+
+ adapt->pPortPrivates[0].ptr = NULL;
+ adapt->pAttributes = Attributes;
+ adapt->nImages = NUM_IMAGES;
+ adapt->nAttributes = NUM_ATTRIBUTES;
+ adapt->pImages = Images;
+ adapt->PutVideo = NULL;
+ adapt->PutStill = NULL;
+ adapt->GetVideo = NULL;
+ adapt->GetStill = NULL;
+#if 0
+ adapt->StopVideo = I810StopVideo;
+ adapt->SetPortAttribute = I810SetPortAttribute;
+ adapt->GetPortAttribute = I810GetPortAttribute;
+ adapt->QueryBestSize = I810QueryBestSize;
+ adapt->PutImage = I810PutImage;
+ adapt->QueryImageAttributes = I810QueryImageAttributes;
+#endif
+
+#if 0
+ pPriv->colorKey = pI810->colorKey & ((1 << pScrn->depth) - 1);
+#endif
+ pPriv->videoStatus = 0;
+ pPriv->brightness = 0;
+ pPriv->contrast = 64;
+ pPriv->linear = NULL;
+ pPriv->currentBuf = 0;
+
+#if 0
+ /* gotta uninit this someplace */
+ REGION_NULL(pScreen, &pPriv->clip);
+#endif
+
+#if 0
+ pI810->adaptor = adapt;
+
+ pI810->BlockHandler = pScreen->BlockHandler;
+ pScreen->BlockHandler = I810BlockHandler;
+#endif
+
+#if 0
+ xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
+ xvContrast = MAKE_ATOM("XV_CONTRAST");
+ xvColorKey = MAKE_ATOM("XV_COLORKEY");
+#endif
+
+#if 0
+ I810ResetVideo(pScrn);
+#endif
+
+ return adapt;
+}
+#endif
diff --git a/xorg-server/hw/xwin/winwindow.c b/xorg-server/hw/xwin/winwindow.c
index 6f22a5a6e..8156671cd 100644
--- a/xorg-server/hw/xwin/winwindow.c
+++ b/xorg-server/hw/xwin/winwindow.c
@@ -1,593 +1,593 @@
-/*
- *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: Harold L Hunt II
- * Kensuke Matsuzaki
- */
-
-#ifdef HAVE_XWIN_CONFIG_H
-#include <xwin-config.h>
-#endif
-#include "win.h"
-
-
-/*
- * Prototypes for local functions
- */
-
-static int
-winAddRgn (WindowPtr pWindow, pointer data);
-
-static
-void
-winUpdateRgnRootless (WindowPtr pWindow);
-
-static
-void
-winReshapeRootless (WindowPtr pWin);
-
-
-#ifdef XWIN_NATIVEGDI
-/* See Porting Layer Definition - p. 37 */
-/* See mfb/mfbwindow.c - mfbCreateWindow() */
-
-Bool
-winCreateWindowNativeGDI (WindowPtr pWin)
-{
- Bool fResult;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winWindowPriv(pWin);
- winScreenPriv(pScreen);
-
- winDebug ("winCreateWindowNativeGDI (%p)\n", pWin);
-
- WIN_UNWRAP(CreateWindow);
- fResult = (*pScreen->CreateWindow) (pWin);
- WIN_WRAP(CreateWindow, winCreateWindowNativeGDI);
-
- return fResult;
-}
-
-
-/* See Porting Layer Definition - p. 37 */
-/* See mfb/mfbwindow.c - mfbDestroyWindow() */
-
-Bool
-winDestroyWindowNativeGDI (WindowPtr pWin)
-{
- Bool fResult = TRUE;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winWindowPriv(pWin);
- winScreenPriv(pScreen);
-
- winDebug ("winDestroyWindowNativeGDI (%p)\n", pWin);
-
- WIN_UNWRAP(DestroyWindow);
- fResult = (*pScreen->DestroyWindow)(pWin);
- WIN_WRAP(DestroyWindow, winDestroyWindowNativeGDI);
-
- return fResult;
-}
-
-
-/* See Porting Layer Definition - p. 37 */
-/* See mfb/mfbwindow.c - mfbPositionWindow() */
-
-Bool
-winPositionWindowNativeGDI (WindowPtr pWin, int x, int y)
-{
- Bool fResult = TRUE;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winWindowPriv(pWin);
- winScreenPriv(pScreen);
-
- winDebug ("winPositionWindowNativeGDI (%p)\n", pWin);
-
- WIN_UNWRAP(PositionWindow);
- fResult = (*pScreen->PositionWindow)(pWin, x, y);
- WIN_WRAP(PositionWindow, winPositionWindowNativeGDI);
-
- return fResult;
-}
-
-
-/* See Porting Layer Definition - p. 39 */
-/* See mfb/mfbwindow.c - mfbCopyWindow() */
-
-void
-winCopyWindowNativeGDI (WindowPtr pWin,
- DDXPointRec ptOldOrg,
- RegionPtr prgnSrc)
-{
- DDXPointPtr pptSrc;
- DDXPointPtr ppt;
- RegionPtr prgnDst;
- BoxPtr pBox;
- int dx, dy;
- int i, nbox;
- WindowPtr pwinRoot;
- BoxPtr pBoxDst;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winScreenPriv(pScreen);
-
- /* Get a pointer to the root window */
- pwinRoot = WindowTable[pWin->drawable.pScreen->myNum];
-
- /* Create a region for the destination */
- prgnDst = REGION_CREATE(pWin->drawable.pScreen, NULL, 1);
-
- /* Calculate the shift from the source to the destination */
- dx = ptOldOrg.x - pWin->drawable.x;
- dy = ptOldOrg.y - pWin->drawable.y;
-
- /* Translate the region from the destination to the source? */
- REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy);
- REGION_INTERSECT(pWin->drawable.pScreen, prgnDst, &pWin->borderClip,
- prgnSrc);
-
- /* Get a pointer to the first box in the region to be copied */
- pBox = REGION_RECTS(prgnDst);
-
- /* Get the number of boxes in the region */
- nbox = REGION_NUM_RECTS(prgnDst);
-
- /* Allocate source points for each box */
- if(!(pptSrc = (DDXPointPtr )xalloc(nbox * sizeof(DDXPointRec))))
- return;
-
- /* Set an iterator pointer */
- ppt = pptSrc;
-
- /* Calculate the source point of each box? */
- for (i = nbox; --i >= 0; ppt++, pBox++)
- {
- ppt->x = pBox->x1 + dx;
- ppt->y = pBox->y1 + dy;
- }
-
- /* Setup loop pointers again */
- pBoxDst = REGION_RECTS(prgnDst);
- ppt = pptSrc;
-
- /* BitBlt each source to the destination point */
- for (i = nbox; --i >= 0; pBoxDst++, ppt++)
- {
- BitBlt (pScreenPriv->hdcScreen,
- pBoxDst->x1, pBoxDst->y1,
- pBoxDst->x2 - pBoxDst->x1, pBoxDst->y2 - pBoxDst->y1,
- pScreenPriv->hdcScreen,
- ppt->x, ppt->y,
- SRCCOPY);
- }
-
- /* Cleanup the regions, etc. */
- xfree(pptSrc);
- REGION_DESTROY(pWin->drawable.pScreen, prgnDst);
-}
-
-
-/* See Porting Layer Definition - p. 37 */
-/* See mfb/mfbwindow.c - mfbChangeWindowAttributes() */
-
-Bool
-winChangeWindowAttributesNativeGDI (WindowPtr pWin, unsigned long mask)
-{
- Bool fResult = TRUE;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winWindowPriv(pWin);
- winScreenPriv(pScreen);
-
- winDebug ("winChangeWindowAttributesNativeGDI (%p)\n", pWin);
-
- WIN_UNWRAP(ChangeWindowAttributes);
- fResult = (*pScreen->ChangeWindowAttributes)(pWin, mask);
- WIN_WRAP(ChangeWindowAttributes, winChangeWindowAttributesNativeGDI);
-
- /*
- * NOTE: We do not currently need to do anything here.
- */
-
- return fResult;
-}
-
-
-/* See Porting Layer Definition - p. 37
- * Also referred to as UnrealizeWindow
- */
-
-Bool
-winUnmapWindowNativeGDI (WindowPtr pWin)
-{
- Bool fResult = TRUE;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winWindowPriv(pWin);
- winScreenPriv(pScreen);
-
- winDebug ("winUnmapWindowNativeGDI (%p)\n", pWin);
-
- WIN_UNWRAP(UnrealizeWindow);
- fResult = (*pScreen->UnrealizeWindow)(pWin);
- WIN_WRAP(UnrealizeWindow, winUnmapWindowNativeGDI);
-
- return fResult;
-}
-
-
-/* See Porting Layer Definition - p. 37
- * Also referred to as RealizeWindow
- */
-
-Bool
-winMapWindowNativeGDI (WindowPtr pWin)
-{
- Bool fResult = TRUE;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winWindowPriv(pWin);
- winScreenPriv(pScreen);
-
- winDebug ("winMapWindowNativeGDI (%p)\n", pWin);
-
- WIN_UNWRAP(RealizeWindow);
- fResult = (*pScreen->RealizeWindow)(pWin);
- WIN_WRAP(RealizeWindow, winMapWindowMultiWindow);
-
- return fResult;
-
-}
-#endif
-
-
-/* See Porting Layer Definition - p. 37 */
-/* See mfb/mfbwindow.c - mfbCreateWindow() */
-
-Bool
-winCreateWindowRootless (WindowPtr pWin)
-{
- Bool fResult = FALSE;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winWindowPriv(pWin);
- winScreenPriv(pScreen);
-
- winDebug ("winCreateWindowRootless (%p)\n", pWin);
-
- WIN_UNWRAP(CreateWindow);
- fResult = (*pScreen->CreateWindow) (pWin);
- WIN_WRAP(CreateWindow, winCreateWindowRootless);
-
- pWinPriv->hRgn = NULL;
-
- return fResult;
-}
-
-
-/* See Porting Layer Definition - p. 37 */
-/* See mfb/mfbwindow.c - mfbDestroyWindow() */
-
-Bool
-winDestroyWindowRootless (WindowPtr pWin)
-{
- Bool fResult = FALSE;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winWindowPriv(pWin);
- winScreenPriv(pScreen);
-
- winDebug ("winDestroyWindowRootless (%p)\n", pWin);
-
- WIN_UNWRAP(DestroyWindow);
- fResult = (*pScreen->DestroyWindow)(pWin);
- WIN_WRAP(DestroyWindow, winDestroyWindowRootless);
-
- if (pWinPriv->hRgn != NULL)
- {
- DeleteObject(pWinPriv->hRgn);
- pWinPriv->hRgn = NULL;
- }
-
- winUpdateRgnRootless (pWin);
-
- return fResult;
-}
-
-
-/* See Porting Layer Definition - p. 37 */
-/* See mfb/mfbwindow.c - mfbPositionWindow() */
-
-Bool
-winPositionWindowRootless (WindowPtr pWin, int x, int y)
-{
- Bool fResult = FALSE;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winScreenPriv(pScreen);
-
- winDebug ("winPositionWindowRootless (%p)\n", pWin);
-
- WIN_UNWRAP(PositionWindow);
- fResult = (*pScreen->PositionWindow)(pWin, x, y);
- WIN_WRAP(PositionWindow, winPositionWindowRootless);
-
- winUpdateRgnRootless (pWin);
-
- return fResult;
-}
-
-
-/* See Porting Layer Definition - p. 37 */
-/* See mfb/mfbwindow.c - mfbChangeWindowAttributes() */
-
-Bool
-winChangeWindowAttributesRootless (WindowPtr pWin, unsigned long mask)
-{
- Bool fResult = FALSE;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winScreenPriv(pScreen);
-
- winDebug ("winChangeWindowAttributesRootless (%p)\n", pWin);
-
- WIN_UNWRAP(ChangeWindowAttributes);
- fResult = (*pScreen->ChangeWindowAttributes)(pWin, mask);
- WIN_WRAP(ChangeWindowAttributes, winChangeWindowAttributesRootless);
-
- winUpdateRgnRootless (pWin);
-
- return fResult;
-}
-
-
-/* See Porting Layer Definition - p. 37
- * Also referred to as UnrealizeWindow
- */
-
-Bool
-winUnmapWindowRootless (WindowPtr pWin)
-{
- Bool fResult = FALSE;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winWindowPriv(pWin);
- winScreenPriv(pScreen);
-
- winDebug ("winUnmapWindowRootless (%p)\n", pWin);
-
- WIN_UNWRAP(UnrealizeWindow);
- fResult = (*pScreen->UnrealizeWindow)(pWin);
- WIN_WRAP(UnrealizeWindow, winUnmapWindowRootless);
-
- if (pWinPriv->hRgn != NULL)
- {
- DeleteObject(pWinPriv->hRgn);
- pWinPriv->hRgn = NULL;
- }
-
- winUpdateRgnRootless (pWin);
-
- return fResult;
-}
-
-
-/* See Porting Layer Definition - p. 37
- * Also referred to as RealizeWindow
- */
-
-Bool
-winMapWindowRootless (WindowPtr pWin)
-{
- Bool fResult = FALSE;
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winScreenPriv(pScreen);
-
- winDebug ("winMapWindowRootless (%p)\n", pWin);
-
- WIN_UNWRAP(RealizeWindow);
- fResult = (*pScreen->RealizeWindow)(pWin);
- WIN_WRAP(RealizeWindow, winMapWindowRootless);
-
- winReshapeRootless (pWin);
-
- winUpdateRgnRootless (pWin);
-
- return fResult;
-}
-
-
-void
-winSetShapeRootless (WindowPtr pWin)
-{
- ScreenPtr pScreen = pWin->drawable.pScreen;
- winScreenPriv(pScreen);
-
- winDebug ("winSetShapeRootless (%p)\n", pWin);
-
- WIN_UNWRAP(SetShape);
- (*pScreen->SetShape)(pWin);
- WIN_WRAP(SetShape, winSetShapeRootless);
-
- winReshapeRootless (pWin);
- winUpdateRgnRootless (pWin);
-
- return;
-}
-
-
-/*
- * Local function for adding a region to the Windows window region
- */
-
-static
-int
-winAddRgn (WindowPtr pWin, pointer data)
-{
- int iX, iY, iWidth, iHeight, iBorder;
- HRGN hRgn = *(HRGN*)data;
- HRGN hRgnWin;
- winWindowPriv(pWin);
-
- /* If pWin is not Root */
- if (pWin->parent != NULL)
- {
- winDebug ("winAddRgn ()\n");
- if (pWin->mapped)
- {
- iBorder = wBorderWidth (pWin);
-
- iX = pWin->drawable.x - iBorder;
- iY = pWin->drawable.y - iBorder;
-
- iWidth = pWin->drawable.width + iBorder * 2;
- iHeight = pWin->drawable.height + iBorder * 2;
-
- hRgnWin = CreateRectRgn (0, 0, iWidth, iHeight);
-
- if (hRgnWin == NULL)
- {
- winDebug ("winAddRgn - CreateRectRgn () failed\n");
- winDebug (" Rect %d %d %d %d\n",
- iX, iY, iX + iWidth, iY + iHeight);
- }
-
- if (pWinPriv->hRgn)
- {
- if (CombineRgn (hRgnWin, hRgnWin, pWinPriv->hRgn, RGN_AND)
- == ERROR)
- {
- ErrorF ("winAddRgn - CombineRgn () failed\n");
- }
- }
-
- OffsetRgn (hRgnWin, iX, iY);
-
- if (CombineRgn (hRgn, hRgn, hRgnWin, RGN_OR) == ERROR)
- {
- ErrorF ("winAddRgn - CombineRgn () failed\n");
- }
-
- DeleteObject (hRgnWin);
- }
- return WT_DONTWALKCHILDREN;
- }
- else
- {
- return WT_WALKCHILDREN;
- }
-}
-
-
-/*
- * Local function to update the Windows window's region
- */
-
-static
-void
-winUpdateRgnRootless (WindowPtr pWin)
-{
- HRGN hRgn = CreateRectRgn (0, 0, 0, 0);
-
- if (hRgn != NULL)
- {
- WalkTree (pWin->drawable.pScreen, winAddRgn, &hRgn);
- SetWindowRgn (winGetScreenPriv(pWin->drawable.pScreen)->hwndScreen,
- hRgn, TRUE);
- }
- else
- {
- ErrorF ("winUpdateRgnRootless - CreateRectRgn failed.\n");
- }
-}
-
-
-static
-void
-winReshapeRootless (WindowPtr pWin)
-{
- int nRects;
- /* ScreenPtr pScreen = pWin->drawable.pScreen;*/
- RegionRec rrNewShape;
- BoxPtr pShape, pRects, pEnd;
- HRGN hRgn, hRgnRect;
- winWindowPriv(pWin);
-
- winDebug ("winReshapeRootless ()\n");
-
- /* Bail if the window is the root window */
- if (pWin->parent == NULL)
- return;
-
- /* Bail if the window is not top level */
- if (pWin->parent->parent != NULL)
- return;
-
- /* Free any existing window region stored in the window privates */
- if (pWinPriv->hRgn != NULL)
- {
- DeleteObject (pWinPriv->hRgn);
- pWinPriv->hRgn = NULL;
- }
-
- /* Bail if the window has no bounding region defined */
- if (!wBoundingShape (pWin))
- return;
-
- REGION_NULL(pScreen, &rrNewShape);
- REGION_COPY(pScreen, &rrNewShape, wBoundingShape(pWin));
- REGION_TRANSLATE(pScreen, &rrNewShape, pWin->borderWidth,
- pWin->borderWidth);
-
- nRects = REGION_NUM_RECTS(&rrNewShape);
- pShape = REGION_RECTS(&rrNewShape);
-
- if (nRects > 0)
- {
- /* Create initial empty Windows region */
- hRgn = CreateRectRgn (0, 0, 0, 0);
-
- /* Loop through all rectangles in the X region */
- for (pRects = pShape, pEnd = pShape + nRects; pRects < pEnd; pRects++)
- {
- /* Create a Windows region for the X rectangle */
- hRgnRect = CreateRectRgn (pRects->x1, pRects->y1,
- pRects->x2, pRects->y2);
- if (hRgnRect == NULL)
- {
- ErrorF("winReshapeRootless - CreateRectRgn() failed\n");
- }
-
- /* Merge the Windows region with the accumulated region */
- if (CombineRgn (hRgn, hRgn, hRgnRect, RGN_OR) == ERROR)
- {
- ErrorF("winReshapeRootless - CombineRgn() failed\n");
- }
-
- /* Delete the temporary Windows region */
- DeleteObject (hRgnRect);
- }
-
- /* Save a handle to the composite region in the window privates */
- pWinPriv->hRgn = hRgn;
- }
-
- REGION_UNINIT(pScreen, &rrNewShape);
-
- return;
-}
+/*
+ *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: Harold L Hunt II
+ * Kensuke Matsuzaki
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "win.h"
+
+
+/*
+ * Prototypes for local functions
+ */
+
+static int
+winAddRgn (WindowPtr pWindow, pointer data);
+
+static
+void
+winUpdateRgnRootless (WindowPtr pWindow);
+
+static
+void
+winReshapeRootless (WindowPtr pWin);
+
+
+#ifdef XWIN_NATIVEGDI
+/* See Porting Layer Definition - p. 37 */
+/* See mfb/mfbwindow.c - mfbCreateWindow() */
+
+Bool
+winCreateWindowNativeGDI (WindowPtr pWin)
+{
+ Bool fResult;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ winWindowPriv(pWin);
+ winScreenPriv(pScreen);
+
+ winDebug ("winCreateWindowNativeGDI (%p)\n", pWin);
+
+ WIN_UNWRAP(CreateWindow);
+ fResult = (*pScreen->CreateWindow) (pWin);
+ WIN_WRAP(CreateWindow, winCreateWindowNativeGDI);
+
+ return fResult;
+}
+
+
+/* See Porting Layer Definition - p. 37 */
+/* See mfb/mfbwindow.c - mfbDestroyWindow() */
+
+Bool
+winDestroyWindowNativeGDI (WindowPtr pWin)
+{
+ Bool fResult = TRUE;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ winWindowPriv(pWin);
+ winScreenPriv(pScreen);
+
+ winDebug ("winDestroyWindowNativeGDI (%p)\n", pWin);
+
+ WIN_UNWRAP(DestroyWindow);
+ fResult = (*pScreen->DestroyWindow)(pWin);
+ WIN_WRAP(DestroyWindow, winDestroyWindowNativeGDI);
+
+ return fResult;
+}
+
+
+/* See Porting Layer Definition - p. 37 */
+/* See mfb/mfbwindow.c - mfbPositionWindow() */
+
+Bool
+winPositionWindowNativeGDI (WindowPtr pWin, int x, int y)
+{
+ Bool fResult = TRUE;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ winWindowPriv(pWin);
+ winScreenPriv(pScreen);
+
+ winDebug ("winPositionWindowNativeGDI (%p)\n", pWin);
+
+ WIN_UNWRAP(PositionWindow);
+ fResult = (*pScreen->PositionWindow)(pWin, x, y);
+ WIN_WRAP(PositionWindow, winPositionWindowNativeGDI);
+
+ return fResult;
+}
+
+
+/* See Porting Layer Definition - p. 39 */
+/* See mfb/mfbwindow.c - mfbCopyWindow() */
+
+void
+winCopyWindowNativeGDI (WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc)
+{
+ DDXPointPtr pptSrc;
+ DDXPointPtr ppt;
+ RegionPtr prgnDst;
+ BoxPtr pBox;
+ int dx, dy;
+ int i, nbox;
+ WindowPtr pwinRoot;
+ BoxPtr pBoxDst;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ winScreenPriv(pScreen);
+
+ /* Get a pointer to the root window */
+ pwinRoot = WindowTable[pWin->drawable.pScreen->myNum];
+
+ /* Create a region for the destination */
+ prgnDst = REGION_CREATE(pWin->drawable.pScreen, NULL, 1);
+
+ /* Calculate the shift from the source to the destination */
+ dx = ptOldOrg.x - pWin->drawable.x;
+ dy = ptOldOrg.y - pWin->drawable.y;
+
+ /* Translate the region from the destination to the source? */
+ REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy);
+ REGION_INTERSECT(pWin->drawable.pScreen, prgnDst, &pWin->borderClip,
+ prgnSrc);
+
+ /* Get a pointer to the first box in the region to be copied */
+ pBox = REGION_RECTS(prgnDst);
+
+ /* Get the number of boxes in the region */
+ nbox = REGION_NUM_RECTS(prgnDst);
+
+ /* Allocate source points for each box */
+ if(!(pptSrc = (DDXPointPtr )malloc(nbox * sizeof(DDXPointRec))))
+ return;
+
+ /* Set an iterator pointer */
+ ppt = pptSrc;
+
+ /* Calculate the source point of each box? */
+ for (i = nbox; --i >= 0; ppt++, pBox++)
+ {
+ ppt->x = pBox->x1 + dx;
+ ppt->y = pBox->y1 + dy;
+ }
+
+ /* Setup loop pointers again */
+ pBoxDst = REGION_RECTS(prgnDst);
+ ppt = pptSrc;
+
+ /* BitBlt each source to the destination point */
+ for (i = nbox; --i >= 0; pBoxDst++, ppt++)
+ {
+ BitBlt (pScreenPriv->hdcScreen,
+ pBoxDst->x1, pBoxDst->y1,
+ pBoxDst->x2 - pBoxDst->x1, pBoxDst->y2 - pBoxDst->y1,
+ pScreenPriv->hdcScreen,
+ ppt->x, ppt->y,
+ SRCCOPY);
+ }
+
+ /* Cleanup the regions, etc. */
+ free(pptSrc);
+ REGION_DESTROY(pWin->drawable.pScreen, prgnDst);
+}
+
+
+/* See Porting Layer Definition - p. 37 */
+/* See mfb/mfbwindow.c - mfbChangeWindowAttributes() */
+
+Bool
+winChangeWindowAttributesNativeGDI (WindowPtr pWin, unsigned long mask)
+{
+ Bool fResult = TRUE;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ winWindowPriv(pWin);
+ winScreenPriv(pScreen);
+
+ winDebug ("winChangeWindowAttributesNativeGDI (%p)\n", pWin);
+
+ WIN_UNWRAP(ChangeWindowAttributes);
+ fResult = (*pScreen->ChangeWindowAttributes)(pWin, mask);
+ WIN_WRAP(ChangeWindowAttributes, winChangeWindowAttributesNativeGDI);
+
+ /*
+ * NOTE: We do not currently need to do anything here.
+ */
+
+ return fResult;
+}
+
+
+/* See Porting Layer Definition - p. 37
+ * Also referred to as UnrealizeWindow
+ */
+
+Bool
+winUnmapWindowNativeGDI (WindowPtr pWin)
+{
+ Bool fResult = TRUE;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ winWindowPriv(pWin);
+ winScreenPriv(pScreen);
+
+ winDebug ("winUnmapWindowNativeGDI (%p)\n", pWin);
+
+ WIN_UNWRAP(UnrealizeWindow);
+ fResult = (*pScreen->UnrealizeWindow)(pWin);
+ WIN_WRAP(UnrealizeWindow, winUnmapWindowNativeGDI);
+
+ return fResult;
+}
+
+
+/* See Porting Layer Definition - p. 37
+ * Also referred to as RealizeWindow
+ */
+
+Bool
+winMapWindowNativeGDI (WindowPtr pWin)
+{
+ Bool fResult = TRUE;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ winWindowPriv(pWin);
+ winScreenPriv(pScreen);
+
+ winDebug ("winMapWindowNativeGDI (%p)\n", pWin);
+
+ WIN_UNWRAP(RealizeWindow);
+ fResult = (*pScreen->RealizeWindow)(pWin);
+ WIN_WRAP(RealizeWindow, winMapWindowMultiWindow);
+
+ return fResult;
+
+}
+#endif
+
+
+/* See Porting Layer Definition - p. 37 */
+/* See mfb/mfbwindow.c - mfbCreateWindow() */
+
+Bool
+winCreateWindowRootless (WindowPtr pWin)
+{
+ Bool fResult = FALSE;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ winWindowPriv(pWin);
+ winScreenPriv(pScreen);
+
+ winDebug ("winCreateWindowRootless (%p)\n", pWin);
+
+ WIN_UNWRAP(CreateWindow);
+ fResult = (*pScreen->CreateWindow) (pWin);
+ WIN_WRAP(CreateWindow, winCreateWindowRootless);
+
+ pWinPriv->hRgn = NULL;
+
+ return fResult;
+}
+
+
+/* See Porting Layer Definition - p. 37 */
+/* See mfb/mfbwindow.c - mfbDestroyWindow() */
+
+Bool
+winDestroyWindowRootless (WindowPtr pWin)
+{
+ Bool fResult = FALSE;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ winWindowPriv(pWin);
+ winScreenPriv(pScreen);
+
+ winDebug ("winDestroyWindowRootless (%p)\n", pWin);
+
+ WIN_UNWRAP(DestroyWindow);
+ fResult = (*pScreen->DestroyWindow)(pWin);
+ WIN_WRAP(DestroyWindow, winDestroyWindowRootless);
+
+ if (pWinPriv->hRgn != NULL)
+ {
+ DeleteObject(pWinPriv->hRgn);
+ pWinPriv->hRgn = NULL;
+ }
+
+ winUpdateRgnRootless (pWin);
+
+ return fResult;
+}
+
+
+/* See Porting Layer Definition - p. 37 */
+/* See mfb/mfbwindow.c - mfbPositionWindow() */
+
+Bool
+winPositionWindowRootless (WindowPtr pWin, int x, int y)
+{
+ Bool fResult = FALSE;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ winScreenPriv(pScreen);
+
+ winDebug ("winPositionWindowRootless (%p)\n", pWin);
+
+ WIN_UNWRAP(PositionWindow);
+ fResult = (*pScreen->PositionWindow)(pWin, x, y);
+ WIN_WRAP(PositionWindow, winPositionWindowRootless);
+
+ winUpdateRgnRootless (pWin);
+
+ return fResult;
+}
+
+
+/* See Porting Layer Definition - p. 37 */
+/* See mfb/mfbwindow.c - mfbChangeWindowAttributes() */
+
+Bool
+winChangeWindowAttributesRootless (WindowPtr pWin, unsigned long mask)
+{
+ Bool fResult = FALSE;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ winScreenPriv(pScreen);
+
+ winDebug ("winChangeWindowAttributesRootless (%p)\n", pWin);
+
+ WIN_UNWRAP(ChangeWindowAttributes);
+ fResult = (*pScreen->ChangeWindowAttributes)(pWin, mask);
+ WIN_WRAP(ChangeWindowAttributes, winChangeWindowAttributesRootless);
+
+ winUpdateRgnRootless (pWin);
+
+ return fResult;
+}
+
+
+/* See Porting Layer Definition - p. 37
+ * Also referred to as UnrealizeWindow
+ */
+
+Bool
+winUnmapWindowRootless (WindowPtr pWin)
+{
+ Bool fResult = FALSE;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ winWindowPriv(pWin);
+ winScreenPriv(pScreen);
+
+ winDebug ("winUnmapWindowRootless (%p)\n", pWin);
+
+ WIN_UNWRAP(UnrealizeWindow);
+ fResult = (*pScreen->UnrealizeWindow)(pWin);
+ WIN_WRAP(UnrealizeWindow, winUnmapWindowRootless);
+
+ if (pWinPriv->hRgn != NULL)
+ {
+ DeleteObject(pWinPriv->hRgn);
+ pWinPriv->hRgn = NULL;
+ }
+
+ winUpdateRgnRootless (pWin);
+
+ return fResult;
+}
+
+
+/* See Porting Layer Definition - p. 37
+ * Also referred to as RealizeWindow
+ */
+
+Bool
+winMapWindowRootless (WindowPtr pWin)
+{
+ Bool fResult = FALSE;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ winScreenPriv(pScreen);
+
+ winDebug ("winMapWindowRootless (%p)\n", pWin);
+
+ WIN_UNWRAP(RealizeWindow);
+ fResult = (*pScreen->RealizeWindow)(pWin);
+ WIN_WRAP(RealizeWindow, winMapWindowRootless);
+
+ winReshapeRootless (pWin);
+
+ winUpdateRgnRootless (pWin);
+
+ return fResult;
+}
+
+
+void
+winSetShapeRootless (WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ winScreenPriv(pScreen);
+
+ winDebug ("winSetShapeRootless (%p)\n", pWin);
+
+ WIN_UNWRAP(SetShape);
+ (*pScreen->SetShape)(pWin);
+ WIN_WRAP(SetShape, winSetShapeRootless);
+
+ winReshapeRootless (pWin);
+ winUpdateRgnRootless (pWin);
+
+ return;
+}
+
+
+/*
+ * Local function for adding a region to the Windows window region
+ */
+
+static
+int
+winAddRgn (WindowPtr pWin, pointer data)
+{
+ int iX, iY, iWidth, iHeight, iBorder;
+ HRGN hRgn = *(HRGN*)data;
+ HRGN hRgnWin;
+ winWindowPriv(pWin);
+
+ /* If pWin is not Root */
+ if (pWin->parent != NULL)
+ {
+ winDebug ("winAddRgn ()\n");
+ if (pWin->mapped)
+ {
+ iBorder = wBorderWidth (pWin);
+
+ iX = pWin->drawable.x - iBorder;
+ iY = pWin->drawable.y - iBorder;
+
+ iWidth = pWin->drawable.width + iBorder * 2;
+ iHeight = pWin->drawable.height + iBorder * 2;
+
+ hRgnWin = CreateRectRgn (0, 0, iWidth, iHeight);
+
+ if (hRgnWin == NULL)
+ {
+ winDebug ("winAddRgn - CreateRectRgn () failed\n");
+ winDebug (" Rect %d %d %d %d\n",
+ iX, iY, iX + iWidth, iY + iHeight);
+ }
+
+ if (pWinPriv->hRgn)
+ {
+ if (CombineRgn (hRgnWin, hRgnWin, pWinPriv->hRgn, RGN_AND)
+ == ERROR)
+ {
+ ErrorF ("winAddRgn - CombineRgn () failed\n");
+ }
+ }
+
+ OffsetRgn (hRgnWin, iX, iY);
+
+ if (CombineRgn (hRgn, hRgn, hRgnWin, RGN_OR) == ERROR)
+ {
+ ErrorF ("winAddRgn - CombineRgn () failed\n");
+ }
+
+ DeleteObject (hRgnWin);
+ }
+ return WT_DONTWALKCHILDREN;
+ }
+ else
+ {
+ return WT_WALKCHILDREN;
+ }
+}
+
+
+/*
+ * Local function to update the Windows window's region
+ */
+
+static
+void
+winUpdateRgnRootless (WindowPtr pWin)
+{
+ HRGN hRgn = CreateRectRgn (0, 0, 0, 0);
+
+ if (hRgn != NULL)
+ {
+ WalkTree (pWin->drawable.pScreen, winAddRgn, &hRgn);
+ SetWindowRgn (winGetScreenPriv(pWin->drawable.pScreen)->hwndScreen,
+ hRgn, TRUE);
+ }
+ else
+ {
+ ErrorF ("winUpdateRgnRootless - CreateRectRgn failed.\n");
+ }
+}
+
+
+static
+void
+winReshapeRootless (WindowPtr pWin)
+{
+ int nRects;
+ /* ScreenPtr pScreen = pWin->drawable.pScreen;*/
+ RegionRec rrNewShape;
+ BoxPtr pShape, pRects, pEnd;
+ HRGN hRgn, hRgnRect;
+ winWindowPriv(pWin);
+
+ winDebug ("winReshapeRootless ()\n");
+
+ /* Bail if the window is the root window */
+ if (pWin->parent == NULL)
+ return;
+
+ /* Bail if the window is not top level */
+ if (pWin->parent->parent != NULL)
+ return;
+
+ /* Free any existing window region stored in the window privates */
+ if (pWinPriv->hRgn != NULL)
+ {
+ DeleteObject (pWinPriv->hRgn);
+ pWinPriv->hRgn = NULL;
+ }
+
+ /* Bail if the window has no bounding region defined */
+ if (!wBoundingShape (pWin))
+ return;
+
+ REGION_NULL(pScreen, &rrNewShape);
+ REGION_COPY(pScreen, &rrNewShape, wBoundingShape(pWin));
+ REGION_TRANSLATE(pScreen, &rrNewShape, pWin->borderWidth,
+ pWin->borderWidth);
+
+ nRects = REGION_NUM_RECTS(&rrNewShape);
+ pShape = REGION_RECTS(&rrNewShape);
+
+ if (nRects > 0)
+ {
+ /* Create initial empty Windows region */
+ hRgn = CreateRectRgn (0, 0, 0, 0);
+
+ /* Loop through all rectangles in the X region */
+ for (pRects = pShape, pEnd = pShape + nRects; pRects < pEnd; pRects++)
+ {
+ /* Create a Windows region for the X rectangle */
+ hRgnRect = CreateRectRgn (pRects->x1, pRects->y1,
+ pRects->x2, pRects->y2);
+ if (hRgnRect == NULL)
+ {
+ ErrorF("winReshapeRootless - CreateRectRgn() failed\n");
+ }
+
+ /* Merge the Windows region with the accumulated region */
+ if (CombineRgn (hRgn, hRgn, hRgnRect, RGN_OR) == ERROR)
+ {
+ ErrorF("winReshapeRootless - CombineRgn() failed\n");
+ }
+
+ /* Delete the temporary Windows region */
+ DeleteObject (hRgnRect);
+ }
+
+ /* Save a handle to the composite region in the window privates */
+ pWinPriv->hRgn = hRgn;
+ }
+
+ REGION_UNINIT(pScreen, &rrNewShape);
+
+ return;
+}
diff --git a/xorg-server/hw/xwin/winwindowswm.c b/xorg-server/hw/xwin/winwindowswm.c
index d0c6de9bc..e16f6cfaf 100644
--- a/xorg-server/hw/xwin/winwindowswm.c
+++ b/xorg-server/hw/xwin/winwindowswm.c
@@ -124,7 +124,7 @@ ProcWindowsWMQueryVersion(register ClientPtr client)
swapl(&rep.length, n);
}
WriteToClient(client, sizeof(xWindowsWMQueryVersionReply), (char *)&rep);
- return (client->noClientException);
+ return Success;
}
@@ -164,7 +164,7 @@ WMFreeClient (pointer data, XID id)
}
updateEventMask (pHead);
}
- xfree ((pointer) pEvent);
+ free((pointer) pEvent);
return 1;
}
@@ -179,9 +179,9 @@ WMFreeEvents (pointer data, XID id)
{
pNext = pCur->next;
FreeResource (pCur->clientResource, ClientType);
- xfree ((pointer) pCur);
+ free((pointer) pCur);
}
- xfree ((pointer) pHead);
+ free((pointer) pHead);
eventMask = 0;
return 1;
}
@@ -212,7 +212,7 @@ ProcWindowsWMSelectInput (register ClientPtr client)
}
/* build the entry */
- pNewEvent = (WMEventPtr) xalloc (sizeof (WMEventRec));
+ pNewEvent = (WMEventPtr) malloc(sizeof (WMEventRec));
if (!pNewEvent)
return BadAlloc;
pNewEvent->next = 0;
@@ -234,7 +234,7 @@ ProcWindowsWMSelectInput (register ClientPtr client)
*/
if (!pHead)
{
- pHead = (WMEventPtr *) xalloc (sizeof (WMEventPtr));
+ pHead = (WMEventPtr *) malloc(sizeof (WMEventPtr));
if (!pHead ||
!AddResource (eventResource, eventResourceType, (pointer)pHead))
{
@@ -266,7 +266,7 @@ ProcWindowsWMSelectInput (register ClientPtr client)
pNewEvent->next = pEvent->next;
else
*pHead = pEvent->next;
- xfree (pEvent);
+ free(pEvent);
updateEventMask (pHead);
}
}
@@ -330,7 +330,7 @@ ProcWindowsWMDisableUpdate (register ClientPtr client)
//winDisableUpdate();
- return (client->noClientException);
+ return Success;
}
static int
@@ -340,7 +340,7 @@ ProcWindowsWMReenableUpdate (register ClientPtr client)
//winEnableUpdate();
- return (client->noClientException);
+ return Success;
}
@@ -353,7 +353,7 @@ ProcWindowsWMSetFrontProcess (register ClientPtr client)
//QuartzMessageMainThread(kWindowsSetFrontProcess, NULL, 0);
- return (client->noClientException);
+ return Success;
}
@@ -403,7 +403,7 @@ ProcWindowsWMFrameGetRect (register ClientPtr client)
rep.x, rep.y, rep.w, rep.h);
WriteToClient(client, sizeof(xWindowsWMFrameGetRectReply), (char *)&rep);
- return (client->noClientException);
+ return Success;
}
@@ -490,7 +490,7 @@ ProcWindowsWMFrameDraw (register ClientPtr client)
}
winDebug ("ProcWindowsWMFrameDraw - done\n");
- return (client->noClientException);
+ return Success;
}
static int
@@ -541,7 +541,7 @@ ProcWindowsWMFrameSetTitle(
winDebug ("ProcWindowsWMFrameSetTitle - done\n");
- return (client->noClientException);
+ return Success;
}